fix: some file didn't have the svn:eol-style native yet

This commit is contained in:
erwin.coumans
2010-03-06 15:23:36 +00:00
parent 4fd48ac691
commit 81f04a4d48
641 changed files with 301123 additions and 301123 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,99 +1,99 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
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.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BASIC_DEMO_H
#define BASIC_DEMO_H
#include "DemoApplication.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
#ifdef BT_USE_CUDA
//#include "btCudaDemoPairCache.h"
//#include <vector_types.h>
#endif //BT_USE_CUDA
class btBroadphaseInterface;
class btCollisionShape;
class btOverlappingPairCache;
class btCollisionDispatcher;
class btConstraintSolver;
struct btCollisionAlgorithmCreateFunc;
class btDefaultCollisionConfiguration;
#include "GlutDemoApplication.h"
///BasicDemo is good starting point for learning the code base and porting.
class BasicDemo : public GlutDemoApplication
{
//keep the collision shapes, for deletion/cleanup
btAlignedObjectArray<btCollisionShape*> m_collisionShapes;
btBroadphaseInterface* m_broadphase;
btCollisionDispatcher* m_dispatcher;
btConstraintSolver* m_solver;
btDefaultCollisionConfiguration* m_collisionConfiguration;
int m_mouseButtons;
int m_mouseOldX;
int m_mouseOldY;
public:
BasicDemo()
{
}
virtual ~BasicDemo()
{
exitPhysics();
}
void initPhysics();
void exitPhysics();
///don't shoot a box in this demo ;-)
virtual void shootBox(const btVector3& dest) {}
virtual void clientMoveAndDisplay();
virtual void displayCallback();
virtual void keyboardCallback(unsigned char key, int x, int y);
virtual void clientResetScene();
static DemoApplication* Create()
{
BasicDemo* demo = new BasicDemo;
demo->myinit();
demo->initPhysics();
demo->m_mouseButtons = 0;
demo->m_mouseOldX = 0;
demo->m_mouseOldY = 0;
return demo;
}
void DrawConstraintInfo();
void outputDebugInfo(int & xOffset,int & yStart, int yIncr);
virtual void renderme();
void addCollisionShape(btCollisionShape* pShape) { m_collisionShapes.push_back(pShape); }
};
#endif //BASIC_DEMO_H
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
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.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BASIC_DEMO_H
#define BASIC_DEMO_H
#include "DemoApplication.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
#ifdef BT_USE_CUDA
//#include "btCudaDemoPairCache.h"
//#include <vector_types.h>
#endif //BT_USE_CUDA
class btBroadphaseInterface;
class btCollisionShape;
class btOverlappingPairCache;
class btCollisionDispatcher;
class btConstraintSolver;
struct btCollisionAlgorithmCreateFunc;
class btDefaultCollisionConfiguration;
#include "GlutDemoApplication.h"
///BasicDemo is good starting point for learning the code base and porting.
class BasicDemo : public GlutDemoApplication
{
//keep the collision shapes, for deletion/cleanup
btAlignedObjectArray<btCollisionShape*> m_collisionShapes;
btBroadphaseInterface* m_broadphase;
btCollisionDispatcher* m_dispatcher;
btConstraintSolver* m_solver;
btDefaultCollisionConfiguration* m_collisionConfiguration;
int m_mouseButtons;
int m_mouseOldX;
int m_mouseOldY;
public:
BasicDemo()
{
}
virtual ~BasicDemo()
{
exitPhysics();
}
void initPhysics();
void exitPhysics();
///don't shoot a box in this demo ;-)
virtual void shootBox(const btVector3& dest) {}
virtual void clientMoveAndDisplay();
virtual void displayCallback();
virtual void keyboardCallback(unsigned char key, int x, int y);
virtual void clientResetScene();
static DemoApplication* Create()
{
BasicDemo* demo = new BasicDemo;
demo->myinit();
demo->initPhysics();
demo->m_mouseButtons = 0;
demo->m_mouseOldX = 0;
demo->m_mouseOldY = 0;
return demo;
}
void DrawConstraintInfo();
void outputDebugInfo(int & xOffset,int & yStart, int yIncr);
virtual void renderme();
void addCollisionShape(btCollisionShape* pShape) { m_collisionShapes.push_back(pShape); }
};
#endif //BASIC_DEMO_H

View File

