Use the add support for double and float triangle vertices. If it has a bad impact on performance, we can hide it behind an #ifdef for double precision vertex support.

Fix btConvexTriangleMeshShape::calculatePrincipalAxisTransform
Both thanks to Ole.

Use our own union to extract a scalar value from an SSE intrinsic (instead of relying on MSVC-only m128_u32
Thanks to BlindSide
This commit is contained in:
erwin.coumans
2008-10-27 21:36:36 +00:00
parent 876009b053
commit 1ff6420ffb
4 changed files with 71 additions and 30 deletions

View File

@@ -568,6 +568,8 @@ DBVT_INLINE btScalar Proximity( const btDbvtAabbMm& a,
return(btFabs(d.x())+btFabs(d.y())+btFabs(d.z())); return(btFabs(d.x())+btFabs(d.y())+btFabs(d.z()));
} }
// //
DBVT_INLINE int Select( const btDbvtAabbMm& o, DBVT_INLINE int Select( const btDbvtAabbMm& o,
const btDbvtAabbMm& a, const btDbvtAabbMm& a,
@@ -577,6 +579,14 @@ DBVT_INLINE int Select( const btDbvtAabbMm& o,
static DBVT_ALIGN const unsigned __int32 mask[]={0x7fffffff,0x7fffffff,0x7fffffff,0x7fffffff}; static DBVT_ALIGN const unsigned __int32 mask[]={0x7fffffff,0x7fffffff,0x7fffffff,0x7fffffff};
// TODO: the intrinsic version is 11% slower // TODO: the intrinsic version is 11% slower
#if DBVT_USE_INTRINSIC_SSE #if DBVT_USE_INTRINSIC_SSE
union btSSEUnion ///NOTE: if we use more intrinsics, move btSSEUnion into the LinearMath directory
{
__m128 ssereg;
float floats[4];
int ints[4];
};
__m128 omi(_mm_load_ps(o.mi)); __m128 omi(_mm_load_ps(o.mi));
omi=_mm_add_ps(omi,_mm_load_ps(o.mx)); omi=_mm_add_ps(omi,_mm_load_ps(o.mx));
__m128 ami(_mm_load_ps(a.mi)); __m128 ami(_mm_load_ps(a.mi));
@@ -590,10 +600,14 @@ DBVT_INLINE int Select( const btDbvtAabbMm& o,
__m128 t0(_mm_movehl_ps(ami,ami)); __m128 t0(_mm_movehl_ps(ami,ami));
ami=_mm_add_ps(ami,t0); ami=_mm_add_ps(ami,t0);
ami=_mm_add_ss(ami,_mm_shuffle_ps(ami,ami,1)); ami=_mm_add_ss(ami,_mm_shuffle_ps(ami,ami,1));
__m128 t1(_mm_movehl_ps(bmi,bmi)); __m128 t1(_mm_movehl_ps(bmi,bmi));
bmi=_mm_add_ps(bmi,t1); bmi=_mm_add_ps(bmi,t1);
bmi=_mm_add_ss(bmi,_mm_shuffle_ps(bmi,bmi,1)); bmi=_mm_add_ss(bmi,_mm_shuffle_ps(bmi,bmi,1));
return(_mm_cmple_ss(bmi,ami).m128_u32[0]&1);
btSSEUnion tmp;
tmp.ssereg = _mm_cmple_ss(bmi,ami);
return tmp.ints[0]&1;
#else #else
DBVT_ALIGN __int32 r[1]; DBVT_ALIGN __int32 r[1];
__asm __asm

View File

@@ -143,10 +143,19 @@ void btBvhTriangleMeshShape::performRaycast (btTriangleCallback* callback, const
for (int j=2;j>=0;j--) for (int j=2;j>=0;j--)
{ {
int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j]; int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride); if (type == PHY_FLOAT)
{
m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ()); float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
}
else
{
double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
}
} }
/* Perform ray vs. triangle collision here */ /* Perform ray vs. triangle collision here */
@@ -204,9 +213,18 @@ void btBvhTriangleMeshShape::performConvexcast (btTriangleCallback* callback, co
{ {
int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j]; int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride); if (type == PHY_FLOAT)
{
float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ()); m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
}
else
{
double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
}
} }
/* Perform ray vs. triangle collision here */ /* Perform ray vs. triangle collision here */
@@ -281,12 +299,24 @@ void btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,co
#ifdef DEBUG_TRIANGLE_MESH #ifdef DEBUG_TRIANGLE_MESH
printf("%d ,",graphicsindex); printf("%d ,",graphicsindex);
#endif //DEBUG_TRIANGLE_MESH #endif //DEBUG_TRIANGLE_MESH
btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride); if (type == PHY_FLOAT)
{
float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
m_triangle[j] = btVector3(
graphicsbase[0]*meshScaling.getX(),
graphicsbase[1]*meshScaling.getY(),
graphicsbase[2]*meshScaling.getZ());
}
else
{
double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
m_triangle[j] = btVector3( m_triangle[j] = btVector3(
graphicsbase[0]*meshScaling.getX(), graphicsbase[0]*meshScaling.getX(),
graphicsbase[1]*meshScaling.getY(), graphicsbase[1]*meshScaling.getY(),
graphicsbase[2]*meshScaling.getZ()); graphicsbase[2]*meshScaling.getZ());
}
#ifdef DEBUG_TRIANGLE_MESH #ifdef DEBUG_TRIANGLE_MESH
printf("triangle vertices:%f,%f,%f\n",triangle[j].x(),triangle[j].y(),triangle[j].z()); printf("triangle vertices:%f,%f,%f\n",triangle[j].x(),triangle[j].y(),triangle[j].z());
#endif //DEBUG_TRIANGLE_MESH #endif //DEBUG_TRIANGLE_MESH

