116 Nodes =
W3DNEWARRAY AABTreeClass::CullNodeStruct[NodeCount];
121 int curpolyindex = 0;
122 Build_Tree_Recursive(builder->Root,curpolyindex);
181 NodeCount = that.NodeCount;
184 memcpy(Nodes,that.Nodes,NodeCount *
sizeof(CullNodeStruct));
187 PolyCount = that.PolyCount;
190 memcpy(PolyIndices,that.PolyIndices,PolyCount *
sizeof(
uint32));
211void AABTreeClass::Reset(
void)
220 delete[] PolyIndices;
242 for (
int i=0;i<NodeCount;++i) {
261void AABTreeClass::Build_Tree_Recursive(AABTreeBuilderClass::CullNodeStruct * node,
int & curpolyindex)
266 CullNodeStruct * newnode = &(Nodes[node->Index]);
268 newnode->Min = node->Min;
269 newnode->Max = node->Max;
274 if (node->Front !=
NULL) {
277 newnode->Set_Front_Child(node->Front->Index);
278 newnode->Set_Back_Child(node->Back->Index);
282 newnode->Set_Poly0(curpolyindex);
283 newnode->Set_Poly_Count(node->PolyCount);
290 for (
int pcounter = 0; pcounter < node->PolyCount; pcounter++) {
291 PolyIndices[curpolyindex++] = node->PolyIndices[pcounter];
298 Build_Tree_Recursive(node->Front,curpolyindex);
301 Build_Tree_Recursive(node->Back,curpolyindex);
339 OBBoxAPTContextStruct context(box,apt);
340 Generate_OBBox_APT_Recursive(&(Nodes[0]),context);
359void AABTreeClass::Generate_OBBox_APT_Recursive(CullNodeStruct * node,OBBoxAPTContextStruct & context)
375 if (node->Is_Leaf()) {
377 int polycount = node->Get_Poly_Count();
378 int poly0 = node->Get_Poly0();
382 const Vector3 * loc = Mesh->Get_Vertex_Array();
383 const TriIndex * polys = Mesh->Get_Polygon_Array();
384#if (!OPTIMIZE_PLANEEQ_RAM)
385 const Vector4 * norms = Mesh->Get_Plane_Array();
387 for (
int poly_counter=0; poly_counter<polycount; poly_counter++) {
389 int poly_index = PolyIndices[poly0 + poly_counter];
391 tri.
V[0] = &(loc[ polys[poly_index][0] ]);
392 tri.
V[1] = &(loc[ polys[poly_index][1] ]);
393 tri.
V[2] = &(loc[ polys[poly_index][2] ]);
394#if (!OPTIMIZE_PLANEEQ_RAM)
395 tri.
N = (Vector3*)&(norms[poly_index]);
402 context.APT.Add(poly_index);
409 Generate_OBBox_APT_Recursive(&(Nodes[node->Get_Front_Child()]),context);
410 Generate_OBBox_APT_Recursive(&(Nodes[node->Get_Back_Child()]),context);
437 OBBoxRayAPTContextStruct context(box,viewdir,apt);
438 Generate_OBBox_APT_Recursive(&(Nodes[0]),context);
454void AABTreeClass::Generate_OBBox_APT_Recursive(CullNodeStruct * node, OBBoxRayAPTContextStruct & context)
470 if (node->Is_Leaf()) {
472 int polycount = node->Get_Poly_Count();
473 int poly0 = node->Get_Poly0();
477 const Vector3 * loc = Mesh->Get_Vertex_Array();
478 const TriIndex * polys = Mesh->Get_Polygon_Array();
479#if (!OPTIMIZE_PLANEEQ_RAM)
480 const Vector4 * norms = Mesh->Get_Plane_Array();
483 for (
int poly_counter=0; poly_counter<polycount; poly_counter++) {
485 int poly_index = PolyIndices[poly0 + poly_counter];
487 tri.
V[0] = &(loc[ polys[poly_index][0] ]);
488 tri.
V[1] = &(loc[ polys[poly_index][1] ]);
489 tri.
V[2] = &(loc[ polys[poly_index][2] ]);
490#if (!OPTIMIZE_PLANEEQ_RAM)
491 tri.
N = (Vector3*)&(norms[poly_index]);
499 context.APT.Add(poly_index);
507 Generate_OBBox_APT_Recursive(&(Nodes[node->Get_Front_Child()]),context);
508 Generate_OBBox_APT_Recursive(&(Nodes[node->Get_Back_Child()]),context);
533 if (raytest.
Cull(node->Min,node->Max)) {
538 if (node->Is_Leaf()) {
540 return Cast_Ray_To_Polys(node,raytest);
544 res = res | Cast_Ray_Recursive(&(Nodes[node->Get_Front_Child()]),raytest);
545 res = res | Cast_Ray_Recursive(&(Nodes[node->Get_Back_Child()]),raytest);
571int AABTreeClass::Cast_Semi_Infinite_Axis_Aligned_Ray_Recursive(CullNodeStruct * node,
572 const Vector3 & start_point,
int axis_r,
int axis_1,
int axis_2,
int direction,
573 unsigned char & flags)
584 static const float sign[2] = { -1.0f, 1.0f };
585 float bounds[2], start[2];
586 bounds[0] = -node->Min[axis_r];
587 bounds[1] = node->Max[axis_r];
588 start[0] = -start_point[axis_r];
589 start[1] = start_point[axis_r];
590 if ( start_point[axis_1] < node->Min[axis_1] || start_point[axis_2] < node->Min[axis_2] ||
591 start_point[axis_1] > node->Max[axis_1] || start_point[axis_2] > node->Max[axis_2] ||
592 start[direction] > bounds[direction] ) {
597 if (node->Is_Leaf()) {
599 return Cast_Semi_Infinite_Axis_Aligned_Ray_To_Polys(node, start_point, axis_r, axis_1,
600 axis_2, direction, flags);
604 count += Cast_Semi_Infinite_Axis_Aligned_Ray_Recursive(&(Nodes[node->Get_Front_Child()]),
605 start_point, axis_r, axis_1, axis_2, direction, flags);
606 count += Cast_Semi_Infinite_Axis_Aligned_Ray_Recursive(&(Nodes[node->Get_Back_Child()]),
607 start_point, axis_r, axis_1, axis_2, direction, flags);
635 if (boxtest.
Cull(node->Min,node->Max)) {
640 if (node->Is_Leaf()) {
642 return Cast_AABox_To_Polys(node,boxtest);
646 res = res | Cast_AABox_Recursive(&(Nodes[node->Get_Front_Child()]),boxtest);
647 res = res | Cast_AABox_Recursive(&(Nodes[node->Get_Back_Child()]),boxtest);
675 if (boxtest.
Cull(node->Min,node->Max)) {
680 if (node->Is_Leaf()) {
682 return Cast_OBBox_To_Polys(node,boxtest);
686 res = res | Cast_OBBox_Recursive(&(Nodes[node->Get_Front_Child()]),boxtest);
687 res = res | Cast_OBBox_Recursive(&(Nodes[node->Get_Back_Child()]),boxtest);
713 if (
test.Cull(node->Min,node->Max)) {
718 if (node->Is_Leaf()) {
720 return Intersect_OBBox_With_Polys(node,
test);
724 res = res | Intersect_OBBox_Recursive(&(Nodes[node->Get_Front_Child()]),
test);
725 res = res | Intersect_OBBox_Recursive(&(Nodes[node->Get_Back_Child()]),
test);
732#pragma optimize("", off)
749 if (node->Get_Poly_Count() > 0) {
755 const Vector3 * loc = Mesh->Get_Vertex_Array();
756 const TriIndex * polyverts = Mesh->Get_Polygon_Array();
757#if (!OPTIMIZE_PLANEEQ_RAM)
758 const Vector4 * norms = Mesh->Get_Plane_Array();
762 int poly0 = node->Get_Poly0();
763 int polycount = node->Get_Poly_Count();
765 for (
int poly_counter=0; poly_counter<polycount; poly_counter++) {
767 int poly_index = PolyIndices[poly0 + poly_counter];
769 tri.
V[0] = &(loc[ polyverts[poly_index][0] ]);
770 tri.
V[1] = &(loc[ polyverts[poly_index][1] ]);
771 tri.
V[2] = &(loc[ polyverts[poly_index][2] ]);
772#if (!OPTIMIZE_PLANEEQ_RAM)
773 tri.
N = (Vector3*)&(norms[poly_index]);
780 polyhit = poly_index;
795#pragma optimize("", on)
817int AABTreeClass::Cast_Semi_Infinite_Axis_Aligned_Ray_To_Polys(CullNodeStruct * node,
818 const Vector3 & start_point,
int axis_r,
int axis_1,
int axis_2,
int direction,
819 unsigned char & flags)
823 if (node->Get_Poly_Count() > 0) {
829 const Vector3 * loc = Mesh->Get_Vertex_Array();
830 const TriIndex * polyverts = Mesh->Get_Polygon_Array();
831 const Vector4 * plane = Mesh->Get_Plane_Array();
832 int poly0 = node->Get_Poly0();
833 int polycount = node->Get_Poly_Count();
835 for (
int poly_counter=0; poly_counter < polycount; poly_counter++) {
837 int poly_index = PolyIndices[poly0 + poly_counter];
839 const Vector3 &v0 = loc[ polyverts[poly_index][0] ];
840 const Vector3 &v1 = loc[ polyverts[poly_index][1] ];
841 const Vector3 &v2 = loc[ polyverts[poly_index][2] ];
842 const Vector4 &tri_plane = plane[poly_index];
846 tri_plane, start_point, axis_r, axis_1, axis_2, direction, flags);
868 if (node->Get_Poly_Count() > 0) {
874 const Vector3 * loc = Mesh->Get_Vertex_Array();
875 const TriIndex * polyverts = Mesh->Get_Polygon_Array();
876#if (!OPTIMIZE_PLANEEQ_RAM)
877 const Vector4 * norms = Mesh->Get_Plane_Array();
881 int poly0 = node->Get_Poly0();
882 int polycount = node->Get_Poly_Count();
884 for (
int poly_counter=0; poly_counter<polycount; poly_counter++) {
886 int poly_index = PolyIndices[poly0 + poly_counter];
888 tri.
V[0] = &(loc[ polyverts[poly_index][0] ]);
889 tri.
V[1] = &(loc[ polyverts[poly_index][1] ]);
890 tri.
V[2] = &(loc[ polyverts[poly_index][2] ]);
891#if (!OPTIMIZE_PLANEEQ_RAM)
892 tri.
N = (Vector3*)&(norms[poly_index]);
899 polyhit = poly_index;
929 int polycount = node->Get_Poly_Count();
930 int poly0 = node->Get_Poly0();
938 const Vector3 * loc = Mesh->Get_Vertex_Array();
939 const TriIndex * polyverts = Mesh->Get_Polygon_Array();
940#if (!OPTIMIZE_PLANEEQ_RAM)
941 const Vector4 * norms = Mesh->Get_Plane_Array();
946 for (
int poly_counter=0; poly_counter<polycount; poly_counter++) {
948 int poly_index = PolyIndices[poly0 + poly_counter];
950 tri.
V[0] = &(loc[ polyverts[poly_index][0] ]);
951 tri.
V[1] = &(loc[ polyverts[poly_index][1] ]);
952 tri.
V[2] = &(loc[ polyverts[poly_index][2] ]);
953#if (!OPTIMIZE_PLANEEQ_RAM)
954 tri.
N = (Vector3*)&(norms[poly_index]);
962 polyhit = poly_index;
991bool AABTreeClass::Intersect_OBBox_With_Polys
993 CullNodeStruct * node,
997 int poly0 = node->Get_Poly0();
998 int polycount = node->Get_Poly_Count();
1000 if (polycount > 0) {
1006 const Vector3 * loc = Mesh->Get_Vertex_Array();
1007 const TriIndex * polyverts = Mesh->Get_Polygon_Array();
1008#if (!OPTIMIZE_PLANEEQ_RAM)
1009 const Vector4 * norms = Mesh->Get_Plane_Array();
1012 for (
int poly_counter=0; poly_counter<polycount; poly_counter++) {
1014 int poly_index = PolyIndices[poly0 + poly_counter];
1016 tri.
V[0] = &(loc[ polyverts[poly_index][0] ]);
1017 tri.
V[1] = &(loc[ polyverts[poly_index][1] ]);
1018 tri.
V[2] = &(loc[ polyverts[poly_index][2] ]);
1019#if (!OPTIMIZE_PLANEEQ_RAM)
1020 tri.
N = (Vector3*)&(norms[poly_index]);
1051void AABTreeClass::Update_Bounding_Boxes_Recursive(CullNodeStruct * node)
1053 node->Min.
Set(100000.0f,100000.0f,100000.0f);
1054 node->Max.Set(-100000.0f,-100000.0f,-100000.0f);
1059 if (node->Is_Leaf() ==
false) {
1061 Update_Bounding_Boxes_Recursive(&(Nodes[node->Get_Front_Child()]));
1062 Update_Bounding_Boxes_Recursive(&(Nodes[node->Get_Back_Child()]));
1067 int front = node->Get_Front_Child();
1068 int back = node->Get_Back_Child();
1070 if (Nodes[front].Min.X < node->Min.X) node->Min.X = Nodes[front].Min.X;
1071 if (Nodes[front].Max.X > node->Max.X) node->Max.X = Nodes[front].Max.X;
1073 if (Nodes[front].Min.Y < node->Min.Y) node->Min.Y = Nodes[front].Min.Y;
1074 if (Nodes[front].Max.Y > node->Max.Y) node->Max.Y = Nodes[front].Max.Y;
1076 if (Nodes[front].Min.Z < node->Min.Z) node->Min.Z = Nodes[front].Min.Z;
1077 if (Nodes[front].Max.Z > node->Max.Z) node->Max.Z = Nodes[front].Max.Z;
1079 if (Nodes[back].Min.X < node->Min.X) node->Min.X = Nodes[back].Min.X;
1080 if (Nodes[back].Max.X > node->Max.X) node->Max.X = Nodes[back].Max.X;
1082 if (Nodes[back].Min.Y < node->Min.Y) node->Min.Y = Nodes[back].Min.Y;
1083 if (Nodes[back].Max.Y > node->Max.Y) node->Max.Y = Nodes[back].Max.Y;
1085 if (Nodes[back].Min.Z < node->Min.Z) node->Min.Z = Nodes[back].Min.Z;
1086 if (Nodes[back].Max.Z > node->Max.Z) node->Max.Z = Nodes[back].Max.Z;
1093 int poly0 = node->Get_Poly0();
1094 int polycount = node->Get_Poly_Count();
1096 for (
int poly_index = 0; poly_index < polycount; poly_index++) {
1097 int pi = PolyIndices[poly0 + poly_index];
1098 Update_Min_Max(pi,node->Min,node->Max );
1103 WWASSERT(node->Min.X != 100000.0f);
1104 WWASSERT(node->Min.Y != 100000.0f);
1105 WWASSERT(node->Min.Z != 100000.0f);
1106 WWASSERT(node->Max.X != -100000.0f);
1107 WWASSERT(node->Max.Y != -100000.0f);
1108 WWASSERT(node->Max.Z != -100000.0f);
1126 for (
int vert_index = 0; vert_index < 3; vert_index++) {
1128 const TriIndex * polyverts = Mesh->Get_Polygon_Array() + poly_index;
1129 const Vector3 * point = Mesh->Get_Vertex_Array() + (*polyverts)[vert_index];
1131 if (point->
X <
min.X)
min.X = point->
X;
1132 if (point->
Y <
min.Y)
min.Y = point->
Y;
1133 if (point->
Z <
min.Z)
min.Z = point->
Z;
1135 if (point->
X >
max.X)
max.X = point->
X;
1136 if (point->
Y >
max.Y)
max.Y = point->
Y;
1137 if (point->
Z >
max.Z)
max.Z = point->
Z;
1161 cload.
Read(&header,
sizeof(header));
1173 Read_Poly_Indices(cload);
1199 cload.
Read(PolyIndices,
sizeof(
uint32) * PolyCount);
1217 W3dMeshAABTreeNode w3dnode;
1219 for (
int i=0; i<NodeCount; i++) {
1220 cload.
Read(&w3dnode,
sizeof(w3dnode));
1222 Nodes[i].Min.X = w3dnode.
Min.
X;
1223 Nodes[i].Min.Y = w3dnode.
Min.
Y;
1224 Nodes[i].Min.Z = w3dnode.
Min.
Z;
1226 Nodes[i].Max.X = w3dnode.
Max.
X;
1227 Nodes[i].Max.Y = w3dnode.
Max.
Y;
1228 Nodes[i].Max.Z = w3dnode.
Max.
Z;
@ W3D_CHUNK_AABTREE_HEADER
@ W3D_CHUNK_AABTREE_POLYINDICES
@ W3D_CHUNK_AABTREE_NODES
void Set_Mesh(MeshGeometryClass *mesh)
friend class MeshGeometryClass
void Load_W3D(ChunkLoadClass &cload)
void Generate_APT(const OBBoxClass &box, SimpleDynVecClass< uint32 > &apt)
friend class AABTreeBuilderClass
void Init_Min_Max(const Vector3 &min, const Vector3 &max)
bool Cull(const Vector3 &min, const Vector3 &max)
uint32 Read(void *buf, uint32 nbytes)
static bool Collide(const LineSegClass &line, const AAPlaneClass &plane, CastResultStruct *result)
static bool Intersection_Test(const AABoxClass &box, const TriClass &tri)
CastResultStruct * Result
bool Cull(const Vector3 &min, const Vector3 &max)
bool Cull(const Vector3 &min, const Vector3 &max)
static WWINLINE float Dot_Product(const Vector3 &a, const Vector3 &b)
WWINLINE void Set(float x, float y, float z)
bool Cast_Semi_Infinite_Axis_Aligned_Ray_To_Triangle(const Vector3 &tri_point0, const Vector3 &tri_point1, const Vector3 &tri_point2, const Vector4 &tri_plane, const Vector3 &ray_start, int axis_r, int axis_1, int axis_2, int direction, unsigned char &flags)