@@ -1,30 +1,30 @@
/*
Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org
Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
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.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "LinearMath/btQuickprof.h"
#include "LinearMath/btScalar.h"
#include "btGpuDemo2dSharedTypes.h"
#include "BulletMultiThreaded/btGpuDefines.h"
#include "BulletMultiThreaded/btGpuUtilsSharedDefs.h"
#include "btGpuDemo2dSharedCode.h"
/*
Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org
Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
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.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "LinearMath/btQuickprof.h"
#include "LinearMath/btScalar.h"
#include "btGpuDemo2dSharedTypes.h"
#include "BulletMultiThreaded/btGpuDefines.h"
#include "BulletMultiThreaded/btGpuUtilsSharedDefs.h"
#include "btGpuDemo2dSharedCode.h"

View File

@@ -1,497 +1,497 @@
/*
Impulse based Rigid body simulation using CUDA
Copyright (c) 2007 Takahiro Harada http://www.iii.u-tokyo.ac.jp/~takahiroharada/projects/impulseCUDA.html
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
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.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#define USE_FRICTION 1
#define FRICTION_BOX_GROUND_FACT 0.05f
#define FRICTION_BOX_BOX_FACT 0.05f
#define USE_CENTERS 1
//#include "LinearMath/btMinMax.h"
//---------- C o n s t r a i n t s o l v e r d e m o ----------------------------
#define MAX_VTX_PER_OBJ 8
/*
BT_GPU___device__ void kill_me()
{
char* badPtr = (char*)0xFFFFFFFF;
*badPtr = 10;
}
*/
BT_GPU___global__ void clearAccumulationOfLambdaDtD(float* lambdaDtBox, int numConstraints, int numContPoints)
{
int index = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x;
if(index < numConstraints)
{
for(int i=0; i < numContPoints; i++)
lambdaDtBox[numContPoints * index + i] = 0;
}
}
#define SPHERE_FACT 1.0f
BT_GPU___device__ void testSphSph(float3 aPos, float3 bPos, float radA, float radB, float4* pOut)
{
float3 del = bPos - aPos;
float dist = BT_GPU_dot(del, del);
dist = sqrtf(dist);
float maxD = radA + radB;
if(dist > maxD)
{
return;
}
float penetration = (radA + radB - dist) * SPHERE_FACT;
// float penetration = (dist - radA - radB) * SPHERE_FACT;
float3 normal;
if(dist > 0.f)
{
float fact = -1.0f/dist;
// float fact = 1.0f/dist;
normal = del * fact;
}
else
{
normal = BT_GPU_make_float3(1.f, 0.f, 0.f);
}
// float3 contact = (bPos + aPos + normal * (radB - radA)) * 0.5f;
float3 tmp = (normal * radA);
float3 contact = aPos - tmp;
// now add point
int numPoints = 0;
for(int i = 0; i < MAX_VTX_PER_OBJ; i++)
{
if(pOut[i*2].w >= 0.f)
{
numPoints++;
}
}
if(numPoints < MAX_VTX_PER_OBJ)
{
pOut[numPoints * 2] = BT_GPU_make_float42(contact, penetration);
pOut[numPoints * 2 + 1] = BT_GPU_make_float42(normal, 0.f);
}
} // testSphSph()
BT_GPU___global__ void setConstraintDataD(int2 *constraints,
int numConstraints,
float4 *pos,
float *rotation,
char* shapes,
int2* shapeIds,
btCudaPartProps pProp,
float4 *contact)
{
int idx = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x;
int aId,bId;
float3 aPos,bPos;
// float positionConstraint;
// float3 normal;
float aRot,bRot;
float sideLength2 = pProp.m_diameter*0.5f/sqrt(2.0f);
if(idx < numConstraints)
{
aId=constraints[idx].x;
bId=constraints[idx].y;
aPos=BT_GPU_make_float34(BT_GPU_FETCH4(pos,aId));
bPos=BT_GPU_make_float34(BT_GPU_FETCH4(pos,bId));
aRot= rotation[aId];
bRot= rotation[bId];
float cosA = cosf(aRot);
float sinA = sinf(aRot);
float cosB = cosf(bRot);
float sinB = sinf(bRot);
float4* shapeA = (float4*)(shapes + shapeIds[aId].x);
int numSphA = shapeIds[aId].y;
float4* shapeB = (float4*)(shapes + shapeIds[bId].x);
int numSphB = shapeIds[bId].y;
int i, j;
float3 ai = BT_GPU_make_float3(cosA, sinA, 0.f);
float3 aj = BT_GPU_make_float3(-sinA, cosA, 0.f);
float3 bi = BT_GPU_make_float3(cosB, sinB, 0.f);
float3 bj = BT_GPU_make_float3(-sinB, cosB, 0.f);
float4* pOut = contact + idx * MAX_VTX_PER_OBJ * 2;
for(i = 0; i < MAX_VTX_PER_OBJ; i++)
{
pOut[i * 2].w = -1.f;
pOut[i * 2 + 1].w = 0.f;
}
for(i = 0; i < numSphA; i++)
{
float3 va = aPos;
float3 tmp = ai * shapeA[i].x;
float3 tmp2 = aj * shapeA[i].y;
va += tmp;
va += tmp2;
float radA = shapeA[i].w;
for(j = 0; j < numSphB; j++)
{
float3 vb = bPos;
float3 tmp =bi * shapeB[j].x;
float3 tmp2 = bj * shapeB[j].y;
vb += tmp;
vb += tmp2;
float radB = shapeB[j].w;
testSphSph(va, vb, radA, radB, pOut);
}
}
}
}
BT_GPU___device__ float computeImpulse1(float3 rVel,
float positionConstraint,
float3 cNormal,
float dt)
{
// const float collisionConstant = 0.1f;
// const float baumgarteConstant = 0.5f;
// const float penetrationError = 0.02f;
const float collisionConstant = -0.1f;
const float baumgarteConstant = 0.3f;
const float penetrationError = 0.02f;
float lambdaDt=0;
float3 impulse=BT_GPU_make_float3(0.f,0.f,0.f);
if(positionConstraint > 0)
return lambdaDt;
// positionConstraint = btMin(0.0f,positionConstraint+penetrationError);
positionConstraint = (positionConstraint+penetrationError) < 0.f ? (positionConstraint+penetrationError) : 0.0f;
lambdaDt = -(BT_GPU_dot(cNormal,rVel)*(1+collisionConstant));
lambdaDt -= (baumgarteConstant/dt*positionConstraint);
return lambdaDt;
}
BT_GPU___global__ void collisionWithWallBoxD(float4 *pos,
float4 *vel,
float *rotation,
float *angVel,
char* shapes,
int2* shapeIds,
float* invMass,
btCudaPartProps pProp,
btCudaBoxProps gProp,
int nParticles,
float dt)
{
int idx = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x;
float3 aPos;
float aRot;
float positionConstraint;
float3 impulse;
if((idx > 0) && (idx < nParticles))
{
float inv_mass = invMass[idx];
if(inv_mass <= 0.f)
{
return;
}
aPos=BT_GPU_make_float34(BT_GPU_FETCH4(pos,idx));
aRot=rotation[idx];
float4* shape = (float4*)(shapes + shapeIds[idx].x);
int numSph = shapeIds[idx].y;
float cosA = cosf(aRot);
float sinA = sinf(aRot);
float3 ai = BT_GPU_make_float3(cosA, sinA, 0.f);
float3 aj = BT_GPU_make_float3(-sinA, cosA, 0.f);
for(int iVtx=0;iVtx < numSph; iVtx++){
float3 aVel = BT_GPU_make_float3(vel[idx].x, vel[idx].y, vel[idx].z);
float aAngVel = angVel[idx];
float3 rerVertex = ai * shape[iVtx].x;
float3 tmp = aj * shape[iVtx].y;
rerVertex += tmp;
float3 vPos = aPos + rerVertex;
float rad = shape[iVtx].w;
float3 vVel =aVel+BT_GPU_cross(BT_GPU_make_float3(0.0f,0.0f,aAngVel),rerVertex);
// float restitution=1.0;
float restitution=0.3f;
{
positionConstraint =vPos.y - rad - gProp.minY;
impulse =BT_GPU_make_float31(0.0f);
if(positionConstraint < 0)
{
float3 groundNormal;
groundNormal = BT_GPU_make_float3(0.0f,1.0f,0.0f);
impulse =groundNormal*
restitution * computeImpulse1(vVel,positionConstraint,
groundNormal,
dt);
#if USE_FRICTION // only with ground for now
float3 lat_vel = vVel - groundNormal * BT_GPU_dot(groundNormal,vVel);
float lat_vel_len = BT_GPU_dot(lat_vel, lat_vel);
if (lat_vel_len > 0)
{
lat_vel_len = sqrtf(lat_vel_len);
lat_vel *= 1.f/lat_vel_len;
float3 tmp = lat_vel * BT_GPU_dot(lat_vel, vVel) * FRICTION_BOX_GROUND_FACT;
impulse -= tmp;
}
#endif //USE_FRICTION
float4 tmp = BT_GPU_make_float42(impulse,0.0f);
vel[idx] += tmp;
float tmp2 = BT_GPU_cross(rerVertex,impulse).z;
angVel[idx] += tmp2;
}
}
{
positionConstraint =vPos.x - rad - gProp.minX;
impulse =BT_GPU_make_float31(0.0f);
if(positionConstraint < 0){
impulse =BT_GPU_make_float3(1.0f,0.0f,0.0f)* restitution *
computeImpulse1(vVel,positionConstraint,
BT_GPU_make_float3(1.0f,0.0f,0.0f),
dt);
float4 tmp = BT_GPU_make_float42(impulse,0.0f);
vel[idx] += tmp;
angVel[idx] += BT_GPU_cross(rerVertex,impulse).z;
}
}
{
positionConstraint = gProp.maxX - vPos.x - rad;
impulse =BT_GPU_make_float31(0.0f);
if(positionConstraint < 0){
impulse =BT_GPU_make_float3(-1.0f,0.0f,0.0f)* restitution *
computeImpulse1(vVel,positionConstraint,
BT_GPU_make_float3(-1.0f,0.0f,0.0f),
dt);
float4 tmp = BT_GPU_make_float42(impulse,0.0f);
vel[idx] += tmp;
angVel[idx] += BT_GPU_cross(rerVertex,impulse).z;
}
}
}
}
}
BT_GPU___device__ void collisionResolutionBox( int constrId,
int2* constraints,
float4 *pos,
float4 *vel,
float *rotation,
float *angularVel,
float *lambdaDtBox,
float4* contact,
float* invMass,
btCudaPartProps pProp,
float dt)
{
#if 1
float3 relVel;
float3 impulse;
float lambdaDt;
float positionConstraint;
int aId=constraints[constrId].x;
int bId=constraints[constrId].y;
float3 aPos=BT_GPU_make_float34(BT_GPU_FETCH4(pos,aId));
float3 bPos=BT_GPU_make_float34(BT_GPU_FETCH4(pos,bId));
float3 aVel=BT_GPU_make_float34(vel[aId]);
float3 bVel=BT_GPU_make_float34(vel[bId]);
float aAngVel=angularVel[aId];
float bAngVel=angularVel[bId];
float4* pCont = contact + constrId * MAX_VTX_PER_OBJ * 2;
// test Vertices in A to Box B
for(int iVtx=0;iVtx<MAX_VTX_PER_OBJ;iVtx++){
float3 contactPoint = BT_GPU_make_float34(pCont[iVtx * 2]);
contactPoint = contactPoint - aPos;
positionConstraint = pCont[iVtx * 2].w;
if(positionConstraint >= 0)
{
float3 contactNormal = BT_GPU_make_float34(pCont[iVtx * 2 + 1]);
relVel=(aVel+BT_GPU_cross(BT_GPU_make_float3(0.0f,0.0f,aAngVel),
contactPoint))
-(bVel+BT_GPU_cross(BT_GPU_make_float3(0.0f,0.0f,bAngVel),
contactPoint+aPos-bPos));
lambdaDt= computeImpulse1(relVel,-positionConstraint,
contactNormal,dt);
{
float rLambdaDt=lambdaDtBox[(MAX_VTX_PER_OBJ)*(2*constrId)+iVtx];
float pLambdaDt=rLambdaDt;
// rLambdaDt=btMax(pLambdaDt+lambdaDt,0.0f);
rLambdaDt=(pLambdaDt+lambdaDt) > 0.0f ? (pLambdaDt+lambdaDt) : 0.0f;
lambdaDt=rLambdaDt-pLambdaDt;
lambdaDtBox[(MAX_VTX_PER_OBJ)*(2*constrId)+iVtx]=rLambdaDt;
}
impulse= contactNormal*lambdaDt*0.5;
#if USE_FRICTION
if(pCont[iVtx * 2 + 1].w <= 0)
{
float3 lat_vel = relVel - contactNormal * BT_GPU_dot(contactNormal, relVel);
float lat_vel_len = BT_GPU_dot(lat_vel, lat_vel);
if (lat_vel_len > 0)
{
lat_vel_len = sqrtf(lat_vel_len);
lat_vel *= 1.f/lat_vel_len;
float3 tmp = lat_vel * BT_GPU_dot(lat_vel , relVel) * FRICTION_BOX_BOX_FACT;
impulse -= tmp;
}
}
#endif //USE_FRICTION
if(aId && (invMass[aId] > 0.f))
{
aVel+= impulse;
aAngVel+= BT_GPU_cross(contactPoint, impulse).z;
}
if(bId && (invMass[bId] > 0.f))
{
bVel-= impulse;
bAngVel-= BT_GPU_cross(contactPoint+aPos-bPos, impulse).z;
}
}
}
vel[aId]=BT_GPU_make_float42(aVel,0.0f);
vel[bId]=BT_GPU_make_float42(bVel,0.0f);
angularVel[aId]=aAngVel;
angularVel[bId]=bAngVel;
#endif
}
BT_GPU___global__ void collisionBatchResolutionBoxD(int2 *constraints,
int *batch,
int nConstraints,
float4 *pos,
float4 *vel,
float *rotation,
float *angularVel,
float *lambdaDtBox,
float4* contact,
float* invMass,
btCudaPartProps pProp,
int iBatch,
float dt)
{
int k_idx = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x;
if(k_idx < nConstraints)
{
int idx = batch[k_idx];
collisionResolutionBox( idx, constraints, pos, vel, rotation, angularVel, lambdaDtBox,
contact, invMass, pProp, dt);
}
}
extern "C"
{
void BT_GPU_PREF(clearAccumulationOfLambdaDt(float* lambdaDtBox, int numConstraints, int numContPoints))
{
if(!numConstraints)
{
return;
}
int numThreads, numBlocks;
BT_GPU_PREF(computeGridSize)(numConstraints, 256, numBlocks, numThreads);
// execute the kernel
BT_GPU_EXECKERNEL(numBlocks, numThreads, clearAccumulationOfLambdaDtD, (lambdaDtBox, numConstraints, numContPoints));
// check if kernel invocation generated an error
BT_GPU_CHECK_ERROR("clearAccumulationOfLambdaDtD kernel execution failed");
}
void BT_GPU_PREF(setConstraintData(void* constraints,int numConstraints,int numObjs,void* pos,float *rotation,char* shapes,void* shapeIds,btCudaPartProps pProp,void* contact))
{
if(!numConstraints)
{
return;
}
int2* pConst = (int2*)constraints;
float4* pPos = (float4*)pos;
float4* pCont = (float4*)contact;
int2* pShapeIds = (int2*)shapeIds;
BT_GPU_SAFE_CALL(BT_GPU_BindTexture(0, posTex, pPos, numObjs * sizeof(float4)));
int numThreads, numBlocks;
BT_GPU_PREF(computeGridSize)(numConstraints, 256, numBlocks, numThreads);
// execute the kernel
BT_GPU_EXECKERNEL(numBlocks, numThreads, setConstraintDataD, (pConst,numConstraints,pPos,rotation,shapes,pShapeIds,pProp,pCont));
BT_GPU_SAFE_CALL(BT_GPU_UnbindTexture(posTex));
// check if kernel invocation generated an error
BT_GPU_CHECK_ERROR("setConstraintDataD kernel execution failed");
}
void BT_GPU_PREF(collisionWithWallBox(void* pos,void* vel,float *rotation,float *angVel,char* shapes,void* shapeIds,void* invMass,btCudaPartProps pProp, btCudaBoxProps gProp,int numObjs,float dt))
{
if(!numObjs)
{
return;
}
float4* pPos = (float4*)pos;
float4* pVel = (float4*)vel;
int2* pShapeIds = (int2*)shapeIds;
float* pInvMass = (float*)invMass;
BT_GPU_SAFE_CALL(BT_GPU_BindTexture(0, posTex, pPos, numObjs * sizeof(float4)));
int numThreads, numBlocks;
BT_GPU_PREF(computeGridSize)(numObjs, 256, numBlocks, numThreads);
// execute the kernel
BT_GPU_EXECKERNEL(numBlocks, numThreads, collisionWithWallBoxD, (pPos,pVel,rotation,angVel,shapes, pShapeIds,pInvMass,pProp,gProp,numObjs,dt));
BT_GPU_SAFE_CALL(BT_GPU_UnbindTexture(posTex));
// check if kernel invocation generated an error
BT_GPU_CHECK_ERROR("collisionWithWallBoxD kernel execution failed");
}
void BT_GPU_PREF(collisionBatchResolutionBox(void* constraints,int *batch,int numConstraints,int numObjs,void *pos,void *vel,float *rotation,float *angularVel,float *lambdaDtBox,void* contact,void* invMass,btCudaPartProps pProp,int iBatch,float dt))
{
if(!numConstraints)
{
return;
}
int2* pConstr = (int2*)constraints;
float4* pPos = (float4*)pos;
float4* pVel = (float4*)vel;
float4* pCont = (float4*)contact;
float* pInvMass = (float*)invMass;
int numThreads, numBlocks;
BT_GPU_PREF(computeGridSize)(numConstraints, 128, numBlocks, numThreads);
BT_GPU_SAFE_CALL(BT_GPU_BindTexture(0, posTex, pPos, numObjs * sizeof(float4)));
// execute the kernel
BT_GPU_EXECKERNEL(numBlocks, numThreads, collisionBatchResolutionBoxD, (pConstr,batch,numConstraints,pPos,pVel,rotation,angularVel,lambdaDtBox,pCont,pInvMass,pProp,iBatch,dt));
// check if kernel invocation generated an error
BT_GPU_CHECK_ERROR("collisionBatchResolutionBox2D kernel execution failed");
BT_GPU_SAFE_CALL(BT_GPU_UnbindTexture(posTex));
}
} // extern "C"
/*
Impulse based Rigid body simulation using CUDA
Copyright (c) 2007 Takahiro Harada http://www.iii.u-tokyo.ac.jp/~takahiroharada/projects/impulseCUDA.html
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
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.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#define USE_FRICTION 1
#define FRICTION_BOX_GROUND_FACT 0.05f
#define FRICTION_BOX_BOX_FACT 0.05f
#define USE_CENTERS 1
//#include "LinearMath/btMinMax.h"
//---------- C o n s t r a i n t s o l v e r d e m o ----------------------------
#define MAX_VTX_PER_OBJ 8
/*
BT_GPU___device__ void kill_me()
{
char* badPtr = (char*)0xFFFFFFFF;
*badPtr = 10;
}
*/
BT_GPU___global__ void clearAccumulationOfLambdaDtD(float* lambdaDtBox, int numConstraints, int numContPoints)
{
int index = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x;
if(index < numConstraints)
{
for(int i=0; i < numContPoints; i++)
lambdaDtBox[numContPoints * index + i] = 0;
}
}
#define SPHERE_FACT 1.0f
BT_GPU___device__ void testSphSph(float3 aPos, float3 bPos, float radA, float radB, float4* pOut)
{
float3 del = bPos - aPos;
float dist = BT_GPU_dot(del, del);
dist = sqrtf(dist);
float maxD = radA + radB;
if(dist > maxD)
{
return;
}
float penetration = (radA + radB - dist) * SPHERE_FACT;
// float penetration = (dist - radA - radB) * SPHERE_FACT;
float3 normal;
if(dist > 0.f)
{
float fact = -1.0f/dist;
// float fact = 1.0f/dist;
normal = del * fact;
}
else
{
normal = BT_GPU_make_float3(1.f, 0.f, 0.f);
}
// float3 contact = (bPos + aPos + normal * (radB - radA)) * 0.5f;
float3 tmp = (normal * radA);
float3 contact = aPos - tmp;
// now add point
int numPoints = 0;
for(int i = 0; i < MAX_VTX_PER_OBJ; i++)
{
if(pOut[i*2].w >= 0.f)
{
numPoints++;
}
}
if(numPoints < MAX_VTX_PER_OBJ)
{
pOut[numPoints * 2] = BT_GPU_make_float42(contact, penetration);
pOut[numPoints * 2 + 1] = BT_GPU_make_float42(normal, 0.f);
}
} // testSphSph()
BT_GPU___global__ void setConstraintDataD(int2 *constraints,
int numConstraints,
float4 *pos,
float *rotation,
char* shapes,
int2* shapeIds,
btCudaPartProps pProp,
float4 *contact)
{
int idx = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x;
int aId,bId;
float3 aPos,bPos;
// float positionConstraint;
// float3 normal;
float aRot,bRot;
float sideLength2 = pProp.m_diameter*0.5f/sqrt(2.0f);
if(idx < numConstraints)
{
aId=constraints[idx].x;
bId=constraints[idx].y;
aPos=BT_GPU_make_float34(BT_GPU_FETCH4(pos,aId));
bPos=BT_GPU_make_float34(BT_GPU_FETCH4(pos,bId));
aRot= rotation[aId];
bRot= rotation[bId];
float cosA = cosf(aRot);
float sinA = sinf(aRot);
float cosB = cosf(bRot);
float sinB = sinf(bRot);
float4* shapeA = (float4*)(shapes + shapeIds[aId].x);
int numSphA = shapeIds[aId].y;
float4* shapeB = (float4*)(shapes + shapeIds[bId].x);
int numSphB = shapeIds[bId].y;
int i, j;
float3 ai = BT_GPU_make_float3(cosA, sinA, 0.f);
float3 aj = BT_GPU_make_float3(-sinA, cosA, 0.f);
float3 bi = BT_GPU_make_float3(cosB, sinB, 0.f);
float3 bj = BT_GPU_make_float3(-sinB, cosB, 0.f);
float4* pOut = contact + idx * MAX_VTX_PER_OBJ * 2;
for(i = 0; i < MAX_VTX_PER_OBJ; i++)
{
pOut[i * 2].w = -1.f;
pOut[i * 2 + 1].w = 0.f;
}
for(i = 0; i < numSphA; i++)
{
float3 va = aPos;
float3 tmp = ai * shapeA[i].x;
float3 tmp2 = aj * shapeA[i].y;
va += tmp;
va += tmp2;
float radA = shapeA[i].w;
for(j = 0; j < numSphB; j++)
{
float3 vb = bPos;
float3 tmp =bi * shapeB[j].x;
float3 tmp2 = bj * shapeB[j].y;
vb += tmp;
vb += tmp2;
float radB = shapeB[j].w;
testSphSph(va, vb, radA, radB, pOut);
}
}
}
}
BT_GPU___device__ float computeImpulse1(float3 rVel,
float positionConstraint,
float3 cNormal,
float dt)
{
// const float collisionConstant = 0.1f;
// const float baumgarteConstant = 0.5f;
// const float penetrationError = 0.02f;
const float collisionConstant = -0.1f;
const float baumgarteConstant = 0.3f;
const float penetrationError = 0.02f;
float lambdaDt=0;
float3 impulse=BT_GPU_make_float3(0.f,0.f,0.f);
if(positionConstraint > 0)
return lambdaDt;
// positionConstraint = btMin(0.0f,positionConstraint+penetrationError);
positionConstraint = (positionConstraint+penetrationError) < 0.f ? (positionConstraint+penetrationError) : 0.0f;
lambdaDt = -(BT_GPU_dot(cNormal,rVel)*(1+collisionConstant));
lambdaDt -= (baumgarteConstant/dt*positionConstraint);
return lambdaDt;
}
BT_GPU___global__ void collisionWithWallBoxD(float4 *pos,
float4 *vel,
float *rotation,
float *angVel,
char* shapes,
int2* shapeIds,
float* invMass,
btCudaPartProps pProp,
btCudaBoxProps gProp,
int nParticles,
float dt)
{
int idx = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x;
float3 aPos;
float aRot;
float positionConstraint;
float3 impulse;
if((idx > 0) && (idx < nParticles))
{
float inv_mass = invMass[idx];
if(inv_mass <= 0.f)
{
return;
}
aPos=BT_GPU_make_float34(BT_GPU_FETCH4(pos,idx));
aRot=rotation[idx];
float4* shape = (float4*)(shapes + shapeIds[idx].x);
int numSph = shapeIds[idx].y;
float cosA = cosf(aRot);
float sinA = sinf(aRot);
float3 ai = BT_GPU_make_float3(cosA, sinA, 0.f);
float3 aj = BT_GPU_make_float3(-sinA, cosA, 0.f);
for(int iVtx=0;iVtx < numSph; iVtx++){
float3 aVel = BT_GPU_make_float3(vel[idx].x, vel[idx].y, vel[idx].z);
float aAngVel = angVel[idx];
float3 rerVertex = ai * shape[iVtx].x;
float3 tmp = aj * shape[iVtx].y;
rerVertex += tmp;
float3 vPos = aPos + rerVertex;
float rad = shape[iVtx].w;
float3 vVel =aVel+BT_GPU_cross(BT_GPU_make_float3(0.0f,0.0f,aAngVel),rerVertex);
// float restitution=1.0;
float restitution=0.3f;
{
positionConstraint =vPos.y - rad - gProp.minY;
impulse =BT_GPU_make_float31(0.0f);
if(positionConstraint < 0)
{
float3 groundNormal;
groundNormal = BT_GPU_make_float3(0.0f,1.0f,0.0f);
impulse =groundNormal*
restitution * computeImpulse1(vVel,positionConstraint,
groundNormal,
dt);
#if USE_FRICTION // only with ground for now
float3 lat_vel = vVel - groundNormal * BT_GPU_dot(groundNormal,vVel);
float lat_vel_len = BT_GPU_dot(lat_vel, lat_vel);
if (lat_vel_len > 0)
{
lat_vel_len = sqrtf(lat_vel_len);
lat_vel *= 1.f/lat_vel_len;
float3 tmp = lat_vel * BT_GPU_dot(lat_vel, vVel) * FRICTION_BOX_GROUND_FACT;
impulse -= tmp;
}
#endif //USE_FRICTION
float4 tmp = BT_GPU_make_float42(impulse,0.0f);
vel[idx] += tmp;
float tmp2 = BT_GPU_cross(rerVertex,impulse).z;
angVel[idx] += tmp2;
}
}
{
positionConstraint =vPos.x - rad - gProp.minX;
impulse =BT_GPU_make_float31(0.0f);
if(positionConstraint < 0){
impulse =BT_GPU_make_float3(1.0f,0.0f,0.0f)* restitution *
computeImpulse1(vVel,positionConstraint,
BT_GPU_make_float3(1.0f,0.0f,0.0f),
dt);
float4 tmp = BT_GPU_make_float42(impulse,0.0f);
vel[idx] += tmp;
angVel[idx] += BT_GPU_cross(rerVertex,impulse).z;
}
}
{
positionConstraint = gProp.maxX - vPos.x - rad;
impulse =BT_GPU_make_float31(0.0f);
if(positionConstraint < 0){
impulse =BT_GPU_make_float3(-1.0f,0.0f,0.0f)* restitution *
computeImpulse1(vVel,positionConstraint,
BT_GPU_make_float3(-1.0f,0.0f,0.0f),
dt);
float4 tmp = BT_GPU_make_float42(impulse,0.0f);
vel[idx] += tmp;
angVel[idx] += BT_GPU_cross(rerVertex,impulse).z;
}
}
}
}
}
BT_GPU___device__ void collisionResolutionBox( int constrId,
int2* constraints,
float4 *pos,
float4 *vel,
float *rotation,
float *angularVel,
float *lambdaDtBox,
float4* contact,
float* invMass,
btCudaPartProps pProp,
float dt)
{
#if 1
float3 relVel;
float3 impulse;
float lambdaDt;
float positionConstraint;
int aId=constraints[constrId].x;
int bId=constraints[constrId].y;
float3 aPos=BT_GPU_make_float34(BT_GPU_FETCH4(pos,aId));
float3 bPos=BT_GPU_make_float34(BT_GPU_FETCH4(pos,bId));
float3 aVel=BT_GPU_make_float34(vel[aId]);
float3 bVel=BT_GPU_make_float34(vel[bId]);
float aAngVel=angularVel[aId];
float bAngVel=angularVel[bId];
float4* pCont = contact + constrId * MAX_VTX_PER_OBJ * 2;
// test Vertices in A to Box B
for(int iVtx=0;iVtx<MAX_VTX_PER_OBJ;iVtx++){
float3 contactPoint = BT_GPU_make_float34(pCont[iVtx * 2]);
contactPoint = contactPoint - aPos;
positionConstraint = pCont[iVtx * 2].w;
if(positionConstraint >= 0)
{
float3 contactNormal = BT_GPU_make_float34(pCont[iVtx * 2 + 1]);
relVel=(aVel+BT_GPU_cross(BT_GPU_make_float3(0.0f,0.0f,aAngVel),
contactPoint))
-(bVel+BT_GPU_cross(BT_GPU_make_float3(0.0f,0.0f,bAngVel),
contactPoint+aPos-bPos));
lambdaDt= computeImpulse1(relVel,-positionConstraint,
contactNormal,dt);
{
float rLambdaDt=lambdaDtBox[(MAX_VTX_PER_OBJ)*(2*constrId)+iVtx];
float pLambdaDt=rLambdaDt;
// rLambdaDt=btMax(pLambdaDt+lambdaDt,0.0f);
rLambdaDt=(pLambdaDt+lambdaDt) > 0.0f ? (pLambdaDt+lambdaDt) : 0.0f;
lambdaDt=rLambdaDt-pLambdaDt;
lambdaDtBox[(MAX_VTX_PER_OBJ)*(2*constrId)+iVtx]=rLambdaDt;
}
impulse= contactNormal*lambdaDt*0.5;
#if USE_FRICTION
if(pCont[iVtx * 2 + 1].w <= 0)
{
float3 lat_vel = relVel - contactNormal * BT_GPU_dot(contactNormal, relVel);
float lat_vel_len = BT_GPU_dot(lat_vel, lat_vel);
if (lat_vel_len > 0)
{
lat_vel_len = sqrtf(lat_vel_len);
lat_vel *= 1.f/lat_vel_len;
float3 tmp = lat_vel * BT_GPU_dot(lat_vel , relVel) * FRICTION_BOX_BOX_FACT;
impulse -= tmp;
}
}
#endif //USE_FRICTION
if(aId && (invMass[aId] > 0.f))
{
aVel+= impulse;
aAngVel+= BT_GPU_cross(contactPoint, impulse).z;
}
if(bId && (invMass[bId] > 0.f))
{
bVel-= impulse;
bAngVel-= BT_GPU_cross(contactPoint+aPos-bPos, impulse).z;
}
}
}
vel[aId]=BT_GPU_make_float42(aVel,0.0f);
vel[bId]=BT_GPU_make_float42(bVel,0.0f);
angularVel[aId]=aAngVel;
angularVel[bId]=bAngVel;
#endif
}
BT_GPU___global__ void collisionBatchResolutionBoxD(int2 *constraints,
int *batch,
int nConstraints,
float4 *pos,
float4 *vel,
float *rotation,
float *angularVel,
float *lambdaDtBox,
float4* contact,
float* invMass,
btCudaPartProps pProp,
int iBatch,
float dt)
{
int k_idx = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x;
if(k_idx < nConstraints)
{
int idx = batch[k_idx];
collisionResolutionBox( idx, constraints, pos, vel, rotation, angularVel, lambdaDtBox,
contact, invMass, pProp, dt);
}
}
extern "C"
{
void BT_GPU_PREF(clearAccumulationOfLambdaDt(float* lambdaDtBox, int numConstraints, int numContPoints))
{
if(!numConstraints)
{
return;
}
int numThreads, numBlocks;
BT_GPU_PREF(computeGridSize)(numConstraints, 256, numBlocks, numThreads);
// execute the kernel
BT_GPU_EXECKERNEL(numBlocks, numThreads, clearAccumulationOfLambdaDtD, (lambdaDtBox, numConstraints, numContPoints));
// check if kernel invocation generated an error
BT_GPU_CHECK_ERROR("clearAccumulationOfLambdaDtD kernel execution failed");
}
void BT_GPU_PREF(setConstraintData(void* constraints,int numConstraints,int numObjs,void* pos,float *rotation,char* shapes,void* shapeIds,btCudaPartProps pProp,void* contact))
{
if(!numConstraints)
{
return;
}
int2* pConst = (int2*)constraints;
float4* pPos = (float4*)pos;
float4* pCont = (float4*)contact;
int2* pShapeIds = (int2*)shapeIds;
BT_GPU_SAFE_CALL(BT_GPU_BindTexture(0, posTex, pPos, numObjs * sizeof(float4)));
int numThreads, numBlocks;
BT_GPU_PREF(computeGridSize)(numConstraints, 256, numBlocks, numThreads);
// execute the kernel
BT_GPU_EXECKERNEL(numBlocks, numThreads, setConstraintDataD, (pConst,numConstraints,pPos,rotation,shapes,pShapeIds,pProp,pCont));
BT_GPU_SAFE_CALL(BT_GPU_UnbindTexture(posTex));
// check if kernel invocation generated an error
BT_GPU_CHECK_ERROR("setConstraintDataD kernel execution failed");
}
void BT_GPU_PREF(collisionWithWallBox(void* pos,void* vel,float *rotation,float *angVel,char* shapes,void* shapeIds,void* invMass,btCudaPartProps pProp, btCudaBoxProps gProp,int numObjs,float dt))
{
if(!numObjs)
{
return;
}
float4* pPos = (float4*)pos;
float4* pVel = (float4*)vel;
int2* pShapeIds = (int2*)shapeIds;
float* pInvMass = (float*)invMass;
BT_GPU_SAFE_CALL(BT_GPU_BindTexture(0, posTex, pPos, numObjs * sizeof(float4)));
int numThreads, numBlocks;
BT_GPU_PREF(computeGridSize)(numObjs, 256, numBlocks, numThreads);
// execute the kernel
BT_GPU_EXECKERNEL(numBlocks, numThreads, collisionWithWallBoxD, (pPos,pVel,rotation,angVel,shapes, pShapeIds,pInvMass,pProp,gProp,numObjs,dt));
BT_GPU_SAFE_CALL(BT_GPU_UnbindTexture(posTex));
// check if kernel invocation generated an error
BT_GPU_CHECK_ERROR("collisionWithWallBoxD kernel execution failed");
}
void BT_GPU_PREF(collisionBatchResolutionBox(void* constraints,int *batch,int numConstraints,int numObjs,void *pos,void *vel,float *rotation,float *angularVel,float *lambdaDtBox,void* contact,void* invMass,btCudaPartProps pProp,int iBatch,float dt))
{
if(!numConstraints)
{
return;
}
int2* pConstr = (int2*)constraints;
float4* pPos = (float4*)pos;
float4* pVel = (float4*)vel;
float4* pCont = (float4*)contact;
float* pInvMass = (float*)invMass;
int numThreads, numBlocks;
BT_GPU_PREF(computeGridSize)(numConstraints, 128, numBlocks, numThreads);
BT_GPU_SAFE_CALL(BT_GPU_BindTexture(0, posTex, pPos, numObjs * sizeof(float4)));
// execute the kernel
BT_GPU_EXECKERNEL(numBlocks, numThreads, collisionBatchResolutionBoxD, (pConstr,batch,numConstraints,pPos,pVel,rotation,angularVel,lambdaDtBox,pCont,pInvMass,pProp,iBatch,dt));
// check if kernel invocation generated an error
BT_GPU_CHECK_ERROR("collisionBatchResolutionBox2D kernel execution failed");
BT_GPU_SAFE_CALL(BT_GPU_UnbindTexture(posTex));
}
} // extern "C"