View File

@@ -269,15 +269,12 @@ void btConvexTriangleMeshShape::calculatePrincipalAxisTransform(btTransform& pri
btVector3 a = triangle[0] - center; btVector3 a = triangle[0] - center;
btVector3 b = triangle[1] - center; btVector3 b = triangle[1] - center;
btVector3 c = triangle[2] - center; btVector3 c = triangle[2] - center;
btVector3 abc = a + b + c;
btScalar volNeg = -btFabs(a.triple(b, c)) * btScalar(1. / 6); btScalar volNeg = -btFabs(a.triple(b, c)) * btScalar(1. / 6);
for (int j = 0; j < 3; j++) for (int j = 0; j < 3; j++)
{ {
for (int k = 0; k <= j; k++) for (int k = 0; k <= j; k++)
{ {
i[j][k] = i[k][j] = volNeg * (center[j] * center[k] i[j][k] = i[k][j] = volNeg * (btScalar(0.1) * (a[j] * a[k] + b[j] * b[k] + c[j] * c[k])
+ btScalar(0.25) * (center[j] * abc[k] + center[k] * abc[j])
+ btScalar(0.1) * (a[j] * a[k] + b[j] * b[k] + c[j] * c[k])
+ btScalar(0.05) * (a[j] * b[k] + a[k] * b[j] + a[j] * c[k] + a[k] * c[j] + b[j] * c[k] + b[k] * c[j])); + btScalar(0.05) * (a[j] * b[k] + a[k] * b[j] + a[j] * c[k] + a[k] * c[j] + b[j] * c[k] + b[k] * c[j]));
} }
} }

View File

@@ -319,19 +319,19 @@ void btOptimizedBvh::updateBvhNodes(btStridingMeshInterface* meshInterface,int f
{ {
int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j]; int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride); if (type == PHY_FLOAT)
#ifdef DEBUG_PATCH_COLORS {
btVector3 mycolor = color[index&3]; float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
graphicsbase[8] = mycolor.getX(); triangleVerts[j] = btVector3(
graphicsbase[9] = mycolor.getY(); graphicsbase[0]*meshScaling.getX(),
graphicsbase[10] = mycolor.getZ(); graphicsbase[1]*meshScaling.getY(),
#endif //DEBUG_PATCH_COLORS graphicsbase[2]*meshScaling.getZ());
}
else
triangleVerts[j] = btVector3( {
graphicsbase[0]*meshScaling.getX(), double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
graphicsbase[1]*meshScaling.getY(), triangleVerts[j] = btVector3( btScalar(graphicsbase[0]*meshScaling.getX()), btScalar(graphicsbase[1]*meshScaling.getY()), btScalar(graphicsbase[2]*meshScaling.getZ()));
graphicsbase[2]*meshScaling.getZ()); }
} }