1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org
4
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
10
11 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15
16 #include "b3StridingMeshInterface.h"
17
~b3StridingMeshInterface()18 b3StridingMeshInterface::~b3StridingMeshInterface()
19 {
20 }
21
InternalProcessAllTriangles(b3InternalTriangleIndexCallback * callback,const b3Vector3 & aabbMin,const b3Vector3 & aabbMax) const22 void b3StridingMeshInterface::InternalProcessAllTriangles(b3InternalTriangleIndexCallback* callback, const b3Vector3& aabbMin, const b3Vector3& aabbMax) const
23 {
24 (void)aabbMin;
25 (void)aabbMax;
26 int numtotalphysicsverts = 0;
27 int part, graphicssubparts = getNumSubParts();
28 const unsigned char* vertexbase;
29 const unsigned char* indexbase;
30 int indexstride;
31 PHY_ScalarType type;
32 PHY_ScalarType gfxindextype;
33 int stride, numverts, numtriangles;
34 int gfxindex;
35 b3Vector3 triangle[3];
36
37 b3Vector3 meshScaling = getScaling();
38
39 ///if the number of parts is big, the performance might drop due to the innerloop switch on indextype
40 for (part = 0; part < graphicssubparts; part++)
41 {
42 getLockedReadOnlyVertexIndexBase(&vertexbase, numverts, type, stride, &indexbase, indexstride, numtriangles, gfxindextype, part);
43 numtotalphysicsverts += numtriangles * 3; //upper bound
44
45 ///unlike that developers want to pass in double-precision meshes in single-precision Bullet build
46 ///so disable this feature by default
47 ///see patch http://code.google.com/p/bullet/issues/detail?id=213
48
49 switch (type)
50 {
51 case PHY_FLOAT:
52 {
53 float* graphicsbase;
54
55 switch (gfxindextype)
56 {
57 case PHY_INTEGER:
58 {
59 for (gfxindex = 0; gfxindex < numtriangles; gfxindex++)
60 {
61 unsigned int* tri_indices = (unsigned int*)(indexbase + gfxindex * indexstride);
62 graphicsbase = (float*)(vertexbase + tri_indices[0] * stride);
63 triangle[0].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ());
64 graphicsbase = (float*)(vertexbase + tri_indices[1] * stride);
65 triangle[1].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ());
66 graphicsbase = (float*)(vertexbase + tri_indices[2] * stride);
67 triangle[2].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ());
68 callback->internalProcessTriangleIndex(triangle, part, gfxindex);
69 }
70 break;
71 }
72 case PHY_SHORT:
73 {
74 for (gfxindex = 0; gfxindex < numtriangles; gfxindex++)
75 {
76 unsigned short int* tri_indices = (unsigned short int*)(indexbase + gfxindex * indexstride);
77 graphicsbase = (float*)(vertexbase + tri_indices[0] * stride);
78 triangle[0].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ());
79 graphicsbase = (float*)(vertexbase + tri_indices[1] * stride);
80 triangle[1].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ());
81 graphicsbase = (float*)(vertexbase + tri_indices[2] * stride);
82 triangle[2].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ());
83 callback->internalProcessTriangleIndex(triangle, part, gfxindex);
84 }
85 break;
86 }
87 case PHY_UCHAR:
88 {
89 for (gfxindex = 0; gfxindex < numtriangles; gfxindex++)
90 {
91 unsigned char* tri_indices = (unsigned char*)(indexbase + gfxindex * indexstride);
92 graphicsbase = (float*)(vertexbase + tri_indices[0] * stride);
93 triangle[0].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ());
94 graphicsbase = (float*)(vertexbase + tri_indices[1] * stride);
95 triangle[1].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ());
96 graphicsbase = (float*)(vertexbase + tri_indices[2] * stride);
97 triangle[2].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ());
98 callback->internalProcessTriangleIndex(triangle, part, gfxindex);
99 }
100 break;
101 }
102 default:
103 b3Assert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT));
104 }
105 break;
106 }
107
108 case PHY_DOUBLE:
109 {
110 double* graphicsbase;
111
112 switch (gfxindextype)
113 {
114 case PHY_INTEGER:
115 {
116 for (gfxindex = 0; gfxindex < numtriangles; gfxindex++)
117 {
118 unsigned int* tri_indices = (unsigned int*)(indexbase + gfxindex * indexstride);
119 graphicsbase = (double*)(vertexbase + tri_indices[0] * stride);
120 triangle[0].setValue((b3Scalar)graphicsbase[0] * meshScaling.getX(), (b3Scalar)graphicsbase[1] * meshScaling.getY(), (b3Scalar)graphicsbase[2] * meshScaling.getZ());
121 graphicsbase = (double*)(vertexbase + tri_indices[1] * stride);
122 triangle[1].setValue((b3Scalar)graphicsbase[0] * meshScaling.getX(), (b3Scalar)graphicsbase[1] * meshScaling.getY(), (b3Scalar)graphicsbase[2] * meshScaling.getZ());
123 graphicsbase = (double*)(vertexbase + tri_indices[2] * stride);
124 triangle[2].setValue((b3Scalar)graphicsbase[0] * meshScaling.getX(), (b3Scalar)graphicsbase[1] * meshScaling.getY(), (b3Scalar)graphicsbase[2] * meshScaling.getZ());
125 callback->internalProcessTriangleIndex(triangle, part, gfxindex);
126 }
127 break;
128 }
129 case PHY_SHORT:
130 {
131 for (gfxindex = 0; gfxindex < numtriangles; gfxindex++)
132 {
133 unsigned short int* tri_indices = (unsigned short int*)(indexbase + gfxindex * indexstride);
134 graphicsbase = (double*)(vertexbase + tri_indices[0] * stride);
135 triangle[0].setValue((b3Scalar)graphicsbase[0] * meshScaling.getX(), (b3Scalar)graphicsbase[1] * meshScaling.getY(), (b3Scalar)graphicsbase[2] * meshScaling.getZ());
136 graphicsbase = (double*)(vertexbase + tri_indices[1] * stride);
137 triangle[1].setValue((b3Scalar)graphicsbase[0] * meshScaling.getX(), (b3Scalar)graphicsbase[1] * meshScaling.getY(), (b3Scalar)graphicsbase[2] * meshScaling.getZ());
138 graphicsbase = (double*)(vertexbase + tri_indices[2] * stride);
139 triangle[2].setValue((b3Scalar)graphicsbase[0] * meshScaling.getX(), (b3Scalar)graphicsbase[1] * meshScaling.getY(), (b3Scalar)graphicsbase[2] * meshScaling.getZ());
140 callback->internalProcessTriangleIndex(triangle, part, gfxindex);
141 }
142 break;
143 }
144 case PHY_UCHAR:
145 {
146 for (gfxindex = 0; gfxindex < numtriangles; gfxindex++)
147 {
148 unsigned char* tri_indices = (unsigned char*)(indexbase + gfxindex * indexstride);
149 graphicsbase = (double*)(vertexbase + tri_indices[0] * stride);
150 triangle[0].setValue((b3Scalar)graphicsbase[0] * meshScaling.getX(), (b3Scalar)graphicsbase[1] * meshScaling.getY(), (b3Scalar)graphicsbase[2] * meshScaling.getZ());
151 graphicsbase = (double*)(vertexbase + tri_indices[1] * stride);
152 triangle[1].setValue((b3Scalar)graphicsbase[0] * meshScaling.getX(), (b3Scalar)graphicsbase[1] * meshScaling.getY(), (b3Scalar)graphicsbase[2] * meshScaling.getZ());
153 graphicsbase = (double*)(vertexbase + tri_indices[2] * stride);
154 triangle[2].setValue((b3Scalar)graphicsbase[0] * meshScaling.getX(), (b3Scalar)graphicsbase[1] * meshScaling.getY(), (b3Scalar)graphicsbase[2] * meshScaling.getZ());
155 callback->internalProcessTriangleIndex(triangle, part, gfxindex);
156 }
157 break;
158 }
159 default:
160 b3Assert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT));
161 }
162 break;
163 }
164 default:
165 b3Assert((type == PHY_FLOAT) || (type == PHY_DOUBLE));
166 }
167
168 unLockReadOnlyVertexBase(part);
169 }
170 }
171
calculateAabbBruteForce(b3Vector3 & aabbMin,b3Vector3 & aabbMax)172 void b3StridingMeshInterface::calculateAabbBruteForce(b3Vector3& aabbMin, b3Vector3& aabbMax)
173 {
174 struct AabbCalculationCallback : public b3InternalTriangleIndexCallback
175 {
176 b3Vector3 m_aabbMin;
177 b3Vector3 m_aabbMax;
178
179 AabbCalculationCallback()
180 {
181 m_aabbMin.setValue(b3Scalar(B3_LARGE_FLOAT), b3Scalar(B3_LARGE_FLOAT), b3Scalar(B3_LARGE_FLOAT));
182 m_aabbMax.setValue(b3Scalar(-B3_LARGE_FLOAT), b3Scalar(-B3_LARGE_FLOAT), b3Scalar(-B3_LARGE_FLOAT));
183 }
184
185 virtual void internalProcessTriangleIndex(b3Vector3* triangle, int partId, int triangleIndex)
186 {
187 (void)partId;
188 (void)triangleIndex;
189
190 m_aabbMin.setMin(triangle[0]);
191 m_aabbMax.setMax(triangle[0]);
192 m_aabbMin.setMin(triangle[1]);
193 m_aabbMax.setMax(triangle[1]);
194 m_aabbMin.setMin(triangle[2]);
195 m_aabbMax.setMax(triangle[2]);
196 }
197 };
198
199 //first calculate the total aabb for all triangles
200 AabbCalculationCallback aabbCallback;
201 aabbMin.setValue(b3Scalar(-B3_LARGE_FLOAT), b3Scalar(-B3_LARGE_FLOAT), b3Scalar(-B3_LARGE_FLOAT));
202 aabbMax.setValue(b3Scalar(B3_LARGE_FLOAT), b3Scalar(B3_LARGE_FLOAT), b3Scalar(B3_LARGE_FLOAT));
203 InternalProcessAllTriangles(&aabbCallback, aabbMin, aabbMax);
204
205 aabbMin = aabbCallback.m_aabbMin;
206 aabbMax = aabbCallback.m_aabbMax;
207 }
208