[1378] | 1 | #include "dxstdafx.h"
|
---|
| 2 | #include ".\quad.h"
|
---|
| 3 | #include "Camera.h"
|
---|
| 4 | #include "Plane.h"
|
---|
| 5 |
|
---|
| 6 | Quad::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 |
|
---|
| 18 | Quad::~Quad(void)
|
---|
| 19 | {
|
---|
| 20 | this->deleteQuadTree();
|
---|
| 21 | }
|
---|
| 22 |
|
---|
| 23 | void 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 |
|
---|
| 38 | void 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 |
|
---|
| 52 | void 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 |
|
---|
| 85 | void 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 |
|
---|
| 110 | bool 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 |
|
---|
| 142 | void Quad::deleteQuadTree() {
|
---|
| 143 | if(this->level>=0) {
|
---|
| 144 | for(int i=0;i<4;i++) {
|
---|
| 145 | delete this->q[i];
|
---|
| 146 | }
|
---|
| 147 | }
|
---|
| 148 | }
|
---|
| 149 |
|
---|
| 150 | Vector Quad::getMinBBox() {
|
---|
| 151 | return minBBox;
|
---|
| 152 | }
|
---|
| 153 |
|
---|
| 154 | Vector Quad::getMaxBBox() {
|
---|
| 155 | return maxBBox;
|
---|
| 156 | }
|
---|
| 157 |
|
---|
| 158 | int 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 | }
|
---|