Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

FSA

Community-Fossil

  • »FSA« ist der Autor dieses Themas
  • Private Nachricht senden

1

20.02.2014, 16:34

Frustum Culling

Hallo! Ich habe vor längerer Zeit eine Frustum Culling Implementation geschrieben, welche die Methoden von David nutzt. Aus irgendeinem Grund funktioniert es nicht mehr wie vorher. Aktuell ist es so, dass sobald der Mittelpunkt des Quaders nicht im sichtbaren Bereich ist, das komplette Objekt den Test nicht besteht. Im angehängten Bild habe ich versucht, das Problem zu verdeutlichen. C = Betrachter, Grün = Planes, roter Quader = das Objekt. Ich habe am Code nicht wirklich etwas geändert, es funktionierte vorher Problemlos. Die AABB Box vom Objekt ist richtig berechnet worden. Hier der Code:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
inline cPlane   PlaneNormalize(const Plane& p) {const float fLength = Vector3Length(p.n); return Plane(p.n / fLength, p.d / fLength);}

void FrustumCulling::ConstructFrustum(const Matrix& mView, const Matrix& mProjection)
{
    Matrix mTemp(mView * mProjection);

    // Linke Clippingebene
    m_pClippingPlanes[0].a = -(mTemp.m14 + mTemp.m11);
    m_pClippingPlanes[0].b = -(mTemp.m24 + mTemp.m21);
    m_pClippingPlanes[0].c = -(mTemp.m34 + mTemp.m31);
    m_pClippingPlanes[0].d = -(mTemp.m44 + mTemp.m41);
    m_pClippingPlanes[0] = PlaneNormalize(m_pClippingPlanes[0]);

    // Rechte Clippingebene
    m_pClippingPlanes[1].a = -(mTemp.m14 - mTemp.m11);
    m_pClippingPlanes[1].b = -(mTemp.m24 - mTemp.m21);
    m_pClippingPlanes[1].c = -(mTemp.m34 - mTemp.m31);
    m_pClippingPlanes[1].d = -(mTemp.m44 - mTemp.m41);
    m_pClippingPlanes[1] = PlaneNormalize(m_pClippingPlanes[1]);

    // Obere Clippingebene
    m_pClippingPlanes[2].a = -(mTemp.m14 - mTemp.m12);
    m_pClippingPlanes[2].b = -(mTemp.m24 - mTemp.m22);
    m_pClippingPlanes[2].c = -(mTemp.m34 - mTemp.m32);
    m_pClippingPlanes[2].d = -(mTemp.m44 - mTemp.m42);
    m_pClippingPlanes[2] = PlaneNormalize(m_pClippingPlanes[2]);

    // Untere Clippingebene
    m_pClippingPlanes[3].a = -(mTemp.m14 + mTemp.m12);
    m_pClippingPlanes[3].b = -(mTemp.m24 + mTemp.m22);
    m_pClippingPlanes[3].c = -(mTemp.m34 + mTemp.m32);
    m_pClippingPlanes[3].d = -(mTemp.m44 + mTemp.m42);
    m_pClippingPlanes[3] = PlaneNormalize(m_pClippingPlanes[3]);

    // Nahe Clippingebene
    m_pClippingPlanes[4].a = -(mTemp.m14 + mTemp.m13);
    m_pClippingPlanes[4].b = -(mTemp.m24 + mTemp.m23);
    m_pClippingPlanes[4].c = -(mTemp.m34 + mTemp.m33);
    m_pClippingPlanes[4].d = -(mTemp.m44 + mTemp.m43);
    m_pClippingPlanes[4] = PlaneNormalize(m_pClippingPlanes[4]);

    // Ferne Clippingebene
    m_pClippingPlanes[5].a = -(mTemp.m14 - mTemp.m13);
    m_pClippingPlanes[5].b = -(mTemp.m24 - mTemp.m23);
    m_pClippingPlanes[5].c = -(mTemp.m34 - mTemp.m33);
    m_pClippingPlanes[5].d = -(mTemp.m44 - mTemp.m43);
    m_pClippingPlanes[5] = PlaneNormalize(m_pClippingPlanes[5]);
}

bool FrustumCulling::BoxVisible(const Vector3& vBoxMin, const Vector3& vBoxMax, const Matrix& mBoxTransformation)
{
    if(!m_pClippingPlanes)
        LOG_ERROR_NULL_POINTER("m_pClippingPlanes", false);

        Matrix mInvBoxTransformation = MatrixInvert(mBoxTransformation);

    if(ClassifyBox_Inv(vBoxMin, vBoxMax, mInvBoxTransformation, m_pClippingPlanes[0]) == 1) return false;
    if(ClassifyBox_Inv(vBoxMin, vBoxMax, mInvBoxTransformation, m_pClippingPlanes[1]) == 1) return false;
    if(ClassifyBox_Inv(vBoxMin, vBoxMax, mInvBoxTransformation, m_pClippingPlanes[2]) == 1) return false;
    if(ClassifyBox_Inv(vBoxMin, vBoxMax, mInvBoxTransformation, m_pClippingPlanes[3]) == 1) return false;
    if(ClassifyBox_Inv(vBoxMin, vBoxMax, mInvBoxTransformation, m_pClippingPlanes[4]) == 1) return false;
    return ClassifyBox_Inv(vBoxMin, vBoxMax, mInvBoxTransformation, m_pClippingPlanes[5]) != 1 ? true : false;
}

NXE_API cPlane PlaneTransform(const cPlane& p, const Matrix& m)
{
    const float a = p.a * m.m11 + p.b * m.m21 + p.c * m.m31;
    const float b = p.a * m.m12 + p.b * m.m22 + p.c * m.m32;
    const float c = p.a * m.m13 + p.b * m.m23 + p.c * m.m33;

    return cPlane(a, b, c, 
                   p.d - (a * m.m41 + b * m.m42 + c * m.m43));
}

inline float    PlaneDotCoords(const Plane& p, const Vector3& v)    {return p.a * v.x + p.b * v.y + p.c * v.z + p.d;}

NXE_API int32_t ClassifyBox_Inv(const Vector3& vBoxMin, 
const Vector3& vBoxMax, 
const Matrix& mInvBoxTransformation, 
const Plane& Plane)
{
    Plane NewPlane(PlaneTransform(Plane, mInvBoxTransformation));

    Vector3 vNearPoint(vBoxMax);
    Vector3 vFarPoint(vBoxMin);
    if(NewPlane.a > 0.0f) {vNearPoint.x = vBoxMin.x; vFarPoint.x = vBoxMax.x;}
    if(NewPlane.b > 0.0f) {vNearPoint.y = vBoxMin.y; vFarPoint.y = vBoxMax.y;}
    if(NewPlane.c > 0.0f) {vNearPoint.z = vBoxMin.z; vFarPoint.z = vBoxMax.z;}

    if(PlaneDotCoords(NewPlane, vNearPoint) > 0.0f) return 1;

    if(PlaneDotCoords(NewPlane, vFarPoint) > 0.0f) return 0;

    return -1;
}


Danke im Voraus!
»FSA« hat folgendes Bild angehängt:
  • Zeichnung.png

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.