27 #ifdef PFX_USE_FREE_VECTORMATH
28 #include "vecmath/vmInclude.h"
31 #endif //PFX_USE_FREE_VECTORMATH
47 #define TMP_BUFF_BYTES (15*1024*1024)
111 vmVector3 dVA = deltaLinearVelocityA +
cross(deltaAngularVelocityA,rA);
112 vmVector3 dVB = deltaLinearVelocityB +
cross(deltaAngularVelocityB,rB);
117 deltaLinearVelocityA += deltaImpulse * massInvA * normal;
118 deltaAngularVelocityA += deltaImpulse * inertiaInvA *
cross(rA,normal);
119 deltaLinearVelocityB -= deltaImpulse * massInvB * normal;
120 deltaAngularVelocityB -= deltaImpulse * inertiaInvB *
cross(rB,normal);
178 for(
int k=0;k<iteration+1;k++) {
183 if(batchId%numTasks == taskId && numPairs > 0) {
191 PfxSolverBody &solverBodyA = iA != 65535 ? offsetSolverBodies[iA] : staticBody;
192 PfxSolverBody &solverBodyB = iB != 65535 ? offsetSolverBodies[iB] : staticBody;
201 for (i=0;i<numRows;i++)
218 if(batchId%numTasks == taskId && numPairs > 0) {
227 btConstraintRow* contactConstraintRows = &offsetContactConstraintRows[contactIndex*12];
258 contactConstraintRows[j*3],
259 contactConstraintRows[j*3+1],
260 contactConstraintRows[j*3+2],
284 for(
uint32_t i=0;i<numRigidBodies;i++) {
302 if(fabsf(n[2]) > 0.707f) {
304 float a = n[1]*n[1] + n[2]*n[2];
305 float k = 1.0f/sqrtf(a);
316 float a = n[0]*n[0] + n[1]*n[1];
317 float k = 1.0f/sqrtf(a);
330 #define PFX_CONTACT_SLOP 0.001f
336 float penetrationDepth,
365 vmVector3 vABrestitution = vArestitution-vBrestitution;
383 float denom =
dot(K*normal,normal);
385 constraintResponse.
m_rhs = -(1.0f+restitution)*
dot(vAB,normal);
387 constraintResponse.
m_rhs /= denom;
398 float denom =
dot(K*normal,normal);
401 constraintFriction1.
m_rhs = -
dot(vAB,normal);
412 float denom =
dot(K*normal,normal);
415 constraintFriction2.
m_rhs = -
dot(vAB,normal);
434 for(
uint32_t i=0;i<numContactPairs;i++) {
446 btConstraintRow* contactConstraintRows = &offsetContactConstraintRows[
id*12];
448 TrbState &stateA = offsetRigStates[iA];
452 TrbState &stateB = offsetRigStates[iB];
481 if (rbB && (rbB->getInvMass()>0.f))
483 linVelB = rbB->getLinearVelocity();
484 angVelB = rbB->getAngularVelocity();
494 contactConstraintRows[j*3],
495 contactConstraintRows[j*3+1],
496 contactConstraintRows[j*3+2],
529 for(
uint32_t i=0;i<numContactPairs;i++) {
537 btConstraintRow* contactConstraintRows = &offsetContactConstraintRows[
id*12];
593 criticalsection->
lock();
601 int nextStart = start + batch;
603 int nextBatch = (rest > batch)?batch:rest;
608 criticalsection->
unlock();
635 criticalsection->
lock();
643 int nextStart = start + batch;
645 int nextBatch = (rest > batch)?batch:rest;
650 criticalsection->
unlock();
687 float separationBias,
697 int div = (int)maxTasks * 4;
698 int batch = ((int)numContactPairs + div - 1) / div;
700 BulletPE2ConstraintSolverSpursSupport* spursThread = (BulletPE2ConstraintSolverSpursSupport*) threadSupport;
709 spursThread->setSharedParam(0,0);
710 spursThread->setSharedParam(1,
btMin(batch,64));
714 for(
int t=0;t<maxTasks;t++) {
728 io[t].
barrierAddr2 = (
unsigned int)spursThread->getBarrierAddress();
734 #ifdef SEQUENTIAL_SETUP
735 CustomSetupContactConstraintsTask(contactPairs1,numContactPairs,offsetContactManifolds,offsetRigStates,offsetSolverBodies,numRigidBodies,separationBias,timeStep);
741 #ifndef SEQUENTIAL_SETUP
742 unsigned int arg0,arg1;
743 for(
int t=0;t<maxTasks;t++) {
747 #endif //SEQUENTIAL_SETUP
761 HeapManager pool((
unsigned char*)poolBuff,poolBytes);
764 int bufSize =
sizeof(
uint8_t)*numRigidBodies;
765 bufSize = ((bufSize+127)>>7)<<7;
770 size_t allocSize =
sizeof(
uint32_t)*((numPairs+31)/32);
772 memset(pairTable,0,allocSize);
785 bool startIndexCheck =
true;
792 memset(bodyTable,0xff,bufSize);
794 for(batchId=0;i<numPairs&&totalCount<numPairs&&batchId<maxBatches;batchId++) {
800 for(;i<numPairs&&pairCount<targetCount;i++) {
805 if(pairTable[idxP] & maskP) {
818 pairTable[idxP] |= maskP;
824 if( (bodyTable[idxA] != batchId && bodyTable[idxA] != 0xff) ||
825 (bodyTable[idxB] != batchId && bodyTable[idxB] != 0xff) ) {
826 startIndexCheck =
false;
833 bodyTable[idxA] = batchId;
835 bodyTable[idxB] = batchId;
840 pairTable[idxP] |= maskP;
847 totalCount += pairCount;
881 HeapManager pool((
unsigned char*)poolBuf,poolBytes);
890 void *tmpBuff = pool.
allocate(tmpBytes);
894 CustomSplitConstraints(contactPairs,numContactPairs,*cgroup,cbatches,maxTasks,numRigidBodies,tmpBuff,tmpBytes);
895 CustomSplitConstraints(jointPairs,numJointPairs,*jgroup,jbatches,maxTasks,numRigidBodies,tmpBuff,tmpBytes);
899 BT_PROFILE(
"PFX_CONSTRAINT_SOLVER_CMD_SOLVE_CONSTRAINTS");
901 #ifdef SOLVE_SEQUENTIAL
902 CustomSolveConstraintsTask(
920 for(
int t=0;t<maxTasks;t++) {
942 BulletPE2ConstraintSolverSpursSupport* spursThread = (BulletPE2ConstraintSolverSpursSupport*) threadSupport;
943 io[t].
barrierAddr2 = (
unsigned int) spursThread->getBarrierAddress();
950 unsigned int arg0,arg1;
951 for(
int t=0;t<maxTasks;t++) {
961 BT_PROFILE(
"PFX_CONSTRAINT_SOLVER_CMD_POST_SOLVER");
962 int batch = ((int)numRigidBodies + maxTasks - 1) / maxTasks;
963 int rest = (int)numRigidBodies;
966 for(
int t=0;t<maxTasks;t++) {
967 int num = (rest - batch ) > 0 ? batch : rest;
974 BulletPE2ConstraintSolverSpursSupport* spursThread = (BulletPE2ConstraintSolverSpursSupport*) threadSupport;
975 io[t].
barrierAddr2 = (
unsigned int)spursThread->getBarrierAddress();
979 #ifdef SOLVE_SEQUENTIAL
988 unsigned int arg0,arg1;
989 for(
int t=0;t<maxTasks;t++) {
990 #ifndef SOLVE_SEQUENTIAL
1004 TrbState* states,
int numRigidBodies,
1021 for(
uint32_t i=0;i<numJoints;i++) {
1046 #ifdef SEQUENTIAL_SETUP
1047 CustomSetupContactConstraintsSeqNew(
1058 offsetContactManifolds,
1059 offsetContactConstraintRows,
1065 solverThreadSupport,
1066 criticalSection,solverIO,
1070 #endif //SEQUENTIAL_SETUP
1078 CustomSolveConstraintsSeq(
1080 jointPairs,numJoints,
1090 jointPairs,numJoints,
1091 offsetContactManifolds,
1092 offsetContactConstraintRows,
1093 offsetSolverConstraints,
1097 solverIO, solverThreadSupport,
1112 offsetContactManifolds,
1113 offsetContactConstraintRows,
1119 solverThreadSupport,
1120 criticalSection,solverIO,
1185 BT_PROFILE(
"create states and solver bodies");
1186 for (
int i=0;i<numRigidBodies;i++)
1247 int totalPoints = 0;
1248 #ifndef USE_C_ARRAYS
1253 #endif//USE_C_ARRAYS
1255 int actualNumManifolds= 0;
1258 for (
int i1=0;i1<numManifolds;i1++)
1260 if (manifoldPtr[i1]->getNumContacts()>0)
1268 if (!obAisActive && !obBisActive)
1296 totalPoints+=numPosPoints;
1304 int contactId = m-offsetContactManifolds;
1307 btAssert(contactId<dispatcher->getInternalManifoldPool()->getMaxCount());
1311 actualNumManifolds++;
1319 int actualNumJoints=0;
1330 int totalNumRows = 0;
1335 for (i=0;i<numConstraints;i++)
1348 for (i=0;i<numConstraints;i++)
1393 info2.
cfm = ¤tConstraintRow->
m_cfm;
1442 rel_vel = vel1Dotn+vel2Dotn;
1446 btScalar velocityError = restitution - rel_vel;
1449 solverConstraint.
m_rhs = penetrationImpulse+velocityImpulse;
1471 int id = currentConstraintRow-offsetSolverConstraints;
1484 float separateBias=0.1;
1496 int totalContacts =0;
1498 for (
int i=0;i<actualNumManifolds;i++)
1511 BT_PROFILE(
"BPE_customConstraintSolverSequentialNew");
1512 if (numRigidBodies>0 && (actualNumManifolds+actualNumJoints)>0)
1523 offsetContactManifolds,
1527 jointPairs,actualNumJoints,
1528 offsetSolverConstraints,
1529 separateBias,timeStep,iteration,
1537 for (
int i=0;i<numRigidBodies;i++)
btScalar * m_constraintError
btScalar getInvMass() const
static T sum(const btAlignedObjectArray< T > &items)
PfxConstraintPair * contactPairs
static const btRigidBody * upcast(const btCollisionObject *colObj)
to keep collision detection and dynamics separate we don't store a rigidbody pointer but a rigidbody ...
class btBarrier * barrier
class btThreadSupportInterface * m_solverThreadSupport
PfxParallelGroup * jointParallelGroup
uint16_t pairIndices[PFX_MAX_SOLVER_PAIRS]
void setAngularDamping(float damping)
void setOrientation(const vmQuat &rot)
PfxSolverBody * offsetSolverBodies
btPersistentManifold is a contact point cache, it stays persistent as long as objects are overlapping...
void CustomSolveConstraintsParallel(PfxConstraintPair *contactPairs, uint32_t numContactPairs, PfxConstraintPair *jointPairs, uint32_t numJointPairs, btPersistentManifold *offsetContactManifolds, btConstraintRow *offsetContactConstraintRows, btSolverConstraint *offsetSolverConstraints, TrbState *offsetRigStates, PfxSolverBody *offsetSolverBodies, uint32_t numRigidBodies, struct btConstraintSolverIO *io, class btThreadSupportInterface *threadSupport, int iteration, void *poolBuf, int poolBytes, class btBarrier *barrier)
void CustomWritebackContactConstraintsTask(PfxConstraintPair *contactPairs, uint32_t numContactPairs, btPersistentManifold *offsetContactManifolds, btConstraintRow *offsetContactConstraintRows, TrbState *offsetRigStates, PfxSolverBody *offsetSolverBodies, uint32_t numRigidBodies, float separateBias, float timeStep)
btScalar * m_J2angularAxis
static void pfxGetPlaneSpace(const vmVector3 &n, vmVector3 &p, vmVector3 &q)
#define PFX_MAX_SOLVER_PHASES
virtual void getInfo1(btConstraintInfo1 *info)=0
internal method used by the constraint solver, don't use them directly
void setAngularVelocity(const vmVector3 &vel)
virtual unsigned int getSharedParam(int i)=0
void CustomSetupContactConstraintsTask(PfxConstraintPair *contactPairs, uint32_t numContactPairs, btPersistentManifold *offsetContactManifolds, btConstraintRow *offsetContactConstraintRows, TrbState *offsetRigStates, PfxSolverBody *offsetSolverBodies, uint32_t numRigidBodies, float separateBias, float timeStep)
virtual btBarrier * createBarrier()=0
const btVector3 & getTotalForce() const
void CustomSetupContactConstraintsNew(PfxConstraintPair *contactPairs1, uint32_t numContactPairs, btPersistentManifold *offsetContactManifolds, btConstraintRow *offsetContactConstraintRows, TrbState *offsetRigStates, PfxSolverBody *offsetSolverBodies, uint32_t numRigidBodies, float separationBias, float timeStep, class btThreadSupportInterface *threadSupport, btCriticalSection *criticalSection, btConstraintSolverIO *io, uint8_t cmd)
btPersistentManifold * offsetContactManifolds
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
virtual int getNumTasks() const =0
btVector3 m_relpos1CrossNormal
const btVector3 & getAngularFactor() const
PfxParallelBatch * jointParallelBatches
btScalar m_appliedImpulseLateral1
#define ATTRIBUTE_ALIGNED128(a)
virtual void getInfo2(btConstraintInfo2 *info)=0
internal method used by the constraint solver, don't use them directly
#define PFX_MOTION_MASK_STATIC
#define PFX_MIN_SOLVER_PAIRS
void * SolverlsMemoryFunc()
virtual void sendRequest(uint32_t uiCommand, ppu_address_t uiArgument0, uint32_t uiArgument1)=0
send messages to SPUs
PfxSetupContactConstraintsIO setupContactConstraints
vmVector3 getPosition() const
btAlignedObjectArray< PfxConstraintRow > m_constraintRows
static void btStoreVector3(const vmVector3 &src, double *p)
PfxSolveConstraintsIO solveConstraints
void pfxSetMotionMaskA(PfxBroadphasePair &pair, uint8_t i)
1D constraint along a normal axis between bodyA and bodyB. It can be combined to solve contact and fr...
void btPlaneSpace1(const T &n, T &p, T &q)
btScalar m_appliedImpulse
PfxParallelBatch * contactParallelBatches
const btScalar & getW() const
btVector3 m_relpos2CrossNormal
void setMotionType(uint8_t t)
const btVector3 & getTotalTorque() const
vmQuat getOrientation() const
#define SIMD_FORCE_INLINE
uint16_t pfxGetRigidBodyIdA(const PfxBroadphasePair &pair)
const Vector3 rotate(const Quat &quat, const Vector3 &vec)
const Matrix3 crossMatrix(const Vector3 &vec)
ManifoldContactPoint collects and maintains persistent contactpoints.
btScalar * m_J1angularAxis
const btCollisionObject * getBody0() const
const btScalar & getY() const
Return the y value.
uint32_t pfxGetContactId1(const PfxBroadphasePair &pair)
unsigned char * getPoolAddress()
virtual void deleteBarrier(btBarrier *barrier)=0
virtual btScalar solveGroup(btCollisionObject **bodies, int numBodies, btPersistentManifold **manifold, int numManifolds, btTypedConstraint **constraints, int numConstraints, const btContactSolverInfo &info, btIDebugDraw *debugDrawer, btDispatcher *dispatcher)
btSequentialImpulseConstraintSolver Sequentially applies impulses
const btScalar & getX() const
Return the x value.
bool pfxGetActive(const PfxBroadphasePair &pair)
void SolverThreadFunc(void *userPtr, void *lsMemory)
uint32_t pfxGetConstraintId1(const PfxConstraintPair &pair)
Vectormath::Aos::Vector3 getVmVector3(const btVector3 &bulletVec)
Vectormath::Aos::Matrix3 vmMatrix3
virtual void deleteCriticalSection(btCriticalSection *criticalSection)=0
btScalar dot(const btVector3 &v) const
Return the dot product.
void pfxSetNumConstraints(PfxConstraintPair &pair, uint8_t n)
void setPosition(const vmVector3 &pos)
const btScalar & getZ() const
Return the z value.
static const Matrix3 identity()
PfxParallelGroup * contactParallelGroup
uint8_t pfxGetMotionMaskA(const PfxBroadphasePair &pair)
btVector3 m_angularComponentA
void pfxSetRigidBodyIdB(PfxBroadphasePair &pair, uint16_t i)
PfxConstraintPair * jointPairs
uint32_t criticalsectionAddr2
uint16_t pfxGetRigidBodyIdB(const PfxBroadphasePair &pair)
void pfxSetContactId(PfxBroadphasePair &pair, uint32_t i)
btTransform & getWorldTransform()
btConstraintSolverIO * createSolverIO(int numThreads)
btVector3 m_normalWorldOnB
static const Matrix3 scale(const Vector3 &scaleVec)
btParallelConstraintSolver(class btThreadSupportInterface *solverThreadSupport)
void setLinearDamping(float damping)
btScalar * m_J1linearAxis
uint8_t pfxGetMotionMaskB(const PfxBroadphasePair &pair)
void setLinearVelocity(const vmVector3 &vel)
btScalar m_appliedImpulseLateral2
void pfxSetRigidBodyIdA(PfxBroadphasePair &pair, uint16_t i)
unsigned char tmp_buff[(15 *1024 *1024)]
const btVector3 & getAngularVelocity() const
bool isStaticOrKinematicObject() const
const btScalar & getY() const
Return the y value.
btCollisionObject can be used to manage collision detection objects.
virtual btPoolAllocator * getInternalManifoldPool()=0
const btScalar & getX() const
Return the x value.
virtual void setSharedParam(int i, unsigned int p)=0
The btIDebugDraw interface class allows hooking up a debug renderer to visually debug simulations...
void setLinearVelocity(const btVector3 &lin_vel)
static void pfxSolveLinearConstraintRow(btConstraintRow &constraint, vmVector3 &deltaLinearVelocityA, vmVector3 &deltaAngularVelocityA, float massInvA, const vmMatrix3 &inertiaInvA, const vmVector3 &rA, vmVector3 &deltaLinearVelocityB, vmVector3 &deltaAngularVelocityB, float massInvB, const vmMatrix3 &inertiaInvB, const vmVector3 &rB)
The btRigidBody is the main class for rigid body objects.
btVector3 m_angularComponentB
struct btSolverConstraint * offsetSolverConstraints
btScalar getRestitution() const
void * allocate(size_t bytes, int alignment=ALIGN16)
uint16_t numBatches[PFX_MAX_SOLVER_PHASES]
vmVector3 mDeltaAngularVelocity
const btManifoldPoint & getContactPoint(int index) const
void pfxSetActive(PfxBroadphasePair &pair, bool b)
void setCompanionId(int id)
PfxPostSolverIO postSolver
btAlignedObjectArray< PfxConstraintPair > m_jointPairs
vmVector3 getAngularVelocity() const
void btSolveContactConstraint(btConstraintRow &constraintResponse, btConstraintRow &constraintFriction1, btConstraintRow &constraintFriction2, const vmVector3 &contactPointA, const vmVector3 &contactPointB, PfxSolverBody &solverBodyA, PfxSolverBody &solverBodyB, float friction)
btVector3 can be used to represent 3D points and vectors.
#define PFX_MAX_SOLVER_BATCHES
PfxSolverBody * solverBodies
int getCompanionId() const
void CustomPostSolverTask(TrbState *states, PfxSolverBody *solverBodies, uint32_t numRigidBodies)
uint8_t pfxGetNumConstraints(const PfxConstraintPair &pair)
uint16_t numPairs[PFX_MAX_SOLVER_PHASES *PFX_MAX_SOLVER_BATCHES]
btSimdScalar m_appliedPushImpulse
btVector3 getBtVector3(const Vectormath::Aos::Vector3 &vmVec)
void * m_originalContactPoint
void pfxSetMotionMaskB(PfxBroadphasePair &pair, uint8_t i)
btAlignedObjectArray< PfxSolverBody > m_mysolverbodies
btAlignedObjectArray< btTypedConstraint::btConstraintInfo1 > m_tmpConstraintSizesPool
btScalar * m_J2linearAxis
struct btParallelSolverMemoryCache * m_memoryCache
TypedConstraint is the baseclass for Bullet constraints and vehicles.
void resize(int newsize, const T &fillData=T())
vmVector3 getLinearVelocity() const
int getNumContacts() const
#define PFX_MAX_SOLVER_PAIRS
class btCriticalSection * m_criticalSection
const btRigidBody & getRigidBodyA() const
void CustomSolveConstraintsTaskParallel(const PfxParallelGroup *contactParallelGroup, const PfxParallelBatch *contactParallelBatches, PfxConstraintPair *contactPairs, uint32_t numContactPairs, btPersistentManifold *offsetContactManifolds, btConstraintRow *offsetContactConstraintRows, const PfxParallelGroup *jointParallelGroup, const PfxParallelBatch *jointParallelBatches, PfxConstraintPair *jointPairs, uint32_t numJointPairs, btSolverConstraint *offsetSolverConstraints, TrbState *offsetRigStates, PfxSolverBody *offsetSolverBodies, uint32_t numRigidBodies, int iteration, unsigned int taskId, unsigned int numTasks, btBarrier *barrier)
void BPE_customConstraintSolverSequentialNew(unsigned int new_num, PfxBroadphasePair *new_pairs1, btPersistentManifold *offsetContactManifolds, PfxConstraintRow *offsetContactConstraintRows, TrbState *states, int numRigidBodies, struct PfxSolverBody *solverBodies, PfxConstraintPair *jointPairs, unsigned int numJoints, btSolverConstraint *offsetSolverConstraints, float separateBias, float timeStep, int iteration, btThreadSupportInterface *solverThreadSupport, btCriticalSection *criticalSection, struct btConstraintSolverIO *solverIO, btBarrier *barrier)
void setAngularVelocity(const btVector3 &ang_vel)
btScalar getFriction() const
static float4 cross(const float4 &a, const float4 &b)
TrbState * offsetRigStates1
btConstraintRow * offsetContactConstraintRows
const T & btMax(const T &a, const T &b)
const btMatrix3x3 & getInvInertiaTensorWorld() const
btAlignedObjectArray< TrbState > m_mystates
const Matrix3 transpose(const Matrix3 &mat)
btScalar m_combinedFriction
struct btConstraintSolverIO * m_solverIO
#define PFX_MOTION_MASK_DYNAMIC
virtual btCriticalSection * createCriticalSection()=0
void resolveSingleConstraintRowGeneric(PfxSolverBody &body1, PfxSolverBody &body2, const btSolverConstraint &c)
Vectormath::Aos::Vector3 vmVector3
const btVector3 & getInvInertiaDiagLocal() const
btVector3 m_contactNormal1
btScalar dot(const btQuaternion &q1, const btQuaternion &q2)
Calculate the dot product between two quaternions.
Matrix3 & setCol(int col, const Vector3 &vec)
const btVector3 & getLinearVelocity() const
btAlignedObjectArray< PfxBroadphasePair > m_mypairs
The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatr...
vmVector3 mDeltaLinearVelocity
static vmVector3 btReadVector3(const double *p)
btSimdScalar m_appliedImpulse
btScalar getDistance() const
void pfxSetBroadphaseFlag(PfxBroadphasePair &pair, uint8_t f)
static void barrier(unsigned int a)
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
const T & btMin(const T &a, const T &b)
virtual void waitForResponse(unsigned int *puiArgument0, unsigned int *puiArgument1)=0
check for messages from SPUs
const T & btClamped(const T &a, const T &lb, const T &ub)
virtual ~btParallelConstraintSolver()
class btBarrier * m_barrier
void btSetupContactConstraint(btConstraintRow &constraintResponse, btConstraintRow &constraintFriction1, btConstraintRow &constraintFriction2, float penetrationDepth, float restitution, float friction, const vmVector3 &contactNormal, const vmVector3 &contactPointA, const vmVector3 &contactPointB, const TrbState &stateA, const TrbState &stateB, PfxSolverBody &solverBodyA, PfxSolverBody &solverBodyB, const vmVector3 &linVelA, const vmVector3 &angVelA, const vmVector3 &linVelB, const vmVector3 &angVelB, float separateBias, float timeStep)
const btRigidBody & getRigidBodyB() const
const btCollisionObject * getBody1() const
void CustomSplitConstraints(PfxConstraintPair *pairs, uint32_t numPairs, PfxParallelGroup &group, PfxParallelBatch *batches, uint32_t numTasks, uint32_t numRigidBodies, void *poolBuff, uint32_t poolBytes)
const btScalar & getZ() const
Return the z value.
btConstraintArray m_tmpSolverNonContactConstraintPool
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
btVector3 m_contactNormal2
void setRigidBodyId(uint16_t i)