bluecore/ode/OPCODE/OPC_TreeBuilders.cpp

256 lines
12 KiB
C++

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*
* OPCODE - Optimized Collision Detection
* Copyright (C) 2001 Pierre Terdiman
* Homepage: http://www.codercorner.com/Opcode.htm
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Contains code for tree builders.
* \file OPC_TreeBuilders.cpp
* \author Pierre Terdiman
* \date March, 20, 2001
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* A builder for AABB-trees of vertices.
*
* \class AABBTreeOfVerticesBuilder
* \author Pierre Terdiman
* \version 1.3
* \date March, 20, 2001
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* A builder for AABB-trees of AABBs.
*
* \class AABBTreeOfAABBsBuilder
* \author Pierre Terdiman
* \version 1.3
* \date March, 20, 2001
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* A builder for AABB-trees of triangles.
*
* \class AABBTreeOfTrianglesBuilder
* \author Pierre Terdiman
* \version 1.3
* \date March, 20, 2001
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Precompiled Header
#include "Stdafx.h"
using namespace Opcode;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Computes the AABB of a set of primitives.
* \param primitives [in] list of indices of primitives
* \param nb_prims [in] number of indices
* \param global_box [out] global AABB enclosing the set of input primitives
* \return true if success
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool AABBTreeOfAABBsBuilder::ComputeGlobalBox(const udword* primitives, udword nb_prims, AABB& global_box) const
{
// Checkings
if(!primitives || !nb_prims) return false;
// Initialize global box
global_box = mAABBArray[primitives[0]];
// Loop through boxes
for(udword i=1;i<nb_prims;i++)
{
// Update global box
global_box.Add(mAABBArray[primitives[i]]);
}
return true;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Computes the splitting value along a given axis for a given primitive.
* \param index [in] index of the primitive to split
* \param axis [in] axis index (0,1,2)
* \return splitting value
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
float AABBTreeOfAABBsBuilder::GetSplittingValue(udword index, udword axis) const
{
// For an AABB, the splitting value is the middle of the given axis,
// i.e. the corresponding component of the center point
return mAABBArray[index].GetCenter(axis);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Computes the AABB of a set of primitives.
* \param primitives [in] list of indices of primitives
* \param nb_prims [in] number of indices
* \param global_box [out] global AABB enclosing the set of input primitives
* \return true if success
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool AABBTreeOfTrianglesBuilder::ComputeGlobalBox(const udword* primitives, udword nb_prims, AABB& global_box) const
{
// Checkings
if(!primitives || !nb_prims) return false;
// Initialize global box
Point Min(MAX_FLOAT, MAX_FLOAT, MAX_FLOAT);
Point Max(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT);
// Loop through triangles
VertexPointers VP;
while(nb_prims--)
{
// Get current triangle-vertices
mIMesh->GetTriangle(VP, *primitives++);
// Update global box
Min.Min(*VP.Vertex[0]).Min(*VP.Vertex[1]).Min(*VP.Vertex[2]);
Max.Max(*VP.Vertex[0]).Max(*VP.Vertex[1]).Max(*VP.Vertex[2]);
}
global_box.SetMinMax(Min, Max);
return true;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Computes the splitting value along a given axis for a given primitive.
* \param index [in] index of the primitive to split
* \param axis [in] axis index (0,1,2)
* \return splitting value
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
float AABBTreeOfTrianglesBuilder::GetSplittingValue(udword index, udword axis) const
{
/* // Compute center of triangle
Point Center;
mTriList[index].Center(mVerts, Center);
// Return value
return Center[axis];*/
// Compute correct component from center of triangle
// return (mVerts[mTriList[index].mVRef[0]][axis]
// +mVerts[mTriList[index].mVRef[1]][axis]
// +mVerts[mTriList[index].mVRef[2]][axis])*INV3;
VertexPointers VP;
mIMesh->GetTriangle(VP, index);
// Compute correct component from center of triangle
return ((*VP.Vertex[0])[axis]
+(*VP.Vertex[1])[axis]
+(*VP.Vertex[2])[axis])*INV3;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Computes the splitting value along a given axis for a given node.
* \param primitives [in] list of indices of primitives
* \param nb_prims [in] number of indices
* \param global_box [in] global AABB enclosing the set of input primitives
* \param axis [in] axis index (0,1,2)
* \return splitting value
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
float AABBTreeOfTrianglesBuilder::GetSplittingValue(const udword* primitives, udword nb_prims, const AABB& global_box, udword axis) const
{
if(mSettings.mRules&SPLIT_GEOM_CENTER)
{
// Loop through triangles
float SplitValue = 0.0f;
VertexPointers VP;
for(udword i=0;i<nb_prims;i++)
{
// Get current triangle-vertices
mIMesh->GetTriangle(VP, primitives[i]);
// Update split value
SplitValue += (*VP.Vertex[0])[axis];
SplitValue += (*VP.Vertex[1])[axis];
SplitValue += (*VP.Vertex[2])[axis];
}
return SplitValue / float(nb_prims*3);
}
else return AABBTreeBuilder::GetSplittingValue(primitives, nb_prims, global_box, axis);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Computes the AABB of a set of primitives.
* \param primitives [in] list of indices of primitives
* \param nb_prims [in] number of indices
* \param global_box [out] global AABB enclosing the set of input primitives
* \return true if success
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool AABBTreeOfVerticesBuilder::ComputeGlobalBox(const udword* primitives, udword nb_prims, AABB& global_box) const
{
// Checkings
if(!primitives || !nb_prims) return false;
// Initialize global box
global_box.SetEmpty();
// Loop through vertices
for(udword i=0;i<nb_prims;i++)
{
// Update global box
global_box.Extend(mVertexArray[primitives[i]]);
}
return true;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Computes the splitting value along a given axis for a given primitive.
* \param index [in] index of the primitive to split
* \param axis [in] axis index (0,1,2)
* \return splitting value
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
float AABBTreeOfVerticesBuilder::GetSplittingValue(udword index, udword axis) const
{
// For a vertex, the splitting value is simply the vertex coordinate.
return mVertexArray[index][axis];
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Computes the splitting value along a given axis for a given node.
* \param primitives [in] list of indices of primitives
* \param nb_prims [in] number of indices
* \param global_box [in] global AABB enclosing the set of input primitives
* \param axis [in] axis index (0,1,2)
* \return splitting value
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
float AABBTreeOfVerticesBuilder::GetSplittingValue(const udword* primitives, udword nb_prims, const AABB& global_box, udword axis) const
{
if(mSettings.mRules&SPLIT_GEOM_CENTER)
{
// Loop through vertices
float SplitValue = 0.0f;
for(udword i=0;i<nb_prims;i++)
{
// Update split value
SplitValue += mVertexArray[primitives[i]][axis];
}
return SplitValue / float(nb_prims);
}
else return AABBTreeBuilder::GetSplittingValue(primitives, nb_prims, global_box, axis);
}