View File

@@ -1,33 +1,33 @@
/*
Impulse based Rigid body simulation using CUDA
Copyright (c) 2007 Takahiro Harada http://www.iii.u-tokyo.ac.jp/~takahiroharada/projects/impulseCUDA.html
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
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.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
//---------- C o n s t r a i n t s o l v e r d e m o ----------------------------
extern "C"
{
void BT_GPU_PREF(clearAccumulationOfLambdaDt(float* lambdaDtBox, int numConstraints, int numContPoints));
void BT_GPU_PREF(setConstraintData(void* constraints,int numConstraints,int numObjs,void* pos,float *rotation,char* shapes,void* shapeIds,btCudaPartProps pProp,void* oContact));
void BT_GPU_PREF(collisionWithWallBox(void* pos,void* vel,float *rotation,float *angVel,char* shapes,void* shapeIds,void* invMass,btCudaPartProps pProp,btCudaBoxProps gProp,int numObjs,float dt));
void BT_GPU_PREF(collisionBatchResolutionBox(void* constraints,int *batch,int numConstraints,int numObjs,void *pos,void *vel,float *rotation,float *angularVel,float *lambdaDtBox,void* contact,void* invMass,btCudaPartProps pProp,int iBatch,float dt));
} // extern "C"
/*
Impulse based Rigid body simulation using CUDA
Copyright (c) 2007 Takahiro Harada http://www.iii.u-tokyo.ac.jp/~takahiroharada/projects/impulseCUDA.html
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
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.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
//---------- C o n s t r a i n t s o l v e r d e m o ----------------------------
extern "C"
{
void BT_GPU_PREF(clearAccumulationOfLambdaDt(float* lambdaDtBox, int numConstraints, int numContPoints));
void BT_GPU_PREF(setConstraintData(void* constraints,int numConstraints,int numObjs,void* pos,float *rotation,char* shapes,void* shapeIds,btCudaPartProps pProp,void* oContact));
void BT_GPU_PREF(collisionWithWallBox(void* pos,void* vel,float *rotation,float *angVel,char* shapes,void* shapeIds,void* invMass,btCudaPartProps pProp,btCudaBoxProps gProp,int numObjs,float dt));
void BT_GPU_PREF(collisionBatchResolutionBox(void* constraints,int *batch,int numConstraints,int numObjs,void *pos,void *vel,float *rotation,float *angularVel,float *lambdaDtBox,void* contact,void* invMass,btCudaPartProps pProp,int iBatch,float dt));
} // extern "C"

View File

@@ -1,35 +1,35 @@
/*
Impulse based Rigid body simulation using CUDA
Copyright (c) 2007 Takahiro Harada http://www.iii.u-tokyo.ac.jp/~takahiroharada/projects/impulseCUDA.html
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
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.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
//---------- C o n s t r a i n t s o l v e r d e m o ----------------------------
struct btCudaPartProps
{
float m_mass;
float m_diameter;
float m_restCoeff;
};
struct btCudaBoxProps
{
float minX;
float maxX;
float minY;
float maxY;
float minZ;
float maxZ;
};
/*
Impulse based Rigid body simulation using CUDA
Copyright (c) 2007 Takahiro Harada http://www.iii.u-tokyo.ac.jp/~takahiroharada/projects/impulseCUDA.html
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
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.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
//---------- C o n s t r a i n t s o l v e r d e m o ----------------------------
struct btCudaPartProps
{
float m_mass;
float m_diameter;
float m_restCoeff;
};
struct btCudaBoxProps
{
float minX;
float maxX;
float minY;
float maxY;
float minZ;
float maxZ;
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,291 +1,291 @@
/*
Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org
Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
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.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BT_CUDA_DEMO_DYNAMICS_WORLD_H
#define BT_CUDA_DEMO_DYNAMICS_WORLD_H
#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h"
//#define BT_USE_CUDA 1
// To enable CUDA :
// 1. Uncomment //#define BT_USE_CUDA 1
// 2. Build and add libbulletcuda (Extras/CUDA) to project
// 3. Add $(CUDA_LIB_PATH) and cudart.lib to linker properties
#ifdef BT_USE_CUDA
// #include "btCudaDemoPairCache.h"
// #include <vector_types.h>
#include "BulletMultiThreaded/btGpuDefines.h"
#undef BT_GPU_PREF
#define BT_GPU_PREF(func) btCuda_##func
#include "BulletMultiThreaded/btGpuUtilsSharedDefs.h"
#else
#include "BulletMultiThreaded/btGpuDefines.h"
#include "../../src/BulletMultiThreaded/btGpuUtilsSharedDefs.h"
#endif
#undef BT_GPU_PREF
#include "btGpuDemo2dSharedTypes.h"
#define CUDA_DEMO_DYNAMICS_WORLD_MAX_BATCHES 20
#define CUDA_DEMO_DYNAMICS_WORLD_MAX_OBJS 1024
#define CUDA_DEMO_DYNAMICS_WORLD_MAX_NEIGHBORS 24
#define CUDA_DEMO_DYNAMICS_WORLD_MAX_SPHERES_PER_OBJ 8
class btGpuDemoDynamicsWorld;
extern btGpuDemoDynamicsWorld* gpCudaDemoDynamicsWorld; // to access world members from pair cache
class btGpuDemoDynamicsWorld : public btDiscreteDynamicsWorld
{
protected:
int m_maxObjs;
int m_maxNeighbors;
int m_numObj;
int m_numSimStep;
bool m_useCPUSolver;
bool m_useBulletNarrowphase;
float4* m_hPos;
float* m_hRot;
float4* m_hVel;
float* m_hAngVel;
float* m_hInvMass;
float* m_dInvMass;
bool m_copyMassDataToGPU;
#ifdef BT_USE_CUDA
float4* m_dPos;
float* m_dRot;
float4* m_dVel;
float* m_dAngVel;
float4* m_dpPos;
float* m_dpRot;
float4* m_dpVel;
float* m_dpAngVel;
float4* m_dcPos;
float* m_dcRot;
float4* m_dcVel;
float* m_dcAngVel;
#endif //BT_USE_CUDA
btOverlappingPairCache* m_pairCache;
int* m_hConstraintBuffer;
int* m_hConstraintCounter;
int m_maxBatches;
int m_numBatches;
int m_totalNumConstraints;
int2* m_hIds;
int* m_hBatchIds;
int m_maxVtxPerObj;
int2* m_dIds;
int* m_dBatchIds;
float* m_dLambdaDtBox;
float4* m_dContact; // 8 floats : pos.x, pos.y, pos.z, penetration, norm.x, norm.y, norm.z, reserved
// ------------- these are only needed for CPU version and for debugging
float* m_hLambdaDtBox;
float4* m_hContact; // 8 floats : pos.x, pos.y, pos.z, penetration, norm.x, norm.y, norm.z, reserved
// -------------
btScalar m_objRad;
btVector3 m_worldMin;
btVector3 m_worldMax;
int* m_hConstraintUsed;
// shape buffer
int m_maxShapeBufferSize;
int m_firstFreeShapeBufferOffset;
char* m_hShapeBuffer; // (pos.x, pos.y, pos.z, radius)
char* m_dShapeBuffer;//pointer in device memory
int2* m_hShapeIds;
int2* m_dShapeIds;
bool m_copyShapeDataToGPU;
void initShapeBuffer(int maxShapeBufferSize);
void freeShapeBuffer();
void sendShapeDataToGpu();
int m_numNonContactConstraints;
void grabNonContactConstraintData();
void grabP2PConstraintData(btPoint2PointConstraint* ct);
public:
int m_numInBatches[CUDA_DEMO_DYNAMICS_WORLD_MAX_BATCHES];
void addSphere(btVector3& pos, btScalar rad);
void addMultiShereObject(int numSpheres, int objIndex);
btGpuDemoDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration,
int maxObjs = CUDA_DEMO_DYNAMICS_WORLD_MAX_OBJS, int maxNeighbors = CUDA_DEMO_DYNAMICS_WORLD_MAX_NEIGHBORS)
: btDiscreteDynamicsWorld(dispatcher, pairCache, constraintSolver, collisionConfiguration)
{
m_maxObjs = maxObjs;
m_maxNeighbors = maxNeighbors;
m_useCPUSolver = false;
m_pairCache = pairCache->getOverlappingPairCache();
int sz = m_maxObjs * m_maxNeighbors;
m_hConstraintBuffer = new int[sz];
m_hConstraintCounter = new int[m_maxObjs];
m_maxBatches = CUDA_DEMO_DYNAMICS_WORLD_MAX_BATCHES;
m_hIds = new int2[sz];
m_hBatchIds = new int[sz];
for(int i = 0; i < sz; i++)
{
m_hBatchIds[i] = -1;
}
m_hPos = new float4[m_maxObjs];
m_hVel = new float4[m_maxObjs];
m_hRot = new float[m_maxObjs];
m_hAngVel = new float[m_maxObjs];
m_hInvMass = new float[m_maxObjs];
m_maxVtxPerObj = 8;
#ifdef BT_USE_CUDA
btCuda_allocateArray((void**)&m_dPos, sizeof(float4) * m_maxObjs);
btCuda_allocateArray((void**)&m_dRot, sizeof(float) * m_maxObjs);
btCuda_allocateArray((void**)&m_dVel, sizeof(float4) * m_maxObjs);
btCuda_allocateArray((void**)&m_dAngVel, sizeof(float) * m_maxObjs);
btCuda_allocateArray((void**)&m_dpPos, sizeof(float4) * m_maxObjs);
btCuda_allocateArray((void**)&m_dpRot, sizeof(float) * m_maxObjs);
btCuda_allocateArray((void**)&m_dpVel, sizeof(float4) * m_maxObjs);
btCuda_allocateArray((void**)&m_dpAngVel, sizeof(float) * m_maxObjs);
btCuda_allocateArray((void**)&m_dInvMass, sizeof(float) * m_maxObjs);
btCuda_allocateArray((void**)&m_dIds, sizeof(int2) * sz);
btCuda_allocateArray((void**)&m_dBatchIds, sizeof(int) * sz);
btCuda_allocateArray((void**)&m_dLambdaDtBox, sizeof(float) * sz * m_maxVtxPerObj);
btCuda_allocateArray((void**)&m_dContact, sizeof(float) * sz * m_maxVtxPerObj * 8);
// btCuda_allocateArray((void**)&m_dPositionConstraint, sizeof(float) * sz * m_maxVtxPerObj * 2);
// btCuda_allocateArray((void**)&m_dNormal, sizeof(float3) * sz * m_maxVtxPerObj * 2);
#endif //BT_USE_CUDA
m_hLambdaDtBox = new float[sz * m_maxVtxPerObj];
m_hContact = new float4[sz * m_maxVtxPerObj * 2];
// m_hPositionConstraint = new float[sz * m_maxVtxPerObj * 2];
// m_hNormal = new float3[sz * m_maxVtxPerObj * 2];
m_numSimStep = 0;
m_objRad = 1.0f;
m_hConstraintUsed = new int[sz];
gpCudaDemoDynamicsWorld = this;
m_totalNumConstraints = 0;
initShapeBuffer(m_maxObjs * CUDA_DEMO_DYNAMICS_WORLD_MAX_SPHERES_PER_OBJ * sizeof(float) * 4);
m_copyMassDataToGPU = true;
}
virtual ~btGpuDemoDynamicsWorld()
{
delete [] m_hConstraintBuffer;
delete [] m_hConstraintCounter;
delete [] m_hIds;
delete [] m_hBatchIds;
delete [] m_hPos;
delete [] m_hRot;
delete [] m_hVel;
delete [] m_hAngVel;
delete [] m_hInvMass;
#ifdef BT_USE_CUDA
btCuda_freeArray(m_dPos);
btCuda_freeArray(m_dRot);
btCuda_freeArray(m_dVel);
btCuda_freeArray(m_dAngVel);
btCuda_freeArray(m_dpPos);
btCuda_freeArray(m_dpRot);
btCuda_freeArray(m_dpVel);
btCuda_freeArray(m_dpAngVel);
btCuda_freeArray(m_dInvMass);
btCuda_freeArray(m_dIds);
btCuda_freeArray(m_dBatchIds);
btCuda_freeArray(m_dLambdaDtBox);
btCuda_freeArray(m_dContact);
#endif //BT_USE_CUDA
delete [] m_hLambdaDtBox;
delete [] m_hContact;
delete [] m_hConstraintUsed;
gpCudaDemoDynamicsWorld = NULL;
freeShapeBuffer();
}
virtual void calculateSimulationIslands()
{
}
virtual void solveConstraints(btContactSolverInfo& solverInfo);
void solveConstraints2(btContactSolverInfo& solverInfo);
void solveConstraintsCPU2(btContactSolverInfo& solverInfo);
void debugDrawConstraints(int selectedBatch, const float* pColorTab);
void setObjRad(btScalar rad) { m_objRad = rad; }
void setWorldMin(const btVector3& worldMin) { m_worldMin = worldMin; }
void setWorldMax(const btVector3& worldMax) { m_worldMax = worldMax; }
void grabData();
void grabContactData();
void copyDataToGPU();
void setConstraintData(btCudaPartProps& partProps);
void copyDataFromGPU();
void writebackData();
void setUseCPUSolver(bool useCPU) { m_useCPUSolver = useCPU; }
void setUseBulletNarrowphase(bool useBulletNarrowphase) {m_useBulletNarrowphase = useBulletNarrowphase; }
void createBatches2();
int2* getIdsPtr() { return m_hIds; }
void setTotalNumConstraints(int totalNumConstraints) { m_totalNumConstraints = totalNumConstraints; }
int getTotalNumConstraints() { return m_totalNumConstraints; }
};
#endif //BT_CUDA_DEMO_DYNAMICS_WORLD_H
/*
Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org
Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
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.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BT_CUDA_DEMO_DYNAMICS_WORLD_H
#define BT_CUDA_DEMO_DYNAMICS_WORLD_H
#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h"
//#define BT_USE_CUDA 1
// To enable CUDA :
// 1. Uncomment //#define BT_USE_CUDA 1
// 2. Build and add libbulletcuda (Extras/CUDA) to project
// 3. Add $(CUDA_LIB_PATH) and cudart.lib to linker properties
#ifdef BT_USE_CUDA
// #include "btCudaDemoPairCache.h"
// #include <vector_types.h>
#include "BulletMultiThreaded/btGpuDefines.h"
#undef BT_GPU_PREF
#define BT_GPU_PREF(func) btCuda_##func
#include "BulletMultiThreaded/btGpuUtilsSharedDefs.h"
#else
#include "BulletMultiThreaded/btGpuDefines.h"
#include "../../src/BulletMultiThreaded/btGpuUtilsSharedDefs.h"
#endif
#undef BT_GPU_PREF
#include "btGpuDemo2dSharedTypes.h"
#define CUDA_DEMO_DYNAMICS_WORLD_MAX_BATCHES 20
#define CUDA_DEMO_DYNAMICS_WORLD_MAX_OBJS 1024
#define CUDA_DEMO_DYNAMICS_WORLD_MAX_NEIGHBORS 24
#define CUDA_DEMO_DYNAMICS_WORLD_MAX_SPHERES_PER_OBJ 8
class btGpuDemoDynamicsWorld;
extern btGpuDemoDynamicsWorld* gpCudaDemoDynamicsWorld; // to access world members from pair cache
class btGpuDemoDynamicsWorld : public btDiscreteDynamicsWorld
{
protected:
int m_maxObjs;
int m_maxNeighbors;
int m_numObj;
int m_numSimStep;
bool m_useCPUSolver;
bool m_useBulletNarrowphase;
float4* m_hPos;
float* m_hRot;
float4* m_hVel;
float* m_hAngVel;
float* m_hInvMass;
float* m_dInvMass;
bool m_copyMassDataToGPU;
#ifdef BT_USE_CUDA
float4* m_dPos;
float* m_dRot;
float4* m_dVel;
float* m_dAngVel;
float4* m_dpPos;
float* m_dpRot;
float4* m_dpVel;
float* m_dpAngVel;
float4* m_dcPos;
float* m_dcRot;
float4* m_dcVel;
float* m_dcAngVel;
#endif //BT_USE_CUDA
btOverlappingPairCache* m_pairCache;
int* m_hConstraintBuffer;
int* m_hConstraintCounter;
int m_maxBatches;
int m_numBatches;
int m_totalNumConstraints;
int2* m_hIds;
int* m_hBatchIds;
int m_maxVtxPerObj;
int2* m_dIds;
int* m_dBatchIds;
float* m_dLambdaDtBox;
float4* m_dContact; // 8 floats : pos.x, pos.y, pos.z, penetration, norm.x, norm.y, norm.z, reserved
// ------------- these are only needed for CPU version and for debugging
float* m_hLambdaDtBox;
float4* m_hContact; // 8 floats : pos.x, pos.y, pos.z, penetration, norm.x, norm.y, norm.z, reserved
// -------------
btScalar m_objRad;
btVector3 m_worldMin;
btVector3 m_worldMax;
int* m_hConstraintUsed;
// shape buffer
int m_maxShapeBufferSize;
int m_firstFreeShapeBufferOffset;
char* m_hShapeBuffer; // (pos.x, pos.y, pos.z, radius)
char* m_dShapeBuffer;//pointer in device memory
int2* m_hShapeIds;
int2* m_dShapeIds;
bool m_copyShapeDataToGPU;
void initShapeBuffer(int maxShapeBufferSize);
void freeShapeBuffer();
void sendShapeDataToGpu();
int m_numNonContactConstraints;
void grabNonContactConstraintData();
void grabP2PConstraintData(btPoint2PointConstraint* ct);
public:
int m_numInBatches[CUDA_DEMO_DYNAMICS_WORLD_MAX_BATCHES];
void addSphere(btVector3& pos, btScalar rad);
void addMultiShereObject(int numSpheres, int objIndex);
btGpuDemoDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration,
int maxObjs = CUDA_DEMO_DYNAMICS_WORLD_MAX_OBJS, int maxNeighbors = CUDA_DEMO_DYNAMICS_WORLD_MAX_NEIGHBORS)
: btDiscreteDynamicsWorld(dispatcher, pairCache, constraintSolver, collisionConfiguration)
{
m_maxObjs = maxObjs;
m_maxNeighbors = maxNeighbors;
m_useCPUSolver = false;
m_pairCache = pairCache->getOverlappingPairCache();
int sz = m_maxObjs * m_maxNeighbors;
m_hConstraintBuffer = new int[sz];
m_hConstraintCounter = new int[m_maxObjs];
m_maxBatches = CUDA_DEMO_DYNAMICS_WORLD_MAX_BATCHES;
m_hIds = new int2[sz];
m_hBatchIds = new int[sz];
for(int i = 0; i < sz; i++)
{
m_hBatchIds[i] = -1;
}
m_hPos = new float4[m_maxObjs];
m_hVel = new float4[m_maxObjs];
m_hRot = new float[m_maxObjs];
m_hAngVel = new float[m_maxObjs];
m_hInvMass = new float[m_maxObjs];
m_maxVtxPerObj = 8;
#ifdef BT_USE_CUDA
btCuda_allocateArray((void**)&m_dPos, sizeof(float4) * m_maxObjs);
btCuda_allocateArray((void**)&m_dRot, sizeof(float) * m_maxObjs);
btCuda_allocateArray((void**)&m_dVel, sizeof(float4) * m_maxObjs);
btCuda_allocateArray((void**)&m_dAngVel, sizeof(float) * m_maxObjs);
btCuda_allocateArray((void**)&m_dpPos, sizeof(float4) * m_maxObjs);
btCuda_allocateArray((void**)&m_dpRot, sizeof(float) * m_maxObjs);
btCuda_allocateArray((void**)&m_dpVel, sizeof(float4) * m_maxObjs);
btCuda_allocateArray((void**)&m_dpAngVel, sizeof(float) * m_maxObjs);
btCuda_allocateArray((void**)&m_dInvMass, sizeof(float) * m_maxObjs);
btCuda_allocateArray((void**)&m_dIds, sizeof(int2) * sz);
btCuda_allocateArray((void**)&m_dBatchIds, sizeof(int) * sz);
btCuda_allocateArray((void**)&m_dLambdaDtBox, sizeof(float) * sz * m_maxVtxPerObj);
btCuda_allocateArray((void**)&m_dContact, sizeof(float) * sz * m_maxVtxPerObj * 8);
// btCuda_allocateArray((void**)&m_dPositionConstraint, sizeof(float) * sz * m_maxVtxPerObj * 2);
// btCuda_allocateArray((void**)&m_dNormal, sizeof(float3) * sz * m_maxVtxPerObj * 2);
#endif //BT_USE_CUDA
m_hLambdaDtBox = new float[sz * m_maxVtxPerObj];
m_hContact = new float4[sz * m_maxVtxPerObj * 2];
// m_hPositionConstraint = new float[sz * m_maxVtxPerObj * 2];
// m_hNormal = new float3[sz * m_maxVtxPerObj * 2];
m_numSimStep = 0;
m_objRad = 1.0f;
m_hConstraintUsed = new int[sz];
gpCudaDemoDynamicsWorld = this;
m_totalNumConstraints = 0;
initShapeBuffer(m_maxObjs * CUDA_DEMO_DYNAMICS_WORLD_MAX_SPHERES_PER_OBJ * sizeof(float) * 4);
m_copyMassDataToGPU = true;
}
virtual ~btGpuDemoDynamicsWorld()
{
delete [] m_hConstraintBuffer;
delete [] m_hConstraintCounter;
delete [] m_hIds;
delete [] m_hBatchIds;
delete [] m_hPos;
delete [] m_hRot;
delete [] m_hVel;
delete [] m_hAngVel;
delete [] m_hInvMass;
#ifdef BT_USE_CUDA
btCuda_freeArray(m_dPos);
btCuda_freeArray(m_dRot);
btCuda_freeArray(m_dVel);
btCuda_freeArray(m_dAngVel);
btCuda_freeArray(m_dpPos);
btCuda_freeArray(m_dpRot);
btCuda_freeArray(m_dpVel);
btCuda_freeArray(m_dpAngVel);
btCuda_freeArray(m_dInvMass);
btCuda_freeArray(m_dIds);
btCuda_freeArray(m_dBatchIds);
btCuda_freeArray(m_dLambdaDtBox);
btCuda_freeArray(m_dContact);
#endif //BT_USE_CUDA
delete [] m_hLambdaDtBox;
delete [] m_hContact;
delete [] m_hConstraintUsed;
gpCudaDemoDynamicsWorld = NULL;
freeShapeBuffer();
}
virtual void calculateSimulationIslands()
{
}
virtual void solveConstraints(btContactSolverInfo& solverInfo);
void solveConstraints2(btContactSolverInfo& solverInfo);
void solveConstraintsCPU2(btContactSolverInfo& solverInfo);
void debugDrawConstraints(int selectedBatch, const float* pColorTab);
void setObjRad(btScalar rad) { m_objRad = rad; }
void setWorldMin(const btVector3& worldMin) { m_worldMin = worldMin; }
void setWorldMax(const btVector3& worldMax) { m_worldMax = worldMax; }
void grabData();
void grabContactData();
void copyDataToGPU();
void setConstraintData(btCudaPartProps& partProps);
void copyDataFromGPU();
void writebackData();
void setUseCPUSolver(bool useCPU) { m_useCPUSolver = useCPU; }
void setUseBulletNarrowphase(bool useBulletNarrowphase) {m_useBulletNarrowphase = useBulletNarrowphase; }
void createBatches2();
int2* getIdsPtr() { return m_hIds; }
void setTotalNumConstraints(int totalNumConstraints) { m_totalNumConstraints = totalNumConstraints; }
int getTotalNumConstraints() { return m_totalNumConstraints; }
};
#endif //BT_CUDA_DEMO_DYNAMICS_WORLD_H

View File

@@ -1,76 +1,76 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
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.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
#include "btGpuDemoPairCache.h"
#include "btGpuDemoDynamicsWorld.h"
void btGpuDemoPairCache::processAllOverlappingPairs(btOverlapCallback* callback, btDispatcher* dispatcher)
{
int sz = m_maxProxies * m_maxNeighbors;
int numContConstraints = 0;
int2* pIds = gpCudaDemoDynamicsWorld->getIdsPtr();
for(int idx = 0; idx < sz; idx++)
{
int neigh = m_hNeighbors[idx];
if(neigh >= 0)
{
int i=idx / m_maxNeighbors;
int j=idx % m_maxNeighbors;
pIds[numContConstraints].x = i;
pIds[numContConstraints].y = m_hNeighbors[i * m_maxNeighbors + j];
numContConstraints++;
}
}
gpCudaDemoDynamicsWorld->setTotalNumConstraints(numContConstraints);
}
// this will be called for each overlapping pair if collision detection uses pairCache other than btGpuDemoPairCache
// IMPORTANT : m_numConstraints in gpCudaDemoDynamicsWorld is set to 0 at start of simulation step
// IMPORTANT : companionIds for all objects should be properly set at start of simulation step
void cudaDemoNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo)
{
btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;
if (dispatcher.needsCollision(colObj0,colObj1))
{
// int id0 = collisionPair.m_pProxy0->m_uniqueId - 2;
// int id1 = collisionPair.m_pProxy1->m_uniqueId - 2;
// cannot use m_uniqueId : it may be altered by broadphase code
// so we'll use companionIds set on the initialization stage
unsigned int id0 = colObj0->getCompanionId();
unsigned int id1 = colObj1->getCompanionId();
if(id0 > id1)
{
int tmp = id0; id0 = id1; id1 = tmp;
}
int totalNumConstraints = gpCudaDemoDynamicsWorld->getTotalNumConstraints();
int2* pIds = gpCudaDemoDynamicsWorld->getIdsPtr();
pIds += totalNumConstraints;
pIds->x = id0;
pIds->y = id1;
totalNumConstraints++;
gpCudaDemoDynamicsWorld->setTotalNumConstraints(totalNumConstraints);
}
} // cudaDemoNearCallback()
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
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.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
#include "btGpuDemoPairCache.h"
#include "btGpuDemoDynamicsWorld.h"
void btGpuDemoPairCache::processAllOverlappingPairs(btOverlapCallback* callback, btDispatcher* dispatcher)
{
int sz = m_maxProxies * m_maxNeighbors;
int numContConstraints = 0;
int2* pIds = gpCudaDemoDynamicsWorld->getIdsPtr();
for(int idx = 0; idx < sz; idx++)
{
int neigh = m_hNeighbors[idx];
if(neigh >= 0)
{
int i=idx / m_maxNeighbors;
int j=idx % m_maxNeighbors;
pIds[numContConstraints].x = i;
pIds[numContConstraints].y = m_hNeighbors[i * m_maxNeighbors + j];
numContConstraints++;
}
}
gpCudaDemoDynamicsWorld->setTotalNumConstraints(numContConstraints);
}
// this will be called for each overlapping pair if collision detection uses pairCache other than btGpuDemoPairCache
// IMPORTANT : m_numConstraints in gpCudaDemoDynamicsWorld is set to 0 at start of simulation step
// IMPORTANT : companionIds for all objects should be properly set at start of simulation step
void cudaDemoNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo)
{
btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;
if (dispatcher.needsCollision(colObj0,colObj1))
{
// int id0 = collisionPair.m_pProxy0->m_uniqueId - 2;
// int id1 = collisionPair.m_pProxy1->m_uniqueId - 2;
// cannot use m_uniqueId : it may be altered by broadphase code
// so we'll use companionIds set on the initialization stage
unsigned int id0 = colObj0->getCompanionId();
unsigned int id1 = colObj1->getCompanionId();
if(id0 > id1)
{
int tmp = id0; id0 = id1; id1 = tmp;
}
int totalNumConstraints = gpCudaDemoDynamicsWorld->getTotalNumConstraints();
int2* pIds = gpCudaDemoDynamicsWorld->getIdsPtr();
pIds += totalNumConstraints;
pIds->x = id0;
pIds->y = id1;
totalNumConstraints++;
gpCudaDemoDynamicsWorld->setTotalNumConstraints(totalNumConstraints);
}
} // cudaDemoNearCallback()

View File

@@ -1,136 +1,136 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
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.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef CUDA_DEMO_PAIR_CACHE_H
#define CUDA_DEMO_PAIR_CACHE_H
#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h"
#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
#include "LinearMath/btAlignedObjectArray.h"
class btGpuDemoPairCache : public btNullPairCache
{
public:
int m_maxProxies;
int m_maxNeighbors;
int* m_hNeighbors;
int m_numPairs;
int m_numSmallProxies;
int m_maxSmallProxies;
btGpuDemoPairCache(int maxProxies, int maxNeighbors, int maxSmallProxies)
{
m_maxProxies = maxProxies;
m_maxNeighbors = maxNeighbors;
m_maxSmallProxies = maxSmallProxies;
int sz = maxProxies * maxNeighbors;
m_hNeighbors = new int [sz];
reset();
}
~btGpuDemoPairCache()
{
delete [] m_hNeighbors;
}
void reset(void)
{
int sz = m_maxProxies * m_maxNeighbors;
for(int i = 0; i < sz; i++)
{
m_hNeighbors[i] = -1;
}
m_numPairs = 0;
}
virtual int getNumOverlappingPairs() const
{
return m_numPairs;
//return 0; // to skip btSimulationIslandManager::findUnions()
}
virtual void processAllOverlappingPairs(btOverlapCallback* callback, btDispatcher* dispatcher);
virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1)
{
int id0 = proxy0->m_uniqueId - 2;
int id1 = proxy1->m_uniqueId - 2;
if(id0 >= m_maxSmallProxies)
{
id0 -= m_maxSmallProxies - m_numSmallProxies;
}
if(id1 >= m_maxSmallProxies)
{
id1 -= m_maxSmallProxies - m_numSmallProxies;
}
if(id0 > id1)
{
int tmp = id0; id0 = id1; id1 = tmp;
}
int offs = id0 * m_maxNeighbors;
int i;
for(i = 0; i < m_maxNeighbors; i++)
{
if(m_hNeighbors[offs + i] < 0)
{
m_hNeighbors[offs + i] = id1;
m_numPairs++;
break;
}
}
// btAssert(i < m_maxNeighbors);
return 0;
}
virtual void* removeOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1,btDispatcher* /*dispatcher*/)
{
int id0 = proxy0->m_uniqueId - 2;
int id1 = proxy1->m_uniqueId - 2;
if(id0 >= m_maxSmallProxies)
{
id0 -= m_maxSmallProxies - m_numSmallProxies;
}
if(id1 >= m_maxSmallProxies)
{
id1 -= m_maxSmallProxies - m_numSmallProxies;
}
if(id0 > id1)
{
int tmp = id0; id0 = id1; id1 = tmp;
}
int offs = id0 * m_maxNeighbors;
int i;
for(i = 0; i < m_maxNeighbors; i++)
{
if(m_hNeighbors[offs + i] == id1)
{
m_hNeighbors[offs + i] = -1;
m_numPairs--;
break;
}
}
// btAssert(i < m_maxNeighbors);
return 0;
}
};
extern void cudaDemoNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo);
#endif //CUDA_DEMO_PAIR_CACHE_H
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
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.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef CUDA_DEMO_PAIR_CACHE_H
#define CUDA_DEMO_PAIR_CACHE_H
#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h"
#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
#include "LinearMath/btAlignedObjectArray.h"
class btGpuDemoPairCache : public btNullPairCache
{
public:
int m_maxProxies;
int m_maxNeighbors;
int* m_hNeighbors;
int m_numPairs;
int m_numSmallProxies;
int m_maxSmallProxies;
btGpuDemoPairCache(int maxProxies, int maxNeighbors, int maxSmallProxies)
{
m_maxProxies = maxProxies;
m_maxNeighbors = maxNeighbors;
m_maxSmallProxies = maxSmallProxies;
int sz = maxProxies * maxNeighbors;
m_hNeighbors = new int [sz];
reset();
}
~btGpuDemoPairCache()
{
delete [] m_hNeighbors;
}
void reset(void)
{
int sz = m_maxProxies * m_maxNeighbors;
for(int i = 0; i < sz; i++)
{
m_hNeighbors[i] = -1;
}
m_numPairs = 0;
}
virtual int getNumOverlappingPairs() const
{
return m_numPairs;
//return 0; // to skip btSimulationIslandManager::findUnions()
}
virtual void processAllOverlappingPairs(btOverlapCallback* callback, btDispatcher* dispatcher);
virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1)
{
int id0 = proxy0->m_uniqueId - 2;
int id1 = proxy1->m_uniqueId - 2;
if(id0 >= m_maxSmallProxies)
{
id0 -= m_maxSmallProxies - m_numSmallProxies;
}
if(id1 >= m_maxSmallProxies)
{
id1 -= m_maxSmallProxies - m_numSmallProxies;
}
if(id0 > id1)
{
int tmp = id0; id0 = id1; id1 = tmp;
}
int offs = id0 * m_maxNeighbors;
int i;
for(i = 0; i < m_maxNeighbors; i++)
{
if(m_hNeighbors[offs + i] < 0)
{
m_hNeighbors[offs + i] = id1;
m_numPairs++;
break;
}
}
// btAssert(i < m_maxNeighbors);
return 0;
}
virtual void* removeOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1,btDispatcher* /*dispatcher*/)
{
int id0 = proxy0->m_uniqueId - 2;
int id1 = proxy1->m_uniqueId - 2;
if(id0 >= m_maxSmallProxies)
{
id0 -= m_maxSmallProxies - m_numSmallProxies;
}
if(id1 >= m_maxSmallProxies)
{
id1 -= m_maxSmallProxies - m_numSmallProxies;
}
if(id0 > id1)
{
int tmp = id0; id0 = id1; id1 = tmp;
}
int offs = id0 * m_maxNeighbors;
int i;
for(i = 0; i < m_maxNeighbors; i++)
{
if(m_hNeighbors[offs + i] == id1)
{
m_hNeighbors[offs + i] = -1;
m_numPairs--;
break;
}
}
// btAssert(i < m_maxNeighbors);
return 0;
}
};
extern void cudaDemoNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo);
#endif //CUDA_DEMO_PAIR_CACHE_H

