source: GTP/trunk/App/Games/Jungle_Rumble/src/Quad.cpp @ 1378

Revision 1378, 5.0 KB checked in by giegl, 18 years ago (diff)

GTPD - Jungle Rumble - integrate into GTP SVN structure

Line 
1#include "dxstdafx.h"
2#include ".\quad.h"
3#include "Camera.h"
4#include "Plane.h"
5
6Quad::Quad(void)
7{
8        this->width = 0;
9        this->height = 0;
10        this->level = -1;
11        for(int i=0;i<4;i++) {
12                q[i] = 0;
13        }
14        this->fullyVisible = false;
15        this->partlyVisible = false;
16}
17
18Quad::~Quad(void)
19{
20        this->deleteQuadTree();
21}
22
23void Quad::setPosition(float _x, float _z) {
24        this->position.x = _x;
25        this->position.y = 0;
26        this->position.z = _z;
27
28        //BBox berechnen
29        this->minBBox.x = this->position.x - this->width/2;
30        this->minBBox.y = 0;
31        this->minBBox.z = this->position.z - this->height/2;
32
33        this->maxBBox.x = this->position.x + this->width/2;
34        this->maxBBox.y = 0;
35        this->maxBBox.z = this->position.z + this->height/2;
36}
37
38void Quad::setDimension(float _width, float _height) {
39        this->width = _width;
40        this->height = _height;
41
42        //BBox berechnen
43        this->minBBox.x = this->position.x - this->width/2;
44        this->minBBox.y = 0;
45        this->minBBox.z = this->position.z - this->height/2;
46
47        this->maxBBox.x = this->position.x + this->width/2;
48        this->maxBBox.y = 0;
49        this->maxBBox.z = this->position.z + this->height/2;
50}
51
52void Quad::buildQuadTree(int _level) {
53        this->level = _level-1;
54        float tx = 0;
55        float tz = 0;
56        for(int i=0;i<4;i++) {
57                q[i] = new Quad();
58                q[i]->setDimension(this->width/2, this->height/2);
59                //Positionieren
60                switch(i) {
61                        case 0:
62                                tx = this->position.x - this->width/4;
63                tz = this->position.z - this->height/4;                         
64                                break;
65                        case 1:
66                                tx = this->position.x + this->width/4;
67                tz = this->position.z - this->height/4;
68                                break;
69                        case 2:
70                                tx = this->position.x - this->width/4;
71                tz = this->position.z + this->height/4;
72                                break;
73                        case 3:
74                                tx = this->position.x + this->width/4;
75                tz = this->position.z + this->height/4;
76                                break;
77                }
78                q[i]->setPosition(tx, tz);
79                if(this->level>0) {
80                        q[i]->buildQuadTree(this->level);
81                }
82        }       
83}
84
85void Quad::clipQuadAgainstCamera(Plane *view)//, std::list<Quad *> &visibleQuadList) {
86{
87        this->fullyVisible = false;
88        this->partlyVisible = false;
89        switch(getClipType(view)) {
90                case 0: //The Quad is in the Cameras ViewFrustum
91                        this->fullyVisible = true;
92                        //visibleQuadList.push_back(this);
93                        break;
94                case 1: //The Quad is outside the Cameras ViewFrustum
95                        break;
96                default: //The Quad is not fully in Cameras ViewFrustum (go down one level)
97                        if(this->level>0) {
98                                this->partlyVisible = true;
99                                for(int i=0;i<4;i++)
100                                        q[i]->clipQuadAgainstCamera(view);//, visibleQuadList);
101                        } else {
102                                //Level 0 Quad which is partly visible -> quad is visible
103                                this->fullyVisible = true;
104                                //visibleQuadList.push_back(this);
105                        }
106                        break;
107        }
108}
109
110bool Quad::nodeInside(Node* node)
111{
112        if(!this->fullyVisible && !this->partlyVisible) {
113                return false;
114        }
115        if(this->fullyVisible) {
116                Vector *minNode;
117                Vector *maxNode;
118
119                minNode = &node->absMinAABBox;
120                maxNode = &node->absMaxAABBox;
121
122                if(maxNode->x < this->minBBox.x ||
123                minNode->x > this->maxBBox.x ||
124                maxNode->z < this->minBBox.z ||
125                minNode->z > this->maxBBox.z) {
126                        return false;
127                } else {
128                        return true;
129                }
130        }
131        if(this->partlyVisible) {
132                for(int i=0;i<4;i++) {
133                        if(q[i]->nodeInside(node)) {
134                                return true;
135                        }
136                }
137                return false;
138        }
139        return false;
140}
141
142void Quad::deleteQuadTree() {
143        if(this->level>=0) {
144                for(int i=0;i<4;i++) {
145                        delete this->q[i];
146                }
147        }
148}
149
150Vector Quad::getMinBBox() {
151        return minBBox;
152}
153
154Vector Quad::getMaxBBox() {
155        return maxBBox;
156}
157
158int Quad::getClipType(Plane *view) {
159        bool inSide[6];
160        Vector corner[4];
161
162        corner[0] = this->maxBBox;
163        corner[1].x = this->maxBBox.x; corner[1].z = this->minBBox.z;
164        corner[2] = this->minBBox;
165        corner[3].x = this->minBBox.x; corner[3].z = this->maxBBox.z;
166
167        //Ueberpruefen ob alle Punkte außerhalb einer Frustumfläche der Kamera liegen -> quad is outside
168        //Ueberprüfung findet fuer front, near, left und right statt da die quads die höhe 0 haben!
169        bool bInFront[16];
170        for(int i=0;i<16;i+=4) {
171                bInFront[i+0] = view[i/4].inFront(corner[0]);
172                bInFront[i+1] = view[i/4].inFront(corner[1]);
173                bInFront[i+2] = view[i/4].inFront(corner[2]);
174                bInFront[i+3] = view[i/4].inFront(corner[3]);
175        }
176
177        for(int i=0;i<4;i++) {
178                if(bInFront[i*4+0] == false &&
179                   bInFront[i*4+1] == false &&
180                   bInFront[i*4+2] == false &&
181                   bInFront[i*4+3] == false) {
182                   //Quad is behind plane i -> quad is outside of frustum
183                   return 1;
184                }
185        }
186
187        //Ueberpruefen ob alle Punkte innerhalb des Frustums liegen -> quad is inside
188        for(int i=0;i<4;i++) {
189                if(bInFront[i*4+0] == true &&
190                   bInFront[i*4+1] == true &&
191                   bInFront[i*4+2] == true &&
192                   bInFront[i*4+3] == true) {
193                        //Quad is behind plane i -> quad is outside of frustum
194                        inSide[i] = true;
195                } else {
196                        inSide[i] = false;
197                }
198        }
199                 
200        if(inSide[0] == true &&
201           inSide[1] == true &&
202           inSide[2] == true &&
203           inSide[3] == true) {
204                //Quad is completely inside frustum
205           return 0;
206        }
207
208        //sonst Quad schneidet Frustum -> divide & conquer
209        return -1;
210}
Note: See TracBrowser for help on using the repository browser.