34 btVector3 point, normal;
39 btTransform sphereInTr = transformB.inverseTimes(transformA);
41 if (
collide(sphereInTr.getOrigin(), point, normal, depth, timeOfImpact, m_contactBreakingThreshold))
45 btVector3 normalOnB = transformB.getBasis() * normal;
46 btVector3 normalOnA = -normalOnB;
47 btVector3 pointOnA = transformB * point + normalOnB * depth;
48 output.addContactPoint(normalOnA, pointOnA, depth);
52 output.addContactPoint(transformB.getBasis() * normal, transformB * point, depth);
64 btVector3
v = to -
from;
84 nearest =
from + t *
v;
88bool SphereTriangleDetector::facecontains(
const btVector3& p,
const btVector3* vertices, btVector3& normal)
91 btVector3 lnormal(normal);
93 return pointInTriangle(vertices, lnormal, &lp);
98 const btVector3* vertices = &m_triangle->getVertexPtr(0);
100 btScalar radius = m_sphere->getRadius();
101 btScalar radiusWithThreshold = radius + contactBreakingThreshold;
103 btVector3 normal = (vertices[1] - vertices[0]).
cross(vertices[2] - vertices[0]);
106 bool hasContact =
false;
107 btVector3 contactPoint;
113 btVector3 p1ToCentre = sphereCenter - vertices[0];
114 btScalar distanceFromPlane = p1ToCentre.dot(normal);
116 if (distanceFromPlane <
btScalar(0.))
123 bool isInsideContactPlane = distanceFromPlane < radiusWithThreshold;
127 if (isInsideContactPlane)
129 if (facecontains(sphereCenter, vertices, normal))
133 contactPoint = sphereCenter - normal * distanceFromPlane;
138 btScalar contactCapsuleRadiusSqr = radiusWithThreshold * radiusWithThreshold;
139 btScalar minDistSqr = contactCapsuleRadiusSqr;
140 btVector3 nearestOnEdge;
141 for (
int i = 0; i < m_triangle->getNumEdges(); i++)
146 m_triangle->getEdge(i, pa, pb);
149 if (distanceSqr < minDistSqr)
152 minDistSqr = distanceSqr;
154 contactPoint = nearestOnEdge;
163 btVector3 contactToCentre = sphereCenter - contactPoint;
164 btScalar distanceSqr = contactToCentre.length2();
166 if (distanceSqr < radiusWithThreshold * radiusWithThreshold)
171 resultNormal = contactToCentre;
172 resultNormal.normalize();
173 point = contactPoint;
178 resultNormal = normal;
179 point = contactPoint;
189bool SphereTriangleDetector::pointInTriangle(
const btVector3 vertices[],
const btVector3& normal, btVector3* p)
191 const btVector3* p1 = &vertices[0];
192 const btVector3* p2 = &vertices[1];
193 const btVector3* p3 = &vertices[2];
195 btVector3 edge1(*p2 - *p1);
196 btVector3 edge2(*p3 - *p2);
197 btVector3 edge3(*p1 - *p3);
199 btVector3 p1_to_p(*p - *p1);
200 btVector3 p2_to_p(*p - *p2);
201 btVector3 p3_to_p(*p - *p3);
203 btVector3 edge1_normal(edge1.cross(normal));
204 btVector3 edge2_normal(edge2.cross(normal));
205 btVector3 edge3_normal(edge3.cross(normal));
208 r1 = edge1_normal.dot(p1_to_p);
209 r2 = edge2_normal.dot(p2_to_p);
210 r3 = edge3_normal.dot(p3_to_p);
211 if ((r1 > 0 && r2 > 0 && r3 > 0) ||
212 (r1 <= 0 && r2 <= 0 && r3 <= 0))
btScalar SegmentSqrDistance(const btVector3 &from, const btVector3 &to, const btVector3 &p, btVector3 &nearest)
ATTR_WARN_UNUSED_RESULT const BMVert * v
void debugDraw(btIDebugDraw *debugDrawer)
btActionInterface interface
btScalar m_contactBreakingThreshold
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
SIMD_FORCE_INLINE btScalar btSqrt(btScalar y)
btSphereShape(btScalar radius)
IMETHOD Vector diff(const Vector &a, const Vector &b, double dt)
VecBase< float, 3 > cross(VecOp< float, 3 >, VecOp< float, 3 >) RET
float distance(VecOp< float, D >, VecOp< float, D >) RET
bool collide(const btVector3 &sphereCenter, btVector3 &point, btVector3 &resultNormal, btScalar &depth, btScalar &timeOfImpact, btScalar contactBreakingThreshold)
SphereTriangleDetector(btSphereShape *sphere, btTriangleShape *triangle, btScalar contactBreakingThreshold)
virtual void getClosestPoints(const ClosestPointInput &input, Result &output, class btIDebugDraw *debugDraw, bool swapResults=false)