View File

@@ -1,62 +1,62 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2007 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
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.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "BasicDemo.h"
#include "GlutStuff.h"
#include "GLDebugDrawer.h"
#include "btBulletDynamicsCommon.h"
#include "LinearMath/btHashMap.h"
class OurValue
{
int m_uid;
public:
OurValue(const btVector3& initialPos)
:m_position(initialPos)
{
static int gUid=0;
m_uid=gUid;
gUid++;
}
btVector3 m_position;
int getUid() const
{
return m_uid;
}
};
GLDebugDrawer gDebugDrawer;
int main(int argc,char** argv)
{
BasicDemo ccdDemo;
ccdDemo.initPhysics();
ccdDemo.getDynamicsWorld()->setDebugDrawer(&gDebugDrawer);
#ifdef CHECK_MEMORY_LEAKS
ccdDemo.exitPhysics();
#else
return glutmain(argc, argv,640,480,"Bullet Physics Demo. http://bulletphysics.com",&ccdDemo);
#endif
//default glut doesn't return from mainloop
return 0;
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2007 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
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.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "BasicDemo.h"
#include "GlutStuff.h"
#include "GLDebugDrawer.h"
#include "btBulletDynamicsCommon.h"
#include "LinearMath/btHashMap.h"
class OurValue
{
int m_uid;
public:
OurValue(const btVector3& initialPos)
:m_position(initialPos)
{
static int gUid=0;
m_uid=gUid;
gUid++;
}
btVector3 m_position;
int getUid() const
{
return m_uid;
}
};
GLDebugDrawer gDebugDrawer;
int main(int argc,char** argv)
{
BasicDemo ccdDemo;
ccdDemo.initPhysics();
ccdDemo.getDynamicsWorld()->setDebugDrawer(&gDebugDrawer);
#ifdef CHECK_MEMORY_LEAKS
ccdDemo.exitPhysics();
#else
return glutmain(argc, argv,640,480,"Bullet Physics Demo. http://bulletphysics.com",&ccdDemo);
#endif
//default glut doesn't return from mainloop
return 0;
}

View File

@@ -1,264 +1,264 @@
#include "oecakeLoader.h"
#include <stdio.h> //printf debugging
#include <stdlib.h>
btCompoundShape* shiftTransform(btCompoundShape* boxCompound,btScalar mass,btTransform& shift)
{
btTransform principal;
btVector3 principalInertia;
btScalar* masses = new btScalar[boxCompound->getNumChildShapes()];
for (int j=0;j<boxCompound->getNumChildShapes();j++)
{
//evenly distribute mass
masses[j]=mass/boxCompound->getNumChildShapes();
}
boxCompound->calculatePrincipalAxisTransform(masses,principal,principalInertia);
///create a new compound with world transform/center of mass properly aligned with the principal axis
///non-recursive compound shapes perform better
//#define USE_RECURSIVE_COMPOUND 1
#ifdef USE_RECURSIVE_COMPOUND
btCompoundShape* newCompound = new btCompoundShape();
newCompound->addChildShape(principal.inverse(),boxCompound);
m_collisionShapes.push_back(newCompound);
btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,newCompound,principalInertia);
#else
#ifdef CHANGE_COMPOUND_INPLACE
for (int i=0;i<boxCompound->getNumChildShapes();i++)
{
btTransform newChildTransform = principal.inverse()*boxCompound->getChildTransform(i);
///updateChildTransform is really slow, because it re-calculates the AABB each time. todo: add option to disable this update
boxCompound->updateChildTransform(i,newChildTransform);
}
if (isDynamic)
boxCompound->calculateLocalInertia(mass,localInertia);
btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,boxCompound,localInertia);
#else
///creation is faster using a new compound to store the shifted children
btCompoundShape* newBoxCompound = new btCompoundShape();
for (int i=0;i<boxCompound->getNumChildShapes();i++)
{
btTransform newChildTransform = principal.inverse()*boxCompound->getChildTransform(i);
///updateChildTransform is really slow, because it re-calculates the AABB each time. todo: add option to disable this update
newBoxCompound->addChildShape(newChildTransform,boxCompound->getChildShape(i));
}
#endif
#endif//USE_RECURSIVE_COMPOUND
shift = principal;
return newBoxCompound;
}
void BasicOECakeReader::addParticle(int materialType, int pIndex, int pColor, float pPosX, float pPosY,float radius)
{
//determine that we have a new shape?
if (m_particlePositions.size())
{
if (
(materialType != m_materialType)
||
(pIndex != m_particleObjectIndex)
)
{
convertParticleGroup();
}
}
//add to array
m_materialType = materialType;
m_particleObjectIndex = pIndex;
m_particleColor = pColor;
m_particlePositions.push_back(btVector3(pPosX,pPosY,0.));
m_particleRadii.push_back(radius);
}
void BasicOECakeReader::convertParticleGroup()
{
printf("found a particle group of %d particles\n",m_particlePositions.size());
if (m_particlePositions.size()>0)
{
addNewCollisionShape(m_particlePositions.size(),&m_particlePositions[0],&m_particleRadii[0],m_materialType,m_particleObjectIndex,m_particleColor);
m_particlePositions.clear();
m_particleRadii.clear();
}
}
void BasicOECakeReader::addNewCollisionShape(int numParticles, btVector3* particlePositions, btScalar* radii, int materialType, int objectIndex,int color )
{
//create Bullet stuff
btCompoundShape* colShape = 0;
btScalar mass;
bool addConstraint = false;
if (materialType&0x800000)
{
addConstraint = true;
}
if ((materialType & 0x20000) ||(materialType & 0x12))
{
mass = 1.f;
} else
{
mass = 0.f;
}
btTransform startTransform;
startTransform.setIdentity();
int numCurSpheres = 0;
{
btTransform localTrans;
localTrans.setIdentity();
//static
btCompoundShape* compound = new btCompoundShape();
for (int i=0;i<numParticles;i++)
{
numCurSpheres++;
localTrans.setOrigin(particlePositions[i]);
btSphereShape* particle = new btSphereShape(radii[i]);
compound->addChildShape(localTrans,particle);
if (mass==0.f && (numCurSpheres>=7))
{
createBodyForCompoundShape(compound,false,startTransform,mass);
compound = new btCompoundShape();
numCurSpheres = 0;
}
}
if (mass)
{
//shift the center of mass, based on all spheres
btCompoundShape* newCompound = shiftTransform(compound,mass,startTransform);
colShape = newCompound;
} else
{
//use unmodified
colShape = compound;
}
}
btDefaultMotionState* myMotionState = 0;
if (colShape && numCurSpheres)
{
createBodyForCompoundShape(colShape,addConstraint,startTransform,mass);
}
}
int BasicOECakeReader::processLine(char * buffer, int size)
{
int numBytesRead = 0;
if (buffer[0] == 'p')
{
int materialType;
int particleObjectIndex;
int particleColor;
int dummy1;
float particlePosX;
float particlePosY;
if (sscanf (buffer, "p %x %x %x %x %f %f", &materialType,&particleObjectIndex,&dummy1, &particleColor, &particlePosX, &particlePosY) == 6)
{
addParticle(materialType,particleObjectIndex,particleColor,particlePosX,particlePosY);
}
else
{
printf("ERROR: invalid line (%s)\n", buffer);
}
}
while (*buffer != '\n' && size != 0)
{
buffer++;
numBytesRead++;
}
if (buffer[0]==0x0a)
{
buffer++;
numBytesRead++;
}
return numBytesRead;
}
bool BasicOECakeReader::processFile(char * fileName)
{
FILE * fp = fopen(fileName, "rb");
if (fp == NULL)
{
printf("ERROR: file(%s) not found", fileName);
return false;
}
int size;
if (fseek(fp, 0, SEEK_END) || (size = ftell(fp)) == EOF || fseek(fp, 0, SEEK_SET))
{
printf("ERROR: problem reading file(%s)", fileName);
fclose(fp);
return false;
}
else
{
rewind (fp);
char * buffer = (char *) malloc(size+1);
memset(buffer,0,size);
if (fread(buffer,1,size,fp) != size)
{
printf("Error reading file %s!\n",fileName);
fclose(fp);
return false;
}
int totalBytesRead = 0;
while(totalBytesRead<size)
{
int remainingSize = size-totalBytesRead;
if (remainingSize<1229)
{
printf("..");
}
totalBytesRead +=processLine(&buffer[totalBytesRead],remainingSize);
}
}
convertParticleGroup();
fclose(fp);
return false;
}
#include "oecakeLoader.h"
#include <stdio.h> //printf debugging
#include <stdlib.h>
btCompoundShape* shiftTransform(btCompoundShape* boxCompound,btScalar mass,btTransform& shift)
{
btTransform principal;
btVector3 principalInertia;
btScalar* masses = new btScalar[boxCompound->getNumChildShapes()];
for (int j=0;j<boxCompound->getNumChildShapes();j++)
{
//evenly distribute mass
masses[j]=mass/boxCompound->getNumChildShapes();
}
boxCompound->calculatePrincipalAxisTransform(masses,principal,principalInertia);
///create a new compound with world transform/center of mass properly aligned with the principal axis
///non-recursive compound shapes perform better
//#define USE_RECURSIVE_COMPOUND 1
#ifdef USE_RECURSIVE_COMPOUND
btCompoundShape* newCompound = new btCompoundShape();
newCompound->addChildShape(principal.inverse(),boxCompound);
m_collisionShapes.push_back(newCompound);
btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,newCompound,principalInertia);
#else
#ifdef CHANGE_COMPOUND_INPLACE
for (int i=0;i<boxCompound->getNumChildShapes();i++)
{
btTransform newChildTransform = principal.inverse()*boxCompound->getChildTransform(i);
///updateChildTransform is really slow, because it re-calculates the AABB each time. todo: add option to disable this update
boxCompound->updateChildTransform(i,newChildTransform);
}
if (isDynamic)
boxCompound->calculateLocalInertia(mass,localInertia);
btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,boxCompound,localInertia);
#else
///creation is faster using a new compound to store the shifted children
btCompoundShape* newBoxCompound = new btCompoundShape();
for (int i=0;i<boxCompound->getNumChildShapes();i++)
{
btTransform newChildTransform = principal.inverse()*boxCompound->getChildTransform(i);
///updateChildTransform is really slow, because it re-calculates the AABB each time. todo: add option to disable this update
newBoxCompound->addChildShape(newChildTransform,boxCompound->getChildShape(i));
}
#endif
#endif//USE_RECURSIVE_COMPOUND
shift = principal;
return newBoxCompound;
}
void BasicOECakeReader::addParticle(int materialType, int pIndex, int pColor, float pPosX, float pPosY,float radius)
{
//determine that we have a new shape?
if (m_particlePositions.size())
{
if (
(materialType != m_materialType)
||
(pIndex != m_particleObjectIndex)
)
{
convertParticleGroup();
}
}
//add to array
m_materialType = materialType;
m_particleObjectIndex = pIndex;
m_particleColor = pColor;
m_particlePositions.push_back(btVector3(pPosX,pPosY,0.));
m_particleRadii.push_back(radius);
}
void BasicOECakeReader::convertParticleGroup()
{
printf("found a particle group of %d particles\n",m_particlePositions.size());
if (m_particlePositions.size()>0)
{
addNewCollisionShape(m_particlePositions.size(),&m_particlePositions[0],&m_particleRadii[0],m_materialType,m_particleObjectIndex,m_particleColor);
m_particlePositions.clear();
m_particleRadii.clear();
}
}
void BasicOECakeReader::addNewCollisionShape(int numParticles, btVector3* particlePositions, btScalar* radii, int materialType, int objectIndex,int color )
{
//create Bullet stuff
btCompoundShape* colShape = 0;
btScalar mass;
bool addConstraint = false;
if (materialType&0x800000)
{
addConstraint = true;
}
if ((materialType & 0x20000) ||(materialType & 0x12))
{
mass = 1.f;
} else
{
mass = 0.f;
}
btTransform startTransform;
startTransform.setIdentity();
int numCurSpheres = 0;
{
btTransform localTrans;
localTrans.setIdentity();
//static
btCompoundShape* compound = new btCompoundShape();
for (int i=0;i<numParticles;i++)
{
numCurSpheres++;
localTrans.setOrigin(particlePositions[i]);
btSphereShape* particle = new btSphereShape(radii[i]);
compound->addChildShape(localTrans,particle);
if (mass==0.f && (numCurSpheres>=7))
{
createBodyForCompoundShape(compound,false,startTransform,mass);
compound = new btCompoundShape();
numCurSpheres = 0;
}
}
if (mass)
{
//shift the center of mass, based on all spheres
btCompoundShape* newCompound = shiftTransform(compound,mass,startTransform);
colShape = newCompound;
} else
{
//use unmodified
colShape = compound;
}
}
btDefaultMotionState* myMotionState = 0;
if (colShape && numCurSpheres)
{
createBodyForCompoundShape(colShape,addConstraint,startTransform,mass);
}
}
int BasicOECakeReader::processLine(char * buffer, int size)
{
int numBytesRead = 0;
if (buffer[0] == 'p')
{
int materialType;
int particleObjectIndex;
int particleColor;
int dummy1;
float particlePosX;
float particlePosY;
if (sscanf (buffer, "p %x %x %x %x %f %f", &materialType,&particleObjectIndex,&dummy1, &particleColor, &particlePosX, &particlePosY) == 6)
{
addParticle(materialType,particleObjectIndex,particleColor,particlePosX,particlePosY);
}
else
{
printf("ERROR: invalid line (%s)\n", buffer);
}
}
while (*buffer != '\n' && size != 0)
{
buffer++;
numBytesRead++;
}
if (buffer[0]==0x0a)
{
buffer++;
numBytesRead++;
}
return numBytesRead;
}
bool BasicOECakeReader::processFile(char * fileName)
{
FILE * fp = fopen(fileName, "rb");
if (fp == NULL)
{
printf("ERROR: file(%s) not found", fileName);
return false;
}
int size;
if (fseek(fp, 0, SEEK_END) || (size = ftell(fp)) == EOF || fseek(fp, 0, SEEK_SET))
{
printf("ERROR: problem reading file(%s)", fileName);
fclose(fp);
return false;
}
else
{
rewind (fp);
char * buffer = (char *) malloc(size+1);
memset(buffer,0,size);
if (fread(buffer,1,size,fp) != size)
{
printf("Error reading file %s!\n",fileName);
fclose(fp);
return false;
}
int totalBytesRead = 0;
while(totalBytesRead<size)
{
int remainingSize = size-totalBytesRead;
if (remainingSize<1229)
{
printf("..");
}
totalBytesRead +=processLine(&buffer[totalBytesRead],remainingSize);
}
}
convertParticleGroup();
fclose(fp);
return false;
}

