Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
OPC_OptimizedTree.cpp File Reference
#include "Stdafx.h"

Go to the source code of this file.

Macros

#define FIND_MAX_VALUES
 
#define INIT_QUANTIZATION
 
#define PERFORM_QUANTIZATION
 
#define REMAP_DATA(member)
 

Functions

static void _BuildCollisionTree (AABBCollisionNode *linear, const udword box_id, udword &current_id, const AABBTreeNode *current_node)
 
static void _BuildNoLeafTree (AABBNoLeafNode *linear, const udword box_id, udword &current_id, const AABBTreeNode *current_node)
 
inline_ void OPComputeMinMax (Point &min, Point &max, const VertexPointers &vp)
 

Variables

static bool gFixQuantized = true
 

Detailed Description

Contains code for optimized trees. Implements 4 trees:

  • normal
  • no leaf
  • quantized
  • no leaf / quantized
Author
Pierre Terdiman
Date
March, 20, 2001

Definition in file OPC_OptimizedTree.cpp.

Macro Definition Documentation

#define FIND_MAX_VALUES
Value:
/* Get max values */ \
for(i=0;i<mNbNodes;i++) \
{ \
if(fabsf(Nodes[i].mAABB.mCenter.x)>CMax.x) CMax.x = fabsf(Nodes[i].mAABB.mCenter.x); \
if(fabsf(Nodes[i].mAABB.mCenter.y)>CMax.y) CMax.y = fabsf(Nodes[i].mAABB.mCenter.y); \
if(fabsf(Nodes[i].mAABB.mCenter.z)>CMax.z) CMax.z = fabsf(Nodes[i].mAABB.mCenter.z); \
if(fabsf(Nodes[i].mAABB.mExtents.x)>EMax.x) EMax.x = fabsf(Nodes[i].mAABB.mExtents.x); \
if(fabsf(Nodes[i].mAABB.mExtents.y)>EMax.y) EMax.y = fabsf(Nodes[i].mAABB.mExtents.y); \
if(fabsf(Nodes[i].mAABB.mExtents.z)>EMax.z) EMax.z = fabsf(Nodes[i].mAABB.mExtents.z); \
}

Definition at line 479 of file OPC_OptimizedTree.cpp.

#define INIT_QUANTIZATION
Value:
udword nbc=15; /* Keep one bit for sign */ \
udword nbe=15; /* Keep one bit for fix */ \
if(!gFixQuantized) nbe++; \
\
/* Compute quantization coeffs */ \
Point CQuantCoeff, EQuantCoeff; \
CQuantCoeff.x = CMax.x!=0.0f ? float((1<<nbc)-1)/CMax.x : 0.0f; \
CQuantCoeff.y = CMax.y!=0.0f ? float((1<<nbc)-1)/CMax.y : 0.0f; \
CQuantCoeff.z = CMax.z!=0.0f ? float((1<<nbc)-1)/CMax.z : 0.0f; \
EQuantCoeff.x = EMax.x!=0.0f ? float((1<<nbe)-1)/EMax.x : 0.0f; \
EQuantCoeff.y = EMax.y!=0.0f ? float((1<<nbe)-1)/EMax.y : 0.0f; \
EQuantCoeff.z = EMax.z!=0.0f ? float((1<<nbe)-1)/EMax.z : 0.0f; \
/* Compute and save dequantization coeffs */ \
mCenterCoeff.x = CQuantCoeff.x!=0.0f ? 1.0f / CQuantCoeff.x : 0.0f; \
mCenterCoeff.y = CQuantCoeff.y!=0.0f ? 1.0f / CQuantCoeff.y : 0.0f; \
mCenterCoeff.z = CQuantCoeff.z!=0.0f ? 1.0f / CQuantCoeff.z : 0.0f; \
mExtentsCoeff.x = EQuantCoeff.x!=0.0f ? 1.0f / EQuantCoeff.x : 0.0f; \
mExtentsCoeff.y = EQuantCoeff.y!=0.0f ? 1.0f / EQuantCoeff.y : 0.0f; \
mExtentsCoeff.z = EQuantCoeff.z!=0.0f ? 1.0f / EQuantCoeff.z : 0.0f; \

Definition at line 493 of file OPC_OptimizedTree.cpp.

#define PERFORM_QUANTIZATION

Definition at line 514 of file OPC_OptimizedTree.cpp.

#define REMAP_DATA (   member)
Value:
/* Fix data */ \
Data = Nodes[i].member; \
if(!(Data&1)) \
{ \
/* Compute box number */ \
udword Nb = (Data - uintptr_t(Nodes))/Nodes[i].GetNodeSize(); \
Data = uintptr_t(&mNodes[Nb]); \
} \
/* ...remapped */ \
mNodes[i].member = Data;

Definition at line 556 of file OPC_OptimizedTree.cpp.

Function Documentation

static void _BuildCollisionTree ( AABBCollisionNode linear,
const udword  box_id,
udword current_id,
const AABBTreeNode current_node 
)
static

Definition at line 101 of file OPC_OptimizedTree.cpp.

