Code-style consistency improvement:
Apply clang-format-all.sh using the _clang-format file through all the cpp/.h files. make sure not to apply it to certain serialization structures, since some parser expects the * as part of the name, instead of type. This commit contains no other changes aside from adding and applying clang-format-all.sh
This commit is contained in:
@@ -5,14 +5,13 @@
|
||||
|
||||
#include "Bullet3Dynamics/shared/b3ContactConstraint4.h"
|
||||
|
||||
|
||||
B3_ATTRIBUTE_ALIGNED16(struct) b3GpuConstraint4 : public b3ContactConstraint4
|
||||
B3_ATTRIBUTE_ALIGNED16(struct)
|
||||
b3GpuConstraint4 : public b3ContactConstraint4
|
||||
{
|
||||
B3_DECLARE_ALIGNED_ALLOCATOR();
|
||||
|
||||
inline void setFrictionCoeff(float value) { m_linear[3] = value; }
|
||||
inline float getFrictionCoeff() const { return m_linear[3]; }
|
||||
inline void setFrictionCoeff(float value) { m_linear[3] = value; }
|
||||
inline float getFrictionCoeff() const { return m_linear[3]; }
|
||||
};
|
||||
|
||||
#endif //B3_CONSTRAINT4_h
|
||||
|
||||
#endif //B3_CONSTRAINT4_h
|
||||
|
||||
@@ -19,11 +19,11 @@ subject to the following restrictions:
|
||||
#include <new>
|
||||
#include "Bullet3Common/b3Transform.h"
|
||||
|
||||
void b3GpuGenericConstraint::getInfo1 (unsigned int* info,const b3RigidBodyData* bodies)
|
||||
void b3GpuGenericConstraint::getInfo1(unsigned int* info, const b3RigidBodyData* bodies)
|
||||
{
|
||||
switch (m_constraintType)
|
||||
{
|
||||
case B3_GPU_POINT2POINT_CONSTRAINT_TYPE:
|
||||
case B3_GPU_POINT2POINT_CONSTRAINT_TYPE:
|
||||
{
|
||||
*info = 3;
|
||||
break;
|
||||
@@ -35,7 +35,7 @@ void b3GpuGenericConstraint::getInfo1 (unsigned int* info,const b3RigidBodyData*
|
||||
};
|
||||
}
|
||||
|
||||
void getInfo2Point2Point(b3GpuGenericConstraint* constraint, b3GpuConstraintInfo2* info, const b3RigidBodyData* bodies)
|
||||
void getInfo2Point2Point(b3GpuGenericConstraint* constraint, b3GpuConstraintInfo2* info, const b3RigidBodyData* bodies)
|
||||
{
|
||||
b3Transform trA;
|
||||
trA.setIdentity();
|
||||
@@ -47,54 +47,52 @@ void getInfo2Point2Point(b3GpuGenericConstraint* constraint, b3GpuConstraintInfo
|
||||
trB.setOrigin(bodies[constraint->m_rbB].m_pos);
|
||||
trB.setRotation(bodies[constraint->m_rbB].m_quat);
|
||||
|
||||
// anchor points in global coordinates with respect to body PORs.
|
||||
|
||||
// set jacobian
|
||||
info->m_J1linearAxis[0] = 1;
|
||||
info->m_J1linearAxis[info->rowskip+1] = 1;
|
||||
info->m_J1linearAxis[2*info->rowskip+2] = 1;
|
||||
// anchor points in global coordinates with respect to body PORs.
|
||||
|
||||
b3Vector3 a1 = trA.getBasis()*constraint->getPivotInA();
|
||||
// set jacobian
|
||||
info->m_J1linearAxis[0] = 1;
|
||||
info->m_J1linearAxis[info->rowskip + 1] = 1;
|
||||
info->m_J1linearAxis[2 * info->rowskip + 2] = 1;
|
||||
|
||||
b3Vector3 a1 = trA.getBasis() * constraint->getPivotInA();
|
||||
//b3Vector3 a1a = b3QuatRotate(trA.getRotation(),constraint->getPivotInA());
|
||||
|
||||
{
|
||||
b3Vector3* angular0 = (b3Vector3*)(info->m_J1angularAxis);
|
||||
b3Vector3* angular1 = (b3Vector3*)(info->m_J1angularAxis+info->rowskip);
|
||||
b3Vector3* angular2 = (b3Vector3*)(info->m_J1angularAxis+2*info->rowskip);
|
||||
b3Vector3* angular1 = (b3Vector3*)(info->m_J1angularAxis + info->rowskip);
|
||||
b3Vector3* angular2 = (b3Vector3*)(info->m_J1angularAxis + 2 * info->rowskip);
|
||||
b3Vector3 a1neg = -a1;
|
||||
a1neg.getSkewSymmetricMatrix(angular0,angular1,angular2);
|
||||
a1neg.getSkewSymmetricMatrix(angular0, angular1, angular2);
|
||||
}
|
||||
|
||||
|
||||
if (info->m_J2linearAxis)
|
||||
{
|
||||
info->m_J2linearAxis[0] = -1;
|
||||
info->m_J2linearAxis[info->rowskip+1] = -1;
|
||||
info->m_J2linearAxis[2*info->rowskip+2] = -1;
|
||||
info->m_J2linearAxis[info->rowskip + 1] = -1;
|
||||
info->m_J2linearAxis[2 * info->rowskip + 2] = -1;
|
||||
}
|
||||
|
||||
b3Vector3 a2 = trB.getBasis()*constraint->getPivotInB();
|
||||
|
||||
|
||||
b3Vector3 a2 = trB.getBasis() * constraint->getPivotInB();
|
||||
|
||||
{
|
||||
// b3Vector3 a2n = -a2;
|
||||
// b3Vector3 a2n = -a2;
|
||||
b3Vector3* angular0 = (b3Vector3*)(info->m_J2angularAxis);
|
||||
b3Vector3* angular1 = (b3Vector3*)(info->m_J2angularAxis+info->rowskip);
|
||||
b3Vector3* angular2 = (b3Vector3*)(info->m_J2angularAxis+2*info->rowskip);
|
||||
a2.getSkewSymmetricMatrix(angular0,angular1,angular2);
|
||||
b3Vector3* angular1 = (b3Vector3*)(info->m_J2angularAxis + info->rowskip);
|
||||
b3Vector3* angular2 = (b3Vector3*)(info->m_J2angularAxis + 2 * info->rowskip);
|
||||
a2.getSkewSymmetricMatrix(angular0, angular1, angular2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// set right hand side
|
||||
// b3Scalar currERP = (m_flags & B3_P2P_FLAGS_ERP) ? m_erp : info->erp;
|
||||
// set right hand side
|
||||
// b3Scalar currERP = (m_flags & B3_P2P_FLAGS_ERP) ? m_erp : info->erp;
|
||||
b3Scalar currERP = info->erp;
|
||||
|
||||
b3Scalar k = info->fps * currERP;
|
||||
int j;
|
||||
for (j=0; j<3; j++)
|
||||
{
|
||||
info->m_constraintError[j*info->rowskip] = k * (a2[j] + trB.getOrigin()[j] - a1[j] - trA.getOrigin()[j]);
|
||||
int j;
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
info->m_constraintError[j * info->rowskip] = k * (a2[j] + trB.getOrigin()[j] - a1[j] - trA.getOrigin()[j]);
|
||||
//printf("info->m_constraintError[%d]=%f\n",j,info->m_constraintError[j]);
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
if(m_flags & B3_P2P_FLAGS_CFM)
|
||||
{
|
||||
@@ -117,21 +115,20 @@ void getInfo2Point2Point(b3GpuGenericConstraint* constraint, b3GpuConstraintInfo
|
||||
}
|
||||
info->m_damping = m_setting.m_damping;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void b3GpuGenericConstraint::getInfo2 (b3GpuConstraintInfo2* info, const b3RigidBodyData* bodies)
|
||||
void b3GpuGenericConstraint::getInfo2(b3GpuConstraintInfo2* info, const b3RigidBodyData* bodies)
|
||||
{
|
||||
switch (m_constraintType)
|
||||
{
|
||||
case B3_GPU_POINT2POINT_CONSTRAINT_TYPE:
|
||||
case B3_GPU_POINT2POINT_CONSTRAINT_TYPE:
|
||||
{
|
||||
getInfo2Point2Point(this,info,bodies);
|
||||
getInfo2Point2Point(this, info, bodies);
|
||||
break;
|
||||
};
|
||||
default:
|
||||
{
|
||||
b3Assert(0);
|
||||
}
|
||||
{
|
||||
b3Assert(0);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -20,37 +20,35 @@ subject to the following restrictions:
|
||||
struct b3RigidBodyData;
|
||||
enum B3_CONSTRAINT_FLAGS
|
||||
{
|
||||
B3_CONSTRAINT_FLAG_ENABLED=1,
|
||||
B3_CONSTRAINT_FLAG_ENABLED = 1,
|
||||
};
|
||||
|
||||
enum b3GpuGenericConstraintType
|
||||
{
|
||||
B3_GPU_POINT2POINT_CONSTRAINT_TYPE=3,
|
||||
B3_GPU_FIXED_CONSTRAINT_TYPE=4,
|
||||
// B3_HINGE_CONSTRAINT_TYPE,
|
||||
// B3_CONETWIST_CONSTRAINT_TYPE,
|
||||
// B3_D6_CONSTRAINT_TYPE,
|
||||
// B3_SLIDER_CONSTRAINT_TYPE,
|
||||
// B3_CONTACT_CONSTRAINT_TYPE,
|
||||
// B3_D6_SPRING_CONSTRAINT_TYPE,
|
||||
// B3_GEAR_CONSTRAINT_TYPE,
|
||||
|
||||
B3_GPU_POINT2POINT_CONSTRAINT_TYPE = 3,
|
||||
B3_GPU_FIXED_CONSTRAINT_TYPE = 4,
|
||||
// B3_HINGE_CONSTRAINT_TYPE,
|
||||
// B3_CONETWIST_CONSTRAINT_TYPE,
|
||||
// B3_D6_CONSTRAINT_TYPE,
|
||||
// B3_SLIDER_CONSTRAINT_TYPE,
|
||||
// B3_CONTACT_CONSTRAINT_TYPE,
|
||||
// B3_D6_SPRING_CONSTRAINT_TYPE,
|
||||
// B3_GEAR_CONSTRAINT_TYPE,
|
||||
|
||||
B3_GPU_MAX_CONSTRAINT_TYPE
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct b3GpuConstraintInfo2
|
||||
struct b3GpuConstraintInfo2
|
||||
{
|
||||
// integrator parameters: frames per second (1/stepsize), default error
|
||||
// reduction parameter (0..1).
|
||||
b3Scalar fps,erp;
|
||||
b3Scalar fps, erp;
|
||||
|
||||
// for the first and second body, pointers to two (linear and angular)
|
||||
// n*3 jacobian sub matrices, stored by rows. these matrices will have
|
||||
// been initialized to 0 on entry. if the second body is zero then the
|
||||
// J2xx pointers may be 0.
|
||||
b3Scalar *m_J1linearAxis,*m_J1angularAxis,*m_J2linearAxis,*m_J2angularAxis;
|
||||
b3Scalar *m_J1linearAxis, *m_J1angularAxis, *m_J2linearAxis, *m_J2angularAxis;
|
||||
|
||||
// elements to jump from one row to the next in J's
|
||||
int rowskip;
|
||||
@@ -58,44 +56,44 @@ struct b3GpuConstraintInfo2
|
||||
// right hand sides of the equation J*v = c + cfm * lambda. cfm is the
|
||||
// "constraint force mixing" vector. c is set to zero on entry, cfm is
|
||||
// set to a constant value (typically very small or zero) value on entry.
|
||||
b3Scalar *m_constraintError,*cfm;
|
||||
b3Scalar *m_constraintError, *cfm;
|
||||
|
||||
// lo and hi limits for variables (set to -/+ infinity on entry).
|
||||
b3Scalar *m_lowerLimit,*m_upperLimit;
|
||||
b3Scalar *m_lowerLimit, *m_upperLimit;
|
||||
|
||||
// findex vector for variables. see the LCP solver interface for a
|
||||
// description of what this does. this is set to -1 on entry.
|
||||
// note that the returned indexes are relative to the first index of
|
||||
// the constraint.
|
||||
int *findex;
|
||||
int* findex;
|
||||
// number of solver iterations
|
||||
int m_numIterations;
|
||||
|
||||
//damping of the velocity
|
||||
b3Scalar m_damping;
|
||||
b3Scalar m_damping;
|
||||
};
|
||||
|
||||
|
||||
B3_ATTRIBUTE_ALIGNED16(struct) b3GpuGenericConstraint
|
||||
B3_ATTRIBUTE_ALIGNED16(struct)
|
||||
b3GpuGenericConstraint
|
||||
{
|
||||
int m_constraintType;
|
||||
int m_rbA;
|
||||
int m_rbB;
|
||||
float m_breakingImpulseThreshold;
|
||||
int m_constraintType;
|
||||
int m_rbA;
|
||||
int m_rbB;
|
||||
float m_breakingImpulseThreshold;
|
||||
|
||||
b3Vector3 m_pivotInA;
|
||||
b3Vector3 m_pivotInB;
|
||||
b3Quaternion m_relTargetAB;
|
||||
|
||||
int m_flags;
|
||||
int m_flags;
|
||||
int m_uid;
|
||||
int m_padding[2];
|
||||
|
||||
int getRigidBodyA() const
|
||||
int getRigidBodyA() const
|
||||
{
|
||||
return m_rbA;
|
||||
}
|
||||
int getRigidBodyB() const
|
||||
int getRigidBodyB() const
|
||||
{
|
||||
return m_rbB;
|
||||
}
|
||||
@@ -121,12 +119,10 @@ B3_ATTRIBUTE_ALIGNED16(struct) b3GpuGenericConstraint
|
||||
}
|
||||
|
||||
///internal method used by the constraint solver, don't use them directly
|
||||
void getInfo1 (unsigned int* info,const b3RigidBodyData* bodies);
|
||||
void getInfo1(unsigned int* info, const b3RigidBodyData* bodies);
|
||||
|
||||
///internal method used by the constraint solver, don't use them directly
|
||||
void getInfo2 (b3GpuConstraintInfo2* info, const b3RigidBodyData* bodies);
|
||||
|
||||
|
||||
void getInfo2(b3GpuConstraintInfo2 * info, const b3RigidBodyData* bodies);
|
||||
};
|
||||
|
||||
#endif //B3_GPU_GENERIC_CONSTRAINT_H
|
||||
#endif //B3_GPU_GENERIC_CONSTRAINT_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,6 @@
|
||||
#include "Bullet3Collision/NarrowPhaseCollision/shared/b3Contact4Data.h"
|
||||
#include "Bullet3OpenCL/ParallelPrimitives/b3OpenCLArray.h"
|
||||
|
||||
|
||||
//struct b3InertiaData;
|
||||
//b3InertiaData
|
||||
|
||||
@@ -21,21 +20,20 @@ struct b3JacobiSolverInfo
|
||||
float m_deltaTime;
|
||||
float m_positionDrift;
|
||||
float m_positionConstraintCoeff;
|
||||
int m_numIterations;
|
||||
int m_numIterations;
|
||||
|
||||
b3JacobiSolverInfo()
|
||||
:m_fixedBodyIndex(0),
|
||||
m_deltaTime(1./60.f),
|
||||
m_positionDrift( 0.005f ),
|
||||
m_positionConstraintCoeff( 0.99f ),
|
||||
m_numIterations(7)
|
||||
: m_fixedBodyIndex(0),
|
||||
m_deltaTime(1. / 60.f),
|
||||
m_positionDrift(0.005f),
|
||||
m_positionConstraintCoeff(0.99f),
|
||||
m_numIterations(7)
|
||||
{
|
||||
}
|
||||
};
|
||||
class b3GpuJacobiContactSolver
|
||||
{
|
||||
protected:
|
||||
|
||||
struct b3GpuJacobiSolverInternalData* m_data;
|
||||
|
||||
cl_context m_context;
|
||||
@@ -43,20 +41,16 @@ protected:
|
||||
cl_command_queue m_queue;
|
||||
|
||||
public:
|
||||
|
||||
b3GpuJacobiContactSolver(cl_context ctx, cl_device_id device, cl_command_queue queue, int pairCapacity);
|
||||
virtual ~b3GpuJacobiContactSolver();
|
||||
|
||||
|
||||
void solveContacts(int numBodies, cl_mem bodyBuf, cl_mem inertiaBuf, int numContacts, cl_mem contactBuf, const struct b3Config& config, int static0Index);
|
||||
void solveGroupHost(b3RigidBodyData* bodies,b3InertiaData* inertias,int numBodies,struct b3Contact4* manifoldPtr, int numManifolds,const b3JacobiSolverInfo& solverInfo);
|
||||
void solveGroupHost(b3RigidBodyData* bodies, b3InertiaData* inertias, int numBodies, struct b3Contact4* manifoldPtr, int numManifolds, const b3JacobiSolverInfo& solverInfo);
|
||||
//void solveGroupHost(btRigidBodyCL* bodies,b3InertiaData* inertias,int numBodies,btContact4* manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btJacobiSolverInfo& solverInfo);
|
||||
|
||||
//b3Scalar solveGroup(b3OpenCLArray<b3RigidBodyData>* gpuBodies,b3OpenCLArray<b3InertiaData>* gpuInertias, int numBodies,b3OpenCLArray<b3GpuGenericConstraint>* gpuConstraints,int numConstraints,const b3ContactSolverInfo& infoGlobal);
|
||||
|
||||
//void solveGroup(btOpenCLArray<btRigidBodyCL>* bodies,btOpenCLArray<btInertiaCL>* inertias,btOpenCLArray<btContact4>* manifoldPtr,const btJacobiSolverInfo& solverInfo);
|
||||
//void solveGroupMixed(btOpenCLArray<btRigidBodyCL>* bodies,btOpenCLArray<btInertiaCL>* inertias,btOpenCLArray<btContact4>* manifoldPtr,const btJacobiSolverInfo& solverInfo);
|
||||
|
||||
};
|
||||
#endif //B3_GPU_JACOBI_CONTACT_SOLVER_H
|
||||
|
||||
#endif //B3_GPU_JACOBI_CONTACT_SOLVER_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,11 +9,10 @@
|
||||
class b3GpuNarrowPhase
|
||||
{
|
||||
protected:
|
||||
|
||||
struct b3GpuNarrowPhaseInternalData* m_data;
|
||||
struct b3GpuNarrowPhaseInternalData* m_data;
|
||||
int m_acceleratedCompanionShapeIndex;
|
||||
int m_planeBodyIndex;
|
||||
int m_static0Index;
|
||||
int m_static0Index;
|
||||
|
||||
cl_context m_context;
|
||||
cl_device_id m_device;
|
||||
@@ -23,64 +22,58 @@ protected:
|
||||
int registerConcaveMeshShape(b3AlignedObjectArray<b3Vector3>* vertices, b3AlignedObjectArray<int>* indices, b3Collidable& col, const float* scaling);
|
||||
|
||||
public:
|
||||
|
||||
|
||||
|
||||
|
||||
b3GpuNarrowPhase(cl_context vtx, cl_device_id dev, cl_command_queue q, const struct b3Config& config);
|
||||
|
||||
virtual ~b3GpuNarrowPhase(void);
|
||||
|
||||
int registerSphereShape(float radius);
|
||||
int registerPlaneShape(const b3Vector3& planeNormal, float planeConstant);
|
||||
int registerSphereShape(float radius);
|
||||
int registerPlaneShape(const b3Vector3& planeNormal, float planeConstant);
|
||||
|
||||
int registerCompoundShape(b3AlignedObjectArray<b3GpuChildShape>* childShapes);
|
||||
int registerFace(const b3Vector3& faceNormal, float faceConstant);
|
||||
|
||||
int registerConcaveMesh(b3AlignedObjectArray<b3Vector3>* vertices, b3AlignedObjectArray<int>* indices,const float* scaling);
|
||||
|
||||
|
||||
int registerConcaveMesh(b3AlignedObjectArray<b3Vector3>* vertices, b3AlignedObjectArray<int>* indices, const float* scaling);
|
||||
|
||||
//do they need to be merged?
|
||||
|
||||
int registerConvexHullShape(b3ConvexUtility* utilPtr);
|
||||
int registerConvexHullShape(const float* vertices, int strideInBytes, int numVertices, const float* scaling);
|
||||
|
||||
int registerRigidBody(int collidableIndex, float mass, const float* position, const float* orientation, const float* aabbMin, const float* aabbMax,bool writeToGpu);
|
||||
void setObjectTransform(const float* position, const float* orientation , int bodyIndex);
|
||||
int registerConvexHullShape(b3ConvexUtility* utilPtr);
|
||||
int registerConvexHullShape(const float* vertices, int strideInBytes, int numVertices, const float* scaling);
|
||||
|
||||
void writeAllBodiesToGpu();
|
||||
void reset();
|
||||
void readbackAllBodiesToCpu();
|
||||
bool getObjectTransformFromCpu(float* position, float* orientation , int bodyIndex) const;
|
||||
int registerRigidBody(int collidableIndex, float mass, const float* position, const float* orientation, const float* aabbMin, const float* aabbMax, bool writeToGpu);
|
||||
void setObjectTransform(const float* position, const float* orientation, int bodyIndex);
|
||||
|
||||
void setObjectTransformCpu(float* position, float* orientation , int bodyIndex);
|
||||
void writeAllBodiesToGpu();
|
||||
void reset();
|
||||
void readbackAllBodiesToCpu();
|
||||
bool getObjectTransformFromCpu(float* position, float* orientation, int bodyIndex) const;
|
||||
|
||||
void setObjectTransformCpu(float* position, float* orientation, int bodyIndex);
|
||||
void setObjectVelocityCpu(float* linVel, float* angVel, int bodyIndex);
|
||||
|
||||
|
||||
virtual void computeContacts(cl_mem broadphasePairs, int numBroadphasePairs, cl_mem aabbsWorldSpace, int numObjects);
|
||||
|
||||
|
||||
cl_mem getBodiesGpu();
|
||||
cl_mem getBodiesGpu();
|
||||
const struct b3RigidBodyData* getBodiesCpu() const;
|
||||
//struct b3RigidBodyData* getBodiesCpu();
|
||||
|
||||
int getNumBodiesGpu() const;
|
||||
int getNumBodiesGpu() const;
|
||||
|
||||
cl_mem getBodyInertiasGpu();
|
||||
int getNumBodyInertiasGpu() const;
|
||||
cl_mem getBodyInertiasGpu();
|
||||
int getNumBodyInertiasGpu() const;
|
||||
|
||||
cl_mem getCollidablesGpu();
|
||||
cl_mem getCollidablesGpu();
|
||||
const struct b3Collidable* getCollidablesCpu() const;
|
||||
int getNumCollidablesGpu() const;
|
||||
int getNumCollidablesGpu() const;
|
||||
|
||||
const struct b3SapAabb* getLocalSpaceAabbsCpu() const;
|
||||
|
||||
const struct b3Contact4* getContactsCPU() const;
|
||||
|
||||
cl_mem getContactsGpu();
|
||||
int getNumContactsGpu() const;
|
||||
cl_mem getContactsGpu();
|
||||
int getNumContactsGpu() const;
|
||||
|
||||
cl_mem getAabbLocalSpaceBufferGpu();
|
||||
|
||||
cl_mem getAabbLocalSpaceBufferGpu();
|
||||
|
||||
int getNumRigidBodies() const;
|
||||
|
||||
int allocateCollidable();
|
||||
@@ -92,18 +85,17 @@ public:
|
||||
b3Collidable& getCollidableCpu(int collidableIndex);
|
||||
const b3Collidable& getCollidableCpu(int collidableIndex) const;
|
||||
|
||||
const b3GpuNarrowPhaseInternalData* getInternalData() const
|
||||
const b3GpuNarrowPhaseInternalData* getInternalData() const
|
||||
{
|
||||
return m_data;
|
||||
return m_data;
|
||||
}
|
||||
|
||||
b3GpuNarrowPhaseInternalData* getInternalData()
|
||||
b3GpuNarrowPhaseInternalData* getInternalData()
|
||||
{
|
||||
return m_data;
|
||||
return m_data;
|
||||
}
|
||||
|
||||
const struct b3SapAabb& getLocalSpaceAabb(int collidableIndex) const;
|
||||
};
|
||||
|
||||
#endif //B3_GPU_NARROWPHASE_H
|
||||
|
||||
#endif //B3_GPU_NARROWPHASE_H
|
||||
|
||||
@@ -20,57 +20,53 @@
|
||||
#include "Bullet3Common/shared/b3Int4.h"
|
||||
#include "Bullet3Common/shared/b3Int2.h"
|
||||
|
||||
|
||||
class b3ConvexUtility;
|
||||
|
||||
struct b3GpuNarrowPhaseInternalData
|
||||
{
|
||||
b3AlignedObjectArray<b3ConvexUtility*>* m_convexData;
|
||||
|
||||
|
||||
b3AlignedObjectArray<b3ConvexPolyhedronData> m_convexPolyhedra;
|
||||
b3AlignedObjectArray<b3Vector3> m_uniqueEdges;
|
||||
b3AlignedObjectArray<b3Vector3> m_convexVertices;
|
||||
b3AlignedObjectArray<int> m_convexIndices;
|
||||
|
||||
|
||||
b3OpenCLArray<b3ConvexPolyhedronData>* m_convexPolyhedraGPU;
|
||||
b3OpenCLArray<b3Vector3>* m_uniqueEdgesGPU;
|
||||
b3OpenCLArray<b3Vector3>* m_convexVerticesGPU;
|
||||
b3OpenCLArray<int>* m_convexIndicesGPU;
|
||||
|
||||
b3OpenCLArray<b3Vector3>* m_worldVertsB1GPU;
|
||||
b3OpenCLArray<b3Int4>* m_clippingFacesOutGPU;
|
||||
b3OpenCLArray<b3Vector3>* m_worldNormalsAGPU;
|
||||
b3OpenCLArray<b3Vector3>* m_worldVertsA1GPU;
|
||||
b3OpenCLArray<b3Vector3>* m_worldVertsB2GPU;
|
||||
|
||||
|
||||
b3OpenCLArray<b3Vector3>* m_worldVertsB1GPU;
|
||||
b3OpenCLArray<b3Int4>* m_clippingFacesOutGPU;
|
||||
b3OpenCLArray<b3Vector3>* m_worldNormalsAGPU;
|
||||
b3OpenCLArray<b3Vector3>* m_worldVertsA1GPU;
|
||||
b3OpenCLArray<b3Vector3>* m_worldVertsB2GPU;
|
||||
|
||||
b3AlignedObjectArray<b3GpuChildShape> m_cpuChildShapes;
|
||||
b3OpenCLArray<b3GpuChildShape>* m_gpuChildShapes;
|
||||
|
||||
b3OpenCLArray<b3GpuChildShape>* m_gpuChildShapes;
|
||||
|
||||
b3AlignedObjectArray<b3GpuFace> m_convexFaces;
|
||||
b3OpenCLArray<b3GpuFace>* m_convexFacesGPU;
|
||||
|
||||
struct GpuSatCollision* m_gpuSatCollision;
|
||||
|
||||
|
||||
b3OpenCLArray<b3Int4>* m_triangleConvexPairs;
|
||||
|
||||
|
||||
|
||||
struct GpuSatCollision* m_gpuSatCollision;
|
||||
|
||||
b3OpenCLArray<b3Int4>* m_triangleConvexPairs;
|
||||
|
||||
b3OpenCLArray<b3Contact4>* m_pBufContactBuffersGPU[2];
|
||||
int m_currentContactBuffer;
|
||||
int m_currentContactBuffer;
|
||||
b3AlignedObjectArray<b3Contact4>* m_pBufContactOutCPU;
|
||||
|
||||
|
||||
|
||||
b3AlignedObjectArray<b3RigidBodyData>* m_bodyBufferCPU;
|
||||
b3OpenCLArray<b3RigidBodyData>* m_bodyBufferGPU;
|
||||
|
||||
b3AlignedObjectArray<b3InertiaData>* m_inertiaBufferCPU;
|
||||
b3OpenCLArray<b3InertiaData>* m_inertiaBufferGPU;
|
||||
|
||||
|
||||
b3AlignedObjectArray<b3InertiaData>* m_inertiaBufferCPU;
|
||||
b3OpenCLArray<b3InertiaData>* m_inertiaBufferGPU;
|
||||
|
||||
int m_numAcceleratedShapes;
|
||||
int m_numAcceleratedRigidBodies;
|
||||
|
||||
b3AlignedObjectArray<b3Collidable> m_collidablesCPU;
|
||||
b3OpenCLArray<b3Collidable>* m_collidablesGPU;
|
||||
|
||||
b3AlignedObjectArray<b3Collidable> m_collidablesCPU;
|
||||
b3OpenCLArray<b3Collidable>* m_collidablesGPU;
|
||||
|
||||
b3OpenCLArray<b3SapAabb>* m_localShapeAABBGPU;
|
||||
b3AlignedObjectArray<b3SapAabb>* m_localShapeAABBCPU;
|
||||
@@ -78,18 +74,16 @@ struct b3GpuNarrowPhaseInternalData
|
||||
b3AlignedObjectArray<class b3OptimizedBvh*> m_bvhData;
|
||||
b3AlignedObjectArray<class b3TriangleIndexVertexArray*> m_meshInterfaces;
|
||||
|
||||
b3AlignedObjectArray<b3QuantizedBvhNode> m_treeNodesCPU;
|
||||
b3AlignedObjectArray<b3BvhSubtreeInfo> m_subTreesCPU;
|
||||
b3AlignedObjectArray<b3QuantizedBvhNode> m_treeNodesCPU;
|
||||
b3AlignedObjectArray<b3BvhSubtreeInfo> m_subTreesCPU;
|
||||
|
||||
b3AlignedObjectArray<b3BvhInfo> m_bvhInfoCPU;
|
||||
b3OpenCLArray<b3BvhInfo>* m_bvhInfoGPU;
|
||||
|
||||
b3OpenCLArray<b3QuantizedBvhNode>* m_treeNodesGPU;
|
||||
b3OpenCLArray<b3BvhSubtreeInfo>* m_subTreesGPU;
|
||||
|
||||
b3AlignedObjectArray<b3BvhInfo> m_bvhInfoCPU;
|
||||
b3OpenCLArray<b3BvhInfo>* m_bvhInfoGPU;
|
||||
|
||||
b3Config m_config;
|
||||
|
||||
b3OpenCLArray<b3QuantizedBvhNode>* m_treeNodesGPU;
|
||||
b3OpenCLArray<b3BvhSubtreeInfo>* m_subTreesGPU;
|
||||
|
||||
b3Config m_config;
|
||||
};
|
||||
|
||||
#endif //B3_GPU_NARROWPHASE_INTERNAL_DATA_H
|
||||
#endif //B3_GPU_NARROWPHASE_INTERNAL_DATA_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -19,7 +19,6 @@ subject to the following restrictions:
|
||||
struct b3Contact4;
|
||||
struct b3ContactPoint;
|
||||
|
||||
|
||||
class b3Dispatcher;
|
||||
|
||||
#include "Bullet3Dynamics/ConstraintSolver/b3TypedConstraint.h"
|
||||
@@ -38,41 +37,40 @@ class b3GpuPgsConstraintSolver
|
||||
protected:
|
||||
int m_staticIdx;
|
||||
struct b3GpuPgsJacobiSolverInternalData* m_gpuData;
|
||||
protected:
|
||||
b3AlignedObjectArray<b3GpuSolverBody> m_tmpSolverBodyPool;
|
||||
b3GpuConstraintArray m_tmpSolverContactConstraintPool;
|
||||
b3GpuConstraintArray m_tmpSolverNonContactConstraintPool;
|
||||
b3GpuConstraintArray m_tmpSolverContactFrictionConstraintPool;
|
||||
b3GpuConstraintArray m_tmpSolverContactRollingFrictionConstraintPool;
|
||||
|
||||
protected:
|
||||
b3AlignedObjectArray<b3GpuSolverBody> m_tmpSolverBodyPool;
|
||||
b3GpuConstraintArray m_tmpSolverContactConstraintPool;
|
||||
b3GpuConstraintArray m_tmpSolverNonContactConstraintPool;
|
||||
b3GpuConstraintArray m_tmpSolverContactFrictionConstraintPool;
|
||||
b3GpuConstraintArray m_tmpSolverContactRollingFrictionConstraintPool;
|
||||
|
||||
b3AlignedObjectArray<unsigned int> m_tmpConstraintSizesPool;
|
||||
|
||||
|
||||
bool m_usePgs;
|
||||
void averageVelocities();
|
||||
bool m_usePgs;
|
||||
void averageVelocities();
|
||||
|
||||
int m_maxOverrideNumSolverIterations;
|
||||
int m_maxOverrideNumSolverIterations;
|
||||
|
||||
int m_numSplitImpulseRecoveries;
|
||||
int m_numSplitImpulseRecoveries;
|
||||
|
||||
// int getOrInitSolverBody(int bodyIndex, b3RigidBodyData* bodies,b3InertiaData* inertias);
|
||||
void initSolverBody(int bodyIndex, b3GpuSolverBody* solverBody, b3RigidBodyData* rb);
|
||||
// int getOrInitSolverBody(int bodyIndex, b3RigidBodyData* bodies,b3InertiaData* inertias);
|
||||
void initSolverBody(int bodyIndex, b3GpuSolverBody* solverBody, b3RigidBodyData* rb);
|
||||
|
||||
public:
|
||||
b3GpuPgsConstraintSolver (cl_context ctx, cl_device_id device, cl_command_queue queue,bool usePgs);
|
||||
virtual~b3GpuPgsConstraintSolver ();
|
||||
b3GpuPgsConstraintSolver(cl_context ctx, cl_device_id device, cl_command_queue queue, bool usePgs);
|
||||
virtual ~b3GpuPgsConstraintSolver();
|
||||
|
||||
virtual b3Scalar solveGroupCacheFriendlyIterations(b3OpenCLArray<b3GpuGenericConstraint>* gpuConstraints1,int numConstraints,const b3ContactSolverInfo& infoGlobal);
|
||||
virtual b3Scalar solveGroupCacheFriendlySetup(b3OpenCLArray<b3RigidBodyData>* gpuBodies, b3OpenCLArray<b3InertiaData>* gpuInertias, int numBodies,b3OpenCLArray<b3GpuGenericConstraint>* gpuConstraints,int numConstraints,const b3ContactSolverInfo& infoGlobal);
|
||||
b3Scalar solveGroupCacheFriendlyFinish(b3OpenCLArray<b3RigidBodyData>* gpuBodies,b3OpenCLArray<b3InertiaData>* gpuInertias,int numBodies,b3OpenCLArray<b3GpuGenericConstraint>* gpuConstraints,int numConstraints,const b3ContactSolverInfo& infoGlobal);
|
||||
virtual b3Scalar solveGroupCacheFriendlyIterations(b3OpenCLArray<b3GpuGenericConstraint>* gpuConstraints1, int numConstraints, const b3ContactSolverInfo& infoGlobal);
|
||||
virtual b3Scalar solveGroupCacheFriendlySetup(b3OpenCLArray<b3RigidBodyData>* gpuBodies, b3OpenCLArray<b3InertiaData>* gpuInertias, int numBodies, b3OpenCLArray<b3GpuGenericConstraint>* gpuConstraints, int numConstraints, const b3ContactSolverInfo& infoGlobal);
|
||||
b3Scalar solveGroupCacheFriendlyFinish(b3OpenCLArray<b3RigidBodyData>* gpuBodies, b3OpenCLArray<b3InertiaData>* gpuInertias, int numBodies, b3OpenCLArray<b3GpuGenericConstraint>* gpuConstraints, int numConstraints, const b3ContactSolverInfo& infoGlobal);
|
||||
|
||||
b3Scalar solveGroup(b3OpenCLArray<b3RigidBodyData>* gpuBodies, b3OpenCLArray<b3InertiaData>* gpuInertias, int numBodies, b3OpenCLArray<b3GpuGenericConstraint>* gpuConstraints, int numConstraints, const b3ContactSolverInfo& infoGlobal);
|
||||
void solveJoints(int numBodies, b3OpenCLArray<b3RigidBodyData>* gpuBodies, b3OpenCLArray<b3InertiaData>* gpuInertias,
|
||||
int numConstraints, b3OpenCLArray<b3GpuGenericConstraint>* gpuConstraints);
|
||||
|
||||
b3Scalar solveGroup(b3OpenCLArray<b3RigidBodyData>* gpuBodies,b3OpenCLArray<b3InertiaData>* gpuInertias, int numBodies,b3OpenCLArray<b3GpuGenericConstraint>* gpuConstraints,int numConstraints,const b3ContactSolverInfo& infoGlobal);
|
||||
void solveJoints(int numBodies, b3OpenCLArray<b3RigidBodyData>* gpuBodies, b3OpenCLArray<b3InertiaData>* gpuInertias,
|
||||
int numConstraints, b3OpenCLArray<b3GpuGenericConstraint>* gpuConstraints);
|
||||
|
||||
int sortConstraintByBatch3( struct b3BatchConstraint* cs, int numConstraints, int simdWidth , int staticIdx, int numBodies);
|
||||
void recomputeBatches();
|
||||
int sortConstraintByBatch3(struct b3BatchConstraint* cs, int numConstraints, int simdWidth, int staticIdx, int numBodies);
|
||||
void recomputeBatches();
|
||||
};
|
||||
|
||||
#endif //B3_GPU_PGS_CONSTRAINT_SOLVER_H
|
||||
#endif //B3_GPU_PGS_CONSTRAINT_SOLVER_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,33 +11,27 @@
|
||||
class b3GpuPgsContactSolver
|
||||
{
|
||||
protected:
|
||||
|
||||
int m_debugOutput;
|
||||
|
||||
struct b3GpuBatchingPgsSolverInternalData* m_data;
|
||||
struct b3GpuBatchingPgsSolverInternalData* m_data;
|
||||
|
||||
void batchContacts( b3OpenCLArray<b3Contact4>* contacts, int nContacts, b3OpenCLArray<unsigned int>* n, b3OpenCLArray<unsigned int>* offsets, int staticIdx );
|
||||
|
||||
inline int sortConstraintByBatch( b3Contact4* cs, int n, int simdWidth , int staticIdx, int numBodies);
|
||||
inline int sortConstraintByBatch2( b3Contact4* cs, int n, int simdWidth , int staticIdx, int numBodies);
|
||||
inline int sortConstraintByBatch3( b3Contact4* cs, int n, int simdWidth , int staticIdx, int numBodies, int* batchSizes);
|
||||
|
||||
void batchContacts(b3OpenCLArray<b3Contact4>* contacts, int nContacts, b3OpenCLArray<unsigned int>* n, b3OpenCLArray<unsigned int>* offsets, int staticIdx);
|
||||
|
||||
|
||||
void solveContactConstraintBatchSizes( const b3OpenCLArray<b3RigidBodyData>* bodyBuf, const b3OpenCLArray<b3InertiaData>* shapeBuf,
|
||||
b3OpenCLArray<b3GpuConstraint4>* constraint, void* additionalData, int n ,int maxNumBatches, int numIterations, const b3AlignedObjectArray<int>* batchSizes);//const b3OpenCLArray<int>* gpuBatchSizes);
|
||||
inline int sortConstraintByBatch(b3Contact4* cs, int n, int simdWidth, int staticIdx, int numBodies);
|
||||
inline int sortConstraintByBatch2(b3Contact4* cs, int n, int simdWidth, int staticIdx, int numBodies);
|
||||
inline int sortConstraintByBatch3(b3Contact4* cs, int n, int simdWidth, int staticIdx, int numBodies, int* batchSizes);
|
||||
|
||||
void solveContactConstraint( const b3OpenCLArray<b3RigidBodyData>* bodyBuf, const b3OpenCLArray<b3InertiaData>* shapeBuf,
|
||||
b3OpenCLArray<b3GpuConstraint4>* constraint, void* additionalData, int n ,int maxNumBatches, int numIterations, const b3AlignedObjectArray<int>* batchSizes);//const b3OpenCLArray<int>* gpuBatchSizes);
|
||||
void solveContactConstraintBatchSizes(const b3OpenCLArray<b3RigidBodyData>* bodyBuf, const b3OpenCLArray<b3InertiaData>* shapeBuf,
|
||||
b3OpenCLArray<b3GpuConstraint4>* constraint, void* additionalData, int n, int maxNumBatches, int numIterations, const b3AlignedObjectArray<int>* batchSizes); //const b3OpenCLArray<int>* gpuBatchSizes);
|
||||
|
||||
void solveContactConstraint(const b3OpenCLArray<b3RigidBodyData>* bodyBuf, const b3OpenCLArray<b3InertiaData>* shapeBuf,
|
||||
b3OpenCLArray<b3GpuConstraint4>* constraint, void* additionalData, int n, int maxNumBatches, int numIterations, const b3AlignedObjectArray<int>* batchSizes); //const b3OpenCLArray<int>* gpuBatchSizes);
|
||||
|
||||
public:
|
||||
|
||||
b3GpuPgsContactSolver(cl_context ctx,cl_device_id device, cl_command_queue q,int pairCapacity);
|
||||
b3GpuPgsContactSolver(cl_context ctx, cl_device_id device, cl_command_queue q, int pairCapacity);
|
||||
virtual ~b3GpuPgsContactSolver();
|
||||
|
||||
void solveContacts(int numBodies, cl_mem bodyBuf, cl_mem inertiaBuf, int numContacts, cl_mem contactBuf, const struct b3Config& config, int static0Index);
|
||||
|
||||
};
|
||||
|
||||
#endif //B3_GPU_BATCHING_PGS_SOLVER_H
|
||||
|
||||
#endif //B3_GPU_BATCHING_PGS_SOLVER_H
|
||||
|
||||
@@ -47,7 +47,7 @@ bool gClearPairsOnGpu = true;
|
||||
#define TEST_OTHER_GPU_SOLVER 1
|
||||
#ifdef TEST_OTHER_GPU_SOLVER
|
||||
#include "b3GpuJacobiContactSolver.h"
|
||||
#endif //TEST_OTHER_GPU_SOLVER
|
||||
#endif //TEST_OTHER_GPU_SOLVER
|
||||
|
||||
#include "Bullet3Collision/NarrowPhaseCollision/shared/b3RigidBodyData.h"
|
||||
#include "Bullet3Collision/NarrowPhaseCollision/b3Contact4.h"
|
||||
@@ -59,73 +59,68 @@ bool gClearPairsOnGpu = true;
|
||||
#include "Bullet3Collision/NarrowPhaseCollision/b3Config.h"
|
||||
#include "Bullet3OpenCL/Raycast/b3GpuRaycast.h"
|
||||
|
||||
|
||||
#include "Bullet3Dynamics/shared/b3IntegrateTransforms.h"
|
||||
#include "Bullet3OpenCL/RigidBody/b3GpuNarrowPhaseInternalData.h"
|
||||
|
||||
b3GpuRigidBodyPipeline::b3GpuRigidBodyPipeline(cl_context ctx,cl_device_id device, cl_command_queue q,class b3GpuNarrowPhase* narrowphase, class b3GpuBroadphaseInterface* broadphaseSap , struct b3DynamicBvhBroadphase* broadphaseDbvt, const b3Config& config)
|
||||
b3GpuRigidBodyPipeline::b3GpuRigidBodyPipeline(cl_context ctx, cl_device_id device, cl_command_queue q, class b3GpuNarrowPhase* narrowphase, class b3GpuBroadphaseInterface* broadphaseSap, struct b3DynamicBvhBroadphase* broadphaseDbvt, const b3Config& config)
|
||||
{
|
||||
m_data = new b3GpuRigidBodyPipelineInternalData;
|
||||
m_data->m_constraintUid=0;
|
||||
m_data->m_constraintUid = 0;
|
||||
m_data->m_config = config;
|
||||
m_data->m_context = ctx;
|
||||
m_data->m_device = device;
|
||||
m_data->m_queue = q;
|
||||
|
||||
m_data->m_solver = new b3PgsJacobiSolver(true);//new b3PgsJacobiSolver(true);
|
||||
m_data->m_gpuSolver = new b3GpuPgsConstraintSolver(ctx,device,q,true);//new b3PgsJacobiSolver(true);
|
||||
|
||||
m_data->m_allAabbsGPU = new b3OpenCLArray<b3SapAabb>(ctx,q,config.m_maxConvexBodies);
|
||||
m_data->m_overlappingPairsGPU = new b3OpenCLArray<b3BroadphasePair>(ctx,q,config.m_maxBroadphasePairs);
|
||||
m_data->m_solver = new b3PgsJacobiSolver(true); //new b3PgsJacobiSolver(true);
|
||||
m_data->m_gpuSolver = new b3GpuPgsConstraintSolver(ctx, device, q, true); //new b3PgsJacobiSolver(true);
|
||||
|
||||
m_data->m_gpuConstraints = new b3OpenCLArray<b3GpuGenericConstraint>(ctx,q);
|
||||
m_data->m_allAabbsGPU = new b3OpenCLArray<b3SapAabb>(ctx, q, config.m_maxConvexBodies);
|
||||
m_data->m_overlappingPairsGPU = new b3OpenCLArray<b3BroadphasePair>(ctx, q, config.m_maxBroadphasePairs);
|
||||
|
||||
m_data->m_gpuConstraints = new b3OpenCLArray<b3GpuGenericConstraint>(ctx, q);
|
||||
#ifdef TEST_OTHER_GPU_SOLVER
|
||||
m_data->m_solver3 = new b3GpuJacobiContactSolver(ctx,device,q,config.m_maxBroadphasePairs);
|
||||
#endif // TEST_OTHER_GPU_SOLVER
|
||||
|
||||
m_data->m_solver2 = new b3GpuPgsContactSolver(ctx,device,q,config.m_maxBroadphasePairs);
|
||||
m_data->m_solver3 = new b3GpuJacobiContactSolver(ctx, device, q, config.m_maxBroadphasePairs);
|
||||
#endif // TEST_OTHER_GPU_SOLVER
|
||||
|
||||
m_data->m_raycaster = new b3GpuRaycast(ctx,device,q);
|
||||
m_data->m_solver2 = new b3GpuPgsContactSolver(ctx, device, q, config.m_maxBroadphasePairs);
|
||||
|
||||
m_data->m_raycaster = new b3GpuRaycast(ctx, device, q);
|
||||
|
||||
|
||||
m_data->m_broadphaseDbvt = broadphaseDbvt;
|
||||
m_data->m_broadphaseSap = broadphaseSap;
|
||||
m_data->m_narrowphase = narrowphase;
|
||||
m_data->m_gravity.setValue(0.f,-9.8f,0.f);
|
||||
m_data->m_gravity.setValue(0.f, -9.8f, 0.f);
|
||||
|
||||
cl_int errNum=0;
|
||||
cl_int errNum = 0;
|
||||
|
||||
{
|
||||
cl_program prog = b3OpenCLUtils::compileCLProgramFromString(m_data->m_context,m_data->m_device,integrateKernelCL,&errNum,"",B3_RIGIDBODY_INTEGRATE_PATH);
|
||||
b3Assert(errNum==CL_SUCCESS);
|
||||
m_data->m_integrateTransformsKernel = b3OpenCLUtils::compileCLKernelFromString(m_data->m_context, m_data->m_device,integrateKernelCL, "integrateTransformsKernel",&errNum,prog);
|
||||
b3Assert(errNum==CL_SUCCESS);
|
||||
cl_program prog = b3OpenCLUtils::compileCLProgramFromString(m_data->m_context, m_data->m_device, integrateKernelCL, &errNum, "", B3_RIGIDBODY_INTEGRATE_PATH);
|
||||
b3Assert(errNum == CL_SUCCESS);
|
||||
m_data->m_integrateTransformsKernel = b3OpenCLUtils::compileCLKernelFromString(m_data->m_context, m_data->m_device, integrateKernelCL, "integrateTransformsKernel", &errNum, prog);
|
||||
b3Assert(errNum == CL_SUCCESS);
|
||||
clReleaseProgram(prog);
|
||||
}
|
||||
{
|
||||
cl_program prog = b3OpenCLUtils::compileCLProgramFromString(m_data->m_context,m_data->m_device,updateAabbsKernelCL,&errNum,"",B3_RIGIDBODY_UPDATEAABB_PATH);
|
||||
b3Assert(errNum==CL_SUCCESS);
|
||||
m_data->m_updateAabbsKernel = b3OpenCLUtils::compileCLKernelFromString(m_data->m_context, m_data->m_device,updateAabbsKernelCL, "initializeGpuAabbsFull",&errNum,prog);
|
||||
b3Assert(errNum==CL_SUCCESS);
|
||||
cl_program prog = b3OpenCLUtils::compileCLProgramFromString(m_data->m_context, m_data->m_device, updateAabbsKernelCL, &errNum, "", B3_RIGIDBODY_UPDATEAABB_PATH);
|
||||
b3Assert(errNum == CL_SUCCESS);
|
||||
m_data->m_updateAabbsKernel = b3OpenCLUtils::compileCLKernelFromString(m_data->m_context, m_data->m_device, updateAabbsKernelCL, "initializeGpuAabbsFull", &errNum, prog);
|
||||
b3Assert(errNum == CL_SUCCESS);
|
||||
|
||||
|
||||
m_data->m_clearOverlappingPairsKernel = b3OpenCLUtils::compileCLKernelFromString(m_data->m_context, m_data->m_device,updateAabbsKernelCL, "clearOverlappingPairsKernel",&errNum,prog);
|
||||
b3Assert(errNum==CL_SUCCESS);
|
||||
m_data->m_clearOverlappingPairsKernel = b3OpenCLUtils::compileCLKernelFromString(m_data->m_context, m_data->m_device, updateAabbsKernelCL, "clearOverlappingPairsKernel", &errNum, prog);
|
||||
b3Assert(errNum == CL_SUCCESS);
|
||||
|
||||
clReleaseProgram(prog);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
b3GpuRigidBodyPipeline::~b3GpuRigidBodyPipeline()
|
||||
{
|
||||
if (m_data->m_integrateTransformsKernel)
|
||||
clReleaseKernel(m_data->m_integrateTransformsKernel);
|
||||
|
||||
|
||||
if (m_data->m_updateAabbsKernel)
|
||||
clReleaseKernel(m_data->m_updateAabbsKernel);
|
||||
|
||||
|
||||
if (m_data->m_clearOverlappingPairsKernel)
|
||||
clReleaseKernel(m_data->m_clearOverlappingPairsKernel);
|
||||
delete m_data->m_raycaster;
|
||||
@@ -136,15 +131,14 @@ b3GpuRigidBodyPipeline::~b3GpuRigidBodyPipeline()
|
||||
|
||||
#ifdef TEST_OTHER_GPU_SOLVER
|
||||
delete m_data->m_solver3;
|
||||
#endif //TEST_OTHER_GPU_SOLVER
|
||||
|
||||
#endif //TEST_OTHER_GPU_SOLVER
|
||||
|
||||
delete m_data->m_solver2;
|
||||
|
||||
|
||||
|
||||
delete m_data;
|
||||
}
|
||||
|
||||
void b3GpuRigidBodyPipeline::reset()
|
||||
void b3GpuRigidBodyPipeline::reset()
|
||||
{
|
||||
m_data->m_gpuConstraints->resize(0);
|
||||
m_data->m_cpuConstraints.resize(0);
|
||||
@@ -152,30 +146,28 @@ void b3GpuRigidBodyPipeline::reset()
|
||||
m_data->m_allAabbsCPU.resize(0);
|
||||
}
|
||||
|
||||
void b3GpuRigidBodyPipeline::addConstraint(b3TypedConstraint* constraint)
|
||||
void b3GpuRigidBodyPipeline::addConstraint(b3TypedConstraint* constraint)
|
||||
{
|
||||
m_data->m_joints.push_back(constraint);
|
||||
}
|
||||
|
||||
void b3GpuRigidBodyPipeline::removeConstraint(b3TypedConstraint* constraint)
|
||||
void b3GpuRigidBodyPipeline::removeConstraint(b3TypedConstraint* constraint)
|
||||
{
|
||||
m_data->m_joints.remove(constraint);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void b3GpuRigidBodyPipeline::removeConstraintByUid(int uid)
|
||||
void b3GpuRigidBodyPipeline::removeConstraintByUid(int uid)
|
||||
{
|
||||
m_data->m_gpuSolver->recomputeBatches();
|
||||
//slow linear search
|
||||
m_data->m_gpuConstraints->copyToHost(m_data->m_cpuConstraints);
|
||||
//remove
|
||||
for (int i=0;i<m_data->m_cpuConstraints.size();i++)
|
||||
for (int i = 0; i < m_data->m_cpuConstraints.size(); i++)
|
||||
{
|
||||
if (m_data->m_cpuConstraints[i].m_uid == uid)
|
||||
{
|
||||
//m_data->m_cpuConstraints.remove(m_data->m_cpuConstraints[i]);
|
||||
m_data->m_cpuConstraints.swap(i,m_data->m_cpuConstraints.size()-1);
|
||||
m_data->m_cpuConstraints.swap(i, m_data->m_cpuConstraints.size() - 1);
|
||||
m_data->m_cpuConstraints.pop_back();
|
||||
|
||||
break;
|
||||
@@ -185,13 +177,13 @@ void b3GpuRigidBodyPipeline::removeConstraintByUid(int uid)
|
||||
if (m_data->m_cpuConstraints.size())
|
||||
{
|
||||
m_data->m_gpuConstraints->copyFromHost(m_data->m_cpuConstraints);
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
m_data->m_gpuConstraints->resize(0);
|
||||
}
|
||||
|
||||
}
|
||||
int b3GpuRigidBodyPipeline::createPoint2PointConstraint(int bodyA, int bodyB, const float* pivotInA, const float* pivotInB,float breakingThreshold)
|
||||
int b3GpuRigidBodyPipeline::createPoint2PointConstraint(int bodyA, int bodyB, const float* pivotInA, const float* pivotInB, float breakingThreshold)
|
||||
{
|
||||
m_data->m_gpuSolver->recomputeBatches();
|
||||
b3GpuGenericConstraint c;
|
||||
@@ -200,14 +192,14 @@ int b3GpuRigidBodyPipeline::createPoint2PointConstraint(int bodyA, int bodyB, co
|
||||
c.m_flags = B3_CONSTRAINT_FLAG_ENABLED;
|
||||
c.m_rbA = bodyA;
|
||||
c.m_rbB = bodyB;
|
||||
c.m_pivotInA.setValue(pivotInA[0],pivotInA[1],pivotInA[2]);
|
||||
c.m_pivotInB.setValue(pivotInB[0],pivotInB[1],pivotInB[2]);
|
||||
c.m_pivotInA.setValue(pivotInA[0], pivotInA[1], pivotInA[2]);
|
||||
c.m_pivotInB.setValue(pivotInB[0], pivotInB[1], pivotInB[2]);
|
||||
c.m_breakingImpulseThreshold = breakingThreshold;
|
||||
c.m_constraintType = B3_GPU_POINT2POINT_CONSTRAINT_TYPE;
|
||||
m_data->m_cpuConstraints.push_back(c);
|
||||
return c.m_uid;
|
||||
}
|
||||
int b3GpuRigidBodyPipeline::createFixedConstraint(int bodyA, int bodyB, const float* pivotInA, const float* pivotInB, const float* relTargetAB,float breakingThreshold)
|
||||
int b3GpuRigidBodyPipeline::createFixedConstraint(int bodyA, int bodyB, const float* pivotInA, const float* pivotInB, const float* relTargetAB, float breakingThreshold)
|
||||
{
|
||||
m_data->m_gpuSolver->recomputeBatches();
|
||||
b3GpuGenericConstraint c;
|
||||
@@ -216,9 +208,9 @@ int b3GpuRigidBodyPipeline::createFixedConstraint(int bodyA, int bodyB, const fl
|
||||
c.m_flags = B3_CONSTRAINT_FLAG_ENABLED;
|
||||
c.m_rbA = bodyA;
|
||||
c.m_rbB = bodyB;
|
||||
c.m_pivotInA.setValue(pivotInA[0],pivotInA[1],pivotInA[2]);
|
||||
c.m_pivotInB.setValue(pivotInB[0],pivotInB[1],pivotInB[2]);
|
||||
c.m_relTargetAB.setValue(relTargetAB[0],relTargetAB[1],relTargetAB[2],relTargetAB[3]);
|
||||
c.m_pivotInA.setValue(pivotInA[0], pivotInA[1], pivotInA[2]);
|
||||
c.m_pivotInB.setValue(pivotInB[0], pivotInB[1], pivotInB[2]);
|
||||
c.m_relTargetAB.setValue(relTargetAB[0], relTargetAB[1], relTargetAB[2], relTargetAB[3]);
|
||||
c.m_breakingImpulseThreshold = breakingThreshold;
|
||||
c.m_constraintType = B3_GPU_FIXED_CONSTRAINT_TYPE;
|
||||
|
||||
@@ -226,31 +218,28 @@ int b3GpuRigidBodyPipeline::createFixedConstraint(int bodyA, int bodyB, const fl
|
||||
return c.m_uid;
|
||||
}
|
||||
|
||||
|
||||
void b3GpuRigidBodyPipeline::stepSimulation(float deltaTime)
|
||||
void b3GpuRigidBodyPipeline::stepSimulation(float deltaTime)
|
||||
{
|
||||
|
||||
//update worldspace AABBs from local AABB/worldtransform
|
||||
{
|
||||
B3_PROFILE("setupGpuAabbs");
|
||||
setupGpuAabbsFull();
|
||||
}
|
||||
|
||||
int numPairs =0;
|
||||
int numPairs = 0;
|
||||
|
||||
//compute overlapping pairs
|
||||
{
|
||||
|
||||
if (gUseDbvt)
|
||||
{
|
||||
{
|
||||
B3_PROFILE("setAabb");
|
||||
m_data->m_allAabbsGPU->copyToHost(m_data->m_allAabbsCPU);
|
||||
for (int i=0;i<m_data->m_allAabbsCPU.size();i++)
|
||||
for (int i = 0; i < m_data->m_allAabbsCPU.size(); i++)
|
||||
{
|
||||
b3Vector3 aabbMin=b3MakeVector3(m_data->m_allAabbsCPU[i].m_min[0],m_data->m_allAabbsCPU[i].m_min[1],m_data->m_allAabbsCPU[i].m_min[2]);
|
||||
b3Vector3 aabbMax=b3MakeVector3(m_data->m_allAabbsCPU[i].m_max[0],m_data->m_allAabbsCPU[i].m_max[1],m_data->m_allAabbsCPU[i].m_max[2]);
|
||||
m_data->m_broadphaseDbvt->setAabb(i,aabbMin,aabbMax,0);
|
||||
b3Vector3 aabbMin = b3MakeVector3(m_data->m_allAabbsCPU[i].m_min[0], m_data->m_allAabbsCPU[i].m_min[1], m_data->m_allAabbsCPU[i].m_min[2]);
|
||||
b3Vector3 aabbMax = b3MakeVector3(m_data->m_allAabbsCPU[i].m_max[0], m_data->m_allAabbsCPU[i].m_max[1], m_data->m_allAabbsCPU[i].m_max[2]);
|
||||
m_data->m_broadphaseDbvt->setAabb(i, aabbMin, aabbMax, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,13 +248,14 @@ void b3GpuRigidBodyPipeline::stepSimulation(float deltaTime)
|
||||
m_data->m_broadphaseDbvt->calculateOverlappingPairs();
|
||||
}
|
||||
numPairs = m_data->m_broadphaseDbvt->getOverlappingPairCache()->getNumOverlappingPairs();
|
||||
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gUseCalculateOverlappingPairsHost)
|
||||
{
|
||||
m_data->m_broadphaseSap->calculateOverlappingPairsHost(m_data->m_config.m_maxBroadphasePairs);
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
m_data->m_broadphaseSap->calculateOverlappingPairs(m_data->m_config.m_maxBroadphasePairs);
|
||||
}
|
||||
@@ -274,24 +264,24 @@ void b3GpuRigidBodyPipeline::stepSimulation(float deltaTime)
|
||||
}
|
||||
|
||||
//compute contact points
|
||||
// printf("numPairs=%d\n",numPairs);
|
||||
|
||||
int numContacts = 0;
|
||||
// printf("numPairs=%d\n",numPairs);
|
||||
|
||||
int numContacts = 0;
|
||||
|
||||
int numBodies = m_data->m_narrowphase->getNumRigidBodies();
|
||||
|
||||
if (numPairs)
|
||||
{
|
||||
cl_mem pairs =0;
|
||||
cl_mem aabbsWS =0;
|
||||
cl_mem pairs = 0;
|
||||
cl_mem aabbsWS = 0;
|
||||
if (gUseDbvt)
|
||||
{
|
||||
B3_PROFILE("m_overlappingPairsGPU->copyFromHost");
|
||||
m_data->m_overlappingPairsGPU->copyFromHost(m_data->m_broadphaseDbvt->getOverlappingPairCache()->getOverlappingPairArray());
|
||||
pairs = m_data->m_overlappingPairsGPU->getBufferCL();
|
||||
aabbsWS = m_data->m_allAabbsGPU->getBufferCL();
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
pairs = m_data->m_broadphaseSap->getOverlappingPairBuffer();
|
||||
aabbsWS = m_data->m_broadphaseSap->getAabbBufferWS();
|
||||
@@ -302,31 +292,27 @@ void b3GpuRigidBodyPipeline::stepSimulation(float deltaTime)
|
||||
//mark the contacts for each pair as 'unused'
|
||||
if (numPairs)
|
||||
{
|
||||
b3OpenCLArray<b3BroadphasePair> gpuPairs(this->m_data->m_context,m_data->m_queue);
|
||||
gpuPairs.setFromOpenCLBuffer(pairs,numPairs);
|
||||
b3OpenCLArray<b3BroadphasePair> gpuPairs(this->m_data->m_context, m_data->m_queue);
|
||||
gpuPairs.setFromOpenCLBuffer(pairs, numPairs);
|
||||
|
||||
if (gClearPairsOnGpu)
|
||||
{
|
||||
|
||||
|
||||
//b3AlignedObjectArray<b3BroadphasePair> hostPairs;//just for debugging
|
||||
//gpuPairs.copyToHost(hostPairs);
|
||||
|
||||
b3LauncherCL launcher(m_data->m_queue,m_data->m_clearOverlappingPairsKernel,"clearOverlappingPairsKernel");
|
||||
b3LauncherCL launcher(m_data->m_queue, m_data->m_clearOverlappingPairsKernel, "clearOverlappingPairsKernel");
|
||||
launcher.setBuffer(pairs);
|
||||
launcher.setConst(numPairs);
|
||||
launcher.launch1D(numPairs);
|
||||
|
||||
|
||||
//gpuPairs.copyToHost(hostPairs);
|
||||
|
||||
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
b3AlignedObjectArray<b3BroadphasePair> hostPairs;
|
||||
gpuPairs.copyToHost(hostPairs);
|
||||
|
||||
for (int i=0;i<hostPairs.size();i++)
|
||||
for (int i = 0; i < hostPairs.size(); i++)
|
||||
{
|
||||
hostPairs[i].z = 0xffffffff;
|
||||
}
|
||||
@@ -335,7 +321,7 @@ void b3GpuRigidBodyPipeline::stepSimulation(float deltaTime)
|
||||
}
|
||||
}
|
||||
|
||||
m_data->m_narrowphase->computeContacts(pairs,numPairs,aabbsWS,numBodies);
|
||||
m_data->m_narrowphase->computeContacts(pairs, numPairs, aabbsWS, numBodies);
|
||||
numContacts = m_data->m_narrowphase->getNumContactsGpu();
|
||||
|
||||
if (gUseDbvt)
|
||||
@@ -347,56 +333,54 @@ void b3GpuRigidBodyPipeline::stepSimulation(float deltaTime)
|
||||
if (gDumpContactStats && numContacts)
|
||||
{
|
||||
m_data->m_narrowphase->getContactsGpu();
|
||||
|
||||
|
||||
printf("numContacts = %d\n", numContacts);
|
||||
|
||||
int totalPoints = 0;
|
||||
int totalPoints = 0;
|
||||
const b3Contact4* contacts = m_data->m_narrowphase->getContactsCPU();
|
||||
|
||||
for (int i=0;i<numContacts;i++)
|
||||
for (int i = 0; i < numContacts; i++)
|
||||
{
|
||||
totalPoints += contacts->getNPoints();
|
||||
}
|
||||
printf("totalPoints=%d\n",totalPoints);
|
||||
|
||||
printf("totalPoints=%d\n", totalPoints);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//convert contact points to contact constraints
|
||||
|
||||
|
||||
//solve constraints
|
||||
|
||||
b3OpenCLArray<b3RigidBodyData> gpuBodies(m_data->m_context,m_data->m_queue,0,true);
|
||||
gpuBodies.setFromOpenCLBuffer(m_data->m_narrowphase->getBodiesGpu(),m_data->m_narrowphase->getNumRigidBodies());
|
||||
b3OpenCLArray<b3InertiaData> gpuInertias(m_data->m_context,m_data->m_queue,0,true);
|
||||
gpuInertias.setFromOpenCLBuffer(m_data->m_narrowphase->getBodyInertiasGpu(),m_data->m_narrowphase->getNumRigidBodies());
|
||||
b3OpenCLArray<b3Contact4> gpuContacts(m_data->m_context,m_data->m_queue,0,true);
|
||||
gpuContacts.setFromOpenCLBuffer(m_data->m_narrowphase->getContactsGpu(),m_data->m_narrowphase->getNumContactsGpu());
|
||||
b3OpenCLArray<b3RigidBodyData> gpuBodies(m_data->m_context, m_data->m_queue, 0, true);
|
||||
gpuBodies.setFromOpenCLBuffer(m_data->m_narrowphase->getBodiesGpu(), m_data->m_narrowphase->getNumRigidBodies());
|
||||
b3OpenCLArray<b3InertiaData> gpuInertias(m_data->m_context, m_data->m_queue, 0, true);
|
||||
gpuInertias.setFromOpenCLBuffer(m_data->m_narrowphase->getBodyInertiasGpu(), m_data->m_narrowphase->getNumRigidBodies());
|
||||
b3OpenCLArray<b3Contact4> gpuContacts(m_data->m_context, m_data->m_queue, 0, true);
|
||||
gpuContacts.setFromOpenCLBuffer(m_data->m_narrowphase->getContactsGpu(), m_data->m_narrowphase->getNumContactsGpu());
|
||||
|
||||
int numJoints = m_data->m_joints.size() ? m_data->m_joints.size() : m_data->m_cpuConstraints.size();
|
||||
int numJoints = m_data->m_joints.size() ? m_data->m_joints.size() : m_data->m_cpuConstraints.size();
|
||||
if (useBullet2CpuSolver && numJoints)
|
||||
{
|
||||
|
||||
// b3AlignedObjectArray<b3Contact4> hostContacts;
|
||||
// b3AlignedObjectArray<b3Contact4> hostContacts;
|
||||
//gpuContacts.copyToHost(hostContacts);
|
||||
{
|
||||
bool useGpu = m_data->m_joints.size()==0;
|
||||
bool useGpu = m_data->m_joints.size() == 0;
|
||||
|
||||
// b3Contact4* contacts = numContacts? &hostContacts[0]: 0;
|
||||
// b3Contact4* contacts = numContacts? &hostContacts[0]: 0;
|
||||
//m_data->m_solver->solveContacts(m_data->m_narrowphase->getNumBodiesGpu(),&hostBodies[0],&hostInertias[0],numContacts,contacts,numJoints, joints);
|
||||
if (useGpu)
|
||||
{
|
||||
m_data->m_gpuSolver->solveJoints(m_data->m_narrowphase->getNumRigidBodies(),&gpuBodies,&gpuInertias,numJoints, m_data->m_gpuConstraints);
|
||||
} else
|
||||
m_data->m_gpuSolver->solveJoints(m_data->m_narrowphase->getNumRigidBodies(), &gpuBodies, &gpuInertias, numJoints, m_data->m_gpuConstraints);
|
||||
}
|
||||
else
|
||||
{
|
||||
b3AlignedObjectArray<b3RigidBodyData> hostBodies;
|
||||
gpuBodies.copyToHost(hostBodies);
|
||||
b3AlignedObjectArray<b3InertiaData> hostInertias;
|
||||
gpuInertias.copyToHost(hostInertias);
|
||||
|
||||
b3TypedConstraint** joints = numJoints? &m_data->m_joints[0] : 0;
|
||||
m_data->m_solver->solveContacts(m_data->m_narrowphase->getNumRigidBodies(),&hostBodies[0],&hostInertias[0],0,0,numJoints, joints);
|
||||
b3TypedConstraint** joints = numJoints ? &m_data->m_joints[0] : 0;
|
||||
m_data->m_solver->solveContacts(m_data->m_narrowphase->getNumRigidBodies(), &hostBodies[0], &hostInertias[0], 0, 0, numJoints, joints);
|
||||
gpuBodies.copyFromHost(hostBodies);
|
||||
}
|
||||
}
|
||||
@@ -404,22 +388,20 @@ void b3GpuRigidBodyPipeline::stepSimulation(float deltaTime)
|
||||
|
||||
if (numContacts)
|
||||
{
|
||||
|
||||
#ifdef TEST_OTHER_GPU_SOLVER
|
||||
|
||||
|
||||
if (gUseJacobi)
|
||||
{
|
||||
bool useGpu = true;
|
||||
if (useGpu)
|
||||
{
|
||||
|
||||
bool forceHost = false;
|
||||
if (forceHost)
|
||||
{
|
||||
b3AlignedObjectArray<b3RigidBodyData> hostBodies;
|
||||
b3AlignedObjectArray<b3InertiaData> hostInertias;
|
||||
b3AlignedObjectArray<b3Contact4> hostContacts;
|
||||
|
||||
|
||||
{
|
||||
B3_PROFILE("copyToHost");
|
||||
gpuBodies.copyToHost(hostBodies);
|
||||
@@ -429,25 +411,24 @@ void b3GpuRigidBodyPipeline::stepSimulation(float deltaTime)
|
||||
|
||||
{
|
||||
b3JacobiSolverInfo solverInfo;
|
||||
m_data->m_solver3->solveGroupHost(&hostBodies[0], &hostInertias[0], hostBodies.size(),&hostContacts[0],hostContacts.size(),solverInfo);
|
||||
|
||||
|
||||
m_data->m_solver3->solveGroupHost(&hostBodies[0], &hostInertias[0], hostBodies.size(), &hostContacts[0], hostContacts.size(), solverInfo);
|
||||
}
|
||||
{
|
||||
B3_PROFILE("copyFromHost");
|
||||
gpuBodies.copyFromHost(hostBodies);
|
||||
}
|
||||
} else
|
||||
|
||||
}
|
||||
else
|
||||
|
||||
{
|
||||
int static0Index = m_data->m_narrowphase->getStatic0Index();
|
||||
b3JacobiSolverInfo solverInfo;
|
||||
//m_data->m_solver3->solveContacts( >solveGroup(&gpuBodies, &gpuInertias, &gpuContacts,solverInfo);
|
||||
//m_data->m_solver3->solveContacts(m_data->m_narrowphase->getNumBodiesGpu(),&hostBodies[0],&hostInertias[0],numContacts,&hostContacts[0]);
|
||||
m_data->m_solver3->solveContacts(numBodies, gpuBodies.getBufferCL(),gpuInertias.getBufferCL(),numContacts, gpuContacts.getBufferCL(),m_data->m_config, static0Index);
|
||||
m_data->m_solver3->solveContacts(numBodies, gpuBodies.getBufferCL(), gpuInertias.getBufferCL(), numContacts, gpuContacts.getBufferCL(), m_data->m_config, static0Index);
|
||||
}
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
b3AlignedObjectArray<b3RigidBodyData> hostBodies;
|
||||
gpuBodies.copyToHost(hostBodies);
|
||||
@@ -460,17 +441,15 @@ void b3GpuRigidBodyPipeline::stepSimulation(float deltaTime)
|
||||
}
|
||||
gpuBodies.copyFromHost(hostBodies);
|
||||
}
|
||||
|
||||
} else
|
||||
#endif //TEST_OTHER_GPU_SOLVER
|
||||
}
|
||||
else
|
||||
#endif //TEST_OTHER_GPU_SOLVER
|
||||
{
|
||||
|
||||
int static0Index = m_data->m_narrowphase->getStatic0Index();
|
||||
m_data->m_solver2->solveContacts(numBodies, gpuBodies.getBufferCL(),gpuInertias.getBufferCL(),numContacts, gpuContacts.getBufferCL(),m_data->m_config, static0Index);
|
||||
|
||||
m_data->m_solver2->solveContacts(numBodies, gpuBodies.getBufferCL(), gpuInertias.getBufferCL(), numContacts, gpuContacts.getBufferCL(), m_data->m_config, static0Index);
|
||||
|
||||
//m_data->m_solver4->solveContacts(m_data->m_narrowphase->getNumBodiesGpu(), gpuBodies.getBufferCL(), gpuInertias.getBufferCL(), numContacts, gpuContacts.getBufferCL());
|
||||
|
||||
|
||||
|
||||
/*m_data->m_solver3->solveContactConstraintHost(
|
||||
(b3OpenCLArray<RigidBodyBase::Body>*)&gpuBodies,
|
||||
(b3OpenCLArray<RigidBodyBase::Inertia>*)&gpuInertias,
|
||||
@@ -481,11 +460,9 @@ void b3GpuRigidBodyPipeline::stepSimulation(float deltaTime)
|
||||
}
|
||||
|
||||
integrate(deltaTime);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void b3GpuRigidBodyPipeline::integrate(float timeStep)
|
||||
void b3GpuRigidBodyPipeline::integrate(float timeStep)
|
||||
{
|
||||
//integrate
|
||||
int numBodies = m_data->m_narrowphase->getNumRigidBodies();
|
||||
@@ -493,24 +470,25 @@ void b3GpuRigidBodyPipeline::integrate(float timeStep)
|
||||
|
||||
if (gIntegrateOnCpu)
|
||||
{
|
||||
if(numBodies)
|
||||
if (numBodies)
|
||||
{
|
||||
b3GpuNarrowPhaseInternalData* npData = m_data->m_narrowphase->getInternalData();
|
||||
b3GpuNarrowPhaseInternalData* npData = m_data->m_narrowphase->getInternalData();
|
||||
npData->m_bodyBufferGPU->copyToHost(*npData->m_bodyBufferCPU);
|
||||
|
||||
b3RigidBodyData_t* bodies = &npData->m_bodyBufferCPU->at(0);
|
||||
|
||||
for (int nodeID=0;nodeID<numBodies;nodeID++)
|
||||
for (int nodeID = 0; nodeID < numBodies; nodeID++)
|
||||
{
|
||||
integrateSingleTransform( bodies,nodeID, timeStep, angularDamp, m_data->m_gravity);
|
||||
integrateSingleTransform(bodies, nodeID, timeStep, angularDamp, m_data->m_gravity);
|
||||
}
|
||||
npData->m_bodyBufferGPU->copyFromHost(*npData->m_bodyBufferCPU);
|
||||
}
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
b3LauncherCL launcher(m_data->m_queue,m_data->m_integrateTransformsKernel,"m_integrateTransformsKernel");
|
||||
b3LauncherCL launcher(m_data->m_queue, m_data->m_integrateTransformsKernel, "m_integrateTransformsKernel");
|
||||
launcher.setBuffer(m_data->m_narrowphase->getBodiesGpu());
|
||||
|
||||
|
||||
launcher.setConst(numBodies);
|
||||
launcher.setConst(timeStep);
|
||||
launcher.setConst(angularDamp);
|
||||
@@ -519,12 +497,9 @@ void b3GpuRigidBodyPipeline::integrate(float timeStep)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void b3GpuRigidBodyPipeline::setupGpuAabbsFull()
|
||||
void b3GpuRigidBodyPipeline::setupGpuAabbsFull()
|
||||
{
|
||||
cl_int ciErrNum=0;
|
||||
cl_int ciErrNum = 0;
|
||||
|
||||
int numBodies = m_data->m_narrowphase->getNumRigidBodies();
|
||||
if (!numBodies)
|
||||
@@ -532,34 +507,35 @@ void b3GpuRigidBodyPipeline::setupGpuAabbsFull()
|
||||
|
||||
if (gCalcWorldSpaceAabbOnCpu)
|
||||
{
|
||||
|
||||
if (numBodies)
|
||||
{
|
||||
if (gUseDbvt)
|
||||
{
|
||||
m_data->m_allAabbsCPU.resize(numBodies);
|
||||
m_data->m_narrowphase->readbackAllBodiesToCpu();
|
||||
for (int i=0;i<numBodies;i++)
|
||||
for (int i = 0; i < numBodies; i++)
|
||||
{
|
||||
b3ComputeWorldAabb( i, m_data->m_narrowphase->getBodiesCpu(), m_data->m_narrowphase->getCollidablesCpu(), m_data->m_narrowphase->getLocalSpaceAabbsCpu(),&m_data->m_allAabbsCPU[0]);
|
||||
b3ComputeWorldAabb(i, m_data->m_narrowphase->getBodiesCpu(), m_data->m_narrowphase->getCollidablesCpu(), m_data->m_narrowphase->getLocalSpaceAabbsCpu(), &m_data->m_allAabbsCPU[0]);
|
||||
}
|
||||
m_data->m_allAabbsGPU->copyFromHost(m_data->m_allAabbsCPU);
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
m_data->m_broadphaseSap->getAllAabbsCPU().resize(numBodies);
|
||||
m_data->m_narrowphase->readbackAllBodiesToCpu();
|
||||
for (int i=0;i<numBodies;i++)
|
||||
for (int i = 0; i < numBodies; i++)
|
||||
{
|
||||
b3ComputeWorldAabb( i, m_data->m_narrowphase->getBodiesCpu(), m_data->m_narrowphase->getCollidablesCpu(), m_data->m_narrowphase->getLocalSpaceAabbsCpu(),&m_data->m_broadphaseSap->getAllAabbsCPU()[0]);
|
||||
b3ComputeWorldAabb(i, m_data->m_narrowphase->getBodiesCpu(), m_data->m_narrowphase->getCollidablesCpu(), m_data->m_narrowphase->getLocalSpaceAabbsCpu(), &m_data->m_broadphaseSap->getAllAabbsCPU()[0]);
|
||||
}
|
||||
m_data->m_broadphaseSap->getAllAabbsGPU().copyFromHost(m_data->m_broadphaseSap->getAllAabbsCPU());
|
||||
//m_data->m_broadphaseSap->writeAabbsToGpu();
|
||||
}
|
||||
}
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
//__kernel void initializeGpuAabbsFull( const int numNodes, __global Body* gBodies,__global Collidable* collidables, __global b3AABBCL* plocalShapeAABB, __global b3AABBCL* pAABB)
|
||||
b3LauncherCL launcher(m_data->m_queue,m_data->m_updateAabbsKernel,"m_updateAabbsKernel");
|
||||
b3LauncherCL launcher(m_data->m_queue, m_data->m_updateAabbsKernel, "m_updateAabbsKernel");
|
||||
launcher.setConst(numBodies);
|
||||
cl_mem bodies = m_data->m_narrowphase->getBodiesGpu();
|
||||
launcher.setBuffer(bodies);
|
||||
@@ -568,17 +544,18 @@ void b3GpuRigidBodyPipeline::setupGpuAabbsFull()
|
||||
cl_mem localAabbs = m_data->m_narrowphase->getAabbLocalSpaceBufferGpu();
|
||||
launcher.setBuffer(localAabbs);
|
||||
|
||||
cl_mem worldAabbs =0;
|
||||
cl_mem worldAabbs = 0;
|
||||
if (gUseDbvt)
|
||||
{
|
||||
worldAabbs = m_data->m_allAabbsGPU->getBufferCL();
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
worldAabbs = m_data->m_broadphaseSap->getAabbBufferWS();
|
||||
}
|
||||
launcher.setBuffer(worldAabbs);
|
||||
launcher.launch1D(numBodies);
|
||||
|
||||
|
||||
oclCHECKERROR(ciErrNum, CL_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -595,78 +572,68 @@ void b3GpuRigidBodyPipeline::setupGpuAabbsFull()
|
||||
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
cl_mem b3GpuRigidBodyPipeline::getBodyBuffer()
|
||||
cl_mem b3GpuRigidBodyPipeline::getBodyBuffer()
|
||||
{
|
||||
return m_data->m_narrowphase->getBodiesGpu();
|
||||
}
|
||||
|
||||
int b3GpuRigidBodyPipeline::getNumBodies() const
|
||||
int b3GpuRigidBodyPipeline::getNumBodies() const
|
||||
{
|
||||
return m_data->m_narrowphase->getNumRigidBodies();
|
||||
}
|
||||
|
||||
void b3GpuRigidBodyPipeline::setGravity(const float* grav)
|
||||
void b3GpuRigidBodyPipeline::setGravity(const float* grav)
|
||||
{
|
||||
m_data->m_gravity.setValue(grav[0],grav[1],grav[2]);
|
||||
m_data->m_gravity.setValue(grav[0], grav[1], grav[2]);
|
||||
}
|
||||
|
||||
void b3GpuRigidBodyPipeline::copyConstraintsToHost()
|
||||
void b3GpuRigidBodyPipeline::copyConstraintsToHost()
|
||||
{
|
||||
m_data->m_gpuConstraints->copyToHost(m_data->m_cpuConstraints);
|
||||
}
|
||||
|
||||
void b3GpuRigidBodyPipeline::writeAllInstancesToGpu()
|
||||
void b3GpuRigidBodyPipeline::writeAllInstancesToGpu()
|
||||
{
|
||||
m_data->m_allAabbsGPU->copyFromHost(m_data->m_allAabbsCPU);
|
||||
m_data->m_gpuConstraints->copyFromHost(m_data->m_cpuConstraints);
|
||||
}
|
||||
|
||||
|
||||
int b3GpuRigidBodyPipeline::registerPhysicsInstance(float mass, const float* position, const float* orientation, int collidableIndex, int userIndex, bool writeInstanceToGpu)
|
||||
int b3GpuRigidBodyPipeline::registerPhysicsInstance(float mass, const float* position, const float* orientation, int collidableIndex, int userIndex, bool writeInstanceToGpu)
|
||||
{
|
||||
|
||||
b3Vector3 aabbMin=b3MakeVector3(0,0,0),aabbMax=b3MakeVector3(0,0,0);
|
||||
b3Vector3 aabbMin = b3MakeVector3(0, 0, 0), aabbMax = b3MakeVector3(0, 0, 0);
|
||||
|
||||
|
||||
if (collidableIndex>=0)
|
||||
if (collidableIndex >= 0)
|
||||
{
|
||||
b3SapAabb localAabb = m_data->m_narrowphase->getLocalSpaceAabb(collidableIndex);
|
||||
b3Vector3 localAabbMin=b3MakeVector3(localAabb.m_min[0],localAabb.m_min[1],localAabb.m_min[2]);
|
||||
b3Vector3 localAabbMax=b3MakeVector3(localAabb.m_max[0],localAabb.m_max[1],localAabb.m_max[2]);
|
||||
|
||||
b3Vector3 localAabbMin = b3MakeVector3(localAabb.m_min[0], localAabb.m_min[1], localAabb.m_min[2]);
|
||||
b3Vector3 localAabbMax = b3MakeVector3(localAabb.m_max[0], localAabb.m_max[1], localAabb.m_max[2]);
|
||||
|
||||
b3Scalar margin = 0.01f;
|
||||
b3Transform t;
|
||||
t.setIdentity();
|
||||
t.setOrigin(b3MakeVector3(position[0],position[1],position[2]));
|
||||
t.setRotation(b3Quaternion(orientation[0],orientation[1],orientation[2],orientation[3]));
|
||||
b3TransformAabb(localAabbMin,localAabbMax, margin,t,aabbMin,aabbMax);
|
||||
} else
|
||||
t.setOrigin(b3MakeVector3(position[0], position[1], position[2]));
|
||||
t.setRotation(b3Quaternion(orientation[0], orientation[1], orientation[2], orientation[3]));
|
||||
b3TransformAabb(localAabbMin, localAabbMax, margin, t, aabbMin, aabbMax);
|
||||
}
|
||||
else
|
||||
{
|
||||
b3Error("registerPhysicsInstance using invalid collidableIndex\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool writeToGpu = false;
|
||||
int bodyIndex = m_data->m_narrowphase->getNumRigidBodies();
|
||||
bodyIndex = m_data->m_narrowphase->registerRigidBody(collidableIndex,mass,position,orientation,&aabbMin.getX(),&aabbMax.getX(),writeToGpu);
|
||||
bodyIndex = m_data->m_narrowphase->registerRigidBody(collidableIndex, mass, position, orientation, &aabbMin.getX(), &aabbMax.getX(), writeToGpu);
|
||||
|
||||
if (bodyIndex>=0)
|
||||
if (bodyIndex >= 0)
|
||||
{
|
||||
if (gUseDbvt)
|
||||
{
|
||||
m_data->m_broadphaseDbvt->createProxy(aabbMin,aabbMax,bodyIndex,0,1,1);
|
||||
m_data->m_broadphaseDbvt->createProxy(aabbMin, aabbMax, bodyIndex, 0, 1, 1);
|
||||
b3SapAabb aabb;
|
||||
for (int i=0;i<3;i++)
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
aabb.m_min[i] = aabbMin[i];
|
||||
aabb.m_max[i] = aabbMax[i];
|
||||
@@ -677,14 +644,16 @@ int b3GpuRigidBodyPipeline::registerPhysicsInstance(float mass, const float* po
|
||||
{
|
||||
m_data->m_allAabbsGPU->copyFromHost(m_data->m_allAabbsCPU);
|
||||
}
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mass)
|
||||
{
|
||||
m_data->m_broadphaseSap->createProxy(aabbMin,aabbMax,bodyIndex,1,1);//m_dispatcher);
|
||||
} else
|
||||
m_data->m_broadphaseSap->createProxy(aabbMin, aabbMax, bodyIndex, 1, 1); //m_dispatcher);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_data->m_broadphaseSap->createLargeProxy(aabbMin,aabbMax,bodyIndex,1,1);//m_dispatcher);
|
||||
m_data->m_broadphaseSap->createLargeProxy(aabbMin, aabbMax, bodyIndex, 1, 1); //m_dispatcher);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -699,10 +668,10 @@ int b3GpuRigidBodyPipeline::registerPhysicsInstance(float mass, const float* po
|
||||
return bodyIndex;
|
||||
}
|
||||
|
||||
void b3GpuRigidBodyPipeline::castRays(const b3AlignedObjectArray<b3RayInfo>& rays, b3AlignedObjectArray<b3RayHit>& hitResults)
|
||||
void b3GpuRigidBodyPipeline::castRays(const b3AlignedObjectArray<b3RayInfo>& rays, b3AlignedObjectArray<b3RayHit>& hitResults)
|
||||
{
|
||||
this->m_data->m_raycaster->castRays(rays,hitResults,
|
||||
getNumBodies(),this->m_data->m_narrowphase->getBodiesCpu(),
|
||||
m_data->m_narrowphase->getNumCollidablesGpu(), m_data->m_narrowphase->getCollidablesCpu(),
|
||||
m_data->m_narrowphase->getInternalData(), m_data->m_broadphaseSap);
|
||||
this->m_data->m_raycaster->castRays(rays, hitResults,
|
||||
getNumBodies(), this->m_data->m_narrowphase->getBodiesCpu(),
|
||||
m_data->m_narrowphase->getNumCollidablesGpu(), m_data->m_narrowphase->getCollidablesCpu(),
|
||||
m_data->m_narrowphase->getInternalData(), m_data->m_broadphaseSap);
|
||||
}
|
||||
|
||||
@@ -25,50 +25,46 @@ subject to the following restrictions:
|
||||
class b3GpuRigidBodyPipeline
|
||||
{
|
||||
protected:
|
||||
struct b3GpuRigidBodyPipelineInternalData* m_data;
|
||||
struct b3GpuRigidBodyPipelineInternalData* m_data;
|
||||
|
||||
int allocateCollidable();
|
||||
|
||||
public:
|
||||
|
||||
|
||||
b3GpuRigidBodyPipeline(cl_context ctx,cl_device_id device, cl_command_queue q , class b3GpuNarrowPhase* narrowphase, class b3GpuBroadphaseInterface* broadphaseSap, struct b3DynamicBvhBroadphase* broadphaseDbvt, const b3Config& config);
|
||||
b3GpuRigidBodyPipeline(cl_context ctx, cl_device_id device, cl_command_queue q, class b3GpuNarrowPhase* narrowphase, class b3GpuBroadphaseInterface* broadphaseSap, struct b3DynamicBvhBroadphase* broadphaseDbvt, const b3Config& config);
|
||||
virtual ~b3GpuRigidBodyPipeline();
|
||||
|
||||
void stepSimulation(float deltaTime);
|
||||
void integrate(float timeStep);
|
||||
void setupGpuAabbsFull();
|
||||
void stepSimulation(float deltaTime);
|
||||
void integrate(float timeStep);
|
||||
void setupGpuAabbsFull();
|
||||
|
||||
int registerConvexPolyhedron(class b3ConvexUtility* convex);
|
||||
int registerConvexPolyhedron(class b3ConvexUtility* convex);
|
||||
|
||||
//int registerConvexPolyhedron(const float* vertices, int strideInBytes, int numVertices, const float* scaling);
|
||||
//int registerSphereShape(float radius);
|
||||
//int registerPlaneShape(const b3Vector3& planeNormal, float planeConstant);
|
||||
|
||||
|
||||
//int registerConcaveMesh(b3AlignedObjectArray<b3Vector3>* vertices, b3AlignedObjectArray<int>* indices, const float* scaling);
|
||||
//int registerCompoundShape(b3AlignedObjectArray<b3GpuChildShape>* childShapes);
|
||||
|
||||
|
||||
int registerPhysicsInstance(float mass, const float* position, const float* orientation, int collisionShapeIndex, int userData, bool writeInstanceToGpu);
|
||||
int registerPhysicsInstance(float mass, const float* position, const float* orientation, int collisionShapeIndex, int userData, bool writeInstanceToGpu);
|
||||
//if you passed "writeInstanceToGpu" false in the registerPhysicsInstance method (for performance) you need to call writeAllInstancesToGpu after all instances are registered
|
||||
void writeAllInstancesToGpu();
|
||||
void copyConstraintsToHost();
|
||||
void setGravity(const float* grav);
|
||||
void writeAllInstancesToGpu();
|
||||
void copyConstraintsToHost();
|
||||
void setGravity(const float* grav);
|
||||
void reset();
|
||||
|
||||
int createPoint2PointConstraint(int bodyA, int bodyB, const float* pivotInA, const float* pivotInB,float breakingThreshold);
|
||||
|
||||
int createPoint2PointConstraint(int bodyA, int bodyB, const float* pivotInA, const float* pivotInB, float breakingThreshold);
|
||||
int createFixedConstraint(int bodyA, int bodyB, const float* pivotInA, const float* pivotInB, const float* relTargetAB, float breakingThreshold);
|
||||
void removeConstraintByUid(int uid);
|
||||
|
||||
void addConstraint(class b3TypedConstraint* constraint);
|
||||
void removeConstraint(b3TypedConstraint* constraint);
|
||||
void addConstraint(class b3TypedConstraint* constraint);
|
||||
void removeConstraint(b3TypedConstraint* constraint);
|
||||
|
||||
void castRays(const b3AlignedObjectArray<b3RayInfo>& rays, b3AlignedObjectArray<b3RayHit>& hitResults);
|
||||
void castRays(const b3AlignedObjectArray<b3RayInfo>& rays, b3AlignedObjectArray<b3RayHit>& hitResults);
|
||||
|
||||
cl_mem getBodyBuffer();
|
||||
|
||||
int getNumBodies() const;
|
||||
cl_mem getBodyBuffer();
|
||||
|
||||
int getNumBodies() const;
|
||||
};
|
||||
|
||||
#endif //B3_GPU_RIGIDBODY_PIPELINE_H
|
||||
#endif //B3_GPU_RIGIDBODY_PIPELINE_H
|
||||
@@ -22,52 +22,47 @@ subject to the following restrictions:
|
||||
#include "Bullet3OpenCL/ParallelPrimitives/b3OpenCLArray.h"
|
||||
#include "Bullet3Collision/NarrowPhaseCollision/shared/b3Collidable.h"
|
||||
|
||||
|
||||
#include "Bullet3OpenCL/BroadphaseCollision/b3SapAabb.h"
|
||||
#include "Bullet3Dynamics/ConstraintSolver/b3TypedConstraint.h"
|
||||
#include "Bullet3Collision/NarrowPhaseCollision/b3Config.h"
|
||||
|
||||
|
||||
|
||||
#include "Bullet3Collision/BroadPhaseCollision/b3OverlappingPair.h"
|
||||
#include "Bullet3OpenCL/RigidBody/b3GpuGenericConstraint.h"
|
||||
|
||||
struct b3GpuRigidBodyPipelineInternalData
|
||||
{
|
||||
cl_context m_context;
|
||||
cl_device_id m_device;
|
||||
cl_command_queue m_queue;
|
||||
|
||||
cl_context m_context;
|
||||
cl_device_id m_device;
|
||||
cl_command_queue m_queue;
|
||||
cl_kernel m_integrateTransformsKernel;
|
||||
cl_kernel m_updateAabbsKernel;
|
||||
cl_kernel m_clearOverlappingPairsKernel;
|
||||
|
||||
cl_kernel m_integrateTransformsKernel;
|
||||
cl_kernel m_updateAabbsKernel;
|
||||
cl_kernel m_clearOverlappingPairsKernel;
|
||||
|
||||
class b3PgsJacobiSolver* m_solver;
|
||||
|
||||
|
||||
class b3GpuPgsConstraintSolver* m_gpuSolver;
|
||||
|
||||
class b3GpuPgsContactSolver* m_solver2;
|
||||
class b3GpuJacobiContactSolver* m_solver3;
|
||||
class b3GpuRaycast* m_raycaster;
|
||||
|
||||
|
||||
class b3GpuBroadphaseInterface* m_broadphaseSap;
|
||||
|
||||
|
||||
struct b3DynamicBvhBroadphase* m_broadphaseDbvt;
|
||||
b3OpenCLArray<b3SapAabb>* m_allAabbsGPU;
|
||||
b3AlignedObjectArray<b3SapAabb> m_allAabbsCPU;
|
||||
b3OpenCLArray<b3BroadphasePair>* m_overlappingPairsGPU;
|
||||
b3OpenCLArray<b3SapAabb>* m_allAabbsGPU;
|
||||
b3AlignedObjectArray<b3SapAabb> m_allAabbsCPU;
|
||||
b3OpenCLArray<b3BroadphasePair>* m_overlappingPairsGPU;
|
||||
|
||||
b3OpenCLArray<b3GpuGenericConstraint>* m_gpuConstraints;
|
||||
b3AlignedObjectArray<b3GpuGenericConstraint> m_cpuConstraints;
|
||||
|
||||
b3AlignedObjectArray<b3TypedConstraint*> m_joints;
|
||||
int m_constraintUid;
|
||||
class b3GpuNarrowPhase* m_narrowphase;
|
||||
b3Vector3 m_gravity;
|
||||
int m_constraintUid;
|
||||
class b3GpuNarrowPhase* m_narrowphase;
|
||||
b3Vector3 m_gravity;
|
||||
|
||||
b3Config m_config;
|
||||
b3Config m_config;
|
||||
};
|
||||
|
||||
#endif //B3_GPU_RIGIDBODY_PIPELINE_INTERNAL_DATA_H
|
||||
|
||||
#endif //B3_GPU_RIGIDBODY_PIPELINE_INTERNAL_DATA_H
|
||||
|
||||
@@ -13,11 +13,9 @@ subject to the following restrictions:
|
||||
*/
|
||||
//Originally written by Erwin Coumans
|
||||
|
||||
|
||||
#ifndef B3_GPU_SOLVER_BODY_H
|
||||
#define B3_GPU_SOLVER_BODY_H
|
||||
|
||||
|
||||
#include "Bullet3Common/b3Vector3.h"
|
||||
#include "Bullet3Common/b3Matrix3x3.h"
|
||||
|
||||
@@ -27,29 +25,27 @@ subject to the following restrictions:
|
||||
///Until we get other contributions, only use SIMD on Windows, when using Visual Studio 2008 or later, and not double precision
|
||||
#ifdef B3_USE_SSE
|
||||
#define USE_SIMD 1
|
||||
#endif //
|
||||
|
||||
|
||||
#endif //
|
||||
|
||||
///The b3SolverBody is an internal datastructure for the constraint solver. Only necessary data is packed to increase cache coherence/performance.
|
||||
B3_ATTRIBUTE_ALIGNED16 (struct) b3GpuSolverBody
|
||||
B3_ATTRIBUTE_ALIGNED16(struct)
|
||||
b3GpuSolverBody
|
||||
{
|
||||
B3_DECLARE_ALIGNED_ALLOCATOR();
|
||||
// b3Transform m_worldTransformUnused;
|
||||
b3Vector3 m_deltaLinearVelocity;
|
||||
b3Vector3 m_deltaAngularVelocity;
|
||||
b3Vector3 m_angularFactor;
|
||||
b3Vector3 m_linearFactor;
|
||||
b3Vector3 m_invMass;
|
||||
b3Vector3 m_pushVelocity;
|
||||
b3Vector3 m_turnVelocity;
|
||||
b3Vector3 m_linearVelocity;
|
||||
b3Vector3 m_angularVelocity;
|
||||
// b3Transform m_worldTransformUnused;
|
||||
b3Vector3 m_deltaLinearVelocity;
|
||||
b3Vector3 m_deltaAngularVelocity;
|
||||
b3Vector3 m_angularFactor;
|
||||
b3Vector3 m_linearFactor;
|
||||
b3Vector3 m_invMass;
|
||||
b3Vector3 m_pushVelocity;
|
||||
b3Vector3 m_turnVelocity;
|
||||
b3Vector3 m_linearVelocity;
|
||||
b3Vector3 m_angularVelocity;
|
||||
|
||||
union
|
||||
{
|
||||
void* m_originalBody;
|
||||
int m_originalBodyIndex;
|
||||
union {
|
||||
void* m_originalBody;
|
||||
int m_originalBodyIndex;
|
||||
};
|
||||
|
||||
int padding[3];
|
||||
@@ -65,44 +61,41 @@ B3_ATTRIBUTE_ALIGNED16 (struct) b3GpuSolverBody
|
||||
return m_worldTransform;
|
||||
}
|
||||
*/
|
||||
B3_FORCE_INLINE void getVelocityInLocalPointObsolete(const b3Vector3& rel_pos, b3Vector3& velocity ) const
|
||||
B3_FORCE_INLINE void getVelocityInLocalPointObsolete(const b3Vector3& rel_pos, b3Vector3& velocity) const
|
||||
{
|
||||
if (m_originalBody)
|
||||
velocity = m_linearVelocity+m_deltaLinearVelocity + (m_angularVelocity+m_deltaAngularVelocity).cross(rel_pos);
|
||||
velocity = m_linearVelocity + m_deltaLinearVelocity + (m_angularVelocity + m_deltaAngularVelocity).cross(rel_pos);
|
||||
else
|
||||
velocity.setValue(0,0,0);
|
||||
velocity.setValue(0, 0, 0);
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE void getAngularVelocity(b3Vector3& angVel) const
|
||||
B3_FORCE_INLINE void getAngularVelocity(b3Vector3 & angVel) const
|
||||
{
|
||||
if (m_originalBody)
|
||||
angVel =m_angularVelocity+m_deltaAngularVelocity;
|
||||
angVel = m_angularVelocity + m_deltaAngularVelocity;
|
||||
else
|
||||
angVel.setValue(0,0,0);
|
||||
angVel.setValue(0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
//Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position
|
||||
B3_FORCE_INLINE void applyImpulse(const b3Vector3& linearComponent, const b3Vector3& angularComponent,const b3Scalar impulseMagnitude)
|
||||
B3_FORCE_INLINE void applyImpulse(const b3Vector3& linearComponent, const b3Vector3& angularComponent, const b3Scalar impulseMagnitude)
|
||||
{
|
||||
if (m_originalBody)
|
||||
{
|
||||
m_deltaLinearVelocity += linearComponent*impulseMagnitude*m_linearFactor;
|
||||
m_deltaAngularVelocity += angularComponent*(impulseMagnitude*m_angularFactor);
|
||||
m_deltaLinearVelocity += linearComponent * impulseMagnitude * m_linearFactor;
|
||||
m_deltaAngularVelocity += angularComponent * (impulseMagnitude * m_angularFactor);
|
||||
}
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE void internalApplyPushImpulse(const b3Vector3& linearComponent, const b3Vector3& angularComponent,b3Scalar impulseMagnitude)
|
||||
B3_FORCE_INLINE void internalApplyPushImpulse(const b3Vector3& linearComponent, const b3Vector3& angularComponent, b3Scalar impulseMagnitude)
|
||||
{
|
||||
if (m_originalBody)
|
||||
{
|
||||
m_pushVelocity += linearComponent*impulseMagnitude*m_linearFactor;
|
||||
m_turnVelocity += angularComponent*(impulseMagnitude*m_angularFactor);
|
||||
m_pushVelocity += linearComponent * impulseMagnitude * m_linearFactor;
|
||||
m_turnVelocity += angularComponent * (impulseMagnitude * m_angularFactor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const b3Vector3& getDeltaLinearVelocity() const
|
||||
{
|
||||
return m_deltaLinearVelocity;
|
||||
@@ -113,20 +106,19 @@ B3_ATTRIBUTE_ALIGNED16 (struct) b3GpuSolverBody
|
||||
return m_deltaAngularVelocity;
|
||||
}
|
||||
|
||||
const b3Vector3& getPushVelocity() const
|
||||
const b3Vector3& getPushVelocity() const
|
||||
{
|
||||
return m_pushVelocity;
|
||||
}
|
||||
|
||||
const b3Vector3& getTurnVelocity() const
|
||||
const b3Vector3& getTurnVelocity() const
|
||||
{
|
||||
return m_turnVelocity;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////
|
||||
///some internal methods, don't use them
|
||||
|
||||
|
||||
b3Vector3& internalGetDeltaLinearVelocity()
|
||||
{
|
||||
return m_deltaLinearVelocity;
|
||||
@@ -151,7 +143,7 @@ B3_ATTRIBUTE_ALIGNED16 (struct) b3GpuSolverBody
|
||||
{
|
||||
m_invMass = invMass;
|
||||
}
|
||||
|
||||
|
||||
b3Vector3& internalGetPushVelocity()
|
||||
{
|
||||
return m_pushVelocity;
|
||||
@@ -162,67 +154,57 @@ B3_ATTRIBUTE_ALIGNED16 (struct) b3GpuSolverBody
|
||||
return m_turnVelocity;
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE void internalGetVelocityInLocalPointObsolete(const b3Vector3& rel_pos, b3Vector3& velocity ) const
|
||||
B3_FORCE_INLINE void internalGetVelocityInLocalPointObsolete(const b3Vector3& rel_pos, b3Vector3& velocity) const
|
||||
{
|
||||
velocity = m_linearVelocity+m_deltaLinearVelocity + (m_angularVelocity+m_deltaAngularVelocity).cross(rel_pos);
|
||||
velocity = m_linearVelocity + m_deltaLinearVelocity + (m_angularVelocity + m_deltaAngularVelocity).cross(rel_pos);
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE void internalGetAngularVelocity(b3Vector3& angVel) const
|
||||
B3_FORCE_INLINE void internalGetAngularVelocity(b3Vector3 & angVel) const
|
||||
{
|
||||
angVel = m_angularVelocity+m_deltaAngularVelocity;
|
||||
angVel = m_angularVelocity + m_deltaAngularVelocity;
|
||||
}
|
||||
|
||||
|
||||
//Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position
|
||||
B3_FORCE_INLINE void internalApplyImpulse(const b3Vector3& linearComponent, const b3Vector3& angularComponent,const b3Scalar impulseMagnitude)
|
||||
B3_FORCE_INLINE void internalApplyImpulse(const b3Vector3& linearComponent, const b3Vector3& angularComponent, const b3Scalar impulseMagnitude)
|
||||
{
|
||||
//if (m_originalBody)
|
||||
{
|
||||
m_deltaLinearVelocity += linearComponent*impulseMagnitude*m_linearFactor;
|
||||
m_deltaAngularVelocity += angularComponent*(impulseMagnitude*m_angularFactor);
|
||||
m_deltaLinearVelocity += linearComponent * impulseMagnitude * m_linearFactor;
|
||||
m_deltaAngularVelocity += angularComponent * (impulseMagnitude * m_angularFactor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void writebackVelocity()
|
||||
void writebackVelocity()
|
||||
{
|
||||
//if (m_originalBody>=0)
|
||||
{
|
||||
m_linearVelocity +=m_deltaLinearVelocity;
|
||||
m_linearVelocity += m_deltaLinearVelocity;
|
||||
m_angularVelocity += m_deltaAngularVelocity;
|
||||
|
||||
|
||||
//m_originalBody->setCompanionId(-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void writebackVelocityAndTransform(b3Scalar timeStep, b3Scalar splitImpulseTurnErp)
|
||||
void writebackVelocityAndTransform(b3Scalar timeStep, b3Scalar splitImpulseTurnErp)
|
||||
{
|
||||
(void) timeStep;
|
||||
(void)timeStep;
|
||||
if (m_originalBody)
|
||||
{
|
||||
m_linearVelocity += m_deltaLinearVelocity;
|
||||
m_angularVelocity += m_deltaAngularVelocity;
|
||||
|
||||
|
||||
//correct the position/orientation based on push/turn recovery
|
||||
b3Transform newTransform;
|
||||
if (m_pushVelocity[0]!=0.f || m_pushVelocity[1]!=0 || m_pushVelocity[2]!=0 || m_turnVelocity[0]!=0.f || m_turnVelocity[1]!=0 || m_turnVelocity[2]!=0)
|
||||
if (m_pushVelocity[0] != 0.f || m_pushVelocity[1] != 0 || m_pushVelocity[2] != 0 || m_turnVelocity[0] != 0.f || m_turnVelocity[1] != 0 || m_turnVelocity[2] != 0)
|
||||
{
|
||||
// b3Quaternion orn = m_worldTransform.getRotation();
|
||||
// b3TransformUtil::integrateTransform(m_worldTransform,m_pushVelocity,m_turnVelocity*splitImpulseTurnErp,timeStep,newTransform);
|
||||
// m_worldTransform = newTransform;
|
||||
// b3Quaternion orn = m_worldTransform.getRotation();
|
||||
// b3TransformUtil::integrateTransform(m_worldTransform,m_pushVelocity,m_turnVelocity*splitImpulseTurnErp,timeStep,newTransform);
|
||||
// m_worldTransform = newTransform;
|
||||
}
|
||||
//m_worldTransform.setRotation(orn);
|
||||
//m_originalBody->setCompanionId(-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif //B3_SOLVER_BODY_H
|
||||
|
||||
|
||||
#endif //B3_SOLVER_BODY_H
|
||||
|
||||
@@ -13,11 +13,9 @@ subject to the following restrictions:
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef B3_GPU_SOLVER_CONSTRAINT_H
|
||||
#define B3_GPU_SOLVER_CONSTRAINT_H
|
||||
|
||||
|
||||
#include "Bullet3Common/b3Vector3.h"
|
||||
#include "Bullet3Common/b3Matrix3x3.h"
|
||||
//#include "b3JacobianEntry.h"
|
||||
@@ -25,58 +23,51 @@ subject to the following restrictions:
|
||||
|
||||
//#define NO_FRICTION_TANGENTIALS 1
|
||||
|
||||
|
||||
|
||||
///1D constraint along a normal axis between bodyA and bodyB. It can be combined to solve contact and friction constraints.
|
||||
B3_ATTRIBUTE_ALIGNED16 (struct) b3GpuSolverConstraint
|
||||
B3_ATTRIBUTE_ALIGNED16(struct)
|
||||
b3GpuSolverConstraint
|
||||
{
|
||||
B3_DECLARE_ALIGNED_ALLOCATOR();
|
||||
|
||||
b3Vector3 m_relpos1CrossNormal;
|
||||
b3Vector3 m_contactNormal;
|
||||
b3Vector3 m_relpos1CrossNormal;
|
||||
b3Vector3 m_contactNormal;
|
||||
|
||||
b3Vector3 m_relpos2CrossNormal;
|
||||
b3Vector3 m_relpos2CrossNormal;
|
||||
//b3Vector3 m_contactNormal2;//usually m_contactNormal2 == -m_contactNormal
|
||||
|
||||
b3Vector3 m_angularComponentA;
|
||||
b3Vector3 m_angularComponentB;
|
||||
|
||||
mutable b3Scalar m_appliedPushImpulse;
|
||||
mutable b3Scalar m_appliedImpulse;
|
||||
b3Vector3 m_angularComponentA;
|
||||
b3Vector3 m_angularComponentB;
|
||||
|
||||
mutable b3Scalar m_appliedPushImpulse;
|
||||
mutable b3Scalar m_appliedImpulse;
|
||||
int m_padding1;
|
||||
int m_padding2;
|
||||
b3Scalar m_friction;
|
||||
b3Scalar m_jacDiagABInv;
|
||||
b3Scalar m_rhs;
|
||||
b3Scalar m_cfm;
|
||||
|
||||
b3Scalar m_lowerLimit;
|
||||
b3Scalar m_upperLimit;
|
||||
b3Scalar m_rhsPenetration;
|
||||
union
|
||||
{
|
||||
void* m_originalContactPoint;
|
||||
int m_originalConstraintIndex;
|
||||
b3Scalar m_unusedPadding4;
|
||||
b3Scalar m_friction;
|
||||
b3Scalar m_jacDiagABInv;
|
||||
b3Scalar m_rhs;
|
||||
b3Scalar m_cfm;
|
||||
|
||||
b3Scalar m_lowerLimit;
|
||||
b3Scalar m_upperLimit;
|
||||
b3Scalar m_rhsPenetration;
|
||||
union {
|
||||
void* m_originalContactPoint;
|
||||
int m_originalConstraintIndex;
|
||||
b3Scalar m_unusedPadding4;
|
||||
};
|
||||
|
||||
int m_overrideNumSolverIterations;
|
||||
int m_frictionIndex;
|
||||
int m_overrideNumSolverIterations;
|
||||
int m_frictionIndex;
|
||||
int m_solverBodyIdA;
|
||||
int m_solverBodyIdB;
|
||||
|
||||
|
||||
enum b3SolverConstraintType
|
||||
enum b3SolverConstraintType
|
||||
{
|
||||
B3_SOLVER_CONTACT_1D = 0,
|
||||
B3_SOLVER_FRICTION_1D
|
||||
};
|
||||
};
|
||||
|
||||
typedef b3AlignedObjectArray<b3GpuSolverConstraint> b3GpuConstraintArray;
|
||||
|
||||
|
||||
#endif //B3_GPU_SOLVER_CONSTRAINT_H
|
||||
|
||||
|
||||
typedef b3AlignedObjectArray<b3GpuSolverConstraint> b3GpuConstraintArray;
|
||||
|
||||
#endif //B3_GPU_SOLVER_CONSTRAINT_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,7 +13,6 @@ subject to the following restrictions:
|
||||
*/
|
||||
//Originally written by Takahiro Harada
|
||||
|
||||
|
||||
#ifndef __ADL_SOLVER_H
|
||||
#define __ADL_SOLVER_H
|
||||
|
||||
@@ -29,98 +28,83 @@ subject to the following restrictions:
|
||||
|
||||
#include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h"
|
||||
|
||||
|
||||
#define B3NEXTMULTIPLEOF(num, alignment) (((num)/(alignment) + (((num)%(alignment)==0)?0:1))*(alignment))
|
||||
#define B3NEXTMULTIPLEOF(num, alignment) (((num) / (alignment) + (((num) % (alignment) == 0) ? 0 : 1)) * (alignment))
|
||||
|
||||
enum
|
||||
{
|
||||
B3_SOLVER_N_SPLIT_X = 8,//16,//4,
|
||||
B3_SOLVER_N_SPLIT_Y = 4,//16,//4,
|
||||
B3_SOLVER_N_SPLIT_Z = 8,//,
|
||||
B3_SOLVER_N_CELLS = B3_SOLVER_N_SPLIT_X*B3_SOLVER_N_SPLIT_Y*B3_SOLVER_N_SPLIT_Z,
|
||||
B3_SOLVER_N_BATCHES = 8,//4,//8,//4,
|
||||
B3_SOLVER_N_SPLIT_X = 8, //16,//4,
|
||||
B3_SOLVER_N_SPLIT_Y = 4, //16,//4,
|
||||
B3_SOLVER_N_SPLIT_Z = 8, //,
|
||||
B3_SOLVER_N_CELLS = B3_SOLVER_N_SPLIT_X * B3_SOLVER_N_SPLIT_Y * B3_SOLVER_N_SPLIT_Z,
|
||||
B3_SOLVER_N_BATCHES = 8, //4,//8,//4,
|
||||
B3_MAX_NUM_BATCHES = 128,
|
||||
};
|
||||
|
||||
class b3SolverBase
|
||||
{
|
||||
public:
|
||||
|
||||
public:
|
||||
struct ConstraintCfg
|
||||
{
|
||||
ConstraintCfg(float dt = 0.f) : m_positionDrift(0.005f), m_positionConstraintCoeff(0.2f), m_dt(dt), m_staticIdx(-1) {}
|
||||
|
||||
struct ConstraintCfg
|
||||
{
|
||||
ConstraintCfg( float dt = 0.f ): m_positionDrift( 0.005f ), m_positionConstraintCoeff( 0.2f ), m_dt(dt), m_staticIdx(-1) {}
|
||||
|
||||
float m_positionDrift;
|
||||
float m_positionConstraintCoeff;
|
||||
float m_dt;
|
||||
bool m_enableParallelSolve;
|
||||
float m_batchCellSize;
|
||||
int m_staticIdx;
|
||||
};
|
||||
|
||||
float m_positionDrift;
|
||||
float m_positionConstraintCoeff;
|
||||
float m_dt;
|
||||
bool m_enableParallelSolve;
|
||||
float m_batchCellSize;
|
||||
int m_staticIdx;
|
||||
};
|
||||
};
|
||||
|
||||
class b3Solver : public b3SolverBase
|
||||
{
|
||||
public:
|
||||
public:
|
||||
cl_context m_context;
|
||||
cl_device_id m_device;
|
||||
cl_command_queue m_queue;
|
||||
|
||||
cl_context m_context;
|
||||
cl_device_id m_device;
|
||||
cl_command_queue m_queue;
|
||||
|
||||
b3OpenCLArray<unsigned int>* m_numConstraints;
|
||||
b3OpenCLArray<unsigned int>* m_offsets;
|
||||
b3OpenCLArray<int> m_batchSizes;
|
||||
|
||||
b3OpenCLArray<unsigned int>* m_numConstraints;
|
||||
b3OpenCLArray<unsigned int>* m_offsets;
|
||||
b3OpenCLArray<int> m_batchSizes;
|
||||
|
||||
|
||||
int m_nIterations;
|
||||
cl_kernel m_batchingKernel;
|
||||
cl_kernel m_batchingKernelNew;
|
||||
cl_kernel m_solveContactKernel;
|
||||
cl_kernel m_solveFrictionKernel;
|
||||
cl_kernel m_contactToConstraintKernel;
|
||||
cl_kernel m_setSortDataKernel;
|
||||
cl_kernel m_reorderContactKernel;
|
||||
cl_kernel m_copyConstraintKernel;
|
||||
int m_nIterations;
|
||||
cl_kernel m_batchingKernel;
|
||||
cl_kernel m_batchingKernelNew;
|
||||
cl_kernel m_solveContactKernel;
|
||||
cl_kernel m_solveFrictionKernel;
|
||||
cl_kernel m_contactToConstraintKernel;
|
||||
cl_kernel m_setSortDataKernel;
|
||||
cl_kernel m_reorderContactKernel;
|
||||
cl_kernel m_copyConstraintKernel;
|
||||
|
||||
class b3RadixSort32CL* m_sort32;
|
||||
class b3BoundSearchCL* m_search;
|
||||
class b3PrefixScanCL* m_scan;
|
||||
class b3RadixSort32CL* m_sort32;
|
||||
class b3BoundSearchCL* m_search;
|
||||
class b3PrefixScanCL* m_scan;
|
||||
|
||||
b3OpenCLArray<b3SortData>* m_sortDataBuffer;
|
||||
b3OpenCLArray<b3Contact4>* m_contactBuffer2;
|
||||
b3OpenCLArray<b3SortData>* m_sortDataBuffer;
|
||||
b3OpenCLArray<b3Contact4>* m_contactBuffer2;
|
||||
|
||||
enum
|
||||
{
|
||||
DYNAMIC_CONTACT_ALLOCATION_THRESHOLD = 2000000,
|
||||
};
|
||||
enum
|
||||
{
|
||||
DYNAMIC_CONTACT_ALLOCATION_THRESHOLD = 2000000,
|
||||
};
|
||||
|
||||
|
||||
b3Solver(cl_context ctx, cl_device_id device, cl_command_queue queue, int pairCapacity);
|
||||
|
||||
|
||||
b3Solver(cl_context ctx, cl_device_id device, cl_command_queue queue, int pairCapacity);
|
||||
virtual ~b3Solver();
|
||||
|
||||
virtual ~b3Solver();
|
||||
|
||||
void solveContactConstraint( const b3OpenCLArray<b3RigidBodyData>* bodyBuf, const b3OpenCLArray<b3InertiaData>* inertiaBuf,
|
||||
b3OpenCLArray<b3GpuConstraint4>* constraint, void* additionalData, int n ,int maxNumBatches);
|
||||
void solveContactConstraint(const b3OpenCLArray<b3RigidBodyData>* bodyBuf, const b3OpenCLArray<b3InertiaData>* inertiaBuf,
|
||||
b3OpenCLArray<b3GpuConstraint4>* constraint, void* additionalData, int n, int maxNumBatches);
|
||||
|
||||
void solveContactConstraintHost( b3OpenCLArray<b3RigidBodyData>* bodyBuf, b3OpenCLArray<b3InertiaData>* shapeBuf,
|
||||
b3OpenCLArray<b3GpuConstraint4>* constraint, void* additionalData, int n ,int maxNumBatches, b3AlignedObjectArray<int>* batchSizes);
|
||||
void solveContactConstraintHost(b3OpenCLArray<b3RigidBodyData>* bodyBuf, b3OpenCLArray<b3InertiaData>* shapeBuf,
|
||||
b3OpenCLArray<b3GpuConstraint4>* constraint, void* additionalData, int n, int maxNumBatches, b3AlignedObjectArray<int>* batchSizes);
|
||||
|
||||
void convertToConstraints(const b3OpenCLArray<b3RigidBodyData>* bodyBuf,
|
||||
const b3OpenCLArray<b3InertiaData>* shapeBuf,
|
||||
b3OpenCLArray<b3Contact4>* contactsIn, b3OpenCLArray<b3GpuConstraint4>* contactCOut, void* additionalData,
|
||||
int nContacts, const ConstraintCfg& cfg);
|
||||
|
||||
void convertToConstraints( const b3OpenCLArray<b3RigidBodyData>* bodyBuf,
|
||||
const b3OpenCLArray<b3InertiaData>* shapeBuf,
|
||||
b3OpenCLArray<b3Contact4>* contactsIn, b3OpenCLArray<b3GpuConstraint4>* contactCOut, void* additionalData,
|
||||
int nContacts, const ConstraintCfg& cfg );
|
||||
|
||||
void batchContacts( b3OpenCLArray<b3Contact4>* contacts, int nContacts, b3OpenCLArray<unsigned int>* n, b3OpenCLArray<unsigned int>* offsets, int staticIdx );
|
||||
|
||||
void batchContacts(b3OpenCLArray<b3Contact4>* contacts, int nContacts, b3OpenCLArray<unsigned int>* n, b3OpenCLArray<unsigned int>* offsets, int staticIdx);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif //__ADL_SOLVER_H
|
||||
#endif //__ADL_SOLVER_H
|
||||
|
||||
@@ -1,388 +1,387 @@
|
||||
//this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project
|
||||
static const char* batchingKernelsCL= \
|
||||
"/*\n"
|
||||
"Copyright (c) 2012 Advanced Micro Devices, Inc. \n"
|
||||
"This software is provided 'as-is', without any express or implied warranty.\n"
|
||||
"In no event will the authors be held liable for any damages arising from the use of this software.\n"
|
||||
"Permission is granted to anyone to use this software for any purpose, \n"
|
||||
"including commercial applications, and to alter it and redistribute it freely, \n"
|
||||
"subject to the following restrictions:\n"
|
||||
"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.\n"
|
||||
"2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n"
|
||||
"3. This notice may not be removed or altered from any source distribution.\n"
|
||||
"*/\n"
|
||||
"//Originally written by Takahiro Harada\n"
|
||||
"#ifndef B3_CONTACT4DATA_H\n"
|
||||
"#define B3_CONTACT4DATA_H\n"
|
||||
"#ifndef B3_FLOAT4_H\n"
|
||||
"#define B3_FLOAT4_H\n"
|
||||
"#ifndef B3_PLATFORM_DEFINITIONS_H\n"
|
||||
"#define B3_PLATFORM_DEFINITIONS_H\n"
|
||||
"struct MyTest\n"
|
||||
"{\n"
|
||||
" int bla;\n"
|
||||
"};\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"//keep B3_LARGE_FLOAT*B3_LARGE_FLOAT < FLT_MAX\n"
|
||||
"#define B3_LARGE_FLOAT 1e18f\n"
|
||||
"#define B3_INFINITY 1e18f\n"
|
||||
"#define b3Assert(a)\n"
|
||||
"#define b3ConstArray(a) __global const a*\n"
|
||||
"#define b3AtomicInc atomic_inc\n"
|
||||
"#define b3AtomicAdd atomic_add\n"
|
||||
"#define b3Fabs fabs\n"
|
||||
"#define b3Sqrt native_sqrt\n"
|
||||
"#define b3Sin native_sin\n"
|
||||
"#define b3Cos native_cos\n"
|
||||
"#define B3_STATIC\n"
|
||||
"#endif\n"
|
||||
"#endif\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
" typedef float4 b3Float4;\n"
|
||||
" #define b3Float4ConstArg const b3Float4\n"
|
||||
" #define b3MakeFloat4 (float4)\n"
|
||||
" float b3Dot3F4(b3Float4ConstArg v0,b3Float4ConstArg v1)\n"
|
||||
" {\n"
|
||||
" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n"
|
||||
" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n"
|
||||
" return dot(a1, b1);\n"
|
||||
" }\n"
|
||||
" b3Float4 b3Cross3(b3Float4ConstArg v0,b3Float4ConstArg v1)\n"
|
||||
" {\n"
|
||||
" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n"
|
||||
" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n"
|
||||
" return cross(a1, b1);\n"
|
||||
" }\n"
|
||||
" #define b3MinFloat4 min\n"
|
||||
" #define b3MaxFloat4 max\n"
|
||||
" #define b3Normalized(a) normalize(a)\n"
|
||||
"#endif \n"
|
||||
" \n"
|
||||
"inline bool b3IsAlmostZero(b3Float4ConstArg v)\n"
|
||||
"{\n"
|
||||
" if(b3Fabs(v.x)>1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n"
|
||||
" return false;\n"
|
||||
" return true;\n"
|
||||
"}\n"
|
||||
"inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n"
|
||||
"{\n"
|
||||
" float maxDot = -B3_INFINITY;\n"
|
||||
" int i = 0;\n"
|
||||
" int ptIndex = -1;\n"
|
||||
" for( i = 0; i < vecLen; i++ )\n"
|
||||
" {\n"
|
||||
" float dot = b3Dot3F4(vecArray[i],vec);\n"
|
||||
" \n"
|
||||
" if( dot > maxDot )\n"
|
||||
" {\n"
|
||||
" maxDot = dot;\n"
|
||||
" ptIndex = i;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" b3Assert(ptIndex>=0);\n"
|
||||
" if (ptIndex<0)\n"
|
||||
" {\n"
|
||||
" ptIndex = 0;\n"
|
||||
" }\n"
|
||||
" *dotOut = maxDot;\n"
|
||||
" return ptIndex;\n"
|
||||
"}\n"
|
||||
"#endif //B3_FLOAT4_H\n"
|
||||
"typedef struct b3Contact4Data b3Contact4Data_t;\n"
|
||||
"struct b3Contact4Data\n"
|
||||
"{\n"
|
||||
" b3Float4 m_worldPosB[4];\n"
|
||||
"// b3Float4 m_localPosA[4];\n"
|
||||
"// b3Float4 m_localPosB[4];\n"
|
||||
" b3Float4 m_worldNormalOnB; // w: m_nPoints\n"
|
||||
" unsigned short m_restituitionCoeffCmp;\n"
|
||||
" unsigned short m_frictionCoeffCmp;\n"
|
||||
" int m_batchIdx;\n"
|
||||
" int m_bodyAPtrAndSignBit;//x:m_bodyAPtr, y:m_bodyBPtr\n"
|
||||
" int m_bodyBPtrAndSignBit;\n"
|
||||
" int m_childIndexA;\n"
|
||||
" int m_childIndexB;\n"
|
||||
" int m_unused1;\n"
|
||||
" int m_unused2;\n"
|
||||
"};\n"
|
||||
"inline int b3Contact4Data_getNumPoints(const struct b3Contact4Data* contact)\n"
|
||||
"{\n"
|
||||
" return (int)contact->m_worldNormalOnB.w;\n"
|
||||
"};\n"
|
||||
"inline void b3Contact4Data_setNumPoints(struct b3Contact4Data* contact, int numPoints)\n"
|
||||
"{\n"
|
||||
" contact->m_worldNormalOnB.w = (float)numPoints;\n"
|
||||
"};\n"
|
||||
"#endif //B3_CONTACT4DATA_H\n"
|
||||
"#pragma OPENCL EXTENSION cl_amd_printf : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable\n"
|
||||
"#ifdef cl_ext_atomic_counters_32\n"
|
||||
"#pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable\n"
|
||||
"#else\n"
|
||||
"#define counter32_t volatile __global int*\n"
|
||||
"#endif\n"
|
||||
"typedef unsigned int u32;\n"
|
||||
"typedef unsigned short u16;\n"
|
||||
"typedef unsigned char u8;\n"
|
||||
"#define GET_GROUP_IDX get_group_id(0)\n"
|
||||
"#define GET_LOCAL_IDX get_local_id(0)\n"
|
||||
"#define GET_GLOBAL_IDX get_global_id(0)\n"
|
||||
"#define GET_GROUP_SIZE get_local_size(0)\n"
|
||||
"#define GET_NUM_GROUPS get_num_groups(0)\n"
|
||||
"#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n"
|
||||
"#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n"
|
||||
"#define AtomInc(x) atom_inc(&(x))\n"
|
||||
"#define AtomInc1(x, out) out = atom_inc(&(x))\n"
|
||||
"#define AppendInc(x, out) out = atomic_inc(x)\n"
|
||||
"#define AtomAdd(x, value) atom_add(&(x), value)\n"
|
||||
"#define AtomCmpxhg(x, cmp, value) atom_cmpxchg( &(x), cmp, value )\n"
|
||||
"#define AtomXhg(x, value) atom_xchg ( &(x), value )\n"
|
||||
"#define SELECT_UINT4( b, a, condition ) select( b,a,condition )\n"
|
||||
"#define make_float4 (float4)\n"
|
||||
"#define make_float2 (float2)\n"
|
||||
"#define make_uint4 (uint4)\n"
|
||||
"#define make_int4 (int4)\n"
|
||||
"#define make_uint2 (uint2)\n"
|
||||
"#define make_int2 (int2)\n"
|
||||
"#define max2 max\n"
|
||||
"#define min2 min\n"
|
||||
"#define WG_SIZE 64\n"
|
||||
"typedef struct \n"
|
||||
"{\n"
|
||||
" int m_n;\n"
|
||||
" int m_start;\n"
|
||||
" int m_staticIdx;\n"
|
||||
" int m_paddings[1];\n"
|
||||
"} ConstBuffer;\n"
|
||||
"typedef struct \n"
|
||||
"{\n"
|
||||
" int m_a;\n"
|
||||
" int m_b;\n"
|
||||
" u32 m_idx;\n"
|
||||
"}Elem;\n"
|
||||
"#define STACK_SIZE (WG_SIZE*10)\n"
|
||||
"//#define STACK_SIZE (WG_SIZE)\n"
|
||||
"#define RING_SIZE 1024\n"
|
||||
"#define RING_SIZE_MASK (RING_SIZE-1)\n"
|
||||
"#define CHECK_SIZE (WG_SIZE)\n"
|
||||
"#define GET_RING_CAPACITY (RING_SIZE - ldsRingEnd)\n"
|
||||
"#define RING_END ldsTmp\n"
|
||||
"u32 readBuf(__local u32* buff, int idx)\n"
|
||||
"{\n"
|
||||
" idx = idx % (32*CHECK_SIZE);\n"
|
||||
" int bitIdx = idx%32;\n"
|
||||
" int bufIdx = idx/32;\n"
|
||||
" return buff[bufIdx] & (1<<bitIdx);\n"
|
||||
"}\n"
|
||||
"void writeBuf(__local u32* buff, int idx)\n"
|
||||
"{\n"
|
||||
" idx = idx % (32*CHECK_SIZE);\n"
|
||||
" int bitIdx = idx%32;\n"
|
||||
" int bufIdx = idx/32;\n"
|
||||
"// buff[bufIdx] |= (1<<bitIdx);\n"
|
||||
" atom_or( &buff[bufIdx], (1<<bitIdx) );\n"
|
||||
"}\n"
|
||||
"u32 tryWrite(__local u32* buff, int idx)\n"
|
||||
"{\n"
|
||||
" idx = idx % (32*CHECK_SIZE);\n"
|
||||
" int bitIdx = idx%32;\n"
|
||||
" int bufIdx = idx/32;\n"
|
||||
" u32 ans = (u32)atom_or( &buff[bufIdx], (1<<bitIdx) );\n"
|
||||
" return ((ans >> bitIdx)&1) == 0;\n"
|
||||
"}\n"
|
||||
"// batching on the GPU\n"
|
||||
"__kernel void CreateBatches( __global const struct b3Contact4Data* gConstraints, __global struct b3Contact4Data* gConstraintsOut,\n"
|
||||
" __global const u32* gN, __global const u32* gStart, __global int* batchSizes, \n"
|
||||
" int m_staticIdx )\n"
|
||||
"{\n"
|
||||
" __local u32 ldsStackIdx[STACK_SIZE];\n"
|
||||
" __local u32 ldsStackEnd;\n"
|
||||
" __local Elem ldsRingElem[RING_SIZE];\n"
|
||||
" __local u32 ldsRingEnd;\n"
|
||||
" __local u32 ldsTmp;\n"
|
||||
" __local u32 ldsCheckBuffer[CHECK_SIZE];\n"
|
||||
" __local u32 ldsFixedBuffer[CHECK_SIZE];\n"
|
||||
" __local u32 ldsGEnd;\n"
|
||||
" __local u32 ldsDstEnd;\n"
|
||||
" int wgIdx = GET_GROUP_IDX;\n"
|
||||
" int lIdx = GET_LOCAL_IDX;\n"
|
||||
" \n"
|
||||
" const int m_n = gN[wgIdx];\n"
|
||||
" const int m_start = gStart[wgIdx];\n"
|
||||
" \n"
|
||||
" if( lIdx == 0 )\n"
|
||||
" {\n"
|
||||
" ldsRingEnd = 0;\n"
|
||||
" ldsGEnd = 0;\n"
|
||||
" ldsStackEnd = 0;\n"
|
||||
" ldsDstEnd = m_start;\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" \n"
|
||||
" \n"
|
||||
"// while(1)\n"
|
||||
"//was 250\n"
|
||||
" int ie=0;\n"
|
||||
" int maxBatch = 0;\n"
|
||||
" for(ie=0; ie<50; ie++)\n"
|
||||
" {\n"
|
||||
" ldsFixedBuffer[lIdx] = 0;\n"
|
||||
" for(int giter=0; giter<4; giter++)\n"
|
||||
" {\n"
|
||||
" int ringCap = GET_RING_CAPACITY;\n"
|
||||
" \n"
|
||||
" // 1. fill ring\n"
|
||||
" if( ldsGEnd < m_n )\n"
|
||||
" {\n"
|
||||
" while( ringCap > WG_SIZE )\n"
|
||||
" {\n"
|
||||
" if( ldsGEnd >= m_n ) break;\n"
|
||||
" if( lIdx < ringCap - WG_SIZE )\n"
|
||||
" {\n"
|
||||
" int srcIdx;\n"
|
||||
" AtomInc1( ldsGEnd, srcIdx );\n"
|
||||
" if( srcIdx < m_n )\n"
|
||||
" {\n"
|
||||
" int dstIdx;\n"
|
||||
" AtomInc1( ldsRingEnd, dstIdx );\n"
|
||||
" \n"
|
||||
" int a = gConstraints[m_start+srcIdx].m_bodyAPtrAndSignBit;\n"
|
||||
" int b = gConstraints[m_start+srcIdx].m_bodyBPtrAndSignBit;\n"
|
||||
" ldsRingElem[dstIdx].m_a = (a>b)? b:a;\n"
|
||||
" ldsRingElem[dstIdx].m_b = (a>b)? a:b;\n"
|
||||
" ldsRingElem[dstIdx].m_idx = srcIdx;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" ringCap = GET_RING_CAPACITY;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" GROUP_LDS_BARRIER;\n"
|
||||
" \n"
|
||||
" // 2. fill stack\n"
|
||||
" __local Elem* dst = ldsRingElem;\n"
|
||||
" if( lIdx == 0 ) RING_END = 0;\n"
|
||||
" int srcIdx=lIdx;\n"
|
||||
" int end = ldsRingEnd;\n"
|
||||
" {\n"
|
||||
" for(int ii=0; ii<end; ii+=WG_SIZE, srcIdx+=WG_SIZE)\n"
|
||||
" {\n"
|
||||
" Elem e;\n"
|
||||
" if(srcIdx<end) e = ldsRingElem[srcIdx];\n"
|
||||
" bool done = (srcIdx<end)?false:true;\n"
|
||||
" for(int i=lIdx; i<CHECK_SIZE; i+=WG_SIZE) ldsCheckBuffer[lIdx] = 0;\n"
|
||||
" \n"
|
||||
" if( !done )\n"
|
||||
" {\n"
|
||||
" int aUsed = readBuf( ldsFixedBuffer, abs(e.m_a));\n"
|
||||
" int bUsed = readBuf( ldsFixedBuffer, abs(e.m_b));\n"
|
||||
" if( aUsed==0 && bUsed==0 )\n"
|
||||
" {\n"
|
||||
" int aAvailable=1;\n"
|
||||
" int bAvailable=1;\n"
|
||||
" int ea = abs(e.m_a);\n"
|
||||
" int eb = abs(e.m_b);\n"
|
||||
" bool aStatic = (e.m_a<0) ||(ea==m_staticIdx);\n"
|
||||
" bool bStatic = (e.m_b<0) ||(eb==m_staticIdx);\n"
|
||||
" \n"
|
||||
" if (!aStatic)\n"
|
||||
" aAvailable = tryWrite( ldsCheckBuffer, ea );\n"
|
||||
" if (!bStatic)\n"
|
||||
" bAvailable = tryWrite( ldsCheckBuffer, eb );\n"
|
||||
" \n"
|
||||
" //aAvailable = aStatic? 1: aAvailable;\n"
|
||||
" //bAvailable = bStatic? 1: bAvailable;\n"
|
||||
" bool success = (aAvailable && bAvailable);\n"
|
||||
" if(success)\n"
|
||||
" {\n"
|
||||
" \n"
|
||||
" if (!aStatic)\n"
|
||||
" writeBuf( ldsFixedBuffer, ea );\n"
|
||||
" if (!bStatic)\n"
|
||||
" writeBuf( ldsFixedBuffer, eb );\n"
|
||||
" }\n"
|
||||
" done = success;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" // put it aside\n"
|
||||
" if(srcIdx<end)\n"
|
||||
" {\n"
|
||||
" if( done )\n"
|
||||
" {\n"
|
||||
" int dstIdx; AtomInc1( ldsStackEnd, dstIdx );\n"
|
||||
" if( dstIdx < STACK_SIZE )\n"
|
||||
" ldsStackIdx[dstIdx] = e.m_idx;\n"
|
||||
" else{\n"
|
||||
" done = false;\n"
|
||||
" AtomAdd( ldsStackEnd, -1 );\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" if( !done )\n"
|
||||
" {\n"
|
||||
" int dstIdx; AtomInc1( RING_END, dstIdx );\n"
|
||||
" dst[dstIdx] = e;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" // if filled, flush\n"
|
||||
" if( ldsStackEnd == STACK_SIZE )\n"
|
||||
" {\n"
|
||||
" for(int i=lIdx; i<STACK_SIZE; i+=WG_SIZE)\n"
|
||||
" {\n"
|
||||
" int idx = m_start + ldsStackIdx[i];\n"
|
||||
" int dstIdx; AtomInc1( ldsDstEnd, dstIdx );\n"
|
||||
" gConstraintsOut[ dstIdx ] = gConstraints[ idx ];\n"
|
||||
" gConstraintsOut[ dstIdx ].m_batchIdx = ie;\n"
|
||||
" }\n"
|
||||
" if( lIdx == 0 ) ldsStackEnd = 0;\n"
|
||||
" //for(int i=lIdx; i<CHECK_SIZE; i+=WG_SIZE) \n"
|
||||
" ldsFixedBuffer[lIdx] = 0;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" if( lIdx == 0 ) ldsRingEnd = RING_END;\n"
|
||||
" }\n"
|
||||
" GROUP_LDS_BARRIER;\n"
|
||||
" for(int i=lIdx; i<ldsStackEnd; i+=WG_SIZE)\n"
|
||||
" {\n"
|
||||
" int idx = m_start + ldsStackIdx[i];\n"
|
||||
" int dstIdx; AtomInc1( ldsDstEnd, dstIdx );\n"
|
||||
" gConstraintsOut[ dstIdx ] = gConstraints[ idx ];\n"
|
||||
" gConstraintsOut[ dstIdx ].m_batchIdx = ie;\n"
|
||||
" }\n"
|
||||
" // in case it couldn't consume any pair. Flush them\n"
|
||||
" // todo. Serial batch worth while?\n"
|
||||
" if( ldsStackEnd == 0 )\n"
|
||||
" {\n"
|
||||
" for(int i=lIdx; i<ldsRingEnd; i+=WG_SIZE)\n"
|
||||
" {\n"
|
||||
" int idx = m_start + ldsRingElem[i].m_idx;\n"
|
||||
" int dstIdx; AtomInc1( ldsDstEnd, dstIdx );\n"
|
||||
" gConstraintsOut[ dstIdx ] = gConstraints[ idx ];\n"
|
||||
" int curBatch = 100+i;\n"
|
||||
" if (maxBatch < curBatch)\n"
|
||||
" maxBatch = curBatch;\n"
|
||||
" \n"
|
||||
" gConstraintsOut[ dstIdx ].m_batchIdx = curBatch;\n"
|
||||
" \n"
|
||||
" }\n"
|
||||
" GROUP_LDS_BARRIER;\n"
|
||||
" if( lIdx == 0 ) ldsRingEnd = 0;\n"
|
||||
" }\n"
|
||||
" if( lIdx == 0 ) ldsStackEnd = 0;\n"
|
||||
" GROUP_LDS_BARRIER;\n"
|
||||
" // termination\n"
|
||||
" if( ldsGEnd == m_n && ldsRingEnd == 0 )\n"
|
||||
" break;\n"
|
||||
" }\n"
|
||||
" if( lIdx == 0 )\n"
|
||||
" {\n"
|
||||
" if (maxBatch < ie)\n"
|
||||
" maxBatch=ie;\n"
|
||||
" batchSizes[wgIdx]=maxBatch;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
;
|
||||
static const char* batchingKernelsCL =
|
||||
"/*\n"
|
||||
"Copyright (c) 2012 Advanced Micro Devices, Inc. \n"
|
||||
"This software is provided 'as-is', without any express or implied warranty.\n"
|
||||
"In no event will the authors be held liable for any damages arising from the use of this software.\n"
|
||||
"Permission is granted to anyone to use this software for any purpose, \n"
|
||||
"including commercial applications, and to alter it and redistribute it freely, \n"
|
||||
"subject to the following restrictions:\n"
|
||||
"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.\n"
|
||||
"2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n"
|
||||
"3. This notice may not be removed or altered from any source distribution.\n"
|
||||
"*/\n"
|
||||
"//Originally written by Takahiro Harada\n"
|
||||
"#ifndef B3_CONTACT4DATA_H\n"
|
||||
"#define B3_CONTACT4DATA_H\n"
|
||||
"#ifndef B3_FLOAT4_H\n"
|
||||
"#define B3_FLOAT4_H\n"
|
||||
"#ifndef B3_PLATFORM_DEFINITIONS_H\n"
|
||||
"#define B3_PLATFORM_DEFINITIONS_H\n"
|
||||
"struct MyTest\n"
|
||||
"{\n"
|
||||
" int bla;\n"
|
||||
"};\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"//keep B3_LARGE_FLOAT*B3_LARGE_FLOAT < FLT_MAX\n"
|
||||
"#define B3_LARGE_FLOAT 1e18f\n"
|
||||
"#define B3_INFINITY 1e18f\n"
|
||||
"#define b3Assert(a)\n"
|
||||
"#define b3ConstArray(a) __global const a*\n"
|
||||
"#define b3AtomicInc atomic_inc\n"
|
||||
"#define b3AtomicAdd atomic_add\n"
|
||||
"#define b3Fabs fabs\n"
|
||||
"#define b3Sqrt native_sqrt\n"
|
||||
"#define b3Sin native_sin\n"
|
||||
"#define b3Cos native_cos\n"
|
||||
"#define B3_STATIC\n"
|
||||
"#endif\n"
|
||||
"#endif\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
" typedef float4 b3Float4;\n"
|
||||
" #define b3Float4ConstArg const b3Float4\n"
|
||||
" #define b3MakeFloat4 (float4)\n"
|
||||
" float b3Dot3F4(b3Float4ConstArg v0,b3Float4ConstArg v1)\n"
|
||||
" {\n"
|
||||
" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n"
|
||||
" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n"
|
||||
" return dot(a1, b1);\n"
|
||||
" }\n"
|
||||
" b3Float4 b3Cross3(b3Float4ConstArg v0,b3Float4ConstArg v1)\n"
|
||||
" {\n"
|
||||
" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n"
|
||||
" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n"
|
||||
" return cross(a1, b1);\n"
|
||||
" }\n"
|
||||
" #define b3MinFloat4 min\n"
|
||||
" #define b3MaxFloat4 max\n"
|
||||
" #define b3Normalized(a) normalize(a)\n"
|
||||
"#endif \n"
|
||||
" \n"
|
||||
"inline bool b3IsAlmostZero(b3Float4ConstArg v)\n"
|
||||
"{\n"
|
||||
" if(b3Fabs(v.x)>1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n"
|
||||
" return false;\n"
|
||||
" return true;\n"
|
||||
"}\n"
|
||||
"inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n"
|
||||
"{\n"
|
||||
" float maxDot = -B3_INFINITY;\n"
|
||||
" int i = 0;\n"
|
||||
" int ptIndex = -1;\n"
|
||||
" for( i = 0; i < vecLen; i++ )\n"
|
||||
" {\n"
|
||||
" float dot = b3Dot3F4(vecArray[i],vec);\n"
|
||||
" \n"
|
||||
" if( dot > maxDot )\n"
|
||||
" {\n"
|
||||
" maxDot = dot;\n"
|
||||
" ptIndex = i;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" b3Assert(ptIndex>=0);\n"
|
||||
" if (ptIndex<0)\n"
|
||||
" {\n"
|
||||
" ptIndex = 0;\n"
|
||||
" }\n"
|
||||
" *dotOut = maxDot;\n"
|
||||
" return ptIndex;\n"
|
||||
"}\n"
|
||||
"#endif //B3_FLOAT4_H\n"
|
||||
"typedef struct b3Contact4Data b3Contact4Data_t;\n"
|
||||
"struct b3Contact4Data\n"
|
||||
"{\n"
|
||||
" b3Float4 m_worldPosB[4];\n"
|
||||
"// b3Float4 m_localPosA[4];\n"
|
||||
"// b3Float4 m_localPosB[4];\n"
|
||||
" b3Float4 m_worldNormalOnB; // w: m_nPoints\n"
|
||||
" unsigned short m_restituitionCoeffCmp;\n"
|
||||
" unsigned short m_frictionCoeffCmp;\n"
|
||||
" int m_batchIdx;\n"
|
||||
" int m_bodyAPtrAndSignBit;//x:m_bodyAPtr, y:m_bodyBPtr\n"
|
||||
" int m_bodyBPtrAndSignBit;\n"
|
||||
" int m_childIndexA;\n"
|
||||
" int m_childIndexB;\n"
|
||||
" int m_unused1;\n"
|
||||
" int m_unused2;\n"
|
||||
"};\n"
|
||||
"inline int b3Contact4Data_getNumPoints(const struct b3Contact4Data* contact)\n"
|
||||
"{\n"
|
||||
" return (int)contact->m_worldNormalOnB.w;\n"
|
||||
"};\n"
|
||||
"inline void b3Contact4Data_setNumPoints(struct b3Contact4Data* contact, int numPoints)\n"
|
||||
"{\n"
|
||||
" contact->m_worldNormalOnB.w = (float)numPoints;\n"
|
||||
"};\n"
|
||||
"#endif //B3_CONTACT4DATA_H\n"
|
||||
"#pragma OPENCL EXTENSION cl_amd_printf : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable\n"
|
||||
"#ifdef cl_ext_atomic_counters_32\n"
|
||||
"#pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable\n"
|
||||
"#else\n"
|
||||
"#define counter32_t volatile __global int*\n"
|
||||
"#endif\n"
|
||||
"typedef unsigned int u32;\n"
|
||||
"typedef unsigned short u16;\n"
|
||||
"typedef unsigned char u8;\n"
|
||||
"#define GET_GROUP_IDX get_group_id(0)\n"
|
||||
"#define GET_LOCAL_IDX get_local_id(0)\n"
|
||||
"#define GET_GLOBAL_IDX get_global_id(0)\n"
|
||||
"#define GET_GROUP_SIZE get_local_size(0)\n"
|
||||
"#define GET_NUM_GROUPS get_num_groups(0)\n"
|
||||
"#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n"
|
||||
"#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n"
|
||||
"#define AtomInc(x) atom_inc(&(x))\n"
|
||||
"#define AtomInc1(x, out) out = atom_inc(&(x))\n"
|
||||
"#define AppendInc(x, out) out = atomic_inc(x)\n"
|
||||
"#define AtomAdd(x, value) atom_add(&(x), value)\n"
|
||||
"#define AtomCmpxhg(x, cmp, value) atom_cmpxchg( &(x), cmp, value )\n"
|
||||
"#define AtomXhg(x, value) atom_xchg ( &(x), value )\n"
|
||||
"#define SELECT_UINT4( b, a, condition ) select( b,a,condition )\n"
|
||||
"#define make_float4 (float4)\n"
|
||||
"#define make_float2 (float2)\n"
|
||||
"#define make_uint4 (uint4)\n"
|
||||
"#define make_int4 (int4)\n"
|
||||
"#define make_uint2 (uint2)\n"
|
||||
"#define make_int2 (int2)\n"
|
||||
"#define max2 max\n"
|
||||
"#define min2 min\n"
|
||||
"#define WG_SIZE 64\n"
|
||||
"typedef struct \n"
|
||||
"{\n"
|
||||
" int m_n;\n"
|
||||
" int m_start;\n"
|
||||
" int m_staticIdx;\n"
|
||||
" int m_paddings[1];\n"
|
||||
"} ConstBuffer;\n"
|
||||
"typedef struct \n"
|
||||
"{\n"
|
||||
" int m_a;\n"
|
||||
" int m_b;\n"
|
||||
" u32 m_idx;\n"
|
||||
"}Elem;\n"
|
||||
"#define STACK_SIZE (WG_SIZE*10)\n"
|
||||
"//#define STACK_SIZE (WG_SIZE)\n"
|
||||
"#define RING_SIZE 1024\n"
|
||||
"#define RING_SIZE_MASK (RING_SIZE-1)\n"
|
||||
"#define CHECK_SIZE (WG_SIZE)\n"
|
||||
"#define GET_RING_CAPACITY (RING_SIZE - ldsRingEnd)\n"
|
||||
"#define RING_END ldsTmp\n"
|
||||
"u32 readBuf(__local u32* buff, int idx)\n"
|
||||
"{\n"
|
||||
" idx = idx % (32*CHECK_SIZE);\n"
|
||||
" int bitIdx = idx%32;\n"
|
||||
" int bufIdx = idx/32;\n"
|
||||
" return buff[bufIdx] & (1<<bitIdx);\n"
|
||||
"}\n"
|
||||
"void writeBuf(__local u32* buff, int idx)\n"
|
||||
"{\n"
|
||||
" idx = idx % (32*CHECK_SIZE);\n"
|
||||
" int bitIdx = idx%32;\n"
|
||||
" int bufIdx = idx/32;\n"
|
||||
"// buff[bufIdx] |= (1<<bitIdx);\n"
|
||||
" atom_or( &buff[bufIdx], (1<<bitIdx) );\n"
|
||||
"}\n"
|
||||
"u32 tryWrite(__local u32* buff, int idx)\n"
|
||||
"{\n"
|
||||
" idx = idx % (32*CHECK_SIZE);\n"
|
||||
" int bitIdx = idx%32;\n"
|
||||
" int bufIdx = idx/32;\n"
|
||||
" u32 ans = (u32)atom_or( &buff[bufIdx], (1<<bitIdx) );\n"
|
||||
" return ((ans >> bitIdx)&1) == 0;\n"
|
||||
"}\n"
|
||||
"// batching on the GPU\n"
|
||||
"__kernel void CreateBatches( __global const struct b3Contact4Data* gConstraints, __global struct b3Contact4Data* gConstraintsOut,\n"
|
||||
" __global const u32* gN, __global const u32* gStart, __global int* batchSizes, \n"
|
||||
" int m_staticIdx )\n"
|
||||
"{\n"
|
||||
" __local u32 ldsStackIdx[STACK_SIZE];\n"
|
||||
" __local u32 ldsStackEnd;\n"
|
||||
" __local Elem ldsRingElem[RING_SIZE];\n"
|
||||
" __local u32 ldsRingEnd;\n"
|
||||
" __local u32 ldsTmp;\n"
|
||||
" __local u32 ldsCheckBuffer[CHECK_SIZE];\n"
|
||||
" __local u32 ldsFixedBuffer[CHECK_SIZE];\n"
|
||||
" __local u32 ldsGEnd;\n"
|
||||
" __local u32 ldsDstEnd;\n"
|
||||
" int wgIdx = GET_GROUP_IDX;\n"
|
||||
" int lIdx = GET_LOCAL_IDX;\n"
|
||||
" \n"
|
||||
" const int m_n = gN[wgIdx];\n"
|
||||
" const int m_start = gStart[wgIdx];\n"
|
||||
" \n"
|
||||
" if( lIdx == 0 )\n"
|
||||
" {\n"
|
||||
" ldsRingEnd = 0;\n"
|
||||
" ldsGEnd = 0;\n"
|
||||
" ldsStackEnd = 0;\n"
|
||||
" ldsDstEnd = m_start;\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" \n"
|
||||
" \n"
|
||||
"// while(1)\n"
|
||||
"//was 250\n"
|
||||
" int ie=0;\n"
|
||||
" int maxBatch = 0;\n"
|
||||
" for(ie=0; ie<50; ie++)\n"
|
||||
" {\n"
|
||||
" ldsFixedBuffer[lIdx] = 0;\n"
|
||||
" for(int giter=0; giter<4; giter++)\n"
|
||||
" {\n"
|
||||
" int ringCap = GET_RING_CAPACITY;\n"
|
||||
" \n"
|
||||
" // 1. fill ring\n"
|
||||
" if( ldsGEnd < m_n )\n"
|
||||
" {\n"
|
||||
" while( ringCap > WG_SIZE )\n"
|
||||
" {\n"
|
||||
" if( ldsGEnd >= m_n ) break;\n"
|
||||
" if( lIdx < ringCap - WG_SIZE )\n"
|
||||
" {\n"
|
||||
" int srcIdx;\n"
|
||||
" AtomInc1( ldsGEnd, srcIdx );\n"
|
||||
" if( srcIdx < m_n )\n"
|
||||
" {\n"
|
||||
" int dstIdx;\n"
|
||||
" AtomInc1( ldsRingEnd, dstIdx );\n"
|
||||
" \n"
|
||||
" int a = gConstraints[m_start+srcIdx].m_bodyAPtrAndSignBit;\n"
|
||||
" int b = gConstraints[m_start+srcIdx].m_bodyBPtrAndSignBit;\n"
|
||||
" ldsRingElem[dstIdx].m_a = (a>b)? b:a;\n"
|
||||
" ldsRingElem[dstIdx].m_b = (a>b)? a:b;\n"
|
||||
" ldsRingElem[dstIdx].m_idx = srcIdx;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" ringCap = GET_RING_CAPACITY;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" GROUP_LDS_BARRIER;\n"
|
||||
" \n"
|
||||
" // 2. fill stack\n"
|
||||
" __local Elem* dst = ldsRingElem;\n"
|
||||
" if( lIdx == 0 ) RING_END = 0;\n"
|
||||
" int srcIdx=lIdx;\n"
|
||||
" int end = ldsRingEnd;\n"
|
||||
" {\n"
|
||||
" for(int ii=0; ii<end; ii+=WG_SIZE, srcIdx+=WG_SIZE)\n"
|
||||
" {\n"
|
||||
" Elem e;\n"
|
||||
" if(srcIdx<end) e = ldsRingElem[srcIdx];\n"
|
||||
" bool done = (srcIdx<end)?false:true;\n"
|
||||
" for(int i=lIdx; i<CHECK_SIZE; i+=WG_SIZE) ldsCheckBuffer[lIdx] = 0;\n"
|
||||
" \n"
|
||||
" if( !done )\n"
|
||||
" {\n"
|
||||
" int aUsed = readBuf( ldsFixedBuffer, abs(e.m_a));\n"
|
||||
" int bUsed = readBuf( ldsFixedBuffer, abs(e.m_b));\n"
|
||||
" if( aUsed==0 && bUsed==0 )\n"
|
||||
" {\n"
|
||||
" int aAvailable=1;\n"
|
||||
" int bAvailable=1;\n"
|
||||
" int ea = abs(e.m_a);\n"
|
||||
" int eb = abs(e.m_b);\n"
|
||||
" bool aStatic = (e.m_a<0) ||(ea==m_staticIdx);\n"
|
||||
" bool bStatic = (e.m_b<0) ||(eb==m_staticIdx);\n"
|
||||
" \n"
|
||||
" if (!aStatic)\n"
|
||||
" aAvailable = tryWrite( ldsCheckBuffer, ea );\n"
|
||||
" if (!bStatic)\n"
|
||||
" bAvailable = tryWrite( ldsCheckBuffer, eb );\n"
|
||||
" \n"
|
||||
" //aAvailable = aStatic? 1: aAvailable;\n"
|
||||
" //bAvailable = bStatic? 1: bAvailable;\n"
|
||||
" bool success = (aAvailable && bAvailable);\n"
|
||||
" if(success)\n"
|
||||
" {\n"
|
||||
" \n"
|
||||
" if (!aStatic)\n"
|
||||
" writeBuf( ldsFixedBuffer, ea );\n"
|
||||
" if (!bStatic)\n"
|
||||
" writeBuf( ldsFixedBuffer, eb );\n"
|
||||
" }\n"
|
||||
" done = success;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" // put it aside\n"
|
||||
" if(srcIdx<end)\n"
|
||||
" {\n"
|
||||
" if( done )\n"
|
||||
" {\n"
|
||||
" int dstIdx; AtomInc1( ldsStackEnd, dstIdx );\n"
|
||||
" if( dstIdx < STACK_SIZE )\n"
|
||||
" ldsStackIdx[dstIdx] = e.m_idx;\n"
|
||||
" else{\n"
|
||||
" done = false;\n"
|
||||
" AtomAdd( ldsStackEnd, -1 );\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" if( !done )\n"
|
||||
" {\n"
|
||||
" int dstIdx; AtomInc1( RING_END, dstIdx );\n"
|
||||
" dst[dstIdx] = e;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" // if filled, flush\n"
|
||||
" if( ldsStackEnd == STACK_SIZE )\n"
|
||||
" {\n"
|
||||
" for(int i=lIdx; i<STACK_SIZE; i+=WG_SIZE)\n"
|
||||
" {\n"
|
||||
" int idx = m_start + ldsStackIdx[i];\n"
|
||||
" int dstIdx; AtomInc1( ldsDstEnd, dstIdx );\n"
|
||||
" gConstraintsOut[ dstIdx ] = gConstraints[ idx ];\n"
|
||||
" gConstraintsOut[ dstIdx ].m_batchIdx = ie;\n"
|
||||
" }\n"
|
||||
" if( lIdx == 0 ) ldsStackEnd = 0;\n"
|
||||
" //for(int i=lIdx; i<CHECK_SIZE; i+=WG_SIZE) \n"
|
||||
" ldsFixedBuffer[lIdx] = 0;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" if( lIdx == 0 ) ldsRingEnd = RING_END;\n"
|
||||
" }\n"
|
||||
" GROUP_LDS_BARRIER;\n"
|
||||
" for(int i=lIdx; i<ldsStackEnd; i+=WG_SIZE)\n"
|
||||
" {\n"
|
||||
" int idx = m_start + ldsStackIdx[i];\n"
|
||||
" int dstIdx; AtomInc1( ldsDstEnd, dstIdx );\n"
|
||||
" gConstraintsOut[ dstIdx ] = gConstraints[ idx ];\n"
|
||||
" gConstraintsOut[ dstIdx ].m_batchIdx = ie;\n"
|
||||
" }\n"
|
||||
" // in case it couldn't consume any pair. Flush them\n"
|
||||
" // todo. Serial batch worth while?\n"
|
||||
" if( ldsStackEnd == 0 )\n"
|
||||
" {\n"
|
||||
" for(int i=lIdx; i<ldsRingEnd; i+=WG_SIZE)\n"
|
||||
" {\n"
|
||||
" int idx = m_start + ldsRingElem[i].m_idx;\n"
|
||||
" int dstIdx; AtomInc1( ldsDstEnd, dstIdx );\n"
|
||||
" gConstraintsOut[ dstIdx ] = gConstraints[ idx ];\n"
|
||||
" int curBatch = 100+i;\n"
|
||||
" if (maxBatch < curBatch)\n"
|
||||
" maxBatch = curBatch;\n"
|
||||
" \n"
|
||||
" gConstraintsOut[ dstIdx ].m_batchIdx = curBatch;\n"
|
||||
" \n"
|
||||
" }\n"
|
||||
" GROUP_LDS_BARRIER;\n"
|
||||
" if( lIdx == 0 ) ldsRingEnd = 0;\n"
|
||||
" }\n"
|
||||
" if( lIdx == 0 ) ldsStackEnd = 0;\n"
|
||||
" GROUP_LDS_BARRIER;\n"
|
||||
" // termination\n"
|
||||
" if( ldsGEnd == m_n && ldsRingEnd == 0 )\n"
|
||||
" break;\n"
|
||||
" }\n"
|
||||
" if( lIdx == 0 )\n"
|
||||
" {\n"
|
||||
" if (maxBatch < ie)\n"
|
||||
" maxBatch=ie;\n"
|
||||
" batchSizes[wgIdx]=maxBatch;\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
|
||||
@@ -1,291 +1,290 @@
|
||||
//this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project
|
||||
static const char* batchingKernelsNewCL= \
|
||||
"/*\n"
|
||||
"Copyright (c) 2012 Advanced Micro Devices, Inc. \n"
|
||||
"This software is provided 'as-is', without any express or implied warranty.\n"
|
||||
"In no event will the authors be held liable for any damages arising from the use of this software.\n"
|
||||
"Permission is granted to anyone to use this software for any purpose, \n"
|
||||
"including commercial applications, and to alter it and redistribute it freely, \n"
|
||||
"subject to the following restrictions:\n"
|
||||
"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.\n"
|
||||
"2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n"
|
||||
"3. This notice may not be removed or altered from any source distribution.\n"
|
||||
"*/\n"
|
||||
"//Originally written by Erwin Coumans\n"
|
||||
"#ifndef B3_CONTACT4DATA_H\n"
|
||||
"#define B3_CONTACT4DATA_H\n"
|
||||
"#ifndef B3_FLOAT4_H\n"
|
||||
"#define B3_FLOAT4_H\n"
|
||||
"#ifndef B3_PLATFORM_DEFINITIONS_H\n"
|
||||
"#define B3_PLATFORM_DEFINITIONS_H\n"
|
||||
"struct MyTest\n"
|
||||
"{\n"
|
||||
" int bla;\n"
|
||||
"};\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"//keep B3_LARGE_FLOAT*B3_LARGE_FLOAT < FLT_MAX\n"
|
||||
"#define B3_LARGE_FLOAT 1e18f\n"
|
||||
"#define B3_INFINITY 1e18f\n"
|
||||
"#define b3Assert(a)\n"
|
||||
"#define b3ConstArray(a) __global const a*\n"
|
||||
"#define b3AtomicInc atomic_inc\n"
|
||||
"#define b3AtomicAdd atomic_add\n"
|
||||
"#define b3Fabs fabs\n"
|
||||
"#define b3Sqrt native_sqrt\n"
|
||||
"#define b3Sin native_sin\n"
|
||||
"#define b3Cos native_cos\n"
|
||||
"#define B3_STATIC\n"
|
||||
"#endif\n"
|
||||
"#endif\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
" typedef float4 b3Float4;\n"
|
||||
" #define b3Float4ConstArg const b3Float4\n"
|
||||
" #define b3MakeFloat4 (float4)\n"
|
||||
" float b3Dot3F4(b3Float4ConstArg v0,b3Float4ConstArg v1)\n"
|
||||
" {\n"
|
||||
" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n"
|
||||
" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n"
|
||||
" return dot(a1, b1);\n"
|
||||
" }\n"
|
||||
" b3Float4 b3Cross3(b3Float4ConstArg v0,b3Float4ConstArg v1)\n"
|
||||
" {\n"
|
||||
" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n"
|
||||
" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n"
|
||||
" return cross(a1, b1);\n"
|
||||
" }\n"
|
||||
" #define b3MinFloat4 min\n"
|
||||
" #define b3MaxFloat4 max\n"
|
||||
" #define b3Normalized(a) normalize(a)\n"
|
||||
"#endif \n"
|
||||
" \n"
|
||||
"inline bool b3IsAlmostZero(b3Float4ConstArg v)\n"
|
||||
"{\n"
|
||||
" if(b3Fabs(v.x)>1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n"
|
||||
" return false;\n"
|
||||
" return true;\n"
|
||||
"}\n"
|
||||
"inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n"
|
||||
"{\n"
|
||||
" float maxDot = -B3_INFINITY;\n"
|
||||
" int i = 0;\n"
|
||||
" int ptIndex = -1;\n"
|
||||
" for( i = 0; i < vecLen; i++ )\n"
|
||||
" {\n"
|
||||
" float dot = b3Dot3F4(vecArray[i],vec);\n"
|
||||
" \n"
|
||||
" if( dot > maxDot )\n"
|
||||
" {\n"
|
||||
" maxDot = dot;\n"
|
||||
" ptIndex = i;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" b3Assert(ptIndex>=0);\n"
|
||||
" if (ptIndex<0)\n"
|
||||
" {\n"
|
||||
" ptIndex = 0;\n"
|
||||
" }\n"
|
||||
" *dotOut = maxDot;\n"
|
||||
" return ptIndex;\n"
|
||||
"}\n"
|
||||
"#endif //B3_FLOAT4_H\n"
|
||||
"typedef struct b3Contact4Data b3Contact4Data_t;\n"
|
||||
"struct b3Contact4Data\n"
|
||||
"{\n"
|
||||
" b3Float4 m_worldPosB[4];\n"
|
||||
"// b3Float4 m_localPosA[4];\n"
|
||||
"// b3Float4 m_localPosB[4];\n"
|
||||
" b3Float4 m_worldNormalOnB; // w: m_nPoints\n"
|
||||
" unsigned short m_restituitionCoeffCmp;\n"
|
||||
" unsigned short m_frictionCoeffCmp;\n"
|
||||
" int m_batchIdx;\n"
|
||||
" int m_bodyAPtrAndSignBit;//x:m_bodyAPtr, y:m_bodyBPtr\n"
|
||||
" int m_bodyBPtrAndSignBit;\n"
|
||||
" int m_childIndexA;\n"
|
||||
" int m_childIndexB;\n"
|
||||
" int m_unused1;\n"
|
||||
" int m_unused2;\n"
|
||||
"};\n"
|
||||
"inline int b3Contact4Data_getNumPoints(const struct b3Contact4Data* contact)\n"
|
||||
"{\n"
|
||||
" return (int)contact->m_worldNormalOnB.w;\n"
|
||||
"};\n"
|
||||
"inline void b3Contact4Data_setNumPoints(struct b3Contact4Data* contact, int numPoints)\n"
|
||||
"{\n"
|
||||
" contact->m_worldNormalOnB.w = (float)numPoints;\n"
|
||||
"};\n"
|
||||
"#endif //B3_CONTACT4DATA_H\n"
|
||||
"#pragma OPENCL EXTENSION cl_amd_printf : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable\n"
|
||||
"#ifdef cl_ext_atomic_counters_32\n"
|
||||
"#pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable\n"
|
||||
"#else\n"
|
||||
"#define counter32_t volatile __global int*\n"
|
||||
"#endif\n"
|
||||
"#define SIMD_WIDTH 64\n"
|
||||
"typedef unsigned int u32;\n"
|
||||
"typedef unsigned short u16;\n"
|
||||
"typedef unsigned char u8;\n"
|
||||
"#define GET_GROUP_IDX get_group_id(0)\n"
|
||||
"#define GET_LOCAL_IDX get_local_id(0)\n"
|
||||
"#define GET_GLOBAL_IDX get_global_id(0)\n"
|
||||
"#define GET_GROUP_SIZE get_local_size(0)\n"
|
||||
"#define GET_NUM_GROUPS get_num_groups(0)\n"
|
||||
"#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n"
|
||||
"#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n"
|
||||
"#define AtomInc(x) atom_inc(&(x))\n"
|
||||
"#define AtomInc1(x, out) out = atom_inc(&(x))\n"
|
||||
"#define AppendInc(x, out) out = atomic_inc(x)\n"
|
||||
"#define AtomAdd(x, value) atom_add(&(x), value)\n"
|
||||
"#define AtomCmpxhg(x, cmp, value) atom_cmpxchg( &(x), cmp, value )\n"
|
||||
"#define AtomXhg(x, value) atom_xchg ( &(x), value )\n"
|
||||
"#define SELECT_UINT4( b, a, condition ) select( b,a,condition )\n"
|
||||
"#define make_float4 (float4)\n"
|
||||
"#define make_float2 (float2)\n"
|
||||
"#define make_uint4 (uint4)\n"
|
||||
"#define make_int4 (int4)\n"
|
||||
"#define make_uint2 (uint2)\n"
|
||||
"#define make_int2 (int2)\n"
|
||||
"#define max2 max\n"
|
||||
"#define min2 min\n"
|
||||
"#define WG_SIZE 64\n"
|
||||
"typedef struct \n"
|
||||
"{\n"
|
||||
" int m_n;\n"
|
||||
" int m_start;\n"
|
||||
" int m_staticIdx;\n"
|
||||
" int m_paddings[1];\n"
|
||||
"} ConstBuffer;\n"
|
||||
"typedef struct \n"
|
||||
"{\n"
|
||||
" int m_a;\n"
|
||||
" int m_b;\n"
|
||||
" u32 m_idx;\n"
|
||||
"}Elem;\n"
|
||||
"// batching on the GPU\n"
|
||||
"__kernel void CreateBatchesBruteForce( __global struct b3Contact4Data* gConstraints, __global const u32* gN, __global const u32* gStart, int m_staticIdx )\n"
|
||||
"{\n"
|
||||
" int wgIdx = GET_GROUP_IDX;\n"
|
||||
" int lIdx = GET_LOCAL_IDX;\n"
|
||||
" \n"
|
||||
" const int m_n = gN[wgIdx];\n"
|
||||
" const int m_start = gStart[wgIdx];\n"
|
||||
" \n"
|
||||
" if( lIdx == 0 )\n"
|
||||
" {\n"
|
||||
" for (int i=0;i<m_n;i++)\n"
|
||||
" {\n"
|
||||
" int srcIdx = i+m_start;\n"
|
||||
" int batchIndex = i;\n"
|
||||
" gConstraints[ srcIdx ].m_batchIdx = batchIndex; \n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"#define CHECK_SIZE (WG_SIZE)\n"
|
||||
"u32 readBuf(__local u32* buff, int idx)\n"
|
||||
"{\n"
|
||||
" idx = idx % (32*CHECK_SIZE);\n"
|
||||
" int bitIdx = idx%32;\n"
|
||||
" int bufIdx = idx/32;\n"
|
||||
" return buff[bufIdx] & (1<<bitIdx);\n"
|
||||
"}\n"
|
||||
"void writeBuf(__local u32* buff, int idx)\n"
|
||||
"{\n"
|
||||
" idx = idx % (32*CHECK_SIZE);\n"
|
||||
" int bitIdx = idx%32;\n"
|
||||
" int bufIdx = idx/32;\n"
|
||||
" buff[bufIdx] |= (1<<bitIdx);\n"
|
||||
" //atom_or( &buff[bufIdx], (1<<bitIdx) );\n"
|
||||
"}\n"
|
||||
"u32 tryWrite(__local u32* buff, int idx)\n"
|
||||
"{\n"
|
||||
" idx = idx % (32*CHECK_SIZE);\n"
|
||||
" int bitIdx = idx%32;\n"
|
||||
" int bufIdx = idx/32;\n"
|
||||
" u32 ans = (u32)atom_or( &buff[bufIdx], (1<<bitIdx) );\n"
|
||||
" return ((ans >> bitIdx)&1) == 0;\n"
|
||||
"}\n"
|
||||
"// batching on the GPU\n"
|
||||
"__kernel void CreateBatchesNew( __global struct b3Contact4Data* gConstraints, __global const u32* gN, __global const u32* gStart, __global int* batchSizes, int staticIdx )\n"
|
||||
"{\n"
|
||||
" int wgIdx = GET_GROUP_IDX;\n"
|
||||
" int lIdx = GET_LOCAL_IDX;\n"
|
||||
" const int numConstraints = gN[wgIdx];\n"
|
||||
" const int m_start = gStart[wgIdx];\n"
|
||||
" b3Contact4Data_t tmp;\n"
|
||||
" \n"
|
||||
" __local u32 ldsFixedBuffer[CHECK_SIZE];\n"
|
||||
" \n"
|
||||
" \n"
|
||||
" \n"
|
||||
" \n"
|
||||
" \n"
|
||||
" if( lIdx == 0 )\n"
|
||||
" {\n"
|
||||
" \n"
|
||||
" \n"
|
||||
" __global struct b3Contact4Data* cs = &gConstraints[m_start]; \n"
|
||||
" \n"
|
||||
" \n"
|
||||
" int numValidConstraints = 0;\n"
|
||||
" int batchIdx = 0;\n"
|
||||
" while( numValidConstraints < numConstraints)\n"
|
||||
" {\n"
|
||||
" int nCurrentBatch = 0;\n"
|
||||
" // clear flag\n"
|
||||
" \n"
|
||||
" for(int i=0; i<CHECK_SIZE; i++) \n"
|
||||
" ldsFixedBuffer[i] = 0; \n"
|
||||
" for(int i=numValidConstraints; i<numConstraints; i++)\n"
|
||||
" {\n"
|
||||
" int bodyAS = cs[i].m_bodyAPtrAndSignBit;\n"
|
||||
" int bodyBS = cs[i].m_bodyBPtrAndSignBit;\n"
|
||||
" int bodyA = abs(bodyAS);\n"
|
||||
" int bodyB = abs(bodyBS);\n"
|
||||
" bool aIsStatic = (bodyAS<0) || bodyAS==staticIdx;\n"
|
||||
" bool bIsStatic = (bodyBS<0) || bodyBS==staticIdx;\n"
|
||||
" int aUnavailable = aIsStatic ? 0 : readBuf( ldsFixedBuffer, bodyA);\n"
|
||||
" int bUnavailable = bIsStatic ? 0 : readBuf( ldsFixedBuffer, bodyB);\n"
|
||||
" \n"
|
||||
" if( aUnavailable==0 && bUnavailable==0 ) // ok\n"
|
||||
" {\n"
|
||||
" if (!aIsStatic)\n"
|
||||
" {\n"
|
||||
" writeBuf( ldsFixedBuffer, bodyA );\n"
|
||||
" }\n"
|
||||
" if (!bIsStatic)\n"
|
||||
" {\n"
|
||||
" writeBuf( ldsFixedBuffer, bodyB );\n"
|
||||
" }\n"
|
||||
" cs[i].m_batchIdx = batchIdx;\n"
|
||||
" if (i!=numValidConstraints)\n"
|
||||
" {\n"
|
||||
" tmp = cs[i];\n"
|
||||
" cs[i] = cs[numValidConstraints];\n"
|
||||
" cs[numValidConstraints] = tmp;\n"
|
||||
" }\n"
|
||||
" numValidConstraints++;\n"
|
||||
" \n"
|
||||
" nCurrentBatch++;\n"
|
||||
" if( nCurrentBatch == SIMD_WIDTH)\n"
|
||||
" {\n"
|
||||
" nCurrentBatch = 0;\n"
|
||||
" for(int i=0; i<CHECK_SIZE; i++) \n"
|
||||
" ldsFixedBuffer[i] = 0;\n"
|
||||
" \n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" }//for\n"
|
||||
" batchIdx ++;\n"
|
||||
" }//while\n"
|
||||
" \n"
|
||||
" batchSizes[wgIdx] = batchIdx;\n"
|
||||
" }//if( lIdx == 0 )\n"
|
||||
" \n"
|
||||
" //return batchIdx;\n"
|
||||
"}\n"
|
||||
;
|
||||
static const char* batchingKernelsNewCL =
|
||||
"/*\n"
|
||||
"Copyright (c) 2012 Advanced Micro Devices, Inc. \n"
|
||||
"This software is provided 'as-is', without any express or implied warranty.\n"
|
||||
"In no event will the authors be held liable for any damages arising from the use of this software.\n"
|
||||
"Permission is granted to anyone to use this software for any purpose, \n"
|
||||
"including commercial applications, and to alter it and redistribute it freely, \n"
|
||||
"subject to the following restrictions:\n"
|
||||
"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.\n"
|
||||
"2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n"
|
||||
"3. This notice may not be removed or altered from any source distribution.\n"
|
||||
"*/\n"
|
||||
"//Originally written by Erwin Coumans\n"
|
||||
"#ifndef B3_CONTACT4DATA_H\n"
|
||||
"#define B3_CONTACT4DATA_H\n"
|
||||
"#ifndef B3_FLOAT4_H\n"
|
||||
"#define B3_FLOAT4_H\n"
|
||||
"#ifndef B3_PLATFORM_DEFINITIONS_H\n"
|
||||
"#define B3_PLATFORM_DEFINITIONS_H\n"
|
||||
"struct MyTest\n"
|
||||
"{\n"
|
||||
" int bla;\n"
|
||||
"};\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"//keep B3_LARGE_FLOAT*B3_LARGE_FLOAT < FLT_MAX\n"
|
||||
"#define B3_LARGE_FLOAT 1e18f\n"
|
||||
"#define B3_INFINITY 1e18f\n"
|
||||
"#define b3Assert(a)\n"
|
||||
"#define b3ConstArray(a) __global const a*\n"
|
||||
"#define b3AtomicInc atomic_inc\n"
|
||||
"#define b3AtomicAdd atomic_add\n"
|
||||
"#define b3Fabs fabs\n"
|
||||
"#define b3Sqrt native_sqrt\n"
|
||||
"#define b3Sin native_sin\n"
|
||||
"#define b3Cos native_cos\n"
|
||||
"#define B3_STATIC\n"
|
||||
"#endif\n"
|
||||
"#endif\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
" typedef float4 b3Float4;\n"
|
||||
" #define b3Float4ConstArg const b3Float4\n"
|
||||
" #define b3MakeFloat4 (float4)\n"
|
||||
" float b3Dot3F4(b3Float4ConstArg v0,b3Float4ConstArg v1)\n"
|
||||
" {\n"
|
||||
" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n"
|
||||
" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n"
|
||||
" return dot(a1, b1);\n"
|
||||
" }\n"
|
||||
" b3Float4 b3Cross3(b3Float4ConstArg v0,b3Float4ConstArg v1)\n"
|
||||
" {\n"
|
||||
" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n"
|
||||
" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n"
|
||||
" return cross(a1, b1);\n"
|
||||
" }\n"
|
||||
" #define b3MinFloat4 min\n"
|
||||
" #define b3MaxFloat4 max\n"
|
||||
" #define b3Normalized(a) normalize(a)\n"
|
||||
"#endif \n"
|
||||
" \n"
|
||||
"inline bool b3IsAlmostZero(b3Float4ConstArg v)\n"
|
||||
"{\n"
|
||||
" if(b3Fabs(v.x)>1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n"
|
||||
" return false;\n"
|
||||
" return true;\n"
|
||||
"}\n"
|
||||
"inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n"
|
||||
"{\n"
|
||||
" float maxDot = -B3_INFINITY;\n"
|
||||
" int i = 0;\n"
|
||||
" int ptIndex = -1;\n"
|
||||
" for( i = 0; i < vecLen; i++ )\n"
|
||||
" {\n"
|
||||
" float dot = b3Dot3F4(vecArray[i],vec);\n"
|
||||
" \n"
|
||||
" if( dot > maxDot )\n"
|
||||
" {\n"
|
||||
" maxDot = dot;\n"
|
||||
" ptIndex = i;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" b3Assert(ptIndex>=0);\n"
|
||||
" if (ptIndex<0)\n"
|
||||
" {\n"
|
||||
" ptIndex = 0;\n"
|
||||
" }\n"
|
||||
" *dotOut = maxDot;\n"
|
||||
" return ptIndex;\n"
|
||||
"}\n"
|
||||
"#endif //B3_FLOAT4_H\n"
|
||||
"typedef struct b3Contact4Data b3Contact4Data_t;\n"
|
||||
"struct b3Contact4Data\n"
|
||||
"{\n"
|
||||
" b3Float4 m_worldPosB[4];\n"
|
||||
"// b3Float4 m_localPosA[4];\n"
|
||||
"// b3Float4 m_localPosB[4];\n"
|
||||
" b3Float4 m_worldNormalOnB; // w: m_nPoints\n"
|
||||
" unsigned short m_restituitionCoeffCmp;\n"
|
||||
" unsigned short m_frictionCoeffCmp;\n"
|
||||
" int m_batchIdx;\n"
|
||||
" int m_bodyAPtrAndSignBit;//x:m_bodyAPtr, y:m_bodyBPtr\n"
|
||||
" int m_bodyBPtrAndSignBit;\n"
|
||||
" int m_childIndexA;\n"
|
||||
" int m_childIndexB;\n"
|
||||
" int m_unused1;\n"
|
||||
" int m_unused2;\n"
|
||||
"};\n"
|
||||
"inline int b3Contact4Data_getNumPoints(const struct b3Contact4Data* contact)\n"
|
||||
"{\n"
|
||||
" return (int)contact->m_worldNormalOnB.w;\n"
|
||||
"};\n"
|
||||
"inline void b3Contact4Data_setNumPoints(struct b3Contact4Data* contact, int numPoints)\n"
|
||||
"{\n"
|
||||
" contact->m_worldNormalOnB.w = (float)numPoints;\n"
|
||||
"};\n"
|
||||
"#endif //B3_CONTACT4DATA_H\n"
|
||||
"#pragma OPENCL EXTENSION cl_amd_printf : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable\n"
|
||||
"#ifdef cl_ext_atomic_counters_32\n"
|
||||
"#pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable\n"
|
||||
"#else\n"
|
||||
"#define counter32_t volatile __global int*\n"
|
||||
"#endif\n"
|
||||
"#define SIMD_WIDTH 64\n"
|
||||
"typedef unsigned int u32;\n"
|
||||
"typedef unsigned short u16;\n"
|
||||
"typedef unsigned char u8;\n"
|
||||
"#define GET_GROUP_IDX get_group_id(0)\n"
|
||||
"#define GET_LOCAL_IDX get_local_id(0)\n"
|
||||
"#define GET_GLOBAL_IDX get_global_id(0)\n"
|
||||
"#define GET_GROUP_SIZE get_local_size(0)\n"
|
||||
"#define GET_NUM_GROUPS get_num_groups(0)\n"
|
||||
"#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n"
|
||||
"#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n"
|
||||
"#define AtomInc(x) atom_inc(&(x))\n"
|
||||
"#define AtomInc1(x, out) out = atom_inc(&(x))\n"
|
||||
"#define AppendInc(x, out) out = atomic_inc(x)\n"
|
||||
"#define AtomAdd(x, value) atom_add(&(x), value)\n"
|
||||
"#define AtomCmpxhg(x, cmp, value) atom_cmpxchg( &(x), cmp, value )\n"
|
||||
"#define AtomXhg(x, value) atom_xchg ( &(x), value )\n"
|
||||
"#define SELECT_UINT4( b, a, condition ) select( b,a,condition )\n"
|
||||
"#define make_float4 (float4)\n"
|
||||
"#define make_float2 (float2)\n"
|
||||
"#define make_uint4 (uint4)\n"
|
||||
"#define make_int4 (int4)\n"
|
||||
"#define make_uint2 (uint2)\n"
|
||||
"#define make_int2 (int2)\n"
|
||||
"#define max2 max\n"
|
||||
"#define min2 min\n"
|
||||
"#define WG_SIZE 64\n"
|
||||
"typedef struct \n"
|
||||
"{\n"
|
||||
" int m_n;\n"
|
||||
" int m_start;\n"
|
||||
" int m_staticIdx;\n"
|
||||
" int m_paddings[1];\n"
|
||||
"} ConstBuffer;\n"
|
||||
"typedef struct \n"
|
||||
"{\n"
|
||||
" int m_a;\n"
|
||||
" int m_b;\n"
|
||||
" u32 m_idx;\n"
|
||||
"}Elem;\n"
|
||||
"// batching on the GPU\n"
|
||||
"__kernel void CreateBatchesBruteForce( __global struct b3Contact4Data* gConstraints, __global const u32* gN, __global const u32* gStart, int m_staticIdx )\n"
|
||||
"{\n"
|
||||
" int wgIdx = GET_GROUP_IDX;\n"
|
||||
" int lIdx = GET_LOCAL_IDX;\n"
|
||||
" \n"
|
||||
" const int m_n = gN[wgIdx];\n"
|
||||
" const int m_start = gStart[wgIdx];\n"
|
||||
" \n"
|
||||
" if( lIdx == 0 )\n"
|
||||
" {\n"
|
||||
" for (int i=0;i<m_n;i++)\n"
|
||||
" {\n"
|
||||
" int srcIdx = i+m_start;\n"
|
||||
" int batchIndex = i;\n"
|
||||
" gConstraints[ srcIdx ].m_batchIdx = batchIndex; \n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"#define CHECK_SIZE (WG_SIZE)\n"
|
||||
"u32 readBuf(__local u32* buff, int idx)\n"
|
||||
"{\n"
|
||||
" idx = idx % (32*CHECK_SIZE);\n"
|
||||
" int bitIdx = idx%32;\n"
|
||||
" int bufIdx = idx/32;\n"
|
||||
" return buff[bufIdx] & (1<<bitIdx);\n"
|
||||
"}\n"
|
||||
"void writeBuf(__local u32* buff, int idx)\n"
|
||||
"{\n"
|
||||
" idx = idx % (32*CHECK_SIZE);\n"
|
||||
" int bitIdx = idx%32;\n"
|
||||
" int bufIdx = idx/32;\n"
|
||||
" buff[bufIdx] |= (1<<bitIdx);\n"
|
||||
" //atom_or( &buff[bufIdx], (1<<bitIdx) );\n"
|
||||
"}\n"
|
||||
"u32 tryWrite(__local u32* buff, int idx)\n"
|
||||
"{\n"
|
||||
" idx = idx % (32*CHECK_SIZE);\n"
|
||||
" int bitIdx = idx%32;\n"
|
||||
" int bufIdx = idx/32;\n"
|
||||
" u32 ans = (u32)atom_or( &buff[bufIdx], (1<<bitIdx) );\n"
|
||||
" return ((ans >> bitIdx)&1) == 0;\n"
|
||||
"}\n"
|
||||
"// batching on the GPU\n"
|
||||
"__kernel void CreateBatchesNew( __global struct b3Contact4Data* gConstraints, __global const u32* gN, __global const u32* gStart, __global int* batchSizes, int staticIdx )\n"
|
||||
"{\n"
|
||||
" int wgIdx = GET_GROUP_IDX;\n"
|
||||
" int lIdx = GET_LOCAL_IDX;\n"
|
||||
" const int numConstraints = gN[wgIdx];\n"
|
||||
" const int m_start = gStart[wgIdx];\n"
|
||||
" b3Contact4Data_t tmp;\n"
|
||||
" \n"
|
||||
" __local u32 ldsFixedBuffer[CHECK_SIZE];\n"
|
||||
" \n"
|
||||
" \n"
|
||||
" \n"
|
||||
" \n"
|
||||
" \n"
|
||||
" if( lIdx == 0 )\n"
|
||||
" {\n"
|
||||
" \n"
|
||||
" \n"
|
||||
" __global struct b3Contact4Data* cs = &gConstraints[m_start]; \n"
|
||||
" \n"
|
||||
" \n"
|
||||
" int numValidConstraints = 0;\n"
|
||||
" int batchIdx = 0;\n"
|
||||
" while( numValidConstraints < numConstraints)\n"
|
||||
" {\n"
|
||||
" int nCurrentBatch = 0;\n"
|
||||
" // clear flag\n"
|
||||
" \n"
|
||||
" for(int i=0; i<CHECK_SIZE; i++) \n"
|
||||
" ldsFixedBuffer[i] = 0; \n"
|
||||
" for(int i=numValidConstraints; i<numConstraints; i++)\n"
|
||||
" {\n"
|
||||
" int bodyAS = cs[i].m_bodyAPtrAndSignBit;\n"
|
||||
" int bodyBS = cs[i].m_bodyBPtrAndSignBit;\n"
|
||||
" int bodyA = abs(bodyAS);\n"
|
||||
" int bodyB = abs(bodyBS);\n"
|
||||
" bool aIsStatic = (bodyAS<0) || bodyAS==staticIdx;\n"
|
||||
" bool bIsStatic = (bodyBS<0) || bodyBS==staticIdx;\n"
|
||||
" int aUnavailable = aIsStatic ? 0 : readBuf( ldsFixedBuffer, bodyA);\n"
|
||||
" int bUnavailable = bIsStatic ? 0 : readBuf( ldsFixedBuffer, bodyB);\n"
|
||||
" \n"
|
||||
" if( aUnavailable==0 && bUnavailable==0 ) // ok\n"
|
||||
" {\n"
|
||||
" if (!aIsStatic)\n"
|
||||
" {\n"
|
||||
" writeBuf( ldsFixedBuffer, bodyA );\n"
|
||||
" }\n"
|
||||
" if (!bIsStatic)\n"
|
||||
" {\n"
|
||||
" writeBuf( ldsFixedBuffer, bodyB );\n"
|
||||
" }\n"
|
||||
" cs[i].m_batchIdx = batchIdx;\n"
|
||||
" if (i!=numValidConstraints)\n"
|
||||
" {\n"
|
||||
" tmp = cs[i];\n"
|
||||
" cs[i] = cs[numValidConstraints];\n"
|
||||
" cs[numValidConstraints] = tmp;\n"
|
||||
" }\n"
|
||||
" numValidConstraints++;\n"
|
||||
" \n"
|
||||
" nCurrentBatch++;\n"
|
||||
" if( nCurrentBatch == SIMD_WIDTH)\n"
|
||||
" {\n"
|
||||
" nCurrentBatch = 0;\n"
|
||||
" for(int i=0; i<CHECK_SIZE; i++) \n"
|
||||
" ldsFixedBuffer[i] = 0;\n"
|
||||
" \n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" }//for\n"
|
||||
" batchIdx ++;\n"
|
||||
" }//while\n"
|
||||
" \n"
|
||||
" batchSizes[wgIdx] = batchIdx;\n"
|
||||
" }//if( lIdx == 0 )\n"
|
||||
" \n"
|
||||
" //return batchIdx;\n"
|
||||
"}\n";
|
||||
|
||||
@@ -1,433 +1,432 @@
|
||||
//this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project
|
||||
static const char* integrateKernelCL= \
|
||||
"/*\n"
|
||||
"Copyright (c) 2013 Advanced Micro Devices, Inc. \n"
|
||||
"This software is provided 'as-is', without any express or implied warranty.\n"
|
||||
"In no event will the authors be held liable for any damages arising from the use of this software.\n"
|
||||
"Permission is granted to anyone to use this software for any purpose, \n"
|
||||
"including commercial applications, and to alter it and redistribute it freely, \n"
|
||||
"subject to the following restrictions:\n"
|
||||
"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.\n"
|
||||
"2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n"
|
||||
"3. This notice may not be removed or altered from any source distribution.\n"
|
||||
"*/\n"
|
||||
"//Originally written by Erwin Coumans\n"
|
||||
"#ifndef B3_RIGIDBODY_DATA_H\n"
|
||||
"#define B3_RIGIDBODY_DATA_H\n"
|
||||
"#ifndef B3_FLOAT4_H\n"
|
||||
"#define B3_FLOAT4_H\n"
|
||||
"#ifndef B3_PLATFORM_DEFINITIONS_H\n"
|
||||
"#define B3_PLATFORM_DEFINITIONS_H\n"
|
||||
"struct MyTest\n"
|
||||
"{\n"
|
||||
" int bla;\n"
|
||||
"};\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"//keep B3_LARGE_FLOAT*B3_LARGE_FLOAT < FLT_MAX\n"
|
||||
"#define B3_LARGE_FLOAT 1e18f\n"
|
||||
"#define B3_INFINITY 1e18f\n"
|
||||
"#define b3Assert(a)\n"
|
||||
"#define b3ConstArray(a) __global const a*\n"
|
||||
"#define b3AtomicInc atomic_inc\n"
|
||||
"#define b3AtomicAdd atomic_add\n"
|
||||
"#define b3Fabs fabs\n"
|
||||
"#define b3Sqrt native_sqrt\n"
|
||||
"#define b3Sin native_sin\n"
|
||||
"#define b3Cos native_cos\n"
|
||||
"#define B3_STATIC\n"
|
||||
"#endif\n"
|
||||
"#endif\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
" typedef float4 b3Float4;\n"
|
||||
" #define b3Float4ConstArg const b3Float4\n"
|
||||
" #define b3MakeFloat4 (float4)\n"
|
||||
" float b3Dot3F4(b3Float4ConstArg v0,b3Float4ConstArg v1)\n"
|
||||
" {\n"
|
||||
" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n"
|
||||
" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n"
|
||||
" return dot(a1, b1);\n"
|
||||
" }\n"
|
||||
" b3Float4 b3Cross3(b3Float4ConstArg v0,b3Float4ConstArg v1)\n"
|
||||
" {\n"
|
||||
" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n"
|
||||
" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n"
|
||||
" return cross(a1, b1);\n"
|
||||
" }\n"
|
||||
" #define b3MinFloat4 min\n"
|
||||
" #define b3MaxFloat4 max\n"
|
||||
" #define b3Normalized(a) normalize(a)\n"
|
||||
"#endif \n"
|
||||
" \n"
|
||||
"inline bool b3IsAlmostZero(b3Float4ConstArg v)\n"
|
||||
"{\n"
|
||||
" if(b3Fabs(v.x)>1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n"
|
||||
" return false;\n"
|
||||
" return true;\n"
|
||||
"}\n"
|
||||
"inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n"
|
||||
"{\n"
|
||||
" float maxDot = -B3_INFINITY;\n"
|
||||
" int i = 0;\n"
|
||||
" int ptIndex = -1;\n"
|
||||
" for( i = 0; i < vecLen; i++ )\n"
|
||||
" {\n"
|
||||
" float dot = b3Dot3F4(vecArray[i],vec);\n"
|
||||
" \n"
|
||||
" if( dot > maxDot )\n"
|
||||
" {\n"
|
||||
" maxDot = dot;\n"
|
||||
" ptIndex = i;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" b3Assert(ptIndex>=0);\n"
|
||||
" if (ptIndex<0)\n"
|
||||
" {\n"
|
||||
" ptIndex = 0;\n"
|
||||
" }\n"
|
||||
" *dotOut = maxDot;\n"
|
||||
" return ptIndex;\n"
|
||||
"}\n"
|
||||
"#endif //B3_FLOAT4_H\n"
|
||||
"#ifndef B3_QUAT_H\n"
|
||||
"#define B3_QUAT_H\n"
|
||||
"#ifndef B3_PLATFORM_DEFINITIONS_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"#endif\n"
|
||||
"#endif\n"
|
||||
"#ifndef B3_FLOAT4_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"#endif \n"
|
||||
"#endif //B3_FLOAT4_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
" typedef float4 b3Quat;\n"
|
||||
" #define b3QuatConstArg const b3Quat\n"
|
||||
" \n"
|
||||
" \n"
|
||||
"inline float4 b3FastNormalize4(float4 v)\n"
|
||||
"{\n"
|
||||
" v = (float4)(v.xyz,0.f);\n"
|
||||
" return fast_normalize(v);\n"
|
||||
"}\n"
|
||||
" \n"
|
||||
"inline b3Quat b3QuatMul(b3Quat a, b3Quat b);\n"
|
||||
"inline b3Quat b3QuatNormalized(b3QuatConstArg in);\n"
|
||||
"inline b3Quat b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec);\n"
|
||||
"inline b3Quat b3QuatInvert(b3QuatConstArg q);\n"
|
||||
"inline b3Quat b3QuatInverse(b3QuatConstArg q);\n"
|
||||
"inline b3Quat b3QuatMul(b3QuatConstArg a, b3QuatConstArg b)\n"
|
||||
"{\n"
|
||||
" b3Quat ans;\n"
|
||||
" ans = b3Cross3( a, b );\n"
|
||||
" ans += a.w*b+b.w*a;\n"
|
||||
"// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n"
|
||||
" ans.w = a.w*b.w - b3Dot3F4(a, b);\n"
|
||||
" return ans;\n"
|
||||
"}\n"
|
||||
"inline b3Quat b3QuatNormalized(b3QuatConstArg in)\n"
|
||||
"{\n"
|
||||
" b3Quat q;\n"
|
||||
" q=in;\n"
|
||||
" //return b3FastNormalize4(in);\n"
|
||||
" float len = native_sqrt(dot(q, q));\n"
|
||||
" if(len > 0.f)\n"
|
||||
" {\n"
|
||||
" q *= 1.f / len;\n"
|
||||
" }\n"
|
||||
" else\n"
|
||||
" {\n"
|
||||
" q.x = q.y = q.z = 0.f;\n"
|
||||
" q.w = 1.f;\n"
|
||||
" }\n"
|
||||
" return q;\n"
|
||||
"}\n"
|
||||
"inline float4 b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec)\n"
|
||||
"{\n"
|
||||
" b3Quat qInv = b3QuatInvert( q );\n"
|
||||
" float4 vcpy = vec;\n"
|
||||
" vcpy.w = 0.f;\n"
|
||||
" float4 out = b3QuatMul(b3QuatMul(q,vcpy),qInv);\n"
|
||||
" return out;\n"
|
||||
"}\n"
|
||||
"inline b3Quat b3QuatInverse(b3QuatConstArg q)\n"
|
||||
"{\n"
|
||||
" return (b3Quat)(-q.xyz, q.w);\n"
|
||||
"}\n"
|
||||
"inline b3Quat b3QuatInvert(b3QuatConstArg q)\n"
|
||||
"{\n"
|
||||
" return (b3Quat)(-q.xyz, q.w);\n"
|
||||
"}\n"
|
||||
"inline float4 b3QuatInvRotate(b3QuatConstArg q, b3QuatConstArg vec)\n"
|
||||
"{\n"
|
||||
" return b3QuatRotate( b3QuatInvert( q ), vec );\n"
|
||||
"}\n"
|
||||
"inline b3Float4 b3TransformPoint(b3Float4ConstArg point, b3Float4ConstArg translation, b3QuatConstArg orientation)\n"
|
||||
"{\n"
|
||||
" return b3QuatRotate( orientation, point ) + (translation);\n"
|
||||
"}\n"
|
||||
" \n"
|
||||
"#endif \n"
|
||||
"#endif //B3_QUAT_H\n"
|
||||
"#ifndef B3_MAT3x3_H\n"
|
||||
"#define B3_MAT3x3_H\n"
|
||||
"#ifndef B3_QUAT_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"#endif \n"
|
||||
"#endif //B3_QUAT_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" b3Float4 m_row[3];\n"
|
||||
"}b3Mat3x3;\n"
|
||||
"#define b3Mat3x3ConstArg const b3Mat3x3\n"
|
||||
"#define b3GetRow(m,row) (m.m_row[row])\n"
|
||||
"inline b3Mat3x3 b3QuatGetRotationMatrix(b3Quat quat)\n"
|
||||
"{\n"
|
||||
" b3Float4 quat2 = (b3Float4)(quat.x*quat.x, quat.y*quat.y, quat.z*quat.z, 0.f);\n"
|
||||
" b3Mat3x3 out;\n"
|
||||
" out.m_row[0].x=1-2*quat2.y-2*quat2.z;\n"
|
||||
" out.m_row[0].y=2*quat.x*quat.y-2*quat.w*quat.z;\n"
|
||||
" out.m_row[0].z=2*quat.x*quat.z+2*quat.w*quat.y;\n"
|
||||
" out.m_row[0].w = 0.f;\n"
|
||||
" out.m_row[1].x=2*quat.x*quat.y+2*quat.w*quat.z;\n"
|
||||
" out.m_row[1].y=1-2*quat2.x-2*quat2.z;\n"
|
||||
" out.m_row[1].z=2*quat.y*quat.z-2*quat.w*quat.x;\n"
|
||||
" out.m_row[1].w = 0.f;\n"
|
||||
" out.m_row[2].x=2*quat.x*quat.z-2*quat.w*quat.y;\n"
|
||||
" out.m_row[2].y=2*quat.y*quat.z+2*quat.w*quat.x;\n"
|
||||
" out.m_row[2].z=1-2*quat2.x-2*quat2.y;\n"
|
||||
" out.m_row[2].w = 0.f;\n"
|
||||
" return out;\n"
|
||||
"}\n"
|
||||
"inline b3Mat3x3 b3AbsoluteMat3x3(b3Mat3x3ConstArg matIn)\n"
|
||||
"{\n"
|
||||
" b3Mat3x3 out;\n"
|
||||
" out.m_row[0] = fabs(matIn.m_row[0]);\n"
|
||||
" out.m_row[1] = fabs(matIn.m_row[1]);\n"
|
||||
" out.m_row[2] = fabs(matIn.m_row[2]);\n"
|
||||
" return out;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtZero();\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtIdentity();\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtTranspose(b3Mat3x3 m);\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b);\n"
|
||||
"__inline\n"
|
||||
"b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b);\n"
|
||||
"__inline\n"
|
||||
"b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b);\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtZero()\n"
|
||||
"{\n"
|
||||
" b3Mat3x3 m;\n"
|
||||
" m.m_row[0] = (b3Float4)(0.f);\n"
|
||||
" m.m_row[1] = (b3Float4)(0.f);\n"
|
||||
" m.m_row[2] = (b3Float4)(0.f);\n"
|
||||
" return m;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtIdentity()\n"
|
||||
"{\n"
|
||||
" b3Mat3x3 m;\n"
|
||||
" m.m_row[0] = (b3Float4)(1,0,0,0);\n"
|
||||
" m.m_row[1] = (b3Float4)(0,1,0,0);\n"
|
||||
" m.m_row[2] = (b3Float4)(0,0,1,0);\n"
|
||||
" return m;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtTranspose(b3Mat3x3 m)\n"
|
||||
"{\n"
|
||||
" b3Mat3x3 out;\n"
|
||||
" out.m_row[0] = (b3Float4)(m.m_row[0].x, m.m_row[1].x, m.m_row[2].x, 0.f);\n"
|
||||
" out.m_row[1] = (b3Float4)(m.m_row[0].y, m.m_row[1].y, m.m_row[2].y, 0.f);\n"
|
||||
" out.m_row[2] = (b3Float4)(m.m_row[0].z, m.m_row[1].z, m.m_row[2].z, 0.f);\n"
|
||||
" return out;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b)\n"
|
||||
"{\n"
|
||||
" b3Mat3x3 transB;\n"
|
||||
" transB = mtTranspose( b );\n"
|
||||
" b3Mat3x3 ans;\n"
|
||||
" // why this doesn't run when 0ing in the for{}\n"
|
||||
" a.m_row[0].w = 0.f;\n"
|
||||
" a.m_row[1].w = 0.f;\n"
|
||||
" a.m_row[2].w = 0.f;\n"
|
||||
" for(int i=0; i<3; i++)\n"
|
||||
" {\n"
|
||||
"// a.m_row[i].w = 0.f;\n"
|
||||
" ans.m_row[i].x = b3Dot3F4(a.m_row[i],transB.m_row[0]);\n"
|
||||
" ans.m_row[i].y = b3Dot3F4(a.m_row[i],transB.m_row[1]);\n"
|
||||
" ans.m_row[i].z = b3Dot3F4(a.m_row[i],transB.m_row[2]);\n"
|
||||
" ans.m_row[i].w = 0.f;\n"
|
||||
" }\n"
|
||||
" return ans;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b)\n"
|
||||
"{\n"
|
||||
" b3Float4 ans;\n"
|
||||
" ans.x = b3Dot3F4( a.m_row[0], b );\n"
|
||||
" ans.y = b3Dot3F4( a.m_row[1], b );\n"
|
||||
" ans.z = b3Dot3F4( a.m_row[2], b );\n"
|
||||
" ans.w = 0.f;\n"
|
||||
" return ans;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b)\n"
|
||||
"{\n"
|
||||
" b3Float4 colx = b3MakeFloat4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n"
|
||||
" b3Float4 coly = b3MakeFloat4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n"
|
||||
" b3Float4 colz = b3MakeFloat4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n"
|
||||
" b3Float4 ans;\n"
|
||||
" ans.x = b3Dot3F4( a, colx );\n"
|
||||
" ans.y = b3Dot3F4( a, coly );\n"
|
||||
" ans.z = b3Dot3F4( a, colz );\n"
|
||||
" return ans;\n"
|
||||
"}\n"
|
||||
"#endif\n"
|
||||
"#endif //B3_MAT3x3_H\n"
|
||||
"typedef struct b3RigidBodyData b3RigidBodyData_t;\n"
|
||||
"struct b3RigidBodyData\n"
|
||||
"{\n"
|
||||
" b3Float4 m_pos;\n"
|
||||
" b3Quat m_quat;\n"
|
||||
" b3Float4 m_linVel;\n"
|
||||
" b3Float4 m_angVel;\n"
|
||||
" int m_collidableIdx;\n"
|
||||
" float m_invMass;\n"
|
||||
" float m_restituitionCoeff;\n"
|
||||
" float m_frictionCoeff;\n"
|
||||
"};\n"
|
||||
"typedef struct b3InertiaData b3InertiaData_t;\n"
|
||||
"struct b3InertiaData\n"
|
||||
"{\n"
|
||||
" b3Mat3x3 m_invInertiaWorld;\n"
|
||||
" b3Mat3x3 m_initInvInertia;\n"
|
||||
"};\n"
|
||||
"#endif //B3_RIGIDBODY_DATA_H\n"
|
||||
" \n"
|
||||
"#ifndef B3_RIGIDBODY_DATA_H\n"
|
||||
"#endif //B3_RIGIDBODY_DATA_H\n"
|
||||
" \n"
|
||||
"inline void integrateSingleTransform( __global b3RigidBodyData_t* bodies,int nodeID, float timeStep, float angularDamping, b3Float4ConstArg gravityAcceleration)\n"
|
||||
"{\n"
|
||||
" \n"
|
||||
" if (bodies[nodeID].m_invMass != 0.f)\n"
|
||||
" {\n"
|
||||
" float BT_GPU_ANGULAR_MOTION_THRESHOLD = (0.25f * 3.14159254f);\n"
|
||||
" //angular velocity\n"
|
||||
" {\n"
|
||||
" b3Float4 axis;\n"
|
||||
" //add some hardcoded angular damping\n"
|
||||
" bodies[nodeID].m_angVel.x *= angularDamping;\n"
|
||||
" bodies[nodeID].m_angVel.y *= angularDamping;\n"
|
||||
" bodies[nodeID].m_angVel.z *= angularDamping;\n"
|
||||
" \n"
|
||||
" b3Float4 angvel = bodies[nodeID].m_angVel;\n"
|
||||
" float fAngle = b3Sqrt(b3Dot3F4(angvel, angvel));\n"
|
||||
" \n"
|
||||
" //limit the angular motion\n"
|
||||
" if(fAngle*timeStep > BT_GPU_ANGULAR_MOTION_THRESHOLD)\n"
|
||||
" {\n"
|
||||
" fAngle = BT_GPU_ANGULAR_MOTION_THRESHOLD / timeStep;\n"
|
||||
" }\n"
|
||||
" if(fAngle < 0.001f)\n"
|
||||
" {\n"
|
||||
" // use Taylor's expansions of sync function\n"
|
||||
" axis = angvel * (0.5f*timeStep-(timeStep*timeStep*timeStep)*0.020833333333f * fAngle * fAngle);\n"
|
||||
" }\n"
|
||||
" else\n"
|
||||
" {\n"
|
||||
" // sync(fAngle) = sin(c*fAngle)/t\n"
|
||||
" axis = angvel * ( b3Sin(0.5f * fAngle * timeStep) / fAngle);\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" b3Quat dorn;\n"
|
||||
" dorn.x = axis.x;\n"
|
||||
" dorn.y = axis.y;\n"
|
||||
" dorn.z = axis.z;\n"
|
||||
" dorn.w = b3Cos(fAngle * timeStep * 0.5f);\n"
|
||||
" b3Quat orn0 = bodies[nodeID].m_quat;\n"
|
||||
" b3Quat predictedOrn = b3QuatMul(dorn, orn0);\n"
|
||||
" predictedOrn = b3QuatNormalized(predictedOrn);\n"
|
||||
" bodies[nodeID].m_quat=predictedOrn;\n"
|
||||
" }\n"
|
||||
" //linear velocity \n"
|
||||
" bodies[nodeID].m_pos += bodies[nodeID].m_linVel * timeStep;\n"
|
||||
" \n"
|
||||
" //apply gravity\n"
|
||||
" bodies[nodeID].m_linVel += gravityAcceleration * timeStep;\n"
|
||||
" \n"
|
||||
" }\n"
|
||||
" \n"
|
||||
"}\n"
|
||||
"inline void b3IntegrateTransform( __global b3RigidBodyData_t* body, float timeStep, float angularDamping, b3Float4ConstArg gravityAcceleration)\n"
|
||||
"{\n"
|
||||
" float BT_GPU_ANGULAR_MOTION_THRESHOLD = (0.25f * 3.14159254f);\n"
|
||||
" \n"
|
||||
" if( (body->m_invMass != 0.f))\n"
|
||||
" {\n"
|
||||
" //angular velocity\n"
|
||||
" {\n"
|
||||
" b3Float4 axis;\n"
|
||||
" //add some hardcoded angular damping\n"
|
||||
" body->m_angVel.x *= angularDamping;\n"
|
||||
" body->m_angVel.y *= angularDamping;\n"
|
||||
" body->m_angVel.z *= angularDamping;\n"
|
||||
" \n"
|
||||
" b3Float4 angvel = body->m_angVel;\n"
|
||||
" float fAngle = b3Sqrt(b3Dot3F4(angvel, angvel));\n"
|
||||
" //limit the angular motion\n"
|
||||
" if(fAngle*timeStep > BT_GPU_ANGULAR_MOTION_THRESHOLD)\n"
|
||||
" {\n"
|
||||
" fAngle = BT_GPU_ANGULAR_MOTION_THRESHOLD / timeStep;\n"
|
||||
" }\n"
|
||||
" if(fAngle < 0.001f)\n"
|
||||
" {\n"
|
||||
" // use Taylor's expansions of sync function\n"
|
||||
" axis = angvel * (0.5f*timeStep-(timeStep*timeStep*timeStep)*0.020833333333f * fAngle * fAngle);\n"
|
||||
" }\n"
|
||||
" else\n"
|
||||
" {\n"
|
||||
" // sync(fAngle) = sin(c*fAngle)/t\n"
|
||||
" axis = angvel * ( b3Sin(0.5f * fAngle * timeStep) / fAngle);\n"
|
||||
" }\n"
|
||||
" b3Quat dorn;\n"
|
||||
" dorn.x = axis.x;\n"
|
||||
" dorn.y = axis.y;\n"
|
||||
" dorn.z = axis.z;\n"
|
||||
" dorn.w = b3Cos(fAngle * timeStep * 0.5f);\n"
|
||||
" b3Quat orn0 = body->m_quat;\n"
|
||||
" b3Quat predictedOrn = b3QuatMul(dorn, orn0);\n"
|
||||
" predictedOrn = b3QuatNormalized(predictedOrn);\n"
|
||||
" body->m_quat=predictedOrn;\n"
|
||||
" }\n"
|
||||
" //apply gravity\n"
|
||||
" body->m_linVel += gravityAcceleration * timeStep;\n"
|
||||
" //linear velocity \n"
|
||||
" body->m_pos += body->m_linVel * timeStep;\n"
|
||||
" \n"
|
||||
" }\n"
|
||||
" \n"
|
||||
"}\n"
|
||||
"__kernel void \n"
|
||||
" integrateTransformsKernel( __global b3RigidBodyData_t* bodies,const int numNodes, float timeStep, float angularDamping, float4 gravityAcceleration)\n"
|
||||
"{\n"
|
||||
" int nodeID = get_global_id(0);\n"
|
||||
" \n"
|
||||
" if( nodeID < numNodes)\n"
|
||||
" {\n"
|
||||
" integrateSingleTransform(bodies,nodeID, timeStep, angularDamping,gravityAcceleration);\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
;
|
||||
static const char* integrateKernelCL =
|
||||
"/*\n"
|
||||
"Copyright (c) 2013 Advanced Micro Devices, Inc. \n"
|
||||
"This software is provided 'as-is', without any express or implied warranty.\n"
|
||||
"In no event will the authors be held liable for any damages arising from the use of this software.\n"
|
||||
"Permission is granted to anyone to use this software for any purpose, \n"
|
||||
"including commercial applications, and to alter it and redistribute it freely, \n"
|
||||
"subject to the following restrictions:\n"
|
||||
"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.\n"
|
||||
"2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n"
|
||||
"3. This notice may not be removed or altered from any source distribution.\n"
|
||||
"*/\n"
|
||||
"//Originally written by Erwin Coumans\n"
|
||||
"#ifndef B3_RIGIDBODY_DATA_H\n"
|
||||
"#define B3_RIGIDBODY_DATA_H\n"
|
||||
"#ifndef B3_FLOAT4_H\n"
|
||||
"#define B3_FLOAT4_H\n"
|
||||
"#ifndef B3_PLATFORM_DEFINITIONS_H\n"
|
||||
"#define B3_PLATFORM_DEFINITIONS_H\n"
|
||||
"struct MyTest\n"
|
||||
"{\n"
|
||||
" int bla;\n"
|
||||
"};\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"//keep B3_LARGE_FLOAT*B3_LARGE_FLOAT < FLT_MAX\n"
|
||||
"#define B3_LARGE_FLOAT 1e18f\n"
|
||||
"#define B3_INFINITY 1e18f\n"
|
||||
"#define b3Assert(a)\n"
|
||||
"#define b3ConstArray(a) __global const a*\n"
|
||||
"#define b3AtomicInc atomic_inc\n"
|
||||
"#define b3AtomicAdd atomic_add\n"
|
||||
"#define b3Fabs fabs\n"
|
||||
"#define b3Sqrt native_sqrt\n"
|
||||
"#define b3Sin native_sin\n"
|
||||
"#define b3Cos native_cos\n"
|
||||
"#define B3_STATIC\n"
|
||||
"#endif\n"
|
||||
"#endif\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
" typedef float4 b3Float4;\n"
|
||||
" #define b3Float4ConstArg const b3Float4\n"
|
||||
" #define b3MakeFloat4 (float4)\n"
|
||||
" float b3Dot3F4(b3Float4ConstArg v0,b3Float4ConstArg v1)\n"
|
||||
" {\n"
|
||||
" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n"
|
||||
" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n"
|
||||
" return dot(a1, b1);\n"
|
||||
" }\n"
|
||||
" b3Float4 b3Cross3(b3Float4ConstArg v0,b3Float4ConstArg v1)\n"
|
||||
" {\n"
|
||||
" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n"
|
||||
" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n"
|
||||
" return cross(a1, b1);\n"
|
||||
" }\n"
|
||||
" #define b3MinFloat4 min\n"
|
||||
" #define b3MaxFloat4 max\n"
|
||||
" #define b3Normalized(a) normalize(a)\n"
|
||||
"#endif \n"
|
||||
" \n"
|
||||
"inline bool b3IsAlmostZero(b3Float4ConstArg v)\n"
|
||||
"{\n"
|
||||
" if(b3Fabs(v.x)>1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n"
|
||||
" return false;\n"
|
||||
" return true;\n"
|
||||
"}\n"
|
||||
"inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n"
|
||||
"{\n"
|
||||
" float maxDot = -B3_INFINITY;\n"
|
||||
" int i = 0;\n"
|
||||
" int ptIndex = -1;\n"
|
||||
" for( i = 0; i < vecLen; i++ )\n"
|
||||
" {\n"
|
||||
" float dot = b3Dot3F4(vecArray[i],vec);\n"
|
||||
" \n"
|
||||
" if( dot > maxDot )\n"
|
||||
" {\n"
|
||||
" maxDot = dot;\n"
|
||||
" ptIndex = i;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" b3Assert(ptIndex>=0);\n"
|
||||
" if (ptIndex<0)\n"
|
||||
" {\n"
|
||||
" ptIndex = 0;\n"
|
||||
" }\n"
|
||||
" *dotOut = maxDot;\n"
|
||||
" return ptIndex;\n"
|
||||
"}\n"
|
||||
"#endif //B3_FLOAT4_H\n"
|
||||
"#ifndef B3_QUAT_H\n"
|
||||
"#define B3_QUAT_H\n"
|
||||
"#ifndef B3_PLATFORM_DEFINITIONS_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"#endif\n"
|
||||
"#endif\n"
|
||||
"#ifndef B3_FLOAT4_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"#endif \n"
|
||||
"#endif //B3_FLOAT4_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
" typedef float4 b3Quat;\n"
|
||||
" #define b3QuatConstArg const b3Quat\n"
|
||||
" \n"
|
||||
" \n"
|
||||
"inline float4 b3FastNormalize4(float4 v)\n"
|
||||
"{\n"
|
||||
" v = (float4)(v.xyz,0.f);\n"
|
||||
" return fast_normalize(v);\n"
|
||||
"}\n"
|
||||
" \n"
|
||||
"inline b3Quat b3QuatMul(b3Quat a, b3Quat b);\n"
|
||||
"inline b3Quat b3QuatNormalized(b3QuatConstArg in);\n"
|
||||
"inline b3Quat b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec);\n"
|
||||
"inline b3Quat b3QuatInvert(b3QuatConstArg q);\n"
|
||||
"inline b3Quat b3QuatInverse(b3QuatConstArg q);\n"
|
||||
"inline b3Quat b3QuatMul(b3QuatConstArg a, b3QuatConstArg b)\n"
|
||||
"{\n"
|
||||
" b3Quat ans;\n"
|
||||
" ans = b3Cross3( a, b );\n"
|
||||
" ans += a.w*b+b.w*a;\n"
|
||||
"// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n"
|
||||
" ans.w = a.w*b.w - b3Dot3F4(a, b);\n"
|
||||
" return ans;\n"
|
||||
"}\n"
|
||||
"inline b3Quat b3QuatNormalized(b3QuatConstArg in)\n"
|
||||
"{\n"
|
||||
" b3Quat q;\n"
|
||||
" q=in;\n"
|
||||
" //return b3FastNormalize4(in);\n"
|
||||
" float len = native_sqrt(dot(q, q));\n"
|
||||
" if(len > 0.f)\n"
|
||||
" {\n"
|
||||
" q *= 1.f / len;\n"
|
||||
" }\n"
|
||||
" else\n"
|
||||
" {\n"
|
||||
" q.x = q.y = q.z = 0.f;\n"
|
||||
" q.w = 1.f;\n"
|
||||
" }\n"
|
||||
" return q;\n"
|
||||
"}\n"
|
||||
"inline float4 b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec)\n"
|
||||
"{\n"
|
||||
" b3Quat qInv = b3QuatInvert( q );\n"
|
||||
" float4 vcpy = vec;\n"
|
||||
" vcpy.w = 0.f;\n"
|
||||
" float4 out = b3QuatMul(b3QuatMul(q,vcpy),qInv);\n"
|
||||
" return out;\n"
|
||||
"}\n"
|
||||
"inline b3Quat b3QuatInverse(b3QuatConstArg q)\n"
|
||||
"{\n"
|
||||
" return (b3Quat)(-q.xyz, q.w);\n"
|
||||
"}\n"
|
||||
"inline b3Quat b3QuatInvert(b3QuatConstArg q)\n"
|
||||
"{\n"
|
||||
" return (b3Quat)(-q.xyz, q.w);\n"
|
||||
"}\n"
|
||||
"inline float4 b3QuatInvRotate(b3QuatConstArg q, b3QuatConstArg vec)\n"
|
||||
"{\n"
|
||||
" return b3QuatRotate( b3QuatInvert( q ), vec );\n"
|
||||
"}\n"
|
||||
"inline b3Float4 b3TransformPoint(b3Float4ConstArg point, b3Float4ConstArg translation, b3QuatConstArg orientation)\n"
|
||||
"{\n"
|
||||
" return b3QuatRotate( orientation, point ) + (translation);\n"
|
||||
"}\n"
|
||||
" \n"
|
||||
"#endif \n"
|
||||
"#endif //B3_QUAT_H\n"
|
||||
"#ifndef B3_MAT3x3_H\n"
|
||||
"#define B3_MAT3x3_H\n"
|
||||
"#ifndef B3_QUAT_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"#endif \n"
|
||||
"#endif //B3_QUAT_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" b3Float4 m_row[3];\n"
|
||||
"}b3Mat3x3;\n"
|
||||
"#define b3Mat3x3ConstArg const b3Mat3x3\n"
|
||||
"#define b3GetRow(m,row) (m.m_row[row])\n"
|
||||
"inline b3Mat3x3 b3QuatGetRotationMatrix(b3Quat quat)\n"
|
||||
"{\n"
|
||||
" b3Float4 quat2 = (b3Float4)(quat.x*quat.x, quat.y*quat.y, quat.z*quat.z, 0.f);\n"
|
||||
" b3Mat3x3 out;\n"
|
||||
" out.m_row[0].x=1-2*quat2.y-2*quat2.z;\n"
|
||||
" out.m_row[0].y=2*quat.x*quat.y-2*quat.w*quat.z;\n"
|
||||
" out.m_row[0].z=2*quat.x*quat.z+2*quat.w*quat.y;\n"
|
||||
" out.m_row[0].w = 0.f;\n"
|
||||
" out.m_row[1].x=2*quat.x*quat.y+2*quat.w*quat.z;\n"
|
||||
" out.m_row[1].y=1-2*quat2.x-2*quat2.z;\n"
|
||||
" out.m_row[1].z=2*quat.y*quat.z-2*quat.w*quat.x;\n"
|
||||
" out.m_row[1].w = 0.f;\n"
|
||||
" out.m_row[2].x=2*quat.x*quat.z-2*quat.w*quat.y;\n"
|
||||
" out.m_row[2].y=2*quat.y*quat.z+2*quat.w*quat.x;\n"
|
||||
" out.m_row[2].z=1-2*quat2.x-2*quat2.y;\n"
|
||||
" out.m_row[2].w = 0.f;\n"
|
||||
" return out;\n"
|
||||
"}\n"
|
||||
"inline b3Mat3x3 b3AbsoluteMat3x3(b3Mat3x3ConstArg matIn)\n"
|
||||
"{\n"
|
||||
" b3Mat3x3 out;\n"
|
||||
" out.m_row[0] = fabs(matIn.m_row[0]);\n"
|
||||
" out.m_row[1] = fabs(matIn.m_row[1]);\n"
|
||||
" out.m_row[2] = fabs(matIn.m_row[2]);\n"
|
||||
" return out;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtZero();\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtIdentity();\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtTranspose(b3Mat3x3 m);\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b);\n"
|
||||
"__inline\n"
|
||||
"b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b);\n"
|
||||
"__inline\n"
|
||||
"b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b);\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtZero()\n"
|
||||
"{\n"
|
||||
" b3Mat3x3 m;\n"
|
||||
" m.m_row[0] = (b3Float4)(0.f);\n"
|
||||
" m.m_row[1] = (b3Float4)(0.f);\n"
|
||||
" m.m_row[2] = (b3Float4)(0.f);\n"
|
||||
" return m;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtIdentity()\n"
|
||||
"{\n"
|
||||
" b3Mat3x3 m;\n"
|
||||
" m.m_row[0] = (b3Float4)(1,0,0,0);\n"
|
||||
" m.m_row[1] = (b3Float4)(0,1,0,0);\n"
|
||||
" m.m_row[2] = (b3Float4)(0,0,1,0);\n"
|
||||
" return m;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtTranspose(b3Mat3x3 m)\n"
|
||||
"{\n"
|
||||
" b3Mat3x3 out;\n"
|
||||
" out.m_row[0] = (b3Float4)(m.m_row[0].x, m.m_row[1].x, m.m_row[2].x, 0.f);\n"
|
||||
" out.m_row[1] = (b3Float4)(m.m_row[0].y, m.m_row[1].y, m.m_row[2].y, 0.f);\n"
|
||||
" out.m_row[2] = (b3Float4)(m.m_row[0].z, m.m_row[1].z, m.m_row[2].z, 0.f);\n"
|
||||
" return out;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b)\n"
|
||||
"{\n"
|
||||
" b3Mat3x3 transB;\n"
|
||||
" transB = mtTranspose( b );\n"
|
||||
" b3Mat3x3 ans;\n"
|
||||
" // why this doesn't run when 0ing in the for{}\n"
|
||||
" a.m_row[0].w = 0.f;\n"
|
||||
" a.m_row[1].w = 0.f;\n"
|
||||
" a.m_row[2].w = 0.f;\n"
|
||||
" for(int i=0; i<3; i++)\n"
|
||||
" {\n"
|
||||
"// a.m_row[i].w = 0.f;\n"
|
||||
" ans.m_row[i].x = b3Dot3F4(a.m_row[i],transB.m_row[0]);\n"
|
||||
" ans.m_row[i].y = b3Dot3F4(a.m_row[i],transB.m_row[1]);\n"
|
||||
" ans.m_row[i].z = b3Dot3F4(a.m_row[i],transB.m_row[2]);\n"
|
||||
" ans.m_row[i].w = 0.f;\n"
|
||||
" }\n"
|
||||
" return ans;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b)\n"
|
||||
"{\n"
|
||||
" b3Float4 ans;\n"
|
||||
" ans.x = b3Dot3F4( a.m_row[0], b );\n"
|
||||
" ans.y = b3Dot3F4( a.m_row[1], b );\n"
|
||||
" ans.z = b3Dot3F4( a.m_row[2], b );\n"
|
||||
" ans.w = 0.f;\n"
|
||||
" return ans;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b)\n"
|
||||
"{\n"
|
||||
" b3Float4 colx = b3MakeFloat4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n"
|
||||
" b3Float4 coly = b3MakeFloat4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n"
|
||||
" b3Float4 colz = b3MakeFloat4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n"
|
||||
" b3Float4 ans;\n"
|
||||
" ans.x = b3Dot3F4( a, colx );\n"
|
||||
" ans.y = b3Dot3F4( a, coly );\n"
|
||||
" ans.z = b3Dot3F4( a, colz );\n"
|
||||
" return ans;\n"
|
||||
"}\n"
|
||||
"#endif\n"
|
||||
"#endif //B3_MAT3x3_H\n"
|
||||
"typedef struct b3RigidBodyData b3RigidBodyData_t;\n"
|
||||
"struct b3RigidBodyData\n"
|
||||
"{\n"
|
||||
" b3Float4 m_pos;\n"
|
||||
" b3Quat m_quat;\n"
|
||||
" b3Float4 m_linVel;\n"
|
||||
" b3Float4 m_angVel;\n"
|
||||
" int m_collidableIdx;\n"
|
||||
" float m_invMass;\n"
|
||||
" float m_restituitionCoeff;\n"
|
||||
" float m_frictionCoeff;\n"
|
||||
"};\n"
|
||||
"typedef struct b3InertiaData b3InertiaData_t;\n"
|
||||
"struct b3InertiaData\n"
|
||||
"{\n"
|
||||
" b3Mat3x3 m_invInertiaWorld;\n"
|
||||
" b3Mat3x3 m_initInvInertia;\n"
|
||||
"};\n"
|
||||
"#endif //B3_RIGIDBODY_DATA_H\n"
|
||||
" \n"
|
||||
"#ifndef B3_RIGIDBODY_DATA_H\n"
|
||||
"#endif //B3_RIGIDBODY_DATA_H\n"
|
||||
" \n"
|
||||
"inline void integrateSingleTransform( __global b3RigidBodyData_t* bodies,int nodeID, float timeStep, float angularDamping, b3Float4ConstArg gravityAcceleration)\n"
|
||||
"{\n"
|
||||
" \n"
|
||||
" if (bodies[nodeID].m_invMass != 0.f)\n"
|
||||
" {\n"
|
||||
" float BT_GPU_ANGULAR_MOTION_THRESHOLD = (0.25f * 3.14159254f);\n"
|
||||
" //angular velocity\n"
|
||||
" {\n"
|
||||
" b3Float4 axis;\n"
|
||||
" //add some hardcoded angular damping\n"
|
||||
" bodies[nodeID].m_angVel.x *= angularDamping;\n"
|
||||
" bodies[nodeID].m_angVel.y *= angularDamping;\n"
|
||||
" bodies[nodeID].m_angVel.z *= angularDamping;\n"
|
||||
" \n"
|
||||
" b3Float4 angvel = bodies[nodeID].m_angVel;\n"
|
||||
" float fAngle = b3Sqrt(b3Dot3F4(angvel, angvel));\n"
|
||||
" \n"
|
||||
" //limit the angular motion\n"
|
||||
" if(fAngle*timeStep > BT_GPU_ANGULAR_MOTION_THRESHOLD)\n"
|
||||
" {\n"
|
||||
" fAngle = BT_GPU_ANGULAR_MOTION_THRESHOLD / timeStep;\n"
|
||||
" }\n"
|
||||
" if(fAngle < 0.001f)\n"
|
||||
" {\n"
|
||||
" // use Taylor's expansions of sync function\n"
|
||||
" axis = angvel * (0.5f*timeStep-(timeStep*timeStep*timeStep)*0.020833333333f * fAngle * fAngle);\n"
|
||||
" }\n"
|
||||
" else\n"
|
||||
" {\n"
|
||||
" // sync(fAngle) = sin(c*fAngle)/t\n"
|
||||
" axis = angvel * ( b3Sin(0.5f * fAngle * timeStep) / fAngle);\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" b3Quat dorn;\n"
|
||||
" dorn.x = axis.x;\n"
|
||||
" dorn.y = axis.y;\n"
|
||||
" dorn.z = axis.z;\n"
|
||||
" dorn.w = b3Cos(fAngle * timeStep * 0.5f);\n"
|
||||
" b3Quat orn0 = bodies[nodeID].m_quat;\n"
|
||||
" b3Quat predictedOrn = b3QuatMul(dorn, orn0);\n"
|
||||
" predictedOrn = b3QuatNormalized(predictedOrn);\n"
|
||||
" bodies[nodeID].m_quat=predictedOrn;\n"
|
||||
" }\n"
|
||||
" //linear velocity \n"
|
||||
" bodies[nodeID].m_pos += bodies[nodeID].m_linVel * timeStep;\n"
|
||||
" \n"
|
||||
" //apply gravity\n"
|
||||
" bodies[nodeID].m_linVel += gravityAcceleration * timeStep;\n"
|
||||
" \n"
|
||||
" }\n"
|
||||
" \n"
|
||||
"}\n"
|
||||
"inline void b3IntegrateTransform( __global b3RigidBodyData_t* body, float timeStep, float angularDamping, b3Float4ConstArg gravityAcceleration)\n"
|
||||
"{\n"
|
||||
" float BT_GPU_ANGULAR_MOTION_THRESHOLD = (0.25f * 3.14159254f);\n"
|
||||
" \n"
|
||||
" if( (body->m_invMass != 0.f))\n"
|
||||
" {\n"
|
||||
" //angular velocity\n"
|
||||
" {\n"
|
||||
" b3Float4 axis;\n"
|
||||
" //add some hardcoded angular damping\n"
|
||||
" body->m_angVel.x *= angularDamping;\n"
|
||||
" body->m_angVel.y *= angularDamping;\n"
|
||||
" body->m_angVel.z *= angularDamping;\n"
|
||||
" \n"
|
||||
" b3Float4 angvel = body->m_angVel;\n"
|
||||
" float fAngle = b3Sqrt(b3Dot3F4(angvel, angvel));\n"
|
||||
" //limit the angular motion\n"
|
||||
" if(fAngle*timeStep > BT_GPU_ANGULAR_MOTION_THRESHOLD)\n"
|
||||
" {\n"
|
||||
" fAngle = BT_GPU_ANGULAR_MOTION_THRESHOLD / timeStep;\n"
|
||||
" }\n"
|
||||
" if(fAngle < 0.001f)\n"
|
||||
" {\n"
|
||||
" // use Taylor's expansions of sync function\n"
|
||||
" axis = angvel * (0.5f*timeStep-(timeStep*timeStep*timeStep)*0.020833333333f * fAngle * fAngle);\n"
|
||||
" }\n"
|
||||
" else\n"
|
||||
" {\n"
|
||||
" // sync(fAngle) = sin(c*fAngle)/t\n"
|
||||
" axis = angvel * ( b3Sin(0.5f * fAngle * timeStep) / fAngle);\n"
|
||||
" }\n"
|
||||
" b3Quat dorn;\n"
|
||||
" dorn.x = axis.x;\n"
|
||||
" dorn.y = axis.y;\n"
|
||||
" dorn.z = axis.z;\n"
|
||||
" dorn.w = b3Cos(fAngle * timeStep * 0.5f);\n"
|
||||
" b3Quat orn0 = body->m_quat;\n"
|
||||
" b3Quat predictedOrn = b3QuatMul(dorn, orn0);\n"
|
||||
" predictedOrn = b3QuatNormalized(predictedOrn);\n"
|
||||
" body->m_quat=predictedOrn;\n"
|
||||
" }\n"
|
||||
" //apply gravity\n"
|
||||
" body->m_linVel += gravityAcceleration * timeStep;\n"
|
||||
" //linear velocity \n"
|
||||
" body->m_pos += body->m_linVel * timeStep;\n"
|
||||
" \n"
|
||||
" }\n"
|
||||
" \n"
|
||||
"}\n"
|
||||
"__kernel void \n"
|
||||
" integrateTransformsKernel( __global b3RigidBodyData_t* bodies,const int numNodes, float timeStep, float angularDamping, float4 gravityAcceleration)\n"
|
||||
"{\n"
|
||||
" int nodeID = get_global_id(0);\n"
|
||||
" \n"
|
||||
" if( nodeID < numNodes)\n"
|
||||
" {\n"
|
||||
" integrateSingleTransform(bodies,nodeID, timeStep, angularDamping,gravityAcceleration);\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,393 +1,392 @@
|
||||
//this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project
|
||||
static const char* solveContactCL= \
|
||||
"/*\n"
|
||||
"Copyright (c) 2012 Advanced Micro Devices, Inc. \n"
|
||||
"This software is provided 'as-is', without any express or implied warranty.\n"
|
||||
"In no event will the authors be held liable for any damages arising from the use of this software.\n"
|
||||
"Permission is granted to anyone to use this software for any purpose, \n"
|
||||
"including commercial applications, and to alter it and redistribute it freely, \n"
|
||||
"subject to the following restrictions:\n"
|
||||
"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.\n"
|
||||
"2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n"
|
||||
"3. This notice may not be removed or altered from any source distribution.\n"
|
||||
"*/\n"
|
||||
"//Originally written by Takahiro Harada\n"
|
||||
"//#pragma OPENCL EXTENSION cl_amd_printf : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable\n"
|
||||
"#ifdef cl_ext_atomic_counters_32\n"
|
||||
"#pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable\n"
|
||||
"#else\n"
|
||||
"#define counter32_t volatile global int*\n"
|
||||
"#endif\n"
|
||||
"typedef unsigned int u32;\n"
|
||||
"typedef unsigned short u16;\n"
|
||||
"typedef unsigned char u8;\n"
|
||||
"#define GET_GROUP_IDX get_group_id(0)\n"
|
||||
"#define GET_LOCAL_IDX get_local_id(0)\n"
|
||||
"#define GET_GLOBAL_IDX get_global_id(0)\n"
|
||||
"#define GET_GROUP_SIZE get_local_size(0)\n"
|
||||
"#define GET_NUM_GROUPS get_num_groups(0)\n"
|
||||
"#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n"
|
||||
"#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n"
|
||||
"#define AtomInc(x) atom_inc(&(x))\n"
|
||||
"#define AtomInc1(x, out) out = atom_inc(&(x))\n"
|
||||
"#define AppendInc(x, out) out = atomic_inc(x)\n"
|
||||
"#define AtomAdd(x, value) atom_add(&(x), value)\n"
|
||||
"#define AtomCmpxhg(x, cmp, value) atom_cmpxchg( &(x), cmp, value )\n"
|
||||
"#define AtomXhg(x, value) atom_xchg ( &(x), value )\n"
|
||||
"#define SELECT_UINT4( b, a, condition ) select( b,a,condition )\n"
|
||||
"#define mymake_float4 (float4)\n"
|
||||
"//#define make_float2 (float2)\n"
|
||||
"//#define make_uint4 (uint4)\n"
|
||||
"//#define make_int4 (int4)\n"
|
||||
"//#define make_uint2 (uint2)\n"
|
||||
"//#define make_int2 (int2)\n"
|
||||
"#define max2 max\n"
|
||||
"#define min2 min\n"
|
||||
"///////////////////////////////////////\n"
|
||||
"// Vector\n"
|
||||
"///////////////////////////////////////\n"
|
||||
"__inline\n"
|
||||
"float4 fastNormalize4(float4 v)\n"
|
||||
"{\n"
|
||||
" return fast_normalize(v);\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"float4 cross3(float4 a, float4 b)\n"
|
||||
"{\n"
|
||||
" return cross(a,b);\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"float dot3F4(float4 a, float4 b)\n"
|
||||
"{\n"
|
||||
" float4 a1 = mymake_float4(a.xyz,0.f);\n"
|
||||
" float4 b1 = mymake_float4(b.xyz,0.f);\n"
|
||||
" return dot(a1, b1);\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"float4 normalize3(const float4 a)\n"
|
||||
"{\n"
|
||||
" float4 n = mymake_float4(a.x, a.y, a.z, 0.f);\n"
|
||||
" return fastNormalize4( n );\n"
|
||||
"// float length = sqrtf(dot3F4(a, a));\n"
|
||||
"// return 1.f/length * a;\n"
|
||||
"}\n"
|
||||
"///////////////////////////////////////\n"
|
||||
"// Matrix3x3\n"
|
||||
"///////////////////////////////////////\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" float4 m_row[3];\n"
|
||||
"}Matrix3x3;\n"
|
||||
"__inline\n"
|
||||
"float4 mtMul1(Matrix3x3 a, float4 b);\n"
|
||||
"__inline\n"
|
||||
"float4 mtMul3(float4 a, Matrix3x3 b);\n"
|
||||
"__inline\n"
|
||||
"float4 mtMul1(Matrix3x3 a, float4 b)\n"
|
||||
"{\n"
|
||||
" float4 ans;\n"
|
||||
" ans.x = dot3F4( a.m_row[0], b );\n"
|
||||
" ans.y = dot3F4( a.m_row[1], b );\n"
|
||||
" ans.z = dot3F4( a.m_row[2], b );\n"
|
||||
" ans.w = 0.f;\n"
|
||||
" return ans;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"float4 mtMul3(float4 a, Matrix3x3 b)\n"
|
||||
"{\n"
|
||||
" float4 colx = mymake_float4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n"
|
||||
" float4 coly = mymake_float4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n"
|
||||
" float4 colz = mymake_float4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n"
|
||||
" float4 ans;\n"
|
||||
" ans.x = dot3F4( a, colx );\n"
|
||||
" ans.y = dot3F4( a, coly );\n"
|
||||
" ans.z = dot3F4( a, colz );\n"
|
||||
" return ans;\n"
|
||||
"}\n"
|
||||
"///////////////////////////////////////\n"
|
||||
"// Quaternion\n"
|
||||
"///////////////////////////////////////\n"
|
||||
"typedef float4 Quaternion;\n"
|
||||
"#define WG_SIZE 64\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" float4 m_pos;\n"
|
||||
" Quaternion m_quat;\n"
|
||||
" float4 m_linVel;\n"
|
||||
" float4 m_angVel;\n"
|
||||
" u32 m_shapeIdx;\n"
|
||||
" float m_invMass;\n"
|
||||
" float m_restituitionCoeff;\n"
|
||||
" float m_frictionCoeff;\n"
|
||||
"} Body;\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" Matrix3x3 m_invInertia;\n"
|
||||
" Matrix3x3 m_initInvInertia;\n"
|
||||
"} Shape;\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" float4 m_linear;\n"
|
||||
" float4 m_worldPos[4];\n"
|
||||
" float4 m_center; \n"
|
||||
" float m_jacCoeffInv[4];\n"
|
||||
" float m_b[4];\n"
|
||||
" float m_appliedRambdaDt[4];\n"
|
||||
" float m_fJacCoeffInv[2]; \n"
|
||||
" float m_fAppliedRambdaDt[2]; \n"
|
||||
" u32 m_bodyA;\n"
|
||||
" u32 m_bodyB;\n"
|
||||
" int m_batchIdx;\n"
|
||||
" u32 m_paddings[1];\n"
|
||||
"} Constraint4;\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" int m_nConstraints;\n"
|
||||
" int m_start;\n"
|
||||
" int m_batchIdx;\n"
|
||||
" int m_nSplit;\n"
|
||||
"// int m_paddings[1];\n"
|
||||
"} ConstBuffer;\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" int m_solveFriction;\n"
|
||||
" int m_maxBatch; // long batch really kills the performance\n"
|
||||
" int m_batchIdx;\n"
|
||||
" int m_nSplit;\n"
|
||||
"// int m_paddings[1];\n"
|
||||
"} ConstBufferBatchSolve;\n"
|
||||
"void setLinearAndAngular( float4 n, float4 r0, float4 r1, float4* linear, float4* angular0, float4* angular1);\n"
|
||||
"void setLinearAndAngular( float4 n, float4 r0, float4 r1, float4* linear, float4* angular0, float4* angular1)\n"
|
||||
"{\n"
|
||||
" *linear = mymake_float4(-n.xyz,0.f);\n"
|
||||
" *angular0 = -cross3(r0, n);\n"
|
||||
" *angular1 = cross3(r1, n);\n"
|
||||
"}\n"
|
||||
"float calcRelVel( float4 l0, float4 l1, float4 a0, float4 a1, float4 linVel0, float4 angVel0, float4 linVel1, float4 angVel1 );\n"
|
||||
"float calcRelVel( float4 l0, float4 l1, float4 a0, float4 a1, float4 linVel0, float4 angVel0, float4 linVel1, float4 angVel1 )\n"
|
||||
"{\n"
|
||||
" return dot3F4(l0, linVel0) + dot3F4(a0, angVel0) + dot3F4(l1, linVel1) + dot3F4(a1, angVel1);\n"
|
||||
"}\n"
|
||||
"float calcJacCoeff(const float4 linear0, const float4 linear1, const float4 angular0, const float4 angular1,\n"
|
||||
" float invMass0, const Matrix3x3* invInertia0, float invMass1, const Matrix3x3* invInertia1);\n"
|
||||
"float calcJacCoeff(const float4 linear0, const float4 linear1, const float4 angular0, const float4 angular1,\n"
|
||||
" float invMass0, const Matrix3x3* invInertia0, float invMass1, const Matrix3x3* invInertia1)\n"
|
||||
"{\n"
|
||||
" // linear0,1 are normlized\n"
|
||||
" float jmj0 = invMass0;//dot3F4(linear0, linear0)*invMass0;\n"
|
||||
" float jmj1 = dot3F4(mtMul3(angular0,*invInertia0), angular0);\n"
|
||||
" float jmj2 = invMass1;//dot3F4(linear1, linear1)*invMass1;\n"
|
||||
" float jmj3 = dot3F4(mtMul3(angular1,*invInertia1), angular1);\n"
|
||||
" return -1.f/(jmj0+jmj1+jmj2+jmj3);\n"
|
||||
"}\n"
|
||||
"void solveContact(__global Constraint4* cs,\n"
|
||||
" float4 posA, float4* linVelA, float4* angVelA, float invMassA, Matrix3x3 invInertiaA,\n"
|
||||
" float4 posB, float4* linVelB, float4* angVelB, float invMassB, Matrix3x3 invInertiaB);\n"
|
||||
"void solveContact(__global Constraint4* cs,\n"
|
||||
" float4 posA, float4* linVelA, float4* angVelA, float invMassA, Matrix3x3 invInertiaA,\n"
|
||||
" float4 posB, float4* linVelB, float4* angVelB, float invMassB, Matrix3x3 invInertiaB)\n"
|
||||
"{\n"
|
||||
" float minRambdaDt = 0;\n"
|
||||
" float maxRambdaDt = FLT_MAX;\n"
|
||||
" for(int ic=0; ic<4; ic++)\n"
|
||||
" {\n"
|
||||
" if( cs->m_jacCoeffInv[ic] == 0.f ) continue;\n"
|
||||
" float4 angular0, angular1, linear;\n"
|
||||
" float4 r0 = cs->m_worldPos[ic] - posA;\n"
|
||||
" float4 r1 = cs->m_worldPos[ic] - posB;\n"
|
||||
" setLinearAndAngular( -cs->m_linear, r0, r1, &linear, &angular0, &angular1 );\n"
|
||||
" float rambdaDt = calcRelVel( cs->m_linear, -cs->m_linear, angular0, angular1, \n"
|
||||
" *linVelA, *angVelA, *linVelB, *angVelB ) + cs->m_b[ic];\n"
|
||||
" rambdaDt *= cs->m_jacCoeffInv[ic];\n"
|
||||
" {\n"
|
||||
" float prevSum = cs->m_appliedRambdaDt[ic];\n"
|
||||
" float updated = prevSum;\n"
|
||||
" updated += rambdaDt;\n"
|
||||
" updated = max2( updated, minRambdaDt );\n"
|
||||
" updated = min2( updated, maxRambdaDt );\n"
|
||||
" rambdaDt = updated - prevSum;\n"
|
||||
" cs->m_appliedRambdaDt[ic] = updated;\n"
|
||||
" }\n"
|
||||
" float4 linImp0 = invMassA*linear*rambdaDt;\n"
|
||||
" float4 linImp1 = invMassB*(-linear)*rambdaDt;\n"
|
||||
" float4 angImp0 = mtMul1(invInertiaA, angular0)*rambdaDt;\n"
|
||||
" float4 angImp1 = mtMul1(invInertiaB, angular1)*rambdaDt;\n"
|
||||
" *linVelA += linImp0;\n"
|
||||
" *angVelA += angImp0;\n"
|
||||
" *linVelB += linImp1;\n"
|
||||
" *angVelB += angImp1;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"void btPlaneSpace1 (const float4* n, float4* p, float4* q);\n"
|
||||
" void btPlaneSpace1 (const float4* n, float4* p, float4* q)\n"
|
||||
"{\n"
|
||||
" if (fabs(n[0].z) > 0.70710678f) {\n"
|
||||
" // choose p in y-z plane\n"
|
||||
" float a = n[0].y*n[0].y + n[0].z*n[0].z;\n"
|
||||
" float k = 1.f/sqrt(a);\n"
|
||||
" p[0].x = 0;\n"
|
||||
" p[0].y = -n[0].z*k;\n"
|
||||
" p[0].z = n[0].y*k;\n"
|
||||
" // set q = n x p\n"
|
||||
" q[0].x = a*k;\n"
|
||||
" q[0].y = -n[0].x*p[0].z;\n"
|
||||
" q[0].z = n[0].x*p[0].y;\n"
|
||||
" }\n"
|
||||
" else {\n"
|
||||
" // choose p in x-y plane\n"
|
||||
" float a = n[0].x*n[0].x + n[0].y*n[0].y;\n"
|
||||
" float k = 1.f/sqrt(a);\n"
|
||||
" p[0].x = -n[0].y*k;\n"
|
||||
" p[0].y = n[0].x*k;\n"
|
||||
" p[0].z = 0;\n"
|
||||
" // set q = n x p\n"
|
||||
" q[0].x = -n[0].z*p[0].y;\n"
|
||||
" q[0].y = n[0].z*p[0].x;\n"
|
||||
" q[0].z = a*k;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"void solveContactConstraint(__global Body* gBodies, __global Shape* gShapes, __global Constraint4* ldsCs);\n"
|
||||
"void solveContactConstraint(__global Body* gBodies, __global Shape* gShapes, __global Constraint4* ldsCs)\n"
|
||||
"{\n"
|
||||
" //float frictionCoeff = ldsCs[0].m_linear.w;\n"
|
||||
" int aIdx = ldsCs[0].m_bodyA;\n"
|
||||
" int bIdx = ldsCs[0].m_bodyB;\n"
|
||||
" float4 posA = gBodies[aIdx].m_pos;\n"
|
||||
" float4 linVelA = gBodies[aIdx].m_linVel;\n"
|
||||
" float4 angVelA = gBodies[aIdx].m_angVel;\n"
|
||||
" float invMassA = gBodies[aIdx].m_invMass;\n"
|
||||
" Matrix3x3 invInertiaA = gShapes[aIdx].m_invInertia;\n"
|
||||
" float4 posB = gBodies[bIdx].m_pos;\n"
|
||||
" float4 linVelB = gBodies[bIdx].m_linVel;\n"
|
||||
" float4 angVelB = gBodies[bIdx].m_angVel;\n"
|
||||
" float invMassB = gBodies[bIdx].m_invMass;\n"
|
||||
" Matrix3x3 invInertiaB = gShapes[bIdx].m_invInertia;\n"
|
||||
" solveContact( ldsCs, posA, &linVelA, &angVelA, invMassA, invInertiaA,\n"
|
||||
" posB, &linVelB, &angVelB, invMassB, invInertiaB );\n"
|
||||
" if (gBodies[aIdx].m_invMass)\n"
|
||||
" {\n"
|
||||
" gBodies[aIdx].m_linVel = linVelA;\n"
|
||||
" gBodies[aIdx].m_angVel = angVelA;\n"
|
||||
" } else\n"
|
||||
" {\n"
|
||||
" gBodies[aIdx].m_linVel = mymake_float4(0,0,0,0);\n"
|
||||
" gBodies[aIdx].m_angVel = mymake_float4(0,0,0,0);\n"
|
||||
" \n"
|
||||
" }\n"
|
||||
" if (gBodies[bIdx].m_invMass)\n"
|
||||
" {\n"
|
||||
" gBodies[bIdx].m_linVel = linVelB;\n"
|
||||
" gBodies[bIdx].m_angVel = angVelB;\n"
|
||||
" } else\n"
|
||||
" {\n"
|
||||
" gBodies[bIdx].m_linVel = mymake_float4(0,0,0,0);\n"
|
||||
" gBodies[bIdx].m_angVel = mymake_float4(0,0,0,0);\n"
|
||||
" \n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"typedef struct \n"
|
||||
"{\n"
|
||||
" int m_valInt0;\n"
|
||||
" int m_valInt1;\n"
|
||||
" int m_valInt2;\n"
|
||||
" int m_valInt3;\n"
|
||||
" float m_val0;\n"
|
||||
" float m_val1;\n"
|
||||
" float m_val2;\n"
|
||||
" float m_val3;\n"
|
||||
"} SolverDebugInfo;\n"
|
||||
"__kernel\n"
|
||||
"__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n"
|
||||
"void BatchSolveKernelContact(__global Body* gBodies,\n"
|
||||
" __global Shape* gShapes,\n"
|
||||
" __global Constraint4* gConstraints,\n"
|
||||
" __global int* gN,\n"
|
||||
" __global int* gOffsets,\n"
|
||||
" __global int* batchSizes,\n"
|
||||
" int maxBatch1,\n"
|
||||
" int cellBatch,\n"
|
||||
" int4 nSplit\n"
|
||||
" )\n"
|
||||
"{\n"
|
||||
" //__local int ldsBatchIdx[WG_SIZE+1];\n"
|
||||
" __local int ldsCurBatch;\n"
|
||||
" __local int ldsNextBatch;\n"
|
||||
" __local int ldsStart;\n"
|
||||
" int lIdx = GET_LOCAL_IDX;\n"
|
||||
" int wgIdx = GET_GROUP_IDX;\n"
|
||||
"// int gIdx = GET_GLOBAL_IDX;\n"
|
||||
"// debugInfo[gIdx].m_valInt0 = gIdx;\n"
|
||||
" //debugInfo[gIdx].m_valInt1 = GET_GROUP_SIZE;\n"
|
||||
" \n"
|
||||
" \n"
|
||||
" int zIdx = (wgIdx/((nSplit.x*nSplit.y)/4))*2+((cellBatch&4)>>2);\n"
|
||||
" int remain= (wgIdx%((nSplit.x*nSplit.y)/4));\n"
|
||||
" int yIdx = (remain/(nSplit.x/2))*2 + ((cellBatch&2)>>1);\n"
|
||||
" int xIdx = (remain%(nSplit.x/2))*2 + (cellBatch&1);\n"
|
||||
" int cellIdx = xIdx+yIdx*nSplit.x+zIdx*(nSplit.x*nSplit.y);\n"
|
||||
" //int xIdx = (wgIdx/(nSplit/2))*2 + (bIdx&1);\n"
|
||||
" //int yIdx = (wgIdx%(nSplit/2))*2 + (bIdx>>1);\n"
|
||||
" //int cellIdx = xIdx+yIdx*nSplit;\n"
|
||||
" \n"
|
||||
" if( gN[cellIdx] == 0 ) \n"
|
||||
" return;\n"
|
||||
" int maxBatch = batchSizes[cellIdx];\n"
|
||||
" \n"
|
||||
" \n"
|
||||
" const int start = gOffsets[cellIdx];\n"
|
||||
" const int end = start + gN[cellIdx];\n"
|
||||
" \n"
|
||||
" \n"
|
||||
" \n"
|
||||
" if( lIdx == 0 )\n"
|
||||
" {\n"
|
||||
" ldsCurBatch = 0;\n"
|
||||
" ldsNextBatch = 0;\n"
|
||||
" ldsStart = start;\n"
|
||||
" }\n"
|
||||
" GROUP_LDS_BARRIER;\n"
|
||||
" int idx=ldsStart+lIdx;\n"
|
||||
" while (ldsCurBatch < maxBatch)\n"
|
||||
" {\n"
|
||||
" for(; idx<end; )\n"
|
||||
" {\n"
|
||||
" if (gConstraints[idx].m_batchIdx == ldsCurBatch)\n"
|
||||
" {\n"
|
||||
" solveContactConstraint( gBodies, gShapes, &gConstraints[idx] );\n"
|
||||
" idx+=64;\n"
|
||||
" } else\n"
|
||||
" {\n"
|
||||
" break;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" GROUP_LDS_BARRIER;\n"
|
||||
" \n"
|
||||
" if( lIdx == 0 )\n"
|
||||
" {\n"
|
||||
" ldsCurBatch++;\n"
|
||||
" }\n"
|
||||
" GROUP_LDS_BARRIER;\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" \n"
|
||||
"}\n"
|
||||
"__kernel void solveSingleContactKernel(__global Body* gBodies,\n"
|
||||
" __global Shape* gShapes,\n"
|
||||
" __global Constraint4* gConstraints,\n"
|
||||
" int cellIdx,\n"
|
||||
" int batchOffset,\n"
|
||||
" int numConstraintsInBatch\n"
|
||||
" )\n"
|
||||
"{\n"
|
||||
" int index = get_global_id(0);\n"
|
||||
" if (index < numConstraintsInBatch)\n"
|
||||
" {\n"
|
||||
" int idx=batchOffset+index;\n"
|
||||
" solveContactConstraint( gBodies, gShapes, &gConstraints[idx] );\n"
|
||||
" } \n"
|
||||
"}\n"
|
||||
;
|
||||
static const char* solveContactCL =
|
||||
"/*\n"
|
||||
"Copyright (c) 2012 Advanced Micro Devices, Inc. \n"
|
||||
"This software is provided 'as-is', without any express or implied warranty.\n"
|
||||
"In no event will the authors be held liable for any damages arising from the use of this software.\n"
|
||||
"Permission is granted to anyone to use this software for any purpose, \n"
|
||||
"including commercial applications, and to alter it and redistribute it freely, \n"
|
||||
"subject to the following restrictions:\n"
|
||||
"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.\n"
|
||||
"2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n"
|
||||
"3. This notice may not be removed or altered from any source distribution.\n"
|
||||
"*/\n"
|
||||
"//Originally written by Takahiro Harada\n"
|
||||
"//#pragma OPENCL EXTENSION cl_amd_printf : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable\n"
|
||||
"#ifdef cl_ext_atomic_counters_32\n"
|
||||
"#pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable\n"
|
||||
"#else\n"
|
||||
"#define counter32_t volatile global int*\n"
|
||||
"#endif\n"
|
||||
"typedef unsigned int u32;\n"
|
||||
"typedef unsigned short u16;\n"
|
||||
"typedef unsigned char u8;\n"
|
||||
"#define GET_GROUP_IDX get_group_id(0)\n"
|
||||
"#define GET_LOCAL_IDX get_local_id(0)\n"
|
||||
"#define GET_GLOBAL_IDX get_global_id(0)\n"
|
||||
"#define GET_GROUP_SIZE get_local_size(0)\n"
|
||||
"#define GET_NUM_GROUPS get_num_groups(0)\n"
|
||||
"#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n"
|
||||
"#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n"
|
||||
"#define AtomInc(x) atom_inc(&(x))\n"
|
||||
"#define AtomInc1(x, out) out = atom_inc(&(x))\n"
|
||||
"#define AppendInc(x, out) out = atomic_inc(x)\n"
|
||||
"#define AtomAdd(x, value) atom_add(&(x), value)\n"
|
||||
"#define AtomCmpxhg(x, cmp, value) atom_cmpxchg( &(x), cmp, value )\n"
|
||||
"#define AtomXhg(x, value) atom_xchg ( &(x), value )\n"
|
||||
"#define SELECT_UINT4( b, a, condition ) select( b,a,condition )\n"
|
||||
"#define mymake_float4 (float4)\n"
|
||||
"//#define make_float2 (float2)\n"
|
||||
"//#define make_uint4 (uint4)\n"
|
||||
"//#define make_int4 (int4)\n"
|
||||
"//#define make_uint2 (uint2)\n"
|
||||
"//#define make_int2 (int2)\n"
|
||||
"#define max2 max\n"
|
||||
"#define min2 min\n"
|
||||
"///////////////////////////////////////\n"
|
||||
"// Vector\n"
|
||||
"///////////////////////////////////////\n"
|
||||
"__inline\n"
|
||||
"float4 fastNormalize4(float4 v)\n"
|
||||
"{\n"
|
||||
" return fast_normalize(v);\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"float4 cross3(float4 a, float4 b)\n"
|
||||
"{\n"
|
||||
" return cross(a,b);\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"float dot3F4(float4 a, float4 b)\n"
|
||||
"{\n"
|
||||
" float4 a1 = mymake_float4(a.xyz,0.f);\n"
|
||||
" float4 b1 = mymake_float4(b.xyz,0.f);\n"
|
||||
" return dot(a1, b1);\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"float4 normalize3(const float4 a)\n"
|
||||
"{\n"
|
||||
" float4 n = mymake_float4(a.x, a.y, a.z, 0.f);\n"
|
||||
" return fastNormalize4( n );\n"
|
||||
"// float length = sqrtf(dot3F4(a, a));\n"
|
||||
"// return 1.f/length * a;\n"
|
||||
"}\n"
|
||||
"///////////////////////////////////////\n"
|
||||
"// Matrix3x3\n"
|
||||
"///////////////////////////////////////\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" float4 m_row[3];\n"
|
||||
"}Matrix3x3;\n"
|
||||
"__inline\n"
|
||||
"float4 mtMul1(Matrix3x3 a, float4 b);\n"
|
||||
"__inline\n"
|
||||
"float4 mtMul3(float4 a, Matrix3x3 b);\n"
|
||||
"__inline\n"
|
||||
"float4 mtMul1(Matrix3x3 a, float4 b)\n"
|
||||
"{\n"
|
||||
" float4 ans;\n"
|
||||
" ans.x = dot3F4( a.m_row[0], b );\n"
|
||||
" ans.y = dot3F4( a.m_row[1], b );\n"
|
||||
" ans.z = dot3F4( a.m_row[2], b );\n"
|
||||
" ans.w = 0.f;\n"
|
||||
" return ans;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"float4 mtMul3(float4 a, Matrix3x3 b)\n"
|
||||
"{\n"
|
||||
" float4 colx = mymake_float4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n"
|
||||
" float4 coly = mymake_float4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n"
|
||||
" float4 colz = mymake_float4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n"
|
||||
" float4 ans;\n"
|
||||
" ans.x = dot3F4( a, colx );\n"
|
||||
" ans.y = dot3F4( a, coly );\n"
|
||||
" ans.z = dot3F4( a, colz );\n"
|
||||
" return ans;\n"
|
||||
"}\n"
|
||||
"///////////////////////////////////////\n"
|
||||
"// Quaternion\n"
|
||||
"///////////////////////////////////////\n"
|
||||
"typedef float4 Quaternion;\n"
|
||||
"#define WG_SIZE 64\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" float4 m_pos;\n"
|
||||
" Quaternion m_quat;\n"
|
||||
" float4 m_linVel;\n"
|
||||
" float4 m_angVel;\n"
|
||||
" u32 m_shapeIdx;\n"
|
||||
" float m_invMass;\n"
|
||||
" float m_restituitionCoeff;\n"
|
||||
" float m_frictionCoeff;\n"
|
||||
"} Body;\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" Matrix3x3 m_invInertia;\n"
|
||||
" Matrix3x3 m_initInvInertia;\n"
|
||||
"} Shape;\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" float4 m_linear;\n"
|
||||
" float4 m_worldPos[4];\n"
|
||||
" float4 m_center; \n"
|
||||
" float m_jacCoeffInv[4];\n"
|
||||
" float m_b[4];\n"
|
||||
" float m_appliedRambdaDt[4];\n"
|
||||
" float m_fJacCoeffInv[2]; \n"
|
||||
" float m_fAppliedRambdaDt[2]; \n"
|
||||
" u32 m_bodyA;\n"
|
||||
" u32 m_bodyB;\n"
|
||||
" int m_batchIdx;\n"
|
||||
" u32 m_paddings[1];\n"
|
||||
"} Constraint4;\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" int m_nConstraints;\n"
|
||||
" int m_start;\n"
|
||||
" int m_batchIdx;\n"
|
||||
" int m_nSplit;\n"
|
||||
"// int m_paddings[1];\n"
|
||||
"} ConstBuffer;\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" int m_solveFriction;\n"
|
||||
" int m_maxBatch; // long batch really kills the performance\n"
|
||||
" int m_batchIdx;\n"
|
||||
" int m_nSplit;\n"
|
||||
"// int m_paddings[1];\n"
|
||||
"} ConstBufferBatchSolve;\n"
|
||||
"void setLinearAndAngular( float4 n, float4 r0, float4 r1, float4* linear, float4* angular0, float4* angular1);\n"
|
||||
"void setLinearAndAngular( float4 n, float4 r0, float4 r1, float4* linear, float4* angular0, float4* angular1)\n"
|
||||
"{\n"
|
||||
" *linear = mymake_float4(-n.xyz,0.f);\n"
|
||||
" *angular0 = -cross3(r0, n);\n"
|
||||
" *angular1 = cross3(r1, n);\n"
|
||||
"}\n"
|
||||
"float calcRelVel( float4 l0, float4 l1, float4 a0, float4 a1, float4 linVel0, float4 angVel0, float4 linVel1, float4 angVel1 );\n"
|
||||
"float calcRelVel( float4 l0, float4 l1, float4 a0, float4 a1, float4 linVel0, float4 angVel0, float4 linVel1, float4 angVel1 )\n"
|
||||
"{\n"
|
||||
" return dot3F4(l0, linVel0) + dot3F4(a0, angVel0) + dot3F4(l1, linVel1) + dot3F4(a1, angVel1);\n"
|
||||
"}\n"
|
||||
"float calcJacCoeff(const float4 linear0, const float4 linear1, const float4 angular0, const float4 angular1,\n"
|
||||
" float invMass0, const Matrix3x3* invInertia0, float invMass1, const Matrix3x3* invInertia1);\n"
|
||||
"float calcJacCoeff(const float4 linear0, const float4 linear1, const float4 angular0, const float4 angular1,\n"
|
||||
" float invMass0, const Matrix3x3* invInertia0, float invMass1, const Matrix3x3* invInertia1)\n"
|
||||
"{\n"
|
||||
" // linear0,1 are normlized\n"
|
||||
" float jmj0 = invMass0;//dot3F4(linear0, linear0)*invMass0;\n"
|
||||
" float jmj1 = dot3F4(mtMul3(angular0,*invInertia0), angular0);\n"
|
||||
" float jmj2 = invMass1;//dot3F4(linear1, linear1)*invMass1;\n"
|
||||
" float jmj3 = dot3F4(mtMul3(angular1,*invInertia1), angular1);\n"
|
||||
" return -1.f/(jmj0+jmj1+jmj2+jmj3);\n"
|
||||
"}\n"
|
||||
"void solveContact(__global Constraint4* cs,\n"
|
||||
" float4 posA, float4* linVelA, float4* angVelA, float invMassA, Matrix3x3 invInertiaA,\n"
|
||||
" float4 posB, float4* linVelB, float4* angVelB, float invMassB, Matrix3x3 invInertiaB);\n"
|
||||
"void solveContact(__global Constraint4* cs,\n"
|
||||
" float4 posA, float4* linVelA, float4* angVelA, float invMassA, Matrix3x3 invInertiaA,\n"
|
||||
" float4 posB, float4* linVelB, float4* angVelB, float invMassB, Matrix3x3 invInertiaB)\n"
|
||||
"{\n"
|
||||
" float minRambdaDt = 0;\n"
|
||||
" float maxRambdaDt = FLT_MAX;\n"
|
||||
" for(int ic=0; ic<4; ic++)\n"
|
||||
" {\n"
|
||||
" if( cs->m_jacCoeffInv[ic] == 0.f ) continue;\n"
|
||||
" float4 angular0, angular1, linear;\n"
|
||||
" float4 r0 = cs->m_worldPos[ic] - posA;\n"
|
||||
" float4 r1 = cs->m_worldPos[ic] - posB;\n"
|
||||
" setLinearAndAngular( -cs->m_linear, r0, r1, &linear, &angular0, &angular1 );\n"
|
||||
" float rambdaDt = calcRelVel( cs->m_linear, -cs->m_linear, angular0, angular1, \n"
|
||||
" *linVelA, *angVelA, *linVelB, *angVelB ) + cs->m_b[ic];\n"
|
||||
" rambdaDt *= cs->m_jacCoeffInv[ic];\n"
|
||||
" {\n"
|
||||
" float prevSum = cs->m_appliedRambdaDt[ic];\n"
|
||||
" float updated = prevSum;\n"
|
||||
" updated += rambdaDt;\n"
|
||||
" updated = max2( updated, minRambdaDt );\n"
|
||||
" updated = min2( updated, maxRambdaDt );\n"
|
||||
" rambdaDt = updated - prevSum;\n"
|
||||
" cs->m_appliedRambdaDt[ic] = updated;\n"
|
||||
" }\n"
|
||||
" float4 linImp0 = invMassA*linear*rambdaDt;\n"
|
||||
" float4 linImp1 = invMassB*(-linear)*rambdaDt;\n"
|
||||
" float4 angImp0 = mtMul1(invInertiaA, angular0)*rambdaDt;\n"
|
||||
" float4 angImp1 = mtMul1(invInertiaB, angular1)*rambdaDt;\n"
|
||||
" *linVelA += linImp0;\n"
|
||||
" *angVelA += angImp0;\n"
|
||||
" *linVelB += linImp1;\n"
|
||||
" *angVelB += angImp1;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"void btPlaneSpace1 (const float4* n, float4* p, float4* q);\n"
|
||||
" void btPlaneSpace1 (const float4* n, float4* p, float4* q)\n"
|
||||
"{\n"
|
||||
" if (fabs(n[0].z) > 0.70710678f) {\n"
|
||||
" // choose p in y-z plane\n"
|
||||
" float a = n[0].y*n[0].y + n[0].z*n[0].z;\n"
|
||||
" float k = 1.f/sqrt(a);\n"
|
||||
" p[0].x = 0;\n"
|
||||
" p[0].y = -n[0].z*k;\n"
|
||||
" p[0].z = n[0].y*k;\n"
|
||||
" // set q = n x p\n"
|
||||
" q[0].x = a*k;\n"
|
||||
" q[0].y = -n[0].x*p[0].z;\n"
|
||||
" q[0].z = n[0].x*p[0].y;\n"
|
||||
" }\n"
|
||||
" else {\n"
|
||||
" // choose p in x-y plane\n"
|
||||
" float a = n[0].x*n[0].x + n[0].y*n[0].y;\n"
|
||||
" float k = 1.f/sqrt(a);\n"
|
||||
" p[0].x = -n[0].y*k;\n"
|
||||
" p[0].y = n[0].x*k;\n"
|
||||
" p[0].z = 0;\n"
|
||||
" // set q = n x p\n"
|
||||
" q[0].x = -n[0].z*p[0].y;\n"
|
||||
" q[0].y = n[0].z*p[0].x;\n"
|
||||
" q[0].z = a*k;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"void solveContactConstraint(__global Body* gBodies, __global Shape* gShapes, __global Constraint4* ldsCs);\n"
|
||||
"void solveContactConstraint(__global Body* gBodies, __global Shape* gShapes, __global Constraint4* ldsCs)\n"
|
||||
"{\n"
|
||||
" //float frictionCoeff = ldsCs[0].m_linear.w;\n"
|
||||
" int aIdx = ldsCs[0].m_bodyA;\n"
|
||||
" int bIdx = ldsCs[0].m_bodyB;\n"
|
||||
" float4 posA = gBodies[aIdx].m_pos;\n"
|
||||
" float4 linVelA = gBodies[aIdx].m_linVel;\n"
|
||||
" float4 angVelA = gBodies[aIdx].m_angVel;\n"
|
||||
" float invMassA = gBodies[aIdx].m_invMass;\n"
|
||||
" Matrix3x3 invInertiaA = gShapes[aIdx].m_invInertia;\n"
|
||||
" float4 posB = gBodies[bIdx].m_pos;\n"
|
||||
" float4 linVelB = gBodies[bIdx].m_linVel;\n"
|
||||
" float4 angVelB = gBodies[bIdx].m_angVel;\n"
|
||||
" float invMassB = gBodies[bIdx].m_invMass;\n"
|
||||
" Matrix3x3 invInertiaB = gShapes[bIdx].m_invInertia;\n"
|
||||
" solveContact( ldsCs, posA, &linVelA, &angVelA, invMassA, invInertiaA,\n"
|
||||
" posB, &linVelB, &angVelB, invMassB, invInertiaB );\n"
|
||||
" if (gBodies[aIdx].m_invMass)\n"
|
||||
" {\n"
|
||||
" gBodies[aIdx].m_linVel = linVelA;\n"
|
||||
" gBodies[aIdx].m_angVel = angVelA;\n"
|
||||
" } else\n"
|
||||
" {\n"
|
||||
" gBodies[aIdx].m_linVel = mymake_float4(0,0,0,0);\n"
|
||||
" gBodies[aIdx].m_angVel = mymake_float4(0,0,0,0);\n"
|
||||
" \n"
|
||||
" }\n"
|
||||
" if (gBodies[bIdx].m_invMass)\n"
|
||||
" {\n"
|
||||
" gBodies[bIdx].m_linVel = linVelB;\n"
|
||||
" gBodies[bIdx].m_angVel = angVelB;\n"
|
||||
" } else\n"
|
||||
" {\n"
|
||||
" gBodies[bIdx].m_linVel = mymake_float4(0,0,0,0);\n"
|
||||
" gBodies[bIdx].m_angVel = mymake_float4(0,0,0,0);\n"
|
||||
" \n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"typedef struct \n"
|
||||
"{\n"
|
||||
" int m_valInt0;\n"
|
||||
" int m_valInt1;\n"
|
||||
" int m_valInt2;\n"
|
||||
" int m_valInt3;\n"
|
||||
" float m_val0;\n"
|
||||
" float m_val1;\n"
|
||||
" float m_val2;\n"
|
||||
" float m_val3;\n"
|
||||
"} SolverDebugInfo;\n"
|
||||
"__kernel\n"
|
||||
"__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n"
|
||||
"void BatchSolveKernelContact(__global Body* gBodies,\n"
|
||||
" __global Shape* gShapes,\n"
|
||||
" __global Constraint4* gConstraints,\n"
|
||||
" __global int* gN,\n"
|
||||
" __global int* gOffsets,\n"
|
||||
" __global int* batchSizes,\n"
|
||||
" int maxBatch1,\n"
|
||||
" int cellBatch,\n"
|
||||
" int4 nSplit\n"
|
||||
" )\n"
|
||||
"{\n"
|
||||
" //__local int ldsBatchIdx[WG_SIZE+1];\n"
|
||||
" __local int ldsCurBatch;\n"
|
||||
" __local int ldsNextBatch;\n"
|
||||
" __local int ldsStart;\n"
|
||||
" int lIdx = GET_LOCAL_IDX;\n"
|
||||
" int wgIdx = GET_GROUP_IDX;\n"
|
||||
"// int gIdx = GET_GLOBAL_IDX;\n"
|
||||
"// debugInfo[gIdx].m_valInt0 = gIdx;\n"
|
||||
" //debugInfo[gIdx].m_valInt1 = GET_GROUP_SIZE;\n"
|
||||
" \n"
|
||||
" \n"
|
||||
" int zIdx = (wgIdx/((nSplit.x*nSplit.y)/4))*2+((cellBatch&4)>>2);\n"
|
||||
" int remain= (wgIdx%((nSplit.x*nSplit.y)/4));\n"
|
||||
" int yIdx = (remain/(nSplit.x/2))*2 + ((cellBatch&2)>>1);\n"
|
||||
" int xIdx = (remain%(nSplit.x/2))*2 + (cellBatch&1);\n"
|
||||
" int cellIdx = xIdx+yIdx*nSplit.x+zIdx*(nSplit.x*nSplit.y);\n"
|
||||
" //int xIdx = (wgIdx/(nSplit/2))*2 + (bIdx&1);\n"
|
||||
" //int yIdx = (wgIdx%(nSplit/2))*2 + (bIdx>>1);\n"
|
||||
" //int cellIdx = xIdx+yIdx*nSplit;\n"
|
||||
" \n"
|
||||
" if( gN[cellIdx] == 0 ) \n"
|
||||
" return;\n"
|
||||
" int maxBatch = batchSizes[cellIdx];\n"
|
||||
" \n"
|
||||
" \n"
|
||||
" const int start = gOffsets[cellIdx];\n"
|
||||
" const int end = start + gN[cellIdx];\n"
|
||||
" \n"
|
||||
" \n"
|
||||
" \n"
|
||||
" if( lIdx == 0 )\n"
|
||||
" {\n"
|
||||
" ldsCurBatch = 0;\n"
|
||||
" ldsNextBatch = 0;\n"
|
||||
" ldsStart = start;\n"
|
||||
" }\n"
|
||||
" GROUP_LDS_BARRIER;\n"
|
||||
" int idx=ldsStart+lIdx;\n"
|
||||
" while (ldsCurBatch < maxBatch)\n"
|
||||
" {\n"
|
||||
" for(; idx<end; )\n"
|
||||
" {\n"
|
||||
" if (gConstraints[idx].m_batchIdx == ldsCurBatch)\n"
|
||||
" {\n"
|
||||
" solveContactConstraint( gBodies, gShapes, &gConstraints[idx] );\n"
|
||||
" idx+=64;\n"
|
||||
" } else\n"
|
||||
" {\n"
|
||||
" break;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" GROUP_LDS_BARRIER;\n"
|
||||
" \n"
|
||||
" if( lIdx == 0 )\n"
|
||||
" {\n"
|
||||
" ldsCurBatch++;\n"
|
||||
" }\n"
|
||||
" GROUP_LDS_BARRIER;\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" \n"
|
||||
"}\n"
|
||||
"__kernel void solveSingleContactKernel(__global Body* gBodies,\n"
|
||||
" __global Shape* gShapes,\n"
|
||||
" __global Constraint4* gConstraints,\n"
|
||||
" int cellIdx,\n"
|
||||
" int batchOffset,\n"
|
||||
" int numConstraintsInBatch\n"
|
||||
" )\n"
|
||||
"{\n"
|
||||
" int index = get_global_id(0);\n"
|
||||
" if (index < numConstraintsInBatch)\n"
|
||||
" {\n"
|
||||
" int idx=batchOffset+index;\n"
|
||||
" solveContactConstraint( gBodies, gShapes, &gConstraints[idx] );\n"
|
||||
" } \n"
|
||||
"}\n";
|
||||
|
||||
@@ -1,421 +1,420 @@
|
||||
//this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project
|
||||
static const char* solveFrictionCL= \
|
||||
"/*\n"
|
||||
"Copyright (c) 2012 Advanced Micro Devices, Inc. \n"
|
||||
"This software is provided 'as-is', without any express or implied warranty.\n"
|
||||
"In no event will the authors be held liable for any damages arising from the use of this software.\n"
|
||||
"Permission is granted to anyone to use this software for any purpose, \n"
|
||||
"including commercial applications, and to alter it and redistribute it freely, \n"
|
||||
"subject to the following restrictions:\n"
|
||||
"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.\n"
|
||||
"2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n"
|
||||
"3. This notice may not be removed or altered from any source distribution.\n"
|
||||
"*/\n"
|
||||
"//Originally written by Takahiro Harada\n"
|
||||
"//#pragma OPENCL EXTENSION cl_amd_printf : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable\n"
|
||||
"#ifdef cl_ext_atomic_counters_32\n"
|
||||
"#pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable\n"
|
||||
"#else\n"
|
||||
"#define counter32_t volatile global int*\n"
|
||||
"#endif\n"
|
||||
"typedef unsigned int u32;\n"
|
||||
"typedef unsigned short u16;\n"
|
||||
"typedef unsigned char u8;\n"
|
||||
"#define GET_GROUP_IDX get_group_id(0)\n"
|
||||
"#define GET_LOCAL_IDX get_local_id(0)\n"
|
||||
"#define GET_GLOBAL_IDX get_global_id(0)\n"
|
||||
"#define GET_GROUP_SIZE get_local_size(0)\n"
|
||||
"#define GET_NUM_GROUPS get_num_groups(0)\n"
|
||||
"#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n"
|
||||
"#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n"
|
||||
"#define AtomInc(x) atom_inc(&(x))\n"
|
||||
"#define AtomInc1(x, out) out = atom_inc(&(x))\n"
|
||||
"#define AppendInc(x, out) out = atomic_inc(x)\n"
|
||||
"#define AtomAdd(x, value) atom_add(&(x), value)\n"
|
||||
"#define AtomCmpxhg(x, cmp, value) atom_cmpxchg( &(x), cmp, value )\n"
|
||||
"#define AtomXhg(x, value) atom_xchg ( &(x), value )\n"
|
||||
"#define SELECT_UINT4( b, a, condition ) select( b,a,condition )\n"
|
||||
"#define mymake_float4 (float4)\n"
|
||||
"//#define make_float2 (float2)\n"
|
||||
"//#define make_uint4 (uint4)\n"
|
||||
"//#define make_int4 (int4)\n"
|
||||
"//#define make_uint2 (uint2)\n"
|
||||
"//#define make_int2 (int2)\n"
|
||||
"#define max2 max\n"
|
||||
"#define min2 min\n"
|
||||
"///////////////////////////////////////\n"
|
||||
"// Vector\n"
|
||||
"///////////////////////////////////////\n"
|
||||
"__inline\n"
|
||||
"float4 fastNormalize4(float4 v)\n"
|
||||
"{\n"
|
||||
" return fast_normalize(v);\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"float4 cross3(float4 a, float4 b)\n"
|
||||
"{\n"
|
||||
" return cross(a,b);\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"float dot3F4(float4 a, float4 b)\n"
|
||||
"{\n"
|
||||
" float4 a1 = mymake_float4(a.xyz,0.f);\n"
|
||||
" float4 b1 = mymake_float4(b.xyz,0.f);\n"
|
||||
" return dot(a1, b1);\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"float4 normalize3(const float4 a)\n"
|
||||
"{\n"
|
||||
" float4 n = mymake_float4(a.x, a.y, a.z, 0.f);\n"
|
||||
" return fastNormalize4( n );\n"
|
||||
"// float length = sqrtf(dot3F4(a, a));\n"
|
||||
"// return 1.f/length * a;\n"
|
||||
"}\n"
|
||||
"///////////////////////////////////////\n"
|
||||
"// Matrix3x3\n"
|
||||
"///////////////////////////////////////\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" float4 m_row[3];\n"
|
||||
"}Matrix3x3;\n"
|
||||
"__inline\n"
|
||||
"float4 mtMul1(Matrix3x3 a, float4 b);\n"
|
||||
"__inline\n"
|
||||
"float4 mtMul3(float4 a, Matrix3x3 b);\n"
|
||||
"__inline\n"
|
||||
"float4 mtMul1(Matrix3x3 a, float4 b)\n"
|
||||
"{\n"
|
||||
" float4 ans;\n"
|
||||
" ans.x = dot3F4( a.m_row[0], b );\n"
|
||||
" ans.y = dot3F4( a.m_row[1], b );\n"
|
||||
" ans.z = dot3F4( a.m_row[2], b );\n"
|
||||
" ans.w = 0.f;\n"
|
||||
" return ans;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"float4 mtMul3(float4 a, Matrix3x3 b)\n"
|
||||
"{\n"
|
||||
" float4 colx = mymake_float4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n"
|
||||
" float4 coly = mymake_float4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n"
|
||||
" float4 colz = mymake_float4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n"
|
||||
" float4 ans;\n"
|
||||
" ans.x = dot3F4( a, colx );\n"
|
||||
" ans.y = dot3F4( a, coly );\n"
|
||||
" ans.z = dot3F4( a, colz );\n"
|
||||
" return ans;\n"
|
||||
"}\n"
|
||||
"///////////////////////////////////////\n"
|
||||
"// Quaternion\n"
|
||||
"///////////////////////////////////////\n"
|
||||
"typedef float4 Quaternion;\n"
|
||||
"#define WG_SIZE 64\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" float4 m_pos;\n"
|
||||
" Quaternion m_quat;\n"
|
||||
" float4 m_linVel;\n"
|
||||
" float4 m_angVel;\n"
|
||||
" u32 m_shapeIdx;\n"
|
||||
" float m_invMass;\n"
|
||||
" float m_restituitionCoeff;\n"
|
||||
" float m_frictionCoeff;\n"
|
||||
"} Body;\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" Matrix3x3 m_invInertia;\n"
|
||||
" Matrix3x3 m_initInvInertia;\n"
|
||||
"} Shape;\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" float4 m_linear;\n"
|
||||
" float4 m_worldPos[4];\n"
|
||||
" float4 m_center; \n"
|
||||
" float m_jacCoeffInv[4];\n"
|
||||
" float m_b[4];\n"
|
||||
" float m_appliedRambdaDt[4];\n"
|
||||
" float m_fJacCoeffInv[2]; \n"
|
||||
" float m_fAppliedRambdaDt[2]; \n"
|
||||
" u32 m_bodyA;\n"
|
||||
" u32 m_bodyB;\n"
|
||||
" int m_batchIdx;\n"
|
||||
" u32 m_paddings[1];\n"
|
||||
"} Constraint4;\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" int m_nConstraints;\n"
|
||||
" int m_start;\n"
|
||||
" int m_batchIdx;\n"
|
||||
" int m_nSplit;\n"
|
||||
"// int m_paddings[1];\n"
|
||||
"} ConstBuffer;\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" int m_solveFriction;\n"
|
||||
" int m_maxBatch; // long batch really kills the performance\n"
|
||||
" int m_batchIdx;\n"
|
||||
" int m_nSplit;\n"
|
||||
"// int m_paddings[1];\n"
|
||||
"} ConstBufferBatchSolve;\n"
|
||||
"void setLinearAndAngular( float4 n, float4 r0, float4 r1, float4* linear, float4* angular0, float4* angular1);\n"
|
||||
"void setLinearAndAngular( float4 n, float4 r0, float4 r1, float4* linear, float4* angular0, float4* angular1)\n"
|
||||
"{\n"
|
||||
" *linear = mymake_float4(-n.xyz,0.f);\n"
|
||||
" *angular0 = -cross3(r0, n);\n"
|
||||
" *angular1 = cross3(r1, n);\n"
|
||||
"}\n"
|
||||
"float calcRelVel( float4 l0, float4 l1, float4 a0, float4 a1, float4 linVel0, float4 angVel0, float4 linVel1, float4 angVel1 );\n"
|
||||
"float calcRelVel( float4 l0, float4 l1, float4 a0, float4 a1, float4 linVel0, float4 angVel0, float4 linVel1, float4 angVel1 )\n"
|
||||
"{\n"
|
||||
" return dot3F4(l0, linVel0) + dot3F4(a0, angVel0) + dot3F4(l1, linVel1) + dot3F4(a1, angVel1);\n"
|
||||
"}\n"
|
||||
"float calcJacCoeff(const float4 linear0, const float4 linear1, const float4 angular0, const float4 angular1,\n"
|
||||
" float invMass0, const Matrix3x3* invInertia0, float invMass1, const Matrix3x3* invInertia1);\n"
|
||||
"float calcJacCoeff(const float4 linear0, const float4 linear1, const float4 angular0, const float4 angular1,\n"
|
||||
" float invMass0, const Matrix3x3* invInertia0, float invMass1, const Matrix3x3* invInertia1)\n"
|
||||
"{\n"
|
||||
" // linear0,1 are normlized\n"
|
||||
" float jmj0 = invMass0;//dot3F4(linear0, linear0)*invMass0;\n"
|
||||
" float jmj1 = dot3F4(mtMul3(angular0,*invInertia0), angular0);\n"
|
||||
" float jmj2 = invMass1;//dot3F4(linear1, linear1)*invMass1;\n"
|
||||
" float jmj3 = dot3F4(mtMul3(angular1,*invInertia1), angular1);\n"
|
||||
" return -1.f/(jmj0+jmj1+jmj2+jmj3);\n"
|
||||
"}\n"
|
||||
"void btPlaneSpace1 (const float4* n, float4* p, float4* q);\n"
|
||||
" void btPlaneSpace1 (const float4* n, float4* p, float4* q)\n"
|
||||
"{\n"
|
||||
" if (fabs(n[0].z) > 0.70710678f) {\n"
|
||||
" // choose p in y-z plane\n"
|
||||
" float a = n[0].y*n[0].y + n[0].z*n[0].z;\n"
|
||||
" float k = 1.f/sqrt(a);\n"
|
||||
" p[0].x = 0;\n"
|
||||
" p[0].y = -n[0].z*k;\n"
|
||||
" p[0].z = n[0].y*k;\n"
|
||||
" // set q = n x p\n"
|
||||
" q[0].x = a*k;\n"
|
||||
" q[0].y = -n[0].x*p[0].z;\n"
|
||||
" q[0].z = n[0].x*p[0].y;\n"
|
||||
" }\n"
|
||||
" else {\n"
|
||||
" // choose p in x-y plane\n"
|
||||
" float a = n[0].x*n[0].x + n[0].y*n[0].y;\n"
|
||||
" float k = 1.f/sqrt(a);\n"
|
||||
" p[0].x = -n[0].y*k;\n"
|
||||
" p[0].y = n[0].x*k;\n"
|
||||
" p[0].z = 0;\n"
|
||||
" // set q = n x p\n"
|
||||
" q[0].x = -n[0].z*p[0].y;\n"
|
||||
" q[0].y = n[0].z*p[0].x;\n"
|
||||
" q[0].z = a*k;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"void solveFrictionConstraint(__global Body* gBodies, __global Shape* gShapes, __global Constraint4* ldsCs);\n"
|
||||
"void solveFrictionConstraint(__global Body* gBodies, __global Shape* gShapes, __global Constraint4* ldsCs)\n"
|
||||
"{\n"
|
||||
" float frictionCoeff = ldsCs[0].m_linear.w;\n"
|
||||
" int aIdx = ldsCs[0].m_bodyA;\n"
|
||||
" int bIdx = ldsCs[0].m_bodyB;\n"
|
||||
" float4 posA = gBodies[aIdx].m_pos;\n"
|
||||
" float4 linVelA = gBodies[aIdx].m_linVel;\n"
|
||||
" float4 angVelA = gBodies[aIdx].m_angVel;\n"
|
||||
" float invMassA = gBodies[aIdx].m_invMass;\n"
|
||||
" Matrix3x3 invInertiaA = gShapes[aIdx].m_invInertia;\n"
|
||||
" float4 posB = gBodies[bIdx].m_pos;\n"
|
||||
" float4 linVelB = gBodies[bIdx].m_linVel;\n"
|
||||
" float4 angVelB = gBodies[bIdx].m_angVel;\n"
|
||||
" float invMassB = gBodies[bIdx].m_invMass;\n"
|
||||
" Matrix3x3 invInertiaB = gShapes[bIdx].m_invInertia;\n"
|
||||
" \n"
|
||||
" {\n"
|
||||
" float maxRambdaDt[4] = {FLT_MAX,FLT_MAX,FLT_MAX,FLT_MAX};\n"
|
||||
" float minRambdaDt[4] = {0.f,0.f,0.f,0.f};\n"
|
||||
" float sum = 0;\n"
|
||||
" for(int j=0; j<4; j++)\n"
|
||||
" {\n"
|
||||
" sum +=ldsCs[0].m_appliedRambdaDt[j];\n"
|
||||
" }\n"
|
||||
" frictionCoeff = 0.7f;\n"
|
||||
" for(int j=0; j<4; j++)\n"
|
||||
" {\n"
|
||||
" maxRambdaDt[j] = frictionCoeff*sum;\n"
|
||||
" minRambdaDt[j] = -maxRambdaDt[j];\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
"// solveFriction( ldsCs, posA, &linVelA, &angVelA, invMassA, invInertiaA,\n"
|
||||
"// posB, &linVelB, &angVelB, invMassB, invInertiaB, maxRambdaDt, minRambdaDt );\n"
|
||||
" \n"
|
||||
" \n"
|
||||
" {\n"
|
||||
" \n"
|
||||
" __global Constraint4* cs = ldsCs;\n"
|
||||
" \n"
|
||||
" if( cs->m_fJacCoeffInv[0] == 0 && cs->m_fJacCoeffInv[0] == 0 ) return;\n"
|
||||
" const float4 center = cs->m_center;\n"
|
||||
" \n"
|
||||
" float4 n = -cs->m_linear;\n"
|
||||
" \n"
|
||||
" float4 tangent[2];\n"
|
||||
" btPlaneSpace1(&n,&tangent[0],&tangent[1]);\n"
|
||||
" float4 angular0, angular1, linear;\n"
|
||||
" float4 r0 = center - posA;\n"
|
||||
" float4 r1 = center - posB;\n"
|
||||
" for(int i=0; i<2; i++)\n"
|
||||
" {\n"
|
||||
" setLinearAndAngular( tangent[i], r0, r1, &linear, &angular0, &angular1 );\n"
|
||||
" float rambdaDt = calcRelVel(linear, -linear, angular0, angular1,\n"
|
||||
" linVelA, angVelA, linVelB, angVelB );\n"
|
||||
" rambdaDt *= cs->m_fJacCoeffInv[i];\n"
|
||||
" \n"
|
||||
" {\n"
|
||||
" float prevSum = cs->m_fAppliedRambdaDt[i];\n"
|
||||
" float updated = prevSum;\n"
|
||||
" updated += rambdaDt;\n"
|
||||
" updated = max2( updated, minRambdaDt[i] );\n"
|
||||
" updated = min2( updated, maxRambdaDt[i] );\n"
|
||||
" rambdaDt = updated - prevSum;\n"
|
||||
" cs->m_fAppliedRambdaDt[i] = updated;\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" float4 linImp0 = invMassA*linear*rambdaDt;\n"
|
||||
" float4 linImp1 = invMassB*(-linear)*rambdaDt;\n"
|
||||
" float4 angImp0 = mtMul1(invInertiaA, angular0)*rambdaDt;\n"
|
||||
" float4 angImp1 = mtMul1(invInertiaB, angular1)*rambdaDt;\n"
|
||||
" \n"
|
||||
" linVelA += linImp0;\n"
|
||||
" angVelA += angImp0;\n"
|
||||
" linVelB += linImp1;\n"
|
||||
" angVelB += angImp1;\n"
|
||||
" }\n"
|
||||
" { // angular damping for point constraint\n"
|
||||
" float4 ab = normalize3( posB - posA );\n"
|
||||
" float4 ac = normalize3( center - posA );\n"
|
||||
" if( dot3F4( ab, ac ) > 0.95f || (invMassA == 0.f || invMassB == 0.f))\n"
|
||||
" {\n"
|
||||
" float angNA = dot3F4( n, angVelA );\n"
|
||||
" float angNB = dot3F4( n, angVelB );\n"
|
||||
" \n"
|
||||
" angVelA -= (angNA*0.1f)*n;\n"
|
||||
" angVelB -= (angNB*0.1f)*n;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" \n"
|
||||
" }\n"
|
||||
" if (gBodies[aIdx].m_invMass)\n"
|
||||
" {\n"
|
||||
" gBodies[aIdx].m_linVel = linVelA;\n"
|
||||
" gBodies[aIdx].m_angVel = angVelA;\n"
|
||||
" } else\n"
|
||||
" {\n"
|
||||
" gBodies[aIdx].m_linVel = mymake_float4(0,0,0,0);\n"
|
||||
" gBodies[aIdx].m_angVel = mymake_float4(0,0,0,0);\n"
|
||||
" }\n"
|
||||
" if (gBodies[bIdx].m_invMass)\n"
|
||||
" {\n"
|
||||
" gBodies[bIdx].m_linVel = linVelB;\n"
|
||||
" gBodies[bIdx].m_angVel = angVelB;\n"
|
||||
" } else\n"
|
||||
" {\n"
|
||||
" gBodies[bIdx].m_linVel = mymake_float4(0,0,0,0);\n"
|
||||
" gBodies[bIdx].m_angVel = mymake_float4(0,0,0,0);\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
"}\n"
|
||||
"typedef struct \n"
|
||||
"{\n"
|
||||
" int m_valInt0;\n"
|
||||
" int m_valInt1;\n"
|
||||
" int m_valInt2;\n"
|
||||
" int m_valInt3;\n"
|
||||
" float m_val0;\n"
|
||||
" float m_val1;\n"
|
||||
" float m_val2;\n"
|
||||
" float m_val3;\n"
|
||||
"} SolverDebugInfo;\n"
|
||||
"__kernel\n"
|
||||
"__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n"
|
||||
"void BatchSolveKernelFriction(__global Body* gBodies,\n"
|
||||
" __global Shape* gShapes,\n"
|
||||
" __global Constraint4* gConstraints,\n"
|
||||
" __global int* gN,\n"
|
||||
" __global int* gOffsets,\n"
|
||||
" __global int* batchSizes,\n"
|
||||
" int maxBatch1,\n"
|
||||
" int cellBatch,\n"
|
||||
" int4 nSplit\n"
|
||||
" )\n"
|
||||
"{\n"
|
||||
" //__local int ldsBatchIdx[WG_SIZE+1];\n"
|
||||
" __local int ldsCurBatch;\n"
|
||||
" __local int ldsNextBatch;\n"
|
||||
" __local int ldsStart;\n"
|
||||
" int lIdx = GET_LOCAL_IDX;\n"
|
||||
" int wgIdx = GET_GROUP_IDX;\n"
|
||||
"// int gIdx = GET_GLOBAL_IDX;\n"
|
||||
"// debugInfo[gIdx].m_valInt0 = gIdx;\n"
|
||||
" //debugInfo[gIdx].m_valInt1 = GET_GROUP_SIZE;\n"
|
||||
" int zIdx = (wgIdx/((nSplit.x*nSplit.y)/4))*2+((cellBatch&4)>>2);\n"
|
||||
" int remain= (wgIdx%((nSplit.x*nSplit.y)/4));\n"
|
||||
" int yIdx = (remain/(nSplit.x/2))*2 + ((cellBatch&2)>>1);\n"
|
||||
" int xIdx = (remain%(nSplit.x/2))*2 + (cellBatch&1);\n"
|
||||
" int cellIdx = xIdx+yIdx*nSplit.x+zIdx*(nSplit.x*nSplit.y);\n"
|
||||
" \n"
|
||||
" if( gN[cellIdx] == 0 ) \n"
|
||||
" return;\n"
|
||||
" int maxBatch = batchSizes[cellIdx];\n"
|
||||
" const int start = gOffsets[cellIdx];\n"
|
||||
" const int end = start + gN[cellIdx];\n"
|
||||
" \n"
|
||||
" if( lIdx == 0 )\n"
|
||||
" {\n"
|
||||
" ldsCurBatch = 0;\n"
|
||||
" ldsNextBatch = 0;\n"
|
||||
" ldsStart = start;\n"
|
||||
" }\n"
|
||||
" GROUP_LDS_BARRIER;\n"
|
||||
" int idx=ldsStart+lIdx;\n"
|
||||
" while (ldsCurBatch < maxBatch)\n"
|
||||
" {\n"
|
||||
" for(; idx<end; )\n"
|
||||
" {\n"
|
||||
" if (gConstraints[idx].m_batchIdx == ldsCurBatch)\n"
|
||||
" {\n"
|
||||
" solveFrictionConstraint( gBodies, gShapes, &gConstraints[idx] );\n"
|
||||
" idx+=64;\n"
|
||||
" } else\n"
|
||||
" {\n"
|
||||
" break;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" GROUP_LDS_BARRIER;\n"
|
||||
" if( lIdx == 0 )\n"
|
||||
" {\n"
|
||||
" ldsCurBatch++;\n"
|
||||
" }\n"
|
||||
" GROUP_LDS_BARRIER;\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" \n"
|
||||
"}\n"
|
||||
"__kernel void solveSingleFrictionKernel(__global Body* gBodies,\n"
|
||||
" __global Shape* gShapes,\n"
|
||||
" __global Constraint4* gConstraints,\n"
|
||||
" int cellIdx,\n"
|
||||
" int batchOffset,\n"
|
||||
" int numConstraintsInBatch\n"
|
||||
" )\n"
|
||||
"{\n"
|
||||
" int index = get_global_id(0);\n"
|
||||
" if (index < numConstraintsInBatch)\n"
|
||||
" {\n"
|
||||
" \n"
|
||||
" int idx=batchOffset+index;\n"
|
||||
" \n"
|
||||
" solveFrictionConstraint( gBodies, gShapes, &gConstraints[idx] );\n"
|
||||
" } \n"
|
||||
"}\n"
|
||||
;
|
||||
static const char* solveFrictionCL =
|
||||
"/*\n"
|
||||
"Copyright (c) 2012 Advanced Micro Devices, Inc. \n"
|
||||
"This software is provided 'as-is', without any express or implied warranty.\n"
|
||||
"In no event will the authors be held liable for any damages arising from the use of this software.\n"
|
||||
"Permission is granted to anyone to use this software for any purpose, \n"
|
||||
"including commercial applications, and to alter it and redistribute it freely, \n"
|
||||
"subject to the following restrictions:\n"
|
||||
"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.\n"
|
||||
"2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n"
|
||||
"3. This notice may not be removed or altered from any source distribution.\n"
|
||||
"*/\n"
|
||||
"//Originally written by Takahiro Harada\n"
|
||||
"//#pragma OPENCL EXTENSION cl_amd_printf : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable\n"
|
||||
"#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable\n"
|
||||
"#ifdef cl_ext_atomic_counters_32\n"
|
||||
"#pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable\n"
|
||||
"#else\n"
|
||||
"#define counter32_t volatile global int*\n"
|
||||
"#endif\n"
|
||||
"typedef unsigned int u32;\n"
|
||||
"typedef unsigned short u16;\n"
|
||||
"typedef unsigned char u8;\n"
|
||||
"#define GET_GROUP_IDX get_group_id(0)\n"
|
||||
"#define GET_LOCAL_IDX get_local_id(0)\n"
|
||||
"#define GET_GLOBAL_IDX get_global_id(0)\n"
|
||||
"#define GET_GROUP_SIZE get_local_size(0)\n"
|
||||
"#define GET_NUM_GROUPS get_num_groups(0)\n"
|
||||
"#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n"
|
||||
"#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n"
|
||||
"#define AtomInc(x) atom_inc(&(x))\n"
|
||||
"#define AtomInc1(x, out) out = atom_inc(&(x))\n"
|
||||
"#define AppendInc(x, out) out = atomic_inc(x)\n"
|
||||
"#define AtomAdd(x, value) atom_add(&(x), value)\n"
|
||||
"#define AtomCmpxhg(x, cmp, value) atom_cmpxchg( &(x), cmp, value )\n"
|
||||
"#define AtomXhg(x, value) atom_xchg ( &(x), value )\n"
|
||||
"#define SELECT_UINT4( b, a, condition ) select( b,a,condition )\n"
|
||||
"#define mymake_float4 (float4)\n"
|
||||
"//#define make_float2 (float2)\n"
|
||||
"//#define make_uint4 (uint4)\n"
|
||||
"//#define make_int4 (int4)\n"
|
||||
"//#define make_uint2 (uint2)\n"
|
||||
"//#define make_int2 (int2)\n"
|
||||
"#define max2 max\n"
|
||||
"#define min2 min\n"
|
||||
"///////////////////////////////////////\n"
|
||||
"// Vector\n"
|
||||
"///////////////////////////////////////\n"
|
||||
"__inline\n"
|
||||
"float4 fastNormalize4(float4 v)\n"
|
||||
"{\n"
|
||||
" return fast_normalize(v);\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"float4 cross3(float4 a, float4 b)\n"
|
||||
"{\n"
|
||||
" return cross(a,b);\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"float dot3F4(float4 a, float4 b)\n"
|
||||
"{\n"
|
||||
" float4 a1 = mymake_float4(a.xyz,0.f);\n"
|
||||
" float4 b1 = mymake_float4(b.xyz,0.f);\n"
|
||||
" return dot(a1, b1);\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"float4 normalize3(const float4 a)\n"
|
||||
"{\n"
|
||||
" float4 n = mymake_float4(a.x, a.y, a.z, 0.f);\n"
|
||||
" return fastNormalize4( n );\n"
|
||||
"// float length = sqrtf(dot3F4(a, a));\n"
|
||||
"// return 1.f/length * a;\n"
|
||||
"}\n"
|
||||
"///////////////////////////////////////\n"
|
||||
"// Matrix3x3\n"
|
||||
"///////////////////////////////////////\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" float4 m_row[3];\n"
|
||||
"}Matrix3x3;\n"
|
||||
"__inline\n"
|
||||
"float4 mtMul1(Matrix3x3 a, float4 b);\n"
|
||||
"__inline\n"
|
||||
"float4 mtMul3(float4 a, Matrix3x3 b);\n"
|
||||
"__inline\n"
|
||||
"float4 mtMul1(Matrix3x3 a, float4 b)\n"
|
||||
"{\n"
|
||||
" float4 ans;\n"
|
||||
" ans.x = dot3F4( a.m_row[0], b );\n"
|
||||
" ans.y = dot3F4( a.m_row[1], b );\n"
|
||||
" ans.z = dot3F4( a.m_row[2], b );\n"
|
||||
" ans.w = 0.f;\n"
|
||||
" return ans;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"float4 mtMul3(float4 a, Matrix3x3 b)\n"
|
||||
"{\n"
|
||||
" float4 colx = mymake_float4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n"
|
||||
" float4 coly = mymake_float4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n"
|
||||
" float4 colz = mymake_float4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n"
|
||||
" float4 ans;\n"
|
||||
" ans.x = dot3F4( a, colx );\n"
|
||||
" ans.y = dot3F4( a, coly );\n"
|
||||
" ans.z = dot3F4( a, colz );\n"
|
||||
" return ans;\n"
|
||||
"}\n"
|
||||
"///////////////////////////////////////\n"
|
||||
"// Quaternion\n"
|
||||
"///////////////////////////////////////\n"
|
||||
"typedef float4 Quaternion;\n"
|
||||
"#define WG_SIZE 64\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" float4 m_pos;\n"
|
||||
" Quaternion m_quat;\n"
|
||||
" float4 m_linVel;\n"
|
||||
" float4 m_angVel;\n"
|
||||
" u32 m_shapeIdx;\n"
|
||||
" float m_invMass;\n"
|
||||
" float m_restituitionCoeff;\n"
|
||||
" float m_frictionCoeff;\n"
|
||||
"} Body;\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" Matrix3x3 m_invInertia;\n"
|
||||
" Matrix3x3 m_initInvInertia;\n"
|
||||
"} Shape;\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" float4 m_linear;\n"
|
||||
" float4 m_worldPos[4];\n"
|
||||
" float4 m_center; \n"
|
||||
" float m_jacCoeffInv[4];\n"
|
||||
" float m_b[4];\n"
|
||||
" float m_appliedRambdaDt[4];\n"
|
||||
" float m_fJacCoeffInv[2]; \n"
|
||||
" float m_fAppliedRambdaDt[2]; \n"
|
||||
" u32 m_bodyA;\n"
|
||||
" u32 m_bodyB;\n"
|
||||
" int m_batchIdx;\n"
|
||||
" u32 m_paddings[1];\n"
|
||||
"} Constraint4;\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" int m_nConstraints;\n"
|
||||
" int m_start;\n"
|
||||
" int m_batchIdx;\n"
|
||||
" int m_nSplit;\n"
|
||||
"// int m_paddings[1];\n"
|
||||
"} ConstBuffer;\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" int m_solveFriction;\n"
|
||||
" int m_maxBatch; // long batch really kills the performance\n"
|
||||
" int m_batchIdx;\n"
|
||||
" int m_nSplit;\n"
|
||||
"// int m_paddings[1];\n"
|
||||
"} ConstBufferBatchSolve;\n"
|
||||
"void setLinearAndAngular( float4 n, float4 r0, float4 r1, float4* linear, float4* angular0, float4* angular1);\n"
|
||||
"void setLinearAndAngular( float4 n, float4 r0, float4 r1, float4* linear, float4* angular0, float4* angular1)\n"
|
||||
"{\n"
|
||||
" *linear = mymake_float4(-n.xyz,0.f);\n"
|
||||
" *angular0 = -cross3(r0, n);\n"
|
||||
" *angular1 = cross3(r1, n);\n"
|
||||
"}\n"
|
||||
"float calcRelVel( float4 l0, float4 l1, float4 a0, float4 a1, float4 linVel0, float4 angVel0, float4 linVel1, float4 angVel1 );\n"
|
||||
"float calcRelVel( float4 l0, float4 l1, float4 a0, float4 a1, float4 linVel0, float4 angVel0, float4 linVel1, float4 angVel1 )\n"
|
||||
"{\n"
|
||||
" return dot3F4(l0, linVel0) + dot3F4(a0, angVel0) + dot3F4(l1, linVel1) + dot3F4(a1, angVel1);\n"
|
||||
"}\n"
|
||||
"float calcJacCoeff(const float4 linear0, const float4 linear1, const float4 angular0, const float4 angular1,\n"
|
||||
" float invMass0, const Matrix3x3* invInertia0, float invMass1, const Matrix3x3* invInertia1);\n"
|
||||
"float calcJacCoeff(const float4 linear0, const float4 linear1, const float4 angular0, const float4 angular1,\n"
|
||||
" float invMass0, const Matrix3x3* invInertia0, float invMass1, const Matrix3x3* invInertia1)\n"
|
||||
"{\n"
|
||||
" // linear0,1 are normlized\n"
|
||||
" float jmj0 = invMass0;//dot3F4(linear0, linear0)*invMass0;\n"
|
||||
" float jmj1 = dot3F4(mtMul3(angular0,*invInertia0), angular0);\n"
|
||||
" float jmj2 = invMass1;//dot3F4(linear1, linear1)*invMass1;\n"
|
||||
" float jmj3 = dot3F4(mtMul3(angular1,*invInertia1), angular1);\n"
|
||||
" return -1.f/(jmj0+jmj1+jmj2+jmj3);\n"
|
||||
"}\n"
|
||||
"void btPlaneSpace1 (const float4* n, float4* p, float4* q);\n"
|
||||
" void btPlaneSpace1 (const float4* n, float4* p, float4* q)\n"
|
||||
"{\n"
|
||||
" if (fabs(n[0].z) > 0.70710678f) {\n"
|
||||
" // choose p in y-z plane\n"
|
||||
" float a = n[0].y*n[0].y + n[0].z*n[0].z;\n"
|
||||
" float k = 1.f/sqrt(a);\n"
|
||||
" p[0].x = 0;\n"
|
||||
" p[0].y = -n[0].z*k;\n"
|
||||
" p[0].z = n[0].y*k;\n"
|
||||
" // set q = n x p\n"
|
||||
" q[0].x = a*k;\n"
|
||||
" q[0].y = -n[0].x*p[0].z;\n"
|
||||
" q[0].z = n[0].x*p[0].y;\n"
|
||||
" }\n"
|
||||
" else {\n"
|
||||
" // choose p in x-y plane\n"
|
||||
" float a = n[0].x*n[0].x + n[0].y*n[0].y;\n"
|
||||
" float k = 1.f/sqrt(a);\n"
|
||||
" p[0].x = -n[0].y*k;\n"
|
||||
" p[0].y = n[0].x*k;\n"
|
||||
" p[0].z = 0;\n"
|
||||
" // set q = n x p\n"
|
||||
" q[0].x = -n[0].z*p[0].y;\n"
|
||||
" q[0].y = n[0].z*p[0].x;\n"
|
||||
" q[0].z = a*k;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"void solveFrictionConstraint(__global Body* gBodies, __global Shape* gShapes, __global Constraint4* ldsCs);\n"
|
||||
"void solveFrictionConstraint(__global Body* gBodies, __global Shape* gShapes, __global Constraint4* ldsCs)\n"
|
||||
"{\n"
|
||||
" float frictionCoeff = ldsCs[0].m_linear.w;\n"
|
||||
" int aIdx = ldsCs[0].m_bodyA;\n"
|
||||
" int bIdx = ldsCs[0].m_bodyB;\n"
|
||||
" float4 posA = gBodies[aIdx].m_pos;\n"
|
||||
" float4 linVelA = gBodies[aIdx].m_linVel;\n"
|
||||
" float4 angVelA = gBodies[aIdx].m_angVel;\n"
|
||||
" float invMassA = gBodies[aIdx].m_invMass;\n"
|
||||
" Matrix3x3 invInertiaA = gShapes[aIdx].m_invInertia;\n"
|
||||
" float4 posB = gBodies[bIdx].m_pos;\n"
|
||||
" float4 linVelB = gBodies[bIdx].m_linVel;\n"
|
||||
" float4 angVelB = gBodies[bIdx].m_angVel;\n"
|
||||
" float invMassB = gBodies[bIdx].m_invMass;\n"
|
||||
" Matrix3x3 invInertiaB = gShapes[bIdx].m_invInertia;\n"
|
||||
" \n"
|
||||
" {\n"
|
||||
" float maxRambdaDt[4] = {FLT_MAX,FLT_MAX,FLT_MAX,FLT_MAX};\n"
|
||||
" float minRambdaDt[4] = {0.f,0.f,0.f,0.f};\n"
|
||||
" float sum = 0;\n"
|
||||
" for(int j=0; j<4; j++)\n"
|
||||
" {\n"
|
||||
" sum +=ldsCs[0].m_appliedRambdaDt[j];\n"
|
||||
" }\n"
|
||||
" frictionCoeff = 0.7f;\n"
|
||||
" for(int j=0; j<4; j++)\n"
|
||||
" {\n"
|
||||
" maxRambdaDt[j] = frictionCoeff*sum;\n"
|
||||
" minRambdaDt[j] = -maxRambdaDt[j];\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
"// solveFriction( ldsCs, posA, &linVelA, &angVelA, invMassA, invInertiaA,\n"
|
||||
"// posB, &linVelB, &angVelB, invMassB, invInertiaB, maxRambdaDt, minRambdaDt );\n"
|
||||
" \n"
|
||||
" \n"
|
||||
" {\n"
|
||||
" \n"
|
||||
" __global Constraint4* cs = ldsCs;\n"
|
||||
" \n"
|
||||
" if( cs->m_fJacCoeffInv[0] == 0 && cs->m_fJacCoeffInv[0] == 0 ) return;\n"
|
||||
" const float4 center = cs->m_center;\n"
|
||||
" \n"
|
||||
" float4 n = -cs->m_linear;\n"
|
||||
" \n"
|
||||
" float4 tangent[2];\n"
|
||||
" btPlaneSpace1(&n,&tangent[0],&tangent[1]);\n"
|
||||
" float4 angular0, angular1, linear;\n"
|
||||
" float4 r0 = center - posA;\n"
|
||||
" float4 r1 = center - posB;\n"
|
||||
" for(int i=0; i<2; i++)\n"
|
||||
" {\n"
|
||||
" setLinearAndAngular( tangent[i], r0, r1, &linear, &angular0, &angular1 );\n"
|
||||
" float rambdaDt = calcRelVel(linear, -linear, angular0, angular1,\n"
|
||||
" linVelA, angVelA, linVelB, angVelB );\n"
|
||||
" rambdaDt *= cs->m_fJacCoeffInv[i];\n"
|
||||
" \n"
|
||||
" {\n"
|
||||
" float prevSum = cs->m_fAppliedRambdaDt[i];\n"
|
||||
" float updated = prevSum;\n"
|
||||
" updated += rambdaDt;\n"
|
||||
" updated = max2( updated, minRambdaDt[i] );\n"
|
||||
" updated = min2( updated, maxRambdaDt[i] );\n"
|
||||
" rambdaDt = updated - prevSum;\n"
|
||||
" cs->m_fAppliedRambdaDt[i] = updated;\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" float4 linImp0 = invMassA*linear*rambdaDt;\n"
|
||||
" float4 linImp1 = invMassB*(-linear)*rambdaDt;\n"
|
||||
" float4 angImp0 = mtMul1(invInertiaA, angular0)*rambdaDt;\n"
|
||||
" float4 angImp1 = mtMul1(invInertiaB, angular1)*rambdaDt;\n"
|
||||
" \n"
|
||||
" linVelA += linImp0;\n"
|
||||
" angVelA += angImp0;\n"
|
||||
" linVelB += linImp1;\n"
|
||||
" angVelB += angImp1;\n"
|
||||
" }\n"
|
||||
" { // angular damping for point constraint\n"
|
||||
" float4 ab = normalize3( posB - posA );\n"
|
||||
" float4 ac = normalize3( center - posA );\n"
|
||||
" if( dot3F4( ab, ac ) > 0.95f || (invMassA == 0.f || invMassB == 0.f))\n"
|
||||
" {\n"
|
||||
" float angNA = dot3F4( n, angVelA );\n"
|
||||
" float angNB = dot3F4( n, angVelB );\n"
|
||||
" \n"
|
||||
" angVelA -= (angNA*0.1f)*n;\n"
|
||||
" angVelB -= (angNB*0.1f)*n;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" \n"
|
||||
" }\n"
|
||||
" if (gBodies[aIdx].m_invMass)\n"
|
||||
" {\n"
|
||||
" gBodies[aIdx].m_linVel = linVelA;\n"
|
||||
" gBodies[aIdx].m_angVel = angVelA;\n"
|
||||
" } else\n"
|
||||
" {\n"
|
||||
" gBodies[aIdx].m_linVel = mymake_float4(0,0,0,0);\n"
|
||||
" gBodies[aIdx].m_angVel = mymake_float4(0,0,0,0);\n"
|
||||
" }\n"
|
||||
" if (gBodies[bIdx].m_invMass)\n"
|
||||
" {\n"
|
||||
" gBodies[bIdx].m_linVel = linVelB;\n"
|
||||
" gBodies[bIdx].m_angVel = angVelB;\n"
|
||||
" } else\n"
|
||||
" {\n"
|
||||
" gBodies[bIdx].m_linVel = mymake_float4(0,0,0,0);\n"
|
||||
" gBodies[bIdx].m_angVel = mymake_float4(0,0,0,0);\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
"}\n"
|
||||
"typedef struct \n"
|
||||
"{\n"
|
||||
" int m_valInt0;\n"
|
||||
" int m_valInt1;\n"
|
||||
" int m_valInt2;\n"
|
||||
" int m_valInt3;\n"
|
||||
" float m_val0;\n"
|
||||
" float m_val1;\n"
|
||||
" float m_val2;\n"
|
||||
" float m_val3;\n"
|
||||
"} SolverDebugInfo;\n"
|
||||
"__kernel\n"
|
||||
"__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n"
|
||||
"void BatchSolveKernelFriction(__global Body* gBodies,\n"
|
||||
" __global Shape* gShapes,\n"
|
||||
" __global Constraint4* gConstraints,\n"
|
||||
" __global int* gN,\n"
|
||||
" __global int* gOffsets,\n"
|
||||
" __global int* batchSizes,\n"
|
||||
" int maxBatch1,\n"
|
||||
" int cellBatch,\n"
|
||||
" int4 nSplit\n"
|
||||
" )\n"
|
||||
"{\n"
|
||||
" //__local int ldsBatchIdx[WG_SIZE+1];\n"
|
||||
" __local int ldsCurBatch;\n"
|
||||
" __local int ldsNextBatch;\n"
|
||||
" __local int ldsStart;\n"
|
||||
" int lIdx = GET_LOCAL_IDX;\n"
|
||||
" int wgIdx = GET_GROUP_IDX;\n"
|
||||
"// int gIdx = GET_GLOBAL_IDX;\n"
|
||||
"// debugInfo[gIdx].m_valInt0 = gIdx;\n"
|
||||
" //debugInfo[gIdx].m_valInt1 = GET_GROUP_SIZE;\n"
|
||||
" int zIdx = (wgIdx/((nSplit.x*nSplit.y)/4))*2+((cellBatch&4)>>2);\n"
|
||||
" int remain= (wgIdx%((nSplit.x*nSplit.y)/4));\n"
|
||||
" int yIdx = (remain/(nSplit.x/2))*2 + ((cellBatch&2)>>1);\n"
|
||||
" int xIdx = (remain%(nSplit.x/2))*2 + (cellBatch&1);\n"
|
||||
" int cellIdx = xIdx+yIdx*nSplit.x+zIdx*(nSplit.x*nSplit.y);\n"
|
||||
" \n"
|
||||
" if( gN[cellIdx] == 0 ) \n"
|
||||
" return;\n"
|
||||
" int maxBatch = batchSizes[cellIdx];\n"
|
||||
" const int start = gOffsets[cellIdx];\n"
|
||||
" const int end = start + gN[cellIdx];\n"
|
||||
" \n"
|
||||
" if( lIdx == 0 )\n"
|
||||
" {\n"
|
||||
" ldsCurBatch = 0;\n"
|
||||
" ldsNextBatch = 0;\n"
|
||||
" ldsStart = start;\n"
|
||||
" }\n"
|
||||
" GROUP_LDS_BARRIER;\n"
|
||||
" int idx=ldsStart+lIdx;\n"
|
||||
" while (ldsCurBatch < maxBatch)\n"
|
||||
" {\n"
|
||||
" for(; idx<end; )\n"
|
||||
" {\n"
|
||||
" if (gConstraints[idx].m_batchIdx == ldsCurBatch)\n"
|
||||
" {\n"
|
||||
" solveFrictionConstraint( gBodies, gShapes, &gConstraints[idx] );\n"
|
||||
" idx+=64;\n"
|
||||
" } else\n"
|
||||
" {\n"
|
||||
" break;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" GROUP_LDS_BARRIER;\n"
|
||||
" if( lIdx == 0 )\n"
|
||||
" {\n"
|
||||
" ldsCurBatch++;\n"
|
||||
" }\n"
|
||||
" GROUP_LDS_BARRIER;\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" \n"
|
||||
"}\n"
|
||||
"__kernel void solveSingleFrictionKernel(__global Body* gBodies,\n"
|
||||
" __global Shape* gShapes,\n"
|
||||
" __global Constraint4* gConstraints,\n"
|
||||
" int cellIdx,\n"
|
||||
" int batchOffset,\n"
|
||||
" int numConstraintsInBatch\n"
|
||||
" )\n"
|
||||
"{\n"
|
||||
" int index = get_global_id(0);\n"
|
||||
" if (index < numConstraintsInBatch)\n"
|
||||
" {\n"
|
||||
" \n"
|
||||
" int idx=batchOffset+index;\n"
|
||||
" \n"
|
||||
" solveFrictionConstraint( gBodies, gShapes, &gConstraints[idx] );\n"
|
||||
" } \n"
|
||||
"}\n";
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,483 +1,482 @@
|
||||
//this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project
|
||||
static const char* updateAabbsKernelCL= \
|
||||
"#ifndef B3_UPDATE_AABBS_H\n"
|
||||
"#define B3_UPDATE_AABBS_H\n"
|
||||
"#ifndef B3_AABB_H\n"
|
||||
"#define B3_AABB_H\n"
|
||||
"#ifndef B3_FLOAT4_H\n"
|
||||
"#define B3_FLOAT4_H\n"
|
||||
"#ifndef B3_PLATFORM_DEFINITIONS_H\n"
|
||||
"#define B3_PLATFORM_DEFINITIONS_H\n"
|
||||
"struct MyTest\n"
|
||||
"{\n"
|
||||
" int bla;\n"
|
||||
"};\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"//keep B3_LARGE_FLOAT*B3_LARGE_FLOAT < FLT_MAX\n"
|
||||
"#define B3_LARGE_FLOAT 1e18f\n"
|
||||
"#define B3_INFINITY 1e18f\n"
|
||||
"#define b3Assert(a)\n"
|
||||
"#define b3ConstArray(a) __global const a*\n"
|
||||
"#define b3AtomicInc atomic_inc\n"
|
||||
"#define b3AtomicAdd atomic_add\n"
|
||||
"#define b3Fabs fabs\n"
|
||||
"#define b3Sqrt native_sqrt\n"
|
||||
"#define b3Sin native_sin\n"
|
||||
"#define b3Cos native_cos\n"
|
||||
"#define B3_STATIC\n"
|
||||
"#endif\n"
|
||||
"#endif\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
" typedef float4 b3Float4;\n"
|
||||
" #define b3Float4ConstArg const b3Float4\n"
|
||||
" #define b3MakeFloat4 (float4)\n"
|
||||
" float b3Dot3F4(b3Float4ConstArg v0,b3Float4ConstArg v1)\n"
|
||||
" {\n"
|
||||
" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n"
|
||||
" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n"
|
||||
" return dot(a1, b1);\n"
|
||||
" }\n"
|
||||
" b3Float4 b3Cross3(b3Float4ConstArg v0,b3Float4ConstArg v1)\n"
|
||||
" {\n"
|
||||
" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n"
|
||||
" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n"
|
||||
" return cross(a1, b1);\n"
|
||||
" }\n"
|
||||
" #define b3MinFloat4 min\n"
|
||||
" #define b3MaxFloat4 max\n"
|
||||
" #define b3Normalized(a) normalize(a)\n"
|
||||
"#endif \n"
|
||||
" \n"
|
||||
"inline bool b3IsAlmostZero(b3Float4ConstArg v)\n"
|
||||
"{\n"
|
||||
" if(b3Fabs(v.x)>1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n"
|
||||
" return false;\n"
|
||||
" return true;\n"
|
||||
"}\n"
|
||||
"inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n"
|
||||
"{\n"
|
||||
" float maxDot = -B3_INFINITY;\n"
|
||||
" int i = 0;\n"
|
||||
" int ptIndex = -1;\n"
|
||||
" for( i = 0; i < vecLen; i++ )\n"
|
||||
" {\n"
|
||||
" float dot = b3Dot3F4(vecArray[i],vec);\n"
|
||||
" \n"
|
||||
" if( dot > maxDot )\n"
|
||||
" {\n"
|
||||
" maxDot = dot;\n"
|
||||
" ptIndex = i;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" b3Assert(ptIndex>=0);\n"
|
||||
" if (ptIndex<0)\n"
|
||||
" {\n"
|
||||
" ptIndex = 0;\n"
|
||||
" }\n"
|
||||
" *dotOut = maxDot;\n"
|
||||
" return ptIndex;\n"
|
||||
"}\n"
|
||||
"#endif //B3_FLOAT4_H\n"
|
||||
"#ifndef B3_MAT3x3_H\n"
|
||||
"#define B3_MAT3x3_H\n"
|
||||
"#ifndef B3_QUAT_H\n"
|
||||
"#define B3_QUAT_H\n"
|
||||
"#ifndef B3_PLATFORM_DEFINITIONS_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"#endif\n"
|
||||
"#endif\n"
|
||||
"#ifndef B3_FLOAT4_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"#endif \n"
|
||||
"#endif //B3_FLOAT4_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
" typedef float4 b3Quat;\n"
|
||||
" #define b3QuatConstArg const b3Quat\n"
|
||||
" \n"
|
||||
" \n"
|
||||
"inline float4 b3FastNormalize4(float4 v)\n"
|
||||
"{\n"
|
||||
" v = (float4)(v.xyz,0.f);\n"
|
||||
" return fast_normalize(v);\n"
|
||||
"}\n"
|
||||
" \n"
|
||||
"inline b3Quat b3QuatMul(b3Quat a, b3Quat b);\n"
|
||||
"inline b3Quat b3QuatNormalized(b3QuatConstArg in);\n"
|
||||
"inline b3Quat b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec);\n"
|
||||
"inline b3Quat b3QuatInvert(b3QuatConstArg q);\n"
|
||||
"inline b3Quat b3QuatInverse(b3QuatConstArg q);\n"
|
||||
"inline b3Quat b3QuatMul(b3QuatConstArg a, b3QuatConstArg b)\n"
|
||||
"{\n"
|
||||
" b3Quat ans;\n"
|
||||
" ans = b3Cross3( a, b );\n"
|
||||
" ans += a.w*b+b.w*a;\n"
|
||||
"// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n"
|
||||
" ans.w = a.w*b.w - b3Dot3F4(a, b);\n"
|
||||
" return ans;\n"
|
||||
"}\n"
|
||||
"inline b3Quat b3QuatNormalized(b3QuatConstArg in)\n"
|
||||
"{\n"
|
||||
" b3Quat q;\n"
|
||||
" q=in;\n"
|
||||
" //return b3FastNormalize4(in);\n"
|
||||
" float len = native_sqrt(dot(q, q));\n"
|
||||
" if(len > 0.f)\n"
|
||||
" {\n"
|
||||
" q *= 1.f / len;\n"
|
||||
" }\n"
|
||||
" else\n"
|
||||
" {\n"
|
||||
" q.x = q.y = q.z = 0.f;\n"
|
||||
" q.w = 1.f;\n"
|
||||
" }\n"
|
||||
" return q;\n"
|
||||
"}\n"
|
||||
"inline float4 b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec)\n"
|
||||
"{\n"
|
||||
" b3Quat qInv = b3QuatInvert( q );\n"
|
||||
" float4 vcpy = vec;\n"
|
||||
" vcpy.w = 0.f;\n"
|
||||
" float4 out = b3QuatMul(b3QuatMul(q,vcpy),qInv);\n"
|
||||
" return out;\n"
|
||||
"}\n"
|
||||
"inline b3Quat b3QuatInverse(b3QuatConstArg q)\n"
|
||||
"{\n"
|
||||
" return (b3Quat)(-q.xyz, q.w);\n"
|
||||
"}\n"
|
||||
"inline b3Quat b3QuatInvert(b3QuatConstArg q)\n"
|
||||
"{\n"
|
||||
" return (b3Quat)(-q.xyz, q.w);\n"
|
||||
"}\n"
|
||||
"inline float4 b3QuatInvRotate(b3QuatConstArg q, b3QuatConstArg vec)\n"
|
||||
"{\n"
|
||||
" return b3QuatRotate( b3QuatInvert( q ), vec );\n"
|
||||
"}\n"
|
||||
"inline b3Float4 b3TransformPoint(b3Float4ConstArg point, b3Float4ConstArg translation, b3QuatConstArg orientation)\n"
|
||||
"{\n"
|
||||
" return b3QuatRotate( orientation, point ) + (translation);\n"
|
||||
"}\n"
|
||||
" \n"
|
||||
"#endif \n"
|
||||
"#endif //B3_QUAT_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" b3Float4 m_row[3];\n"
|
||||
"}b3Mat3x3;\n"
|
||||
"#define b3Mat3x3ConstArg const b3Mat3x3\n"
|
||||
"#define b3GetRow(m,row) (m.m_row[row])\n"
|
||||
"inline b3Mat3x3 b3QuatGetRotationMatrix(b3Quat quat)\n"
|
||||
"{\n"
|
||||
" b3Float4 quat2 = (b3Float4)(quat.x*quat.x, quat.y*quat.y, quat.z*quat.z, 0.f);\n"
|
||||
" b3Mat3x3 out;\n"
|
||||
" out.m_row[0].x=1-2*quat2.y-2*quat2.z;\n"
|
||||
" out.m_row[0].y=2*quat.x*quat.y-2*quat.w*quat.z;\n"
|
||||
" out.m_row[0].z=2*quat.x*quat.z+2*quat.w*quat.y;\n"
|
||||
" out.m_row[0].w = 0.f;\n"
|
||||
" out.m_row[1].x=2*quat.x*quat.y+2*quat.w*quat.z;\n"
|
||||
" out.m_row[1].y=1-2*quat2.x-2*quat2.z;\n"
|
||||
" out.m_row[1].z=2*quat.y*quat.z-2*quat.w*quat.x;\n"
|
||||
" out.m_row[1].w = 0.f;\n"
|
||||
" out.m_row[2].x=2*quat.x*quat.z-2*quat.w*quat.y;\n"
|
||||
" out.m_row[2].y=2*quat.y*quat.z+2*quat.w*quat.x;\n"
|
||||
" out.m_row[2].z=1-2*quat2.x-2*quat2.y;\n"
|
||||
" out.m_row[2].w = 0.f;\n"
|
||||
" return out;\n"
|
||||
"}\n"
|
||||
"inline b3Mat3x3 b3AbsoluteMat3x3(b3Mat3x3ConstArg matIn)\n"
|
||||
"{\n"
|
||||
" b3Mat3x3 out;\n"
|
||||
" out.m_row[0] = fabs(matIn.m_row[0]);\n"
|
||||
" out.m_row[1] = fabs(matIn.m_row[1]);\n"
|
||||
" out.m_row[2] = fabs(matIn.m_row[2]);\n"
|
||||
" return out;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtZero();\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtIdentity();\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtTranspose(b3Mat3x3 m);\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b);\n"
|
||||
"__inline\n"
|
||||
"b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b);\n"
|
||||
"__inline\n"
|
||||
"b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b);\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtZero()\n"
|
||||
"{\n"
|
||||
" b3Mat3x3 m;\n"
|
||||
" m.m_row[0] = (b3Float4)(0.f);\n"
|
||||
" m.m_row[1] = (b3Float4)(0.f);\n"
|
||||
" m.m_row[2] = (b3Float4)(0.f);\n"
|
||||
" return m;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtIdentity()\n"
|
||||
"{\n"
|
||||
" b3Mat3x3 m;\n"
|
||||
" m.m_row[0] = (b3Float4)(1,0,0,0);\n"
|
||||
" m.m_row[1] = (b3Float4)(0,1,0,0);\n"
|
||||
" m.m_row[2] = (b3Float4)(0,0,1,0);\n"
|
||||
" return m;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtTranspose(b3Mat3x3 m)\n"
|
||||
"{\n"
|
||||
" b3Mat3x3 out;\n"
|
||||
" out.m_row[0] = (b3Float4)(m.m_row[0].x, m.m_row[1].x, m.m_row[2].x, 0.f);\n"
|
||||
" out.m_row[1] = (b3Float4)(m.m_row[0].y, m.m_row[1].y, m.m_row[2].y, 0.f);\n"
|
||||
" out.m_row[2] = (b3Float4)(m.m_row[0].z, m.m_row[1].z, m.m_row[2].z, 0.f);\n"
|
||||
" return out;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b)\n"
|
||||
"{\n"
|
||||
" b3Mat3x3 transB;\n"
|
||||
" transB = mtTranspose( b );\n"
|
||||
" b3Mat3x3 ans;\n"
|
||||
" // why this doesn't run when 0ing in the for{}\n"
|
||||
" a.m_row[0].w = 0.f;\n"
|
||||
" a.m_row[1].w = 0.f;\n"
|
||||
" a.m_row[2].w = 0.f;\n"
|
||||
" for(int i=0; i<3; i++)\n"
|
||||
" {\n"
|
||||
"// a.m_row[i].w = 0.f;\n"
|
||||
" ans.m_row[i].x = b3Dot3F4(a.m_row[i],transB.m_row[0]);\n"
|
||||
" ans.m_row[i].y = b3Dot3F4(a.m_row[i],transB.m_row[1]);\n"
|
||||
" ans.m_row[i].z = b3Dot3F4(a.m_row[i],transB.m_row[2]);\n"
|
||||
" ans.m_row[i].w = 0.f;\n"
|
||||
" }\n"
|
||||
" return ans;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b)\n"
|
||||
"{\n"
|
||||
" b3Float4 ans;\n"
|
||||
" ans.x = b3Dot3F4( a.m_row[0], b );\n"
|
||||
" ans.y = b3Dot3F4( a.m_row[1], b );\n"
|
||||
" ans.z = b3Dot3F4( a.m_row[2], b );\n"
|
||||
" ans.w = 0.f;\n"
|
||||
" return ans;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b)\n"
|
||||
"{\n"
|
||||
" b3Float4 colx = b3MakeFloat4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n"
|
||||
" b3Float4 coly = b3MakeFloat4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n"
|
||||
" b3Float4 colz = b3MakeFloat4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n"
|
||||
" b3Float4 ans;\n"
|
||||
" ans.x = b3Dot3F4( a, colx );\n"
|
||||
" ans.y = b3Dot3F4( a, coly );\n"
|
||||
" ans.z = b3Dot3F4( a, colz );\n"
|
||||
" return ans;\n"
|
||||
"}\n"
|
||||
"#endif\n"
|
||||
"#endif //B3_MAT3x3_H\n"
|
||||
"typedef struct b3Aabb b3Aabb_t;\n"
|
||||
"struct b3Aabb\n"
|
||||
"{\n"
|
||||
" union\n"
|
||||
" {\n"
|
||||
" float m_min[4];\n"
|
||||
" b3Float4 m_minVec;\n"
|
||||
" int m_minIndices[4];\n"
|
||||
" };\n"
|
||||
" union\n"
|
||||
" {\n"
|
||||
" float m_max[4];\n"
|
||||
" b3Float4 m_maxVec;\n"
|
||||
" int m_signedMaxIndices[4];\n"
|
||||
" };\n"
|
||||
"};\n"
|
||||
"inline void b3TransformAabb2(b3Float4ConstArg localAabbMin,b3Float4ConstArg localAabbMax, float margin,\n"
|
||||
" b3Float4ConstArg pos,\n"
|
||||
" b3QuatConstArg orn,\n"
|
||||
" b3Float4* aabbMinOut,b3Float4* aabbMaxOut)\n"
|
||||
"{\n"
|
||||
" b3Float4 localHalfExtents = 0.5f*(localAabbMax-localAabbMin);\n"
|
||||
" localHalfExtents+=b3MakeFloat4(margin,margin,margin,0.f);\n"
|
||||
" b3Float4 localCenter = 0.5f*(localAabbMax+localAabbMin);\n"
|
||||
" b3Mat3x3 m;\n"
|
||||
" m = b3QuatGetRotationMatrix(orn);\n"
|
||||
" b3Mat3x3 abs_b = b3AbsoluteMat3x3(m);\n"
|
||||
" b3Float4 center = b3TransformPoint(localCenter,pos,orn);\n"
|
||||
" \n"
|
||||
" b3Float4 extent = b3MakeFloat4(b3Dot3F4(localHalfExtents,b3GetRow(abs_b,0)),\n"
|
||||
" b3Dot3F4(localHalfExtents,b3GetRow(abs_b,1)),\n"
|
||||
" b3Dot3F4(localHalfExtents,b3GetRow(abs_b,2)),\n"
|
||||
" 0.f);\n"
|
||||
" *aabbMinOut = center-extent;\n"
|
||||
" *aabbMaxOut = center+extent;\n"
|
||||
"}\n"
|
||||
"/// conservative test for overlap between two aabbs\n"
|
||||
"inline bool b3TestAabbAgainstAabb(b3Float4ConstArg aabbMin1,b3Float4ConstArg aabbMax1,\n"
|
||||
" b3Float4ConstArg aabbMin2, b3Float4ConstArg aabbMax2)\n"
|
||||
"{\n"
|
||||
" bool overlap = true;\n"
|
||||
" overlap = (aabbMin1.x > aabbMax2.x || aabbMax1.x < aabbMin2.x) ? false : overlap;\n"
|
||||
" overlap = (aabbMin1.z > aabbMax2.z || aabbMax1.z < aabbMin2.z) ? false : overlap;\n"
|
||||
" overlap = (aabbMin1.y > aabbMax2.y || aabbMax1.y < aabbMin2.y) ? false : overlap;\n"
|
||||
" return overlap;\n"
|
||||
"}\n"
|
||||
"#endif //B3_AABB_H\n"
|
||||
"#ifndef B3_COLLIDABLE_H\n"
|
||||
"#define B3_COLLIDABLE_H\n"
|
||||
"#ifndef B3_FLOAT4_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"#endif \n"
|
||||
"#endif //B3_FLOAT4_H\n"
|
||||
"#ifndef B3_QUAT_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"#endif \n"
|
||||
"#endif //B3_QUAT_H\n"
|
||||
"enum b3ShapeTypes\n"
|
||||
"{\n"
|
||||
" SHAPE_HEIGHT_FIELD=1,\n"
|
||||
" SHAPE_CONVEX_HULL=3,\n"
|
||||
" SHAPE_PLANE=4,\n"
|
||||
" SHAPE_CONCAVE_TRIMESH=5,\n"
|
||||
" SHAPE_COMPOUND_OF_CONVEX_HULLS=6,\n"
|
||||
" SHAPE_SPHERE=7,\n"
|
||||
" MAX_NUM_SHAPE_TYPES,\n"
|
||||
"};\n"
|
||||
"typedef struct b3Collidable b3Collidable_t;\n"
|
||||
"struct b3Collidable\n"
|
||||
"{\n"
|
||||
" union {\n"
|
||||
" int m_numChildShapes;\n"
|
||||
" int m_bvhIndex;\n"
|
||||
" };\n"
|
||||
" union\n"
|
||||
" {\n"
|
||||
" float m_radius;\n"
|
||||
" int m_compoundBvhIndex;\n"
|
||||
" };\n"
|
||||
" int m_shapeType;\n"
|
||||
" union\n"
|
||||
" {\n"
|
||||
" int m_shapeIndex;\n"
|
||||
" float m_height;\n"
|
||||
" };\n"
|
||||
"};\n"
|
||||
"typedef struct b3GpuChildShape b3GpuChildShape_t;\n"
|
||||
"struct b3GpuChildShape\n"
|
||||
"{\n"
|
||||
" b3Float4 m_childPosition;\n"
|
||||
" b3Quat m_childOrientation;\n"
|
||||
" union\n"
|
||||
" {\n"
|
||||
" int m_shapeIndex;//used for SHAPE_COMPOUND_OF_CONVEX_HULLS\n"
|
||||
" int m_capsuleAxis;\n"
|
||||
" };\n"
|
||||
" union \n"
|
||||
" {\n"
|
||||
" float m_radius;//used for childshape of SHAPE_COMPOUND_OF_SPHERES or SHAPE_COMPOUND_OF_CAPSULES\n"
|
||||
" int m_numChildShapes;//used for compound shape\n"
|
||||
" };\n"
|
||||
" union \n"
|
||||
" {\n"
|
||||
" float m_height;//used for childshape of SHAPE_COMPOUND_OF_CAPSULES\n"
|
||||
" int m_collidableShapeIndex;\n"
|
||||
" };\n"
|
||||
" int m_shapeType;\n"
|
||||
"};\n"
|
||||
"struct b3CompoundOverlappingPair\n"
|
||||
"{\n"
|
||||
" int m_bodyIndexA;\n"
|
||||
" int m_bodyIndexB;\n"
|
||||
"// int m_pairType;\n"
|
||||
" int m_childShapeIndexA;\n"
|
||||
" int m_childShapeIndexB;\n"
|
||||
"};\n"
|
||||
"#endif //B3_COLLIDABLE_H\n"
|
||||
"#ifndef B3_RIGIDBODY_DATA_H\n"
|
||||
"#define B3_RIGIDBODY_DATA_H\n"
|
||||
"#ifndef B3_FLOAT4_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"#endif \n"
|
||||
"#endif //B3_FLOAT4_H\n"
|
||||
"#ifndef B3_QUAT_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"#endif \n"
|
||||
"#endif //B3_QUAT_H\n"
|
||||
"#ifndef B3_MAT3x3_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"#endif\n"
|
||||
"#endif //B3_MAT3x3_H\n"
|
||||
"typedef struct b3RigidBodyData b3RigidBodyData_t;\n"
|
||||
"struct b3RigidBodyData\n"
|
||||
"{\n"
|
||||
" b3Float4 m_pos;\n"
|
||||
" b3Quat m_quat;\n"
|
||||
" b3Float4 m_linVel;\n"
|
||||
" b3Float4 m_angVel;\n"
|
||||
" int m_collidableIdx;\n"
|
||||
" float m_invMass;\n"
|
||||
" float m_restituitionCoeff;\n"
|
||||
" float m_frictionCoeff;\n"
|
||||
"};\n"
|
||||
"typedef struct b3InertiaData b3InertiaData_t;\n"
|
||||
"struct b3InertiaData\n"
|
||||
"{\n"
|
||||
" b3Mat3x3 m_invInertiaWorld;\n"
|
||||
" b3Mat3x3 m_initInvInertia;\n"
|
||||
"};\n"
|
||||
"#endif //B3_RIGIDBODY_DATA_H\n"
|
||||
" \n"
|
||||
"void b3ComputeWorldAabb( int bodyId, __global const b3RigidBodyData_t* bodies, __global const b3Collidable_t* collidables, __global const b3Aabb_t* localShapeAABB, __global b3Aabb_t* worldAabbs)\n"
|
||||
"{\n"
|
||||
" __global const b3RigidBodyData_t* body = &bodies[bodyId];\n"
|
||||
" b3Float4 position = body->m_pos;\n"
|
||||
" b3Quat orientation = body->m_quat;\n"
|
||||
" \n"
|
||||
" int collidableIndex = body->m_collidableIdx;\n"
|
||||
" int shapeIndex = collidables[collidableIndex].m_shapeIndex;\n"
|
||||
" \n"
|
||||
" if (shapeIndex>=0)\n"
|
||||
" {\n"
|
||||
" \n"
|
||||
" b3Aabb_t localAabb = localShapeAABB[collidableIndex];\n"
|
||||
" b3Aabb_t worldAabb;\n"
|
||||
" \n"
|
||||
" b3Float4 aabbAMinOut,aabbAMaxOut; \n"
|
||||
" float margin = 0.f;\n"
|
||||
" b3TransformAabb2(localAabb.m_minVec,localAabb.m_maxVec,margin,position,orientation,&aabbAMinOut,&aabbAMaxOut);\n"
|
||||
" \n"
|
||||
" worldAabb.m_minVec =aabbAMinOut;\n"
|
||||
" worldAabb.m_minIndices[3] = bodyId;\n"
|
||||
" worldAabb.m_maxVec = aabbAMaxOut;\n"
|
||||
" worldAabb.m_signedMaxIndices[3] = body[bodyId].m_invMass==0.f? 0 : 1;\n"
|
||||
" worldAabbs[bodyId] = worldAabb;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"#endif //B3_UPDATE_AABBS_H\n"
|
||||
"__kernel void initializeGpuAabbsFull( const int numNodes, __global b3RigidBodyData_t* gBodies,__global b3Collidable_t* collidables, __global b3Aabb_t* plocalShapeAABB, __global b3Aabb_t* pAABB)\n"
|
||||
"{\n"
|
||||
" int nodeID = get_global_id(0);\n"
|
||||
" if( nodeID < numNodes )\n"
|
||||
" {\n"
|
||||
" b3ComputeWorldAabb(nodeID, gBodies, collidables, plocalShapeAABB,pAABB);\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"__kernel void clearOverlappingPairsKernel( __global int4* pairs, int numPairs)\n"
|
||||
"{\n"
|
||||
" int pairId = get_global_id(0);\n"
|
||||
" if( pairId< numPairs )\n"
|
||||
" {\n"
|
||||
" pairs[pairId].z = 0xffffffff;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
;
|
||||
static const char* updateAabbsKernelCL =
|
||||
"#ifndef B3_UPDATE_AABBS_H\n"
|
||||
"#define B3_UPDATE_AABBS_H\n"
|
||||
"#ifndef B3_AABB_H\n"
|
||||
"#define B3_AABB_H\n"
|
||||
"#ifndef B3_FLOAT4_H\n"
|
||||
"#define B3_FLOAT4_H\n"
|
||||
"#ifndef B3_PLATFORM_DEFINITIONS_H\n"
|
||||
"#define B3_PLATFORM_DEFINITIONS_H\n"
|
||||
"struct MyTest\n"
|
||||
"{\n"
|
||||
" int bla;\n"
|
||||
"};\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"//keep B3_LARGE_FLOAT*B3_LARGE_FLOAT < FLT_MAX\n"
|
||||
"#define B3_LARGE_FLOAT 1e18f\n"
|
||||
"#define B3_INFINITY 1e18f\n"
|
||||
"#define b3Assert(a)\n"
|
||||
"#define b3ConstArray(a) __global const a*\n"
|
||||
"#define b3AtomicInc atomic_inc\n"
|
||||
"#define b3AtomicAdd atomic_add\n"
|
||||
"#define b3Fabs fabs\n"
|
||||
"#define b3Sqrt native_sqrt\n"
|
||||
"#define b3Sin native_sin\n"
|
||||
"#define b3Cos native_cos\n"
|
||||
"#define B3_STATIC\n"
|
||||
"#endif\n"
|
||||
"#endif\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
" typedef float4 b3Float4;\n"
|
||||
" #define b3Float4ConstArg const b3Float4\n"
|
||||
" #define b3MakeFloat4 (float4)\n"
|
||||
" float b3Dot3F4(b3Float4ConstArg v0,b3Float4ConstArg v1)\n"
|
||||
" {\n"
|
||||
" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n"
|
||||
" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n"
|
||||
" return dot(a1, b1);\n"
|
||||
" }\n"
|
||||
" b3Float4 b3Cross3(b3Float4ConstArg v0,b3Float4ConstArg v1)\n"
|
||||
" {\n"
|
||||
" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n"
|
||||
" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n"
|
||||
" return cross(a1, b1);\n"
|
||||
" }\n"
|
||||
" #define b3MinFloat4 min\n"
|
||||
" #define b3MaxFloat4 max\n"
|
||||
" #define b3Normalized(a) normalize(a)\n"
|
||||
"#endif \n"
|
||||
" \n"
|
||||
"inline bool b3IsAlmostZero(b3Float4ConstArg v)\n"
|
||||
"{\n"
|
||||
" if(b3Fabs(v.x)>1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n"
|
||||
" return false;\n"
|
||||
" return true;\n"
|
||||
"}\n"
|
||||
"inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n"
|
||||
"{\n"
|
||||
" float maxDot = -B3_INFINITY;\n"
|
||||
" int i = 0;\n"
|
||||
" int ptIndex = -1;\n"
|
||||
" for( i = 0; i < vecLen; i++ )\n"
|
||||
" {\n"
|
||||
" float dot = b3Dot3F4(vecArray[i],vec);\n"
|
||||
" \n"
|
||||
" if( dot > maxDot )\n"
|
||||
" {\n"
|
||||
" maxDot = dot;\n"
|
||||
" ptIndex = i;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" b3Assert(ptIndex>=0);\n"
|
||||
" if (ptIndex<0)\n"
|
||||
" {\n"
|
||||
" ptIndex = 0;\n"
|
||||
" }\n"
|
||||
" *dotOut = maxDot;\n"
|
||||
" return ptIndex;\n"
|
||||
"}\n"
|
||||
"#endif //B3_FLOAT4_H\n"
|
||||
"#ifndef B3_MAT3x3_H\n"
|
||||
"#define B3_MAT3x3_H\n"
|
||||
"#ifndef B3_QUAT_H\n"
|
||||
"#define B3_QUAT_H\n"
|
||||
"#ifndef B3_PLATFORM_DEFINITIONS_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"#endif\n"
|
||||
"#endif\n"
|
||||
"#ifndef B3_FLOAT4_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"#endif \n"
|
||||
"#endif //B3_FLOAT4_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
" typedef float4 b3Quat;\n"
|
||||
" #define b3QuatConstArg const b3Quat\n"
|
||||
" \n"
|
||||
" \n"
|
||||
"inline float4 b3FastNormalize4(float4 v)\n"
|
||||
"{\n"
|
||||
" v = (float4)(v.xyz,0.f);\n"
|
||||
" return fast_normalize(v);\n"
|
||||
"}\n"
|
||||
" \n"
|
||||
"inline b3Quat b3QuatMul(b3Quat a, b3Quat b);\n"
|
||||
"inline b3Quat b3QuatNormalized(b3QuatConstArg in);\n"
|
||||
"inline b3Quat b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec);\n"
|
||||
"inline b3Quat b3QuatInvert(b3QuatConstArg q);\n"
|
||||
"inline b3Quat b3QuatInverse(b3QuatConstArg q);\n"
|
||||
"inline b3Quat b3QuatMul(b3QuatConstArg a, b3QuatConstArg b)\n"
|
||||
"{\n"
|
||||
" b3Quat ans;\n"
|
||||
" ans = b3Cross3( a, b );\n"
|
||||
" ans += a.w*b+b.w*a;\n"
|
||||
"// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n"
|
||||
" ans.w = a.w*b.w - b3Dot3F4(a, b);\n"
|
||||
" return ans;\n"
|
||||
"}\n"
|
||||
"inline b3Quat b3QuatNormalized(b3QuatConstArg in)\n"
|
||||
"{\n"
|
||||
" b3Quat q;\n"
|
||||
" q=in;\n"
|
||||
" //return b3FastNormalize4(in);\n"
|
||||
" float len = native_sqrt(dot(q, q));\n"
|
||||
" if(len > 0.f)\n"
|
||||
" {\n"
|
||||
" q *= 1.f / len;\n"
|
||||
" }\n"
|
||||
" else\n"
|
||||
" {\n"
|
||||
" q.x = q.y = q.z = 0.f;\n"
|
||||
" q.w = 1.f;\n"
|
||||
" }\n"
|
||||
" return q;\n"
|
||||
"}\n"
|
||||
"inline float4 b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec)\n"
|
||||
"{\n"
|
||||
" b3Quat qInv = b3QuatInvert( q );\n"
|
||||
" float4 vcpy = vec;\n"
|
||||
" vcpy.w = 0.f;\n"
|
||||
" float4 out = b3QuatMul(b3QuatMul(q,vcpy),qInv);\n"
|
||||
" return out;\n"
|
||||
"}\n"
|
||||
"inline b3Quat b3QuatInverse(b3QuatConstArg q)\n"
|
||||
"{\n"
|
||||
" return (b3Quat)(-q.xyz, q.w);\n"
|
||||
"}\n"
|
||||
"inline b3Quat b3QuatInvert(b3QuatConstArg q)\n"
|
||||
"{\n"
|
||||
" return (b3Quat)(-q.xyz, q.w);\n"
|
||||
"}\n"
|
||||
"inline float4 b3QuatInvRotate(b3QuatConstArg q, b3QuatConstArg vec)\n"
|
||||
"{\n"
|
||||
" return b3QuatRotate( b3QuatInvert( q ), vec );\n"
|
||||
"}\n"
|
||||
"inline b3Float4 b3TransformPoint(b3Float4ConstArg point, b3Float4ConstArg translation, b3QuatConstArg orientation)\n"
|
||||
"{\n"
|
||||
" return b3QuatRotate( orientation, point ) + (translation);\n"
|
||||
"}\n"
|
||||
" \n"
|
||||
"#endif \n"
|
||||
"#endif //B3_QUAT_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" b3Float4 m_row[3];\n"
|
||||
"}b3Mat3x3;\n"
|
||||
"#define b3Mat3x3ConstArg const b3Mat3x3\n"
|
||||
"#define b3GetRow(m,row) (m.m_row[row])\n"
|
||||
"inline b3Mat3x3 b3QuatGetRotationMatrix(b3Quat quat)\n"
|
||||
"{\n"
|
||||
" b3Float4 quat2 = (b3Float4)(quat.x*quat.x, quat.y*quat.y, quat.z*quat.z, 0.f);\n"
|
||||
" b3Mat3x3 out;\n"
|
||||
" out.m_row[0].x=1-2*quat2.y-2*quat2.z;\n"
|
||||
" out.m_row[0].y=2*quat.x*quat.y-2*quat.w*quat.z;\n"
|
||||
" out.m_row[0].z=2*quat.x*quat.z+2*quat.w*quat.y;\n"
|
||||
" out.m_row[0].w = 0.f;\n"
|
||||
" out.m_row[1].x=2*quat.x*quat.y+2*quat.w*quat.z;\n"
|
||||
" out.m_row[1].y=1-2*quat2.x-2*quat2.z;\n"
|
||||
" out.m_row[1].z=2*quat.y*quat.z-2*quat.w*quat.x;\n"
|
||||
" out.m_row[1].w = 0.f;\n"
|
||||
" out.m_row[2].x=2*quat.x*quat.z-2*quat.w*quat.y;\n"
|
||||
" out.m_row[2].y=2*quat.y*quat.z+2*quat.w*quat.x;\n"
|
||||
" out.m_row[2].z=1-2*quat2.x-2*quat2.y;\n"
|
||||
" out.m_row[2].w = 0.f;\n"
|
||||
" return out;\n"
|
||||
"}\n"
|
||||
"inline b3Mat3x3 b3AbsoluteMat3x3(b3Mat3x3ConstArg matIn)\n"
|
||||
"{\n"
|
||||
" b3Mat3x3 out;\n"
|
||||
" out.m_row[0] = fabs(matIn.m_row[0]);\n"
|
||||
" out.m_row[1] = fabs(matIn.m_row[1]);\n"
|
||||
" out.m_row[2] = fabs(matIn.m_row[2]);\n"
|
||||
" return out;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtZero();\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtIdentity();\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtTranspose(b3Mat3x3 m);\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b);\n"
|
||||
"__inline\n"
|
||||
"b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b);\n"
|
||||
"__inline\n"
|
||||
"b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b);\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtZero()\n"
|
||||
"{\n"
|
||||
" b3Mat3x3 m;\n"
|
||||
" m.m_row[0] = (b3Float4)(0.f);\n"
|
||||
" m.m_row[1] = (b3Float4)(0.f);\n"
|
||||
" m.m_row[2] = (b3Float4)(0.f);\n"
|
||||
" return m;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtIdentity()\n"
|
||||
"{\n"
|
||||
" b3Mat3x3 m;\n"
|
||||
" m.m_row[0] = (b3Float4)(1,0,0,0);\n"
|
||||
" m.m_row[1] = (b3Float4)(0,1,0,0);\n"
|
||||
" m.m_row[2] = (b3Float4)(0,0,1,0);\n"
|
||||
" return m;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtTranspose(b3Mat3x3 m)\n"
|
||||
"{\n"
|
||||
" b3Mat3x3 out;\n"
|
||||
" out.m_row[0] = (b3Float4)(m.m_row[0].x, m.m_row[1].x, m.m_row[2].x, 0.f);\n"
|
||||
" out.m_row[1] = (b3Float4)(m.m_row[0].y, m.m_row[1].y, m.m_row[2].y, 0.f);\n"
|
||||
" out.m_row[2] = (b3Float4)(m.m_row[0].z, m.m_row[1].z, m.m_row[2].z, 0.f);\n"
|
||||
" return out;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b)\n"
|
||||
"{\n"
|
||||
" b3Mat3x3 transB;\n"
|
||||
" transB = mtTranspose( b );\n"
|
||||
" b3Mat3x3 ans;\n"
|
||||
" // why this doesn't run when 0ing in the for{}\n"
|
||||
" a.m_row[0].w = 0.f;\n"
|
||||
" a.m_row[1].w = 0.f;\n"
|
||||
" a.m_row[2].w = 0.f;\n"
|
||||
" for(int i=0; i<3; i++)\n"
|
||||
" {\n"
|
||||
"// a.m_row[i].w = 0.f;\n"
|
||||
" ans.m_row[i].x = b3Dot3F4(a.m_row[i],transB.m_row[0]);\n"
|
||||
" ans.m_row[i].y = b3Dot3F4(a.m_row[i],transB.m_row[1]);\n"
|
||||
" ans.m_row[i].z = b3Dot3F4(a.m_row[i],transB.m_row[2]);\n"
|
||||
" ans.m_row[i].w = 0.f;\n"
|
||||
" }\n"
|
||||
" return ans;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b)\n"
|
||||
"{\n"
|
||||
" b3Float4 ans;\n"
|
||||
" ans.x = b3Dot3F4( a.m_row[0], b );\n"
|
||||
" ans.y = b3Dot3F4( a.m_row[1], b );\n"
|
||||
" ans.z = b3Dot3F4( a.m_row[2], b );\n"
|
||||
" ans.w = 0.f;\n"
|
||||
" return ans;\n"
|
||||
"}\n"
|
||||
"__inline\n"
|
||||
"b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b)\n"
|
||||
"{\n"
|
||||
" b3Float4 colx = b3MakeFloat4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n"
|
||||
" b3Float4 coly = b3MakeFloat4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n"
|
||||
" b3Float4 colz = b3MakeFloat4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n"
|
||||
" b3Float4 ans;\n"
|
||||
" ans.x = b3Dot3F4( a, colx );\n"
|
||||
" ans.y = b3Dot3F4( a, coly );\n"
|
||||
" ans.z = b3Dot3F4( a, colz );\n"
|
||||
" return ans;\n"
|
||||
"}\n"
|
||||
"#endif\n"
|
||||
"#endif //B3_MAT3x3_H\n"
|
||||
"typedef struct b3Aabb b3Aabb_t;\n"
|
||||
"struct b3Aabb\n"
|
||||
"{\n"
|
||||
" union\n"
|
||||
" {\n"
|
||||
" float m_min[4];\n"
|
||||
" b3Float4 m_minVec;\n"
|
||||
" int m_minIndices[4];\n"
|
||||
" };\n"
|
||||
" union\n"
|
||||
" {\n"
|
||||
" float m_max[4];\n"
|
||||
" b3Float4 m_maxVec;\n"
|
||||
" int m_signedMaxIndices[4];\n"
|
||||
" };\n"
|
||||
"};\n"
|
||||
"inline void b3TransformAabb2(b3Float4ConstArg localAabbMin,b3Float4ConstArg localAabbMax, float margin,\n"
|
||||
" b3Float4ConstArg pos,\n"
|
||||
" b3QuatConstArg orn,\n"
|
||||
" b3Float4* aabbMinOut,b3Float4* aabbMaxOut)\n"
|
||||
"{\n"
|
||||
" b3Float4 localHalfExtents = 0.5f*(localAabbMax-localAabbMin);\n"
|
||||
" localHalfExtents+=b3MakeFloat4(margin,margin,margin,0.f);\n"
|
||||
" b3Float4 localCenter = 0.5f*(localAabbMax+localAabbMin);\n"
|
||||
" b3Mat3x3 m;\n"
|
||||
" m = b3QuatGetRotationMatrix(orn);\n"
|
||||
" b3Mat3x3 abs_b = b3AbsoluteMat3x3(m);\n"
|
||||
" b3Float4 center = b3TransformPoint(localCenter,pos,orn);\n"
|
||||
" \n"
|
||||
" b3Float4 extent = b3MakeFloat4(b3Dot3F4(localHalfExtents,b3GetRow(abs_b,0)),\n"
|
||||
" b3Dot3F4(localHalfExtents,b3GetRow(abs_b,1)),\n"
|
||||
" b3Dot3F4(localHalfExtents,b3GetRow(abs_b,2)),\n"
|
||||
" 0.f);\n"
|
||||
" *aabbMinOut = center-extent;\n"
|
||||
" *aabbMaxOut = center+extent;\n"
|
||||
"}\n"
|
||||
"/// conservative test for overlap between two aabbs\n"
|
||||
"inline bool b3TestAabbAgainstAabb(b3Float4ConstArg aabbMin1,b3Float4ConstArg aabbMax1,\n"
|
||||
" b3Float4ConstArg aabbMin2, b3Float4ConstArg aabbMax2)\n"
|
||||
"{\n"
|
||||
" bool overlap = true;\n"
|
||||
" overlap = (aabbMin1.x > aabbMax2.x || aabbMax1.x < aabbMin2.x) ? false : overlap;\n"
|
||||
" overlap = (aabbMin1.z > aabbMax2.z || aabbMax1.z < aabbMin2.z) ? false : overlap;\n"
|
||||
" overlap = (aabbMin1.y > aabbMax2.y || aabbMax1.y < aabbMin2.y) ? false : overlap;\n"
|
||||
" return overlap;\n"
|
||||
"}\n"
|
||||
"#endif //B3_AABB_H\n"
|
||||
"#ifndef B3_COLLIDABLE_H\n"
|
||||
"#define B3_COLLIDABLE_H\n"
|
||||
"#ifndef B3_FLOAT4_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"#endif \n"
|
||||
"#endif //B3_FLOAT4_H\n"
|
||||
"#ifndef B3_QUAT_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"#endif \n"
|
||||
"#endif //B3_QUAT_H\n"
|
||||
"enum b3ShapeTypes\n"
|
||||
"{\n"
|
||||
" SHAPE_HEIGHT_FIELD=1,\n"
|
||||
" SHAPE_CONVEX_HULL=3,\n"
|
||||
" SHAPE_PLANE=4,\n"
|
||||
" SHAPE_CONCAVE_TRIMESH=5,\n"
|
||||
" SHAPE_COMPOUND_OF_CONVEX_HULLS=6,\n"
|
||||
" SHAPE_SPHERE=7,\n"
|
||||
" MAX_NUM_SHAPE_TYPES,\n"
|
||||
"};\n"
|
||||
"typedef struct b3Collidable b3Collidable_t;\n"
|
||||
"struct b3Collidable\n"
|
||||
"{\n"
|
||||
" union {\n"
|
||||
" int m_numChildShapes;\n"
|
||||
" int m_bvhIndex;\n"
|
||||
" };\n"
|
||||
" union\n"
|
||||
" {\n"
|
||||
" float m_radius;\n"
|
||||
" int m_compoundBvhIndex;\n"
|
||||
" };\n"
|
||||
" int m_shapeType;\n"
|
||||
" union\n"
|
||||
" {\n"
|
||||
" int m_shapeIndex;\n"
|
||||
" float m_height;\n"
|
||||
" };\n"
|
||||
"};\n"
|
||||
"typedef struct b3GpuChildShape b3GpuChildShape_t;\n"
|
||||
"struct b3GpuChildShape\n"
|
||||
"{\n"
|
||||
" b3Float4 m_childPosition;\n"
|
||||
" b3Quat m_childOrientation;\n"
|
||||
" union\n"
|
||||
" {\n"
|
||||
" int m_shapeIndex;//used for SHAPE_COMPOUND_OF_CONVEX_HULLS\n"
|
||||
" int m_capsuleAxis;\n"
|
||||
" };\n"
|
||||
" union \n"
|
||||
" {\n"
|
||||
" float m_radius;//used for childshape of SHAPE_COMPOUND_OF_SPHERES or SHAPE_COMPOUND_OF_CAPSULES\n"
|
||||
" int m_numChildShapes;//used for compound shape\n"
|
||||
" };\n"
|
||||
" union \n"
|
||||
" {\n"
|
||||
" float m_height;//used for childshape of SHAPE_COMPOUND_OF_CAPSULES\n"
|
||||
" int m_collidableShapeIndex;\n"
|
||||
" };\n"
|
||||
" int m_shapeType;\n"
|
||||
"};\n"
|
||||
"struct b3CompoundOverlappingPair\n"
|
||||
"{\n"
|
||||
" int m_bodyIndexA;\n"
|
||||
" int m_bodyIndexB;\n"
|
||||
"// int m_pairType;\n"
|
||||
" int m_childShapeIndexA;\n"
|
||||
" int m_childShapeIndexB;\n"
|
||||
"};\n"
|
||||
"#endif //B3_COLLIDABLE_H\n"
|
||||
"#ifndef B3_RIGIDBODY_DATA_H\n"
|
||||
"#define B3_RIGIDBODY_DATA_H\n"
|
||||
"#ifndef B3_FLOAT4_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"#endif \n"
|
||||
"#endif //B3_FLOAT4_H\n"
|
||||
"#ifndef B3_QUAT_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"#endif \n"
|
||||
"#endif //B3_QUAT_H\n"
|
||||
"#ifndef B3_MAT3x3_H\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#else\n"
|
||||
"#endif\n"
|
||||
"#endif //B3_MAT3x3_H\n"
|
||||
"typedef struct b3RigidBodyData b3RigidBodyData_t;\n"
|
||||
"struct b3RigidBodyData\n"
|
||||
"{\n"
|
||||
" b3Float4 m_pos;\n"
|
||||
" b3Quat m_quat;\n"
|
||||
" b3Float4 m_linVel;\n"
|
||||
" b3Float4 m_angVel;\n"
|
||||
" int m_collidableIdx;\n"
|
||||
" float m_invMass;\n"
|
||||
" float m_restituitionCoeff;\n"
|
||||
" float m_frictionCoeff;\n"
|
||||
"};\n"
|
||||
"typedef struct b3InertiaData b3InertiaData_t;\n"
|
||||
"struct b3InertiaData\n"
|
||||
"{\n"
|
||||
" b3Mat3x3 m_invInertiaWorld;\n"
|
||||
" b3Mat3x3 m_initInvInertia;\n"
|
||||
"};\n"
|
||||
"#endif //B3_RIGIDBODY_DATA_H\n"
|
||||
" \n"
|
||||
"void b3ComputeWorldAabb( int bodyId, __global const b3RigidBodyData_t* bodies, __global const b3Collidable_t* collidables, __global const b3Aabb_t* localShapeAABB, __global b3Aabb_t* worldAabbs)\n"
|
||||
"{\n"
|
||||
" __global const b3RigidBodyData_t* body = &bodies[bodyId];\n"
|
||||
" b3Float4 position = body->m_pos;\n"
|
||||
" b3Quat orientation = body->m_quat;\n"
|
||||
" \n"
|
||||
" int collidableIndex = body->m_collidableIdx;\n"
|
||||
" int shapeIndex = collidables[collidableIndex].m_shapeIndex;\n"
|
||||
" \n"
|
||||
" if (shapeIndex>=0)\n"
|
||||
" {\n"
|
||||
" \n"
|
||||
" b3Aabb_t localAabb = localShapeAABB[collidableIndex];\n"
|
||||
" b3Aabb_t worldAabb;\n"
|
||||
" \n"
|
||||
" b3Float4 aabbAMinOut,aabbAMaxOut; \n"
|
||||
" float margin = 0.f;\n"
|
||||
" b3TransformAabb2(localAabb.m_minVec,localAabb.m_maxVec,margin,position,orientation,&aabbAMinOut,&aabbAMaxOut);\n"
|
||||
" \n"
|
||||
" worldAabb.m_minVec =aabbAMinOut;\n"
|
||||
" worldAabb.m_minIndices[3] = bodyId;\n"
|
||||
" worldAabb.m_maxVec = aabbAMaxOut;\n"
|
||||
" worldAabb.m_signedMaxIndices[3] = body[bodyId].m_invMass==0.f? 0 : 1;\n"
|
||||
" worldAabbs[bodyId] = worldAabb;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"#endif //B3_UPDATE_AABBS_H\n"
|
||||
"__kernel void initializeGpuAabbsFull( const int numNodes, __global b3RigidBodyData_t* gBodies,__global b3Collidable_t* collidables, __global b3Aabb_t* plocalShapeAABB, __global b3Aabb_t* pAABB)\n"
|
||||
"{\n"
|
||||
" int nodeID = get_global_id(0);\n"
|
||||
" if( nodeID < numNodes )\n"
|
||||
" {\n"
|
||||
" b3ComputeWorldAabb(nodeID, gBodies, collidables, plocalShapeAABB,pAABB);\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"__kernel void clearOverlappingPairsKernel( __global int4* pairs, int numPairs)\n"
|
||||
"{\n"
|
||||
" int pairId = get_global_id(0);\n"
|
||||
" if( pairId< numPairs )\n"
|
||||
" {\n"
|
||||
" pairs[pairId].z = 0xffffffff;\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
|
||||
Reference in New Issue
Block a user