View File

@@ -1,35 +1,35 @@
#ifndef OE_CAKE_LOADER_H
#define OE_CAKE_LOADER_H
#include "btBulletDynamicsCommon.h"
class BasicOECakeReader
{
int m_materialType;
int m_particleObjectIndex;
int m_particleColor;
btAlignedObjectArray<btVector3> m_particlePositions;
btAlignedObjectArray<btScalar> m_particleRadii;
void addParticle(int materialType, int pIndex, int pColor, float pPosX, float pPosY, float radius=1);
virtual void addNewCollisionShape(int numParticles, btVector3* particlePositions, btScalar* radii, int materialType, int objectIndex,int color );
int processLine(char * buffer, int size);
void convertParticleGroup();
public:
BasicOECakeReader()
{
}
bool processFile(char * fileName);
virtual void createBodyForCompoundShape(btCompoundShape* compound,bool addConstraint,const btTransform& worldTransform, btScalar mass) = 0;
};
#endif //OE_CAKE_LOADER_H
#ifndef OE_CAKE_LOADER_H
#define OE_CAKE_LOADER_H
#include "btBulletDynamicsCommon.h"
class BasicOECakeReader
{
int m_materialType;
int m_particleObjectIndex;
int m_particleColor;
btAlignedObjectArray<btVector3> m_particlePositions;
btAlignedObjectArray<btScalar> m_particleRadii;
void addParticle(int materialType, int pIndex, int pColor, float pPosX, float pPosY, float radius=1);
virtual void addNewCollisionShape(int numParticles, btVector3* particlePositions, btScalar* radii, int materialType, int objectIndex,int color );
int processLine(char * buffer, int size);
void convertParticleGroup();
public:
BasicOECakeReader()
{
}
bool processFile(char * fileName);
virtual void createBodyForCompoundShape(btCompoundShape* compound,bool addConstraint,const btTransform& worldTransform, btScalar mass) = 0;
};
#endif //OE_CAKE_LOADER_H