102 {
103  // Current node from input tree is "current_node". Must be flattened into "linear[boxid]".
104 
105  // Store the AABB
106  current_node->GetAABB()->GetCenter(linear[box_id].mAABB.mCenter);
107  current_node->GetAABB()->GetExtents(linear[box_id].mAABB.mExtents);
108  // Store remaining info
109  if(current_node->IsLeaf())
110  {
111  // The input tree must be complete => i.e. one primitive/leaf
112  OPASSERT(current_node->GetNbPrimitives()==1);
113  // Get the primitive index from the input tree
114  udword PrimitiveIndex = current_node->GetPrimitives()[0];
115  // Setup box data as the primitive index, marked as leaf
116  linear[box_id].mData = (PrimitiveIndex<<1)|1;
117  }
118  else
119  {
120  // To make the negative one implicit, we must store P and N in successive order
121  udword PosID = current_id++; // Get a new id for positive child
122  udword NegID = current_id++; // Get a new id for negative child
123  // Setup box data as the forthcoming new P pointer
124  linear[box_id].mData = (uintptr_t)&linear[PosID];
125  // Make sure it's not marked as leaf
126  OPASSERT(!(linear[box_id].mData&1));
127  // Recurse with new IDs
128  _BuildCollisionTree(linear, PosID, current_id, current_node->GetPos());
129  _BuildCollisionTree(linear, NegID, current_id, current_node->GetNeg());
130  }
131 }
static void _BuildNoLeafTree ( AABBNoLeafNode linear,
const udword  box_id,
udword current_id,
const AABBTreeNode current_node 
)
static

Definition at line 152 of file OPC_OptimizedTree.cpp.

153 {
154  const AABBTreeNode* P = current_node->GetPos();
155  const AABBTreeNode* N = current_node->GetNeg();
156  // Leaf nodes here?!
157  OPASSERT(P);
158  OPASSERT(N);
159  // Internal node => keep the box
160  current_node->GetAABB()->GetCenter(linear[box_id].mAABB.mCenter);
161  current_node->GetAABB()->GetExtents(linear[box_id].mAABB.mExtents);
162 
163  if(P->IsLeaf())
164  {
165  // The input tree must be complete => i.e. one primitive/leaf
166  OPASSERT(P->GetNbPrimitives()==1);
167  // Get the primitive index from the input tree
168  udword PrimitiveIndex = P->GetPrimitives()[0];
169  // Setup prev box data as the primitive index, marked as leaf
170  linear[box_id].mPosData = (PrimitiveIndex<<1)|1;
171  }
172  else
173  {
174  // Get a new id for positive child
175  udword PosID = current_id++;
176  // Setup box data
177  linear[box_id].mPosData = (uintptr_t)&linear[PosID];
178  // Make sure it's not marked as leaf
179  OPASSERT(!(linear[box_id].mPosData&1));
180  // Recurse
181  _BuildNoLeafTree(linear, PosID, current_id, P);
182  }
183 
184  if(N->IsLeaf())
185  {
186  // The input tree must be complete => i.e. one primitive/leaf
187  OPASSERT(N->GetNbPrimitives()==1);
188  // Get the primitive index from the input tree
189  udword PrimitiveIndex = N->GetPrimitives()[0];
190  // Setup prev box data as the primitive index, marked as leaf
191  linear[box_id].mNegData = (PrimitiveIndex<<1)|1;
192  }
193  else
194  {
195  // Get a new id for negative child
196  udword NegID = current_id++;
197  // Setup box data
198  linear[box_id].mNegData = (uintptr_t)&linear[NegID];
199  // Make sure it's not marked as leaf
200  OPASSERT(!(linear[box_id].mNegData&1));
201  // Recurse
202  _BuildNoLeafTree(linear, NegID, current_id, N);
203  }
204 }
inline_ void OPComputeMinMax ( Point min,
Point max,
const VertexPointers vp 
)

Definition at line 353 of file OPC_OptimizedTree.cpp.

References Opcode::Point::Max(), Opcode::Point::Min(), Opcode::VertexPointers::Vertex, Opcode::Point::x, Opcode::Point::y, and Opcode::Point::z.

354 {
355  // Compute triangle's AABB = a leaf box
356 #ifdef OPC_USE_FCOMI // a 15% speedup on my machine, not much
357  min.x = FCMin3(vp.Vertex[0]->x, vp.Vertex[1]->x, vp.Vertex[2]->x);
358  max.x = FCMax3(vp.Vertex[0]->x, vp.Vertex[1]->x, vp.Vertex[2]->x);
359 
360  min.y = FCMin3(vp.Vertex[0]->y, vp.Vertex[1]->y, vp.Vertex[2]->y);
361  max.y = FCMax3(vp.Vertex[0]->y, vp.Vertex[1]->y, vp.Vertex[2]->y);
362 
363  min.z = FCMin3(vp.Vertex[0]->z, vp.Vertex[1]->z, vp.Vertex[2]->z);
364  max.z = FCMax3(vp.Vertex[0]->z, vp.Vertex[1]->z, vp.Vertex[2]->z);
365 #else
366  min = *vp.Vertex[0];
367  max = *vp.Vertex[0];
368  min.Min(*vp.Vertex[1]);
369  max.Max(*vp.Vertex[1]);
370  min.Min(*vp.Vertex[2]);
371  max.Max(*vp.Vertex[2]);
372 #endif
373 }

Variable Documentation

bool gFixQuantized = true
static

Compilation flag:

  • true to fix quantized boxes (i.e. make sure they enclose the original ones)
  • false to see the effects of quantization errors (faster, but wrong results in some cases)

Definition at line 78 of file OPC_OptimizedTree.cpp.