/usr/include/libwildmagic/Wm5BoundTree.inl is in libwildmagic-dev 5.13-1+b2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 | // Geometric Tools, LLC
// Copyright (c) 1998-2014
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
// http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
//
// File Version: 5.0.0 (2010/01/01)
//----------------------------------------------------------------------------
template <class Mesh, class Bound>
BoundTree<Mesh,Bound>::BoundTree (const Mesh* mesh, int maxTrisPerLeaf,
bool storeInteriorTris)
:
mMesh(mesh),
mLChild(0),
mRChild(0),
mNumTriangles(0),
mTriangles(0)
{
if (maxTrisPerLeaf == 0)
{
// This is a signal to defer construction. This behavior is needed
// in the BuildTree function.
return;
}
// Centroids of triangles are used for splitting a mesh. The centroids
// are projected onto a splitting axis and sorted. The split is based
// on the median of the projections.
int numTriangles = mMesh->GetNumTriangles();
APoint* centroids = new1<APoint>(numTriangles);
const float oneThird = 1.0f/3.0f;
int t, i;
for (t = 0, i = 0; t < numTriangles; ++t)
{
APoint vertex[3];
mMesh->GetModelTriangle(t, vertex);
centroids[t] = oneThird*(vertex[0] + vertex[1] + vertex[2]);
}
// Initialize binary-tree arrays for storing triangle indices. These
// are used to store the indices when the mesh is split.
int* inSplit = new1<int>(numTriangles);
int* outSplit = new1<int>(numTriangles);
for (t = 0; t < numTriangles; ++t)
{
inSplit[t] = t;
}
BuildTree(maxTrisPerLeaf, storeInteriorTris, centroids, 0, numTriangles-1,
inSplit, outSplit);
delete1(centroids);
delete1(inSplit);
delete1(outSplit);
}
//----------------------------------------------------------------------------
template <class Mesh, class Bound>
BoundTree<Mesh,Bound>::~BoundTree ()
{
delete0(mLChild);
delete0(mRChild);
delete1(mTriangles);
}
//----------------------------------------------------------------------------
template <class Mesh, class Bound>
inline BoundTree<Mesh,Bound>* BoundTree<Mesh,Bound>::GetLChild ()
{
return mLChild;
}
//----------------------------------------------------------------------------
template <class Mesh, class Bound>
inline BoundTree<Mesh,Bound>* BoundTree<Mesh,Bound>::GetRChild ()
{
return mRChild;
}
//----------------------------------------------------------------------------
template <class Mesh, class Bound>
inline bool BoundTree<Mesh,Bound>::IsInteriorNode () const
{
return mLChild || mRChild;
}
//----------------------------------------------------------------------------
template <class Mesh, class Bound>
inline bool BoundTree<Mesh,Bound>::IsLeafNode () const
{
return !mLChild && !mRChild;
}
//----------------------------------------------------------------------------
template <class Mesh, class Bound>
inline Mesh* BoundTree<Mesh,Bound>::GetMesh () const
{
// The mesh geometry and topology cannot change, but other members might
// need to be modified for the collision response.
return (Mesh*)mMesh;
}
//----------------------------------------------------------------------------
template <class Mesh, class Bound>
inline const Bound& BoundTree<Mesh,Bound>::GetWorldBound () const
{
return mWorldBound;
}
//----------------------------------------------------------------------------
template <class Mesh, class Bound>
inline int BoundTree<Mesh,Bound>::GetNumTriangles () const
{
return mNumTriangles;
}
//----------------------------------------------------------------------------
template <class Mesh, class Bound>
inline int BoundTree<Mesh,Bound>::GetTriangle (int i) const
{
return mTriangles[i];
}
//----------------------------------------------------------------------------
template <class Mesh, class Bound>
inline const int* BoundTree<Mesh,Bound>::GetTriangles () const
{
return mTriangles;
}
//----------------------------------------------------------------------------
template <class Mesh, class Bound>
void BoundTree<Mesh,Bound>::UpdateWorldBound ()
{
mModelBound.TransformBy(mMesh->GetWorldTransform(), mWorldBound);
}
//----------------------------------------------------------------------------
template <class Mesh, class Bound>
void BoundTree<Mesh,Bound>::BuildTree (int maxTrisPerLeaf,
bool storeInteriorTris, const APoint* centroids, int i0, int i1,
int* inSplit, int* outSplit)
{
assertion(i0 <= i1, "Invalid index ordering\n");
APoint origin;
AVector direction;
CreateModelBound(i0, i1, inSplit, origin, direction);
if (i1 - i0 < maxTrisPerLeaf)
{
// At a leaf node.
mNumTriangles = i1 - i0 + 1;
mTriangles = new1<int>(mNumTriangles);
memcpy(mTriangles, &inSplit[i0], mNumTriangles*sizeof(int));
mLChild = 0;
mRChild = 0;
}
else
{
// At an interior node.
if (storeInteriorTris)
{
mNumTriangles = i1 - i0 + 1;
mTriangles = new1<int>(mNumTriangles);
memcpy(mTriangles, &inSplit[i0], mNumTriangles*sizeof(int));
}
else
{
mNumTriangles = 0;
mTriangles = 0;
}
int j0, j1;
SplitTriangles(centroids, i0, i1, inSplit, j0, j1, outSplit, origin,
direction);
mLChild = new0 BoundTree(mMesh, 0, false);
mLChild->BuildTree(maxTrisPerLeaf, storeInteriorTris, centroids,
i0, j0, outSplit, inSplit);
mRChild = new0 BoundTree(mMesh, 0, false);
mRChild->BuildTree(maxTrisPerLeaf, storeInteriorTris, centroids,
j1, i1, outSplit, inSplit);
}
}
//----------------------------------------------------------------------------
template <class Mesh, class Bound>
void BoundTree<Mesh,Bound>::CreateModelBound (int i0, int i1, int* inSplit,
APoint& origin, AVector& direction)
{
// Tag vertices that are used in the submesh.
int numVertices = mMesh->GetNumVertices();
int* valid = new1<int>(numVertices);
memset(valid, 0, numVertices*sizeof(int));
int i;
for (i = i0; i <= i1; ++i)
{
int v0, v1, v2;
mMesh->GetTriangle(inSplit[i], v0, v1, v2);
valid[v0] = 1;
valid[v1] = 1;
valid[v2] = 1;
}
// Create a contiguous set of vertices in the submesh.
std::vector<Float3> meshVertices;
for (i = 0; i < numVertices; ++i)
{
if (valid[i])
{
meshVertices.push_back(mMesh->GetPosition(i));
}
}
delete1(valid);
// Compute the bound for the submesh.
int numSubvertices = (int)meshVertices.size();
mModelBound.ComputeFromData(numSubvertices, 3*sizeof(float),
(const char*)&meshVertices[0]);
// Compute a splitting line for the submesh.
Line3f line = OrthogonalLineFit3<float>(numSubvertices,
(const Vector3f*)&meshVertices[0]);
origin = APoint(line.Origin);
direction = AVector(line.Direction);
}
//----------------------------------------------------------------------------
template <class Mesh, class Bound>
void BoundTree<Mesh,Bound>::SplitTriangles (const APoint* centroids,
int i0, int i1, int* inSplit, int& j0, int& j1, int* outSplit,
const APoint& origin, const AVector& direction)
{
// Project onto specified line.
int quantity = i1 - i0 + 1;
std::vector<ProjectionInfo> info(quantity);
int i, k;
for (i = i0, k = 0; i <= i1; ++i, ++k)
{
int triangle = inSplit[i];
AVector diff = centroids[triangle] - origin;
info[k].Triangle = triangle;
info[k].Projection = direction.Dot(diff);
}
// Find median of projections by sorting.
std::sort(info.begin(), info.end());
int median = (quantity - 1)/2;
// Partition the triangles by the median.
for (k = 0, j0 = i0 - 1; k <= median; ++k)
{
outSplit[++j0] = info[k].Triangle;
}
for (j1 = i1 + 1; k < quantity; ++k)
{
outSplit[--j1] = info[k].Triangle;
}
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// BoundTree::ProjectionInfo
//----------------------------------------------------------------------------
template <class Mesh, class Bound>
BoundTree<Mesh,Bound>::ProjectionInfo::ProjectionInfo ()
:
Triangle(0),
Projection(0.0f)
{
}
//----------------------------------------------------------------------------
template <class Mesh, class Bound>
bool BoundTree<Mesh,Bound>::ProjectionInfo::operator< (
const ProjectionInfo& info) const
{
return Projection < info.Projection;
}
//----------------------------------------------------------------------------
|