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 "btConvexHullShape.h"
17 #include "BulletCollision/CollisionShapes/btCollisionMargin.h"
18 
19 #include "LinearMath/btQuaternion.h"
20 #include "LinearMath/btSerializer.h"
21 
btConvexHullShape(const btScalar * points,int numPoints,int stride)22 btConvexHullShape ::btConvexHullShape (const btScalar* points,int numPoints,int stride) : btPolyhedralConvexAabbCachingShape ()
23 {
24 	m_shapeType = CONVEX_HULL_SHAPE_PROXYTYPE;
25 	m_unscaledPoints.resize(numPoints);
26 
27 	unsigned char* pointsAddress = (unsigned char*)points;
28 
29 	for (int i=0;i<numPoints;i++)
30 	{
31 		btScalar* point = (btScalar*)pointsAddress;
32 		m_unscaledPoints[i] = btVector3(point[0], point[1], point[2]);
33 		pointsAddress += stride;
34 	}
35 
36 	recalcLocalAabb();
37 
38 }
39 
40 
41 
setLocalScaling(const btVector3 & scaling)42 void btConvexHullShape::setLocalScaling(const btVector3& scaling)
43 {
44 	m_localScaling = scaling;
45 	recalcLocalAabb();
46 }
47 
addPoint(const btVector3 & point)48 void btConvexHullShape::addPoint(const btVector3& point)
49 {
50 	m_unscaledPoints.push_back(point);
51 	recalcLocalAabb();
52 
53 }
54 
localGetSupportingVertexWithoutMargin(const btVector3 & vec0) const55 btVector3	btConvexHullShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
56 {
57 	btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.));
58 	btScalar newDot,maxDot = btScalar(-BT_LARGE_FLOAT);
59 
60 	btVector3 vec = vec0;
61 	btScalar lenSqr = vec.length2();
62 	if (lenSqr < btScalar(0.0001))
63 	{
64 		vec.setValue(1,0,0);
65 	} else
66 	{
67 		btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
68 		vec *= rlen;
69 	}
70 
71 
72 	for (int i=0;i<m_unscaledPoints.size();i++)
73 	{
74 		btVector3 vtx = m_unscaledPoints[i] * m_localScaling;
75 
76 		newDot = vec.dot(vtx);
77 		if (newDot > maxDot)
78 		{
79 			maxDot = newDot;
80 			supVec = vtx;
81 		}
82 	}
83 	return supVec;
84 }
85 
batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3 * vectors,btVector3 * supportVerticesOut,int numVectors) const86 void	btConvexHullShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
87 {
88 	btScalar newDot;
89 	//use 'w' component of supportVerticesOut?
90 	{
91 		for (int i=0;i<numVectors;i++)
92 		{
93 			supportVerticesOut[i][3] = btScalar(-BT_LARGE_FLOAT);
94 		}
95 	}
96 	for (int i=0;i<m_unscaledPoints.size();i++)
97 	{
98 		btVector3 vtx = getScaledPoint(i);
99 
100 		for (int j=0;j<numVectors;j++)
101 		{
102 			const btVector3& vec = vectors[j];
103 
104 			newDot = vec.dot(vtx);
105 			if (newDot > supportVerticesOut[j][3])
106 			{
107 				//WARNING: don't swap next lines, the w component would get overwritten!
108 				supportVerticesOut[j] = vtx;
109 				supportVerticesOut[j][3] = newDot;
110 			}
111 		}
112 	}
113 
114 
115 
116 }
117 
118 
119 
localGetSupportingVertex(const btVector3 & vec) const120 btVector3	btConvexHullShape::localGetSupportingVertex(const btVector3& vec)const
121 {
122 	btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec);
123 
124 	if ( getMargin()!=btScalar(0.) )
125 	{
126 		btVector3 vecnorm = vec;
127 		if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
128 		{
129 			vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
130 		}
131 		vecnorm.normalize();
132 		supVertex+= getMargin() * vecnorm;
133 	}
134 	return supVertex;
135 }
136 
137 
138 
139 
140 
141 
142 
143 
144 
145 //currently just for debugging (drawing), perhaps future support for algebraic continuous collision detection
146 //Please note that you can debug-draw btConvexHullShape with the Raytracer Demo
getNumVertices() const147 int	btConvexHullShape::getNumVertices() const
148 {
149 	return m_unscaledPoints.size();
150 }
151 
getNumEdges() const152 int btConvexHullShape::getNumEdges() const
153 {
154 	return m_unscaledPoints.size();
155 }
156 
getEdge(int i,btVector3 & pa,btVector3 & pb) const157 void btConvexHullShape::getEdge(int i,btVector3& pa,btVector3& pb) const
158 {
159 
160 	int index0 = i%m_unscaledPoints.size();
161 	int index1 = (i+1)%m_unscaledPoints.size();
162 	pa = getScaledPoint(index0);
163 	pb = getScaledPoint(index1);
164 }
165 
getVertex(int i,btVector3 & vtx) const166 void btConvexHullShape::getVertex(int i,btVector3& vtx) const
167 {
168 	vtx = getScaledPoint(i);
169 }
170 
getNumPlanes() const171 int	btConvexHullShape::getNumPlanes() const
172 {
173 	return 0;
174 }
175 
getPlane(btVector3 &,btVector3 &,int) const176 void btConvexHullShape::getPlane(btVector3& ,btVector3& ,int ) const
177 {
178 
179 	btAssert(0);
180 }
181 
182 //not yet
isInside(const btVector3 &,btScalar) const183 bool btConvexHullShape::isInside(const btVector3& ,btScalar ) const
184 {
185 	btAssert(0);
186 	return false;
187 }
188 
189 ///fills the dataBuffer and returns the struct name (and 0 on failure)
serialize(void * dataBuffer,btSerializer * serializer) const190 const char*	btConvexHullShape::serialize(void* dataBuffer, btSerializer* serializer) const
191 {
192 	//int szc = sizeof(btConvexHullShapeData);
193 	btConvexHullShapeData* shapeData = (btConvexHullShapeData*) dataBuffer;
194 	btConvexInternalShape::serialize(&shapeData->m_convexInternalShapeData, serializer);
195 
196 	int numElem = m_unscaledPoints.size();
197 	shapeData->m_numUnscaledPoints = numElem;
198 #ifdef BT_USE_DOUBLE_PRECISION
199 	shapeData->m_unscaledPointsFloatPtr = 0;
200 	shapeData->m_unscaledPointsDoublePtr = numElem ? (btVector3Data*)serializer->getUniquePointer((void*)&m_unscaledPoints[0]):  0;
201 #else
202 	shapeData->m_unscaledPointsFloatPtr = numElem ? (btVector3Data*)serializer->getUniquePointer((void*)&m_unscaledPoints[0]):  0;
203 	shapeData->m_unscaledPointsDoublePtr = 0;
204 #endif
205 
206 	if (numElem)
207 	{
208 		int sz = sizeof(btVector3Data);
209 	//	int sz2 = sizeof(btVector3DoubleData);
210 	//	int sz3 = sizeof(btVector3FloatData);
211 		btChunk* chunk = serializer->allocate(sz,numElem);
212 		btVector3Data* memPtr = (btVector3Data*)chunk->m_oldPtr;
213 		for (int i=0;i<numElem;i++,memPtr++)
214 		{
215 			m_unscaledPoints[i].serialize(*memPtr);
216 		}
217 		serializer->finalizeChunk(chunk,btVector3DataName,BT_ARRAY_CODE,(void*)&m_unscaledPoints[0]);
218 	}
219 
220 	return "btConvexHullShapeData";
221 }
222 
223 
224