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:
erwincoumans
2018-09-23 14:17:31 -07:00
parent b73b05e9fb
commit ab8f16961e
1773 changed files with 1081087 additions and 474249 deletions

View File

@@ -13,7 +13,6 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#include "BasicExample.h"
#include "btBulletDynamicsCommon.h"
@@ -26,14 +25,13 @@ subject to the following restrictions:
#include "../CommonInterfaces/CommonRigidBodyBase.h"
struct BasicExample : public CommonRigidBodyBase
{
BasicExample(struct GUIHelperInterface* helper)
:CommonRigidBodyBase(helper)
: CommonRigidBodyBase(helper)
{
}
virtual ~BasicExample(){}
virtual ~BasicExample() {}
virtual void initPhysics();
virtual void renderScene();
void resetCamera()
@@ -41,8 +39,8 @@ struct BasicExample : public CommonRigidBodyBase
float dist = 4;
float pitch = -35;
float yaw = 52;
float targetPos[3]={0,0,0};
m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]);
float targetPos[3] = {0, 0, 0};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
};
@@ -55,33 +53,30 @@ void BasicExample::initPhysics()
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
if (m_dynamicsWorld->getDebugDrawer())
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints);
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints);
///create a few basic rigid bodies
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.)));
//groundShape->initializePolyhedralFeatures();
//btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50);
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0,-50,0));
groundTransform.setOrigin(btVector3(0, -50, 0));
{
btScalar mass(0.);
createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1));
createRigidBody(mass, groundTransform, groundShape, btVector4(0, 0, 1, 1));
}
{
//create a few dynamic rigidbodies
// Re-using the same collision is better for memory usage and performance
btBoxShape* colShape = createBoxShape(btVector3(.1,.1,.1));
btBoxShape* colShape = createBoxShape(btVector3(.1, .1, .1));
//btCollisionShape* colShape = new btSphereShape(btScalar(1.));
m_collisionShapes.push_back(colShape);
@@ -90,62 +85,43 @@ void BasicExample::initPhysics()
btTransform startTransform;
startTransform.setIdentity();
btScalar mass(1.f);
btScalar mass(1.f);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0,0,0);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
colShape->calculateLocalInertia(mass,localInertia);
colShape->calculateLocalInertia(mass, localInertia);
for (int k=0;k<ARRAY_SIZE_Y;k++)
for (int k = 0; k < ARRAY_SIZE_Y; k++)
{
for (int i=0;i<ARRAY_SIZE_X;i++)
for (int i = 0; i < ARRAY_SIZE_X; i++)
{
for(int j = 0;j<ARRAY_SIZE_Z;j++)
for (int j = 0; j < ARRAY_SIZE_Z; j++)
{
startTransform.setOrigin(btVector3(
btScalar(0.2*i),
btScalar(2+.2*k),
btScalar(0.2*j)));
createRigidBody(mass,startTransform,colShape);
btScalar(0.2 * i),
btScalar(2 + .2 * k),
btScalar(0.2 * j)));
createRigidBody(mass, startTransform, colShape);
}
}
}
}
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void BasicExample::renderScene()
{
CommonRigidBodyBase::renderScene();
}
CommonExampleInterface* BasicExampleCreateFunc(CommonExampleOptions& options)
CommonExampleInterface* BasicExampleCreateFunc(CommonExampleOptions& options)
{
return new BasicExample(options.m_guiHelper);
}
B3_STANDALONE_EXAMPLE(BasicExampleCreateFunc)

View File

@@ -16,7 +16,6 @@ subject to the following restrictions:
#ifndef BASIC_EXAMPLE_H
#define BASIC_EXAMPLE_H
class CommonExampleInterface* BasicExampleCreateFunc(struct CommonExampleOptions& options);
class CommonExampleInterface* BasicExampleCreateFunc(struct CommonExampleOptions& options);
#endif //BASIC_DEMO_PHYSICS_SETUP_H
#endif //BASIC_DEMO_PHYSICS_SETUP_H

View File

@@ -13,7 +13,6 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#include "BasicExample.h"
#include "../CommonInterfaces/CommonExampleInterface.h"
@@ -22,26 +21,21 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
#include "LinearMath/btTransform.h"
#include "LinearMath/btHashMap.h"
int main(int argc, char* argv[])
{
DummyGUIHelper noGfx;
CommonExampleOptions options(&noGfx);
CommonExampleInterface* example = BasicExampleCreateFunc(options);
CommonExampleInterface* example = BasicExampleCreateFunc(options);
example->initPhysics();
example->stepSimulation(1.f/60.f);
example->stepSimulation(1.f / 60.f);
example->exitPhysics();
delete example;
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -15,9 +15,6 @@ subject to the following restrictions:
#ifndef BENCHMARK_EXAMPLE_H
#define BENCHMARK_EXAMPLE_H
class CommonExampleInterface* BenchmarkCreateFunc(struct CommonExampleOptions& options);
#endif //BENCHMARK_EXAMPLE_H
class CommonExampleInterface* BenchmarkCreateFunc(struct CommonExampleOptions& options);
#endif //BENCHMARK_EXAMPLE_H

View File

@@ -2,48 +2,133 @@
#define TaruIdxCount 132
static float TaruVtx[] = {
1.08664f,-1.99237f,0.0f,
0.768369f,-1.99237f,-0.768369f,
1.28852f,1.34412e-007f,-1.28852f,
1.82224f,1.90735e-007f,0.0f,
0.0f,-1.99237f,-1.08664f,
0.0f,0.0f,-1.82224f,
0.0f,-1.99237f,-1.08664f,
-0.768369f,-1.99237f,-0.768369f,
-1.28852f,1.34412e-007f,-1.28852f,
0.0f,0.0f,-1.82224f,
-1.08664f,-1.99237f,1.82086e-007f,
-1.82224f,1.90735e-007f,1.59305e-007f,
-0.768369f,-1.99237f,0.76837f,
-1.28852f,2.47058e-007f,1.28852f,
1.42495e-007f,-1.99237f,1.08664f,
2.38958e-007f,2.70388e-007f,1.82224f,
0.768369f,-1.99237f,0.768369f,
1.28852f,2.47058e-007f,1.28852f,
0.768369f,1.99237f,-0.768369f,
1.08664f,1.99237f,0.0f,
0.0f,1.99237f,-1.08664f,
-0.768369f,1.99237f,-0.768369f,
0.0f,1.99237f,-1.08664f,
-1.08664f,1.99237f,0.0f,
-0.768369f,1.99237f,0.768369f,
1.42495e-007f,1.99237f,1.08664f,
0.768369f,1.99237f,0.768369f,
1.42495e-007f,-1.99237f,1.08664f,
-0.768369f,-1.99237f,0.76837f,
-1.08664f,-1.99237f,1.82086e-007f,
-0.768369f,-1.99237f,-0.768369f,
0.0f,-1.99237f,-1.08664f,
0.768369f,-1.99237f,-0.768369f,
1.08664f,-1.99237f,0.0f,
0.768369f,-1.99237f,0.768369f,
0.768369f,1.99237f,-0.768369f,
0.0f,1.99237f,-1.08664f,
-0.768369f,1.99237f,-0.768369f,
-1.08664f,1.99237f,0.0f,
-0.768369f,1.99237f,0.768369f,
1.42495e-007f,1.99237f,1.08664f,
0.768369f,1.99237f,0.768369f,
1.08664f,1.99237f,0.0f,
1.08664f,
-1.99237f,
0.0f,
0.768369f,
-1.99237f,
-0.768369f,
1.28852f,
1.34412e-007f,
-1.28852f,
1.82224f,
1.90735e-007f,
0.0f,
0.0f,
-1.99237f,
-1.08664f,
0.0f,
0.0f,
-1.82224f,
0.0f,
-1.99237f,
-1.08664f,
-0.768369f,
-1.99237f,
-0.768369f,
-1.28852f,
1.34412e-007f,
-1.28852f,
0.0f,
0.0f,
-1.82224f,
-1.08664f,
-1.99237f,
1.82086e-007f,
-1.82224f,
1.90735e-007f,
1.59305e-007f,
-0.768369f,
-1.99237f,
0.76837f,
-1.28852f,
2.47058e-007f,
1.28852f,
1.42495e-007f,
-1.99237f,
1.08664f,
2.38958e-007f,
2.70388e-007f,
1.82224f,
0.768369f,
-1.99237f,
0.768369f,
1.28852f,
2.47058e-007f,
1.28852f,
0.768369f,
1.99237f,
-0.768369f,
1.08664f,
1.99237f,
0.0f,
0.0f,
1.99237f,
-1.08664f,
-0.768369f,
1.99237f,
-0.768369f,
0.0f,
1.99237f,
-1.08664f,
-1.08664f,
1.99237f,
0.0f,
-0.768369f,
1.99237f,
0.768369f,
1.42495e-007f,
1.99237f,
1.08664f,
0.768369f,
1.99237f,
0.768369f,
1.42495e-007f,
-1.99237f,
1.08664f,
-0.768369f,
-1.99237f,
0.76837f,
-1.08664f,
-1.99237f,
1.82086e-007f,
-0.768369f,
-1.99237f,
-0.768369f,
0.0f,
-1.99237f,
-1.08664f,
0.768369f,
-1.99237f,
-0.768369f,
1.08664f,
-1.99237f,
0.0f,
0.768369f,
-1.99237f,
0.768369f,
0.768369f,
1.99237f,
-0.768369f,
0.0f,
1.99237f,
-1.08664f,
-0.768369f,
1.99237f,
-0.768369f,
-1.08664f,
1.99237f,
0.0f,
-0.768369f,
1.99237f,
0.768369f,
1.42495e-007f,
1.99237f,
1.08664f,
0.768369f,
1.99237f,
0.768369f,
1.08664f,
1.99237f,
0.0f,
};

File diff suppressed because it is too large Load Diff

View File

@@ -3,17 +3,17 @@
#include "Internal/Bullet2CollisionSdk.h"
#include "Internal/RealTimeBullet3CollisionSdk.h"
/* Collision World */
/* Collision World */
plCollisionWorldHandle plCreateCollisionWorld(plCollisionSdkHandle collisionSdkHandle, int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity)
{
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
return sdk->createCollisionWorld( maxNumObjsCapacity, maxNumShapesCapacity, maxNumPairsCapacity);
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
return sdk->createCollisionWorld(maxNumObjsCapacity, maxNumShapesCapacity, maxNumPairsCapacity);
}
void plDeleteCollisionWorld(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle)
void plDeleteCollisionWorld(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle)
{
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
if (sdk && worldHandle)
{
sdk->deleteCollisionWorld(worldHandle);
@@ -26,7 +26,7 @@ plCollisionSdkHandle plCreateBullet2CollisionSdk()
return Bullet2CollisionSdk::createBullet2SdkHandle();
#else
return 0;
#endif //DISABLE_BULLET2_COLLISION_SDK
#endif //DISABLE_BULLET2_COLLISION_SDK
}
plCollisionSdkHandle plCreateRealTimeBullet3CollisionSdk()
@@ -40,91 +40,89 @@ plCollisionSdkHandle plCreateRealTimeBullet3CollisionSdk()
void plDeleteCollisionSdk(plCollisionSdkHandle collisionSdkHandle)
{
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
delete sdk;
}
plCollisionShapeHandle plCreateSphereShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plReal radius)
{
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
return sdk->createSphereShape(worldHandle,radius);
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
return sdk->createSphereShape(worldHandle, radius);
}
plCollisionShapeHandle plCreatePlaneShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle,
plReal planeNormalX,
plReal planeNormalY,
plReal planeNormalZ,
plReal planeConstant)
plCollisionShapeHandle plCreatePlaneShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle,
plReal planeNormalX,
plReal planeNormalY,
plReal planeNormalZ,
plReal planeConstant)
{
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
return sdk->createPlaneShape(worldHandle,planeNormalX,planeNormalY,planeNormalZ,planeConstant);
}
plCollisionShapeHandle plCreateCapsuleShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plReal radius, plReal height, int capsuleAxis)
{
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
return sdk->createCapsuleShape(worldHandle,radius,height,capsuleAxis);
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
return sdk->createPlaneShape(worldHandle, planeNormalX, planeNormalY, planeNormalZ, planeConstant);
}
plCollisionShapeHandle plCreateCompoundShape(plCollisionSdkHandle collisionSdkHandle,plCollisionWorldHandle worldHandle)
plCollisionShapeHandle plCreateCapsuleShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plReal radius, plReal height, int capsuleAxis)
{
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
return sdk->createCapsuleShape(worldHandle, radius, height, capsuleAxis);
}
plCollisionShapeHandle plCreateCompoundShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle)
{
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
return sdk->createCompoundShape(worldHandle);
}
void plAddChildShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShape,plCollisionShapeHandle childShape, plVector3 childPos,plQuaternion childOrn)
void plAddChildShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape, plVector3 childPos, plQuaternion childOrn)
{
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
sdk->addChildShape(worldHandle,compoundShape,childShape,childPos,childOrn);
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
sdk->addChildShape(worldHandle, compoundShape, childShape, childPos, childOrn);
}
void plDeleteShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionShapeHandle shapeHandle)
{
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
sdk->deleteShape(worldHandle,shapeHandle);
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
sdk->deleteShape(worldHandle, shapeHandle);
}
plCollisionObjectHandle plCreateCollisionObject( plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, void* userData, int userIndex, plCollisionShapeHandle cshape ,plVector3 childPos,plQuaternion childOrn)
plCollisionObjectHandle plCreateCollisionObject(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, void* userData, int userIndex, plCollisionShapeHandle cshape, plVector3 childPos, plQuaternion childOrn)
{
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
return sdk->createCollisionObject(worldHandle, userData, userIndex, cshape, childPos, childOrn);
}
void plDeleteCollisionObject(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle body)
{
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
sdk->deleteCollisionObject(body);
}
void plSetCollisionObjectTransform( plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle objHandle, plVector3 position,plQuaternion orientation)
void plSetCollisionObjectTransform(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle objHandle, plVector3 position, plQuaternion orientation)
{
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
sdk->setCollisionObjectTransform(worldHandle,objHandle,position,orientation);
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
sdk->setCollisionObjectTransform(worldHandle, objHandle, position, orientation);
}
void plAddCollisionObject(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle world, plCollisionObjectHandle object)
{
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
sdk->addCollisionObject(world,object);
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
sdk->addCollisionObject(world, object);
}
void plRemoveCollisionObject(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle world, plCollisionObjectHandle object)
{
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
sdk->removeCollisionObject(world,object);
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
sdk->removeCollisionObject(world, object);
}
/* Collision Queries */
int plCollide(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle colA, plCollisionObjectHandle colB,
lwContactPoint* pointsOut, int pointCapacity)
lwContactPoint* pointsOut, int pointCapacity)
{
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
return sdk->collide(worldHandle, colA,colB,pointsOut,pointCapacity);
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
return sdk->collide(worldHandle, colA, colB, pointsOut, pointCapacity);
}
void plWorldCollide(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle world,
plNearCallback filter, void* userData)
plNearCallback filter, void* userData)
{
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
sdk->collideWorld(world,filter,userData);
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
sdk->collideWorld(world, filter, userData);
}

View File

@@ -1,111 +1,104 @@
#ifndef LW_COLLISION_C_API_H
#define LW_COLLISION_C_API_H
#define PL_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
#define PL_DECLARE_HANDLE(name) \
typedef struct name##__ \
{ \
int unused; \
} * name
#ifdef BT_USE_DOUBLE_PRECISION
typedef double plReal;
typedef double plReal;
#else
typedef float plReal;
typedef float plReal;
#endif
typedef plReal plVector3[3];
typedef plReal plQuaternion[4];
typedef plReal plVector3[3];
typedef plReal plQuaternion[4];
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
/** Particular collision SDK (C-API) */
PL_DECLARE_HANDLE(plCollisionSdkHandle);
/** Collision world, belonging to some collision SDK (C-API)*/
PL_DECLARE_HANDLE(plCollisionWorldHandle);
/** Collision object that can be part of a collision World (C-API)*/
PL_DECLARE_HANDLE(plCollisionObjectHandle);
/** Collision Shape/Geometry, property of a collision object (C-API)*/
PL_DECLARE_HANDLE(plCollisionShapeHandle);
/* Collision SDK */
extern plCollisionSdkHandle plCreateBullet2CollisionSdk();
#ifndef DISABLE_REAL_TIME_BULLET3_COLLISION_SDK
extern plCollisionSdkHandle plCreateRealTimeBullet3CollisionSdk();
#endif //DISABLE_REAL_TIME_BULLET3_COLLISION_SDK
#endif //DISABLE_REAL_TIME_BULLET3_COLLISION_SDK
// extern plCollisionSdkHandle plCreateCustomCollisionSdk();
// extern plCollisionSdkHandle plCreateCustomCollisionSdk();
extern void plDeleteCollisionSdk(plCollisionSdkHandle collisionSdkHandle);
//extern int plGetSdkWorldCreationIntParameter();
//extern int plSetSdkWorldCreationIntParameter(int newValue);
/* Collision World */
extern plCollisionWorldHandle plCreateCollisionWorld(plCollisionSdkHandle collisionSdkHandle, int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity);
extern void plDeleteCollisionWorld(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle world);
extern void plAddCollisionObject(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle world, plCollisionObjectHandle object);
extern void plRemoveCollisionObject(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle world, plCollisionObjectHandle object);
extern plCollisionWorldHandle plCreateCollisionWorld(plCollisionSdkHandle collisionSdkHandle, int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity);
extern void plDeleteCollisionWorld(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle world);
extern void plAddCollisionObject(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle world, plCollisionObjectHandle object);
extern void plRemoveCollisionObject(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle world, plCollisionObjectHandle object);
/* Collision Object */
extern plCollisionObjectHandle plCreateCollisionObject( plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle cshape , plVector3 startPosition,plQuaternion startOrientation);
extern void plDeleteCollisionObject(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle body);
extern void plSetCollisionObjectTransform( plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle objHandle, plVector3 startPosition,plQuaternion startOrientation);
extern plCollisionObjectHandle plCreateCollisionObject(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle cshape, plVector3 startPosition, plQuaternion startOrientation);
extern void plDeleteCollisionObject(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle body);
extern void plSetCollisionObjectTransform(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle objHandle, plVector3 startPosition, plQuaternion startOrientation);
/* Collision Shape definition */
extern plCollisionShapeHandle plCreateSphereShape(plCollisionSdkHandle sdk, plCollisionWorldHandle worldHandle, plReal radius);
extern plCollisionShapeHandle plCreateCapsuleShape(plCollisionSdkHandle sdk, plCollisionWorldHandle worldHandle, plReal radius, plReal height, int capsuleAxis);
extern plCollisionShapeHandle plCreatePlaneShape(plCollisionSdkHandle sdk, plCollisionWorldHandle worldHandle,
plReal planeNormalX,
plReal planeNormalY,
plReal planeNormalZ,
plReal planeConstant);
extern plCollisionShapeHandle plCreateCompoundShape(plCollisionSdkHandle sdk,plCollisionWorldHandle worldHandle);
extern void plAddChildShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShape,plCollisionShapeHandle childShape, plVector3 childPos,plQuaternion childOrn);
extern void plDeleteShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionShapeHandle shape);
extern plCollisionShapeHandle plCreateSphereShape(plCollisionSdkHandle sdk, plCollisionWorldHandle worldHandle, plReal radius);
extern plCollisionShapeHandle plCreateCapsuleShape(plCollisionSdkHandle sdk, plCollisionWorldHandle worldHandle, plReal radius, plReal height, int capsuleAxis);
extern plCollisionShapeHandle plCreatePlaneShape(plCollisionSdkHandle sdk, plCollisionWorldHandle worldHandle,
plReal planeNormalX,
plReal planeNormalY,
plReal planeNormalZ,
plReal planeConstant);
extern plCollisionShapeHandle plCreateCompoundShape(plCollisionSdkHandle sdk, plCollisionWorldHandle worldHandle);
extern void plAddChildShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape, plVector3 childPos, plQuaternion childOrn);
extern void plDeleteShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionShapeHandle shape);
/* Contact Results */
struct lwContactPoint
{
plVector3 m_ptOnAWorld;
plVector3 m_ptOnBWorld;
plVector3 m_normalOnB;
plReal m_distance;
plReal m_distance;
};
/* Collision Filtering */
typedef void(*plNearCallback)(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, void* userData,
plCollisionObjectHandle objA, plCollisionObjectHandle objB);
typedef void (*plNearCallback)(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, void* userData,
plCollisionObjectHandle objA, plCollisionObjectHandle objB);
/* Collision Queries */
extern int plCollide(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle colA, plCollisionObjectHandle colB,
lwContactPoint* pointsOut, int pointCapacity);
extern void plWorldCollide(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle world,
plNearCallback filter, void* userData);
#ifdef __cplusplus
}
#endif
#endif //LW_COLLISION_C_API_H
#endif //LW_COLLISION_C_API_H

View File

@@ -27,124 +27,121 @@ const int sNumSpheres = 10;
lwContactPoint pointsOut[sPointCapacity];
int numNearCallbacks = 0;
static btVector4 sColors[4] =
{
btVector4(1,0.7,0.7,1),
btVector4(1,1,0.7,1),
btVector4(0.7,1,0.7,1),
btVector4(0.7,1,1,1),
static btVector4 sColors[4] =
{
btVector4(1, 0.7, 0.7, 1),
btVector4(1, 1, 0.7, 1),
btVector4(0.7, 1, 0.7, 1),
btVector4(0.7, 1, 1, 1),
};
void myNearCallback(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, void* userData, plCollisionObjectHandle objA, plCollisionObjectHandle objB)
{
numNearCallbacks++;
int remainingCapacity = sPointCapacity-gTotalPoints;
btAssert(remainingCapacity>0);
int remainingCapacity = sPointCapacity - gTotalPoints;
btAssert(remainingCapacity > 0);
if (remainingCapacity>0)
if (remainingCapacity > 0)
{
lwContactPoint* pointPtr = &pointsOut[gTotalPoints];
int numNewPoints = plCollide(sdkHandle, worldHandle, objA,objB,pointPtr,remainingCapacity);
int numNewPoints = plCollide(sdkHandle, worldHandle, objA, objB, pointPtr, remainingCapacity);
btAssert(numNewPoints <= remainingCapacity);
gTotalPoints+=numNewPoints;
gTotalPoints += numNewPoints;
}
}
class CollisionTutorialBullet2 : public CommonExampleInterface
{
CommonGraphicsApp* m_app;
CommonGraphicsApp* m_app;
GUIHelperInterface* m_guiHelper;
int m_tutorialIndex;
TimeSeriesCanvas* m_timeSeriesCanvas0;
int m_tutorialIndex;
TimeSeriesCanvas* m_timeSeriesCanvas0;
plCollisionSdkHandle m_collisionSdkHandle;
plCollisionWorldHandle m_collisionWorldHandle;
// int m_stage;
// int m_counter;
// int m_stage;
// int m_counter;
public:
CollisionTutorialBullet2(GUIHelperInterface* guiHelper, int tutorialIndex)
:m_app(guiHelper->getAppInterface()),
m_guiHelper(guiHelper),
m_tutorialIndex(tutorialIndex),
m_timeSeriesCanvas0(0),
m_collisionSdkHandle(0),
m_collisionWorldHandle(0)
// m_stage(0),
// m_counter(0)
{
CollisionTutorialBullet2(GUIHelperInterface* guiHelper, int tutorialIndex)
: m_app(guiHelper->getAppInterface()),
m_guiHelper(guiHelper),
m_tutorialIndex(tutorialIndex),
m_timeSeriesCanvas0(0),
m_collisionSdkHandle(0),
m_collisionWorldHandle(0)
// m_stage(0),
// m_counter(0)
{
gTotalPoints = 0;
m_app->setUpAxis(1);
switch (m_tutorialIndex)
{
case TUT_SPHERE_PLANE_RTB3:
case TUT_SPHERE_PLANE_BULLET2:
{
if (m_tutorialIndex==TUT_SPHERE_PLANE_BULLET2)
if (m_tutorialIndex == TUT_SPHERE_PLANE_BULLET2)
{
m_collisionSdkHandle = plCreateBullet2CollisionSdk();
} else
}
else
{
#ifndef DISABLE_REAL_TIME_BULLET3_COLLISION_SDK
m_collisionSdkHandle = plCreateRealTimeBullet3CollisionSdk();
#endif //DISABLE_REAL_TIME_BULLET3_COLLISION_SDK
#endif //DISABLE_REAL_TIME_BULLET3_COLLISION_SDK
}
if (m_collisionSdkHandle)
{
int maxNumObjsCapacity=1024;
int maxNumShapesCapacity=1024;
int maxNumPairsCapacity=16384;
int maxNumObjsCapacity = 1024;
int maxNumShapesCapacity = 1024;
int maxNumPairsCapacity = 16384;
btAlignedObjectArray<plCollisionObjectHandle> colliders;
m_collisionWorldHandle = plCreateCollisionWorld(m_collisionSdkHandle,maxNumObjsCapacity,maxNumShapesCapacity,maxNumPairsCapacity);
m_collisionWorldHandle = plCreateCollisionWorld(m_collisionSdkHandle, maxNumObjsCapacity, maxNumShapesCapacity, maxNumPairsCapacity);
//create objects, do query etc
{
float radius = 1.f;
void* userPointer = 0;
{
for (int j=0;j<sNumCompounds;j++)
for (int j = 0; j < sNumCompounds; j++)
{
plCollisionShapeHandle compoundShape = plCreateCompoundShape(m_collisionSdkHandle,m_collisionWorldHandle);
plCollisionShapeHandle compoundShape = plCreateCompoundShape(m_collisionSdkHandle, m_collisionWorldHandle);
for (int i=0;i<sNumSpheres;i++)
for (int i = 0; i < sNumSpheres; i++)
{
btVector3 childPos(i*1.5,0,0);
btQuaternion childOrn(0,0,0,1);
btVector3 scaling(radius,radius,radius);
plCollisionShapeHandle childShape = plCreateSphereShape(m_collisionSdkHandle, m_collisionWorldHandle,radius);
plAddChildShape(m_collisionSdkHandle,m_collisionWorldHandle,compoundShape, childShape,childPos,childOrn);
btVector3 childPos(i * 1.5, 0, 0);
btQuaternion childOrn(0, 0, 0, 1);
btVector3 scaling(radius, radius, radius);
plCollisionShapeHandle childShape = plCreateSphereShape(m_collisionSdkHandle, m_collisionWorldHandle, radius);
plAddChildShape(m_collisionSdkHandle, m_collisionWorldHandle, compoundShape, childShape, childPos, childOrn);
//m_guiHelper->createCollisionObjectGraphicsObject(colObj,color);
}
if (m_tutorialIndex==TUT_SPHERE_PLANE_BULLET2)
if (m_tutorialIndex == TUT_SPHERE_PLANE_BULLET2)
{
btCollisionShape* colShape = (btCollisionShape*) compoundShape;
btCollisionShape* colShape = (btCollisionShape*)compoundShape;
m_guiHelper->createCollisionShapeGraphicsObject(colShape);
} else
}
else
{
}
{
btVector3 pos(j*sNumSpheres*1.5,-2.4,0);
btQuaternion orn(0,0,0,1);
plCollisionObjectHandle colObjHandle = plCreateCollisionObject(m_collisionSdkHandle,m_collisionWorldHandle,userPointer, -1,compoundShape,pos,orn);
if (m_tutorialIndex==TUT_SPHERE_PLANE_BULLET2)
btVector3 pos(j * sNumSpheres * 1.5, -2.4, 0);
btQuaternion orn(0, 0, 0, 1);
plCollisionObjectHandle colObjHandle = plCreateCollisionObject(m_collisionSdkHandle, m_collisionWorldHandle, userPointer, -1, compoundShape, pos, orn);
if (m_tutorialIndex == TUT_SPHERE_PLANE_BULLET2)
{
btCollisionObject* colObj = (btCollisionObject*) colObjHandle;
btVector4 color=sColors[j&3];
m_guiHelper->createCollisionObjectGraphicsObject(colObj,color);
btCollisionObject* colObj = (btCollisionObject*)colObjHandle;
btVector4 color = sColors[j & 3];
m_guiHelper->createCollisionObjectGraphicsObject(colObj, color);
colliders.push_back(colObjHandle);
plAddCollisionObject(m_collisionSdkHandle, m_collisionWorldHandle,colObjHandle);
plAddCollisionObject(m_collisionSdkHandle, m_collisionWorldHandle, colObjHandle);
}
}
}
@@ -152,27 +149,26 @@ public:
}
{
plCollisionShapeHandle colShape = plCreatePlaneShape(m_collisionSdkHandle, m_collisionWorldHandle,0,1,0,-3.5);
btVector3 pos(0,0,0);
btQuaternion orn(0,0,0,1);
plCollisionShapeHandle colShape = plCreatePlaneShape(m_collisionSdkHandle, m_collisionWorldHandle, 0, 1, 0, -3.5);
btVector3 pos(0, 0, 0);
btQuaternion orn(0, 0, 0, 1);
void* userPointer = 0;
plCollisionObjectHandle colObj = plCreateCollisionObject(m_collisionSdkHandle,m_collisionWorldHandle,userPointer, 0,colShape,pos,orn);
plCollisionObjectHandle colObj = plCreateCollisionObject(m_collisionSdkHandle, m_collisionWorldHandle, userPointer, 0, colShape, pos, orn);
colliders.push_back(colObj);
plAddCollisionObject(m_collisionSdkHandle, m_collisionWorldHandle,colObj);
plAddCollisionObject(m_collisionSdkHandle, m_collisionWorldHandle, colObj);
}
int numContacts = plCollide(m_collisionSdkHandle,m_collisionWorldHandle,colliders[0],colliders[1],pointsOut,sPointCapacity);
printf("numContacts = %d\n", numContacts);
void* myUserPtr = 0;
plWorldCollide(m_collisionSdkHandle,m_collisionWorldHandle,myNearCallback, myUserPtr);
printf("total points=%d\n",gTotalPoints);
//plRemoveCollisionObject(m_collisionSdkHandle,m_collisionWorldHandle,colObj);
int numContacts = plCollide(m_collisionSdkHandle, m_collisionWorldHandle, colliders[0], colliders[1], pointsOut, sPointCapacity);
printf("numContacts = %d\n", numContacts);
void* myUserPtr = 0;
plWorldCollide(m_collisionSdkHandle, m_collisionWorldHandle, myNearCallback, myUserPtr);
printf("total points=%d\n", gTotalPoints);
//plRemoveCollisionObject(m_collisionSdkHandle,m_collisionWorldHandle,colObj);
//plDeleteCollisionObject(m_collisionSdkHandle,colObj);
//plDeleteShape(m_collisionSdkHandle,colShape);
}
/*
m_timeSeriesCanvas0 = new TimeSeriesCanvas(m_app->m_2dCanvasInterface,512,256,"Constant Velocity");
@@ -184,100 +180,86 @@ public:
*/
break;
}
default:
{
m_timeSeriesCanvas0 = new TimeSeriesCanvas(m_app->m_2dCanvasInterface,512,256,"Unknown");
m_timeSeriesCanvas0 ->setupTimeSeries(1,60, 0);
m_timeSeriesCanvas0 = new TimeSeriesCanvas(m_app->m_2dCanvasInterface, 512, 256, "Unknown");
m_timeSeriesCanvas0->setupTimeSeries(1, 60, 0);
}
};
{
int boxId = m_app->registerCubeShape(100,0.01,100);
b3Vector3 pos = b3MakeVector3(0,-3.5,0);
b3Quaternion orn(0,0,0,1);
b3Vector4 color = b3MakeVector4(1,1,1,1);
b3Vector3 scaling = b3MakeVector3(1,1,1);
m_app->m_renderer->registerGraphicsInstance(boxId,pos,orn,color,scaling);
int boxId = m_app->registerCubeShape(100, 0.01, 100);
b3Vector3 pos = b3MakeVector3(0, -3.5, 0);
b3Quaternion orn(0, 0, 0, 1);
b3Vector4 color = b3MakeVector4(1, 1, 1, 1);
b3Vector3 scaling = b3MakeVector3(1, 1, 1);
m_app->m_renderer->registerGraphicsInstance(boxId, pos, orn, color, scaling);
}
{
int textureIndex = -1;
if (1)
{
int width,height,n;
int width, height, n;
const char* filename = "data/cube.png";
const unsigned char* image=0;
const char* prefix[]={"./","../","../../","../../../","../../../../"};
int numprefix = sizeof(prefix)/sizeof(const char*);
for (int i=0;!image && i<numprefix;i++)
const unsigned char* image = 0;
const char* prefix[] = {"./", "../", "../../", "../../../", "../../../../"};
int numprefix = sizeof(prefix) / sizeof(const char*);
for (int i = 0; !image && i < numprefix; i++)
{
char relativeFileName[1024];
sprintf(relativeFileName,"%s%s",prefix[i],filename);
sprintf(relativeFileName, "%s%s", prefix[i], filename);
image = stbi_load(relativeFileName, &width, &height, &n, 3);
}
b3Assert(image);
if (image)
{
textureIndex = m_app->m_renderer->registerTexture(image,width,height);
textureIndex = m_app->m_renderer->registerTexture(image, width, height);
}
}
}
m_app->m_renderer->writeTransforms();
}
virtual ~CollisionTutorialBullet2()
{
}
virtual ~CollisionTutorialBullet2()
{
delete m_timeSeriesCanvas0;
plDeleteCollisionWorld(m_collisionSdkHandle,m_collisionWorldHandle);
plDeleteCollisionWorld(m_collisionSdkHandle, m_collisionWorldHandle);
plDeleteCollisionSdk(m_collisionSdkHandle);
m_timeSeriesCanvas0 = 0;
}
}
virtual void initPhysics()
{
}
virtual void exitPhysics()
{
}
virtual void stepSimulation(float deltaTime)
{
virtual void initPhysics()
{
}
virtual void exitPhysics()
{
}
virtual void stepSimulation(float deltaTime)
{
#ifndef BT_NO_PROFILE
CProfileManager::Reset();
#endif
void* myUserPtr = 0;
gTotalPoints = 0;
numNearCallbacks = 0;
{
BT_PROFILE("plWorldCollide");
if (m_collisionSdkHandle && m_collisionWorldHandle)
{
plWorldCollide(m_collisionSdkHandle,m_collisionWorldHandle,myNearCallback, myUserPtr);
plWorldCollide(m_collisionSdkHandle, m_collisionWorldHandle, myNearCallback, myUserPtr);
}
}
@@ -303,87 +285,76 @@ public:
};
#endif
if (m_timeSeriesCanvas0)
m_timeSeriesCanvas0->nextTick();
// m_app->m_renderer->writeSingleInstanceTransformToCPU(m_bodies[i]->m_worldPose.m_position, m_bodies[i]->m_worldPose.m_orientation, m_bodies[i]->m_graphicsIndex);
m_app->m_renderer->writeTransforms();
m_app->m_renderer->writeTransforms();
#ifndef BT_NO_PROFILE
CProfileManager::Increment_Frame_Counter();
CProfileManager::Increment_Frame_Counter();
#endif
}
virtual void renderScene()
{
}
virtual void renderScene()
{
if (m_app && m_app->m_renderer)
{
m_app->m_renderer->renderScene();
m_app->m_renderer->clearZBuffer();
m_app->drawText3D("X",1,0,0,1);
m_app->drawText3D("Y",0,1,0,1);
m_app->drawText3D("Z",0,0,1,1);
m_app->drawText3D("X", 1, 0, 0, 1);
m_app->drawText3D("Y", 0, 1, 0, 1);
m_app->drawText3D("Z", 0, 0, 1, 1);
for (int i=0;i<gTotalPoints;i++)
for (int i = 0; i < gTotalPoints; i++)
{
const lwContactPoint& contact = pointsOut[i];
btVector3 color(1,1,0);
btScalar lineWidth=3;
if (contact.m_distance<0)
btVector3 color(1, 1, 0);
btScalar lineWidth = 3;
if (contact.m_distance < 0)
{
color.setValue(1,0,0);
color.setValue(1, 0, 0);
}
m_app->m_renderer->drawLine(contact.m_ptOnAWorld,contact.m_ptOnBWorld,color,lineWidth);
m_app->m_renderer->drawLine(contact.m_ptOnAWorld, contact.m_ptOnBWorld, color, lineWidth);
}
}
}
}
virtual void physicsDebugDraw(int debugDrawFlags)
{
}
virtual bool mouseMoveCallback(float x,float y)
{
return false;
}
virtual bool mouseButtonCallback(int button, int state, float x, float y)
{
return false;
}
virtual bool keyboardCallback(int key, int state)
{
return false;
}
virtual void physicsDebugDraw(int debugDrawFlags)
{
}
virtual bool mouseMoveCallback(float x, float y)
{
return false;
}
virtual bool mouseButtonCallback(int button, int state, float x, float y)
{
return false;
}
virtual bool keyboardCallback(int key, int state)
{
return false;
}
virtual void resetCamera()
{
float dist = 10.5;
float pitch = -32;
float yaw = 136;
float targetPos[3]={0,0,0};
if (m_app->m_renderer && m_app->m_renderer->getActiveCamera())
float targetPos[3] = {0, 0, 0};
if (m_app->m_renderer && m_app->m_renderer->getActiveCamera())
{
m_app->m_renderer->getActiveCamera()->setCameraDistance(dist);
m_app->m_renderer->getActiveCamera()->setCameraPitch(pitch);
m_app->m_renderer->getActiveCamera()->setCameraYaw(yaw);
m_app->m_renderer->getActiveCamera()->setCameraTargetPosition(targetPos[0],targetPos[1],targetPos[2]);
m_app->m_renderer->getActiveCamera()->setCameraTargetPosition(targetPos[0], targetPos[1], targetPos[2]);
}
}
};
class CommonExampleInterface* CollisionTutorialBullet2CreateFunc(struct CommonExampleOptions& options)
class CommonExampleInterface* CollisionTutorialBullet2CreateFunc(struct CommonExampleOptions& options)
{
return new CollisionTutorialBullet2(options.m_guiHelper, options.m_option);
}

View File

@@ -1,12 +1,12 @@
#ifndef COLLISION_TUTORIAL_H
#define COLLISION_TUTORIAL_H
#define COLLISION_TUTORIAL_H
enum EnumCollisionTutorialTypes
{
TUT_SPHERE_PLANE_BULLET2=0,
TUT_SPHERE_PLANE_RTB3,
TUT_SPHERE_PLANE_BULLET2 = 0,
TUT_SPHERE_PLANE_RTB3,
};
class CommonExampleInterface* CollisionTutorialBullet2CreateFunc(struct CommonExampleOptions& options);
class CommonExampleInterface* CollisionTutorialBullet2CreateFunc(struct CommonExampleOptions& options);
#endif //COLLISION_TUTORIAL_H
#endif //COLLISION_TUTORIAL_H

View File

@@ -7,103 +7,101 @@ struct Bullet2CollisionSdkInternalData
btCollisionDispatcher* m_dispatcher;
btBroadphaseInterface* m_aabbBroadphase;
btCollisionWorld* m_collisionWorld;
Bullet2CollisionSdkInternalData()
:
m_collisionConfig(0),
m_dispatcher(0),
m_aabbBroadphase(0),
m_collisionWorld(0)
: m_collisionConfig(0),
m_dispatcher(0),
m_aabbBroadphase(0),
m_collisionWorld(0)
{
}
};
Bullet2CollisionSdk::Bullet2CollisionSdk()
{
m_internalData = new Bullet2CollisionSdkInternalData;
}
Bullet2CollisionSdk::~Bullet2CollisionSdk()
{
delete m_internalData;
m_internalData = 0;
}
plCollisionWorldHandle Bullet2CollisionSdk::createCollisionWorld(int /*maxNumObjsCapacity*/, int /*maxNumShapesCapacity*/, int /*maxNumPairsCapacity*/)
{
m_internalData->m_collisionConfig = new btDefaultCollisionConfiguration;
m_internalData->m_dispatcher = new btCollisionDispatcher(m_internalData->m_collisionConfig);
m_internalData->m_aabbBroadphase = new btDbvtBroadphase();
m_internalData->m_collisionWorld = new btCollisionWorld(m_internalData->m_dispatcher,
m_internalData->m_aabbBroadphase,
m_internalData->m_collisionConfig);
return (plCollisionWorldHandle) m_internalData->m_collisionWorld;
return (plCollisionWorldHandle)m_internalData->m_collisionWorld;
}
void Bullet2CollisionSdk::deleteCollisionWorld(plCollisionWorldHandle worldHandle)
{
btCollisionWorld* world = (btCollisionWorld*) worldHandle;
btCollisionWorld* world = (btCollisionWorld*)worldHandle;
btAssert(m_internalData->m_collisionWorld == world);
if (m_internalData->m_collisionWorld == world)
{
delete m_internalData->m_collisionWorld;
m_internalData->m_collisionWorld=0;
m_internalData->m_collisionWorld = 0;
delete m_internalData->m_aabbBroadphase;
m_internalData->m_aabbBroadphase=0;
m_internalData->m_aabbBroadphase = 0;
delete m_internalData->m_dispatcher;
m_internalData->m_dispatcher=0;
m_internalData->m_dispatcher = 0;
delete m_internalData->m_collisionConfig;
m_internalData->m_collisionConfig=0;
}
m_internalData->m_collisionConfig = 0;
}
}
plCollisionShapeHandle Bullet2CollisionSdk::createSphereShape(plCollisionWorldHandle /*worldHandle*/, plReal radius)
{
btSphereShape* sphereShape = new btSphereShape(radius);
return (plCollisionShapeHandle) sphereShape;
return (plCollisionShapeHandle)sphereShape;
}
plCollisionShapeHandle Bullet2CollisionSdk::createPlaneShape(plCollisionWorldHandle worldHandle,
plReal planeNormalX,
plReal planeNormalY,
plReal planeNormalZ,
plReal planeConstant)
plCollisionShapeHandle Bullet2CollisionSdk::createPlaneShape(plCollisionWorldHandle worldHandle,
plReal planeNormalX,
plReal planeNormalY,
plReal planeNormalZ,
plReal planeConstant)
{
btStaticPlaneShape* planeShape = new btStaticPlaneShape(btVector3(planeNormalX,planeNormalY,planeNormalZ),planeConstant);
return (plCollisionShapeHandle) planeShape;
btStaticPlaneShape* planeShape = new btStaticPlaneShape(btVector3(planeNormalX, planeNormalY, planeNormalZ), planeConstant);
return (plCollisionShapeHandle)planeShape;
}
plCollisionShapeHandle Bullet2CollisionSdk::createCapsuleShape(plCollisionWorldHandle worldHandle,
plReal radius,
plReal height,
int capsuleAxis)
plCollisionShapeHandle Bullet2CollisionSdk::createCapsuleShape(plCollisionWorldHandle worldHandle,
plReal radius,
plReal height,
int capsuleAxis)
{
btCapsuleShape* capsule = 0;
switch (capsuleAxis)
{
case 0:
{
capsule = new btCapsuleShapeX(radius,height);
break;
}
case 1:
{
capsule = new btCapsuleShape(radius,height);
break;
}
case 2:
{
capsule = new btCapsuleShapeZ(radius,height);
break;
}
default:
{
btAssert(0);
}
case 0:
{
capsule = new btCapsuleShapeX(radius, height);
break;
}
case 1:
{
capsule = new btCapsuleShape(radius, height);
break;
}
case 2:
{
capsule = new btCapsuleShapeZ(radius, height);
break;
}
default:
{
btAssert(0);
}
}
return (plCollisionShapeHandle)capsule;
}
@@ -112,28 +110,27 @@ plCollisionShapeHandle Bullet2CollisionSdk::createCompoundShape(plCollisionWorld
{
return (plCollisionShapeHandle) new btCompoundShape();
}
void Bullet2CollisionSdk::addChildShape(plCollisionWorldHandle worldHandle,plCollisionShapeHandle compoundShapeHandle, plCollisionShapeHandle childShapeHandle,plVector3 childPos,plQuaternion childOrn)
void Bullet2CollisionSdk::addChildShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShapeHandle, plCollisionShapeHandle childShapeHandle, plVector3 childPos, plQuaternion childOrn)
{
btCompoundShape* compound = (btCompoundShape*) compoundShapeHandle;
btCollisionShape* childShape = (btCollisionShape*) childShapeHandle;
btCompoundShape* compound = (btCompoundShape*)compoundShapeHandle;
btCollisionShape* childShape = (btCollisionShape*)childShapeHandle;
btTransform localTrans;
localTrans.setOrigin(btVector3(childPos[0],childPos[1],childPos[2]));
localTrans.setRotation(btQuaternion(childOrn[0],childOrn[1],childOrn[2],childOrn[3]));
compound->addChildShape(localTrans,childShape);
localTrans.setOrigin(btVector3(childPos[0], childPos[1], childPos[2]));
localTrans.setRotation(btQuaternion(childOrn[0], childOrn[1], childOrn[2], childOrn[3]));
compound->addChildShape(localTrans, childShape);
}
void Bullet2CollisionSdk::deleteShape(plCollisionWorldHandle /*worldHandle*/, plCollisionShapeHandle shapeHandle)
{
btCollisionShape* shape = (btCollisionShape*) shapeHandle;
btCollisionShape* shape = (btCollisionShape*)shapeHandle;
delete shape;
}
void Bullet2CollisionSdk::addCollisionObject(plCollisionWorldHandle worldHandle, plCollisionObjectHandle objectHandle)
{
btCollisionWorld* world = (btCollisionWorld*) worldHandle;
btCollisionObject* colObj = (btCollisionObject*) objectHandle;
btAssert(world && colObj);
btCollisionWorld* world = (btCollisionWorld*)worldHandle;
btCollisionObject* colObj = (btCollisionObject*)objectHandle;
btAssert(world && colObj);
if (world == m_internalData->m_collisionWorld && colObj)
{
world->addCollisionObject(colObj);
@@ -141,101 +138,98 @@ void Bullet2CollisionSdk::addCollisionObject(plCollisionWorldHandle worldHandle,
}
void Bullet2CollisionSdk::removeCollisionObject(plCollisionWorldHandle worldHandle, plCollisionObjectHandle objectHandle)
{
btCollisionWorld* world = (btCollisionWorld*) worldHandle;
btCollisionObject* colObj = (btCollisionObject*) objectHandle;
btAssert(world && colObj);
btCollisionWorld* world = (btCollisionWorld*)worldHandle;
btCollisionObject* colObj = (btCollisionObject*)objectHandle;
btAssert(world && colObj);
if (world == m_internalData->m_collisionWorld && colObj)
{
world->removeCollisionObject(colObj);
}
}
}
plCollisionObjectHandle Bullet2CollisionSdk::createCollisionObject( plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle shapeHandle ,
plVector3 startPosition,plQuaternion startOrientation )
plCollisionObjectHandle Bullet2CollisionSdk::createCollisionObject(plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle shapeHandle,
plVector3 startPosition, plQuaternion startOrientation)
{
btCollisionShape* colShape = (btCollisionShape*) shapeHandle;
btCollisionShape* colShape = (btCollisionShape*)shapeHandle;
btAssert(colShape);
if (colShape)
{
btCollisionObject* colObj= new btCollisionObject;
btCollisionObject* colObj = new btCollisionObject;
colObj->setUserIndex(userIndex);
colObj->setUserPointer(userPointer);
colObj->setCollisionShape(colShape);
btTransform tr;
tr.setOrigin(btVector3(startPosition[0],startPosition[1],startPosition[2]));
tr.setRotation(btQuaternion(startOrientation[0],startOrientation[1],startOrientation[2],startOrientation[3]));
btTransform tr;
tr.setOrigin(btVector3(startPosition[0], startPosition[1], startPosition[2]));
tr.setRotation(btQuaternion(startOrientation[0], startOrientation[1], startOrientation[2], startOrientation[3]));
colObj->setWorldTransform(tr);
return (plCollisionObjectHandle) colObj;
return (plCollisionObjectHandle)colObj;
}
return 0;
}
void Bullet2CollisionSdk::deleteCollisionObject(plCollisionObjectHandle bodyHandle)
{
btCollisionObject* colObj = (btCollisionObject*) bodyHandle;
btCollisionObject* colObj = (btCollisionObject*)bodyHandle;
delete colObj;
}
void Bullet2CollisionSdk::setCollisionObjectTransform(plCollisionWorldHandle /*worldHandle*/, plCollisionObjectHandle bodyHandle,
plVector3 position,plQuaternion orientation )
plVector3 position, plQuaternion orientation)
{
btCollisionObject* colObj = (btCollisionObject*) bodyHandle;
btTransform tr;
tr.setOrigin(btVector3(position[0],position[1],position[2]));
tr.setRotation(btQuaternion(orientation[0],orientation[1],orientation[2],orientation[3]));
btCollisionObject* colObj = (btCollisionObject*)bodyHandle;
btTransform tr;
tr.setOrigin(btVector3(position[0], position[1], position[2]));
tr.setRotation(btQuaternion(orientation[0], orientation[1], orientation[2], orientation[3]));
colObj->setWorldTransform(tr);
}
struct Bullet2ContactResultCallback : public btCollisionWorld::ContactResultCallback
struct Bullet2ContactResultCallback : public btCollisionWorld::ContactResultCallback
{
int m_numContacts;
lwContactPoint* m_pointsOut;
int m_pointCapacity;
Bullet2ContactResultCallback(lwContactPoint* pointsOut, int pointCapacity) :
m_numContacts(0),
m_pointsOut(pointsOut),
m_pointCapacity(pointCapacity)
{
}
virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1)
{
if (m_numContacts<m_pointCapacity)
{
lwContactPoint& ptOut = m_pointsOut[m_numContacts];
ptOut.m_distance = cp.m_distance1;
ptOut.m_normalOnB[0] = cp.m_normalWorldOnB.getX();
ptOut.m_normalOnB[1] = cp.m_normalWorldOnB.getY();
ptOut.m_normalOnB[2] = cp.m_normalWorldOnB.getZ();
ptOut.m_ptOnAWorld[0] = cp.m_positionWorldOnA[0];
ptOut.m_ptOnAWorld[1] = cp.m_positionWorldOnA[1];
ptOut.m_ptOnAWorld[2] = cp.m_positionWorldOnA[2];
ptOut.m_ptOnBWorld[0] = cp.m_positionWorldOnB[0];
ptOut.m_ptOnBWorld[1] = cp.m_positionWorldOnB[1];
ptOut.m_ptOnBWorld[2] = cp.m_positionWorldOnB[2];
m_numContacts++;
}
return 1.f;
}
int m_numContacts;
lwContactPoint* m_pointsOut;
int m_pointCapacity;
Bullet2ContactResultCallback(lwContactPoint* pointsOut, int pointCapacity) : m_numContacts(0),
m_pointsOut(pointsOut),
m_pointCapacity(pointCapacity)
{
}
virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper* colObj1Wrap, int partId1, int index1)
{
if (m_numContacts < m_pointCapacity)
{
lwContactPoint& ptOut = m_pointsOut[m_numContacts];
ptOut.m_distance = cp.m_distance1;
ptOut.m_normalOnB[0] = cp.m_normalWorldOnB.getX();
ptOut.m_normalOnB[1] = cp.m_normalWorldOnB.getY();
ptOut.m_normalOnB[2] = cp.m_normalWorldOnB.getZ();
ptOut.m_ptOnAWorld[0] = cp.m_positionWorldOnA[0];
ptOut.m_ptOnAWorld[1] = cp.m_positionWorldOnA[1];
ptOut.m_ptOnAWorld[2] = cp.m_positionWorldOnA[2];
ptOut.m_ptOnBWorld[0] = cp.m_positionWorldOnB[0];
ptOut.m_ptOnBWorld[1] = cp.m_positionWorldOnB[1];
ptOut.m_ptOnBWorld[2] = cp.m_positionWorldOnB[2];
m_numContacts++;
}
return 1.f;
}
};
int Bullet2CollisionSdk::collide(plCollisionWorldHandle worldHandle,plCollisionObjectHandle colA, plCollisionObjectHandle colB,
lwContactPoint* pointsOut, int pointCapacity)
int Bullet2CollisionSdk::collide(plCollisionWorldHandle worldHandle, plCollisionObjectHandle colA, plCollisionObjectHandle colB,
lwContactPoint* pointsOut, int pointCapacity)
{
btCollisionWorld* world = (btCollisionWorld*) worldHandle;
btCollisionObject* colObjA = (btCollisionObject*) colA;
btCollisionObject* colObjB = (btCollisionObject*) colB;
btAssert(world && colObjA && colObjB);
if (world == m_internalData->m_collisionWorld && colObjA && colObjB)
{
Bullet2ContactResultCallback cb(pointsOut,pointCapacity);
world->contactPairTest(colObjA,colObjB,cb);
return cb.m_numContacts;
}
return 0;
btCollisionWorld* world = (btCollisionWorld*)worldHandle;
btCollisionObject* colObjA = (btCollisionObject*)colA;
btCollisionObject* colObjB = (btCollisionObject*)colB;
btAssert(world && colObjA && colObjB);
if (world == m_internalData->m_collisionWorld && colObjA && colObjB)
{
Bullet2ContactResultCallback cb(pointsOut, pointCapacity);
world->contactPairTest(colObjA, colObjB, cb);
return cb.m_numContacts;
}
return 0;
}
static plNearCallback gTmpFilter;
@@ -247,30 +241,30 @@ static void* gUserData = 0;
void Bullet2NearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo)
{
btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;
plCollisionObjectHandle obA =(plCollisionObjectHandle) colObj0;
plCollisionObjectHandle obB =(plCollisionObjectHandle) colObj1;
if(gTmpFilter)
{
gTmpFilter(gCollisionSdk,gCollisionWorldHandle, gUserData,obA,obB);
gNearCallbackCount++;
}
btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;
plCollisionObjectHandle obA = (plCollisionObjectHandle)colObj0;
plCollisionObjectHandle obB = (plCollisionObjectHandle)colObj1;
if (gTmpFilter)
{
gTmpFilter(gCollisionSdk, gCollisionWorldHandle, gUserData, obA, obB);
gNearCallbackCount++;
}
}
void Bullet2CollisionSdk::collideWorld( plCollisionWorldHandle worldHandle,
plNearCallback filter, void* userData)
void Bullet2CollisionSdk::collideWorld(plCollisionWorldHandle worldHandle,
plNearCallback filter, void* userData)
{
btCollisionWorld* world = (btCollisionWorld*) worldHandle;
//chain the near-callback
gTmpFilter = filter;
gNearCallbackCount = 0;
gUserData = userData;
gCollisionSdk = (plCollisionSdkHandle)this;
gCollisionWorldHandle = worldHandle;
m_internalData->m_dispatcher->setNearCallback(Bullet2NearCallback);
world->performDiscreteCollisionDetection();
gTmpFilter = 0;
btCollisionWorld* world = (btCollisionWorld*)worldHandle;
//chain the near-callback
gTmpFilter = filter;
gNearCallbackCount = 0;
gUserData = userData;
gCollisionSdk = (plCollisionSdkHandle)this;
gCollisionWorldHandle = worldHandle;
m_internalData->m_dispatcher->setNearCallback(Bullet2NearCallback);
world->performDiscreteCollisionDetection();
gTmpFilter = 0;
}
plCollisionSdkHandle Bullet2CollisionSdk::createBullet2SdkHandle()

View File

@@ -6,51 +6,50 @@
class Bullet2CollisionSdk : public CollisionSdkInterface
{
struct Bullet2CollisionSdkInternalData* m_internalData;
public:
Bullet2CollisionSdk();
virtual ~Bullet2CollisionSdk();
virtual plCollisionWorldHandle createCollisionWorld(int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity);
virtual void deleteCollisionWorld(plCollisionWorldHandle worldHandle);
virtual plCollisionShapeHandle createSphereShape(plCollisionWorldHandle worldHandle, plReal radius);
virtual plCollisionShapeHandle createPlaneShape(plCollisionWorldHandle worldHandle,
plReal planeNormalX,
plReal planeNormalY,
plReal planeNormalZ,
virtual plCollisionShapeHandle createPlaneShape(plCollisionWorldHandle worldHandle,
plReal planeNormalX,
plReal planeNormalY,
plReal planeNormalZ,
plReal planeConstant);
virtual plCollisionShapeHandle createCapsuleShape(plCollisionWorldHandle worldHandle,
plReal radius,
plReal height,
int capsuleAxis);
virtual plCollisionShapeHandle createCapsuleShape(plCollisionWorldHandle worldHandle,
plReal radius,
plReal height,
int capsuleAxis);
virtual plCollisionShapeHandle createCompoundShape(plCollisionWorldHandle worldHandle);
virtual void addChildShape(plCollisionWorldHandle worldHandle,plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape,plVector3 childPos,plQuaternion childOrn);
virtual void addChildShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape, plVector3 childPos, plQuaternion childOrn);
virtual void deleteShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle shape);
virtual void addCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object);
virtual void removeCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object);
virtual plCollisionObjectHandle createCollisionObject( plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle cshape ,
plVector3 startPosition,plQuaternion startOrientation );
virtual void deleteCollisionObject(plCollisionObjectHandle body);
virtual void removeCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object);
virtual plCollisionObjectHandle createCollisionObject(plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle cshape,
plVector3 startPosition, plQuaternion startOrientation);
virtual void deleteCollisionObject(plCollisionObjectHandle body);
virtual void setCollisionObjectTransform(plCollisionWorldHandle world, plCollisionObjectHandle body,
plVector3 position,plQuaternion orientation );
virtual int collide(plCollisionWorldHandle world,plCollisionObjectHandle colA, plCollisionObjectHandle colB,
lwContactPoint* pointsOut, int pointCapacity);
virtual void collideWorld( plCollisionWorldHandle world,
plNearCallback filter, void* userData);
plVector3 position, plQuaternion orientation);
virtual int collide(plCollisionWorldHandle world, plCollisionObjectHandle colA, plCollisionObjectHandle colB,
lwContactPoint* pointsOut, int pointCapacity);
virtual void collideWorld(plCollisionWorldHandle world,
plNearCallback filter, void* userData);
static plCollisionSdkHandle createBullet2SdkHandle();
};
#endif //BULLET2_COLLISION_SDK_H
#endif //BULLET2_COLLISION_SDK_H

View File

@@ -6,50 +6,46 @@
class CollisionSdkInterface
{
public:
virtual ~CollisionSdkInterface()
{
}
virtual plCollisionWorldHandle createCollisionWorld(int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity) = 0;
virtual void deleteCollisionWorld(plCollisionWorldHandle worldHandle) = 0;
virtual plCollisionShapeHandle createSphereShape(plCollisionWorldHandle worldHandle, plReal radius) = 0;
virtual plCollisionShapeHandle createPlaneShape(plCollisionWorldHandle worldHandle,
plReal planeNormalX,
plReal planeNormalY,
plReal planeNormalZ,
virtual plCollisionShapeHandle createPlaneShape(plCollisionWorldHandle worldHandle,
plReal planeNormalX,
plReal planeNormalY,
plReal planeNormalZ,
plReal planeConstant) = 0;
virtual plCollisionShapeHandle createCapsuleShape(plCollisionWorldHandle worldHandle,
plReal radius,
plReal height,
int capsuleAxis) = 0;
virtual plCollisionShapeHandle createCapsuleShape(plCollisionWorldHandle worldHandle,
plReal radius,
plReal height,
int capsuleAxis) = 0;
virtual plCollisionShapeHandle createCompoundShape(plCollisionWorldHandle worldHandle) = 0;
virtual void addChildShape(plCollisionWorldHandle worldHandle,plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape,plVector3 childPos,plQuaternion childOrn)=0;
virtual void addChildShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape, plVector3 childPos, plQuaternion childOrn) = 0;
virtual void deleteShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle shape) = 0;
virtual void addCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object)=0;
virtual void removeCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object)=0;
virtual plCollisionObjectHandle createCollisionObject( plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle cshape ,
plVector3 startPosition,plQuaternion startOrientation )=0;
virtual void deleteCollisionObject(plCollisionObjectHandle body)=0;
virtual void setCollisionObjectTransform(plCollisionWorldHandle world, plCollisionObjectHandle body,
plVector3 position,plQuaternion orientation )=0;
virtual int collide(plCollisionWorldHandle world,plCollisionObjectHandle colA, plCollisionObjectHandle colB,
lwContactPoint* pointsOut, int pointCapacity)=0;
virtual void collideWorld( plCollisionWorldHandle world,
plNearCallback filter, void* userData)=0;
virtual void addCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object) = 0;
virtual void removeCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object) = 0;
virtual plCollisionObjectHandle createCollisionObject(plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle cshape,
plVector3 startPosition, plQuaternion startOrientation) = 0;
virtual void deleteCollisionObject(plCollisionObjectHandle body) = 0;
virtual void setCollisionObjectTransform(plCollisionWorldHandle world, plCollisionObjectHandle body,
plVector3 position, plQuaternion orientation) = 0;
virtual int collide(plCollisionWorldHandle world, plCollisionObjectHandle colA, plCollisionObjectHandle colB,
lwContactPoint* pointsOut, int pointCapacity) = 0;
virtual void collideWorld(plCollisionWorldHandle world,
plNearCallback filter, void* userData) = 0;
};
#endif //COLLISION_SDK_INTERFACE_H
#endif //COLLISION_SDK_INTERFACE_H

View File

@@ -8,30 +8,27 @@
//convert the opaque pointer to int
struct RTB3_ColliderOpaque2Int
{
union
{
plCollisionObjectHandle m_ptrValue;
int m_intValue;
};
union {
plCollisionObjectHandle m_ptrValue;
int m_intValue;
};
};
struct RTB3_ShapeOpaque2Int
{
union
{
plCollisionShapeHandle m_ptrValue;
int m_intValue;
};
union {
plCollisionShapeHandle m_ptrValue;
int m_intValue;
};
};
enum RTB3ShapeTypes
{
RTB3_SHAPE_SPHERE=0,
RTB3_SHAPE_SPHERE = 0,
RTB3_SHAPE_PLANE,
RTB3_SHAPE_CAPSULE,
MAX_NUM_SINGLE_SHAPE_TYPES,
RTB3_SHAPE_COMPOUND_INTERNAL,
};
//we start at 1, so that the 0 index is 'invalid' just like a nullptr
@@ -47,15 +44,14 @@ struct RTB3CollisionWorld
b3AlignedObjectArray<b3Transform> m_collidableTransforms;
b3AlignedObjectArray<b3Collidable> m_collidables;
b3AlignedObjectArray<b3GpuChildShape> m_childShapes;
b3AlignedObjectArray<b3Aabb> m_localSpaceAabbs;
b3AlignedObjectArray<b3Aabb> m_worldSpaceAabbs;
b3AlignedObjectArray<b3Aabb> m_localSpaceAabbs;
b3AlignedObjectArray<b3Aabb> m_worldSpaceAabbs;
b3AlignedObjectArray<b3GpuFace> m_planeFaces;
b3AlignedObjectArray<b3CompoundOverlappingPair> m_compoundOverlappingPairs;
union
{
union {
int m_nextFreeShapeIndex;
void* m_nextFreeShapePtr;
};
@@ -63,10 +59,9 @@ struct RTB3CollisionWorld
int m_nextFreePlaneFaceIndex;
RTB3CollisionWorld()
:
m_nextFreeShapeIndex(START_SHAPE_INDEX),
m_nextFreeCollidableIndex(START_COLLIDABLE_INDEX),
m_nextFreePlaneFaceIndex(0)//this value is never exposed to the user, so we can start from 0
: m_nextFreeShapeIndex(START_SHAPE_INDEX),
m_nextFreeCollidableIndex(START_COLLIDABLE_INDEX),
m_nextFreePlaneFaceIndex(0) //this value is never exposed to the user, so we can start from 0
{
}
};
@@ -78,42 +73,42 @@ struct RealTimeBullet3CollisionSdkInternalData
RealTimeBullet3CollisionSdk::RealTimeBullet3CollisionSdk()
{
// int szCol = sizeof(b3Collidable);
// int szShap = sizeof(b3GpuChildShape);
// int szComPair = sizeof(b3CompoundOverlappingPair);
// int szCol = sizeof(b3Collidable);
// int szShap = sizeof(b3GpuChildShape);
// int szComPair = sizeof(b3CompoundOverlappingPair);
m_internalData = new RealTimeBullet3CollisionSdkInternalData;
}
RealTimeBullet3CollisionSdk::~RealTimeBullet3CollisionSdk()
{
delete m_internalData;
m_internalData=0;
m_internalData = 0;
}
plCollisionWorldHandle RealTimeBullet3CollisionSdk::createCollisionWorld(int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity)
{
RTB3CollisionWorld* world = new RTB3CollisionWorld();
world->m_collidables.resize(maxNumObjsCapacity+START_COLLIDABLE_INDEX);
world->m_collidablePositions.resize(maxNumObjsCapacity+START_COLLIDABLE_INDEX);
world->m_collidableOrientations.resize(maxNumObjsCapacity+START_COLLIDABLE_INDEX);
world->m_collidableTransforms.resize(maxNumObjsCapacity+START_COLLIDABLE_INDEX);
world->m_collidableUserPointers.resize(maxNumObjsCapacity+START_COLLIDABLE_INDEX);
world->m_collidableUserIndices.resize(maxNumObjsCapacity+START_COLLIDABLE_INDEX);
world->m_childShapes.resize(maxNumShapesCapacity+START_SHAPE_INDEX);
world->m_collidables.resize(maxNumObjsCapacity + START_COLLIDABLE_INDEX);
world->m_collidablePositions.resize(maxNumObjsCapacity + START_COLLIDABLE_INDEX);
world->m_collidableOrientations.resize(maxNumObjsCapacity + START_COLLIDABLE_INDEX);
world->m_collidableTransforms.resize(maxNumObjsCapacity + START_COLLIDABLE_INDEX);
world->m_collidableUserPointers.resize(maxNumObjsCapacity + START_COLLIDABLE_INDEX);
world->m_collidableUserIndices.resize(maxNumObjsCapacity + START_COLLIDABLE_INDEX);
world->m_childShapes.resize(maxNumShapesCapacity + START_SHAPE_INDEX);
world->m_planeFaces.resize(maxNumShapesCapacity);
world->m_compoundOverlappingPairs.resize(maxNumPairsCapacity);
m_internalData->m_collisionWorlds.push_back(world);
return (plCollisionWorldHandle) world;
return (plCollisionWorldHandle)world;
}
void RealTimeBullet3CollisionSdk::deleteCollisionWorld(plCollisionWorldHandle worldHandle)
{
RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle;
RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle;
int loc = m_internalData->m_collisionWorlds.findLinearSearch(world);
b3Assert(loc >=0 && loc<m_internalData->m_collisionWorlds.size());
if (loc >=0 && loc<m_internalData->m_collisionWorlds.size())
b3Assert(loc >= 0 && loc < m_internalData->m_collisionWorlds.size());
if (loc >= 0 && loc < m_internalData->m_collisionWorlds.size())
{
m_internalData->m_collisionWorlds.remove(world);
delete world;
@@ -122,88 +117,87 @@ void RealTimeBullet3CollisionSdk::deleteCollisionWorld(plCollisionWorldHandle wo
plCollisionShapeHandle RealTimeBullet3CollisionSdk::createSphereShape(plCollisionWorldHandle worldHandle, plReal radius)
{
RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle;
b3Assert(world->m_nextFreeShapeIndex<world->m_childShapes.size());
if (world->m_nextFreeShapeIndex<world->m_childShapes.size())
RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle;
b3Assert(world->m_nextFreeShapeIndex < world->m_childShapes.size());
if (world->m_nextFreeShapeIndex < world->m_childShapes.size())
{
b3GpuChildShape& shape = world->m_childShapes[world->m_nextFreeShapeIndex];
shape.m_childPosition.setZero();
shape.m_childOrientation.setValue(0,0,0,1);
shape.m_childOrientation.setValue(0, 0, 0, 1);
shape.m_radius = radius;
shape.m_shapeType = RTB3_SHAPE_SPHERE;
world->m_nextFreeShapeIndex++;
return (plCollisionShapeHandle) world->m_nextFreeShapePtr;
return (plCollisionShapeHandle)world->m_nextFreeShapePtr;
}
return 0;
}
plCollisionShapeHandle RealTimeBullet3CollisionSdk::createPlaneShape(plCollisionWorldHandle worldHandle,
plReal planeNormalX,
plReal planeNormalY,
plReal planeNormalZ,
plReal planeConstant)
plCollisionShapeHandle RealTimeBullet3CollisionSdk::createPlaneShape(plCollisionWorldHandle worldHandle,
plReal planeNormalX,
plReal planeNormalY,
plReal planeNormalZ,
plReal planeConstant)
{
RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle;
RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle;
b3Assert(world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size());
if (world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size())
{
b3GpuChildShape& shape = world->m_childShapes[world->m_nextFreeShapeIndex];
shape.m_childPosition.setZero();
shape.m_childOrientation.setValue(0,0,0,1);
world->m_planeFaces[world->m_nextFreePlaneFaceIndex].m_plane = b3MakeVector4(planeNormalX,planeNormalY,planeNormalZ,planeConstant);
shape.m_childOrientation.setValue(0, 0, 0, 1);
world->m_planeFaces[world->m_nextFreePlaneFaceIndex].m_plane = b3MakeVector4(planeNormalX, planeNormalY, planeNormalZ, planeConstant);
shape.m_shapeIndex = world->m_nextFreePlaneFaceIndex++;
shape.m_shapeType = RTB3_SHAPE_PLANE;
world->m_nextFreeShapeIndex++;
return (plCollisionShapeHandle)world->m_nextFreeShapePtr ;
return (plCollisionShapeHandle)world->m_nextFreeShapePtr;
}
return 0;
}
plCollisionShapeHandle RealTimeBullet3CollisionSdk::createCapsuleShape(plCollisionWorldHandle worldHandle,
plReal radius,
plReal height,
int capsuleAxis)
plCollisionShapeHandle RealTimeBullet3CollisionSdk::createCapsuleShape(plCollisionWorldHandle worldHandle,
plReal radius,
plReal height,
int capsuleAxis)
{
RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle;
RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle;
b3Assert(world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size());
if (world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size())
{
b3GpuChildShape& shape = world->m_childShapes[world->m_nextFreeShapeIndex];
shape.m_childPosition.setZero();
shape.m_childOrientation.setValue(0,0,0,1);
shape.m_childOrientation.setValue(0, 0, 0, 1);
shape.m_radius = radius;
shape.m_height = height;
shape.m_shapeIndex = capsuleAxis;
shape.m_shapeType = RTB3_SHAPE_CAPSULE;
world->m_nextFreeShapeIndex++;
return (plCollisionShapeHandle) world->m_nextFreeShapePtr;
return (plCollisionShapeHandle)world->m_nextFreeShapePtr;
}
return 0;
}
plCollisionShapeHandle RealTimeBullet3CollisionSdk::createCompoundShape(plCollisionWorldHandle worldHandle)
{
RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle;
RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle;
b3Assert(world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size());
if (world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size())
{
b3GpuChildShape& shape = world->m_childShapes[world->m_nextFreeShapeIndex];
shape.m_childPosition.setZero();
shape.m_childOrientation.setValue(0,0,0,1);
shape.m_childOrientation.setValue(0, 0, 0, 1);
shape.m_numChildShapes = 0;
shape.m_shapeType = RTB3_SHAPE_COMPOUND_INTERNAL;
world->m_nextFreeShapeIndex++;
return (plCollisionShapeHandle) world->m_nextFreeShapePtr;
return (plCollisionShapeHandle)world->m_nextFreeShapePtr;
}
return 0;
}
void RealTimeBullet3CollisionSdk::addChildShape(plCollisionWorldHandle worldHandle,plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape,plVector3 childPos,plQuaternion childOrn)
void RealTimeBullet3CollisionSdk::addChildShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape, plVector3 childPos, plQuaternion childOrn)
{
}
void RealTimeBullet3CollisionSdk::deleteShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle shape)
{
@@ -212,7 +206,7 @@ void RealTimeBullet3CollisionSdk::deleteShape(plCollisionWorldHandle worldHandle
//this would be solved by one more in-direction, at some performance penalty for certain operations
//for now, we don't delete and eventually run out-of-shapes
}
void RealTimeBullet3CollisionSdk::addCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object)
{
///createCollisionObject already adds it to the world
@@ -222,46 +216,45 @@ void RealTimeBullet3CollisionSdk::removeCollisionObject(plCollisionWorldHandle w
{
///todo, see deleteShape
}
plCollisionObjectHandle RealTimeBullet3CollisionSdk::createCollisionObject( plCollisionWorldHandle worldHandle, void* userPointer,
int userIndex, plCollisionShapeHandle shapeHandle ,
plVector3 startPosition,plQuaternion startOrientation )
plCollisionObjectHandle RealTimeBullet3CollisionSdk::createCollisionObject(plCollisionWorldHandle worldHandle, void* userPointer,
int userIndex, plCollisionShapeHandle shapeHandle,
plVector3 startPosition, plQuaternion startOrientation)
{
RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle;
RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle;
b3Assert(world->m_nextFreeCollidableIndex < world->m_collidables.size());
if (world->m_nextFreeCollidableIndex < world->m_collidables.size())
{
b3Collidable& collidable = world->m_collidables[world->m_nextFreeCollidableIndex];
world->m_collidablePositions[world->m_nextFreeCollidableIndex].setValue(startPosition[0],startPosition[1],startPosition[2]);
world->m_collidableOrientations[world->m_nextFreeCollidableIndex].setValue(startOrientation[0],startOrientation[1],startOrientation[2],startOrientation[3]);
world->m_collidablePositions[world->m_nextFreeCollidableIndex].setValue(startPosition[0], startPosition[1], startPosition[2]);
world->m_collidableOrientations[world->m_nextFreeCollidableIndex].setValue(startOrientation[0], startOrientation[1], startOrientation[2], startOrientation[3]);
world->m_collidableTransforms[world->m_nextFreeCollidableIndex].setOrigin(world->m_collidablePositions[world->m_nextFreeCollidableIndex]);
world->m_collidableTransforms[world->m_nextFreeCollidableIndex].setRotation(world->m_collidableOrientations[world->m_nextFreeCollidableIndex]);
world->m_collidableUserPointers[world->m_nextFreeCollidableIndex] = userPointer;
world->m_collidableUserIndices[world->m_nextFreeCollidableIndex] = userIndex;
RTB3_ShapeOpaque2Int caster;
caster.m_ptrValue = shapeHandle;
int shapeIndex = caster.m_intValue;
collidable.m_shapeIndex = shapeIndex;
RTB3_ShapeOpaque2Int caster;
caster.m_ptrValue = shapeHandle;
int shapeIndex = caster.m_intValue;
collidable.m_shapeIndex = shapeIndex;
b3GpuChildShape& shape = world->m_childShapes[shapeIndex];
collidable.m_shapeType = shape.m_shapeType;
collidable.m_numChildShapes = 1;
switch (collidable.m_shapeType)
{
case RTB3_SHAPE_SPHERE:
case RTB3_SHAPE_SPHERE:
{
break;
}
case RTB3_SHAPE_PLANE:
case RTB3_SHAPE_PLANE:
{
break;
}
case RTB3_SHAPE_COMPOUND_INTERNAL:
case RTB3_SHAPE_COMPOUND_INTERNAL:
{
break;
}
default:
default:
{
b3Assert(0);
}
@@ -280,14 +273,14 @@ plCollisionObjectHandle RealTimeBullet3CollisionSdk::createCollisionObject( plC
}
return 0;
}
void RealTimeBullet3CollisionSdk::deleteCollisionObject(plCollisionObjectHandle body)
{
///todo, see deleteShape
}
void RealTimeBullet3CollisionSdk::setCollisionObjectTransform(plCollisionWorldHandle world, plCollisionObjectHandle body,
plVector3 position,plQuaternion orientation )
plVector3 position, plQuaternion orientation)
{
}
@@ -298,159 +291,154 @@ struct plContactCache
int numAddedPoints;
};
typedef void (*plDetectCollisionFunc)(RTB3CollisionWorld* world,int colA, int shapeIndexA, int colB, int shapeIndexB,
plContactCache* contactCache);
typedef void (*plDetectCollisionFunc)(RTB3CollisionWorld* world, int colA, int shapeIndexA, int colB, int shapeIndexB,
plContactCache* contactCache);
void detectCollisionDummy(RTB3CollisionWorld* world,int colA, int shapeIndexA, int colB, int shapeIndexB,
plContactCache* contactCache)
void detectCollisionDummy(RTB3CollisionWorld* world, int colA, int shapeIndexA, int colB, int shapeIndexB,
plContactCache* contactCache)
{
(void)world;
(void)colA,(void)colB;
(void)colA, (void)colB;
(void)contactCache;
}
void plVecCopy(float* dst,const b3Vector3& src)
void plVecCopy(float* dst, const b3Vector3& src)
{
dst[0] = src.x;
dst[1] = src.y;
dst[2] = src.z;
}
void plVecCopy(double* dst,const b3Vector3& src)
void plVecCopy(double* dst, const b3Vector3& src)
{
dst[0] = src.x;
dst[1] = src.y;
dst[2] = src.z;
dst[0] = src.x;
dst[1] = src.y;
dst[2] = src.z;
}
void ComputeClosestPointsPlaneSphere(const b3Vector3& planeNormalWorld, b3Scalar planeConstant, const b3Vector3& spherePosWorld,b3Scalar sphereRadius, plContactCache* contactCache)
void ComputeClosestPointsPlaneSphere(const b3Vector3& planeNormalWorld, b3Scalar planeConstant, const b3Vector3& spherePosWorld, b3Scalar sphereRadius, plContactCache* contactCache)
{
if (contactCache->numAddedPoints < contactCache->pointCapacity)
{
lwContactPoint& pointOut = contactCache->pointsOut[contactCache->numAddedPoints];
b3Scalar t = -(spherePosWorld.dot(-planeNormalWorld)+planeConstant);
b3Vector3 intersectionPoint = spherePosWorld+t*-planeNormalWorld;
b3Scalar distance = t-sphereRadius;
if (distance<=0)
b3Scalar t = -(spherePosWorld.dot(-planeNormalWorld) + planeConstant);
b3Vector3 intersectionPoint = spherePosWorld + t * -planeNormalWorld;
b3Scalar distance = t - sphereRadius;
if (distance <= 0)
{
pointOut.m_distance = distance;
plVecCopy(pointOut.m_ptOnBWorld,intersectionPoint);
plVecCopy(pointOut.m_ptOnAWorld,spherePosWorld+sphereRadius*-planeNormalWorld);
plVecCopy(pointOut.m_normalOnB,planeNormalWorld);
plVecCopy(pointOut.m_ptOnBWorld, intersectionPoint);
plVecCopy(pointOut.m_ptOnAWorld, spherePosWorld + sphereRadius * -planeNormalWorld);
plVecCopy(pointOut.m_normalOnB, planeNormalWorld);
contactCache->numAddedPoints++;
}
}
}
void ComputeClosestPointsSphereSphere(b3Scalar sphereARadius, const b3Vector3& sphereAPosWorld, b3Scalar sphereBRadius, const b3Vector3& sphereBPosWorld, plContactCache* contactCache) {
void ComputeClosestPointsSphereSphere(b3Scalar sphereARadius, const b3Vector3& sphereAPosWorld, b3Scalar sphereBRadius, const b3Vector3& sphereBPosWorld, plContactCache* contactCache)
{
if (contactCache->numAddedPoints < contactCache->pointCapacity)
{
lwContactPoint& pointOut = contactCache->pointsOut[contactCache->numAddedPoints];
b3Vector3 diff = sphereAPosWorld-sphereBPosWorld;
b3Vector3 diff = sphereAPosWorld - sphereBPosWorld;
b3Scalar len = diff.length();
pointOut.m_distance = len - (sphereARadius+sphereBRadius);
if (pointOut.m_distance<=0)
pointOut.m_distance = len - (sphereARadius + sphereBRadius);
if (pointOut.m_distance <= 0)
{
b3Vector3 normOnB = b3MakeVector3(1,0,0);
if (len > B3_EPSILON) {
b3Vector3 normOnB = b3MakeVector3(1, 0, 0);
if (len > B3_EPSILON)
{
normOnB = diff / len;
}
plVecCopy(pointOut.m_normalOnB,normOnB);
b3Vector3 ptAWorld = sphereAPosWorld - sphereARadius*normOnB;
plVecCopy(pointOut.m_ptOnAWorld,ptAWorld);
plVecCopy(pointOut.m_ptOnBWorld,ptAWorld-normOnB*pointOut.m_distance);
plVecCopy(pointOut.m_normalOnB, normOnB);
b3Vector3 ptAWorld = sphereAPosWorld - sphereARadius * normOnB;
plVecCopy(pointOut.m_ptOnAWorld, ptAWorld);
plVecCopy(pointOut.m_ptOnBWorld, ptAWorld - normOnB * pointOut.m_distance);
contactCache->numAddedPoints++;
}
}
}
B3_FORCE_INLINE void detectCollisionSphereSphere(RTB3CollisionWorld* world,int colA, int shapeIndexA, int colB, int shapeIndexB,
plContactCache* contactCache)
B3_FORCE_INLINE void detectCollisionSphereSphere(RTB3CollisionWorld* world, int colA, int shapeIndexA, int colB, int shapeIndexB,
plContactCache* contactCache)
{
const b3Scalar radiusA = world->m_childShapes[shapeIndexA].m_radius;
const b3Scalar radiusB = world->m_childShapes[shapeIndexB].m_radius;
const b3Transform& trA = world->m_collidableTransforms[colA];
const b3Vector3& sphereALocalPos = world->m_childShapes[shapeIndexA].m_childPosition;
b3Vector3 spherePosAWorld = trA(sphereALocalPos);
//b3Vector3 spherePosAWorld = b3QuatRotate( world->m_collidableOrientations[colA], sphereALocalPos ) + (world->m_collidablePositions[colA]);
const b3Transform& trB = world->m_collidableTransforms[colB];
const b3Vector3& sphereBLocalPos = world->m_childShapes[shapeIndexB].m_childPosition;
b3Vector3 spherePosBWorld = trB(sphereBLocalPos);
//b3Vector3 spherePosBWorld = b3QuatRotate( world->m_collidableOrientations[colB], sphereBLocalPos ) + (world->m_collidablePositions[colB]);
ComputeClosestPointsSphereSphere(radiusA,spherePosAWorld,radiusB,spherePosBWorld,contactCache);
ComputeClosestPointsSphereSphere(radiusA, spherePosAWorld, radiusB, spherePosBWorld, contactCache);
}
void detectCollisionSpherePlane(RTB3CollisionWorld* world,int colA, int shapeIndexA, int colB, int shapeIndexB,
plContactCache* contactCache)
void detectCollisionSpherePlane(RTB3CollisionWorld* world, int colA, int shapeIndexA, int colB, int shapeIndexB,
plContactCache* contactCache)
{
const b3Transform& trA = world->m_collidableTransforms[colA];
const b3Vector3& sphereALocalPos = world->m_childShapes[shapeIndexA].m_childPosition;
b3Vector3 spherePosAWorld = trA(sphereALocalPos);
int planeFaceIndex = world->m_childShapes[shapeIndexB].m_shapeIndex;
b3Vector3 planeNormal = world->m_planeFaces[planeFaceIndex].m_plane;
b3Scalar planeConstant = planeNormal[3];
planeNormal[3] = 0.f;
ComputeClosestPointsPlaneSphere(planeNormal, planeConstant, spherePosAWorld,world->m_childShapes[shapeIndexA].m_radius, contactCache);
ComputeClosestPointsPlaneSphere(planeNormal, planeConstant, spherePosAWorld, world->m_childShapes[shapeIndexA].m_radius, contactCache);
}
void detectCollisionPlaneSphere(RTB3CollisionWorld* world,int colA, int shapeIndexA, int colB, int shapeIndexB,
plContactCache* contactCache)
void detectCollisionPlaneSphere(RTB3CollisionWorld* world, int colA, int shapeIndexA, int colB, int shapeIndexB,
plContactCache* contactCache)
{
(void)world;
(void)colA,(void)shapeIndexA,(void)colB,(void)shapeIndexB;
(void)colA, (void)shapeIndexA, (void)colB, (void)shapeIndexB;
(void)contactCache;
}
#ifdef RTB3_SHAPE_CAPSULE
plDetectCollisionFunc funcTbl_detectCollision[MAX_NUM_SINGLE_SHAPE_TYPES,][MAX_NUM_SINGLE_SHAPE_TYPES,] = {
{detectCollisionSphereSphere ,detectCollisionSpherePlane ,detectCollisionSphereCapsule},
{detectCollisionPlaneSphere ,detectCollisionDummy ,detectCollisionPlaneCapsule},
{detectCollisionCapsuleSphere ,detectCollisionCapsulePlane ,detectCollisionCapsuleCapsule},
plDetectCollisionFunc funcTbl_detectCollision[MAX_NUM_SINGLE_SHAPE_TYPES, ][MAX_NUM_SINGLE_SHAPE_TYPES, ] = {
{detectCollisionSphereSphere, detectCollisionSpherePlane, detectCollisionSphereCapsule},
{detectCollisionPlaneSphere, detectCollisionDummy, detectCollisionPlaneCapsule},
{detectCollisionCapsuleSphere, detectCollisionCapsulePlane, detectCollisionCapsuleCapsule},
};
#else
plDetectCollisionFunc funcTbl_detectCollision[MAX_NUM_SINGLE_SHAPE_TYPES][MAX_NUM_SINGLE_SHAPE_TYPES] = {
{detectCollisionSphereSphere ,detectCollisionSpherePlane},
{detectCollisionPlaneSphere ,detectCollisionDummy },
{detectCollisionSphereSphere, detectCollisionSpherePlane},
{detectCollisionPlaneSphere, detectCollisionDummy},
};
#endif
int RealTimeBullet3CollisionSdk::collide(plCollisionWorldHandle worldHandle,plCollisionObjectHandle colAHandle, plCollisionObjectHandle colBHandle,
lwContactPoint* pointsOutOrg, int pointCapacity)
int RealTimeBullet3CollisionSdk::collide(plCollisionWorldHandle worldHandle, plCollisionObjectHandle colAHandle, plCollisionObjectHandle colBHandle,
lwContactPoint* pointsOutOrg, int pointCapacity)
{
RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle;
RTB3_ColliderOpaque2Int caster;
caster.m_ptrValue =colAHandle;
int colAIndex = caster.m_intValue;
caster.m_ptrValue = colBHandle;
int colBIndex = caster.m_intValue;
const b3Collidable& colA = world->m_collidables[colAIndex];
RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle;
RTB3_ColliderOpaque2Int caster;
caster.m_ptrValue = colAHandle;
int colAIndex = caster.m_intValue;
caster.m_ptrValue = colBHandle;
int colBIndex = caster.m_intValue;
const b3Collidable& colA = world->m_collidables[colAIndex];
const b3Collidable& colB = world->m_collidables[colBIndex];
plContactCache contactCache;
contactCache.pointCapacity = pointCapacity;
contactCache.pointsOut = pointsOutOrg;
contactCache.numAddedPoints = 0;
for (int i=0;i<colA.m_numChildShapes;i++)
for (int i = 0; i < colA.m_numChildShapes; i++)
{
for (int j=0;j<colB.m_numChildShapes;j++)
for (int j = 0; j < colB.m_numChildShapes; j++)
{
if (contactCache.numAddedPoints<pointCapacity)
if (contactCache.numAddedPoints < pointCapacity)
{
//funcTbl_detectCollision[world->m_childShapes[colA.m_shapeIndex+i].m_shapeType]
// [world->m_childShapes[colB.m_shapeIndex+j].m_shapeType](world,colAIndex,colA.m_shapeIndex+i,colBIndex,colB.m_shapeIndex+j,&contactCache);
@@ -462,25 +450,24 @@ int RealTimeBullet3CollisionSdk::collide(plCollisionWorldHandle worldHandle,plCo
return 0;
}
void RealTimeBullet3CollisionSdk::collideWorld( plCollisionWorldHandle worldHandle,
plNearCallback filter, void* userData)
void RealTimeBullet3CollisionSdk::collideWorld(plCollisionWorldHandle worldHandle,
plNearCallback filter, void* userData)
{
RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle;
RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle;
if (filter)
{
RTB3_ColliderOpaque2Int caster;
plCollisionObjectHandle colA;
plCollisionObjectHandle colB;
for (int i=START_COLLIDABLE_INDEX;i<world->m_nextFreeCollidableIndex;i++)
for (int i = START_COLLIDABLE_INDEX; i < world->m_nextFreeCollidableIndex; i++)
{
for (int j=i+1;j<world->m_nextFreeCollidableIndex;j++)
for (int j = i + 1; j < world->m_nextFreeCollidableIndex; j++)
{
caster.m_intValue = i;
colA = caster.m_ptrValue;
caster.m_intValue = j;
colA = caster.m_ptrValue;
caster.m_intValue = j;
colB = caster.m_ptrValue;
filter((plCollisionSdkHandle)this,worldHandle,userData,colA,colB);
filter((plCollisionSdkHandle)this, worldHandle, userData, colA, colB);
}
}
}

View File

@@ -6,50 +6,48 @@
class RealTimeBullet3CollisionSdk : public CollisionSdkInterface
{
struct RealTimeBullet3CollisionSdkInternalData* m_internalData;
public:
RealTimeBullet3CollisionSdk();
virtual ~RealTimeBullet3CollisionSdk();
virtual plCollisionWorldHandle createCollisionWorld(int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity);
virtual void deleteCollisionWorld(plCollisionWorldHandle worldHandle);
virtual plCollisionShapeHandle createSphereShape(plCollisionWorldHandle worldHandle, plReal radius);
virtual plCollisionShapeHandle createPlaneShape(plCollisionWorldHandle worldHandle,
plReal planeNormalX,
plReal planeNormalY,
plReal planeNormalZ,
virtual plCollisionShapeHandle createPlaneShape(plCollisionWorldHandle worldHandle,
plReal planeNormalX,
plReal planeNormalY,
plReal planeNormalZ,
plReal planeConstant);
virtual plCollisionShapeHandle createCapsuleShape(plCollisionWorldHandle worldHandle,
plReal radius,
plReal height,
int capsuleAxis);
virtual plCollisionShapeHandle createCapsuleShape(plCollisionWorldHandle worldHandle,
plReal radius,
plReal height,
int capsuleAxis);
virtual plCollisionShapeHandle createCompoundShape(plCollisionWorldHandle worldHandle);
virtual void addChildShape(plCollisionWorldHandle worldHandle,plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape,plVector3 childPos,plQuaternion childOrn);
virtual void addChildShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape, plVector3 childPos, plQuaternion childOrn);
virtual void deleteShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle shape);
virtual void addCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object);
virtual void removeCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object);
virtual plCollisionObjectHandle createCollisionObject( plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle cshape ,
plVector3 startPosition,plQuaternion startOrientation );
virtual void deleteCollisionObject(plCollisionObjectHandle body);
virtual void removeCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object);
virtual plCollisionObjectHandle createCollisionObject(plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle cshape,
plVector3 startPosition, plQuaternion startOrientation);
virtual void deleteCollisionObject(plCollisionObjectHandle body);
virtual void setCollisionObjectTransform(plCollisionWorldHandle world, plCollisionObjectHandle body,
plVector3 position,plQuaternion orientation );
virtual int collide(plCollisionWorldHandle world,plCollisionObjectHandle colA, plCollisionObjectHandle colB,
lwContactPoint* pointsOut, int pointCapacity);
virtual void collideWorld( plCollisionWorldHandle world,
plNearCallback filter, void* userData);
plVector3 position, plQuaternion orientation);
virtual int collide(plCollisionWorldHandle world, plCollisionObjectHandle colA, plCollisionObjectHandle colB,
lwContactPoint* pointsOut, int pointCapacity);
virtual void collideWorld(plCollisionWorldHandle world,
plNearCallback filter, void* userData);
static plCollisionSdkHandle createRealTimeBullet3CollisionSdkHandle();
};
#endif //REAL_TIME_COLLISION_SDK_H
#endif //REAL_TIME_COLLISION_SDK_H

View File

@@ -4,14 +4,12 @@
struct Common2dCanvasInterface
{
virtual ~Common2dCanvasInterface() {}
virtual int createCanvas(const char* canvasName, int width, int height, int xPos, int yPos)=0;
virtual void destroyCanvas(int canvasId)=0;
virtual void setPixel(int canvasId, int x, int y, unsigned char red, unsigned char green,unsigned char blue, unsigned char alpha)=0;
virtual void getPixel(int canvasId, int x, int y, unsigned char& red, unsigned char& green,unsigned char& blue, unsigned char& alpha)=0;
virtual void refreshImageData(int canvasId)=0;
virtual int createCanvas(const char* canvasName, int width, int height, int xPos, int yPos) = 0;
virtual void destroyCanvas(int canvasId) = 0;
virtual void setPixel(int canvasId, int x, int y, unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha) = 0;
virtual void getPixel(int canvasId, int x, int y, unsigned char& red, unsigned char& green, unsigned char& blue, unsigned char& alpha) = 0;
virtual void refreshImageData(int canvasId) = 0;
};
#endif //COMMON_2D_CANVAS_INTERFACE_H
#endif //COMMON_2D_CANVAS_INTERFACE_H

View File

@@ -1,47 +1,46 @@
#ifndef COMMON_CALLBACKS_H
#define COMMON_CALLBACKS_H
typedef void (*b3WheelCallback)(float deltax, float deltay);
typedef void (*b3ResizeCallback)( float width, float height);
typedef void (*b3MouseMoveCallback)( float x, float y);
typedef void (*b3ResizeCallback)(float width, float height);
typedef void (*b3MouseMoveCallback)(float x, float y);
typedef void (*b3MouseButtonCallback)(int button, int state, float x, float y);
typedef void (*b3KeyboardCallback)(int keycode, int state);
typedef void (*b3RenderCallback) ();
typedef void (*b3RenderCallback)();
enum {
B3G_ESCAPE = 27,
B3G_F1 = 0xff00,
B3G_F2,
B3G_F3,
B3G_F4,
B3G_F5,
B3G_F6,
B3G_F7,
B3G_F8,
B3G_F9,
B3G_F10,
B3G_F11,
B3G_F12,
B3G_F13,
B3G_F14,
B3G_F15,
B3G_LEFT_ARROW,
B3G_RIGHT_ARROW,
B3G_UP_ARROW,
B3G_DOWN_ARROW,
B3G_PAGE_UP,
B3G_PAGE_DOWN,
B3G_END,
B3G_HOME,
B3G_INSERT,
B3G_DELETE,
B3G_BACKSPACE,
B3G_SHIFT,
B3G_CONTROL,
B3G_ALT,
B3G_RETURN
enum
{
B3G_ESCAPE = 27,
B3G_F1 = 0xff00,
B3G_F2,
B3G_F3,
B3G_F4,
B3G_F5,
B3G_F6,
B3G_F7,
B3G_F8,
B3G_F9,
B3G_F10,
B3G_F11,
B3G_F12,
B3G_F13,
B3G_F14,
B3G_F15,
B3G_LEFT_ARROW,
B3G_RIGHT_ARROW,
B3G_UP_ARROW,
B3G_DOWN_ARROW,
B3G_PAGE_UP,
B3G_PAGE_DOWN,
B3G_END,
B3G_HOME,
B3G_INSERT,
B3G_DELETE,
B3G_BACKSPACE,
B3G_SHIFT,
B3G_CONTROL,
B3G_ALT,
B3G_RETURN
};
#endif

View File

@@ -3,14 +3,14 @@
struct CommonCameraInterface
{
virtual ~CommonCameraInterface(){}
virtual void getCameraProjectionMatrix(float m[16])const = 0;
virtual ~CommonCameraInterface() {}
virtual void getCameraProjectionMatrix(float m[16]) const = 0;
virtual void getCameraViewMatrix(float m[16]) const = 0;
virtual void setVRCamera(const float viewMat[16], const float projectionMatrix[16])=0;
virtual void disableVRCamera()=0;
virtual bool isVRCamera() const =0;
virtual void setVRCameraOffsetTransform(const float offset[16])=0;
virtual void setVRCamera(const float viewMat[16], const float projectionMatrix[16]) = 0;
virtual void disableVRCamera() = 0;
virtual bool isVRCamera() const = 0;
virtual void setVRCameraOffsetTransform(const float offset[16]) = 0;
virtual void getCameraTargetPosition(float pos[3]) const = 0;
virtual void getCameraPosition(float pos[3]) const = 0;
@@ -18,30 +18,29 @@ struct CommonCameraInterface
virtual void getCameraTargetPosition(double pos[3]) const = 0;
virtual void getCameraPosition(double pos[3]) const = 0;
virtual void setCameraTargetPosition(float x,float y,float z) = 0;
virtual void setCameraDistance(float dist) = 0;
virtual float getCameraDistance() const = 0;
virtual void setCameraTargetPosition(float x, float y, float z) = 0;
virtual void setCameraDistance(float dist) = 0;
virtual float getCameraDistance() const = 0;
virtual void setCameraUpVector(float x,float y, float z) = 0;
virtual void getCameraUpVector(float up[3]) const = 0;
virtual void getCameraForwardVector(float fwd[3]) const = 0;
virtual void setCameraUpVector(float x, float y, float z) = 0;
virtual void getCameraUpVector(float up[3]) const = 0;
virtual void getCameraForwardVector(float fwd[3]) const = 0;
///the setCameraUpAxis will call the 'setCameraUpVector' and 'setCameraForwardVector'
virtual void setCameraUpAxis(int axis) = 0;
virtual int getCameraUpAxis() const = 0;
virtual void setCameraUpAxis(int axis) = 0;
virtual int getCameraUpAxis() const = 0;
virtual void setCameraYaw(float yaw) = 0;
virtual float getCameraYaw() const = 0;
virtual void setCameraPitch(float pitch) = 0;
virtual float getCameraPitch() const = 0;
virtual void setCameraYaw(float yaw) = 0;
virtual float getCameraYaw() const = 0;
virtual void setAspectRatio(float ratio) = 0;
virtual float getAspectRatio() const = 0;
virtual float getCameraFrustumFar() const = 0;
virtual float getCameraFrustumNear() const = 0;
virtual void setCameraPitch(float pitch) = 0;
virtual float getCameraPitch() const = 0;
virtual void setAspectRatio(float ratio) = 0;
virtual float getAspectRatio() const = 0;
virtual float getCameraFrustumFar() const = 0;
virtual float getCameraFrustumNear() const = 0;
};
#endif //COMMON_CAMERA_INTERFACE_H
#endif //COMMON_CAMERA_INTERFACE_H

View File

@@ -6,102 +6,91 @@
struct CommandProcessorCreationInterface
{
virtual ~CommandProcessorCreationInterface() {}
virtual class CommandProcessorInterface* createCommandProcessor()=0;
virtual void deleteCommandProcessor(CommandProcessorInterface*)=0;
virtual class CommandProcessorInterface* createCommandProcessor() = 0;
virtual void deleteCommandProcessor(CommandProcessorInterface*) = 0;
};
struct CommonExampleOptions
{
struct GUIHelperInterface* m_guiHelper;
struct GUIHelperInterface* m_guiHelper;
//Those are optional, some examples will use them others don't. Each example should work with them being 0.
int m_option;
int m_option;
const char* m_fileName;
class SharedMemoryInterface* m_sharedMem;
CommandProcessorCreationInterface* m_commandProcessorCreation;
bool m_skipGraphicsUpdate;
CommonExampleOptions(struct GUIHelperInterface* helper, int option=0)
:m_guiHelper(helper),
m_option(option),
m_fileName(0),
m_sharedMem(0),
m_commandProcessorCreation(0),
m_skipGraphicsUpdate(false)
bool m_skipGraphicsUpdate;
CommonExampleOptions(struct GUIHelperInterface* helper, int option = 0)
: m_guiHelper(helper),
m_option(option),
m_fileName(0),
m_sharedMem(0),
m_commandProcessorCreation(0),
m_skipGraphicsUpdate(false)
{
}
};
class CommonExampleInterface
{
public:
typedef class CommonExampleInterface* (CreateFunc)(CommonExampleOptions& options);
typedef class CommonExampleInterface*(CreateFunc)(CommonExampleOptions& options);
virtual ~CommonExampleInterface()
{
}
virtual void initPhysics()=0;
virtual void exitPhysics()=0;
virtual void updateGraphics(){}
virtual void stepSimulation(float deltaTime)=0;
virtual void renderScene()=0;
virtual void physicsDebugDraw(int debugFlags)=0;//for now we reuse the flags in Bullet/src/LinearMath/btIDebugDraw.h
virtual void initPhysics() = 0;
virtual void exitPhysics() = 0;
virtual void updateGraphics() {}
virtual void stepSimulation(float deltaTime) = 0;
virtual void renderScene() = 0;
virtual void physicsDebugDraw(int debugFlags) = 0; //for now we reuse the flags in Bullet/src/LinearMath/btIDebugDraw.h
//reset camera is only called when switching demo. this way you can restart (initPhysics) and watch in a specific location easier
virtual void resetCamera(){};
virtual bool mouseMoveCallback(float x,float y)=0;
virtual bool mouseButtonCallback(int button, int state, float x, float y)=0;
virtual bool keyboardCallback(int key, int state)=0;
virtual void resetCamera(){};
virtual bool mouseMoveCallback(float x, float y) = 0;
virtual bool mouseButtonCallback(int button, int state, float x, float y) = 0;
virtual bool keyboardCallback(int key, int state) = 0;
virtual void vrControllerMoveCallback(int controllerId, float pos[4], float orientation[4], float analogAxis, float auxAnalogAxes[10]) {}
virtual void vrControllerButtonCallback(int controllerId, int button, int state, float pos[4], float orientation[4]){}
virtual void vrHMDMoveCallback(int controllerId, float pos[4], float orientation[4]){}
virtual void vrGenericTrackerMoveCallback(int controllerId, float pos[4], float orientation[4]){}
virtual void vrControllerMoveCallback(int controllerId, float pos[4], float orientation[4], float analogAxis, float auxAnalogAxes[10]) {}
virtual void vrControllerButtonCallback(int controllerId, int button, int state, float pos[4], float orientation[4]) {}
virtual void vrHMDMoveCallback(int controllerId, float pos[4], float orientation[4]) {}
virtual void vrGenericTrackerMoveCallback(int controllerId, float pos[4], float orientation[4]) {}
virtual void processCommandLineArgs(int argc, char* argv[]){};
virtual void processCommandLineArgs(int argc, char* argv[]){};
};
class ExampleEntries
{
public:
virtual ~ExampleEntries() {}
virtual ~ExampleEntries() {}
virtual void initExampleEntries() = 0;
virtual void initOpenCLExampleEntries() = 0;
virtual void initExampleEntries()=0;
virtual int getNumRegisteredExamples() = 0;
virtual void initOpenCLExampleEntries()=0;
virtual CommonExampleInterface::CreateFunc* getExampleCreateFunc(int index) = 0;
virtual int getNumRegisteredExamples()=0;
virtual const char* getExampleName(int index) = 0;
virtual CommonExampleInterface::CreateFunc* getExampleCreateFunc(int index)=0;
virtual const char* getExampleName(int index)=0;
virtual const char* getExampleDescription(int index)=0;
virtual int getExampleOption(int index)=0;
virtual const char* getExampleDescription(int index) = 0;
virtual int getExampleOption(int index) = 0;
};
CommonExampleInterface* StandaloneExampleCreateFunc(CommonExampleOptions& options);
#ifdef B3_USE_STANDALONE_EXAMPLE
#define B3_STANDALONE_EXAMPLE(ExampleFunc) CommonExampleInterface* StandaloneExampleCreateFunc(CommonExampleOptions& options)\
{\
return ExampleFunc(options);\
#define B3_STANDALONE_EXAMPLE(ExampleFunc) \
CommonExampleInterface* StandaloneExampleCreateFunc(CommonExampleOptions& options) \
{ \
return ExampleFunc(options); \
}
#else//B3_USE_STANDALONE_EXAMPLE
#define B3_STANDALONE_EXAMPLE(ExampleFunc)
#endif //B3_USE_STANDALONE_EXAMPLE
#else //B3_USE_STANDALONE_EXAMPLE
#define B3_STANDALONE_EXAMPLE(ExampleFunc)
#endif //B3_USE_STANDALONE_EXAMPLE
#endif //COMMON_EXAMPLE_INTERFACE_H
#endif //COMMON_EXAMPLE_INTERFACE_H

View File

@@ -1,7 +1,6 @@
#ifndef GUI_HELPER_INTERFACE_H
#define GUI_HELPER_INTERFACE_H
class btRigidBody;
class btVector3;
class btCollisionObject;
@@ -12,8 +11,6 @@ struct CommonParameterInterface;
struct CommonRenderInterface;
struct CommonGraphicsApp;
typedef void (*VisualizerFlagCallback)(int flag, bool enable);
///The Bullet 2 GraphicsPhysicsBridge let's the graphics engine create graphics representation and synchronize
@@ -21,132 +18,129 @@ struct GUIHelperInterface
{
virtual ~GUIHelperInterface() {}
virtual void createRigidBodyGraphicsObject(btRigidBody* body,const btVector3& color) = 0;
virtual void createRigidBodyGraphicsObject(btRigidBody* body, const btVector3& color) = 0;
virtual void createCollisionObjectGraphicsObject(btCollisionObject* obj,const btVector3& color) = 0;
virtual void createCollisionObjectGraphicsObject(btCollisionObject* obj, const btVector3& color) = 0;
virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape)=0;
virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape) = 0;
virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld)=0;
virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld) = 0;
virtual void render(const btDiscreteDynamicsWorld* rbWorld)=0;
virtual void render(const btDiscreteDynamicsWorld* rbWorld) = 0;
virtual void createPhysicsDebugDrawer( btDiscreteDynamicsWorld* rbWorld)=0;
virtual void createPhysicsDebugDrawer(btDiscreteDynamicsWorld* rbWorld) = 0;
virtual int registerTexture(const unsigned char* texels, int width, int height)=0;
virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices,int primitiveType, int textureId) = 0;
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) =0;
virtual void removeAllGraphicsInstances()=0;
virtual int registerTexture(const unsigned char* texels, int width, int height) = 0;
virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices, int primitiveType, int textureId) = 0;
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) = 0;
virtual void removeAllGraphicsInstances() = 0;
virtual void removeGraphicsInstance(int graphicsUid) {}
virtual void changeRGBAColor(int instanceUid, const double rgbaColor[4]) {}
virtual void changeSpecularColor(int instanceUid, const double specularColor[3]) {}
virtual void changeTexture(int textureUniqueId, const unsigned char* rgbTexels, int width, int height){}
virtual void changeTexture(int textureUniqueId, const unsigned char* rgbTexels, int width, int height) {}
virtual int getShapeIndexFromInstance(int instanceUid){return -1;}
virtual void replaceTexture(int shapeIndex, int textureUid){}
virtual int getShapeIndexFromInstance(int instanceUid) { return -1; }
virtual void replaceTexture(int shapeIndex, int textureUid) {}
virtual void removeTexture(int textureUid) {}
virtual Common2dCanvasInterface* get2dCanvasInterface()=0;
virtual CommonParameterInterface* getParameterInterface()=0;
virtual CommonRenderInterface* getRenderInterface()=0;
virtual Common2dCanvasInterface* get2dCanvasInterface() = 0;
virtual CommonParameterInterface* getParameterInterface() = 0;
virtual CommonRenderInterface* getRenderInterface() = 0;
virtual const CommonRenderInterface* getRenderInterface() const
{
return 0;
}
virtual CommonGraphicsApp* getAppInterface()=0;
virtual CommonGraphicsApp* getAppInterface() = 0;
virtual void setUpAxis(int axis)=0;
virtual void setUpAxis(int axis) = 0;
virtual void resetCamera(float camDist, float yaw, float pitch, float camPosX,float camPosY, float camPosZ)=0;
virtual void resetCamera(float camDist, float yaw, float pitch, float camPosX, float camPosY, float camPosZ) = 0;
virtual bool getCameraInfo(int* width, int* height, float viewMatrix[16], float projectionMatrix[16], float camUp[3], float camForward[3],float hor[3], float vert[3], float* yaw, float* pitch, float* camDist, float camTarget[3]) const
virtual bool getCameraInfo(int* width, int* height, float viewMatrix[16], float projectionMatrix[16], float camUp[3], float camForward[3], float hor[3], float vert[3], float* yaw, float* pitch, float* camDist, float camTarget[3]) const
{
return false;
}
virtual void setVisualizerFlag(int flag, int enable){};
virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
float* depthBuffer, int depthBufferSizeInPixels,
int startPixelIndex, int destinationWidth, int destinationHeight, int* numPixelsCopied)
{
copyCameraImageData(viewMatrix,projectionMatrix,pixelsRGBA,rgbaBufferSizeInPixels,
depthBuffer,depthBufferSizeInPixels,
0,0,
startPixelIndex,destinationWidth,
destinationHeight,numPixelsCopied);
}
virtual void setVisualizerFlag(int flag, int enable){};
virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
float* depthBuffer, int depthBufferSizeInPixels,
int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels,
int startPixelIndex, int destinationWidth, int destinationHeight, int* numPixelsCopied)=0;
virtual void debugDisplayCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
float* depthBuffer, int depthBufferSizeInPixels,
int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels,
int startPixelIndex, int destinationWidth, int destinationHeight, int* numPixelsCopied){}
virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
float* depthBuffer, int depthBufferSizeInPixels,
int startPixelIndex, int destinationWidth, int destinationHeight, int* numPixelsCopied)
{
copyCameraImageData(viewMatrix, projectionMatrix, pixelsRGBA, rgbaBufferSizeInPixels,
depthBuffer, depthBufferSizeInPixels,
0, 0,
startPixelIndex, destinationWidth,
destinationHeight, numPixelsCopied);
}
virtual void setProjectiveTextureMatrices(const float viewMatrix[16], const float projectionMatrix[16]){}
virtual void setProjectiveTexture(bool useProjectiveTexture){}
virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
float* depthBuffer, int depthBufferSizeInPixels,
int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels,
int startPixelIndex, int destinationWidth, int destinationHeight, int* numPixelsCopied) = 0;
virtual void debugDisplayCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
float* depthBuffer, int depthBufferSizeInPixels,
int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels,
int startPixelIndex, int destinationWidth, int destinationHeight, int* numPixelsCopied) {}
virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld) =0;
virtual void drawText3D( const char* txt, float posX, float posY, float posZ, float size){}
virtual void drawText3D( const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag){}
virtual int addUserDebugText3D( const char* txt, const double positionXYZ[3], const double orientation[4], const double textColorRGB[3], double size, double lifeTime, int trackingVisualShapeIndex, int optionFlags, int replaceItemUid){return -1;}
virtual int addUserDebugLine(const double debugLineFromXYZ[3], const double debugLineToXYZ[3], const double debugLineColorRGB[3], double lineWidth, double lifeTime , int trackingVisualShapeIndex, int replaceItemUid){return -1;};
virtual int addUserDebugParameter(const char* txt, double rangeMin, double rangeMax, double startValue){return -1;};
virtual int readUserDebugParameter(int itemUniqueId, double* value) { return 0;}
virtual void setProjectiveTextureMatrices(const float viewMatrix[16], const float projectionMatrix[16]) {}
virtual void setProjectiveTexture(bool useProjectiveTexture) {}
virtual void removeUserDebugItem( int debugItemUniqueId){};
virtual void removeAllUserDebugItems( ){};
virtual void setVisualizerFlagCallback(VisualizerFlagCallback callback){}
virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld) = 0;
virtual void drawText3D(const char* txt, float posX, float posY, float posZ, float size) {}
virtual void drawText3D(const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag) {}
virtual int addUserDebugText3D(const char* txt, const double positionXYZ[3], const double orientation[4], const double textColorRGB[3], double size, double lifeTime, int trackingVisualShapeIndex, int optionFlags, int replaceItemUid) { return -1; }
virtual int addUserDebugLine(const double debugLineFromXYZ[3], const double debugLineToXYZ[3], const double debugLineColorRGB[3], double lineWidth, double lifeTime, int trackingVisualShapeIndex, int replaceItemUid) { return -1; };
virtual int addUserDebugParameter(const char* txt, double rangeMin, double rangeMax, double startValue) { return -1; };
virtual int readUserDebugParameter(int itemUniqueId, double* value) { return 0; }
virtual void removeUserDebugItem(int debugItemUniqueId){};
virtual void removeAllUserDebugItems(){};
virtual void setVisualizerFlagCallback(VisualizerFlagCallback callback) {}
//empty name stops dumping video
virtual void dumpFramesToVideo(const char* mp4FileName) {};
virtual void dumpFramesToVideo(const char* mp4FileName){};
};
///the DummyGUIHelper does nothing, so we can test the examples without GUI/graphics (in 'console mode')
struct DummyGUIHelper : public GUIHelperInterface
{
DummyGUIHelper() {}
virtual ~DummyGUIHelper() {}
virtual void createRigidBodyGraphicsObject(btRigidBody* body,const btVector3& color){}
virtual void createRigidBodyGraphicsObject(btRigidBody* body, const btVector3& color) {}
virtual void createCollisionObjectGraphicsObject(btCollisionObject* obj,const btVector3& color) {}
virtual void createCollisionObjectGraphicsObject(btCollisionObject* obj, const btVector3& color) {}
virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape){}
virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape) {}
virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld){}
virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld) {}
virtual void render(const btDiscreteDynamicsWorld* rbWorld) {}
virtual void createPhysicsDebugDrawer( btDiscreteDynamicsWorld* rbWorld){}
virtual void createPhysicsDebugDrawer(btDiscreteDynamicsWorld* rbWorld) {}
virtual int registerTexture(const unsigned char* texels, int width, int height){return -1;}
virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices,int primitiveType, int textureId){return -1;}
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) {return -1;}
virtual void removeAllGraphicsInstances(){}
virtual void removeGraphicsInstance(int graphicsUid){}
virtual int registerTexture(const unsigned char* texels, int width, int height) { return -1; }
virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices, int primitiveType, int textureId) { return -1; }
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) { return -1; }
virtual void removeAllGraphicsInstances() {}
virtual void removeGraphicsInstance(int graphicsUid) {}
virtual void changeRGBAColor(int instanceUid, const double rgbaColor[4]) {}
virtual Common2dCanvasInterface* get2dCanvasInterface()
{
return 0;
}
virtual CommonParameterInterface* getParameterInterface()
{
return 0;
@@ -156,63 +150,60 @@ struct DummyGUIHelper : public GUIHelperInterface
{
return 0;
}
virtual CommonGraphicsApp* getAppInterface()
{
return 0;
}
virtual void setUpAxis(int axis)
{
}
virtual void resetCamera(float camDist, float yaw, float pitch, float camPosX,float camPosY, float camPosZ)
virtual void resetCamera(float camDist, float yaw, float pitch, float camPosX, float camPosY, float camPosZ)
{
}
virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
float* depthBuffer, int depthBufferSizeInPixels,
int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels,
int startPixelIndex, int width, int height, int* numPixelsCopied)
virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
float* depthBuffer, int depthBufferSizeInPixels,
int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels,
int startPixelIndex, int width, int height, int* numPixelsCopied)
{
if (numPixelsCopied)
*numPixelsCopied = 0;
if (numPixelsCopied)
*numPixelsCopied = 0;
}
virtual void setProjectiveTextureMatrices(const float viewMatrix[16], const float projectionMatrix[16])
{
}
virtual void setProjectiveTexture(bool useProjectiveTexture)
{
}
virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld)
{
}
virtual void drawText3D( const char* txt, float posX, float posZY, float posZ, float size)
{
}
virtual void drawText3D( const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag)
virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld)
{
}
virtual int addUserDebugLine(const double debugLineFromXYZ[3], const double debugLineToXYZ[3], const double debugLineColorRGB[3], double lineWidth, double lifeTime , int trackingVisualShapeIndex, int replaceItemUid)
virtual void drawText3D(const char* txt, float posX, float posZY, float posZ, float size)
{
}
virtual void drawText3D(const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag)
{
}
virtual int addUserDebugLine(const double debugLineFromXYZ[3], const double debugLineToXYZ[3], const double debugLineColorRGB[3], double lineWidth, double lifeTime, int trackingVisualShapeIndex, int replaceItemUid)
{
return -1;
}
virtual void removeUserDebugItem( int debugItemUniqueId)
virtual void removeUserDebugItem(int debugItemUniqueId)
{
}
virtual void removeAllUserDebugItems( )
virtual void removeAllUserDebugItems()
{
}
};
#endif //GUI_HELPER_INTERFACE_H
#endif //GUI_HELPER_INTERFACE_H

View File

@@ -1,8 +1,6 @@
#ifndef COMMON_GRAPHICS_APP_H
#define COMMON_GRAPHICS_APP_H
#include "Bullet3Common/b3Vector3.h"
#include "CommonRenderInterface.h"
#include "CommonWindowInterface.h"
@@ -10,26 +8,26 @@
struct DrawGridData
{
int gridSize;
float upOffset;
int upAxis;
float gridColor[4];
int gridSize;
float upOffset;
int upAxis;
float gridColor[4];
DrawGridData(int upAxis=1)
:gridSize(10),
upOffset(0.001f),
upAxis(upAxis)
{
gridColor[0] = 0.6f;
gridColor[1] = 0.6f;
gridColor[2] = 0.6f;
gridColor[3] = 1.f;
}
DrawGridData(int upAxis = 1)
: gridSize(10),
upOffset(0.001f),
upAxis(upAxis)
{
gridColor[0] = 0.6f;
gridColor[1] = 0.6f;
gridColor[2] = 0.6f;
gridColor[3] = 1.f;
}
};
enum EnumSphereLevelOfDetail
{
SPHERE_LOD_POINT_SPRITE=0,
SPHERE_LOD_POINT_SPRITE = 0,
SPHERE_LOD_LOW,
SPHERE_LOD_MEDIUM,
SPHERE_LOD_HIGH,
@@ -39,38 +37,38 @@ struct CommonGraphicsApp
{
enum drawText3DOption
{
eDrawText3D_OrtogonalFaceCamera=1,
eDrawText3D_TrueType=2,
eDrawText3D_TrackObject=4,
eDrawText3D_OrtogonalFaceCamera = 1,
eDrawText3D_TrueType = 2,
eDrawText3D_TrackObject = 4,
};
class CommonWindowInterface* m_window;
struct CommonRenderInterface* m_renderer;
struct CommonParameterInterface* m_parameterInterface;
struct Common2dCanvasInterface* m_2dCanvasInterface;
class CommonWindowInterface* m_window;
struct CommonRenderInterface* m_renderer;
struct CommonParameterInterface* m_parameterInterface;
struct Common2dCanvasInterface* m_2dCanvasInterface;
bool m_leftMouseButton;
bool m_middleMouseButton;
bool m_rightMouseButton;
bool m_leftMouseButton;
bool m_middleMouseButton;
bool m_rightMouseButton;
float m_wheelMultiplier;
float m_mouseMoveMultiplier;
float m_mouseXpos;
float m_mouseYpos;
bool m_mouseInitialized;
float m_backgroundColorRGB[3];
float m_mouseXpos;
float m_mouseYpos;
bool m_mouseInitialized;
float m_backgroundColorRGB[3];
CommonGraphicsApp()
:m_window(0),
m_renderer(0),
m_parameterInterface(0),
m_2dCanvasInterface(0),
m_leftMouseButton(false),
m_middleMouseButton(false),
m_rightMouseButton(false),
m_wheelMultiplier(0.01f),
m_mouseMoveMultiplier(0.4f),
m_mouseXpos(0.f),
m_mouseYpos(0.f),
m_mouseInitialized(false)
: m_window(0),
m_renderer(0),
m_parameterInterface(0),
m_2dCanvasInterface(0),
m_leftMouseButton(false),
m_middleMouseButton(false),
m_rightMouseButton(false),
m_wheelMultiplier(0.01f),
m_mouseMoveMultiplier(0.4f),
m_mouseXpos(0.f),
m_mouseYpos(0.f),
m_mouseInitialized(false)
{
m_backgroundColorRGB[0] = 0.7;
m_backgroundColorRGB[1] = 0.7;
@@ -80,11 +78,11 @@ struct CommonGraphicsApp
{
}
virtual void dumpNextFrameToPng(const char* pngFilename){}
virtual void dumpFramesToVideo(const char* mp4Filename){}
virtual void getScreenPixels(unsigned char* rgbaBuffer, int bufferSizeInBytes, float* depthBuffer, int depthBufferSizeInBytes){}
virtual void dumpNextFrameToPng(const char* pngFilename) {}
virtual void dumpFramesToVideo(const char* mp4Filename) {}
virtual void getScreenPixels(unsigned char* rgbaBuffer, int bufferSizeInBytes, float* depthBuffer, int depthBufferSizeInBytes) {}
virtual void getBackgroundColor(float* red, float* green, float* blue) const
{
if (red)
@@ -113,190 +111,175 @@ struct CommonGraphicsApp
{
m_mouseMoveMultiplier = mult;
}
virtual float getMouseMoveMultiplier() const
{
return m_mouseMoveMultiplier;
}
virtual void drawGrid(DrawGridData data=DrawGridData()) = 0;
virtual void drawGrid(DrawGridData data = DrawGridData()) = 0;
virtual void setUpAxis(int axis) = 0;
virtual int getUpAxis() const = 0;
virtual void swapBuffer() = 0;
virtual void drawText( const char* txt, int posX, int posY)
virtual void drawText(const char* txt, int posX, int posY)
{
float size=1;
float colorRGBA[4]={0,0,0,1};
drawText(txt,posX,posY, size, colorRGBA);
float size = 1;
float colorRGBA[4] = {0, 0, 0, 1};
drawText(txt, posX, posY, size, colorRGBA);
}
virtual void drawText( const char* txt, int posX, int posY, float size)
virtual void drawText(const char* txt, int posX, int posY, float size)
{
float colorRGBA[4]={0,0,0,1};
drawText(txt,posX,posY,size,colorRGBA);
float colorRGBA[4] = {0, 0, 0, 1};
drawText(txt, posX, posY, size, colorRGBA);
}
virtual void drawText( const char* txt, int posX, int posY, float size, float colorRGBA[4]) = 0;
virtual void drawText3D( const char* txt, float posX, float posY, float posZ, float size)=0;
virtual void drawText3D( const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag)=0;
virtual void drawTexturedRect(float x0, float y0, float x1, float y1, float color[4], float u0,float v0, float u1, float v1, int useRGBA)=0;
virtual int registerCubeShape(float halfExtentsX,float halfExtentsY, float halfExtentsZ, int textureIndex = -1, float textureScaling = 1)=0;
virtual int registerGraphicsUnitSphereShape(EnumSphereLevelOfDetail lod, int textureId=-1) = 0;
virtual void drawText(const char* txt, int posX, int posY, float size, float colorRGBA[4]) = 0;
virtual void drawText3D(const char* txt, float posX, float posY, float posZ, float size) = 0;
virtual void drawText3D(const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag) = 0;
virtual void drawTexturedRect(float x0, float y0, float x1, float y1, float color[4], float u0, float v0, float u1, float v1, int useRGBA) = 0;
virtual int registerCubeShape(float halfExtentsX, float halfExtentsY, float halfExtentsZ, int textureIndex = -1, float textureScaling = 1) = 0;
virtual int registerGraphicsUnitSphereShape(EnumSphereLevelOfDetail lod, int textureId = -1) = 0;
virtual void registerGrid(int xres, int yres, float color0[4], float color1[4])=0;
virtual void registerGrid(int xres, int yres, float color0[4], float color1[4]) = 0;
void defaultMouseButtonCallback( int button, int state, float x, float y)
void defaultMouseButtonCallback(int button, int state, float x, float y)
{
if (button==0)
m_leftMouseButton= (state==1);
if (button==1)
m_middleMouseButton= (state==1);
if (button == 0)
m_leftMouseButton = (state == 1);
if (button == 1)
m_middleMouseButton = (state == 1);
if (button==2)
m_rightMouseButton= (state==1);
if (button == 2)
m_rightMouseButton = (state == 1);
m_mouseXpos = x;
m_mouseYpos = y;
m_mouseInitialized = true;
}
void defaultMouseMoveCallback( float x, float y)
void defaultMouseMoveCallback(float x, float y)
{
if (m_window && m_renderer)
{
CommonCameraInterface* camera = m_renderer->getActiveCamera();
bool isAltPressed = m_window->isModifierKeyPressed(B3G_ALT);
bool isControlPressed = m_window->isModifierKeyPressed(B3G_CONTROL);
if (isAltPressed || isControlPressed)
{
float xDelta = x-m_mouseXpos;
float yDelta = y-m_mouseYpos;
float xDelta = x - m_mouseXpos;
float yDelta = y - m_mouseYpos;
float cameraDistance = camera->getCameraDistance();
float pitch = camera->getCameraPitch();
float yaw = camera->getCameraYaw();
float targPos[3];
float camPos[3];
float camPos[3];
camera->getCameraTargetPosition(targPos);
camera->getCameraPosition(camPos);
b3Vector3 cameraPosition = b3MakeVector3(b3Scalar(camPos[0]),
b3Scalar(camPos[1]),
b3Scalar(camPos[2]));
b3Vector3 cameraTargetPosition = b3MakeVector3( b3Scalar(targPos[0]),
b3Scalar(targPos[1]),
b3Scalar(targPos[2]));
b3Vector3 cameraUp = b3MakeVector3(0,0,0);
b3Vector3 cameraPosition = b3MakeVector3(b3Scalar(camPos[0]),
b3Scalar(camPos[1]),
b3Scalar(camPos[2]));
b3Vector3 cameraTargetPosition = b3MakeVector3(b3Scalar(targPos[0]),
b3Scalar(targPos[1]),
b3Scalar(targPos[2]));
b3Vector3 cameraUp = b3MakeVector3(0, 0, 0);
cameraUp[camera->getCameraUpAxis()] = 1.f;
if (m_leftMouseButton)
{
// if (b3Fabs(xDelta)>b3Fabs(yDelta))
// {
pitch -= yDelta*m_mouseMoveMultiplier;
// } else
// {
yaw -= xDelta*m_mouseMoveMultiplier;
// }
// if (b3Fabs(xDelta)>b3Fabs(yDelta))
// {
pitch -= yDelta * m_mouseMoveMultiplier;
// } else
// {
yaw -= xDelta * m_mouseMoveMultiplier;
// }
}
if (m_middleMouseButton)
{
cameraTargetPosition += cameraUp * yDelta*0.01;
cameraTargetPosition += cameraUp * yDelta * 0.01;
b3Vector3 fwd = cameraTargetPosition-cameraPosition;
b3Vector3 fwd = cameraTargetPosition - cameraPosition;
b3Vector3 side = cameraUp.cross(fwd);
side.normalize();
cameraTargetPosition += side * xDelta*0.01;
cameraTargetPosition += side * xDelta * 0.01;
}
if (m_rightMouseButton)
{
cameraDistance -= xDelta*0.01f;
cameraDistance -= yDelta*0.01f;
if (cameraDistance<1)
cameraDistance=1;
if (cameraDistance>1000)
cameraDistance=1000;
cameraDistance -= xDelta * 0.01f;
cameraDistance -= yDelta * 0.01f;
if (cameraDistance < 1)
cameraDistance = 1;
if (cameraDistance > 1000)
cameraDistance = 1000;
}
camera->setCameraDistance(cameraDistance);
camera->setCameraPitch(pitch);
camera->setCameraYaw(yaw);
camera->setCameraTargetPosition(cameraTargetPosition[0],cameraTargetPosition[1],cameraTargetPosition[2]);
}
camera->setCameraTargetPosition(cameraTargetPosition[0], cameraTargetPosition[1], cameraTargetPosition[2]);
}
} //m_window && m_renderer
}//m_window && m_renderer
m_mouseXpos = x;
m_mouseYpos = y;
m_mouseInitialized = true;
}
// void defaultKeyboardCallback(int key, int state)
// {
// }
void defaultWheelCallback( float deltax, float deltay)
// void defaultKeyboardCallback(int key, int state)
// {
// }
void defaultWheelCallback(float deltax, float deltay)
{
if (m_renderer)
{
b3Vector3 cameraTargetPosition, cameraPosition, cameraUp = b3MakeVector3(0,0,0);
b3Vector3 cameraTargetPosition, cameraPosition, cameraUp = b3MakeVector3(0, 0, 0);
cameraUp[getUpAxis()] = 1;
CommonCameraInterface* camera = m_renderer->getActiveCamera();
camera->getCameraPosition(cameraPosition);
camera->getCameraTargetPosition(cameraTargetPosition);
if (!m_leftMouseButton)
{
float cameraDistance = camera->getCameraDistance();
if (deltay<0 || cameraDistance>1)
float cameraDistance = camera->getCameraDistance();
if (deltay < 0 || cameraDistance > 1)
{
cameraDistance -= deltay*0.01f;
if (cameraDistance<1)
cameraDistance=1;
cameraDistance -= deltay * 0.01f;
if (cameraDistance < 1)
cameraDistance = 1;
camera->setCameraDistance(cameraDistance);
} else
{
b3Vector3 fwd = cameraTargetPosition-cameraPosition;
fwd.normalize();
cameraTargetPosition += fwd*deltay*m_wheelMultiplier;//todo: expose it in the GUI?
}
} else
{
if (b3Fabs(deltax)>b3Fabs(deltay))
else
{
b3Vector3 fwd = cameraTargetPosition-cameraPosition;
b3Vector3 fwd = cameraTargetPosition - cameraPosition;
fwd.normalize();
cameraTargetPosition += fwd * deltay * m_wheelMultiplier; //todo: expose it in the GUI?
}
}
else
{
if (b3Fabs(deltax) > b3Fabs(deltay))
{
b3Vector3 fwd = cameraTargetPosition - cameraPosition;
b3Vector3 side = cameraUp.cross(fwd);
side.normalize();
cameraTargetPosition += side * deltax*m_wheelMultiplier;
} else
cameraTargetPosition += side * deltax * m_wheelMultiplier;
}
else
{
cameraTargetPosition -= cameraUp * deltay*m_wheelMultiplier;
cameraTargetPosition -= cameraUp * deltay * m_wheelMultiplier;
}
}
camera->setCameraTargetPosition(cameraTargetPosition[0],cameraTargetPosition[1],cameraTargetPosition[2]);
camera->setCameraTargetPosition(cameraTargetPosition[0], cameraTargetPosition[1], cameraTargetPosition[2]);
}
}
};
#endif //COMMON_GRAPHICS_APP_H
#endif //COMMON_GRAPHICS_APP_H

View File

@@ -2,7 +2,6 @@
#ifndef COMMON_MULTI_BODY_SETUP_H
#define COMMON_MULTI_BODY_SETUP_H
#include "btBulletDynamicsCommon.h"
#include "BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h"
@@ -20,32 +19,33 @@
enum MyFilterModes
{
FILTER_GROUPAMASKB_AND_GROUPBMASKA2=0,
FILTER_GROUPAMASKB_AND_GROUPBMASKA2 = 0,
FILTER_GROUPAMASKB_OR_GROUPBMASKA2
};
struct MyOverlapFilterCallback2 : public btOverlapFilterCallback
{
int m_filterMode;
MyOverlapFilterCallback2()
:m_filterMode(FILTER_GROUPAMASKB_AND_GROUPBMASKA2)
: m_filterMode(FILTER_GROUPAMASKB_AND_GROUPBMASKA2)
{
}
virtual ~MyOverlapFilterCallback2()
{}
// return true when pairs need collision
virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
{
if (m_filterMode==FILTER_GROUPAMASKB_AND_GROUPBMASKA2)
}
// return true when pairs need collision
virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) const
{
if (m_filterMode == FILTER_GROUPAMASKB_AND_GROUPBMASKA2)
{
bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
return collides;
}
if (m_filterMode==FILTER_GROUPAMASKB_OR_GROUPBMASKA2)
if (m_filterMode == FILTER_GROUPAMASKB_OR_GROUPBMASKA2)
{
bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
collides = collides || (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
@@ -57,20 +57,20 @@ struct MyOverlapFilterCallback2 : public btOverlapFilterCallback
struct CommonMultiBodyBase : public CommonExampleInterface
{
//keep the collision shapes, for deletion/cleanup
btAlignedObjectArray<btCollisionShape*> m_collisionShapes;
//keep the collision shapes, for deletion/cleanup
btAlignedObjectArray<btCollisionShape*> m_collisionShapes;
MyOverlapFilterCallback2* m_filterCallback;
btOverlappingPairCache* m_pairCache;
btBroadphaseInterface* m_broadphase;
btCollisionDispatcher* m_dispatcher;
btMultiBodyConstraintSolver* m_solver;
btBroadphaseInterface* m_broadphase;
btCollisionDispatcher* m_dispatcher;
btMultiBodyConstraintSolver* m_solver;
btDefaultCollisionConfiguration* m_collisionConfiguration;
btMultiBodyDynamicsWorld* m_dynamicsWorld;
//data for picking objects
class btRigidBody* m_pickedBody;
class btRigidBody* m_pickedBody;
class btTypedConstraint* m_pickedConstraint;
class btMultiBodyPoint2Point* m_pickingMultiBodyPoint2Point;
class btMultiBodyPoint2Point* m_pickingMultiBodyPoint2Point;
btVector3 m_oldPickingPos;
btVector3 m_hitPos;
@@ -80,18 +80,18 @@ struct CommonMultiBodyBase : public CommonExampleInterface
struct GUIHelperInterface* m_guiHelper;
CommonMultiBodyBase(GUIHelperInterface* helper)
:m_filterCallback(0),
m_pairCache(0),
m_broadphase(0),
m_dispatcher(0),
m_solver(0),
m_collisionConfiguration(0),
m_dynamicsWorld(0),
m_pickedBody(0),
m_pickedConstraint(0),
m_pickingMultiBodyPoint2Point(0),
m_prevCanSleep(false),
m_guiHelper(helper)
: m_filterCallback(0),
m_pairCache(0),
m_broadphase(0),
m_dispatcher(0),
m_solver(0),
m_collisionConfiguration(0),
m_dynamicsWorld(0),
m_pickedBody(0),
m_pickedConstraint(0),
m_pickingMultiBodyPoint2Point(0),
m_prevCanSleep(false),
m_guiHelper(helper)
{
}
@@ -101,15 +101,15 @@ struct CommonMultiBodyBase : public CommonExampleInterface
m_collisionConfiguration = new btDefaultCollisionConfiguration();
//m_collisionConfiguration->setConvexConvexMultipointIterations();
m_filterCallback = new MyOverlapFilterCallback2();
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_pairCache = new btHashedOverlappingPairCache();
m_pairCache->setOverlapFilterCallback(m_filterCallback);
m_broadphase = new btDbvtBroadphase(m_pairCache);//btSimpleBroadphase();
m_broadphase = new btDbvtBroadphase(m_pairCache); //btSimpleBroadphase();
m_solver = new btMultiBodyConstraintSolver;
@@ -118,7 +118,6 @@ struct CommonMultiBodyBase : public CommonExampleInterface
m_dynamicsWorld->setGravity(btVector3(0, -10, 0));
}
virtual void stepSimulation(float deltaTime)
{
if (m_dynamicsWorld)
@@ -127,7 +126,6 @@ struct CommonMultiBodyBase : public CommonExampleInterface
}
}
virtual void exitPhysics()
{
removePickingConstraint();
@@ -137,13 +135,12 @@ struct CommonMultiBodyBase : public CommonExampleInterface
if (m_dynamicsWorld)
{
int i;
for (i = m_dynamicsWorld->getNumConstraints() - 1; i >= 0; i--)
{
m_dynamicsWorld->removeConstraint(m_dynamicsWorld->getConstraint(i));
}
int i;
for (i = m_dynamicsWorld->getNumConstraints() - 1; i >= 0; i--)
{
m_dynamicsWorld->removeConstraint(m_dynamicsWorld->getConstraint(i));
}
for (i = m_dynamicsWorld->getNumMultiBodyConstraints() - 1; i >= 0; i--)
{
btMultiBodyConstraint* mbc = m_dynamicsWorld->getMultiBodyConstraint(i);
@@ -170,7 +167,7 @@ struct CommonMultiBodyBase : public CommonExampleInterface
}
}
//delete collision shapes
for (int j = 0; j<m_collisionShapes.size(); j++)
for (int j = 0; j < m_collisionShapes.size(); j++)
{
btCollisionShape* shape = m_collisionShapes[j];
delete shape;
@@ -181,22 +178,22 @@ struct CommonMultiBodyBase : public CommonExampleInterface
m_dynamicsWorld = 0;
delete m_solver;
m_solver=0;
m_solver = 0;
delete m_broadphase;
m_broadphase=0;
m_broadphase = 0;
delete m_dispatcher;
m_dispatcher=0;
m_dispatcher = 0;
delete m_pairCache;
m_pairCache = 0;
delete m_filterCallback;
m_filterCallback = 0;
delete m_collisionConfiguration;
m_collisionConfiguration=0;
m_collisionConfiguration = 0;
}
virtual void syncPhysicsToGraphics()
@@ -209,76 +206,72 @@ struct CommonMultiBodyBase : public CommonExampleInterface
virtual void renderScene()
{
if (m_dynamicsWorld)
{
m_guiHelper->syncPhysicsToGraphics(m_dynamicsWorld);
if (m_dynamicsWorld)
{
m_guiHelper->syncPhysicsToGraphics(m_dynamicsWorld);
m_guiHelper->render(m_dynamicsWorld);
}
m_guiHelper->render(m_dynamicsWorld);
}
}
virtual void physicsDebugDraw(int debugDrawFlags)
{
if (m_dynamicsWorld)
{
virtual void physicsDebugDraw(int debugDrawFlags)
{
if (m_dynamicsWorld)
{
if (m_dynamicsWorld->getDebugDrawer())
{
m_dynamicsWorld->getDebugDrawer()->setDebugMode(debugDrawFlags);
}
m_dynamicsWorld->debugDrawWorld();
}
m_dynamicsWorld->debugDrawWorld();
}
}
}
virtual bool keyboardCallback(int key, int state)
virtual bool keyboardCallback(int key, int state)
{
if ((key==B3G_F3) && state && m_dynamicsWorld)
if ((key == B3G_F3) && state && m_dynamicsWorld)
{
btDefaultSerializer* serializer = new btDefaultSerializer();
btDefaultSerializer* serializer = new btDefaultSerializer();
m_dynamicsWorld->serialize(serializer);
FILE* file = fopen("testFile.bullet","wb");
fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1, file);
FILE* file = fopen("testFile.bullet", "wb");
fwrite(serializer->getBufferPointer(), serializer->getCurrentBufferSize(), 1, file);
fclose(file);
//b3Printf("btDefaultSerializer wrote testFile.bullet");
delete serializer;
return true;
}
return false;//don't handle this key
return false; //don't handle this key
}
btVector3 getRayTo(int x,int y)
btVector3 getRayTo(int x, int y)
{
CommonRenderInterface* renderer = m_guiHelper->getRenderInterface();
if (!renderer)
{
btAssert(0);
return btVector3(0,0,0);
return btVector3(0, 0, 0);
}
float top = 1.f;
float bottom = -1.f;
float nearPlane = 1.f;
float tanFov = (top-bottom)*0.5f / nearPlane;
float tanFov = (top - bottom) * 0.5f / nearPlane;
float fov = btScalar(2.0) * btAtan(tanFov);
btVector3 camPos,camTarget;
btVector3 camPos, camTarget;
renderer->getActiveCamera()->getCameraPosition(camPos);
renderer->getActiveCamera()->getCameraTargetPosition(camTarget);
btVector3 rayFrom = camPos;
btVector3 rayForward = (camTarget-camPos);
btVector3 rayFrom = camPos;
btVector3 rayForward = (camTarget - camPos);
rayForward.normalize();
float farPlane = 10000.f;
rayForward*= farPlane;
rayForward *= farPlane;
btVector3 rightOffset;
btVector3 cameraUp=btVector3(0,0,0);
cameraUp[m_guiHelper->getAppInterface()->getUpAxis()]=1;
btVector3 cameraUp = btVector3(0, 0, 0);
cameraUp[m_guiHelper->getAppInterface()->getUpAxis()] = 1;
btVector3 vertical = cameraUp;
@@ -288,25 +281,22 @@ struct CommonMultiBodyBase : public CommonExampleInterface
vertical = hor.cross(rayForward);
vertical.normalize();
float tanfov = tanf(0.5f*fov);
float tanfov = tanf(0.5f * fov);
hor *= 2.f * farPlane * tanfov;
vertical *= 2.f * farPlane * tanfov;
btScalar aspect;
float width = float(renderer->getScreenWidth());
float height = float (renderer->getScreenHeight());
float height = float(renderer->getScreenHeight());
aspect = width / height;
hor*=aspect;
aspect = width / height;
hor *= aspect;
btVector3 rayToCenter = rayFrom + rayForward;
btVector3 dHor = hor * 1.f/width;
btVector3 dVert = vertical * 1.f/height;
btVector3 dHor = hor * 1.f / width;
btVector3 dVert = vertical * 1.f / height;
btVector3 rayTo = rayToCenter - 0.5f * hor + 0.5f * vertical;
rayTo += btScalar(x) * dHor;
@@ -314,10 +304,10 @@ struct CommonMultiBodyBase : public CommonExampleInterface
return rayTo;
}
virtual bool mouseMoveCallback(float x,float y)
virtual bool mouseMoveCallback(float x, float y)
{
CommonRenderInterface* renderer = m_guiHelper->getRenderInterface();
if (!renderer)
{
btAssert(0);
@@ -327,41 +317,39 @@ struct CommonMultiBodyBase : public CommonExampleInterface
btVector3 rayTo = getRayTo(int(x), int(y));
btVector3 rayFrom;
renderer->getActiveCamera()->getCameraPosition(rayFrom);
movePickedBody(rayFrom,rayTo);
movePickedBody(rayFrom, rayTo);
return false;
}
virtual bool mouseButtonCallback(int button, int state, float x, float y)
virtual bool mouseButtonCallback(int button, int state, float x, float y)
{
CommonRenderInterface* renderer = m_guiHelper->getRenderInterface();
if (!renderer)
{
btAssert(0);
return false;
}
CommonWindowInterface* window = m_guiHelper->getAppInterface()->m_window;
if (state==1)
if (state == 1)
{
if(button==0 && (!window->isModifierKeyPressed(B3G_ALT) && !window->isModifierKeyPressed(B3G_CONTROL) ))
if (button == 0 && (!window->isModifierKeyPressed(B3G_ALT) && !window->isModifierKeyPressed(B3G_CONTROL)))
{
btVector3 camPos;
renderer->getActiveCamera()->getCameraPosition(camPos);
btVector3 rayFrom = camPos;
btVector3 rayTo = getRayTo(int(x),int(y));
btVector3 rayTo = getRayTo(int(x), int(y));
pickBody(rayFrom, rayTo);
}
} else
}
else
{
if (button==0)
if (button == 0)
{
removePickingConstraint();
//remove p2p
@@ -372,10 +360,9 @@ struct CommonMultiBodyBase : public CommonExampleInterface
return false;
}
virtual bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)
{
if (m_dynamicsWorld==0)
if (m_dynamicsWorld == 0)
return false;
btCollisionWorld::ClosestRayResultCallback rayCallback(rayFromWorld, rayToWorld);
@@ -383,7 +370,6 @@ struct CommonMultiBodyBase : public CommonExampleInterface
m_dynamicsWorld->rayTest(rayFromWorld, rayToWorld, rayCallback);
if (rayCallback.hasHit())
{
btVector3 pickPos = rayCallback.m_hitPointWorld;
btRigidBody* body = (btRigidBody*)btRigidBody::upcast(rayCallback.m_collisionObject);
if (body)
@@ -403,33 +389,31 @@ struct CommonMultiBodyBase : public CommonExampleInterface
//very weak constraint for picking
p2p->m_setting.m_tau = 0.001f;
}
} else
}
else
{
btMultiBodyLinkCollider* multiCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(rayCallback.m_collisionObject);
if (multiCol && multiCol->m_multiBody)
{
m_prevCanSleep = multiCol->m_multiBody->getCanSleep();
multiCol->m_multiBody->setCanSleep(false);
btVector3 pivotInA = multiCol->m_multiBody->worldPosToLocal(multiCol->m_link, pickPos);
btMultiBodyPoint2Point* p2p = new btMultiBodyPoint2Point(multiCol->m_multiBody,multiCol->m_link,0,pivotInA,pickPos);
btMultiBodyPoint2Point* p2p = new btMultiBodyPoint2Point(multiCol->m_multiBody, multiCol->m_link, 0, pivotInA, pickPos);
//if you add too much energy to the system, causing high angular velocities, simulation 'explodes'
//see also http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=4&t=949
//so we try to avoid it by clamping the maximum impulse (force) that the mouse pick can apply
//it is not satisfying, hopefully we find a better solution (higher order integrator, using joint friction using a zero-velocity target motor with limited force etc?)
btScalar scaling=1;
p2p->setMaxAppliedImpulse(2*scaling);
btMultiBodyDynamicsWorld* world = (btMultiBodyDynamicsWorld*) m_dynamicsWorld;
btScalar scaling = 1;
p2p->setMaxAppliedImpulse(2 * scaling);
btMultiBodyDynamicsWorld* world = (btMultiBodyDynamicsWorld*)m_dynamicsWorld;
world->addMultiBodyConstraint(p2p);
m_pickingMultiBodyPoint2Point =p2p;
m_pickingMultiBodyPoint2Point = p2p;
}
}
// pickObject(pickPos, rayCallback.m_collisionObject);
m_oldPickingPos = rayToWorld;
m_hitPos = pickPos;
@@ -441,14 +425,14 @@ struct CommonMultiBodyBase : public CommonExampleInterface
}
virtual bool movePickedBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)
{
if (m_pickedBody && m_pickedConstraint)
if (m_pickedBody && m_pickedConstraint)
{
btPoint2PointConstraint* pickCon = static_cast<btPoint2PointConstraint*>(m_pickedConstraint);
if (pickCon)
{
//keep it at the same picking distance
btVector3 dir = rayToWorld-rayFromWorld;
btVector3 dir = rayToWorld - rayFromWorld;
dir.normalize();
dir *= m_oldPickingDist;
@@ -456,21 +440,20 @@ struct CommonMultiBodyBase : public CommonExampleInterface
pickCon->setPivotB(newPivotB);
}
}
if (m_pickingMultiBodyPoint2Point)
{
//keep it at the same picking distance
btVector3 dir = rayToWorld-rayFromWorld;
btVector3 dir = rayToWorld - rayFromWorld;
dir.normalize();
dir *= m_oldPickingDist;
btVector3 newPivotB = rayFromWorld + dir;
m_pickingMultiBodyPoint2Point->setPivotInB(newPivotB);
}
return false;
}
virtual void removePickingConstraint()
@@ -491,22 +474,20 @@ struct CommonMultiBodyBase : public CommonExampleInterface
if (m_pickingMultiBodyPoint2Point)
{
m_pickingMultiBodyPoint2Point->getMultiBodyA()->setCanSleep(m_prevCanSleep);
btMultiBodyDynamicsWorld* world = (btMultiBodyDynamicsWorld*) m_dynamicsWorld;
btMultiBodyDynamicsWorld* world = (btMultiBodyDynamicsWorld*)m_dynamicsWorld;
world->removeMultiBodyConstraint(m_pickingMultiBodyPoint2Point);
delete m_pickingMultiBodyPoint2Point;
m_pickingMultiBodyPoint2Point = 0;
}
}
btBoxShape* createBoxShape(const btVector3& halfExtents)
{
btBoxShape* box = new btBoxShape(halfExtents);
return box;
}
btRigidBody* createRigidBody(float mass, const btTransform& startTransform, btCollisionShape* shape, const btVector4& color = btVector4(1, 0, 0, 1))
btRigidBody* createRigidBody(float mass, const btTransform& startTransform, btCollisionShape* shape, const btVector4& color = btVector4(1, 0, 0, 1))
{
btAssert((!shape || shape->getShapeType() != INVALID_SHAPE_PROXYTYPE));
@@ -517,7 +498,7 @@ struct CommonMultiBodyBase : public CommonExampleInterface
if (isDynamic)
shape->calculateLocalInertia(mass, localInertia);
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
#define USE_MOTIONSTATE 1
#ifdef USE_MOTIONSTATE
@@ -531,7 +512,7 @@ struct CommonMultiBodyBase : public CommonExampleInterface
#else
btRigidBody* body = new btRigidBody(mass, 0, shape, localInertia);
body->setWorldTransform(startTransform);
#endif//
#endif //
body->setUserIndex(-1);
m_dynamicsWorld->addRigidBody(body);
@@ -539,5 +520,4 @@ struct CommonMultiBodyBase : public CommonExampleInterface
}
};
#endif //COMMON_MULTI_BODY_SETUP_H
#endif //COMMON_MULTI_BODY_SETUP_H

View File

@@ -4,7 +4,7 @@
#pragma once
typedef void (*SliderParamChangedCallback) (float newVal, void* userPointer);
typedef void (*SliderParamChangedCallback)(float newVal, void* userPointer);
#include "LinearMath/btScalar.h"
struct SliderParams
@@ -16,43 +16,42 @@ struct SliderParams
btScalar* m_paramValuePointer;
void* m_userPointer;
bool m_clampToNotches;
bool m_clampToIntegers;
bool m_showValues;
bool m_clampToIntegers;
bool m_showValues;
SliderParams(const char* name, btScalar* targetValuePointer)
:m_name(name),
m_minVal(-100),
m_maxVal(100),
m_callback(0),
m_paramValuePointer(targetValuePointer),
m_userPointer(0),
m_clampToNotches(false),
m_clampToIntegers(false),
m_showValues(true)
: m_name(name),
m_minVal(-100),
m_maxVal(100),
m_callback(0),
m_paramValuePointer(targetValuePointer),
m_userPointer(0),
m_clampToNotches(false),
m_clampToIntegers(false),
m_showValues(true)
{
}
};
typedef void (*ButtonParamChangedCallback) (int buttonId, bool buttonState, void* userPointer);
typedef void (*ComboBoxCallback) (int combobox, const char* item, void* userPointer);
typedef void (*ButtonParamChangedCallback)(int buttonId, bool buttonState, void* userPointer);
typedef void (*ComboBoxCallback)(int combobox, const char* item, void* userPointer);
struct ButtonParams
{
const char* m_name;
int m_buttonId;
void* m_userPointer;
bool m_isTrigger;
bool m_initialState;
bool m_isTrigger;
bool m_initialState;
ButtonParamChangedCallback m_callback;
ButtonParams(const char* name, int buttonId, bool isTrigger)
:m_name(name),
m_buttonId(buttonId),
m_userPointer(0),
m_isTrigger(isTrigger),
m_initialState(false),
m_callback(0)
: m_name(name),
m_buttonId(buttonId),
m_userPointer(0),
m_isTrigger(isTrigger),
m_initialState(false),
m_callback(0)
{
}
};
@@ -64,32 +63,29 @@ struct ComboBoxParams
const char** m_items;
int m_startItem;
ComboBoxCallback m_callback;
void* m_userPointer;
void* m_userPointer;
ComboBoxParams()
:m_comboboxId(-1),
m_numItems(0),
m_items(0),
m_startItem(0),
m_callback(0),
m_userPointer(0)
: m_comboboxId(-1),
m_numItems(0),
m_items(0),
m_startItem(0),
m_callback(0),
m_userPointer(0)
{
}
};
struct CommonParameterInterface
{
virtual ~CommonParameterInterface() {}
virtual void registerSliderFloatParameter(SliderParams& params)=0;
virtual void registerButtonParameter(ButtonParams& params)=0;
virtual void registerComboBox(ComboBoxParams& params)=0;
virtual void syncParameters()=0;
virtual void removeAllParameters()=0;
virtual void setSliderValue(int sliderIndex, double sliderValue)=0;
virtual void registerSliderFloatParameter(SliderParams& params) = 0;
virtual void registerButtonParameter(ButtonParams& params) = 0;
virtual void registerComboBox(ComboBoxParams& params) = 0;
virtual void syncParameters() = 0;
virtual void removeAllParameters() = 0;
virtual void setSliderValue(int sliderIndex, double sliderValue) = 0;
};
#endif //PARAM_INTERFACE_H
#endif //PARAM_INTERFACE_H

View File

@@ -9,9 +9,9 @@ enum
B3_GL_POINTS
};
enum
enum
{
B3_DEFAULT_RENDERMODE=1,
B3_DEFAULT_RENDERMODE = 1,
//B3_WIREFRAME_RENDERMODE,
B3_CREATE_SHADOWMAP_RENDERMODE,
B3_USE_SHADOWMAP_RENDERMODE,
@@ -20,120 +20,117 @@ enum
B3_USE_PROJECTIVE_TEXTURE_RENDERMODE,
};
struct GfxVertexFormat0
{
float x,y,z,w;
float unused0,unused1,unused2,unused3;
float u,v;
float x, y, z, w;
float unused0, unused1, unused2, unused3;
float u, v;
};
struct GfxVertexFormat1
{
float x,y,z,w;
float nx,ny,nz;
float u,v;
float x, y, z, w;
float nx, ny, nz;
float u, v;
};
struct CommonRenderInterface
{
virtual ~CommonRenderInterface() {}
virtual void init()=0;
virtual void updateCamera(int upAxis)=0;
virtual void init() = 0;
virtual void updateCamera(int upAxis) = 0;
virtual void removeAllInstances() = 0;
virtual void removeGraphicsInstance(int instanceUid) = 0;
virtual const CommonCameraInterface* getActiveCamera() const =0;
virtual CommonCameraInterface* getActiveCamera()=0;
virtual void setActiveCamera(CommonCameraInterface* cam)=0;
virtual const CommonCameraInterface* getActiveCamera() const = 0;
virtual CommonCameraInterface* getActiveCamera() = 0;
virtual void setActiveCamera(CommonCameraInterface* cam) = 0;
virtual void setLightPosition(const float lightPos[3]) = 0;
virtual void setLightPosition(const double lightPos[3]) = 0;
virtual void setProjectiveTextureMatrices(const float viewMatrix[16], const float projectionMatrix[16]){};
virtual void setProjectiveTexture(bool useProjectiveTexture){};
virtual void renderScene()=0;
virtual void renderSceneInternal(int renderMode=B3_DEFAULT_RENDERMODE){};
virtual void renderScene() = 0;
virtual void renderSceneInternal(int renderMode = B3_DEFAULT_RENDERMODE){};
virtual int getScreenWidth() = 0;
virtual int getScreenHeight() = 0;
virtual void resize(int width, int height) = 0;
virtual void resize(int width, int height) = 0;
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling)=0;
virtual int registerGraphicsInstance(int shapeIndex, const double* position, const double* quaternion, const double* color, const double* scaling)=0;
virtual void drawLines(const float* positions, const float color[4], int numPoints, int pointStrideInBytes, const unsigned int* indices, int numIndices, float pointDrawSize)=0;
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) = 0;
virtual int registerGraphicsInstance(int shapeIndex, const double* position, const double* quaternion, const double* color, const double* scaling) = 0;
virtual void drawLines(const float* positions, const float color[4], int numPoints, int pointStrideInBytes, const unsigned int* indices, int numIndices, float pointDrawSize) = 0;
virtual void drawLine(const float from[4], const float to[4], const float color[4], float lineWidth) = 0;
virtual void drawLine(const double from[4], const double to[4], const double color[4], double lineWidth) = 0;
virtual void drawPoint(const float* position, const float color[4], float pointDrawSize)=0;
virtual void drawPoint(const double* position, const double color[4], double pointDrawSize)=0;
virtual void drawTexturedTriangleMesh(float worldPosition[3], float worldOrientation[4], const float* vertices, int numvertices, const unsigned int* indices, int numIndices, float color[4], int textureIndex=-1, int vertexLayout=0)=0;
virtual void drawPoint(const float* position, const float color[4], float pointDrawSize) = 0;
virtual void drawPoint(const double* position, const double color[4], double pointDrawSize) = 0;
virtual void drawTexturedTriangleMesh(float worldPosition[3], float worldOrientation[4], const float* vertices, int numvertices, const unsigned int* indices, int numIndices, float color[4], int textureIndex = -1, int vertexLayout = 0) = 0;
virtual int registerShape(const float* vertices, int numvertices, const int* indices, int numIndices,int primitiveType=B3_GL_TRIANGLES, int textureIndex=-1)=0;
virtual void updateShape(int shapeIndex, const float* vertices)=0;
virtual int registerTexture(const unsigned char* texels, int width, int height, bool flipPixelsY=true)=0;
virtual void updateTexture(int textureIndex, const unsigned char* texels, bool flipPixelsY=true)=0;
virtual void activateTexture(int textureIndex)=0;
virtual int registerShape(const float* vertices, int numvertices, const int* indices, int numIndices, int primitiveType = B3_GL_TRIANGLES, int textureIndex = -1) = 0;
virtual void updateShape(int shapeIndex, const float* vertices) = 0;
virtual int registerTexture(const unsigned char* texels, int width, int height, bool flipPixelsY = true) = 0;
virtual void updateTexture(int textureIndex, const unsigned char* texels, bool flipPixelsY = true) = 0;
virtual void activateTexture(int textureIndex) = 0;
virtual void replaceTexture(int shapeIndex, int textureIndex){};
virtual void removeTexture(int textureIndex) = 0;
virtual void setPlaneReflectionShapeIndex(int index) {}
virtual int getShapeIndexFromInstance(int srcIndex) {return -1;}
virtual int getShapeIndexFromInstance(int srcIndex) { return -1; }
virtual bool readSingleInstanceTransformToCPU(float* position, float* orientation, int srcIndex)=0;
virtual bool readSingleInstanceTransformToCPU(float* position, float* orientation, int srcIndex) = 0;
virtual void writeSingleInstanceTransformToCPU(const float* position, const float* orientation, int srcIndex)=0;
virtual void writeSingleInstanceTransformToCPU(const double* position, const double* orientation, int srcIndex)=0;
virtual void writeSingleInstanceColorToCPU(const float* color, int srcIndex)=0;
virtual void writeSingleInstanceColorToCPU(const double* color, int srcIndex)=0;
virtual void writeSingleInstanceScaleToCPU(const float* scale, int srcIndex)=0;
virtual void writeSingleInstanceScaleToCPU(const double* scale, int srcIndex)=0;
virtual void writeSingleInstanceSpecularColorToCPU(const double* specular, int srcIndex)=0;
virtual void writeSingleInstanceSpecularColorToCPU(const float* specular, int srcIndex)=0;
virtual int getTotalNumInstances() const = 0;
virtual void writeTransforms()=0;
virtual void clearZBuffer()=0;
virtual void writeSingleInstanceTransformToCPU(const float* position, const float* orientation, int srcIndex) = 0;
virtual void writeSingleInstanceTransformToCPU(const double* position, const double* orientation, int srcIndex) = 0;
virtual void writeSingleInstanceColorToCPU(const float* color, int srcIndex) = 0;
virtual void writeSingleInstanceColorToCPU(const double* color, int srcIndex) = 0;
virtual void writeSingleInstanceScaleToCPU(const float* scale, int srcIndex) = 0;
virtual void writeSingleInstanceScaleToCPU(const double* scale, int srcIndex) = 0;
virtual void writeSingleInstanceSpecularColorToCPU(const double* specular, int srcIndex) = 0;
virtual void writeSingleInstanceSpecularColorToCPU(const float* specular, int srcIndex) = 0;
virtual int getTotalNumInstances() const = 0;
virtual void writeTransforms() = 0;
virtual void clearZBuffer() = 0;
//This is internal access to OpenGL3+ features, mainly used for OpenCL-OpenGL interop
//Only the GLInstancingRenderer supports it, just return 0 otherwise.
virtual struct GLInstanceRendererInternalData* getInternalData()=0;
virtual struct GLInstanceRendererInternalData* getInternalData() = 0;
};
template <typename T>
inline int projectWorldCoordToScreen(T objx, T objy, T objz,
const T modelMatrix[16],
const T projMatrix[16],
const int viewport[4],
T *winx, T *winy, T *winz)
const T modelMatrix[16],
const T projMatrix[16],
const int viewport[4],
T* winx, T* winy, T* winz)
{
int i;
T in2[4];
T tmp[4];
in2[0]=objx;
in2[1]=objy;
in2[2]=objz;
in2[3]=T(1.0);
in2[0] = objx;
in2[1] = objy;
in2[2] = objz;
in2[3] = T(1.0);
for (i=0; i<4; i++)
for (i = 0; i < 4; i++)
{
tmp[i] = in2[0] * modelMatrix[0*4+i] + in2[1] * modelMatrix[1*4+i] +
in2[2] * modelMatrix[2*4+i] + in2[3] * modelMatrix[3*4+i];
tmp[i] = in2[0] * modelMatrix[0 * 4 + i] + in2[1] * modelMatrix[1 * 4 + i] +
in2[2] * modelMatrix[2 * 4 + i] + in2[3] * modelMatrix[3 * 4 + i];
}
T out[4];
for (i=0; i<4; i++)
for (i = 0; i < 4; i++)
{
out[i] = tmp[0] * projMatrix[0*4+i] + tmp[1] * projMatrix[1*4+i] + tmp[2] * projMatrix[2*4+i] + tmp[3] * projMatrix[3*4+i];
out[i] = tmp[0] * projMatrix[0 * 4 + i] + tmp[1] * projMatrix[1 * 4 + i] + tmp[2] * projMatrix[2 * 4 + i] + tmp[3] * projMatrix[3 * 4 + i];
}
if (out[3] == T(0.0))
if (out[3] == T(0.0))
return 0;
out[0] /= out[3];
out[1] /= out[3];
@@ -147,11 +144,10 @@ inline int projectWorldCoordToScreen(T objx, T objy, T objz,
out[0] = out[0] * viewport[2] + viewport[0];
out[1] = out[1] * viewport[3] + viewport[1];
*winx=out[0];
*winy=out[1];
*winz=out[2];
*winx = out[0];
*winy = out[1];
*winz = out[2];
return 1;
}
#endif//COMMON_RENDER_INTERFACE_H
#endif //COMMON_RENDER_INTERFACE_H

View File

@@ -2,7 +2,6 @@
#ifndef COMMON_RIGID_BODY_BASE_H
#define COMMON_RIGID_BODY_BASE_H
#include "btBulletDynamicsCommon.h"
#include "CommonExampleInterface.h"
#include "CommonGUIHelperInterface.h"
@@ -14,40 +13,39 @@
struct CommonRigidBodyBase : public CommonExampleInterface
{
//keep the collision shapes, for deletion/cleanup
btAlignedObjectArray<btCollisionShape*> m_collisionShapes;
btBroadphaseInterface* m_broadphase;
btCollisionDispatcher* m_dispatcher;
btConstraintSolver* m_solver;
//keep the collision shapes, for deletion/cleanup
btAlignedObjectArray<btCollisionShape*> m_collisionShapes;
btBroadphaseInterface* m_broadphase;
btCollisionDispatcher* m_dispatcher;
btConstraintSolver* m_solver;
btDefaultCollisionConfiguration* m_collisionConfiguration;
btDiscreteDynamicsWorld* m_dynamicsWorld;
//data for picking objects
class btRigidBody* m_pickedBody;
class btRigidBody* m_pickedBody;
class btTypedConstraint* m_pickedConstraint;
int m_savedState;
int m_savedState;
btVector3 m_oldPickingPos;
btVector3 m_hitPos;
btScalar m_oldPickingDist;
struct GUIHelperInterface* m_guiHelper;
CommonRigidBodyBase(struct GUIHelperInterface* helper)
:m_broadphase(0),
m_dispatcher(0),
m_solver(0),
m_collisionConfiguration(0),
m_dynamicsWorld(0),
m_pickedBody(0),
m_pickedConstraint(0),
m_guiHelper(helper)
: m_broadphase(0),
m_dispatcher(0),
m_solver(0),
m_collisionConfiguration(0),
m_dynamicsWorld(0),
m_pickedBody(0),
m_pickedConstraint(0),
m_guiHelper(helper)
{
}
virtual ~CommonRigidBodyBase()
{
}
btDiscreteDynamicsWorld* getDynamicsWorld()
btDiscreteDynamicsWorld* getDynamicsWorld()
{
return m_dynamicsWorld;
}
@@ -59,7 +57,7 @@ struct CommonRigidBodyBase : public CommonExampleInterface
//m_collisionConfiguration->setConvexConvexMultipointIterations();
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase();
@@ -72,7 +70,6 @@ struct CommonRigidBodyBase : public CommonExampleInterface
m_dynamicsWorld->setGravity(btVector3(0, -10, 0));
}
virtual void stepSimulation(float deltaTime)
{
if (m_dynamicsWorld)
@@ -96,15 +93,14 @@ struct CommonRigidBodyBase : public CommonExampleInterface
//cleanup in the reverse order of creation/initialization
//remove the rigidbodies from the dynamics world and delete them
if (m_dynamicsWorld)
{
int i;
for (i = m_dynamicsWorld->getNumConstraints() - 1; i >= 0; i--)
{
m_dynamicsWorld->removeConstraint(m_dynamicsWorld->getConstraint(i));
}
int i;
for (i = m_dynamicsWorld->getNumConstraints() - 1; i >= 0; i--)
{
m_dynamicsWorld->removeConstraint(m_dynamicsWorld->getConstraint(i));
}
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
{
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
@@ -118,7 +114,7 @@ struct CommonRigidBodyBase : public CommonExampleInterface
}
}
//delete collision shapes
for (int j = 0; j<m_collisionShapes.size(); j++)
for (int j = 0; j < m_collisionShapes.size(); j++)
{
btCollisionShape* shape = m_collisionShapes[j];
delete shape;
@@ -126,84 +122,80 @@ struct CommonRigidBodyBase : public CommonExampleInterface
m_collisionShapes.clear();
delete m_dynamicsWorld;
m_dynamicsWorld=0;
m_dynamicsWorld = 0;
delete m_solver;
m_solver=0;
m_solver = 0;
delete m_broadphase;
m_broadphase=0;
m_broadphase = 0;
delete m_dispatcher;
m_dispatcher=0;
m_dispatcher = 0;
delete m_collisionConfiguration;
m_collisionConfiguration=0;
m_collisionConfiguration = 0;
}
virtual void debugDraw(int debugDrawFlags)
{
if (m_dynamicsWorld)
{
virtual void debugDraw(int debugDrawFlags)
{
if (m_dynamicsWorld)
{
if (m_dynamicsWorld->getDebugDrawer())
{
m_dynamicsWorld->getDebugDrawer()->setDebugMode(debugDrawFlags);
}
m_dynamicsWorld->debugDrawWorld();
}
m_dynamicsWorld->debugDrawWorld();
}
}
}
virtual bool keyboardCallback(int key, int state)
virtual bool keyboardCallback(int key, int state)
{
if ((key==B3G_F3) && state && m_dynamicsWorld)
if ((key == B3G_F3) && state && m_dynamicsWorld)
{
btDefaultSerializer* serializer = new btDefaultSerializer();
btDefaultSerializer* serializer = new btDefaultSerializer();
m_dynamicsWorld->serialize(serializer);
FILE* file = fopen("testFile.bullet","wb");
fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1, file);
FILE* file = fopen("testFile.bullet", "wb");
fwrite(serializer->getBufferPointer(), serializer->getCurrentBufferSize(), 1, file);
fclose(file);
//b3Printf("btDefaultSerializer wrote testFile.bullet");
delete serializer;
return true;
}
return false;//don't handle this key
return false; //don't handle this key
}
btVector3 getRayTo(int x,int y)
btVector3 getRayTo(int x, int y)
{
CommonRenderInterface* renderer = m_guiHelper->getRenderInterface();
if (!renderer)
{
btAssert(0);
return btVector3(0,0,0);
return btVector3(0, 0, 0);
}
float top = 1.f;
float bottom = -1.f;
float nearPlane = 1.f;
float tanFov = (top-bottom)*0.5f / nearPlane;
float tanFov = (top - bottom) * 0.5f / nearPlane;
float fov = btScalar(2.0) * btAtan(tanFov);
btVector3 camPos,camTarget;
btVector3 camPos, camTarget;
renderer->getActiveCamera()->getCameraPosition(camPos);
renderer->getActiveCamera()->getCameraTargetPosition(camTarget);
btVector3 rayFrom = camPos;
btVector3 rayForward = (camTarget-camPos);
btVector3 rayFrom = camPos;
btVector3 rayForward = (camTarget - camPos);
rayForward.normalize();
float farPlane = 10000.f;
rayForward*= farPlane;
rayForward *= farPlane;
btVector3 rightOffset;
btVector3 cameraUp=btVector3(0,0,0);
cameraUp[m_guiHelper->getAppInterface()->getUpAxis()]=1;
btVector3 cameraUp = btVector3(0, 0, 0);
cameraUp[m_guiHelper->getAppInterface()->getUpAxis()] = 1;
btVector3 vertical = cameraUp;
@@ -213,25 +205,22 @@ struct CommonRigidBodyBase : public CommonExampleInterface
vertical = hor.cross(rayForward);
vertical.safeNormalize();
float tanfov = tanf(0.5f*fov);
float tanfov = tanf(0.5f * fov);
hor *= 2.f * farPlane * tanfov;
vertical *= 2.f * farPlane * tanfov;
btScalar aspect;
float width = float(renderer->getScreenWidth());
float height = float (renderer->getScreenHeight());
float height = float(renderer->getScreenHeight());
aspect = width / height;
hor*=aspect;
aspect = width / height;
hor *= aspect;
btVector3 rayToCenter = rayFrom + rayForward;
btVector3 dHor = hor * 1.f/width;
btVector3 dVert = vertical * 1.f/height;
btVector3 dHor = hor * 1.f / width;
btVector3 dVert = vertical * 1.f / height;
btVector3 rayTo = rayToCenter - 0.5f * hor + 0.5f * vertical;
rayTo += btScalar(x) * dHor;
@@ -239,10 +228,10 @@ struct CommonRigidBodyBase : public CommonExampleInterface
return rayTo;
}
virtual bool mouseMoveCallback(float x,float y)
virtual bool mouseMoveCallback(float x, float y)
{
CommonRenderInterface* renderer = m_guiHelper->getRenderInterface();
if (!renderer)
{
btAssert(0);
@@ -252,21 +241,21 @@ struct CommonRigidBodyBase : public CommonExampleInterface
btVector3 rayTo = getRayTo(int(x), int(y));
btVector3 rayFrom;
renderer->getActiveCamera()->getCameraPosition(rayFrom);
movePickedBody(rayFrom,rayTo);
movePickedBody(rayFrom, rayTo);
return false;
}
virtual bool mouseButtonCallback(int button, int state, float x, float y)
virtual bool mouseButtonCallback(int button, int state, float x, float y)
{
CommonRenderInterface* renderer = m_guiHelper->getRenderInterface();
if (!renderer)
{
btAssert(0);
return false;
}
CommonWindowInterface* window = m_guiHelper->getAppInterface()->m_window;
#if 0
@@ -294,25 +283,23 @@ struct CommonRigidBodyBase : public CommonExampleInterface
printf("NO CONTROL pressed\n");
}
#endif
if (state==1)
if (state == 1)
{
if(button==0 && (!window->isModifierKeyPressed(B3G_ALT) && !window->isModifierKeyPressed(B3G_CONTROL) ))
if (button == 0 && (!window->isModifierKeyPressed(B3G_ALT) && !window->isModifierKeyPressed(B3G_CONTROL)))
{
btVector3 camPos;
renderer->getActiveCamera()->getCameraPosition(camPos);
btVector3 rayFrom = camPos;
btVector3 rayTo = getRayTo(int(x),int(y));
btVector3 rayTo = getRayTo(int(x), int(y));
pickBody(rayFrom, rayTo);
}
} else
}
else
{
if (button==0)
if (button == 0)
{
removePickingConstraint();
//remove p2p
@@ -323,10 +310,9 @@ struct CommonRigidBodyBase : public CommonExampleInterface
return false;
}
virtual bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)
{
if (m_dynamicsWorld==0)
if (m_dynamicsWorld == 0)
return false;
btCollisionWorld::ClosestRayResultCallback rayCallback(rayFromWorld, rayToWorld);
@@ -334,7 +320,6 @@ struct CommonRigidBodyBase : public CommonExampleInterface
m_dynamicsWorld->rayTest(rayFromWorld, rayToWorld, rayCallback);
if (rayCallback.hasHit())
{
btVector3 pickPos = rayCallback.m_hitPointWorld;
btRigidBody* body = (btRigidBody*)btRigidBody::upcast(rayCallback.m_collisionObject);
if (body)
@@ -357,7 +342,6 @@ struct CommonRigidBodyBase : public CommonExampleInterface
}
}
// pickObject(pickPos, rayCallback.m_collisionObject);
m_oldPickingPos = rayToWorld;
m_hitPos = pickPos;
@@ -369,7 +353,7 @@ struct CommonRigidBodyBase : public CommonExampleInterface
}
virtual bool movePickedBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)
{
if (m_pickedBody && m_pickedConstraint)
if (m_pickedBody && m_pickedConstraint)
{
btPoint2PointConstraint* pickCon = static_cast<btPoint2PointConstraint*>(m_pickedConstraint);
if (pickCon)
@@ -402,8 +386,6 @@ struct CommonRigidBodyBase : public CommonExampleInterface
}
}
btBoxShape* createBoxShape(const btVector3& halfExtents)
{
btBoxShape* box = new btBoxShape(halfExtents);
@@ -419,10 +401,9 @@ struct CommonRigidBodyBase : public CommonExampleInterface
btMotionState* ms = body->getMotionState();
delete body;
delete ms;
}
btRigidBody* createRigidBody(float mass, const btTransform& startTransform, btCollisionShape* shape, const btVector4& color = btVector4(1, 0, 0, 1))
btRigidBody* createRigidBody(float mass, const btTransform& startTransform, btCollisionShape* shape, const btVector4& color = btVector4(1, 0, 0, 1))
{
btAssert((!shape || shape->getShapeType() != INVALID_SHAPE_PROXYTYPE));
@@ -433,7 +414,7 @@ struct CommonRigidBodyBase : public CommonExampleInterface
if (isDynamic)
shape->calculateLocalInertia(mass, localInertia);
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
#define USE_MOTIONSTATE 1
#ifdef USE_MOTIONSTATE
@@ -447,28 +428,23 @@ struct CommonRigidBodyBase : public CommonExampleInterface
#else
btRigidBody* body = new btRigidBody(mass, 0, shape, localInertia);
body->setWorldTransform(startTransform);
#endif//
#endif //
body->setUserIndex(-1);
m_dynamicsWorld->addRigidBody(body);
return body;
}
virtual void renderScene()
{
{
m_guiHelper->syncPhysicsToGraphics(m_dynamicsWorld);
}
{
m_guiHelper->render(m_dynamicsWorld);
}
}
};
#endif //COMMON_RIGID_BODY_SETUP_H
#endif //COMMON_RIGID_BODY_SETUP_H

View File

@@ -3,91 +3,86 @@
#include "CommonCallbacks.h"
struct b3gWindowConstructionInfo
{
int m_width;
int m_height;
bool m_fullscreen;
int m_colorBitsPerPixel;
void* m_windowHandle;
const char* m_title;
int m_openglVersion;
int m_renderDevice;
int m_width;
int m_height;
bool m_fullscreen;
int m_colorBitsPerPixel;
void* m_windowHandle;
const char* m_title;
int m_openglVersion;
int m_renderDevice;
b3gWindowConstructionInfo(int width=1024, int height=768)
:m_width(width),
m_height(height),
m_fullscreen(false),
m_colorBitsPerPixel(32),
m_windowHandle(0),
m_title("title"),
m_openglVersion(3),
m_renderDevice(-1)
{
}
b3gWindowConstructionInfo(int width = 1024, int height = 768)
: m_width(width),
m_height(height),
m_fullscreen(false),
m_colorBitsPerPixel(32),
m_windowHandle(0),
m_title("title"),
m_openglVersion(3),
m_renderDevice(-1)
{
}
};
class CommonWindowInterface
{
public:
virtual ~CommonWindowInterface()
{
}
public:
virtual ~CommonWindowInterface()
{
}
virtual void createDefaultWindow(int width, int height, const char* title)
{
b3gWindowConstructionInfo ci(width,height);
ci.m_title = title;
createWindow(ci);
}
virtual void createDefaultWindow(int width, int height, const char* title)
{
b3gWindowConstructionInfo ci(width, height);
ci.m_title = title;
createWindow(ci);
}
virtual void createWindow(const b3gWindowConstructionInfo& ci)=0;
virtual void closeWindow()=0;
virtual void createWindow(const b3gWindowConstructionInfo& ci) = 0;
virtual void runMainLoop()=0;
virtual float getTimeInSeconds()=0;
virtual void closeWindow() = 0;
virtual bool requestedExit() const = 0;
virtual void setRequestExit() = 0;
virtual void runMainLoop() = 0;
virtual float getTimeInSeconds() = 0;
virtual void startRendering()=0;
virtual bool requestedExit() const = 0;
virtual void setRequestExit() = 0;
virtual void endRendering()=0;
virtual void startRendering() = 0;
virtual bool isModifierKeyPressed(int key) = 0;
virtual void setMouseMoveCallback(b3MouseMoveCallback mouseCallback)=0;
virtual b3MouseMoveCallback getMouseMoveCallback()=0;
virtual void setMouseButtonCallback(b3MouseButtonCallback mouseCallback)=0;
virtual b3MouseButtonCallback getMouseButtonCallback()=0;
virtual void endRendering() = 0;
virtual void setResizeCallback(b3ResizeCallback resizeCallback)=0;
virtual b3ResizeCallback getResizeCallback()=0;
virtual void setWheelCallback(b3WheelCallback wheelCallback)=0;
virtual b3WheelCallback getWheelCallback()=0;
virtual void setKeyboardCallback( b3KeyboardCallback keyboardCallback)=0;
virtual b3KeyboardCallback getKeyboardCallback()=0;
virtual bool isModifierKeyPressed(int key) = 0;
virtual void setRenderCallback( b3RenderCallback renderCallback) = 0;
virtual void setWindowTitle(const char* title)=0;
virtual void setMouseMoveCallback(b3MouseMoveCallback mouseCallback) = 0;
virtual b3MouseMoveCallback getMouseMoveCallback() = 0;
virtual float getRetinaScale() const =0;
virtual void setAllowRetina(bool allow) =0;
virtual void setMouseButtonCallback(b3MouseButtonCallback mouseCallback) = 0;
virtual b3MouseButtonCallback getMouseButtonCallback() = 0;
virtual int getWidth() const = 0;
virtual int getHeight() const = 0;
virtual void setResizeCallback(b3ResizeCallback resizeCallback) = 0;
virtual b3ResizeCallback getResizeCallback() = 0;
virtual int fileOpenDialog(char* fileName, int maxFileNameLength) = 0;
virtual void setWheelCallback(b3WheelCallback wheelCallback) = 0;
virtual b3WheelCallback getWheelCallback() = 0;
virtual void setKeyboardCallback(b3KeyboardCallback keyboardCallback) = 0;
virtual b3KeyboardCallback getKeyboardCallback() = 0;
virtual void setRenderCallback(b3RenderCallback renderCallback) = 0;
virtual void setWindowTitle(const char* title) = 0;
virtual float getRetinaScale() const = 0;
virtual void setAllowRetina(bool allow) = 0;
virtual int getWidth() const = 0;
virtual int getHeight() const = 0;
virtual int fileOpenDialog(char* fileName, int maxFileNameLength) = 0;
};
#endif //B3G_WINDOW_INTERFACE_H
#endif //B3G_WINDOW_INTERFACE_H

View File

@@ -13,60 +13,47 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#include "ConstraintDemo.h"
#include "btBulletDynamicsCommon.h"
#include "LinearMath/btIDebugDraw.h"
#include <stdio.h> //printf debugging
#include <stdio.h> //printf debugging
#include "../CommonInterfaces/CommonRigidBodyBase.h"
///AllConstraintDemo shows how to create a constraint, like Hinge or btGenericD6constraint
class AllConstraintDemo : public CommonRigidBodyBase
class AllConstraintDemo : public CommonRigidBodyBase
{
//keep track of variables to delete memory at the end
void setupEmptyDynamicsWorld();
public:
void setupEmptyDynamicsWorld();
public:
AllConstraintDemo(struct GUIHelperInterface* helper);
virtual ~AllConstraintDemo();
virtual void initPhysics();
virtual void initPhysics();
virtual void exitPhysics();
virtual void exitPhysics();
virtual void resetCamera()
{
float dist = 27;
float pitch = -30;
float yaw = 720;
float targetPos[3]={2,0,-10};
m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]);
float targetPos[3] = {2, 0, -10};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
virtual bool keyboardCallback(int key, int state);
virtual bool keyboardCallback(int key, int state);
// for cone-twist motor driving
float m_Time;
class btConeTwistConstraint* m_ctc;
};
#define ENABLE_ALL_DEMOS 1
#define CUBE_HALF_EXTENTS 1.f
@@ -74,14 +61,11 @@ class AllConstraintDemo : public CommonRigidBodyBase
#define SIMD_PI_2 ((SIMD_PI)*0.5f)
#define SIMD_PI_4 ((SIMD_PI)*0.25f)
btTransform sliderTransform;
btVector3 lowerSliderLimit = btVector3(-10,0,0);
btVector3 hiSliderLimit = btVector3(10,0,0);
btVector3 lowerSliderLimit = btVector3(-10, 0, 0);
btVector3 hiSliderLimit = btVector3(10, 0, 0);
btRigidBody* d6body0 =0;
btRigidBody* d6body0 = 0;
btHingeConstraint* spDoorHinge = NULL;
btHingeConstraint* spHingeDynAB = NULL;
@@ -89,22 +73,16 @@ btGeneric6DofConstraint* spSlider6Dof = NULL;
static bool s_bTestConeTwistMotor = false;
void AllConstraintDemo::setupEmptyDynamicsWorld()
void AllConstraintDemo::setupEmptyDynamicsWorld()
{
m_collisionConfiguration = new btDefaultCollisionConfiguration();
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase();
m_solver = new btSequentialImpulseConstraintSolver();
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration);
}
void AllConstraintDemo::initPhysics()
void AllConstraintDemo::initPhysics()
{
m_guiHelper->setUpAxis(1);
@@ -115,223 +93,210 @@ void AllConstraintDemo::initPhysics()
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
//btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(40.),btScalar(50.)));
btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),40);
btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0, 1, 0), 40);
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0,-56,0));
groundTransform.setOrigin(btVector3(0, -56, 0));
btRigidBody* groundBody;
groundBody= createRigidBody(0, groundTransform, groundShape);
groundBody = createRigidBody(0, groundTransform, groundShape);
btCollisionShape* shape = new btBoxShape(btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS));
btCollisionShape* shape = new btBoxShape(btVector3(CUBE_HALF_EXTENTS, CUBE_HALF_EXTENTS, CUBE_HALF_EXTENTS));
m_collisionShapes.push_back(shape);
btTransform trans;
trans.setIdentity();
trans.setOrigin(btVector3(0,20,0));
trans.setOrigin(btVector3(0, 20, 0));
float mass = 1.f;
#if ENABLE_ALL_DEMOS
///gear constraint demo
///gear constraint demo
#define THETA SIMD_PI/4.f
#define THETA SIMD_PI / 4.f
#define L_1 (2 - tan(THETA))
#define L_2 (1 / cos(THETA))
#define RATIO L_2 / L_1
btRigidBody* bodyA=0;
btRigidBody* bodyB=0;
btRigidBody* bodyA = 0;
btRigidBody* bodyB = 0;
{
btCollisionShape* cylA = new btCylinderShape(btVector3(0.2,0.25,0.2));
btCollisionShape* cylB = new btCylinderShape(btVector3(L_1,0.025,L_1));
btCollisionShape* cylA = new btCylinderShape(btVector3(0.2, 0.25, 0.2));
btCollisionShape* cylB = new btCylinderShape(btVector3(L_1, 0.025, L_1));
btCompoundShape* cyl0 = new btCompoundShape();
cyl0->addChildShape(btTransform::getIdentity(),cylA);
cyl0->addChildShape(btTransform::getIdentity(),cylB);
cyl0->addChildShape(btTransform::getIdentity(), cylA);
cyl0->addChildShape(btTransform::getIdentity(), cylB);
btScalar mass = 6.28;
btVector3 localInertia;
cyl0->calculateLocalInertia(mass,localInertia);
btRigidBody::btRigidBodyConstructionInfo ci(mass,0,cyl0,localInertia);
ci.m_startWorldTransform.setOrigin(btVector3(-8,1,-8));
cyl0->calculateLocalInertia(mass, localInertia);
btRigidBody::btRigidBodyConstructionInfo ci(mass, 0, cyl0, localInertia);
ci.m_startWorldTransform.setOrigin(btVector3(-8, 1, -8));
btRigidBody* body = new btRigidBody(ci);//1,0,cyl0,localInertia);
btRigidBody* body = new btRigidBody(ci); //1,0,cyl0,localInertia);
m_dynamicsWorld->addRigidBody(body);
body->setLinearFactor(btVector3(0,0,0));
body->setAngularFactor(btVector3(0,1,0));
body->setLinearFactor(btVector3(0, 0, 0));
body->setAngularFactor(btVector3(0, 1, 0));
bodyA = body;
}
{
btCollisionShape* cylA = new btCylinderShape(btVector3(0.2,0.26,0.2));
btCollisionShape* cylB = new btCylinderShape(btVector3(L_2,0.025,L_2));
btCollisionShape* cylA = new btCylinderShape(btVector3(0.2, 0.26, 0.2));
btCollisionShape* cylB = new btCylinderShape(btVector3(L_2, 0.025, L_2));
btCompoundShape* cyl0 = new btCompoundShape();
cyl0->addChildShape(btTransform::getIdentity(),cylA);
cyl0->addChildShape(btTransform::getIdentity(),cylB);
cyl0->addChildShape(btTransform::getIdentity(), cylA);
cyl0->addChildShape(btTransform::getIdentity(), cylB);
btScalar mass = 6.28;
btVector3 localInertia;
cyl0->calculateLocalInertia(mass,localInertia);
btRigidBody::btRigidBodyConstructionInfo ci(mass,0,cyl0,localInertia);
ci.m_startWorldTransform.setOrigin(btVector3(-10,2,-8));
cyl0->calculateLocalInertia(mass, localInertia);
btRigidBody::btRigidBodyConstructionInfo ci(mass, 0, cyl0, localInertia);
ci.m_startWorldTransform.setOrigin(btVector3(-10, 2, -8));
btQuaternion orn(btVector3(0,0,1),-THETA);
btQuaternion orn(btVector3(0, 0, 1), -THETA);
ci.m_startWorldTransform.setRotation(orn);
btRigidBody* body = new btRigidBody(ci);//1,0,cyl0,localInertia);
body->setLinearFactor(btVector3(0,0,0));
btHingeConstraint* hinge = new btHingeConstraint(*body,btVector3(0,0,0),btVector3(0,1,0),true);
btRigidBody* body = new btRigidBody(ci); //1,0,cyl0,localInertia);
body->setLinearFactor(btVector3(0, 0, 0));
btHingeConstraint* hinge = new btHingeConstraint(*body, btVector3(0, 0, 0), btVector3(0, 1, 0), true);
m_dynamicsWorld->addConstraint(hinge);
bodyB= body;
body->setAngularVelocity(btVector3(0,3,0));
bodyB = body;
body->setAngularVelocity(btVector3(0, 3, 0));
m_dynamicsWorld->addRigidBody(body);
}
btVector3 axisA(0,1,0);
btVector3 axisB(0,1,0);
btQuaternion orn(btVector3(0,0,1),-THETA);
btVector3 axisA(0, 1, 0);
btVector3 axisB(0, 1, 0);
btQuaternion orn(btVector3(0, 0, 1), -THETA);
btMatrix3x3 mat(orn);
axisB = mat.getRow(1);
btGearConstraint* gear = new btGearConstraint(*bodyA,*bodyB, axisA,axisB,RATIO);
m_dynamicsWorld->addConstraint(gear,true);
btGearConstraint* gear = new btGearConstraint(*bodyA, *bodyB, axisA, axisB, RATIO);
m_dynamicsWorld->addConstraint(gear, true);
#endif
#if ENABLE_ALL_DEMOS
//point to point constraint with a breaking threshold
{
trans.setIdentity();
trans.setOrigin(btVector3(1,30,-5));
createRigidBody( mass,trans,shape);
trans.setOrigin(btVector3(0,0,-5));
trans.setOrigin(btVector3(1, 30, -5));
createRigidBody(mass, trans, shape);
trans.setOrigin(btVector3(0, 0, -5));
btRigidBody* body0 = createRigidBody( mass,trans,shape);
trans.setOrigin(btVector3(2*CUBE_HALF_EXTENTS,20,0));
btRigidBody* body0 = createRigidBody(mass, trans, shape);
trans.setOrigin(btVector3(2 * CUBE_HALF_EXTENTS, 20, 0));
mass = 1.f;
// btRigidBody* body1 = 0;//createRigidBody( mass,trans,shape);
btVector3 pivotInA(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,0);
btTypedConstraint* p2p = new btPoint2PointConstraint(*body0,pivotInA);
// btRigidBody* body1 = 0;//createRigidBody( mass,trans,shape);
btVector3 pivotInA(CUBE_HALF_EXTENTS, CUBE_HALF_EXTENTS, 0);
btTypedConstraint* p2p = new btPoint2PointConstraint(*body0, pivotInA);
m_dynamicsWorld->addConstraint(p2p);
p2p ->setBreakingImpulseThreshold(10.2);
p2p->setBreakingImpulseThreshold(10.2);
p2p->setDbgDrawSize(btScalar(5.f));
}
#endif
#if ENABLE_ALL_DEMOS
//point to point constraint (ball socket)
{
btRigidBody* body0 = createRigidBody( mass,trans,shape);
trans.setOrigin(btVector3(2*CUBE_HALF_EXTENTS,20,0));
btRigidBody* body0 = createRigidBody(mass, trans, shape);
trans.setOrigin(btVector3(2 * CUBE_HALF_EXTENTS, 20, 0));
mass = 1.f;
// btRigidBody* body1 = 0;//createRigidBody( mass,trans,shape);
// btRigidBody* body1 = createRigidBody( 0.0,trans,0);
// btRigidBody* body1 = 0;//createRigidBody( mass,trans,shape);
// btRigidBody* body1 = createRigidBody( 0.0,trans,0);
//body1->setActivationState(DISABLE_DEACTIVATION);
//body1->setDamping(0.3,0.3);
btVector3 pivotInA(CUBE_HALF_EXTENTS,-CUBE_HALF_EXTENTS,-CUBE_HALF_EXTENTS);
btVector3 axisInA(0,0,1);
btVector3 pivotInA(CUBE_HALF_EXTENTS, -CUBE_HALF_EXTENTS, -CUBE_HALF_EXTENTS);
btVector3 axisInA(0, 0, 1);
// btVector3 pivotInB = body1 ? body1->getCenterOfMassTransform().inverse()(body0->getCenterOfMassTransform()(pivotInA)) : pivotInA;
// btVector3 axisInB = body1?
// (body1->getCenterOfMassTransform().getBasis().inverse()*(body1->getCenterOfMassTransform().getBasis() * axisInA)) :
// btVector3 pivotInB = body1 ? body1->getCenterOfMassTransform().inverse()(body0->getCenterOfMassTransform()(pivotInA)) : pivotInA;
// btVector3 axisInB = body1?
// (body1->getCenterOfMassTransform().getBasis().inverse()*(body1->getCenterOfMassTransform().getBasis() * axisInA)) :
body0->getCenterOfMassTransform().getBasis() * axisInA;
#define P2P
#ifdef P2P
btTypedConstraint* p2p = new btPoint2PointConstraint(*body0,pivotInA);
btTypedConstraint* p2p = new btPoint2PointConstraint(*body0, pivotInA);
//btTypedConstraint* p2p = new btPoint2PointConstraint(*body0,*body1,pivotInA,pivotInB);
//btTypedConstraint* hinge = new btHingeConstraint(*body0,*body1,pivotInA,pivotInB,axisInA,axisInB);
m_dynamicsWorld->addConstraint(p2p);
p2p->setDbgDrawSize(btScalar(5.f));
#else
btHingeConstraint* hinge = new btHingeConstraint(*body0,pivotInA,axisInA);
btHingeConstraint* hinge = new btHingeConstraint(*body0, pivotInA, axisInA);
//use zero targetVelocity and a small maxMotorImpulse to simulate joint friction
//float targetVelocity = 0.f;
//float maxMotorImpulse = 0.01;
float targetVelocity = 1.f;
float maxMotorImpulse = 1.0f;
hinge->enableAngularMotor(true,targetVelocity,maxMotorImpulse);
float targetVelocity = 1.f;
float maxMotorImpulse = 1.0f;
hinge->enableAngularMotor(true, targetVelocity, maxMotorImpulse);
m_dynamicsWorld->addConstraint(hinge);
hinge->setDbgDrawSize(btScalar(5.f));
#endif //P2P
#endif //P2P
}
#endif
#if ENABLE_ALL_DEMOS
{
btTransform trans;
trans.setIdentity();
btVector3 worldPos(-20,0,30);
trans.setOrigin(worldPos);
trans.setIdentity();
btVector3 worldPos(-20, 0, 30);
trans.setOrigin(worldPos);
btTransform frameInA, frameInB;
frameInA = btTransform::getIdentity();
frameInB = btTransform::getIdentity();
btTransform frameInA, frameInB;
frameInA = btTransform::getIdentity();
frameInB = btTransform::getIdentity();
btRigidBody* pRbA1 = createRigidBody(mass, trans, shape);
// btRigidBody* pRbA1 = createRigidBody(0.f, trans, shape);
pRbA1->setActivationState(DISABLE_DEACTIVATION);
btRigidBody* pRbA1 = createRigidBody(mass, trans, shape);
// btRigidBody* pRbA1 = createRigidBody(0.f, trans, shape);
pRbA1->setActivationState(DISABLE_DEACTIVATION);
// add dynamic rigid body B1
worldPos.setValue(-30,0,30);
trans.setOrigin(worldPos);
btRigidBody* pRbB1 = createRigidBody(mass, trans, shape);
// btRigidBody* pRbB1 = createRigidBody(0.f, trans, shape);
pRbB1->setActivationState(DISABLE_DEACTIVATION);
// add dynamic rigid body B1
worldPos.setValue(-30, 0, 30);
trans.setOrigin(worldPos);
btRigidBody* pRbB1 = createRigidBody(mass, trans, shape);
// btRigidBody* pRbB1 = createRigidBody(0.f, trans, shape);
pRbB1->setActivationState(DISABLE_DEACTIVATION);
// create slider constraint between A1 and B1 and add it to world
btSliderConstraint* spSlider1 = new btSliderConstraint(*pRbA1, *pRbB1, frameInA, frameInB, true);
// spSlider1 = new btSliderConstraint(*pRbA1, *pRbB1, frameInA, frameInB, false);
spSlider1->setLowerLinLimit(-15.0F);
spSlider1->setUpperLinLimit(-5.0F);
// spSlider1->setLowerLinLimit(5.0F);
// spSlider1->setUpperLinLimit(15.0F);
// spSlider1->setLowerLinLimit(-10.0F);
// spSlider1->setUpperLinLimit(-10.0F);
// create slider constraint between A1 and B1 and add it to world
spSlider1->setLowerAngLimit(-SIMD_PI / 3.0F);
spSlider1->setUpperAngLimit( SIMD_PI / 3.0F);
btSliderConstraint* spSlider1 = new btSliderConstraint(*pRbA1, *pRbB1, frameInA, frameInB, true);
// spSlider1 = new btSliderConstraint(*pRbA1, *pRbB1, frameInA, frameInB, false);
spSlider1->setLowerLinLimit(-15.0F);
spSlider1->setUpperLinLimit(-5.0F);
// spSlider1->setLowerLinLimit(5.0F);
// spSlider1->setUpperLinLimit(15.0F);
// spSlider1->setLowerLinLimit(-10.0F);
// spSlider1->setUpperLinLimit(-10.0F);
spSlider1->setLowerAngLimit(-SIMD_PI / 3.0F);
spSlider1->setUpperAngLimit(SIMD_PI / 3.0F);
m_dynamicsWorld->addConstraint(spSlider1, true);
spSlider1->setDbgDrawSize(btScalar(5.f));
m_dynamicsWorld->addConstraint(spSlider1, true);
spSlider1->setDbgDrawSize(btScalar(5.f));
}
#endif
#if ENABLE_ALL_DEMOS
#if ENABLE_ALL_DEMOS
//create a slider, using the generic D6 constraint
{
mass = 1.f;
btVector3 sliderWorldPos(0,10,0);
btVector3 sliderAxis(1,0,0);
btScalar angle=0.f;//SIMD_RADS_PER_DEG * 10.f;
btMatrix3x3 sliderOrientation(btQuaternion(sliderAxis ,angle));
btVector3 sliderWorldPos(0, 10, 0);
btVector3 sliderAxis(1, 0, 0);
btScalar angle = 0.f; //SIMD_RADS_PER_DEG * 10.f;
btMatrix3x3 sliderOrientation(btQuaternion(sliderAxis, angle));
trans.setIdentity();
trans.setOrigin(sliderWorldPos);
//trans.setBasis(sliderOrientation);
sliderTransform = trans;
d6body0 = createRigidBody( mass,trans,shape);
d6body0 = createRigidBody(mass, trans, shape);
d6body0->setActivationState(DISABLE_DEACTIVATION);
btRigidBody* fixedBody1 = createRigidBody(0,trans,0);
btRigidBody* fixedBody1 = createRigidBody(0, trans, 0);
m_dynamicsWorld->addRigidBody(fixedBody1);
btTransform frameInA, frameInB;
@@ -340,54 +305,52 @@ void AllConstraintDemo::initPhysics()
frameInA.setOrigin(btVector3(0., 5., 0.));
frameInB.setOrigin(btVector3(0., 5., 0.));
// bool useLinearReferenceFrameA = false;//use fixed frame B for linear llimits
bool useLinearReferenceFrameA = true;//use fixed frame A for linear llimits
spSlider6Dof = new btGeneric6DofConstraint(*fixedBody1, *d6body0,frameInA,frameInB,useLinearReferenceFrameA);
// bool useLinearReferenceFrameA = false;//use fixed frame B for linear llimits
bool useLinearReferenceFrameA = true; //use fixed frame A for linear llimits
spSlider6Dof = new btGeneric6DofConstraint(*fixedBody1, *d6body0, frameInA, frameInB, useLinearReferenceFrameA);
spSlider6Dof->setLinearLowerLimit(lowerSliderLimit);
spSlider6Dof->setLinearUpperLimit(hiSliderLimit);
//range should be small, otherwise singularities will 'explode' the constraint
// spSlider6Dof->setAngularLowerLimit(btVector3(-1.5,0,0));
// spSlider6Dof->setAngularUpperLimit(btVector3(1.5,0,0));
// spSlider6Dof->setAngularLowerLimit(btVector3(0,0,0));
// spSlider6Dof->setAngularUpperLimit(btVector3(0,0,0));
spSlider6Dof->setAngularLowerLimit(btVector3(-SIMD_PI,0,0));
spSlider6Dof->setAngularUpperLimit(btVector3(1.5,0,0));
// spSlider6Dof->setAngularLowerLimit(btVector3(-1.5,0,0));
// spSlider6Dof->setAngularUpperLimit(btVector3(1.5,0,0));
// spSlider6Dof->setAngularLowerLimit(btVector3(0,0,0));
// spSlider6Dof->setAngularUpperLimit(btVector3(0,0,0));
spSlider6Dof->setAngularLowerLimit(btVector3(-SIMD_PI, 0, 0));
spSlider6Dof->setAngularUpperLimit(btVector3(1.5, 0, 0));
spSlider6Dof->getTranslationalLimitMotor()->m_enableMotor[0] = true;
spSlider6Dof->getTranslationalLimitMotor()->m_targetVelocity[0] = -5.0f;
spSlider6Dof->getTranslationalLimitMotor()->m_maxMotorForce[0] = 6.0f;
m_dynamicsWorld->addConstraint(spSlider6Dof);
spSlider6Dof->setDbgDrawSize(btScalar(5.f));
}
#endif
#if ENABLE_ALL_DEMOS
{ // create a door using hinge constraint attached to the world
{ // create a door using hinge constraint attached to the world
btCollisionShape* pDoorShape = new btBoxShape(btVector3(2.0f, 5.0f, 0.2f));
m_collisionShapes.push_back(pDoorShape);
btTransform doorTrans;
doorTrans.setIdentity();
doorTrans.setOrigin(btVector3(-5.0f, -2.0f, 0.0f));
btRigidBody* pDoorBody = createRigidBody( 1.0, doorTrans, pDoorShape);
btRigidBody* pDoorBody = createRigidBody(1.0, doorTrans, pDoorShape);
pDoorBody->setActivationState(DISABLE_DEACTIVATION);
const btVector3 btPivotA(10.f + 2.1f, -2.0f, 0.0f ); // right next to the door slightly outside
btVector3 btAxisA( 0.0f, 1.0f, 0.0f ); // pointing upwards, aka Y-axis
const btVector3 btPivotA(10.f + 2.1f, -2.0f, 0.0f); // right next to the door slightly outside
btVector3 btAxisA(0.0f, 1.0f, 0.0f); // pointing upwards, aka Y-axis
spDoorHinge = new btHingeConstraint( *pDoorBody, btPivotA, btAxisA );
spDoorHinge = new btHingeConstraint(*pDoorBody, btPivotA, btAxisA);
// spDoorHinge->setLimit( 0.0f, SIMD_PI_2 );
// spDoorHinge->setLimit( 0.0f, SIMD_PI_2 );
// test problem values
// spDoorHinge->setLimit( -SIMD_PI, SIMD_PI*0.8f);
// spDoorHinge->setLimit( -SIMD_PI, SIMD_PI*0.8f);
// spDoorHinge->setLimit( 1.f, -1.f);
// spDoorHinge->setLimit( -SIMD_PI*0.8f, SIMD_PI);
// spDoorHinge->setLimit( -SIMD_PI*0.8f, SIMD_PI, 0.9f, 0.3f, 0.0f);
// spDoorHinge->setLimit( -SIMD_PI*0.8f, SIMD_PI, 0.9f, 0.01f, 0.0f); // "sticky limits"
spDoorHinge->setLimit( -SIMD_PI * 0.25f, SIMD_PI * 0.25f );
// spDoorHinge->setLimit( 0.0f, 0.0f );
// spDoorHinge->setLimit( 1.f, -1.f);
// spDoorHinge->setLimit( -SIMD_PI*0.8f, SIMD_PI);
// spDoorHinge->setLimit( -SIMD_PI*0.8f, SIMD_PI, 0.9f, 0.3f, 0.0f);
// spDoorHinge->setLimit( -SIMD_PI*0.8f, SIMD_PI, 0.9f, 0.01f, 0.0f); // "sticky limits"
spDoorHinge->setLimit(-SIMD_PI * 0.25f, SIMD_PI * 0.25f);
// spDoorHinge->setLimit( 0.0f, 0.0f );
m_dynamicsWorld->addConstraint(spDoorHinge);
spDoorHinge->setDbgDrawSize(btScalar(5.f));
@@ -396,22 +359,22 @@ void AllConstraintDemo::initPhysics()
}
#endif
#if ENABLE_ALL_DEMOS
{ // create a generic 6DOF constraint
{ // create a generic 6DOF constraint
btTransform tr;
tr.setIdentity();
tr.setOrigin(btVector3(btScalar(10.), btScalar(6.), btScalar(0.)));
tr.getBasis().setEulerZYX(0,0,0);
// btRigidBody* pBodyA = createRigidBody( mass, tr, shape);
btRigidBody* pBodyA = createRigidBody( 0.0, tr, shape);
// btRigidBody* pBodyA = createRigidBody( 0.0, tr, 0);
tr.getBasis().setEulerZYX(0, 0, 0);
// btRigidBody* pBodyA = createRigidBody( mass, tr, shape);
btRigidBody* pBodyA = createRigidBody(0.0, tr, shape);
// btRigidBody* pBodyA = createRigidBody( 0.0, tr, 0);
pBodyA->setActivationState(DISABLE_DEACTIVATION);
tr.setIdentity();
tr.setOrigin(btVector3(btScalar(0.), btScalar(6.), btScalar(0.)));
tr.getBasis().setEulerZYX(0,0,0);
tr.getBasis().setEulerZYX(0, 0, 0);
btRigidBody* pBodyB = createRigidBody(mass, tr, shape);
// btRigidBody* pBodyB = createRigidBody(0.f, tr, shape);
// btRigidBody* pBodyB = createRigidBody(0.f, tr, shape);
pBodyB->setActivationState(DISABLE_DEACTIVATION);
btTransform frameInA, frameInB;
@@ -421,75 +384,72 @@ void AllConstraintDemo::initPhysics()
frameInB.setOrigin(btVector3(btScalar(5.), btScalar(0.), btScalar(0.)));
btGeneric6DofConstraint* pGen6DOF = new btGeneric6DofConstraint(*pBodyA, *pBodyB, frameInA, frameInB, true);
// btGeneric6DofConstraint* pGen6DOF = new btGeneric6DofConstraint(*pBodyA, *pBodyB, frameInA, frameInB, false);
// btGeneric6DofConstraint* pGen6DOF = new btGeneric6DofConstraint(*pBodyA, *pBodyB, frameInA, frameInB, false);
pGen6DOF->setLinearLowerLimit(btVector3(-10., -2., -1.));
pGen6DOF->setLinearUpperLimit(btVector3(10., 2., 1.));
// pGen6DOF->setLinearLowerLimit(btVector3(-10., 0., 0.));
// pGen6DOF->setLinearUpperLimit(btVector3(10., 0., 0.));
// pGen6DOF->setLinearLowerLimit(btVector3(0., 0., 0.));
// pGen6DOF->setLinearUpperLimit(btVector3(0., 0., 0.));
// pGen6DOF->setLinearLowerLimit(btVector3(-10., 0., 0.));
// pGen6DOF->setLinearUpperLimit(btVector3(10., 0., 0.));
// pGen6DOF->setLinearLowerLimit(btVector3(0., 0., 0.));
// pGen6DOF->setLinearUpperLimit(btVector3(0., 0., 0.));
// pGen6DOF->getTranslationalLimitMotor()->m_enableMotor[0] = true;
// pGen6DOF->getTranslationalLimitMotor()->m_targetVelocity[0] = 5.0f;
// pGen6DOF->getTranslationalLimitMotor()->m_maxMotorForce[0] = 6.0f;
// pGen6DOF->getTranslationalLimitMotor()->m_enableMotor[0] = true;
// pGen6DOF->getTranslationalLimitMotor()->m_targetVelocity[0] = 5.0f;
// pGen6DOF->getTranslationalLimitMotor()->m_maxMotorForce[0] = 6.0f;
// pGen6DOF->setAngularLowerLimit(btVector3(0., SIMD_HALF_PI*0.9, 0.));
// pGen6DOF->setAngularUpperLimit(btVector3(0., -SIMD_HALF_PI*0.9, 0.));
// pGen6DOF->setAngularLowerLimit(btVector3(0., 0., -SIMD_HALF_PI));
// pGen6DOF->setAngularUpperLimit(btVector3(0., 0., SIMD_HALF_PI));
// pGen6DOF->setAngularLowerLimit(btVector3(0., SIMD_HALF_PI*0.9, 0.));
// pGen6DOF->setAngularUpperLimit(btVector3(0., -SIMD_HALF_PI*0.9, 0.));
// pGen6DOF->setAngularLowerLimit(btVector3(0., 0., -SIMD_HALF_PI));
// pGen6DOF->setAngularUpperLimit(btVector3(0., 0., SIMD_HALF_PI));
pGen6DOF->setAngularLowerLimit(btVector3(-SIMD_HALF_PI * 0.5f, -0.75, -SIMD_HALF_PI * 0.8f));
pGen6DOF->setAngularUpperLimit(btVector3(SIMD_HALF_PI * 0.5f, 0.75, SIMD_HALF_PI * 0.8f));
// pGen6DOF->setAngularLowerLimit(btVector3(0.f, -0.75, SIMD_HALF_PI * 0.8f));
// pGen6DOF->setAngularUpperLimit(btVector3(0.f, 0.75, -SIMD_HALF_PI * 0.8f));
// pGen6DOF->setAngularLowerLimit(btVector3(0.f, -SIMD_HALF_PI * 0.8f, SIMD_HALF_PI * 1.98f));
// pGen6DOF->setAngularUpperLimit(btVector3(0.f, SIMD_HALF_PI * 0.8f, -SIMD_HALF_PI * 1.98f));
// pGen6DOF->setAngularLowerLimit(btVector3(0.f, -0.75, SIMD_HALF_PI * 0.8f));
// pGen6DOF->setAngularUpperLimit(btVector3(0.f, 0.75, -SIMD_HALF_PI * 0.8f));
// pGen6DOF->setAngularLowerLimit(btVector3(0.f, -SIMD_HALF_PI * 0.8f, SIMD_HALF_PI * 1.98f));
// pGen6DOF->setAngularUpperLimit(btVector3(0.f, SIMD_HALF_PI * 0.8f, -SIMD_HALF_PI * 1.98f));
// pGen6DOF->setAngularLowerLimit(btVector3(-0.75,-0.5, -0.5));
// pGen6DOF->setAngularUpperLimit(btVector3(0.75,0.5, 0.5));
// pGen6DOF->setAngularLowerLimit(btVector3(-0.75,0., 0.));
// pGen6DOF->setAngularUpperLimit(btVector3(0.75,0., 0.));
// pGen6DOF->setAngularLowerLimit(btVector3(0., -0.7,0.));
// pGen6DOF->setAngularUpperLimit(btVector3(0., 0.7, 0.));
// pGen6DOF->setAngularLowerLimit(btVector3(-1., 0.,0.));
// pGen6DOF->setAngularUpperLimit(btVector3(1., 0., 0.));
// pGen6DOF->setAngularLowerLimit(btVector3(-0.75,-0.5, -0.5));
// pGen6DOF->setAngularUpperLimit(btVector3(0.75,0.5, 0.5));
// pGen6DOF->setAngularLowerLimit(btVector3(-0.75,0., 0.));
// pGen6DOF->setAngularUpperLimit(btVector3(0.75,0., 0.));
// pGen6DOF->setAngularLowerLimit(btVector3(0., -0.7,0.));
// pGen6DOF->setAngularUpperLimit(btVector3(0., 0.7, 0.));
// pGen6DOF->setAngularLowerLimit(btVector3(-1., 0.,0.));
// pGen6DOF->setAngularUpperLimit(btVector3(1., 0., 0.));
m_dynamicsWorld->addConstraint(pGen6DOF, true);
pGen6DOF->setDbgDrawSize(btScalar(5.f));
}
#endif
#if ENABLE_ALL_DEMOS
{ // create a ConeTwist constraint
{ // create a ConeTwist constraint
btTransform tr;
tr.setIdentity();
tr.setOrigin(btVector3(btScalar(-10.), btScalar(5.), btScalar(0.)));
tr.getBasis().setEulerZYX(0,0,0);
btRigidBody* pBodyA = createRigidBody( 1.0, tr, shape);
// btRigidBody* pBodyA = createRigidBody( 0.0, tr, shape);
tr.getBasis().setEulerZYX(0, 0, 0);
btRigidBody* pBodyA = createRigidBody(1.0, tr, shape);
// btRigidBody* pBodyA = createRigidBody( 0.0, tr, shape);
pBodyA->setActivationState(DISABLE_DEACTIVATION);
tr.setIdentity();
tr.setOrigin(btVector3(btScalar(-10.), btScalar(-5.), btScalar(0.)));
tr.getBasis().setEulerZYX(0,0,0);
tr.getBasis().setEulerZYX(0, 0, 0);
btRigidBody* pBodyB = createRigidBody(0.0, tr, shape);
// btRigidBody* pBodyB = createRigidBody(1.0, tr, shape);
// btRigidBody* pBodyB = createRigidBody(1.0, tr, shape);
btTransform frameInA, frameInB;
frameInA = btTransform::getIdentity();
frameInA.getBasis().setEulerZYX(0, 0, SIMD_PI_2);
frameInA.setOrigin(btVector3(btScalar(0.), btScalar(-5.), btScalar(0.)));
frameInB = btTransform::getIdentity();
frameInB.getBasis().setEulerZYX(0,0, SIMD_PI_2);
frameInB.getBasis().setEulerZYX(0, 0, SIMD_PI_2);
frameInB.setOrigin(btVector3(btScalar(0.), btScalar(5.), btScalar(0.)));
m_ctc = new btConeTwistConstraint(*pBodyA, *pBodyB, frameInA, frameInB);
// m_ctc->setLimit(btScalar(SIMD_PI_4), btScalar(SIMD_PI_4), btScalar(SIMD_PI) * 0.8f);
// m_ctc->setLimit(btScalar(SIMD_PI_4*0.6f), btScalar(SIMD_PI_4), btScalar(SIMD_PI) * 0.8f, 1.0f); // soft limit == hard limit
m_ctc->setLimit(btScalar(SIMD_PI_4*0.6f), btScalar(SIMD_PI_4), btScalar(SIMD_PI) * 0.8f, 0.5f);
// m_ctc->setLimit(btScalar(SIMD_PI_4), btScalar(SIMD_PI_4), btScalar(SIMD_PI) * 0.8f);
// m_ctc->setLimit(btScalar(SIMD_PI_4*0.6f), btScalar(SIMD_PI_4), btScalar(SIMD_PI) * 0.8f, 1.0f); // soft limit == hard limit
m_ctc->setLimit(btScalar(SIMD_PI_4 * 0.6f), btScalar(SIMD_PI_4), btScalar(SIMD_PI) * 0.8f, 0.5f);
m_dynamicsWorld->addConstraint(m_ctc, true);
m_ctc->setDbgDrawSize(btScalar(5.f));
// s_bTestConeTwistMotor = true; // use only with old solver for now
@@ -497,32 +457,32 @@ void AllConstraintDemo::initPhysics()
}
#endif
#if ENABLE_ALL_DEMOS
{ // Hinge connected to the world, with motor (to hinge motor with new and old constraint solver)
{ // Hinge connected to the world, with motor (to hinge motor with new and old constraint solver)
btTransform tr;
tr.setIdentity();
tr.setOrigin(btVector3(btScalar(0.), btScalar(0.), btScalar(0.)));
btRigidBody* pBody = createRigidBody( 1.0, tr, shape);
btRigidBody* pBody = createRigidBody(1.0, tr, shape);
pBody->setActivationState(DISABLE_DEACTIVATION);
const btVector3 btPivotA( 10.0f, 0.0f, 0.0f );
btVector3 btAxisA( 0.0f, 0.0f, 1.0f );
const btVector3 btPivotA(10.0f, 0.0f, 0.0f);
btVector3 btAxisA(0.0f, 0.0f, 1.0f);
btHingeConstraint* pHinge = new btHingeConstraint( *pBody, btPivotA, btAxisA );
// pHinge->enableAngularMotor(true, -1.0, 0.165); // use for the old solver
pHinge->enableAngularMotor(true, -1.0f, 1.65f); // use for the new SIMD solver
btHingeConstraint* pHinge = new btHingeConstraint(*pBody, btPivotA, btAxisA);
// pHinge->enableAngularMotor(true, -1.0, 0.165); // use for the old solver
pHinge->enableAngularMotor(true, -1.0f, 1.65f); // use for the new SIMD solver
m_dynamicsWorld->addConstraint(pHinge);
pHinge->setDbgDrawSize(btScalar(5.f));
}
#endif
#if ENABLE_ALL_DEMOS
{
{
// create a universal joint using generic 6DOF constraint
// create two rigid bodies
// static bodyA (parent) on top:
btTransform tr;
tr.setIdentity();
tr.setOrigin(btVector3(btScalar(20.), btScalar(4.), btScalar(0.)));
btRigidBody* pBodyA = createRigidBody( 0.0, tr, shape);
btRigidBody* pBodyA = createRigidBody(0.0, tr, shape);
pBodyA->setActivationState(DISABLE_DEACTIVATION);
// dynamic bodyB (child) below it :
tr.setIdentity();
@@ -530,13 +490,13 @@ void AllConstraintDemo::initPhysics()
btRigidBody* pBodyB = createRigidBody(1.0, tr, shape);
pBodyB->setActivationState(DISABLE_DEACTIVATION);
// add some (arbitrary) data to build constraint frames
btVector3 parentAxis(1.f, 0.f, 0.f);
btVector3 childAxis(0.f, 0.f, 1.f);
btVector3 parentAxis(1.f, 0.f, 0.f);
btVector3 childAxis(0.f, 0.f, 1.f);
btVector3 anchor(20.f, 2.f, 0.f);
btUniversalConstraint* pUniv = new btUniversalConstraint(*pBodyA, *pBodyB, anchor, parentAxis, childAxis);
pUniv->setLowerLimit(-SIMD_HALF_PI * 0.5f, -SIMD_HALF_PI * 0.5f);
pUniv->setUpperLimit(SIMD_HALF_PI * 0.5f, SIMD_HALF_PI * 0.5f);
pUniv->setUpperLimit(SIMD_HALF_PI * 0.5f, SIMD_HALF_PI * 0.5f);
// add constraint to world
m_dynamicsWorld->addConstraint(pUniv, true);
// draw constraint frames and limits for debugging
@@ -545,18 +505,18 @@ void AllConstraintDemo::initPhysics()
#endif
#if ENABLE_ALL_DEMOS
{ // create a generic 6DOF constraint with springs
{ // create a generic 6DOF constraint with springs
btTransform tr;
tr.setIdentity();
tr.setOrigin(btVector3(btScalar(-20.), btScalar(16.), btScalar(0.)));
tr.getBasis().setEulerZYX(0,0,0);
btRigidBody* pBodyA = createRigidBody( 0.0, tr, shape);
tr.getBasis().setEulerZYX(0, 0, 0);
btRigidBody* pBodyA = createRigidBody(0.0, tr, shape);
pBodyA->setActivationState(DISABLE_DEACTIVATION);
tr.setIdentity();
tr.setOrigin(btVector3(btScalar(-10.), btScalar(16.), btScalar(0.)));
tr.getBasis().setEulerZYX(0,0,0);
tr.getBasis().setEulerZYX(0, 0, 0);
btRigidBody* pBodyB = createRigidBody(1.0, tr, shape);
pBodyB->setActivationState(DISABLE_DEACTIVATION);
@@ -575,7 +535,7 @@ void AllConstraintDemo::initPhysics()
m_dynamicsWorld->addConstraint(pGen6DOFSpring, true);
pGen6DOFSpring->setDbgDrawSize(btScalar(5.f));
pGen6DOFSpring->enableSpring(0, true);
pGen6DOFSpring->setStiffness(0, 39.478f);
pGen6DOFSpring->setDamping(0, 0.5f);
@@ -586,14 +546,14 @@ void AllConstraintDemo::initPhysics()
}
#endif
#if ENABLE_ALL_DEMOS
{
{
// create a Hinge2 joint
// create two rigid bodies
// static bodyA (parent) on top:
btTransform tr;
tr.setIdentity();
tr.setOrigin(btVector3(btScalar(-20.), btScalar(4.), btScalar(0.)));
btRigidBody* pBodyA = createRigidBody( 0.0, tr, shape);
btRigidBody* pBodyA = createRigidBody(0.0, tr, shape);
pBodyA->setActivationState(DISABLE_DEACTIVATION);
// dynamic bodyB (child) below it :
tr.setIdentity();
@@ -601,27 +561,27 @@ void AllConstraintDemo::initPhysics()
btRigidBody* pBodyB = createRigidBody(1.0, tr, shape);
pBodyB->setActivationState(DISABLE_DEACTIVATION);
// add some data to build constraint frames
btVector3 parentAxis(0.f, 1.f, 0.f);
btVector3 childAxis(1.f, 0.f, 0.f);
btVector3 parentAxis(0.f, 1.f, 0.f);
btVector3 childAxis(1.f, 0.f, 0.f);
btVector3 anchor(-20.f, 0.f, 0.f);
btHinge2Constraint* pHinge2 = new btHinge2Constraint(*pBodyA, *pBodyB, anchor, parentAxis, childAxis);
pHinge2->setLowerLimit(-SIMD_HALF_PI * 0.5f);
pHinge2->setUpperLimit( SIMD_HALF_PI * 0.5f);
pHinge2->setUpperLimit(SIMD_HALF_PI * 0.5f);
// add constraint to world
m_dynamicsWorld->addConstraint(pHinge2, true);
// draw constraint frames and limits for debugging
pHinge2->setDbgDrawSize(btScalar(5.f));
}
#endif
#if ENABLE_ALL_DEMOS
{
#if ENABLE_ALL_DEMOS
{
// create a Hinge joint between two dynamic bodies
// create two rigid bodies
// static bodyA (parent) on top:
btTransform tr;
tr.setIdentity();
tr.setOrigin(btVector3(btScalar(-20.), btScalar(-2.), btScalar(0.)));
btRigidBody* pBodyA = createRigidBody( 1.0f, tr, shape);
btRigidBody* pBodyA = createRigidBody(1.0f, tr, shape);
pBodyA->setActivationState(DISABLE_DEACTIVATION);
// dynamic bodyB:
tr.setIdentity();
@@ -629,10 +589,10 @@ void AllConstraintDemo::initPhysics()
btRigidBody* pBodyB = createRigidBody(10.0, tr, shape);
pBodyB->setActivationState(DISABLE_DEACTIVATION);
// add some data to build constraint frames
btVector3 axisA(0.f, 1.f, 0.f);
btVector3 axisB(0.f, 1.f, 0.f);
btVector3 axisA(0.f, 1.f, 0.f);
btVector3 axisB(0.f, 1.f, 0.f);
btVector3 pivotA(-5.f, 0.f, 0.f);
btVector3 pivotB( 5.f, 0.f, 0.f);
btVector3 pivotB(5.f, 0.f, 0.f);
spHingeDynAB = new btHingeConstraint(*pBodyA, *pBodyB, pivotA, pivotB, axisA, axisB);
spHingeDynAB->setLimit(-SIMD_HALF_PI * 0.5f, SIMD_HALF_PI * 0.5f);
// add constraint to world
@@ -643,20 +603,20 @@ void AllConstraintDemo::initPhysics()
#endif
#if ENABLE_ALL_DEMOS
{ // 6DOF connected to the world, with motor
{ // 6DOF connected to the world, with motor
btTransform tr;
tr.setIdentity();
tr.setOrigin(btVector3(btScalar(10.), btScalar(-15.), btScalar(0.)));
btRigidBody* pBody = createRigidBody( 1.0, tr, shape);
btRigidBody* pBody = createRigidBody(1.0, tr, shape);
pBody->setActivationState(DISABLE_DEACTIVATION);
btTransform frameB;
frameB.setIdentity();
btGeneric6DofConstraint* pGen6Dof = new btGeneric6DofConstraint( *pBody, frameB, false );
btGeneric6DofConstraint* pGen6Dof = new btGeneric6DofConstraint(*pBody, frameB, false);
m_dynamicsWorld->addConstraint(pGen6Dof);
pGen6Dof->setDbgDrawSize(btScalar(5.f));
pGen6Dof->setAngularLowerLimit(btVector3(0,0,0));
pGen6Dof->setAngularUpperLimit(btVector3(0,0,0));
pGen6Dof->setAngularLowerLimit(btVector3(0, 0, 0));
pGen6Dof->setAngularUpperLimit(btVector3(0, 0, 0));
pGen6Dof->setLinearLowerLimit(btVector3(-10., 0, 0));
pGen6Dof->setLinearUpperLimit(btVector3(10., 0, 0));
@@ -667,17 +627,14 @@ void AllConstraintDemo::initPhysics()
#endif
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void AllConstraintDemo::exitPhysics()
void AllConstraintDemo::exitPhysics()
{
int i;
int i;
//removed/delete constraints
for (i=m_dynamicsWorld->getNumConstraints()-1; i>=0 ;i--)
for (i = m_dynamicsWorld->getNumConstraints() - 1; i >= 0; i--)
{
btTypedConstraint* constraint = m_dynamicsWorld->getConstraint(i);
m_dynamicsWorld->removeConstraint(constraint);
@@ -686,7 +643,7 @@ void AllConstraintDemo::exitPhysics()
m_ctc = NULL;
//remove the rigidbodies from the dynamics world and delete them
for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--)
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
{
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
@@ -694,15 +651,12 @@ void AllConstraintDemo::exitPhysics()
{
delete body->getMotionState();
}
m_dynamicsWorld->removeCollisionObject( obj );
m_dynamicsWorld->removeCollisionObject(obj);
delete obj;
}
//delete collision shapes
for (int j=0;j<m_collisionShapes.size();j++)
for (int j = 0; j < m_collisionShapes.size(); j++)
{
btCollisionShape* shape = m_collisionShapes[j];
delete shape;
@@ -712,25 +666,24 @@ void AllConstraintDemo::exitPhysics()
//delete dynamics world
delete m_dynamicsWorld;
m_dynamicsWorld=0;
m_dynamicsWorld = 0;
//delete solver
delete m_solver;
m_solver=0;
m_solver = 0;
//delete broadphase
delete m_broadphase;
m_broadphase=0;
m_broadphase = 0;
//delete dispatcher
delete m_dispatcher;
delete m_collisionConfiguration;
}
AllConstraintDemo::AllConstraintDemo(struct GUIHelperInterface* helper)
:CommonRigidBodyBase(helper)
: CommonRigidBodyBase(helper)
{
}
@@ -738,8 +691,7 @@ AllConstraintDemo::~AllConstraintDemo()
{
//cleanup in the reverse order of creation/initialization
btAssert(m_dynamicsWorld==0);
btAssert(m_dynamicsWorld == 0);
}
#if 0
@@ -838,51 +790,48 @@ void AllConstraintDemo::displayCallback(void) {
}
#endif
bool AllConstraintDemo::keyboardCallback(int key, int state)
bool AllConstraintDemo::keyboardCallback(int key, int state)
{
bool handled = false;
switch (key)
switch (key)
{
case 'O' :
case 'O':
{
bool offectOnOff;
if (spDoorHinge)
{
bool offectOnOff;
if(spDoorHinge)
{
offectOnOff = spDoorHinge->getUseFrameOffset();
offectOnOff = !offectOnOff;
spDoorHinge->setUseFrameOffset(offectOnOff);
printf("DoorHinge %s frame offset\n", offectOnOff ? "uses" : "does not use");
}
if(spHingeDynAB)
{
offectOnOff = spHingeDynAB->getUseFrameOffset();
offectOnOff = !offectOnOff;
spHingeDynAB->setUseFrameOffset(offectOnOff);
printf("HingeDynAB %s frame offset\n", offectOnOff ? "uses" : "does not use");
}
if(spSlider6Dof)
{
offectOnOff = spSlider6Dof->getUseFrameOffset();
offectOnOff = !offectOnOff;
spSlider6Dof->setUseFrameOffset(offectOnOff);
printf("Slider6Dof %s frame offset\n", offectOnOff ? "uses" : "does not use");
}
offectOnOff = spDoorHinge->getUseFrameOffset();
offectOnOff = !offectOnOff;
spDoorHinge->setUseFrameOffset(offectOnOff);
printf("DoorHinge %s frame offset\n", offectOnOff ? "uses" : "does not use");
}
if (spHingeDynAB)
{
offectOnOff = spHingeDynAB->getUseFrameOffset();
offectOnOff = !offectOnOff;
spHingeDynAB->setUseFrameOffset(offectOnOff);
printf("HingeDynAB %s frame offset\n", offectOnOff ? "uses" : "does not use");
}
if (spSlider6Dof)
{
offectOnOff = spSlider6Dof->getUseFrameOffset();
offectOnOff = !offectOnOff;
spSlider6Dof->setUseFrameOffset(offectOnOff);
printf("Slider6Dof %s frame offset\n", offectOnOff ? "uses" : "does not use");
}
}
handled = true;
break;
default :
{
}
break;
default:
{
}
break;
}
return handled;
}
class CommonExampleInterface* AllConstraintCreateFunc(struct CommonExampleOptions& options)
class CommonExampleInterface* AllConstraintCreateFunc(struct CommonExampleOptions& options)
{
return new AllConstraintDemo(options.m_guiHelper);
}

View File

@@ -15,8 +15,6 @@ subject to the following restrictions:
#ifndef ALL_CONSTRAINT_DEMO_H
#define ALL_CONSTRAINT_DEMO_H
class CommonExampleInterface* AllConstraintCreateFunc(struct CommonExampleOptions& options);
#endif //ALL_CONSTRAINT_DEMO_H
class CommonExampleInterface* AllConstraintCreateFunc(struct CommonExampleOptions& options);
#endif //ALL_CONSTRAINT_DEMO_H

View File

@@ -1,11 +1,8 @@
#include "ConstraintPhysicsSetup.h"
#include "../CommonInterfaces/CommonRigidBodyBase.h"
#include "../CommonInterfaces/CommonParameterInterface.h"
struct ConstraintPhysicsSetup : public CommonRigidBodyBase
{
ConstraintPhysicsSetup(struct GUIHelperInterface* helper);
@@ -14,21 +11,18 @@ struct ConstraintPhysicsSetup : public CommonRigidBodyBase
virtual void stepSimulation(float deltaTime);
virtual void resetCamera()
{
float dist = 7;
float pitch = -44;
float yaw = 721;
float targetPos[3]={8,1,-11};
m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]);
float targetPos[3] = {8, 1, -11};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
};
ConstraintPhysicsSetup::ConstraintPhysicsSetup(struct GUIHelperInterface* helper)
:CommonRigidBodyBase(helper)
: CommonRigidBodyBase(helper)
{
}
ConstraintPhysicsSetup::~ConstraintPhysicsSetup()
@@ -36,63 +30,56 @@ ConstraintPhysicsSetup::~ConstraintPhysicsSetup()
}
static btScalar val;
static btScalar targetVel=0;
static btScalar maxImpulse=10000;
static btHingeAccumulatedAngleConstraint* spDoorHinge=0;
static btScalar actualHingeVelocity=0.f;
static btScalar targetVel = 0;
static btScalar maxImpulse = 10000;
static btHingeAccumulatedAngleConstraint* spDoorHinge = 0;
static btScalar actualHingeVelocity = 0.f;
static btVector3 btAxisA(0,1,0);
static btVector3 btAxisA(0, 1, 0);
void ConstraintPhysicsSetup::stepSimulation(float deltaTime)
{
val=spDoorHinge->getAccumulatedHingeAngle()*SIMD_DEGS_PER_RAD;
if (m_dynamicsWorld)
val = spDoorHinge->getAccumulatedHingeAngle() * SIMD_DEGS_PER_RAD;
if (m_dynamicsWorld)
{
spDoorHinge->enableAngularMotor(true,targetVel,maxImpulse);
spDoorHinge->enableAngularMotor(true, targetVel, maxImpulse);
m_dynamicsWorld->stepSimulation(deltaTime,10,1./240.);
m_dynamicsWorld->stepSimulation(deltaTime, 10, 1. / 240.);
btHingeConstraint* hinge = spDoorHinge;
btHingeConstraint* hinge = spDoorHinge;
if (hinge)
{
const btRigidBody& bodyA = hinge->getRigidBodyA();
const btRigidBody& bodyB = hinge->getRigidBodyB();
if (hinge)
{
btTransform trA = bodyA.getWorldTransform();
btVector3 angVelA = bodyA.getAngularVelocity();
btVector3 angVelB = bodyB.getAngularVelocity();
const btRigidBody& bodyA = hinge->getRigidBodyA();
const btRigidBody& bodyB = hinge->getRigidBodyB();
btTransform trA = bodyA.getWorldTransform();
btVector3 angVelA = bodyA.getAngularVelocity();
btVector3 angVelB = bodyB.getAngularVelocity();
{
btVector3 ax1 = trA.getBasis()*hinge->getFrameOffsetA().getBasis().getColumn(2);
btScalar vel = angVelA.dot(ax1);
vel -= angVelB.dot(ax1);
printf("hinge velocity (q) = %f\n", vel);
actualHingeVelocity=vel;
}
btVector3 ortho0,ortho1;
btPlaneSpace1(btAxisA,ortho0,ortho1);
{
btScalar vel2 = angVelA.dot(ortho0);
vel2 -= angVelB.dot(ortho0);
printf("hinge orthogonal1 velocity (q) = %f\n", vel2);
}
{
btScalar vel0 = angVelA.dot(ortho1);
vel0 -= angVelB.dot(ortho1);
printf("hinge orthogonal0 velocity (q) = %f\n", vel0);
}
}
{
btVector3 ax1 = trA.getBasis() * hinge->getFrameOffsetA().getBasis().getColumn(2);
btScalar vel = angVelA.dot(ax1);
vel -= angVelB.dot(ax1);
printf("hinge velocity (q) = %f\n", vel);
actualHingeVelocity = vel;
}
btVector3 ortho0, ortho1;
btPlaneSpace1(btAxisA, ortho0, ortho1);
{
btScalar vel2 = angVelA.dot(ortho0);
vel2 -= angVelB.dot(ortho0);
printf("hinge orthogonal1 velocity (q) = %f\n", vel2);
}
{
btScalar vel0 = angVelA.dot(ortho1);
vel0 -= angVelB.dot(ortho1);
printf("hinge orthogonal0 velocity (q) = %f\n", vel0);
}
}
}
}
void ConstraintPhysicsSetup::initPhysics()
{
m_guiHelper->setUpAxis(1);
@@ -100,62 +87,59 @@ void ConstraintPhysicsSetup::initPhysics()
createEmptyDynamicsWorld();
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
int mode = btIDebugDraw::DBG_DrawWireframe
+btIDebugDraw::DBG_DrawConstraints
+btIDebugDraw::DBG_DrawConstraintLimits;
int mode = btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawConstraints + btIDebugDraw::DBG_DrawConstraintLimits;
m_dynamicsWorld->getDebugDrawer()->setDebugMode(mode);
{
SliderParams slider("target vel", &targetVel);
slider.m_minVal = -4;
slider.m_maxVal = 4;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{
SliderParams slider("target vel",&targetVel);
slider.m_minVal=-4;
slider.m_maxVal=4;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{
SliderParams slider("max impulse", &maxImpulse);
slider.m_minVal = 0;
slider.m_maxVal = 1000;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{
SliderParams slider("max impulse",&maxImpulse);
slider.m_minVal=0;
slider.m_maxVal=1000;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{
SliderParams slider("actual vel", &actualHingeVelocity);
slider.m_minVal = -4;
slider.m_maxVal = 4;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{
SliderParams slider("actual vel",&actualHingeVelocity);
slider.m_minVal=-4;
slider.m_maxVal=4;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
val = 1.f;
{
SliderParams slider("angle", &val);
slider.m_minVal = -720;
slider.m_maxVal = 720;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
val=1.f;
{
SliderParams slider("angle",&val);
slider.m_minVal=-720;
slider.m_maxVal=720;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{ // create a door using hinge constraint attached to the world
{ // create a door using hinge constraint attached to the world
btCollisionShape* pDoorShape = new btBoxShape(btVector3(2.0f, 5.0f, 0.2f));
m_collisionShapes.push_back(pDoorShape);
btTransform doorTrans;
doorTrans.setIdentity();
doorTrans.setOrigin(btVector3(-5.0f, -2.0f, 0.0f));
btRigidBody* pDoorBody = createRigidBody( 1.0, doorTrans, pDoorShape);
btRigidBody* pDoorBody = createRigidBody(1.0, doorTrans, pDoorShape);
pDoorBody->setActivationState(DISABLE_DEACTIVATION);
const btVector3 btPivotA(10.f + 2.1f, -2.0f, 0.0f ); // right next to the door slightly outside
const btVector3 btPivotA(10.f + 2.1f, -2.0f, 0.0f); // right next to the door slightly outside
spDoorHinge = new btHingeAccumulatedAngleConstraint( *pDoorBody, btPivotA, btAxisA );
spDoorHinge = new btHingeAccumulatedAngleConstraint(*pDoorBody, btPivotA, btAxisA);
m_dynamicsWorld->addConstraint(spDoorHinge);
m_dynamicsWorld->addConstraint(spDoorHinge);
spDoorHinge->setDbgDrawSize(btScalar(5.f));
}
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
class CommonExampleInterface* ConstraintCreateFunc(CommonExampleOptions& options)
class CommonExampleInterface* ConstraintCreateFunc(CommonExampleOptions& options)
{
return new ConstraintPhysicsSetup(options.m_guiHelper);
}

View File

@@ -1,6 +1,6 @@
#ifndef CONSTAINT_PHYSICS_SETUP_H
#define CONSTAINT_PHYSICS_SETUP_H
class CommonExampleInterface* ConstraintCreateFunc(struct CommonExampleOptions& options);
class CommonExampleInterface* ConstraintCreateFunc(struct CommonExampleOptions& options);
#endif //CONSTAINT_PHYSICS_SETUP_H
#endif //CONSTAINT_PHYSICS_SETUP_H

View File

@@ -9,37 +9,32 @@
#include "BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
#define M_PI 3.14159265358979323846
#endif
#ifndef M_PI_2
#define M_PI_2 1.57079632679489661923
#define M_PI_2 1.57079632679489661923
#endif
#ifndef M_PI_4
#define M_PI_4 0.785398163397448309616
#define M_PI_4 0.785398163397448309616
#endif
extern float g_additionalBodyMass;
//comment this out to compare with original spring constraint
#define USE_6DOF2
#ifdef USE_6DOF2
#define CONSTRAINT_TYPE btGeneric6DofSpring2Constraint
#define EXTRAPARAMS
#define CONSTRAINT_TYPE btGeneric6DofSpring2Constraint
#define EXTRAPARAMS
#else
#define CONSTRAINT_TYPE btGeneric6DofSpringConstraint
#define EXTRAPARAMS ,true
#define CONSTRAINT_TYPE btGeneric6DofSpringConstraint
#define EXTRAPARAMS , true
#endif
#include "../CommonInterfaces/CommonRigidBodyBase.h"
struct Dof6Spring2Setup : public CommonRigidBodyBase
{
struct Dof6Spring2SetupInternalData* m_data;
@@ -57,40 +52,37 @@ struct Dof6Spring2Setup : public CommonRigidBodyBase
float dist = 5;
float pitch = -35;
float yaw = 722;
float targetPos[3]={4,2,-11};
m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]);
float targetPos[3] = {4, 2, -11};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
};
struct Dof6Spring2SetupInternalData
{
btRigidBody* m_TranslateSpringBody;
btRigidBody* m_TranslateSpringBody2;
btRigidBody* m_RotateSpringBody;
btRigidBody* m_RotateSpringBody2;
btRigidBody* m_BouncingTranslateBody;
btRigidBody* m_MotorBody;
btRigidBody* m_ServoMotorBody;
btRigidBody* m_ChainLeftBody;
btRigidBody* m_ChainRightBody;
CONSTRAINT_TYPE* m_ServoMotorConstraint;
CONSTRAINT_TYPE* m_ChainLeftConstraint;
CONSTRAINT_TYPE* m_ChainRightConstraint;
btRigidBody* m_TranslateSpringBody;
btRigidBody* m_TranslateSpringBody2;
btRigidBody* m_RotateSpringBody;
btRigidBody* m_RotateSpringBody2;
btRigidBody* m_BouncingTranslateBody;
btRigidBody* m_MotorBody;
btRigidBody* m_ServoMotorBody;
btRigidBody* m_ChainLeftBody;
btRigidBody* m_ChainRightBody;
CONSTRAINT_TYPE* m_ServoMotorConstraint;
CONSTRAINT_TYPE* m_ChainLeftConstraint;
CONSTRAINT_TYPE* m_ChainRightConstraint;
float mDt;
unsigned int frameID;
Dof6Spring2SetupInternalData()
: mDt(1./60.),frameID(0)
: mDt(1. / 60.), frameID(0)
{
}
};
Dof6Spring2Setup::Dof6Spring2Setup(struct GUIHelperInterface* helper)
:CommonRigidBodyBase(helper)
: CommonRigidBodyBase(helper)
{
m_data = new Dof6Spring2SetupInternalData;
}
@@ -102,392 +94,397 @@ Dof6Spring2Setup::~Dof6Spring2Setup()
void Dof6Spring2Setup::initPhysics()
{
// Setup the basic world
m_guiHelper->setUpAxis(1);
m_collisionConfiguration = new btDefaultCollisionConfiguration();
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
btVector3 worldAabbMin(-10000,-10000,-10000);
btVector3 worldAabbMax(10000,10000,10000);
m_broadphase = new btAxisSweep3 (worldAabbMin, worldAabbMax);
m_collisionConfiguration = new btDefaultCollisionConfiguration();
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
btVector3 worldAabbMin(-10000, -10000, -10000);
btVector3 worldAabbMax(10000, 10000, 10000);
m_broadphase = new btAxisSweep3(worldAabbMin, worldAabbMax);
/////// uncomment the corresponding line to test a solver.
//m_solver = new btSequentialImpulseConstraintSolver;
m_solver = new btNNCGConstraintSolver;
//m_solver = new btMLCPSolver(new btSolveProjectedGaussSeidel());
//m_solver = new btMLCPSolver(new btDantzigSolver());
//m_solver = new btMLCPSolver(new btLemkeSolver());
/////// uncomment the corresponding line to test a solver.
//m_solver = new btSequentialImpulseConstraintSolver;
m_solver = new btNNCGConstraintSolver;
//m_solver = new btMLCPSolver(new btSolveProjectedGaussSeidel());
//m_solver = new btMLCPSolver(new btDantzigSolver());
//m_solver = new btMLCPSolver(new btLemkeSolver());
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
m_dynamicsWorld->getDispatchInfo().m_useContinuous = true;
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration);
m_dynamicsWorld->getDispatchInfo().m_useContinuous = true;
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
m_dynamicsWorld->setGravity(btVector3(0,0,0));
// Setup a big ground box
{
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.),btScalar(5.),btScalar(200.)));
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0,-10,0));
m_dynamicsWorld->setGravity(btVector3(0, 0, 0));
// Setup a big ground box
{
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.), btScalar(5.), btScalar(200.)));
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0, -10, 0));
#define CREATE_GROUND_COLLISION_OBJECT 1
#ifdef CREATE_GROUND_COLLISION_OBJECT
btCollisionObject* fixedGround = new btCollisionObject();
fixedGround->setCollisionShape(groundShape);
fixedGround->setWorldTransform(groundTransform);
m_dynamicsWorld->addCollisionObject(fixedGround);
btCollisionObject* fixedGround = new btCollisionObject();
fixedGround->setCollisionShape(groundShape);
fixedGround->setWorldTransform(groundTransform);
m_dynamicsWorld->addCollisionObject(fixedGround);
#else
localCreateRigidBody(btScalar(0.),groundTransform,groundShape);
#endif //CREATE_GROUND_COLLISION_OBJECT
}
localCreateRigidBody(btScalar(0.), groundTransform, groundShape);
#endif //CREATE_GROUND_COLLISION_OBJECT
}
m_dynamicsWorld->getSolverInfo().m_numIterations = 100;
m_dynamicsWorld->getSolverInfo().m_numIterations = 100;
btCollisionShape* shape;
btVector3 localInertia(0,0,0);
btDefaultMotionState* motionState;
btTransform bodyTransform;
btScalar mass;
btTransform localA;
btTransform localB;
CONSTRAINT_TYPE* constraint;
btCollisionShape* shape;
btVector3 localInertia(0, 0, 0);
btDefaultMotionState* motionState;
btTransform bodyTransform;
btScalar mass;
btTransform localA;
btTransform localB;
CONSTRAINT_TYPE* constraint;
//static body centered in the origo
mass = 0.0;
shape= new btBoxShape(btVector3(0.5,0.5,0.5));
localInertia = btVector3(0,0,0);
//static body centered in the origo
mass = 0.0;
shape = new btBoxShape(btVector3(0.5, 0.5, 0.5));
localInertia = btVector3(0, 0, 0);
bodyTransform.setIdentity();
motionState = new btDefaultMotionState(bodyTransform);
btRigidBody* staticBody = new btRigidBody(mass, motionState, shape, localInertia);
/////////// box with undamped translate spring attached to static body
/////////// the box should oscillate left-to-right forever
{
mass = 1.0;
shape = new btBoxShape(btVector3(0.5, 0.5, 0.5));
shape->calculateLocalInertia(mass, localInertia);
bodyTransform.setIdentity();
bodyTransform.setOrigin(btVector3(-2, 0, -5));
motionState = new btDefaultMotionState(bodyTransform);
btRigidBody* staticBody = new btRigidBody(mass,motionState,shape,localInertia);
/////////// box with undamped translate spring attached to static body
/////////// the box should oscillate left-to-right forever
{
mass = 1.0;
shape= new btBoxShape(btVector3(0.5,0.5,0.5));
shape->calculateLocalInertia(mass,localInertia);
bodyTransform.setIdentity();
bodyTransform.setOrigin(btVector3(-2,0,-5));
motionState = new btDefaultMotionState(bodyTransform);
m_data->m_TranslateSpringBody = new btRigidBody(mass,motionState,shape,localInertia);
m_data->m_TranslateSpringBody->setActivationState(DISABLE_DEACTIVATION);
m_dynamicsWorld->addRigidBody(m_data->m_TranslateSpringBody);
localA.setIdentity();localA.getOrigin() = btVector3(0,0,-5);
localB.setIdentity();
constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_TranslateSpringBody, localA, localB EXTRAPARAMS);
constraint->setLimit(0, 1,-1);
constraint->setLimit(1, 0, 0);
constraint->setLimit(2, 0, 0);
constraint->setLimit(3, 0, 0);
constraint->setLimit(4, 0, 0);
constraint->setLimit(5, 0, 0);
constraint->enableSpring(0, true);
constraint->setStiffness(0, 100);
#ifdef USE_6DOF2
constraint->setDamping(0, 0);
#else
constraint->setDamping(0, 1);
#endif
constraint->setEquilibriumPoint(0, 0);
constraint->setDbgDrawSize(btScalar(2.f));
m_dynamicsWorld->addConstraint(constraint, true);
}
/////////// box with rotate spring, attached to static body
/////////// box should swing (rotate) left-to-right forever
{
mass = 1.0;
shape= new btBoxShape(btVector3(0.5,0.5,0.5));
shape->calculateLocalInertia(mass,localInertia);
bodyTransform.setIdentity();
bodyTransform.getBasis().setEulerZYX(0,0,M_PI_2);
motionState = new btDefaultMotionState(bodyTransform);
m_data->m_RotateSpringBody = new btRigidBody(mass,motionState,shape,localInertia);
m_data->m_RotateSpringBody->setActivationState(DISABLE_DEACTIVATION);
m_dynamicsWorld->addRigidBody(m_data->m_RotateSpringBody);
localA.setIdentity();localA.getOrigin() = btVector3(0,0,0);
localB.setIdentity();localB.setOrigin(btVector3(0,0.5,0));
constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_RotateSpringBody, localA, localB EXTRAPARAMS);
constraint->setLimit(0, 0, 0);
constraint->setLimit(1, 0, 0);
constraint->setLimit(2, 0, 0);
constraint->setLimit(3, 0, 0);
constraint->setLimit(4, 0, 0);
constraint->setLimit(5, 1, -1);
constraint->enableSpring(5, true);
constraint->setStiffness(5, 100);
#ifdef USE_6DOF2
constraint->setDamping(5, 0);
#else
constraint->setDamping(5, 1);
#endif
constraint->setEquilibriumPoint(0, 0);
constraint->setDbgDrawSize(btScalar(2.f));
m_dynamicsWorld->addConstraint(constraint, true);
}
/////////// box with bouncing constraint, translation is bounced at the positive x limit, but not at the negative limit
/////////// bouncing can not be set independently at low and high limits, so two constraints will be created: one that defines the low (non bouncing) limit, and one that defines the high (bouncing) limit
/////////// the box should move to the left (as an impulse will be applied to it periodically) until it reaches its limit, then bounce back
{
mass = 1.0;
shape= new btBoxShape(btVector3(0.5,0.5,0.5));
shape->calculateLocalInertia(mass,localInertia);
bodyTransform.setIdentity();
bodyTransform.setOrigin(btVector3(0,0,-3));
motionState = new btDefaultMotionState(bodyTransform);
m_data->m_BouncingTranslateBody = new btRigidBody(mass,motionState,shape,localInertia);
m_data->m_BouncingTranslateBody->setActivationState(DISABLE_DEACTIVATION);
m_data->m_BouncingTranslateBody->setDeactivationTime(btScalar(20000000));
m_dynamicsWorld->addRigidBody(m_data->m_BouncingTranslateBody);
localA.setIdentity();localA.getOrigin() = btVector3(0,0,0);
localB.setIdentity();
constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_BouncingTranslateBody, localA, localB EXTRAPARAMS);
constraint->setLimit(0, -2, SIMD_INFINITY);
constraint->setLimit(1, 0, 0);
constraint->setLimit(2, -3, -3);
constraint->setLimit(3, 0, 0);
constraint->setLimit(4, 0, 0);
constraint->setLimit(5, 0, 0);
#ifdef USE_6DOF2
constraint->setBounce(0,0);
#else //bounce is named restitution in 6dofspring, but not implemented for translational limit motor, so the following line has no effect
constraint->getTranslationalLimitMotor()->m_restitution = 0.0;
#endif
constraint->setParam(BT_CONSTRAINT_STOP_ERP,0.995,0);
constraint->setParam(BT_CONSTRAINT_STOP_CFM,0.0,0);
constraint->setDbgDrawSize(btScalar(2.f));
m_dynamicsWorld->addConstraint(constraint, true);
constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_BouncingTranslateBody, localA, localB EXTRAPARAMS);
constraint->setLimit(0, -SIMD_INFINITY, 2);
constraint->setLimit(1, 0, 0);
constraint->setLimit(2, -3, -3);
constraint->setLimit(3, 0, 0);
constraint->setLimit(4, 0, 0);
constraint->setLimit(5, 0, 0);
#ifdef USE_6DOF2
constraint->setBounce(0,1);
#else //bounce is named restitution in 6dofspring, but not implemented for translational limit motor, so the following line has no effect
constraint->getTranslationalLimitMotor()->m_restitution = 1.0;
#endif
constraint->setParam(BT_CONSTRAINT_STOP_ERP,0.995,0);
constraint->setParam(BT_CONSTRAINT_STOP_CFM,0.0,0);
constraint->setDbgDrawSize(btScalar(2.f));
m_dynamicsWorld->addConstraint(constraint, true);
}
/////////// box with rotational motor, attached to static body
/////////// the box should rotate around the y axis
{
mass = 1.0;
shape= new btBoxShape(btVector3(0.5,0.5,0.5));
shape->calculateLocalInertia(mass,localInertia);
bodyTransform.setIdentity();
bodyTransform.setOrigin(btVector3(4,0,0));
motionState = new btDefaultMotionState(bodyTransform);
m_data->m_MotorBody = new btRigidBody(mass,motionState,shape,localInertia);
m_data->m_MotorBody->setActivationState(DISABLE_DEACTIVATION);
m_dynamicsWorld->addRigidBody(m_data->m_MotorBody);
localA.setIdentity();localA.getOrigin() = btVector3(4,0,0);
localB.setIdentity();
constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_MotorBody, localA, localB EXTRAPARAMS);
constraint->setLimit(0, 0, 0);
constraint->setLimit(1, 0, 0);
constraint->setLimit(2, 0, 0);
constraint->setLimit(3, 0, 0);
constraint->setLimit(4, 0, 0);
constraint->setLimit(5, 1,-1);
#ifdef USE_6DOF2
constraint->enableMotor(5,true);
constraint->setTargetVelocity(5,3.f);
constraint->setMaxMotorForce(5,600.f);
#else
constraint->getRotationalLimitMotor(2)->m_enableMotor = true;
constraint->getRotationalLimitMotor(2)->m_targetVelocity = 3.f;
constraint->getRotationalLimitMotor(2)->m_maxMotorForce = 600.f;
#endif
constraint->setDbgDrawSize(btScalar(2.f));
m_dynamicsWorld->addConstraint(constraint, true);
}
/////////// box with rotational servo motor, attached to static body
/////////// the box should rotate around the y axis until it reaches its target
/////////// the target will be negated periodically
{
mass = 1.0;
shape= new btBoxShape(btVector3(0.5,0.5,0.5));
shape->calculateLocalInertia(mass,localInertia);
bodyTransform.setIdentity();
bodyTransform.setOrigin(btVector3(7,0,0));
motionState = new btDefaultMotionState(bodyTransform);
m_data->m_ServoMotorBody = new btRigidBody(mass,motionState,shape,localInertia);
m_data->m_ServoMotorBody->setActivationState(DISABLE_DEACTIVATION);
m_dynamicsWorld->addRigidBody(m_data->m_ServoMotorBody);
localA.setIdentity();localA.getOrigin() = btVector3(7,0,0);
localB.setIdentity();
constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_ServoMotorBody, localA, localB EXTRAPARAMS);
constraint->setLimit(0, 0, 0);
constraint->setLimit(1, 0, 0);
constraint->setLimit(2, 0, 0);
constraint->setLimit(3, 0, 0);
constraint->setLimit(4, 0, 0);
constraint->setLimit(5, 1,-1);
#ifdef USE_6DOF2
constraint->enableMotor(5,true);
constraint->setTargetVelocity(5,3.f);
constraint->setMaxMotorForce(5,600.f);
constraint->setServo(5,true);
constraint->setServoTarget(5, M_PI_2);
#else
constraint->getRotationalLimitMotor(2)->m_enableMotor = true;
constraint->getRotationalLimitMotor(2)->m_targetVelocity = 3.f;
constraint->getRotationalLimitMotor(2)->m_maxMotorForce = 600.f;
//servo motor is not implemented in 6dofspring constraint
#endif
constraint->setDbgDrawSize(btScalar(2.f));
m_dynamicsWorld->addConstraint(constraint, true);
m_data->m_ServoMotorConstraint = constraint;
}
////////// chain of boxes linked together with fully limited rotational and translational constraints
////////// the chain will be pulled to the left and to the right periodically. They should strictly stick together.
{
btScalar limitConstraintStrength = 0.6;
int bodycount = 10;
btRigidBody* prevBody = 0;
for(int i = 0; i < bodycount; ++i)
{
mass = 1.0;
shape= new btBoxShape(btVector3(0.5,0.5,0.5));
shape->calculateLocalInertia(mass,localInertia);
bodyTransform.setIdentity();
bodyTransform.setOrigin(btVector3(- i,0,3));
motionState = new btDefaultMotionState(bodyTransform);
btRigidBody* body = new btRigidBody(mass,motionState,shape,localInertia);
body->setActivationState(DISABLE_DEACTIVATION);
m_dynamicsWorld->addRigidBody(body);
if(prevBody != 0)
{
localB.setIdentity();
localB.setOrigin(btVector3(0.5,0,0));
btTransform localA;
localA.setIdentity();
localA.setOrigin(btVector3(-0.5,0,0));
CONSTRAINT_TYPE* constraint = new CONSTRAINT_TYPE(*prevBody, *body, localA, localB EXTRAPARAMS);
constraint->setLimit(0, -0.01, 0.01);
constraint->setLimit(1, 0, 0);
constraint->setLimit(2, 0, 0);
constraint->setLimit(3, 0, 0);
constraint->setLimit(4, 0, 0);
constraint->setLimit(5, 0, 0);
for(int a = 0; a < 6; ++a)
{
constraint->setParam(BT_CONSTRAINT_STOP_ERP,0.9,a);
constraint->setParam(BT_CONSTRAINT_STOP_CFM,0.0,a);
}
constraint->setDbgDrawSize(btScalar(1.f));
m_dynamicsWorld->addConstraint(constraint, true);
if(i < bodycount - 1)
{
localA.setIdentity();localA.getOrigin() = btVector3(0,0,3);
localB.setIdentity();
CONSTRAINT_TYPE* constraintZY = new CONSTRAINT_TYPE(*staticBody, *body, localA, localB EXTRAPARAMS);
constraintZY->setLimit(0, 1, -1);
constraintZY->setDbgDrawSize(btScalar(1.f));
m_dynamicsWorld->addConstraint(constraintZY, true);
}
}
else
{
localA.setIdentity();localA.getOrigin() = btVector3(bodycount,0,3);
localB.setIdentity();
localB.setOrigin(btVector3(0,0,0));
m_data->m_ChainLeftBody = body;
m_data->m_ChainLeftConstraint = new CONSTRAINT_TYPE(*staticBody, *body, localA, localB EXTRAPARAMS);
m_data->m_ChainLeftConstraint->setLimit(3,0,0);
m_data->m_ChainLeftConstraint->setLimit(4,0,0);
m_data->m_ChainLeftConstraint->setLimit(5,0,0);
for(int a = 0; a < 6; ++a)
{
m_data->m_ChainLeftConstraint->setParam(BT_CONSTRAINT_STOP_ERP,limitConstraintStrength,a);
m_data->m_ChainLeftConstraint->setParam(BT_CONSTRAINT_STOP_CFM,0.0,a);
}
m_data->m_ChainLeftConstraint->setDbgDrawSize(btScalar(1.f));
m_dynamicsWorld->addConstraint(m_data->m_ChainLeftConstraint, true);
}
prevBody = body;
}
m_data->m_ChainRightBody = prevBody;
localA.setIdentity();localA.getOrigin() = btVector3(-bodycount,0,3);
localB.setIdentity();
localB.setOrigin(btVector3(0,0,0));
m_data->m_ChainRightConstraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_ChainRightBody, localA, localB EXTRAPARAMS);
m_data->m_ChainRightConstraint->setLimit(3,0,0);
m_data->m_ChainRightConstraint->setLimit(4,0,0);
m_data->m_ChainRightConstraint->setLimit(5,0,0);
for(int a = 0; a < 6; ++a)
{
m_data->m_ChainRightConstraint->setParam(BT_CONSTRAINT_STOP_ERP,limitConstraintStrength,a);
m_data->m_ChainRightConstraint->setParam(BT_CONSTRAINT_STOP_CFM,0.0,a);
}
}
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void Dof6Spring2Setup::animate()
{
/////// servo motor: flip its target periodically
m_data->m_TranslateSpringBody = new btRigidBody(mass, motionState, shape, localInertia);
m_data->m_TranslateSpringBody->setActivationState(DISABLE_DEACTIVATION);
m_dynamicsWorld->addRigidBody(m_data->m_TranslateSpringBody);
localA.setIdentity();
localA.getOrigin() = btVector3(0, 0, -5);
localB.setIdentity();
constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_TranslateSpringBody, localA, localB EXTRAPARAMS);
constraint->setLimit(0, 1, -1);
constraint->setLimit(1, 0, 0);
constraint->setLimit(2, 0, 0);
constraint->setLimit(3, 0, 0);
constraint->setLimit(4, 0, 0);
constraint->setLimit(5, 0, 0);
constraint->enableSpring(0, true);
constraint->setStiffness(0, 100);
#ifdef USE_6DOF2
static float servoNextFrame = -1;
if(servoNextFrame < 0)
{
m_data->m_ServoMotorConstraint->getRotationalLimitMotor(2)->m_servoTarget *= -1;
servoNextFrame = 3.0;
}
servoNextFrame -= m_data->mDt;
constraint->setDamping(0, 0);
#else
constraint->setDamping(0, 1);
#endif
constraint->setEquilibriumPoint(0, 0);
constraint->setDbgDrawSize(btScalar(2.f));
m_dynamicsWorld->addConstraint(constraint, true);
}
/////// constraint chain: pull the chain left and right periodically
static float chainNextFrame = -1;
static bool left = true;
if(chainNextFrame < 0)
/////////// box with rotate spring, attached to static body
/////////// box should swing (rotate) left-to-right forever
{
mass = 1.0;
shape = new btBoxShape(btVector3(0.5, 0.5, 0.5));
shape->calculateLocalInertia(mass, localInertia);
bodyTransform.setIdentity();
bodyTransform.getBasis().setEulerZYX(0, 0, M_PI_2);
motionState = new btDefaultMotionState(bodyTransform);
m_data->m_RotateSpringBody = new btRigidBody(mass, motionState, shape, localInertia);
m_data->m_RotateSpringBody->setActivationState(DISABLE_DEACTIVATION);
m_dynamicsWorld->addRigidBody(m_data->m_RotateSpringBody);
localA.setIdentity();
localA.getOrigin() = btVector3(0, 0, 0);
localB.setIdentity();
localB.setOrigin(btVector3(0, 0.5, 0));
constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_RotateSpringBody, localA, localB EXTRAPARAMS);
constraint->setLimit(0, 0, 0);
constraint->setLimit(1, 0, 0);
constraint->setLimit(2, 0, 0);
constraint->setLimit(3, 0, 0);
constraint->setLimit(4, 0, 0);
constraint->setLimit(5, 1, -1);
constraint->enableSpring(5, true);
constraint->setStiffness(5, 100);
#ifdef USE_6DOF2
constraint->setDamping(5, 0);
#else
constraint->setDamping(5, 1);
#endif
constraint->setEquilibriumPoint(0, 0);
constraint->setDbgDrawSize(btScalar(2.f));
m_dynamicsWorld->addConstraint(constraint, true);
}
/////////// box with bouncing constraint, translation is bounced at the positive x limit, but not at the negative limit
/////////// bouncing can not be set independently at low and high limits, so two constraints will be created: one that defines the low (non bouncing) limit, and one that defines the high (bouncing) limit
/////////// the box should move to the left (as an impulse will be applied to it periodically) until it reaches its limit, then bounce back
{
mass = 1.0;
shape = new btBoxShape(btVector3(0.5, 0.5, 0.5));
shape->calculateLocalInertia(mass, localInertia);
bodyTransform.setIdentity();
bodyTransform.setOrigin(btVector3(0, 0, -3));
motionState = new btDefaultMotionState(bodyTransform);
m_data->m_BouncingTranslateBody = new btRigidBody(mass, motionState, shape, localInertia);
m_data->m_BouncingTranslateBody->setActivationState(DISABLE_DEACTIVATION);
m_data->m_BouncingTranslateBody->setDeactivationTime(btScalar(20000000));
m_dynamicsWorld->addRigidBody(m_data->m_BouncingTranslateBody);
localA.setIdentity();
localA.getOrigin() = btVector3(0, 0, 0);
localB.setIdentity();
constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_BouncingTranslateBody, localA, localB EXTRAPARAMS);
constraint->setLimit(0, -2, SIMD_INFINITY);
constraint->setLimit(1, 0, 0);
constraint->setLimit(2, -3, -3);
constraint->setLimit(3, 0, 0);
constraint->setLimit(4, 0, 0);
constraint->setLimit(5, 0, 0);
#ifdef USE_6DOF2
constraint->setBounce(0, 0);
#else //bounce is named restitution in 6dofspring, but not implemented for translational limit motor, so the following line has no effect
constraint->getTranslationalLimitMotor()->m_restitution = 0.0;
#endif
constraint->setParam(BT_CONSTRAINT_STOP_ERP, 0.995, 0);
constraint->setParam(BT_CONSTRAINT_STOP_CFM, 0.0, 0);
constraint->setDbgDrawSize(btScalar(2.f));
m_dynamicsWorld->addConstraint(constraint, true);
constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_BouncingTranslateBody, localA, localB EXTRAPARAMS);
constraint->setLimit(0, -SIMD_INFINITY, 2);
constraint->setLimit(1, 0, 0);
constraint->setLimit(2, -3, -3);
constraint->setLimit(3, 0, 0);
constraint->setLimit(4, 0, 0);
constraint->setLimit(5, 0, 0);
#ifdef USE_6DOF2
constraint->setBounce(0, 1);
#else //bounce is named restitution in 6dofspring, but not implemented for translational limit motor, so the following line has no effect
constraint->getTranslationalLimitMotor()->m_restitution = 1.0;
#endif
constraint->setParam(BT_CONSTRAINT_STOP_ERP, 0.995, 0);
constraint->setParam(BT_CONSTRAINT_STOP_CFM, 0.0, 0);
constraint->setDbgDrawSize(btScalar(2.f));
m_dynamicsWorld->addConstraint(constraint, true);
}
/////////// box with rotational motor, attached to static body
/////////// the box should rotate around the y axis
{
mass = 1.0;
shape = new btBoxShape(btVector3(0.5, 0.5, 0.5));
shape->calculateLocalInertia(mass, localInertia);
bodyTransform.setIdentity();
bodyTransform.setOrigin(btVector3(4, 0, 0));
motionState = new btDefaultMotionState(bodyTransform);
m_data->m_MotorBody = new btRigidBody(mass, motionState, shape, localInertia);
m_data->m_MotorBody->setActivationState(DISABLE_DEACTIVATION);
m_dynamicsWorld->addRigidBody(m_data->m_MotorBody);
localA.setIdentity();
localA.getOrigin() = btVector3(4, 0, 0);
localB.setIdentity();
constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_MotorBody, localA, localB EXTRAPARAMS);
constraint->setLimit(0, 0, 0);
constraint->setLimit(1, 0, 0);
constraint->setLimit(2, 0, 0);
constraint->setLimit(3, 0, 0);
constraint->setLimit(4, 0, 0);
constraint->setLimit(5, 1, -1);
#ifdef USE_6DOF2
constraint->enableMotor(5, true);
constraint->setTargetVelocity(5, 3.f);
constraint->setMaxMotorForce(5, 600.f);
#else
constraint->getRotationalLimitMotor(2)->m_enableMotor = true;
constraint->getRotationalLimitMotor(2)->m_targetVelocity = 3.f;
constraint->getRotationalLimitMotor(2)->m_maxMotorForce = 600.f;
#endif
constraint->setDbgDrawSize(btScalar(2.f));
m_dynamicsWorld->addConstraint(constraint, true);
}
/////////// box with rotational servo motor, attached to static body
/////////// the box should rotate around the y axis until it reaches its target
/////////// the target will be negated periodically
{
mass = 1.0;
shape = new btBoxShape(btVector3(0.5, 0.5, 0.5));
shape->calculateLocalInertia(mass, localInertia);
bodyTransform.setIdentity();
bodyTransform.setOrigin(btVector3(7, 0, 0));
motionState = new btDefaultMotionState(bodyTransform);
m_data->m_ServoMotorBody = new btRigidBody(mass, motionState, shape, localInertia);
m_data->m_ServoMotorBody->setActivationState(DISABLE_DEACTIVATION);
m_dynamicsWorld->addRigidBody(m_data->m_ServoMotorBody);
localA.setIdentity();
localA.getOrigin() = btVector3(7, 0, 0);
localB.setIdentity();
constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_ServoMotorBody, localA, localB EXTRAPARAMS);
constraint->setLimit(0, 0, 0);
constraint->setLimit(1, 0, 0);
constraint->setLimit(2, 0, 0);
constraint->setLimit(3, 0, 0);
constraint->setLimit(4, 0, 0);
constraint->setLimit(5, 1, -1);
#ifdef USE_6DOF2
constraint->enableMotor(5, true);
constraint->setTargetVelocity(5, 3.f);
constraint->setMaxMotorForce(5, 600.f);
constraint->setServo(5, true);
constraint->setServoTarget(5, M_PI_2);
#else
constraint->getRotationalLimitMotor(2)->m_enableMotor = true;
constraint->getRotationalLimitMotor(2)->m_targetVelocity = 3.f;
constraint->getRotationalLimitMotor(2)->m_maxMotorForce = 600.f;
//servo motor is not implemented in 6dofspring constraint
#endif
constraint->setDbgDrawSize(btScalar(2.f));
m_dynamicsWorld->addConstraint(constraint, true);
m_data->m_ServoMotorConstraint = constraint;
}
////////// chain of boxes linked together with fully limited rotational and translational constraints
////////// the chain will be pulled to the left and to the right periodically. They should strictly stick together.
{
btScalar limitConstraintStrength = 0.6;
int bodycount = 10;
btRigidBody* prevBody = 0;
for (int i = 0; i < bodycount; ++i)
{
if(!left)
mass = 1.0;
shape = new btBoxShape(btVector3(0.5, 0.5, 0.5));
shape->calculateLocalInertia(mass, localInertia);
bodyTransform.setIdentity();
bodyTransform.setOrigin(btVector3(-i, 0, 3));
motionState = new btDefaultMotionState(bodyTransform);
btRigidBody* body = new btRigidBody(mass, motionState, shape, localInertia);
body->setActivationState(DISABLE_DEACTIVATION);
m_dynamicsWorld->addRigidBody(body);
if (prevBody != 0)
{
m_data->m_ChainRightBody->setActivationState(ACTIVE_TAG);
m_dynamicsWorld->removeConstraint(m_data->m_ChainRightConstraint);
m_data->m_ChainLeftConstraint->setDbgDrawSize(btScalar(2.f));
m_dynamicsWorld->addConstraint(m_data->m_ChainLeftConstraint, true);
localB.setIdentity();
localB.setOrigin(btVector3(0.5, 0, 0));
btTransform localA;
localA.setIdentity();
localA.setOrigin(btVector3(-0.5, 0, 0));
CONSTRAINT_TYPE* constraint = new CONSTRAINT_TYPE(*prevBody, *body, localA, localB EXTRAPARAMS);
constraint->setLimit(0, -0.01, 0.01);
constraint->setLimit(1, 0, 0);
constraint->setLimit(2, 0, 0);
constraint->setLimit(3, 0, 0);
constraint->setLimit(4, 0, 0);
constraint->setLimit(5, 0, 0);
for (int a = 0; a < 6; ++a)
{
constraint->setParam(BT_CONSTRAINT_STOP_ERP, 0.9, a);
constraint->setParam(BT_CONSTRAINT_STOP_CFM, 0.0, a);
}
constraint->setDbgDrawSize(btScalar(1.f));
m_dynamicsWorld->addConstraint(constraint, true);
if (i < bodycount - 1)
{
localA.setIdentity();
localA.getOrigin() = btVector3(0, 0, 3);
localB.setIdentity();
CONSTRAINT_TYPE* constraintZY = new CONSTRAINT_TYPE(*staticBody, *body, localA, localB EXTRAPARAMS);
constraintZY->setLimit(0, 1, -1);
constraintZY->setDbgDrawSize(btScalar(1.f));
m_dynamicsWorld->addConstraint(constraintZY, true);
}
}
else
{
m_data->m_ChainLeftBody->setActivationState(ACTIVE_TAG);
m_dynamicsWorld->removeConstraint(m_data->m_ChainLeftConstraint);
m_data->m_ChainRightConstraint->setDbgDrawSize(btScalar(2.f));
m_dynamicsWorld->addConstraint(m_data->m_ChainRightConstraint, true);
localA.setIdentity();
localA.getOrigin() = btVector3(bodycount, 0, 3);
localB.setIdentity();
localB.setOrigin(btVector3(0, 0, 0));
m_data->m_ChainLeftBody = body;
m_data->m_ChainLeftConstraint = new CONSTRAINT_TYPE(*staticBody, *body, localA, localB EXTRAPARAMS);
m_data->m_ChainLeftConstraint->setLimit(3, 0, 0);
m_data->m_ChainLeftConstraint->setLimit(4, 0, 0);
m_data->m_ChainLeftConstraint->setLimit(5, 0, 0);
for (int a = 0; a < 6; ++a)
{
m_data->m_ChainLeftConstraint->setParam(BT_CONSTRAINT_STOP_ERP, limitConstraintStrength, a);
m_data->m_ChainLeftConstraint->setParam(BT_CONSTRAINT_STOP_CFM, 0.0, a);
}
m_data->m_ChainLeftConstraint->setDbgDrawSize(btScalar(1.f));
m_dynamicsWorld->addConstraint(m_data->m_ChainLeftConstraint, true);
}
chainNextFrame = 3.0;
left = !left;
prevBody = body;
}
chainNextFrame -= m_data->mDt;
/////// bouncing constraint: push the box periodically
m_data->m_BouncingTranslateBody->setActivationState(ACTIVE_TAG);
static float bounceNextFrame = -1;
if(bounceNextFrame < 0)
m_data->m_ChainRightBody = prevBody;
localA.setIdentity();
localA.getOrigin() = btVector3(-bodycount, 0, 3);
localB.setIdentity();
localB.setOrigin(btVector3(0, 0, 0));
m_data->m_ChainRightConstraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_ChainRightBody, localA, localB EXTRAPARAMS);
m_data->m_ChainRightConstraint->setLimit(3, 0, 0);
m_data->m_ChainRightConstraint->setLimit(4, 0, 0);
m_data->m_ChainRightConstraint->setLimit(5, 0, 0);
for (int a = 0; a < 6; ++a)
{
m_data->m_BouncingTranslateBody->applyCentralImpulse(btVector3(10,0,0));
bounceNextFrame = 3.0;
m_data->m_ChainRightConstraint->setParam(BT_CONSTRAINT_STOP_ERP, limitConstraintStrength, a);
m_data->m_ChainRightConstraint->setParam(BT_CONSTRAINT_STOP_CFM, 0.0, a);
}
bounceNextFrame -= m_data->mDt;
m_data->frameID++;
}
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void Dof6Spring2Setup::animate()
{
/////// servo motor: flip its target periodically
#ifdef USE_6DOF2
static float servoNextFrame = -1;
if (servoNextFrame < 0)
{
m_data->m_ServoMotorConstraint->getRotationalLimitMotor(2)->m_servoTarget *= -1;
servoNextFrame = 3.0;
}
servoNextFrame -= m_data->mDt;
#endif
/////// constraint chain: pull the chain left and right periodically
static float chainNextFrame = -1;
static bool left = true;
if (chainNextFrame < 0)
{
if (!left)
{
m_data->m_ChainRightBody->setActivationState(ACTIVE_TAG);
m_dynamicsWorld->removeConstraint(m_data->m_ChainRightConstraint);
m_data->m_ChainLeftConstraint->setDbgDrawSize(btScalar(2.f));
m_dynamicsWorld->addConstraint(m_data->m_ChainLeftConstraint, true);
}
else
{
m_data->m_ChainLeftBody->setActivationState(ACTIVE_TAG);
m_dynamicsWorld->removeConstraint(m_data->m_ChainLeftConstraint);
m_data->m_ChainRightConstraint->setDbgDrawSize(btScalar(2.f));
m_dynamicsWorld->addConstraint(m_data->m_ChainRightConstraint, true);
}
chainNextFrame = 3.0;
left = !left;
}
chainNextFrame -= m_data->mDt;
/////// bouncing constraint: push the box periodically
m_data->m_BouncingTranslateBody->setActivationState(ACTIVE_TAG);
static float bounceNextFrame = -1;
if (bounceNextFrame < 0)
{
m_data->m_BouncingTranslateBody->applyCentralImpulse(btVector3(10, 0, 0));
bounceNextFrame = 3.0;
}
bounceNextFrame -= m_data->mDt;
m_data->frameID++;
}
void Dof6Spring2Setup::stepSimulation(float deltaTime)
{
@@ -495,7 +492,7 @@ void Dof6Spring2Setup::stepSimulation(float deltaTime)
m_dynamicsWorld->stepSimulation(deltaTime);
}
class CommonExampleInterface* Dof6Spring2CreateFunc( CommonExampleOptions& options)
class CommonExampleInterface* Dof6Spring2CreateFunc(CommonExampleOptions& options)
{
return new Dof6Spring2Setup(options.m_guiHelper);
}

View File

@@ -1,6 +1,6 @@
#ifndef GENERIC_6DOF_SPRING2_CONSTRAINT_DEMO_H
#define GENERIC_6DOF_SPRING2_CONSTRAINT_DEMO_H
class CommonExampleInterface* Dof6Spring2CreateFunc(struct CommonExampleOptions& options);
class CommonExampleInterface* Dof6Spring2CreateFunc(struct CommonExampleOptions& options);
#endif //GENERIC_6DOF_SPRING2_CONSTRAINT_DEMO_H
#endif //GENERIC_6DOF_SPRING2_CONSTRAINT_DEMO_H

View File

@@ -1,6 +1,5 @@
#include "TestHingeTorque.h"
#include "../CommonInterfaces/CommonRigidBodyBase.h"
#include "../CommonInterfaces/CommonParameterInterface.h"
@@ -10,99 +9,88 @@ static btScalar radius(0.2);
struct TestHingeTorque : public CommonRigidBodyBase
{
bool m_once;
btAlignedObjectArray<btJointFeedback*> m_jointFeedback;
bool m_once;
btAlignedObjectArray<btJointFeedback*> m_jointFeedback;
TestHingeTorque(struct GUIHelperInterface* helper);
virtual ~ TestHingeTorque();
virtual ~TestHingeTorque();
virtual void initPhysics();
virtual void stepSimulation(float deltaTime);
virtual void resetCamera()
{
float dist = 5;
float pitch = -21;
float yaw = 270;
float targetPos[3]={-1.34,3.4,-0.44};
m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]);
float dist = 5;
float pitch = -21;
float yaw = 270;
float targetPos[3] = {-1.34, 3.4, -0.44};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
};
TestHingeTorque::TestHingeTorque(struct GUIHelperInterface* helper)
:CommonRigidBodyBase(helper),
m_once(true)
: CommonRigidBodyBase(helper),
m_once(true)
{
}
TestHingeTorque::~ TestHingeTorque()
TestHingeTorque::~TestHingeTorque()
{
for (int i=0;i<m_jointFeedback.size();i++)
for (int i = 0; i < m_jointFeedback.size(); i++)
{
delete m_jointFeedback[i];
}
}
void TestHingeTorque::stepSimulation(float deltaTime)
{
if (0)//m_once)
{
m_once=false;
btHingeConstraint* hinge = (btHingeConstraint*)m_dynamicsWorld->getConstraint(0);
btRigidBody& bodyA = hinge->getRigidBodyA();
btTransform trA = bodyA.getWorldTransform();
btVector3 hingeAxisInWorld = trA.getBasis()*hinge->getFrameOffsetA().getBasis().getColumn(2);
hinge->getRigidBodyA().applyTorque(-hingeAxisInWorld*10);
hinge->getRigidBodyB().applyTorque(hingeAxisInWorld*10);
}
m_dynamicsWorld->stepSimulation(1./240,0);
if (0) //m_once)
{
m_once = false;
btHingeConstraint* hinge = (btHingeConstraint*)m_dynamicsWorld->getConstraint(0);
btRigidBody& bodyA = hinge->getRigidBodyA();
btTransform trA = bodyA.getWorldTransform();
btVector3 hingeAxisInWorld = trA.getBasis() * hinge->getFrameOffsetA().getBasis().getColumn(2);
hinge->getRigidBodyA().applyTorque(-hingeAxisInWorld * 10);
hinge->getRigidBodyB().applyTorque(hingeAxisInWorld * 10);
}
m_dynamicsWorld->stepSimulation(1. / 240, 0);
static int count = 0;
if ((count& 0x0f)==0)
if ((count & 0x0f) == 0)
{
btRigidBody* base = btRigidBody::upcast(m_dynamicsWorld->getCollisionObjectArray()[0]);
b3Printf("base angvel = %f,%f,%f",base->getAngularVelocity()[0],
b3Printf("base angvel = %f,%f,%f", base->getAngularVelocity()[0],
base->getAngularVelocity()[1],
base->getAngularVelocity()[2]);
btRigidBody* child = btRigidBody::upcast(m_dynamicsWorld->getCollisionObjectArray()[1]);
b3Printf("child angvel = %f,%f,%f",child->getAngularVelocity()[0],
b3Printf("child angvel = %f,%f,%f", child->getAngularVelocity()[0],
child->getAngularVelocity()[1],
child->getAngularVelocity()[2]);
for (int i=0;i<m_jointFeedback.size();i++)
for (int i = 0; i < m_jointFeedback.size(); i++)
{
b3Printf("Applied force at the COM/Inertial frame B[%d]:(%f,%f,%f), torque B:(%f,%f,%f)\n", i,
m_jointFeedback[i]->m_appliedForceBodyB.x(),
m_jointFeedback[i]->m_appliedForceBodyB.y(),
m_jointFeedback[i]->m_appliedForceBodyB.z(),
m_jointFeedback[i]->m_appliedTorqueBodyB.x(),
m_jointFeedback[i]->m_appliedTorqueBodyB.y(),
m_jointFeedback[i]->m_appliedTorqueBodyB.z());
m_jointFeedback[i]->m_appliedForceBodyB.x(),
m_jointFeedback[i]->m_appliedForceBodyB.y(),
m_jointFeedback[i]->m_appliedForceBodyB.z(),
m_jointFeedback[i]->m_appliedTorqueBodyB.x(),
m_jointFeedback[i]->m_appliedTorqueBodyB.y(),
m_jointFeedback[i]->m_appliedTorqueBodyB.z());
}
}
count++;
//CommonRigidBodyBase::stepSimulation(deltaTime);
//CommonRigidBodyBase::stepSimulation(deltaTime);
}
void TestHingeTorque::initPhysics()
{
int upAxis = 1;
@@ -110,92 +98,89 @@ void TestHingeTorque::initPhysics()
createEmptyDynamicsWorld();
m_dynamicsWorld->getSolverInfo().m_splitImpulse = false;
m_dynamicsWorld->setGravity(btVector3(0,0,-10));
m_dynamicsWorld->setGravity(btVector3(0, 0, -10));
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
int mode = btIDebugDraw::DBG_DrawWireframe
+btIDebugDraw::DBG_DrawConstraints
+btIDebugDraw::DBG_DrawConstraintLimits;
int mode = btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawConstraints + btIDebugDraw::DBG_DrawConstraintLimits;
m_dynamicsWorld->getDebugDrawer()->setDebugMode(mode);
{ // create a door using hinge constraint attached to the world
{ // create a door using hinge constraint attached to the world
int numLinks = 2;
// bool selfCollide = false;
btVector3 linkHalfExtents(0.05, 0.37, 0.1);
btVector3 baseHalfExtents(0.05, 0.37, 0.1);
int numLinks = 2;
// bool selfCollide = false;
btVector3 linkHalfExtents(0.05, 0.37, 0.1);
btVector3 baseHalfExtents(0.05, 0.37, 0.1);
btBoxShape* baseBox = new btBoxShape(baseHalfExtents);
btVector3 basePosition = btVector3(-0.4f, 3.f, 0.f);
btTransform baseWorldTrans;
baseWorldTrans.setIdentity();
baseWorldTrans.setOrigin(basePosition);
//mbC->forceMultiDof(); //if !spherical, you can comment this line to check the 1DoF algorithm
//init the base
btVector3 baseInertiaDiag(0.f, 0.f, 0.f);
float baseMass = 0.f;
float linkMass = 1.f;
btRigidBody* base = createRigidBody(baseMass,baseWorldTrans,baseBox);
m_dynamicsWorld->removeRigidBody(base);
base->setDamping(0,0);
m_dynamicsWorld->addRigidBody(base,collisionFilterGroup,collisionFilterMask);
btBoxShape* linkBox1 = new btBoxShape(linkHalfExtents);
btBoxShape* baseBox = new btBoxShape(baseHalfExtents);
btVector3 basePosition = btVector3(-0.4f, 3.f, 0.f);
btTransform baseWorldTrans;
baseWorldTrans.setIdentity();
baseWorldTrans.setOrigin(basePosition);
//mbC->forceMultiDof(); //if !spherical, you can comment this line to check the 1DoF algorithm
//init the base
btVector3 baseInertiaDiag(0.f, 0.f, 0.f);
float baseMass = 0.f;
float linkMass = 1.f;
btRigidBody* base = createRigidBody(baseMass, baseWorldTrans, baseBox);
m_dynamicsWorld->removeRigidBody(base);
base->setDamping(0, 0);
m_dynamicsWorld->addRigidBody(base, collisionFilterGroup, collisionFilterMask);
btBoxShape* linkBox1 = new btBoxShape(linkHalfExtents);
btSphereShape* linkSphere = new btSphereShape(radius);
btRigidBody* prevBody = base;
for (int i=0;i<numLinks;i++)
{
btTransform linkTrans;
linkTrans = baseWorldTrans;
linkTrans.setOrigin(basePosition-btVector3(0,linkHalfExtents[1]*2.f*(i+1),0));
btRigidBody* prevBody = base;
for (int i = 0; i < numLinks; i++)
{
btTransform linkTrans;
linkTrans = baseWorldTrans;
linkTrans.setOrigin(basePosition - btVector3(0, linkHalfExtents[1] * 2.f * (i + 1), 0));
btCollisionShape* colOb = 0;
if (i==0)
if (i == 0)
{
colOb = linkBox1;
} else
}
else
{
colOb = linkSphere;
}
btRigidBody* linkBody = createRigidBody(linkMass,linkTrans,colOb);
m_dynamicsWorld->removeRigidBody(linkBody);
m_dynamicsWorld->addRigidBody(linkBody,collisionFilterGroup,collisionFilterMask);
linkBody->setDamping(0,0);
btRigidBody* linkBody = createRigidBody(linkMass, linkTrans, colOb);
m_dynamicsWorld->removeRigidBody(linkBody);
m_dynamicsWorld->addRigidBody(linkBody, collisionFilterGroup, collisionFilterMask);
linkBody->setDamping(0, 0);
btTypedConstraint* con = 0;
if (i==0)
if (i == 0)
{
//create a hinge constraint
btVector3 pivotInA(0,-linkHalfExtents[1],0);
btVector3 pivotInB(0,linkHalfExtents[1],0);
btVector3 axisInA(1,0,0);
btVector3 axisInB(1,0,0);
btVector3 pivotInA(0, -linkHalfExtents[1], 0);
btVector3 pivotInB(0, linkHalfExtents[1], 0);
btVector3 axisInA(1, 0, 0);
btVector3 axisInB(1, 0, 0);
bool useReferenceA = true;
btHingeConstraint* hinge = new btHingeConstraint(*prevBody,*linkBody,
pivotInA,pivotInB,
axisInA,axisInB,useReferenceA);
btHingeConstraint* hinge = new btHingeConstraint(*prevBody, *linkBody,
pivotInA, pivotInB,
axisInA, axisInB, useReferenceA);
con = hinge;
} else
}
else
{
btTransform pivotInA(btQuaternion::getIdentity(),btVector3(0, -radius, 0)); //par body's COM to cur body's COM offset
btTransform pivotInB(btQuaternion::getIdentity(),btVector3(0, radius, 0)); //cur body's COM to cur body's PIV offset
btTransform pivotInA(btQuaternion::getIdentity(), btVector3(0, -radius, 0)); //par body's COM to cur body's COM offset
btTransform pivotInB(btQuaternion::getIdentity(), btVector3(0, radius, 0)); //cur body's COM to cur body's PIV offset
btGeneric6DofSpring2Constraint* fixed = new btGeneric6DofSpring2Constraint(*prevBody, *linkBody,
pivotInA,pivotInB);
fixed->setLinearLowerLimit(btVector3(0,0,0));
fixed->setLinearUpperLimit(btVector3(0,0,0));
fixed->setAngularLowerLimit(btVector3(0,0,0));
fixed->setAngularUpperLimit(btVector3(0,0,0));
con = fixed;
pivotInA, pivotInB);
fixed->setLinearLowerLimit(btVector3(0, 0, 0));
fixed->setLinearUpperLimit(btVector3(0, 0, 0));
fixed->setAngularLowerLimit(btVector3(0, 0, 0));
fixed->setAngularUpperLimit(btVector3(0, 0, 0));
con = fixed;
}
btAssert(con);
if (con)
@@ -204,38 +189,36 @@ void TestHingeTorque::initPhysics()
m_jointFeedback.push_back(fb);
con->setJointFeedback(fb);
m_dynamicsWorld->addConstraint(con,true);
m_dynamicsWorld->addConstraint(con, true);
}
prevBody = linkBody;
}
}
}
if (1)
{
btVector3 groundHalfExtents(1,1,0.2);
groundHalfExtents[upAxis]=1.f;
btVector3 groundHalfExtents(1, 1, 0.2);
groundHalfExtents[upAxis] = 1.f;
btBoxShape* box = new btBoxShape(groundHalfExtents);
box->initializePolyhedralFeatures();
btTransform start; start.setIdentity();
btTransform start;
start.setIdentity();
btVector3 groundOrigin(-0.4f, 3.f, 0.f);
// btVector3 basePosition = btVector3(-0.4f, 3.f, 0.f);
btQuaternion groundOrn(btVector3(0,1,0),0.25*SIMD_PI);
groundOrigin[upAxis] -=.5;
groundOrigin[2]-=0.6;
// btVector3 basePosition = btVector3(-0.4f, 3.f, 0.f);
btQuaternion groundOrn(btVector3(0, 1, 0), 0.25 * SIMD_PI);
groundOrigin[upAxis] -= .5;
groundOrigin[2] -= 0.6;
start.setOrigin(groundOrigin);
// start.setRotation(groundOrn);
btRigidBody* body = createRigidBody(0,start,box);
// start.setRotation(groundOrn);
btRigidBody* body = createRigidBody(0, start, box);
body->setFriction(0);
}
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
class CommonExampleInterface* TestHingeTorqueCreateFunc(CommonExampleOptions& options)
class CommonExampleInterface* TestHingeTorqueCreateFunc(CommonExampleOptions& options)
{
return new TestHingeTorque(options.m_guiHelper);
}

View File

@@ -1,7 +1,6 @@
#ifndef TEST_HINGE_TORQUE_H
#define TEST_HINGE_TORQUE_H
class CommonExampleInterface* TestHingeTorqueCreateFunc(struct CommonExampleOptions& options);
#endif //TEST_HINGE_TORQUE_H
class CommonExampleInterface* TestHingeTorqueCreateFunc(struct CommonExampleOptions& options);
#endif //TEST_HINGE_TORQUE_H

View File

@@ -13,13 +13,11 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#include "btBulletDynamicsCommon.h"
#include "LinearMath/btIDebugDraw.h"
#include "MotorDemo.h"
#include "LinearMath/btAlignedObjectArray.h"
class btBroadphaseInterface;
class btCollisionShape;
@@ -34,85 +32,80 @@ class btDefaultCollisionConfiguration;
class MotorDemo : public CommonRigidBodyBase
{
float m_Time;
float m_fCyclePeriod; // in milliseconds
float m_fCyclePeriod; // in milliseconds
float m_fMuscleStrength;
btAlignedObjectArray<class TestRig*> m_rigs;
public:
MotorDemo(struct GUIHelperInterface* helper)
:CommonRigidBodyBase(helper)
: CommonRigidBodyBase(helper)
{
}
void initPhysics();
void exitPhysics();
virtual ~MotorDemo()
{
}
void spawnTestRig(const btVector3& startOffset, bool bFixed);
// virtual void keyboardCallback(unsigned char key, int x, int y);
// virtual void keyboardCallback(unsigned char key, int x, int y);
void setMotorTargets(btScalar deltaTime);
void resetCamera()
{
float dist = 11;
float pitch = -35;
float yaw = 52;
float targetPos[3]={0,0.46,0};
m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]);
float targetPos[3] = {0, 0.46, 0};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
};
#ifndef M_PI
#define M_PI 3.14159265358979323846
#define M_PI 3.14159265358979323846
#endif
#ifndef M_PI_2
#define M_PI_2 1.57079632679489661923
#define M_PI_2 1.57079632679489661923
#endif
#ifndef M_PI_4
#define M_PI_4 0.785398163397448309616
#define M_PI_4 0.785398163397448309616
#endif
#ifndef M_PI_8
#define M_PI_8 0.5 * M_PI_4
#define M_PI_8 0.5 * M_PI_4
#endif
// /LOCAL FUNCTIONS
#define NUM_LEGS 6
#define BODYPART_COUNT 2 * NUM_LEGS + 1
#define JOINT_COUNT BODYPART_COUNT - 1
class TestRig
{
btDynamicsWorld* m_ownerWorld;
btCollisionShape* m_shapes[BODYPART_COUNT];
btRigidBody* m_bodies[BODYPART_COUNT];
btTypedConstraint* m_joints[JOINT_COUNT];
btDynamicsWorld* m_ownerWorld;
btCollisionShape* m_shapes[BODYPART_COUNT];
btRigidBody* m_bodies[BODYPART_COUNT];
btTypedConstraint* m_joints[JOINT_COUNT];
btRigidBody* localCreateRigidBody (btScalar mass, const btTransform& startTransform, btCollisionShape* shape)
btRigidBody* localCreateRigidBody(btScalar mass, const btTransform& startTransform, btCollisionShape* shape)
{
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0,0,0);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
shape->calculateLocalInertia(mass,localInertia);
shape->calculateLocalInertia(mass, localInertia);
btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,shape,localInertia);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, shape, localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
m_ownerWorld->addRigidBody(body);
@@ -120,33 +113,33 @@ class TestRig
return body;
}
public:
TestRig (btDynamicsWorld* ownerWorld, const btVector3& positionOffset, bool bFixed)
: m_ownerWorld (ownerWorld)
TestRig(btDynamicsWorld* ownerWorld, const btVector3& positionOffset, bool bFixed)
: m_ownerWorld(ownerWorld)
{
btVector3 vUp(0, 1, 0);
//
// Setup geometry
//
float fBodySize = 0.25f;
float fBodySize = 0.25f;
float fLegLength = 0.45f;
float fForeLegLength = 0.75f;
m_shapes[0] = new btCapsuleShape(btScalar(fBodySize), btScalar(0.10));
int i;
for ( i=0; i<NUM_LEGS; i++)
for (i = 0; i < NUM_LEGS; i++)
{
m_shapes[1 + 2*i] = new btCapsuleShape(btScalar(0.10), btScalar(fLegLength));
m_shapes[2 + 2*i] = new btCapsuleShape(btScalar(0.08), btScalar(fForeLegLength));
m_shapes[1 + 2 * i] = new btCapsuleShape(btScalar(0.10), btScalar(fLegLength));
m_shapes[2 + 2 * i] = new btCapsuleShape(btScalar(0.08), btScalar(fForeLegLength));
}
//
// Setup rigid bodies
//
float fHeight = 0.5;
btTransform offset; offset.setIdentity();
offset.setOrigin(positionOffset);
btTransform offset;
offset.setIdentity();
offset.setOrigin(positionOffset);
// root
btVector3 vRoot = btVector3(btScalar(0.), btScalar(fHeight), btScalar(0.));
@@ -155,32 +148,33 @@ public:
transform.setOrigin(vRoot);
if (bFixed)
{
m_bodies[0] = localCreateRigidBody(btScalar(0.), offset*transform, m_shapes[0]);
} else
m_bodies[0] = localCreateRigidBody(btScalar(0.), offset * transform, m_shapes[0]);
}
else
{
m_bodies[0] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[0]);
m_bodies[0] = localCreateRigidBody(btScalar(1.), offset * transform, m_shapes[0]);
}
// legs
for ( i=0; i<NUM_LEGS; i++)
for (i = 0; i < NUM_LEGS; i++)
{
float fAngle = 2 * M_PI * i / NUM_LEGS;
float fSin = sin(fAngle);
float fCos = cos(fAngle);
transform.setIdentity();
btVector3 vBoneOrigin = btVector3(btScalar(fCos*(fBodySize+0.5*fLegLength)), btScalar(fHeight), btScalar(fSin*(fBodySize+0.5*fLegLength)));
btVector3 vBoneOrigin = btVector3(btScalar(fCos * (fBodySize + 0.5 * fLegLength)), btScalar(fHeight), btScalar(fSin * (fBodySize + 0.5 * fLegLength)));
transform.setOrigin(vBoneOrigin);
// thigh
btVector3 vToBone = (vBoneOrigin - vRoot).normalize();
btVector3 vAxis = vToBone.cross(vUp);
btVector3 vAxis = vToBone.cross(vUp);
transform.setRotation(btQuaternion(vAxis, M_PI_2));
m_bodies[1+2*i] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[1+2*i]);
m_bodies[1 + 2 * i] = localCreateRigidBody(btScalar(1.), offset * transform, m_shapes[1 + 2 * i]);
// shin
transform.setIdentity();
transform.setOrigin(btVector3(btScalar(fCos*(fBodySize+fLegLength)), btScalar(fHeight-0.5*fForeLegLength), btScalar(fSin*(fBodySize+fLegLength))));
m_bodies[2+2*i] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[2+2*i]);
transform.setOrigin(btVector3(btScalar(fCos * (fBodySize + fLegLength)), btScalar(fHeight - 0.5 * fForeLegLength), btScalar(fSin * (fBodySize + fLegLength))));
m_bodies[2 + 2 * i] = localCreateRigidBody(btScalar(1.), offset * transform, m_shapes[2 + 2 * i]);
}
// Setup some damping on the m_bodies
@@ -192,7 +186,6 @@ public:
m_bodies[i]->setSleepingThresholds(0.5f, 0.5f);
}
//
// Setup the constraints
//
@@ -201,74 +194,76 @@ public:
btTransform localA, localB, localC;
for ( i=0; i<NUM_LEGS; i++)
for (i = 0; i < NUM_LEGS; i++)
{
float fAngle = 2 * M_PI * i / NUM_LEGS;
float fSin = sin(fAngle);
float fCos = cos(fAngle);
// hip joints
localA.setIdentity(); localB.setIdentity();
localA.getBasis().setEulerZYX(0,-fAngle,0); localA.setOrigin(btVector3(btScalar(fCos*fBodySize), btScalar(0.), btScalar(fSin*fBodySize)));
localB = m_bodies[1+2*i]->getWorldTransform().inverse() * m_bodies[0]->getWorldTransform() * localA;
hingeC = new btHingeConstraint(*m_bodies[0], *m_bodies[1+2*i], localA, localB);
localA.setIdentity();
localB.setIdentity();
localA.getBasis().setEulerZYX(0, -fAngle, 0);
localA.setOrigin(btVector3(btScalar(fCos * fBodySize), btScalar(0.), btScalar(fSin * fBodySize)));
localB = m_bodies[1 + 2 * i]->getWorldTransform().inverse() * m_bodies[0]->getWorldTransform() * localA;
hingeC = new btHingeConstraint(*m_bodies[0], *m_bodies[1 + 2 * i], localA, localB);
hingeC->setLimit(btScalar(-0.75 * M_PI_4), btScalar(M_PI_8));
//hingeC->setLimit(btScalar(-0.1), btScalar(0.1));
m_joints[2*i] = hingeC;
m_ownerWorld->addConstraint(m_joints[2*i], true);
m_joints[2 * i] = hingeC;
m_ownerWorld->addConstraint(m_joints[2 * i], true);
// knee joints
localA.setIdentity(); localB.setIdentity(); localC.setIdentity();
localA.getBasis().setEulerZYX(0,-fAngle,0); localA.setOrigin(btVector3(btScalar(fCos*(fBodySize+fLegLength)), btScalar(0.), btScalar(fSin*(fBodySize+fLegLength))));
localB = m_bodies[1+2*i]->getWorldTransform().inverse() * m_bodies[0]->getWorldTransform() * localA;
localC = m_bodies[2+2*i]->getWorldTransform().inverse() * m_bodies[0]->getWorldTransform() * localA;
hingeC = new btHingeConstraint(*m_bodies[1+2*i], *m_bodies[2+2*i], localB, localC);
localA.setIdentity();
localB.setIdentity();
localC.setIdentity();
localA.getBasis().setEulerZYX(0, -fAngle, 0);
localA.setOrigin(btVector3(btScalar(fCos * (fBodySize + fLegLength)), btScalar(0.), btScalar(fSin * (fBodySize + fLegLength))));
localB = m_bodies[1 + 2 * i]->getWorldTransform().inverse() * m_bodies[0]->getWorldTransform() * localA;
localC = m_bodies[2 + 2 * i]->getWorldTransform().inverse() * m_bodies[0]->getWorldTransform() * localA;
hingeC = new btHingeConstraint(*m_bodies[1 + 2 * i], *m_bodies[2 + 2 * i], localB, localC);
//hingeC->setLimit(btScalar(-0.01), btScalar(0.01));
hingeC->setLimit(btScalar(-M_PI_8), btScalar(0.2));
m_joints[1+2*i] = hingeC;
m_ownerWorld->addConstraint(m_joints[1+2*i], true);
m_joints[1 + 2 * i] = hingeC;
m_ownerWorld->addConstraint(m_joints[1 + 2 * i], true);
}
}
virtual ~TestRig ()
virtual ~TestRig()
{
int i;
// Remove all constraints
for ( i = 0; i < JOINT_COUNT; ++i)
for (i = 0; i < JOINT_COUNT; ++i)
{
m_ownerWorld->removeConstraint(m_joints[i]);
delete m_joints[i]; m_joints[i] = 0;
delete m_joints[i];
m_joints[i] = 0;
}
// Remove all bodies and shapes
for ( i = 0; i < BODYPART_COUNT; ++i)
for (i = 0; i < BODYPART_COUNT; ++i)
{
m_ownerWorld->removeRigidBody(m_bodies[i]);
delete m_bodies[i]->getMotionState();
delete m_bodies[i]; m_bodies[i] = 0;
delete m_shapes[i]; m_shapes[i] = 0;
delete m_bodies[i];
m_bodies[i] = 0;
delete m_shapes[i];
m_shapes[i] = 0;
}
}
btTypedConstraint** GetJoints() {return &m_joints[0];}
btTypedConstraint** GetJoints() { return &m_joints[0]; }
};
void motorPreTickCallback (btDynamicsWorld *world, btScalar timeStep)
void motorPreTickCallback(btDynamicsWorld* world, btScalar timeStep)
{
MotorDemo* motorDemo = (MotorDemo*)world->getWorldUserInfo();
motorDemo->setMotorTargets(timeStep);
}
void MotorDemo::initPhysics()
{
m_guiHelper->setUpAxis(1);
@@ -276,70 +271,62 @@ void MotorDemo::initPhysics()
// Setup the basic world
m_Time = 0;
m_fCyclePeriod = 2000.f; // in milliseconds
m_fCyclePeriod = 2000.f; // in milliseconds
// m_fMuscleStrength = 0.05f;
// m_fMuscleStrength = 0.05f;
// new SIMD solver for joints clips accumulated impulse, so the new limits for the motor
// should be (numberOfsolverIterations * oldLimits)
// currently solver uses 10 iterations, so:
m_fMuscleStrength = 0.5f;
m_collisionConfiguration = new btDefaultCollisionConfiguration();
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
btVector3 worldAabbMin(-10000,-10000,-10000);
btVector3 worldAabbMax(10000,10000,10000);
m_broadphase = new btAxisSweep3 (worldAabbMin, worldAabbMax);
btVector3 worldAabbMin(-10000, -10000, -10000);
btVector3 worldAabbMax(10000, 10000, 10000);
m_broadphase = new btAxisSweep3(worldAabbMin, worldAabbMax);
m_solver = new btSequentialImpulseConstraintSolver;
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration);
m_dynamicsWorld->setInternalTickCallback(motorPreTickCallback,this,true);
m_dynamicsWorld->setInternalTickCallback(motorPreTickCallback, this, true);
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
// Setup a big ground box
{
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.),btScalar(10.),btScalar(200.)));
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.), btScalar(10.), btScalar(200.)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0,-10,0));
createRigidBody(btScalar(0.),groundTransform,groundShape);
groundTransform.setOrigin(btVector3(0, -10, 0));
createRigidBody(btScalar(0.), groundTransform, groundShape);
}
// Spawn one ragdoll
btVector3 startOffset(1,0.5,0);
btVector3 startOffset(1, 0.5, 0);
spawnTestRig(startOffset, false);
startOffset.setValue(-2,0.5,0);
startOffset.setValue(-2, 0.5, 0);
spawnTestRig(startOffset, true);
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void MotorDemo::spawnTestRig(const btVector3& startOffset, bool bFixed)
{
TestRig* rig = new TestRig(m_dynamicsWorld, startOffset, bFixed);
m_rigs.push_back(rig);
}
void PreStep()
void PreStep()
{
}
void MotorDemo::setMotorTargets(btScalar deltaTime)
{
float ms = deltaTime*1000000.;
float minFPS = 1000000.f/60.f;
float ms = deltaTime * 1000000.;
float minFPS = 1000000.f / 60.f;
if (ms > minFPS)
ms = minFPS;
@@ -347,24 +334,22 @@ void MotorDemo::setMotorTargets(btScalar deltaTime)
//
// set per-frame sinusoidal position targets using angular motor (hacky?)
//
for (int r=0; r<m_rigs.size(); r++)
//
for (int r = 0; r < m_rigs.size(); r++)
{
for (int i=0; i<2*NUM_LEGS; i++)
for (int i = 0; i < 2 * NUM_LEGS; i++)
{
btHingeConstraint* hingeC = static_cast<btHingeConstraint*>(m_rigs[r]->GetJoints()[i]);
btScalar fCurAngle = hingeC->getHingeAngle();
btScalar fCurAngle = hingeC->getHingeAngle();
btScalar fTargetPercent = (int(m_Time / 1000) % int(m_fCyclePeriod)) / m_fCyclePeriod;
btScalar fTargetAngle = 0.5 * (1 + sin(2 * M_PI * fTargetPercent));
btScalar fTargetAngle = 0.5 * (1 + sin(2 * M_PI * fTargetPercent));
btScalar fTargetLimitAngle = hingeC->getLowerLimit() + fTargetAngle * (hingeC->getUpperLimit() - hingeC->getLowerLimit());
btScalar fAngleError = fTargetLimitAngle - fCurAngle;
btScalar fDesiredAngularVel = 1000000.f * fAngleError/ms;
btScalar fAngleError = fTargetLimitAngle - fCurAngle;
btScalar fDesiredAngularVel = 1000000.f * fAngleError / ms;
hingeC->enableAngularMotor(true, fDesiredAngularVel, m_fMuscleStrength);
}
}
}
#if 0
@@ -392,14 +377,11 @@ void MotorDemo::keyboardCallback(unsigned char key, int x, int y)
}
#endif
void MotorDemo::exitPhysics()
{
int i;
for (i=0;i<m_rigs.size();i++)
for (i = 0; i < m_rigs.size(); i++)
{
TestRig* rig = m_rigs[i];
delete rig;
@@ -408,8 +390,8 @@ void MotorDemo::exitPhysics()
//cleanup in the reverse order of creation/initialization
//remove the rigidbodies from the dynamics world and delete them
for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--)
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
{
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
@@ -417,12 +399,12 @@ void MotorDemo::exitPhysics()
{
delete body->getMotionState();
}
m_dynamicsWorld->removeCollisionObject( obj );
m_dynamicsWorld->removeCollisionObject(obj);
delete obj;
}
//delete collision shapes
for (int j=0;j<m_collisionShapes.size();j++)
for (int j = 0; j < m_collisionShapes.size(); j++)
{
btCollisionShape* shape = m_collisionShapes[j];
delete shape;
@@ -440,11 +422,10 @@ void MotorDemo::exitPhysics()
//delete dispatcher
delete m_dispatcher;
delete m_collisionConfiguration;
delete m_collisionConfiguration;
}
class CommonExampleInterface* MotorControlCreateFunc(struct CommonExampleOptions& options)
class CommonExampleInterface* MotorControlCreateFunc(struct CommonExampleOptions& options)
{
return new MotorDemo(options.m_guiHelper);
}

View File

@@ -13,11 +13,9 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef MOTORDEMO_H
#define MOTORDEMO_H
class CommonExampleInterface* MotorControlCreateFunc(struct CommonExampleOptions& options);
class CommonExampleInterface* MotorControlCreateFunc(struct CommonExampleOptions& options);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -16,7 +16,6 @@ subject to the following restrictions:
#ifndef ET_NN_3D_WALKERS_EXAMPLE_H
#define ET_NN_3D_WALKERS_EXAMPLE_H
class CommonExampleInterface* ET_NN3DWalkersCreateFunc(struct CommonExampleOptions& options);
class CommonExampleInterface* ET_NN3DWalkersCreateFunc(struct CommonExampleOptions& options);
#endif //ET_NN_3D_WALKERS_EXAMPLE_H
#endif //ET_NN_3D_WALKERS_EXAMPLE_H

File diff suppressed because it is too large Load Diff

View File

@@ -2,12 +2,12 @@
#include "CollisionShape2TriangleMesh.h"
#include "btBulletCollisionCommon.h"
#include "BulletCollision/CollisionShapes/btShapeHull.h"//to create a tesselation of a generic btConvexShape
#include "BulletCollision/CollisionShapes/btShapeHull.h" //to create a tesselation of a generic btConvexShape
void CollisionShape2TriangleMesh(btCollisionShape* collisionShape, const btTransform& parentTransform, btAlignedObjectArray<btVector3>& vertexPositions, btAlignedObjectArray<btVector3>& vertexNormals, btAlignedObjectArray<int>& indicesOut)
{
//todo: support all collision shape types
//todo: support all collision shape types
switch (collisionShape->getShapeType())
{
case SOFTBODY_SHAPE_PROXYTYPE:
@@ -22,31 +22,30 @@ void CollisionShape2TriangleMesh(btCollisionShape* collisionShape, const btTrans
btScalar planeConst = staticPlaneShape->getPlaneConstant();
const btVector3& planeNormal = staticPlaneShape->getPlaneNormal();
btVector3 planeOrigin = planeNormal * planeConst;
btVector3 vec0,vec1;
btPlaneSpace1(planeNormal,vec0,vec1);
btVector3 vec0, vec1;
btPlaneSpace1(planeNormal, vec0, vec1);
btScalar vecLen = 100.f;
btVector3 verts[4];
verts[0] = planeOrigin + vec0*vecLen + vec1*vecLen;
verts[1] = planeOrigin - vec0*vecLen + vec1*vecLen;
verts[2] = planeOrigin - vec0*vecLen - vec1*vecLen;
verts[3] = planeOrigin + vec0*vecLen - vec1*vecLen;
verts[0] = planeOrigin + vec0 * vecLen + vec1 * vecLen;
verts[1] = planeOrigin - vec0 * vecLen + vec1 * vecLen;
verts[2] = planeOrigin - vec0 * vecLen - vec1 * vecLen;
verts[3] = planeOrigin + vec0 * vecLen - vec1 * vecLen;
int startIndex = vertexPositions.size();
indicesOut.push_back(startIndex+0);
indicesOut.push_back(startIndex+1);
indicesOut.push_back(startIndex+2);
indicesOut.push_back(startIndex+0);
indicesOut.push_back(startIndex+2);
indicesOut.push_back(startIndex+3);
indicesOut.push_back(startIndex + 0);
indicesOut.push_back(startIndex + 1);
indicesOut.push_back(startIndex + 2);
indicesOut.push_back(startIndex + 0);
indicesOut.push_back(startIndex + 2);
indicesOut.push_back(startIndex + 3);
btVector3 triNormal = parentTransform.getBasis()*planeNormal;
btVector3 triNormal = parentTransform.getBasis() * planeNormal;
for (int i=0;i<4;i++)
for (int i = 0; i < 4; i++)
{
btVector3 vtxPos;
btVector3 pos =parentTransform*verts[i];
btVector3 pos = parentTransform * verts[i];
vertexPositions.push_back(pos);
vertexNormals.push_back(triNormal);
}
@@ -54,53 +53,49 @@ void CollisionShape2TriangleMesh(btCollisionShape* collisionShape, const btTrans
}
case TRIANGLE_MESH_SHAPE_PROXYTYPE:
{
btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*) collisionShape;
btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)collisionShape;
btVector3 trimeshScaling = trimesh->getLocalScaling();
btStridingMeshInterface* meshInterface = trimesh->getMeshInterface();
btAlignedObjectArray<btVector3> vertices;
btAlignedObjectArray<int> indices;
for (int partId=0;partId<meshInterface->getNumSubParts();partId++)
for (int partId = 0; partId < meshInterface->getNumSubParts(); partId++)
{
const unsigned char *vertexbase = 0;
const unsigned char* vertexbase = 0;
int numverts = 0;
PHY_ScalarType type = PHY_INTEGER;
int stride = 0;
const unsigned char *indexbase = 0;
const unsigned char* indexbase = 0;
int indexstride = 0;
int numfaces = 0;
PHY_ScalarType indicestype = PHY_INTEGER;
//PHY_ScalarType indexType=0;
btVector3 triangleVerts[3];
meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase,numverts, type,stride,&indexbase,indexstride,numfaces,indicestype,partId);
btVector3 aabbMin,aabbMax;
for (int triangleIndex = 0 ; triangleIndex < numfaces;triangleIndex++)
meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase, numverts, type, stride, &indexbase, indexstride, numfaces, indicestype, partId);
btVector3 aabbMin, aabbMax;
for (int triangleIndex = 0; triangleIndex < numfaces; triangleIndex++)
{
unsigned int* gfxbase = (unsigned int*)(indexbase+triangleIndex*indexstride);
for (int j=2;j>=0;j--)
unsigned int* gfxbase = (unsigned int*)(indexbase + triangleIndex * indexstride);
for (int j = 2; j >= 0; j--)
{
int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
int graphicsindex = indicestype == PHY_SHORT ? ((unsigned short*)gfxbase)[j] : gfxbase[j];
if (type == PHY_FLOAT)
{
float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
float* graphicsbase = (float*)(vertexbase + graphicsindex * stride);
triangleVerts[j] = btVector3(
graphicsbase[0]*trimeshScaling.getX(),
graphicsbase[1]*trimeshScaling.getY(),
graphicsbase[2]*trimeshScaling.getZ());
graphicsbase[0] * trimeshScaling.getX(),
graphicsbase[1] * trimeshScaling.getY(),
graphicsbase[2] * trimeshScaling.getZ());
}
else
{
double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
triangleVerts[j] = btVector3( btScalar(graphicsbase[0]*trimeshScaling.getX()),
btScalar(graphicsbase[1]*trimeshScaling.getY()),
btScalar(graphicsbase[2]*trimeshScaling.getZ()));
double* graphicsbase = (double*)(vertexbase + graphicsindex * stride);
triangleVerts[j] = btVector3(btScalar(graphicsbase[0] * trimeshScaling.getX()),
btScalar(graphicsbase[1] * trimeshScaling.getY()),
btScalar(graphicsbase[2] * trimeshScaling.getZ()));
}
}
indices.push_back(vertices.size());
@@ -110,26 +105,24 @@ void CollisionShape2TriangleMesh(btCollisionShape* collisionShape, const btTrans
indices.push_back(vertices.size());
vertices.push_back(triangleVerts[2]);
btVector3 triNormal = (triangleVerts[1]-triangleVerts[0]).cross(triangleVerts[2]-triangleVerts[0]);
btVector3 triNormal = (triangleVerts[1] - triangleVerts[0]).cross(triangleVerts[2] - triangleVerts[0]);
btScalar dot = triNormal.dot(triNormal);
//cull degenerate triangles
if (dot >= SIMD_EPSILON*SIMD_EPSILON)
if (dot >= SIMD_EPSILON * SIMD_EPSILON)
{
triNormal /= btSqrt(dot);
for (int v = 0; v < 3; v++)
{
btVector3 pos = parentTransform*triangleVerts[v];
btVector3 pos = parentTransform * triangleVerts[v];
indicesOut.push_back(vertexPositions.size());
vertexPositions.push_back(pos);
vertexNormals.push_back(triNormal);
}
}
}
}
break;
}
default:
@@ -146,24 +139,23 @@ void CollisionShape2TriangleMesh(btCollisionShape* collisionShape, const btTrans
//int numVertices = hull->numVertices();
//int numIndices =hull->numIndices();
for (int t=0;t<hull->numTriangles();t++)
for (int t = 0; t < hull->numTriangles(); t++)
{
btVector3 triNormal;
int index0 = hull->getIndexPointer()[t*3+0];
int index1 = hull->getIndexPointer()[t*3+1];
int index2 = hull->getIndexPointer()[t*3+2];
btVector3 pos0 =parentTransform*hull->getVertexPointer()[index0];
btVector3 pos1 =parentTransform*hull->getVertexPointer()[index1];
btVector3 pos2 =parentTransform*hull->getVertexPointer()[index2];
triNormal = (pos1-pos0).cross(pos2-pos0);
int index0 = hull->getIndexPointer()[t * 3 + 0];
int index1 = hull->getIndexPointer()[t * 3 + 1];
int index2 = hull->getIndexPointer()[t * 3 + 2];
btVector3 pos0 = parentTransform * hull->getVertexPointer()[index0];
btVector3 pos1 = parentTransform * hull->getVertexPointer()[index1];
btVector3 pos2 = parentTransform * hull->getVertexPointer()[index2];
triNormal = (pos1 - pos0).cross(pos2 - pos0);
triNormal.safeNormalize();
for (int v=0;v<3;v++)
for (int v = 0; v < 3; v++)
{
int index = hull->getIndexPointer()[t*3+v];
btVector3 pos =parentTransform*hull->getVertexPointer()[index];
int index = hull->getIndexPointer()[t * 3 + v];
btVector3 pos = parentTransform * hull->getVertexPointer()[index];
indicesOut.push_back(vertexPositions.size());
vertexPositions.push_back(pos);
vertexNormals.push_back(triNormal);
@@ -172,31 +164,30 @@ void CollisionShape2TriangleMesh(btCollisionShape* collisionShape, const btTrans
}
delete hull;
}
} else
}
else
{
if (collisionShape->isCompound())
{
btCompoundShape* compound = (btCompoundShape*) collisionShape;
for (int i=0;i<compound->getNumChildShapes();i++)
btCompoundShape* compound = (btCompoundShape*)collisionShape;
for (int i = 0; i < compound->getNumChildShapes(); i++)
{
btTransform childWorldTrans = parentTransform * compound->getChildTransform(i);
CollisionShape2TriangleMesh(compound->getChildShape(i),childWorldTrans,vertexPositions,vertexNormals,indicesOut);
CollisionShape2TriangleMesh(compound->getChildShape(i), childWorldTrans, vertexPositions, vertexNormals, indicesOut);
}
} else
}
else
{
if (collisionShape->getShapeType()==SDF_SHAPE_PROXYTYPE)
if (collisionShape->getShapeType() == SDF_SHAPE_PROXYTYPE)
{
//not yet
} else
}
else
{
btAssert(0);
}
}
}
}
};
}

View File

@@ -7,4 +7,4 @@ class btCollisionShape;
void CollisionShape2TriangleMesh(btCollisionShape* collisionShape, const btTransform& parentTransform, btAlignedObjectArray<btVector3>& vertexPositions, btAlignedObjectArray<btVector3>& vertexNormals, btAlignedObjectArray<int>& indicesOut);
#endif //COLLISION_SHAPE_2_GRAPHICS_H
#endif //COLLISION_SHAPE_2_GRAPHICS_H

View File

@@ -7,7 +7,6 @@
class EmptyBrowser : public ExampleBrowserInterface
{
public:
EmptyExample m_emptyExample;
virtual CommonExampleInterface* getCurrentExample()
@@ -35,4 +34,4 @@ public:
}
};
#endif //EMPTY_BROWSER
#endif //EMPTY_BROWSER

View File

@@ -6,27 +6,22 @@
class EmptyExample : public CommonExampleInterface
{
public:
EmptyExample() {}
virtual ~EmptyExample(){}
virtual ~EmptyExample() {}
static CommonExampleInterface* CreateFunc(struct CommonExampleOptions& /* unusedOptions*/)
{
return new EmptyExample;
}
virtual void initPhysics(){}
virtual void exitPhysics(){}
virtual void stepSimulation(float deltaTime){}
virtual void renderScene(){}
virtual void physicsDebugDraw(int debugFlags){}
virtual bool mouseMoveCallback(float x,float y){ return false;}
virtual bool mouseButtonCallback(int button, int state, float x, float y){return false;}
virtual bool keyboardCallback(int key, int state){return false;}
virtual void initPhysics() {}
virtual void exitPhysics() {}
virtual void stepSimulation(float deltaTime) {}
virtual void renderScene() {}
virtual void physicsDebugDraw(int debugFlags) {}
virtual bool mouseMoveCallback(float x, float y) { return false; }
virtual bool mouseButtonCallback(int button, int state, float x, float y) { return false; }
virtual bool keyboardCallback(int key, int state) { return false; }
};
#endif //EMPTY_EXAMPLE_H
#endif //EMPTY_EXAMPLE_H

View File

@@ -5,19 +5,16 @@
class ExampleBrowserInterface
{
public:
public:
virtual ~ExampleBrowserInterface() {}
virtual CommonExampleInterface* getCurrentExample() = 0;
virtual bool init(int argc, char* argv[])=0;
virtual void update(float deltaTime)=0;
virtual bool init(int argc, char* argv[]) = 0;
virtual bool requestedExit()=0;
virtual void update(float deltaTime) = 0;
virtual bool requestedExit() = 0;
};
#endif //EXAMPLE_BROWSER_GUI_H
#endif //EXAMPLE_BROWSER_GUI_H

View File

@@ -56,7 +56,7 @@
#ifdef B3_ENABLE_TINY_AUDIO
#include "../TinyAudio/TinyAudioExample.h"
#endif //B3_ENABLE_TINY_AUDIO
#endif //B3_ENABLE_TINY_AUDIO
#ifdef ENABLE_LUA
#include "../LuaDemo/LuaPhysicsSetup.h"
@@ -67,7 +67,7 @@
#include "../OpenCL/broadphase/PairBench.h"
#include "../OpenCL/rigidbody/GpuConvexScene.h"
#endif
#endif //B3_USE_CLEW
#endif //B3_USE_CLEW
//Extended Tutorial Includes Added by Mobeen and Benelot
#include "../ExtendedTutorials/SimpleBox.h"
@@ -86,280 +86,262 @@
struct ExampleEntry
{
int m_menuLevel;
const char* m_name;
const char* m_description;
CommonExampleInterface::CreateFunc* m_createFunc;
int m_option;
int m_menuLevel;
const char* m_name;
const char* m_description;
CommonExampleInterface::CreateFunc* m_createFunc;
int m_option;
ExampleEntry(int menuLevel, const char* name)
:m_menuLevel(menuLevel), m_name(name), m_description(0), m_createFunc(0), m_option(0)
: m_menuLevel(menuLevel), m_name(name), m_description(0), m_createFunc(0), m_option(0)
{
}
ExampleEntry(int menuLevel, const char* name,const char* description, CommonExampleInterface::CreateFunc* createFunc, int option=0)
:m_menuLevel(menuLevel), m_name(name), m_description(description), m_createFunc(createFunc), m_option(option)
ExampleEntry(int menuLevel, const char* name, const char* description, CommonExampleInterface::CreateFunc* createFunc, int option = 0)
: m_menuLevel(menuLevel), m_name(name), m_description(description), m_createFunc(createFunc), m_option(option)
{
}
};
static ExampleEntry gDefaultExamples[] =
{
ExampleEntry(0, "API"),
ExampleEntry(1, "Basic Example", "Create some rigid bodies using box collision shapes. This is a good example to familiarize with the basic initialization of Bullet. The Basic Example can also be compiled without graphical user interface, as a console application. Press W for wireframe, A to show AABBs, I to suspend/restart physics simulation. Press D to toggle auto-deactivation of the simulation. ", BasicExampleCreateFunc),
static ExampleEntry gDefaultExamples[]=
{
ExampleEntry(0,"API"),
ExampleEntry(1, "Rolling Friction", "Damping is often not good enough to keep rounded objects from rolling down a sloped surface. Instead, you can set the rolling friction of a rigid body. Generally it is best to leave the rolling friction to zero, to avoid artifacts.", RollingFrictionCreateFunc),
ExampleEntry(1,"Basic Example","Create some rigid bodies using box collision shapes. This is a good example to familiarize with the basic initialization of Bullet. The Basic Example can also be compiled without graphical user interface, as a console application. Press W for wireframe, A to show AABBs, I to suspend/restart physics simulation. Press D to toggle auto-deactivation of the simulation. ", BasicExampleCreateFunc),
ExampleEntry(1, "Constraints", "Show the use of the various constraints in Bullet. Press the L key to visualize the constraint limits. Press the C key to visualize the constraint frames.",
AllConstraintCreateFunc),
ExampleEntry(1,"Rolling Friction", "Damping is often not good enough to keep rounded objects from rolling down a sloped surface. Instead, you can set the rolling friction of a rigid body. Generally it is best to leave the rolling friction to zero, to avoid artifacts.", RollingFrictionCreateFunc),
ExampleEntry(1, "Motorized Hinge", "Use of a btHingeConstraint. You can adjust the first slider to change the target velocity, and the second slider to adjust the maximum impulse applied to reach the target velocity. Note that the hinge angle can reach beyond -360 and 360 degrees.", ConstraintCreateFunc),
ExampleEntry(1, "TestHingeTorque", "Apply a torque in the hinge axis. This example uses a btHingeConstraint and btRigidBody. The setup is similar to the multi body example TestJointTorque.",
TestHingeTorqueCreateFunc),
// ExampleEntry(0,"What's new in 2.83"),
ExampleEntry(1,"Constraints","Show the use of the various constraints in Bullet. Press the L key to visualize the constraint limits. Press the C key to visualize the constraint frames.",
AllConstraintCreateFunc),
ExampleEntry(1, "6DofSpring2", "Show the use of the btGeneric6DofSpring2Constraint. This is a replacement of the btGeneric6DofSpringConstraint, it has various improvements. This includes improved spring implementation and better control over the restitution (bounce) when the constraint hits its limits.",
Dof6Spring2CreateFunc),
ExampleEntry(1,"Motorized Hinge","Use of a btHingeConstraint. You can adjust the first slider to change the target velocity, and the second slider to adjust the maximum impulse applied to reach the target velocity. Note that the hinge angle can reach beyond -360 and 360 degrees.", ConstraintCreateFunc),
ExampleEntry(1,"TestHingeTorque", "Apply a torque in the hinge axis. This example uses a btHingeConstraint and btRigidBody. The setup is similar to the multi body example TestJointTorque.",
TestHingeTorqueCreateFunc),
// ExampleEntry(0,"What's new in 2.83"),
ExampleEntry(1, "Motor Demo", "Dynamic control the target velocity of a motor of a btHingeConstraint. This demo makes use of the 'internal tick callback'. You can press W for wireframe, C and L to visualize constraint frame and limits.", MotorControlCreateFunc),
ExampleEntry(1,"6DofSpring2","Show the use of the btGeneric6DofSpring2Constraint. This is a replacement of the btGeneric6DofSpringConstraint, it has various improvements. This includes improved spring implementation and better control over the restitution (bounce) when the constraint hits its limits.",
Dof6Spring2CreateFunc),
ExampleEntry(1, "Gyroscopic", "Show the Dzhanibekov effect using various settings of the gyroscopic term. You can select the gyroscopic term computation using btRigidBody::setFlags, with arguments BT_ENABLE_GYROSCOPIC_FORCE_EXPLICIT (using explicit integration, which adds energy and can lead to explosions), BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_WORLD, BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY. If you don't set any of these flags, there is no gyroscopic term used.", GyroscopicCreateFunc),
ExampleEntry(1,"Motor Demo", "Dynamic control the target velocity of a motor of a btHingeConstraint. This demo makes use of the 'internal tick callback'. You can press W for wireframe, C and L to visualize constraint frame and limits.", MotorControlCreateFunc),
ExampleEntry(1, "Soft Contact", "Using the error correction parameter (ERP) and constraint force mixing (CFM) values for contacts to simulate compliant contact.", RigidBodySoftContactCreateFunc),
ExampleEntry(1,"Gyroscopic", "Show the Dzhanibekov effect using various settings of the gyroscopic term. You can select the gyroscopic term computation using btRigidBody::setFlags, with arguments BT_ENABLE_GYROSCOPIC_FORCE_EXPLICIT (using explicit integration, which adds energy and can lead to explosions), BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_WORLD, BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY. If you don't set any of these flags, there is no gyroscopic term used.", GyroscopicCreateFunc),
ExampleEntry(0, "MultiBody"),
ExampleEntry(1, "MultiDof", "Create a basic btMultiBody with 3-DOF spherical joints (mobilizers). The demo uses a fixed base or a floating base at restart.", MultiDofCreateFunc),
ExampleEntry(1, "TestJointTorque", "Apply a torque to a btMultiBody with 1-DOF joints (mobilizers). This setup is similar to API/TestHingeTorque.", TestJointTorqueCreateFunc),
ExampleEntry(1, "TestPendulum", "Simulate a pendulum using btMultiBody with a constant joint torque applied. The same code is also used as a unit test comparing Bullet with the numerical solution of second-order non-linear differential equation stored in pendulum_gold.h", TestPendulumCreateFunc),
ExampleEntry(1,"Soft Contact", "Using the error correction parameter (ERP) and constraint force mixing (CFM) values for contacts to simulate compliant contact.",RigidBodySoftContactCreateFunc),
ExampleEntry(1, "Constraint Feedback", "The example shows how to receive joint reaction forces in a btMultiBody. Also the applied impulse is available for a btMultiBodyJointMotor", MultiBodyConstraintFeedbackCreateFunc),
ExampleEntry(1, "Inverted Pendulum PD", "Keep an inverted pendulum up using open loop PD control", InvertedPendulumPDControlCreateFunc),
ExampleEntry(1, "MultiBody Soft Contact", "Using the error correction parameter (ERP) and constraint force mixing (CFM) values for contacts to simulate compliant contact.", MultiBodySoftContactCreateFunc, 0),
ExampleEntry(1, "Serial Chains", "Show colliding two serial chains using different constraint solvers.", SerialChainsCreateFunc, 0),
ExampleEntry(0,"MultiBody"),
ExampleEntry(1,"MultiDof","Create a basic btMultiBody with 3-DOF spherical joints (mobilizers). The demo uses a fixed base or a floating base at restart.", MultiDofCreateFunc),
ExampleEntry(1,"TestJointTorque","Apply a torque to a btMultiBody with 1-DOF joints (mobilizers). This setup is similar to API/TestHingeTorque.", TestJointTorqueCreateFunc),
ExampleEntry(1,"TestPendulum","Simulate a pendulum using btMultiBody with a constant joint torque applied. The same code is also used as a unit test comparing Bullet with the numerical solution of second-order non-linear differential equation stored in pendulum_gold.h", TestPendulumCreateFunc),
ExampleEntry(0, "Physics Client-Server"),
ExampleEntry(1, "Physics Server", "Create a physics server that communicates with a physics client over shared memory. You can connect to the server using pybullet, a PhysicsClient or a UDP/TCP Bridge.",
PhysicsServerCreateFuncBullet2),
ExampleEntry(1, "Physics Client (Shared Mem)", "Create a physics client that can communicate with a physics server over shared memory.", PhysicsClientCreateFunc),
ExampleEntry(1,"Constraint Feedback", "The example shows how to receive joint reaction forces in a btMultiBody. Also the applied impulse is available for a btMultiBodyJointMotor", MultiBodyConstraintFeedbackCreateFunc),
ExampleEntry(1,"Inverted Pendulum PD","Keep an inverted pendulum up using open loop PD control", InvertedPendulumPDControlCreateFunc),
ExampleEntry(1,"MultiBody Soft Contact", "Using the error correction parameter (ERP) and constraint force mixing (CFM) values for contacts to simulate compliant contact.",MultiBodySoftContactCreateFunc,0),
ExampleEntry(1,"Serial Chains", "Show colliding two serial chains using different constraint solvers.", SerialChainsCreateFunc,0),
ExampleEntry(1, "Physics Server (Logging)", "Create a physics server that communicates with a physics client over shared memory. It will log all commands to a file.",
PhysicsServerCreateFuncBullet2, PHYSICS_SERVER_ENABLE_COMMAND_LOGGING),
ExampleEntry(1, "Physics Server (Replay Log)", "Create a physics server that replay a command log from disk.",
PhysicsServerCreateFuncBullet2, PHYSICS_SERVER_REPLAY_FROM_COMMAND_LOG),
//
// ExampleEntry(1, "Physics Client (Direct)", "Create a physics client that can communicate with a physics server directly in-process.", PhysicsClientCreateFunc,eCLIENTEXAMPLE_DIRECT),
ExampleEntry(0,"Physics Client-Server"),
ExampleEntry(1,"Physics Server", "Create a physics server that communicates with a physics client over shared memory. You can connect to the server using pybullet, a PhysicsClient or a UDP/TCP Bridge.",
PhysicsServerCreateFuncBullet2),
ExampleEntry(1, "Physics Client (Shared Mem)", "Create a physics client that can communicate with a physics server over shared memory.", PhysicsClientCreateFunc),
ExampleEntry(0, "Inverse Dynamics"),
ExampleEntry(1, "Inverse Dynamics URDF", "Create a btMultiBody from URDF. Create an inverse MultiBodyTree model from that. Use either decoupled PD control or computed torque control using the inverse model to track joint position targets", InverseDynamicsExampleCreateFunc, BT_ID_LOAD_URDF),
ExampleEntry(1, "Inverse Dynamics Prog", "Create a btMultiBody programatically. Create an inverse MultiBodyTree model from that. Use either decoupled PD control or computed torque control using the inverse model to track joint position targets", InverseDynamicsExampleCreateFunc, BT_ID_PROGRAMMATICALLY),
ExampleEntry(1,"Physics Server (Logging)", "Create a physics server that communicates with a physics client over shared memory. It will log all commands to a file.",
PhysicsServerCreateFuncBullet2,PHYSICS_SERVER_ENABLE_COMMAND_LOGGING),
ExampleEntry(1,"Physics Server (Replay Log)", "Create a physics server that replay a command log from disk.",
PhysicsServerCreateFuncBullet2,PHYSICS_SERVER_REPLAY_FROM_COMMAND_LOG),
//
// ExampleEntry(1, "Physics Client (Direct)", "Create a physics client that can communicate with a physics server directly in-process.", PhysicsClientCreateFunc,eCLIENTEXAMPLE_DIRECT),
ExampleEntry(0, "Inverse Kinematics"),
ExampleEntry(1, "SDLS", "Selectively Damped Least Squares by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_SDLS),
ExampleEntry(1, "DLS", "Damped Least Squares by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_DLS),
ExampleEntry(1, "DLS-SVD", "Damped Least Squares with Singular Value Decomposition by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_DLS_SVD),
ExampleEntry(0,"Inverse Dynamics"),
ExampleEntry(1,"Inverse Dynamics URDF", "Create a btMultiBody from URDF. Create an inverse MultiBodyTree model from that. Use either decoupled PD control or computed torque control using the inverse model to track joint position targets", InverseDynamicsExampleCreateFunc,BT_ID_LOAD_URDF),
ExampleEntry(1,"Inverse Dynamics Prog", "Create a btMultiBody programatically. Create an inverse MultiBodyTree model from that. Use either decoupled PD control or computed torque control using the inverse model to track joint position targets", InverseDynamicsExampleCreateFunc,BT_ID_PROGRAMMATICALLY),
ExampleEntry(0, "Inverse Kinematics"),
ExampleEntry(1, "SDLS", "Selectively Damped Least Squares by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_SDLS),
ExampleEntry(1, "DLS", "Damped Least Squares by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_DLS),
ExampleEntry(1, "DLS-SVD", "Damped Least Squares with Singular Value Decomposition by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_DLS_SVD),
ExampleEntry(1, "Jacobi Transpose", "Jacobi Transpose by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_JACOB_TRANS),
ExampleEntry(1, "Jacobi Pseudo Inv", "Jacobi Pseudo Inverse Method by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_PURE_PSEUDO),
ExampleEntry(0,"Tutorial"),
ExampleEntry(1,"Constant Velocity","Free moving rigid body, without external or constraint forces", TutorialCreateFunc,TUT_VELOCITY),
ExampleEntry(1,"Gravity Acceleration","Motion of a free falling rigid body under constant gravitational acceleration", TutorialCreateFunc,TUT_ACCELERATION),
ExampleEntry(1,"Contact Computation","Discrete Collision Detection for sphere-sphere", TutorialCreateFunc,TUT_COLLISION),
ExampleEntry(1,"Solve Contact Constraint","Compute and apply the impulses needed to satisfy non-penetrating contact constraints", TutorialCreateFunc,TUT_SOLVE_CONTACT_CONSTRAINT),
ExampleEntry(1,"Spring constraint","A rigid body with a spring constraint attached", Dof6ConstraintTutorialCreateFunc,0),
ExampleEntry(0,"Collision"),
ExampleEntry(1, "Spheres & Plane C-API (Bullet2)", "Collision C-API using Bullet 2.x backend", CollisionTutorialBullet2CreateFunc,TUT_SPHERE_PLANE_BULLET2),
//ExampleEntry(1, "Spheres & Plane C-API (Bullet3)", "Collision C-API using Bullet 3.x backend", CollisionTutorialBullet2CreateFunc,TUT_SPHERE_PLANE_RTB3),
ExampleEntry(1, "Jacobi Transpose", "Jacobi Transpose by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_JACOB_TRANS),
ExampleEntry(1, "Jacobi Pseudo Inv", "Jacobi Pseudo Inverse Method by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_PURE_PSEUDO),
ExampleEntry(0, "Tutorial"),
ExampleEntry(1, "Constant Velocity", "Free moving rigid body, without external or constraint forces", TutorialCreateFunc, TUT_VELOCITY),
ExampleEntry(1, "Gravity Acceleration", "Motion of a free falling rigid body under constant gravitational acceleration", TutorialCreateFunc, TUT_ACCELERATION),
ExampleEntry(1, "Contact Computation", "Discrete Collision Detection for sphere-sphere", TutorialCreateFunc, TUT_COLLISION),
ExampleEntry(1, "Solve Contact Constraint", "Compute and apply the impulses needed to satisfy non-penetrating contact constraints", TutorialCreateFunc, TUT_SOLVE_CONTACT_CONSTRAINT),
ExampleEntry(1, "Spring constraint", "A rigid body with a spring constraint attached", Dof6ConstraintTutorialCreateFunc, 0),
ExampleEntry(0, "Collision"),
ExampleEntry(1, "Spheres & Plane C-API (Bullet2)", "Collision C-API using Bullet 2.x backend", CollisionTutorialBullet2CreateFunc, TUT_SPHERE_PLANE_BULLET2),
//ExampleEntry(1, "Spheres & Plane C-API (Bullet3)", "Collision C-API using Bullet 3.x backend", CollisionTutorialBullet2CreateFunc,TUT_SPHERE_PLANE_RTB3),
#ifdef INCLUDE_CLOTH_DEMOS
ExampleEntry(0,"Soft Body"),
ExampleEntry(1,"Cloth","Simulate a patch of cloth.", SoftDemoCreateFunc,0),
ExampleEntry(0, "Soft Body"),
ExampleEntry(1, "Cloth", "Simulate a patch of cloth.", SoftDemoCreateFunc, 0),
ExampleEntry(1,"Pressure","Simulate 3d soft body using a pressure constraint.",SoftDemoCreateFunc,1),
ExampleEntry(1,"Volume","Simulate 3d soft body using a volume constraint.",SoftDemoCreateFunc,2),
ExampleEntry(1,"Ropes","Simulate ropes", SoftDemoCreateFunc,3),
ExampleEntry(1,"Rope Attach","Simulate a rigid body connected to a rope.", SoftDemoCreateFunc,4),
ExampleEntry(1,"Cloth Attach","A rigid body attached to a cloth.", SoftDemoCreateFunc,5),
ExampleEntry(1,"Sticks","Show simulation of ropes fixed to the ground.", SoftDemoCreateFunc,6),
ExampleEntry(1,"Capsule Collision","Collision detection between a capsule shape and cloth.", SoftDemoCreateFunc,7),
ExampleEntry(1, "Pressure", "Simulate 3d soft body using a pressure constraint.", SoftDemoCreateFunc, 1),
ExampleEntry(1, "Volume", "Simulate 3d soft body using a volume constraint.", SoftDemoCreateFunc, 2),
ExampleEntry(1, "Ropes", "Simulate ropes", SoftDemoCreateFunc, 3),
ExampleEntry(1, "Rope Attach", "Simulate a rigid body connected to a rope.", SoftDemoCreateFunc, 4),
ExampleEntry(1, "Cloth Attach", "A rigid body attached to a cloth.", SoftDemoCreateFunc, 5),
ExampleEntry(1, "Sticks", "Show simulation of ropes fixed to the ground.", SoftDemoCreateFunc, 6),
ExampleEntry(1, "Capsule Collision", "Collision detection between a capsule shape and cloth.", SoftDemoCreateFunc, 7),
ExampleEntry(1,"Collide","Soft body collision", SoftDemoCreateFunc,8),
ExampleEntry(1,"Collide 2","Soft body collision",SoftDemoCreateFunc,9),
ExampleEntry(1,"Collide 3","Soft body collision",SoftDemoCreateFunc,10),
ExampleEntry(1,"Impact","Soft body impact",SoftDemoCreateFunc,11),
ExampleEntry(1,"Aero","Rudimentary aero dynamics simulation", SoftDemoCreateFunc,12),
ExampleEntry(1,"Aero 2","Rudimentary aero dynamics simulation",SoftDemoCreateFunc,13),
ExampleEntry(1,"Friction","Simulate soft body friction with friction coefficients ranging from 0 to 1.", SoftDemoCreateFunc,14),
ExampleEntry(1,"Torus","Simulate a soft body torus.",SoftDemoCreateFunc,15),
ExampleEntry(1,"Torus (Shape Match)","Simulate a soft body torus using shape matching.", SoftDemoCreateFunc,16),
ExampleEntry(1,"Bunny","Simulate the Stanford bunny as deformable object.", SoftDemoCreateFunc,17),
ExampleEntry(1,"Bunny (Shape Match)","Simulate the Stanford bunny as deformable object including shape matching.", SoftDemoCreateFunc,18),
ExampleEntry(1,"Cutting","Allow cutting of the soft body, by clicking on the cloth", SoftDemoCreateFunc,19),
ExampleEntry(1,"Cluster Deform","Soft body collision detection using convex collision clusters.", SoftDemoCreateFunc,20),
ExampleEntry(1,"Cluster Collide1","Collision detection between soft bodies using convex collision clusters.", SoftDemoCreateFunc,21),
ExampleEntry(1,"Cluster Collide2","Collision detection between soft bodies using convex collision clusters.",SoftDemoCreateFunc,22),
ExampleEntry(1,"Cluster Socket","Soft bodies connected by a point to point (ball-socket) constraints. This requires collision clusters, in order to define a frame of reference for the constraint."
, SoftDemoCreateFunc,23),
ExampleEntry(1,"Cluster Hinge","Soft bodies connected by a hinge constraints. This requires collision clusters, in order to define a frame of reference for the constraint.", SoftDemoCreateFunc,24),
ExampleEntry(1,"Cluster Combine","Simulate soft bodies using collision clusters.", SoftDemoCreateFunc,25),
ExampleEntry(1,"Cluster Car","Simulate the Stanford bunny by multiple soft bodies connected by constraints.", SoftDemoCreateFunc,26),
ExampleEntry(1,"Cluster Robot","A rigid body base connected by soft body wheels, connected by constraints.", SoftDemoCreateFunc,27),
ExampleEntry(1,"Cluster Stack Soft","Stacking of soft bodies.", SoftDemoCreateFunc,28),
ExampleEntry(1,"Cluster Stack Mixed","Stacking of soft bodies and rigid bodies.",SoftDemoCreateFunc,29),
ExampleEntry(1,"Tetra Cube","Simulate a volumetric soft body cube defined by tetrahedra.", SoftDemoCreateFunc,30),
ExampleEntry(1,"Tetra Bunny","Simulate a volumetric soft body Stanford bunny defined by tetrahedra.", SoftDemoCreateFunc,31),
ExampleEntry(1, "Collide", "Soft body collision", SoftDemoCreateFunc, 8),
ExampleEntry(1, "Collide 2", "Soft body collision", SoftDemoCreateFunc, 9),
ExampleEntry(1, "Collide 3", "Soft body collision", SoftDemoCreateFunc, 10),
ExampleEntry(1, "Impact", "Soft body impact", SoftDemoCreateFunc, 11),
ExampleEntry(1, "Aero", "Rudimentary aero dynamics simulation", SoftDemoCreateFunc, 12),
ExampleEntry(1, "Aero 2", "Rudimentary aero dynamics simulation", SoftDemoCreateFunc, 13),
ExampleEntry(1, "Friction", "Simulate soft body friction with friction coefficients ranging from 0 to 1.", SoftDemoCreateFunc, 14),
ExampleEntry(1, "Torus", "Simulate a soft body torus.", SoftDemoCreateFunc, 15),
ExampleEntry(1, "Torus (Shape Match)", "Simulate a soft body torus using shape matching.", SoftDemoCreateFunc, 16),
ExampleEntry(1, "Bunny", "Simulate the Stanford bunny as deformable object.", SoftDemoCreateFunc, 17),
ExampleEntry(1, "Bunny (Shape Match)", "Simulate the Stanford bunny as deformable object including shape matching.", SoftDemoCreateFunc, 18),
ExampleEntry(1, "Cutting", "Allow cutting of the soft body, by clicking on the cloth", SoftDemoCreateFunc, 19),
ExampleEntry(1, "Cluster Deform", "Soft body collision detection using convex collision clusters.", SoftDemoCreateFunc, 20),
ExampleEntry(1, "Cluster Collide1", "Collision detection between soft bodies using convex collision clusters.", SoftDemoCreateFunc, 21),
ExampleEntry(1, "Cluster Collide2", "Collision detection between soft bodies using convex collision clusters.", SoftDemoCreateFunc, 22),
ExampleEntry(1, "Cluster Socket", "Soft bodies connected by a point to point (ball-socket) constraints. This requires collision clusters, in order to define a frame of reference for the constraint.", SoftDemoCreateFunc, 23),
ExampleEntry(1, "Cluster Hinge", "Soft bodies connected by a hinge constraints. This requires collision clusters, in order to define a frame of reference for the constraint.", SoftDemoCreateFunc, 24),
ExampleEntry(1, "Cluster Combine", "Simulate soft bodies using collision clusters.", SoftDemoCreateFunc, 25),
ExampleEntry(1, "Cluster Car", "Simulate the Stanford bunny by multiple soft bodies connected by constraints.", SoftDemoCreateFunc, 26),
ExampleEntry(1, "Cluster Robot", "A rigid body base connected by soft body wheels, connected by constraints.", SoftDemoCreateFunc, 27),
ExampleEntry(1, "Cluster Stack Soft", "Stacking of soft bodies.", SoftDemoCreateFunc, 28),
ExampleEntry(1, "Cluster Stack Mixed", "Stacking of soft bodies and rigid bodies.", SoftDemoCreateFunc, 29),
ExampleEntry(1, "Tetra Cube", "Simulate a volumetric soft body cube defined by tetrahedra.", SoftDemoCreateFunc, 30),
ExampleEntry(1, "Tetra Bunny", "Simulate a volumetric soft body Stanford bunny defined by tetrahedra.", SoftDemoCreateFunc, 31),
#endif //INCLUDE_CLOTH_DEMOS
#endif //INCLUDE_CLOTH_DEMOS
///we disable the benchmarks in debug mode, they are way too slow and benchmarking in debug mode is not recommended
//#ifndef _DEBUG
ExampleEntry(0,"Benchmarks"),
ExampleEntry(1,"3000 boxes", "Benchmark a stack of 3000 boxes. It will stress the collision detection, a specialized box-box implementation based on the separating axis test, and the constraint solver. ", BenchmarkCreateFunc, 1),
ExampleEntry(1,"1000 stack", "Benchmark a stack of 3000 boxes. It will stress the collision detection, a specialized box-box implementation based on the separating axis test, and the constraint solver. ",
BenchmarkCreateFunc, 2),
ExampleEntry(1,"Ragdolls", "Benchmark the performance of the ragdoll constraints, btHingeConstraint and btConeTwistConstraint, in addition to capsule collision detection.", BenchmarkCreateFunc, 3),
ExampleEntry(1,"Convex stack", "Benchmark the performance and stability of rigid bodies using btConvexHullShape.", BenchmarkCreateFunc, 4),
ExampleEntry(1,"Prim vs Mesh", "Benchmark the performance and stability of rigid bodies using primitive collision shapes (btSphereShape, btBoxShape), resting on a triangle mesh, btBvhTriangleMeshShape.", BenchmarkCreateFunc, 5),
ExampleEntry(1,"Convex vs Mesh", "Benchmark the performance and stability of rigid bodies using convex hull collision shapes (btConvexHullShape), resting on a triangle mesh, btBvhTriangleMeshShape.", BenchmarkCreateFunc, 6),
ExampleEntry(1,"Raycast", "Benchmark the performance of the btCollisionWorld::rayTest. Note that currently the rays are not rendered.", BenchmarkCreateFunc, 7),
//#endif
///we disable the benchmarks in debug mode, they are way too slow and benchmarking in debug mode is not recommended
//#ifndef _DEBUG
ExampleEntry(0, "Benchmarks"),
ExampleEntry(1, "3000 boxes", "Benchmark a stack of 3000 boxes. It will stress the collision detection, a specialized box-box implementation based on the separating axis test, and the constraint solver. ", BenchmarkCreateFunc, 1),
ExampleEntry(1, "1000 stack", "Benchmark a stack of 3000 boxes. It will stress the collision detection, a specialized box-box implementation based on the separating axis test, and the constraint solver. ",
BenchmarkCreateFunc, 2),
ExampleEntry(1, "Ragdolls", "Benchmark the performance of the ragdoll constraints, btHingeConstraint and btConeTwistConstraint, in addition to capsule collision detection.", BenchmarkCreateFunc, 3),
ExampleEntry(1, "Convex stack", "Benchmark the performance and stability of rigid bodies using btConvexHullShape.", BenchmarkCreateFunc, 4),
ExampleEntry(1, "Prim vs Mesh", "Benchmark the performance and stability of rigid bodies using primitive collision shapes (btSphereShape, btBoxShape), resting on a triangle mesh, btBvhTriangleMeshShape.", BenchmarkCreateFunc, 5),
ExampleEntry(1, "Convex vs Mesh", "Benchmark the performance and stability of rigid bodies using convex hull collision shapes (btConvexHullShape), resting on a triangle mesh, btBvhTriangleMeshShape.", BenchmarkCreateFunc, 6),
ExampleEntry(1, "Raycast", "Benchmark the performance of the btCollisionWorld::rayTest. Note that currently the rays are not rendered.", BenchmarkCreateFunc, 7),
//#endif
ExampleEntry(0, "Importers"),
ExampleEntry(1, "Import .bullet", "Load a binary .bullet file. The serialization mechanism can deal with versioning, differences in endianess, 32 and 64bit, double/single precision. It is easy to save a .bullet file, see the examples/Importers/ImportBullet/SerializeDemo.cpp for a code example how to export a .bullet file.", SerializeBulletCreateFunc),
ExampleEntry(1, "Wavefront Obj", "Import a Wavefront .obj file", ImportObjCreateFunc, 0),
ExampleEntry(1, "Obj2RigidBody (Show Obj)", "Load a triangle mesh from Wavefront .obj and turn it in a convex hull collision shape, connected to a rigid body. We can use the original .obj mesh data to visualize the rigid body. In 'debug' wireframe mode (press 'w' to toggle) we still see the convex hull data.", ET_RigidBodyFromObjCreateFunc),
ExampleEntry(1, "Obj2RigidBody (Show Hull)", "Load a triangle mesh from Wavefront .obj and turn it in a convex hull collision shape, connected to a rigid body", ET_RigidBodyFromObjCreateFunc, ObjUseConvexHullForRendering),
ExampleEntry(1, "Obj2RigidBody Optimize", "Load a triangle mesh from Wavefront .obj, remove the vertices that are not on the convex hull", ET_RigidBodyFromObjCreateFunc, OptimizeConvexObj),
ExampleEntry(1, "Quake BSP", "Import a Quake .bsp file", ImportBspCreateFunc, 0),
ExampleEntry(1, "COLLADA dae", "Import the geometric mesh data from a COLLADA file. This is used as part of the URDF importer. This loader can also be used to import collision geometry in general. ",
ImportColladaCreateFunc, 0),
ExampleEntry(1, "STL", "Import the geometric mesh data from a STL file. This is used as part of the URDF importer. This loader can also be used to import collision geometry in general. ", ImportSTLCreateFunc, 0),
ExampleEntry(1, "URDF (RigidBody)", "Import a URDF file, and create rigid bodies (btRigidBody) connected by constraints.", ImportURDFCreateFunc, 0),
ExampleEntry(1, "URDF (MultiBody)", "Import a URDF file and create a single multibody (btMultiBody) with tree hierarchy of links (mobilizers).",
ImportURDFCreateFunc, 1),
ExampleEntry(1, "MJCF (MultiBody)", "Import a MJCF xml file, create multiple multibodies etc", ImportMJCFCreateFunc),
ExampleEntry(1, "SDF (MultiBody)", "Import an SDF file, create multiple multibodies etc", ImportSDFCreateFunc),
ExampleEntry(0,"Importers"),
ExampleEntry(1,"Import .bullet", "Load a binary .bullet file. The serialization mechanism can deal with versioning, differences in endianess, 32 and 64bit, double/single precision. It is easy to save a .bullet file, see the examples/Importers/ImportBullet/SerializeDemo.cpp for a code example how to export a .bullet file.", SerializeBulletCreateFunc),
ExampleEntry(1,"Wavefront Obj", "Import a Wavefront .obj file", ImportObjCreateFunc, 0),
ExampleEntry(1,"Obj2RigidBody (Show Obj)", "Load a triangle mesh from Wavefront .obj and turn it in a convex hull collision shape, connected to a rigid body. We can use the original .obj mesh data to visualize the rigid body. In 'debug' wireframe mode (press 'w' to toggle) we still see the convex hull data.", ET_RigidBodyFromObjCreateFunc),
ExampleEntry(1,"Obj2RigidBody (Show Hull)", "Load a triangle mesh from Wavefront .obj and turn it in a convex hull collision shape, connected to a rigid body", ET_RigidBodyFromObjCreateFunc,ObjUseConvexHullForRendering),
ExampleEntry(1,"Obj2RigidBody Optimize", "Load a triangle mesh from Wavefront .obj, remove the vertices that are not on the convex hull", ET_RigidBodyFromObjCreateFunc,OptimizeConvexObj),
ExampleEntry(0, "Vehicles"),
ExampleEntry(1, "Hinge2 Vehicle", "A rigid body chassis with 4 rigid body wheels attached by a btHinge2Constraint", Hinge2VehicleCreateFunc),
ExampleEntry(1, "ForkLift",
"Simulate a fork lift vehicle with a working fork lift that can be moved using the cursor keys. The wheels collision is simplified using ray tests."
"There are currently some issues with the wheel rendering, the wheels rotate when picking up the object."
"The demo implementation allows to choose various MLCP constraint solvers.",
ForkLiftCreateFunc),
ExampleEntry(1,"Quake BSP", "Import a Quake .bsp file", ImportBspCreateFunc, 0),
ExampleEntry(1,"COLLADA dae", "Import the geometric mesh data from a COLLADA file. This is used as part of the URDF importer. This loader can also be used to import collision geometry in general. ",
ImportColladaCreateFunc, 0),
ExampleEntry(1,"STL", "Import the geometric mesh data from a STL file. This is used as part of the URDF importer. This loader can also be used to import collision geometry in general. ",ImportSTLCreateFunc, 0),
ExampleEntry(1,"URDF (RigidBody)", "Import a URDF file, and create rigid bodies (btRigidBody) connected by constraints.", ImportURDFCreateFunc, 0),
ExampleEntry(1,"URDF (MultiBody)", "Import a URDF file and create a single multibody (btMultiBody) with tree hierarchy of links (mobilizers).",
ImportURDFCreateFunc, 1),
ExampleEntry(1,"MJCF (MultiBody)", "Import a MJCF xml file, create multiple multibodies etc", ImportMJCFCreateFunc),
ExampleEntry(0, "Raycast"),
ExampleEntry(1, "Raytest", "Cast rays using the btCollisionWorld::rayTest method. The example shows how to receive the hit position and normal along the ray against the first object. Also it shows how to receive all the hits along a ray.", RaytestCreateFunc),
ExampleEntry(1, "Raytracer", "Implement an extremely simple ray tracer using the ray trace functionality in btCollisionWorld.",
RayTracerCreateFunc),
ExampleEntry(1,"SDF (MultiBody)", "Import an SDF file, create multiple multibodies etc", ImportSDFCreateFunc),
ExampleEntry(0, "Experiments"),
ExampleEntry(0,"Vehicles"),
ExampleEntry(1,"Hinge2 Vehicle", "A rigid body chassis with 4 rigid body wheels attached by a btHinge2Constraint",Hinge2VehicleCreateFunc),
ExampleEntry(1,"ForkLift","Simulate a fork lift vehicle with a working fork lift that can be moved using the cursor keys. The wheels collision is simplified using ray tests."
"There are currently some issues with the wheel rendering, the wheels rotate when picking up the object."
"The demo implementation allows to choose various MLCP constraint solvers.",
ForkLiftCreateFunc),
ExampleEntry(1, "Robot Control", "Create a physics client and server to create and control robots.",
PhysicsClientCreateFunc, eCLIENTEXAMPLE_SERVER),
ExampleEntry(0,"Raycast"),
ExampleEntry(1,"Raytest", "Cast rays using the btCollisionWorld::rayTest method. The example shows how to receive the hit position and normal along the ray against the first object. Also it shows how to receive all the hits along a ray.", RaytestCreateFunc),
ExampleEntry(1,"Raytracer","Implement an extremely simple ray tracer using the ray trace functionality in btCollisionWorld.",
RayTracerCreateFunc),
ExampleEntry(0,"Experiments"),
ExampleEntry(1,"Robot Control", "Create a physics client and server to create and control robots.",
PhysicsClientCreateFunc, eCLIENTEXAMPLE_SERVER),
ExampleEntry(1,"R2D2 Grasp","Load the R2D2 robot from URDF file and control it to grasp objects", R2D2GraspExampleCreateFunc, eROBOTIC_LEARN_GRASP),
ExampleEntry(1,"Kuka IK","Control a Kuka IIWA robot to follow a target using IK. This IK is not setup properly yet.", KukaGraspExampleCreateFunc,0),
ExampleEntry(1,"URDF Compliant Contact","Work-in-progress, experiment/improve compliant rigid contact using parameters from URDF file (contact_cfm, contact_erp, lateral_friction, rolling_friction)", R2D2GraspExampleCreateFunc,eROBOTIC_LEARN_COMPLIANT_CONTACT),
ExampleEntry(1,"Rolling friction","Experiment on multibody rolling friction", R2D2GraspExampleCreateFunc,eROBOTIC_LEARN_ROLLING_FRICTION),
ExampleEntry(1,"Gripper Grasp","Grasp experiment with a gripper to improve contact model", GripperGraspExampleCreateFunc,eGRIPPER_GRASP),
ExampleEntry(1,"Two Point Grasp","Grasp experiment with two point contact to test rolling friction", GripperGraspExampleCreateFunc, eTWO_POINT_GRASP),
ExampleEntry(1,"One Motor Gripper Grasp","Grasp experiment with a gripper with one motor to test slider constraint for closed loop structure", GripperGraspExampleCreateFunc, eONE_MOTOR_GRASP),
#ifndef SKIP_SOFT_BODY_MULTI_BODY_DYNAMICS_WORLD
ExampleEntry(1,"Grasp Soft Body","Grasp soft body experiment", GripperGraspExampleCreateFunc, eGRASP_SOFT_BODY),
ExampleEntry(1,"Softbody Multibody Coupling","Two way coupling between soft body and multibody experiment", GripperGraspExampleCreateFunc, eSOFTBODY_MULTIBODY_COUPLING),
#endif //SKIP_SOFT_BODY_MULTI_BODY_DYNAMICS_WORLD
ExampleEntry(1, "R2D2 Grasp", "Load the R2D2 robot from URDF file and control it to grasp objects", R2D2GraspExampleCreateFunc, eROBOTIC_LEARN_GRASP),
ExampleEntry(1, "Kuka IK", "Control a Kuka IIWA robot to follow a target using IK. This IK is not setup properly yet.", KukaGraspExampleCreateFunc, 0),
ExampleEntry(1, "URDF Compliant Contact", "Work-in-progress, experiment/improve compliant rigid contact using parameters from URDF file (contact_cfm, contact_erp, lateral_friction, rolling_friction)", R2D2GraspExampleCreateFunc, eROBOTIC_LEARN_COMPLIANT_CONTACT),
ExampleEntry(1, "Rolling friction", "Experiment on multibody rolling friction", R2D2GraspExampleCreateFunc, eROBOTIC_LEARN_ROLLING_FRICTION),
ExampleEntry(1, "Gripper Grasp", "Grasp experiment with a gripper to improve contact model", GripperGraspExampleCreateFunc, eGRIPPER_GRASP),
ExampleEntry(1, "Two Point Grasp", "Grasp experiment with two point contact to test rolling friction", GripperGraspExampleCreateFunc, eTWO_POINT_GRASP),
ExampleEntry(1, "One Motor Gripper Grasp", "Grasp experiment with a gripper with one motor to test slider constraint for closed loop structure", GripperGraspExampleCreateFunc, eONE_MOTOR_GRASP),
#ifndef SKIP_SOFT_BODY_MULTI_BODY_DYNAMICS_WORLD
ExampleEntry(1, "Grasp Soft Body", "Grasp soft body experiment", GripperGraspExampleCreateFunc, eGRASP_SOFT_BODY),
ExampleEntry(1, "Softbody Multibody Coupling", "Two way coupling between soft body and multibody experiment", GripperGraspExampleCreateFunc, eSOFTBODY_MULTIBODY_COUPLING),
#endif //SKIP_SOFT_BODY_MULTI_BODY_DYNAMICS_WORLD
#ifdef ENABLE_LUA
ExampleEntry(1,"Lua Script", "Create the dynamics world, collision shapes and rigid bodies using Lua scripting",
LuaDemoCreateFunc),
ExampleEntry(1, "Lua Script", "Create the dynamics world, collision shapes and rigid bodies using Lua scripting",
LuaDemoCreateFunc),
#endif
ExampleEntry(1,"MultiThreading (submitJob)", "Simple example of executing jobs across multiple threads.",
MultiThreadingExampleCreateFunc,SINGLE_SIM_THREAD),
ExampleEntry(1, "MultiThreading (submitJob)", "Simple example of executing jobs across multiple threads.",
MultiThreadingExampleCreateFunc, SINGLE_SIM_THREAD),
ExampleEntry(1,"Voronoi Fracture", "Automatically create a compound rigid body using voronoi tesselation. Individual parts are modeled as rigid bodies using a btConvexHullShape.",
VoronoiFractureCreateFunc),
ExampleEntry(1, "Voronoi Fracture", "Automatically create a compound rigid body using voronoi tesselation. Individual parts are modeled as rigid bodies using a btConvexHullShape.",
VoronoiFractureCreateFunc),
ExampleEntry(1,"Fracture demo", "Create a basic custom implementation to model fracturing objects, based on a btCompoundShape. It explicitly propagates the collision impulses and breaks the rigid body into multiple rigid bodies. Press F to toggle fracture and glue mode.", FractureDemoCreateFunc),
ExampleEntry(1, "Fracture demo", "Create a basic custom implementation to model fracturing objects, based on a btCompoundShape. It explicitly propagates the collision impulses and breaks the rigid body into multiple rigid bodies. Press F to toggle fracture and glue mode.", FractureDemoCreateFunc),
ExampleEntry(1,"Planar 2D","Show the use of 2D collision shapes and rigid body simulation. The collision shape is wrapped into a btConvex2dShape. The rigid bodies are restricted in a plane using the 'setAngularFactor' and 'setLinearFactor' API call.",Planar2DCreateFunc),
ExampleEntry(1, "Planar 2D", "Show the use of 2D collision shapes and rigid body simulation. The collision shape is wrapped into a btConvex2dShape. The rigid bodies are restricted in a plane using the 'setAngularFactor' and 'setLinearFactor' API call.", Planar2DCreateFunc),
#if BT_THREADSAFE
// only enable MultiThreaded demo if a task scheduler is available
ExampleEntry( 1, "Multithreaded Demo",
"Stacks of boxes that do not sleep. Good for testing performance with large numbers of bodies and contacts. Sliders can be used to change the number of stacks (restart needed after each change)."
,
MultiThreadedDemoCreateFunc ),
// only enable MultiThreaded demo if a task scheduler is available
ExampleEntry(1, "Multithreaded Demo",
"Stacks of boxes that do not sleep. Good for testing performance with large numbers of bodies and contacts. Sliders can be used to change the number of stacks (restart needed after each change).",
MultiThreadedDemoCreateFunc),
#endif
ExampleEntry(0,"Rendering"),
ExampleEntry(1,"Instanced Rendering", "Simple example of fast instanced rendering, only active when using OpenGL3+.",RenderInstancingCreateFunc),
ExampleEntry(1,"CoordinateSystemDemo","Show the axis and positive rotation direction around the axis.", CoordinateSystemCreateFunc),
ExampleEntry(1,"Time Series", "Render some value(s) in a 2D graph window, shifting to the left", TimeSeriesCreateFunc),
ExampleEntry(1,"TinyRenderer", "Very small software renderer.", TinyRendererCreateFunc),
ExampleEntry(1,"Dynamic Texture", "Dynamic updated textured applied to a cube.", DynamicTexturedCubeDemoCreateFunc),
ExampleEntry(0, "Rendering"),
ExampleEntry(1, "Instanced Rendering", "Simple example of fast instanced rendering, only active when using OpenGL3+.", RenderInstancingCreateFunc),
ExampleEntry(1, "CoordinateSystemDemo", "Show the axis and positive rotation direction around the axis.", CoordinateSystemCreateFunc),
ExampleEntry(1, "Time Series", "Render some value(s) in a 2D graph window, shifting to the left", TimeSeriesCreateFunc),
ExampleEntry(1, "TinyRenderer", "Very small software renderer.", TinyRendererCreateFunc),
ExampleEntry(1, "Dynamic Texture", "Dynamic updated textured applied to a cube.", DynamicTexturedCubeDemoCreateFunc),
#ifdef B3_ENABLE_TINY_AUDIO
ExampleEntry(0,"Audio"),
ExampleEntry(1,"Simple Audio","Play some sound", TinyAudioExampleCreateFunc),
ExampleEntry(0, "Audio"),
ExampleEntry(1, "Simple Audio", "Play some sound", TinyAudioExampleCreateFunc),
#endif
//Extended Tutorials Added by Mobeen
ExampleEntry(0, "Extended Tutorials"),
ExampleEntry(1, "Simple Box", "Simplest possible demo creating a single box rigid body that falls under gravity", ET_SimpleBoxCreateFunc),
ExampleEntry(1, "Multiple Boxes", "Add multiple box rigid bodies that fall under gravity", ET_MultipleBoxesCreateFunc),
ExampleEntry(1, "Compound Boxes", "Add multiple boxes to a single CompoundShape to form a simple rigid L-beam, that falls under gravity", ET_CompoundBoxesCreateFunc),
ExampleEntry(1, "Simple Joint", "Create a single distance constraint between two box rigid bodies", ET_SimpleJointCreateFunc),
ExampleEntry(1, "Simple Cloth", "Create a simple piece of cloth", ET_SimpleClothCreateFunc),
ExampleEntry(1, "Simple Chain", "Create a simple chain using a pair of point2point/distance constraints. You may click and drag any box to see the chain respond.", ET_ChainCreateFunc),
ExampleEntry(1, "Simple Bridge", "Create a simple bridge using a pair of point2point/distance constraints. You may click and drag any plank to see the bridge respond.", ET_BridgeCreateFunc),
ExampleEntry(1, "Inclined Plane", "Create an inclined plane to show restitution and different types of friction. Use the sliders to vary restitution and friction and press space to reset the scene.", ET_InclinedPlaneCreateFunc),
ExampleEntry(1, "Newton's Cradle", "Create a Newton's Cradle using a pair of point2point/slider constraints. Press 1/2 to lengthen/shorten the pendula, press 3 to displace pendula. Use the sliders to select the number (reset simulation), length and restitution of pendula, the number of displaced pendula and apply the displacement force.", ET_NewtonsCradleCreateFunc),
ExampleEntry(1, "Newton's Rope Cradle", "Create a Newton's Cradle using ropes. Press 3 to displace pendula. Use the sliders to select the number (reset simulation), length and restitution of pendula and the number of displaced pendula and apply the displacement force.", ET_NewtonsRopeCradleCreateFunc),
ExampleEntry(1, "Multi-Pendulum", "Create a Multi-Pendulum using point2point/slider constraints. Press 1/2 to lengthen/shorten the pendula, press 3 to displace pendula. Use the sliders to select the number (reset simulation), length and restitution of pendula, the number of displaced pendula and apply the displacement force.", ET_MultiPendulumCreateFunc),
//Extended Tutorials Added by Mobeen
ExampleEntry(0,"Extended Tutorials"),
ExampleEntry(1,"Simple Box", "Simplest possible demo creating a single box rigid body that falls under gravity", ET_SimpleBoxCreateFunc),
ExampleEntry(1,"Multiple Boxes", "Add multiple box rigid bodies that fall under gravity", ET_MultipleBoxesCreateFunc),
ExampleEntry(1,"Compound Boxes", "Add multiple boxes to a single CompoundShape to form a simple rigid L-beam, that falls under gravity", ET_CompoundBoxesCreateFunc),
ExampleEntry(1,"Simple Joint", "Create a single distance constraint between two box rigid bodies", ET_SimpleJointCreateFunc),
ExampleEntry(1,"Simple Cloth", "Create a simple piece of cloth", ET_SimpleClothCreateFunc),
ExampleEntry(1,"Simple Chain", "Create a simple chain using a pair of point2point/distance constraints. You may click and drag any box to see the chain respond.", ET_ChainCreateFunc),
ExampleEntry(1,"Simple Bridge", "Create a simple bridge using a pair of point2point/distance constraints. You may click and drag any plank to see the bridge respond.", ET_BridgeCreateFunc),
ExampleEntry(1,"Inclined Plane", "Create an inclined plane to show restitution and different types of friction. Use the sliders to vary restitution and friction and press space to reset the scene.", ET_InclinedPlaneCreateFunc),
ExampleEntry(1,"Newton's Cradle", "Create a Newton's Cradle using a pair of point2point/slider constraints. Press 1/2 to lengthen/shorten the pendula, press 3 to displace pendula. Use the sliders to select the number (reset simulation), length and restitution of pendula, the number of displaced pendula and apply the displacement force.", ET_NewtonsCradleCreateFunc),
ExampleEntry(1,"Newton's Rope Cradle", "Create a Newton's Cradle using ropes. Press 3 to displace pendula. Use the sliders to select the number (reset simulation), length and restitution of pendula and the number of displaced pendula and apply the displacement force.",ET_NewtonsRopeCradleCreateFunc),
ExampleEntry(1,"Multi-Pendulum", "Create a Multi-Pendulum using point2point/slider constraints. Press 1/2 to lengthen/shorten the pendula, press 3 to displace pendula. Use the sliders to select the number (reset simulation), length and restitution of pendula, the number of displaced pendula and apply the displacement force.",ET_MultiPendulumCreateFunc),
ExampleEntry(9,"Evolution"),
ExampleEntry(1,"Neural Network 3D Walkers","A simple example of using evolution to make a creature walk.",ET_NN3DWalkersCreateFunc),
//todo: create a category/tutorial about advanced topics, such as optimizations, using different collision detection algorithm, different constraint solvers etc.
//ExampleEntry(0,"Advanced"),
//ExampleEntry(1,"Obj2RigidBody Add Features", "Load a triangle mesh from Wavefront .obj and create polyhedral features to perform the separating axis test (instead of GJK/MPR). It is best to combine optimization and polyhedral feature generation.", ET_RigidBodyFromObjCreateFunc,OptimizeConvexObj+ComputePolyhedralFeatures),
ExampleEntry(9, "Evolution"),
ExampleEntry(1, "Neural Network 3D Walkers", "A simple example of using evolution to make a creature walk.", ET_NN3DWalkersCreateFunc),
//todo: create a category/tutorial about advanced topics, such as optimizations, using different collision detection algorithm, different constraint solvers etc.
//ExampleEntry(0,"Advanced"),
//ExampleEntry(1,"Obj2RigidBody Add Features", "Load a triangle mesh from Wavefront .obj and create polyhedral features to perform the separating axis test (instead of GJK/MPR). It is best to combine optimization and polyhedral feature generation.", ET_RigidBodyFromObjCreateFunc,OptimizeConvexObj+ComputePolyhedralFeatures),
};
#ifdef B3_USE_CLEW
#ifndef NO_OPENGL3
static ExampleEntry gOpenCLExamples[]=
{
ExampleEntry(0,"OpenCL (experimental)"),
ExampleEntry(1,"Box-Box", "Full OpenCL implementation of the entire physics and collision detection pipeline, showing box-box rigid body",
OpenCLBoxBoxCreateFunc),
ExampleEntry(1,"Pair Bench", "Benchmark of overlapping pair search using OpenCL.", PairBenchOpenCLCreateFunc),
static ExampleEntry gOpenCLExamples[] =
{
ExampleEntry(0, "OpenCL (experimental)"),
ExampleEntry(1, "Box-Box", "Full OpenCL implementation of the entire physics and collision detection pipeline, showing box-box rigid body",
OpenCLBoxBoxCreateFunc),
ExampleEntry(1, "Pair Bench", "Benchmark of overlapping pair search using OpenCL.", PairBenchOpenCLCreateFunc),
};
#endif
#endif //
#endif //
static btAlignedObjectArray<ExampleEntry> gAdditionalRegisteredExamples;
struct ExampleEntriesInternalData
{
btAlignedObjectArray<ExampleEntry> m_allExamples;
@@ -379,51 +361,47 @@ void ExampleEntriesAll::initOpenCLExampleEntries()
{
#ifdef B3_USE_CLEW
#ifndef NO_OPENGL3
int numDefaultEntries = sizeof(gOpenCLExamples)/sizeof(ExampleEntry);
for (int i=0;i<numDefaultEntries;i++)
int numDefaultEntries = sizeof(gOpenCLExamples) / sizeof(ExampleEntry);
for (int i = 0; i < numDefaultEntries; i++)
{
m_data->m_allExamples.push_back(gOpenCLExamples[i]);
}
#endif
#endif //B3_USE_CLEW
#endif //B3_USE_CLEW
}
void ExampleEntriesAll::initExampleEntries()
{
m_data->m_allExamples.clear();
for (int i=0;i<gAdditionalRegisteredExamples.size();i++)
for (int i = 0; i < gAdditionalRegisteredExamples.size(); i++)
{
m_data->m_allExamples.push_back(gAdditionalRegisteredExamples[i]);
}
int numDefaultEntries = sizeof(gDefaultExamples)/sizeof(ExampleEntry);
for (int i=0;i<numDefaultEntries;i++)
int numDefaultEntries = sizeof(gDefaultExamples) / sizeof(ExampleEntry);
for (int i = 0; i < numDefaultEntries; i++)
{
m_data->m_allExamples.push_back(gDefaultExamples[i]);
}
if (m_data->m_allExamples.size()==0)
if (m_data->m_allExamples.size() == 0)
{
{
ExampleEntry e(0,"Empty");
ExampleEntry e(0, "Empty");
m_data->m_allExamples.push_back(e);
}
{
ExampleEntry e(1,"Empty","Empty Description", EmptyExample::CreateFunc);
ExampleEntry e(1, "Empty", "Empty Description", EmptyExample::CreateFunc);
m_data->m_allExamples.push_back(e);
}
}
}
void ExampleEntriesAll::registerExampleEntry(int menuLevel, const char* name,const char* description, CommonExampleInterface::CreateFunc* createFunc, int option)
void ExampleEntriesAll::registerExampleEntry(int menuLevel, const char* name, const char* description, CommonExampleInterface::CreateFunc* createFunc, int option)
{
ExampleEntry e( menuLevel,name,description, createFunc, option);
ExampleEntry e(menuLevel, name, description, createFunc, option);
gAdditionalRegisteredExamples.push_back(e);
}

View File

@@ -4,36 +4,29 @@
#include "../CommonInterfaces/CommonExampleInterface.h"
class ExampleEntriesAll : public ExampleEntries
{
struct ExampleEntriesInternalData* m_data;
public:
ExampleEntriesAll();
virtual ~ExampleEntriesAll();
static void registerExampleEntry(int menuLevel, const char* name,const char* description, CommonExampleInterface::CreateFunc* createFunc, int option=0);
static void registerExampleEntry(int menuLevel, const char* name, const char* description, CommonExampleInterface::CreateFunc* createFunc, int option = 0);
virtual void initExampleEntries();
virtual void initOpenCLExampleEntries();
virtual int getNumRegisteredExamples();
virtual CommonExampleInterface::CreateFunc* getExampleCreateFunc(int index);
virtual const char* getExampleName(int index);
virtual const char* getExampleDescription(int index);
virtual int getExampleOption(int index);
virtual int getExampleOption(int index);
};
#endif //EXAMPLE_ENTRIES_H
#endif //EXAMPLE_ENTRIES_H

File diff suppressed because it is too large Load Diff

View File

@@ -30,48 +30,52 @@ class GL_ShapeDrawer
protected:
struct ShapeCache
{
struct Edge { btVector3 n[2];int v[2]; };
ShapeCache(btConvexShape* s) : m_shapehull(s) {}
btShapeHull m_shapehull;
btAlignedObjectArray<Edge> m_edges;
struct Edge
{
btVector3 n[2];
int v[2];
};
ShapeCache(btConvexShape* s) : m_shapehull(s) {}
btShapeHull m_shapehull;
btAlignedObjectArray<Edge> m_edges;
};
//clean-up memory of dynamically created shape hulls
btAlignedObjectArray<ShapeCache*> m_shapecaches;
unsigned int m_texturehandle;
bool m_textureenabled;
bool m_textureinitialized;
btAlignedObjectArray<ShapeCache*> m_shapecaches;
unsigned int m_texturehandle;
bool m_textureenabled;
bool m_textureinitialized;
ShapeCache* cache(btConvexShape*);
ShapeCache* cache(btConvexShape*);
virtual void drawSceneInternal(const btDiscreteDynamicsWorld* world, int pass, int cameraUpAxis);
public:
GL_ShapeDrawer();
GL_ShapeDrawer();
virtual ~GL_ShapeDrawer();
virtual ~GL_ShapeDrawer();
virtual void drawScene(const btDiscreteDynamicsWorld* world, bool useShadows, int cameraUpAxis);
virtual void drawScene(const btDiscreteDynamicsWorld* world, bool useShadows, int cameraUpAxis);
///drawOpenGL might allocate temporary memoty, stores pointer in shape userpointer
virtual void drawOpenGL(btScalar* m, const btCollisionShape* shape, const btVector3& color, int debugMode, const btVector3& worldBoundsMin, const btVector3& worldBoundsMax);
virtual void drawShadow(btScalar* m, const btVector3& extrusion, const btCollisionShape* shape, const btVector3& worldBoundsMin, const btVector3& worldBoundsMax);
///drawOpenGL might allocate temporary memoty, stores pointer in shape userpointer
virtual void drawOpenGL(btScalar* m, const btCollisionShape* shape, const btVector3& color,int debugMode,const btVector3& worldBoundsMin,const btVector3& worldBoundsMax);
virtual void drawShadow(btScalar* m, const btVector3& extrusion,const btCollisionShape* shape,const btVector3& worldBoundsMin,const btVector3& worldBoundsMax);
bool enableTexture(bool enable) { bool p=m_textureenabled;m_textureenabled=enable;return(p); }
bool hasTextureEnabled() const
{
return m_textureenabled;
}
void drawSphere(btScalar r, int lats, int longs);
static void drawCoordSystem();
bool enableTexture(bool enable)
{
bool p = m_textureenabled;
m_textureenabled = enable;
return (p);
}
bool hasTextureEnabled() const
{
return m_textureenabled;
}
void drawSphere(btScalar r, int lats, int longs);
static void drawCoordSystem();
};
void OGL_displaylist_register_shape(btCollisionShape * shape);
void OGL_displaylist_register_shape(btCollisionShape* shape);
void OGL_displaylist_clean();
#endif //GL_SHAPE_DRAWER_H
#endif //GL_SHAPE_DRAWER_H

View File

@@ -3,9 +3,9 @@
#include <assert.h>
GraphingTexture::GraphingTexture()
:m_textureId(0),
m_width(0),
m_height(0)
: m_textureId(0),
m_width(0),
m_height(0)
{
}
@@ -18,10 +18,9 @@ void GraphingTexture::destroy()
{
//TODO(erwincoumans) release memory etc...
m_width = 0;
m_height=0;
glDeleteTextures(1,(GLuint*)&m_textureId);
m_textureId=0;
m_height = 0;
glDeleteTextures(1, (GLuint*)&m_textureId);
m_textureId = 0;
}
bool GraphingTexture::create(int texWidth, int texHeight)
@@ -29,50 +28,46 @@ bool GraphingTexture::create(int texWidth, int texHeight)
m_width = texWidth;
m_height = texHeight;
glActiveTexture(GL_TEXTURE0);
m_imageData.resize(texWidth*texHeight*4);
for(int y=0;y<texHeight;++y)
m_imageData.resize(texWidth * texHeight * 4);
for (int y = 0; y < texHeight; ++y)
{
// const int t=y>>5;
GLubyte* pi=&m_imageData[y*texWidth*4];
for(int x=0;x<texWidth;++x)
GLubyte* pi = &m_imageData[y * texWidth * 4];
for (int x = 0; x < texWidth; ++x)
{
if (x>=y)//x<2||y<2||x>253||y>253)
if (x >= y) //x<2||y<2||x>253||y>253)
{
pi[0]=0;
pi[1]=0;
pi[2]=255;
pi[3]=255;
} else
{
pi[0]=255;
pi[1]=0;
pi[2]=0;
pi[3]=255;
pi[0] = 0;
pi[1] = 0;
pi[2] = 255;
pi[3] = 255;
}
pi+=4;
else
{
pi[0] = 255;
pi[1] = 0;
pi[2] = 0;
pi[3] = 255;
}
pi += 4;
}
}
glGenTextures(1,(GLuint*)&m_textureId);
glGenTextures(1, (GLuint*)&m_textureId);
uploadImageData();
return true;
}
void GraphingTexture::uploadImageData()
{
glBindTexture(GL_TEXTURE_2D,m_textureId);
assert(glGetError()==GL_NO_ERROR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width,m_height,0,GL_RGBA,GL_UNSIGNED_BYTE,&m_imageData[0]);
glBindTexture(GL_TEXTURE_2D, m_textureId);
assert(glGetError() == GL_NO_ERROR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &m_imageData[0]);
glGenerateMipmap(GL_TEXTURE_2D);
assert(glGetError()==GL_NO_ERROR);
assert(glGetError() == GL_NO_ERROR);
}

View File

@@ -9,38 +9,37 @@ struct GraphingTexture
btAlignedObjectArray<unsigned char> m_imageData;
int m_width;
int m_height;
GraphingTexture();
virtual ~GraphingTexture();
bool create(int texWidth, int texHeight);
void destroy();
void destroy();
void setPixel(int x, int y, unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha)
{
if (y>=0 && y<m_height && x>=0 && x<m_width)
if (y >= 0 && y < m_height && x >= 0 && x < m_width)
{
m_imageData[x*4+y*4*m_width+0] = red;
m_imageData[x*4+y*4*m_width+1] = green;
m_imageData[x*4+y*4*m_width+2] = blue;
m_imageData[x*4+y*4*m_width+3] = alpha;
m_imageData[x * 4 + y * 4 * m_width + 0] = red;
m_imageData[x * 4 + y * 4 * m_width + 1] = green;
m_imageData[x * 4 + y * 4 * m_width + 2] = blue;
m_imageData[x * 4 + y * 4 * m_width + 3] = alpha;
}
}
void getPixel(int x, int y, unsigned char& red, unsigned char& green, unsigned char& blue, unsigned char& alpha)
{
red = m_imageData[x*4+y*4*m_width+0];
green = m_imageData[x*4+y*4*m_width+1];
blue = m_imageData[x*4+y*4*m_width+2];
alpha = m_imageData[x*4+y*4*m_width+3];
red = m_imageData[x * 4 + y * 4 * m_width + 0];
green = m_imageData[x * 4 + y * 4 * m_width + 1];
blue = m_imageData[x * 4 + y * 4 * m_width + 2];
alpha = m_imageData[x * 4 + y * 4 * m_width + 3];
}
void uploadImageData();
int getTextureId()
{
return m_textureId;
}
};
#endif //GRAPHING_TEXTURE_H
#endif //GRAPHING_TEXTURE_H

View File

@@ -3,35 +3,34 @@
struct MyButtonEventHandler : public Gwen::Event::Handler
{
Gwen::Controls::Button* m_buttonControl;
Gwen::Controls::Button* m_buttonControl;
ButtonParamChangedCallback m_callback;
void* m_userPointer;
int m_buttonId;
MyButtonEventHandler(Gwen::Controls::Button* buttonControl, ButtonParamChangedCallback callback, int buttonId, void* userPointer)
:m_buttonControl(buttonControl),
m_callback(callback),
m_userPointer(userPointer),
m_buttonId(buttonId)
: m_buttonControl(buttonControl),
m_callback(callback),
m_userPointer(userPointer),
m_buttonId(buttonId)
{
}
void onButtonPress( Gwen::Controls::Base* pControl )
void onButtonPress(Gwen::Controls::Base* pControl)
{
if (m_callback)
{
bool buttonState = true;
if (m_buttonControl->IsToggle())
{
buttonState = m_buttonControl->GetToggleState();
}
( *m_callback )( m_buttonId, buttonState, m_userPointer );
bool buttonState = true;
if (m_buttonControl->IsToggle())
{
buttonState = m_buttonControl->GetToggleState();
}
(*m_callback)(m_buttonId, buttonState, m_userPointer);
}
}
};
template<typename T>
template <typename T>
struct MySliderEventHandler : public Gwen::Event::Handler
{
SliderParamChangedCallback m_callback;
@@ -40,22 +39,21 @@ struct MySliderEventHandler : public Gwen::Event::Handler
Gwen::Controls::Slider* m_pSlider;
char m_variableName[1024];
T* m_targetValue;
bool m_showValue;
bool m_showValue;
MySliderEventHandler(const char* varName, Gwen::Controls::TextBox* label, Gwen::Controls::Slider* pSlider,T* target, SliderParamChangedCallback callback, void* userPtr)
: m_callback(callback),
m_userPointer(userPtr),
m_label(label),
m_pSlider(pSlider),
m_targetValue(target),
m_showValue(true)
MySliderEventHandler(const char* varName, Gwen::Controls::TextBox* label, Gwen::Controls::Slider* pSlider, T* target, SliderParamChangedCallback callback, void* userPtr)
: m_callback(callback),
m_userPointer(userPtr),
m_label(label),
m_pSlider(pSlider),
m_targetValue(target),
m_showValue(true)
{
memcpy(m_variableName,varName,strlen(varName)+1);
memcpy(m_variableName, varName, strlen(varName) + 1);
}
void SliderMoved( Gwen::Controls::Base* pControl )
void SliderMoved(Gwen::Controls::Base* pControl)
{
Gwen::Controls::Slider* pSlider = (Gwen::Controls::Slider*)pControl;
//printf("value = %f\n", pSlider->GetValue());//UnitPrint( Utility::Format( L"Slider Value: %.2f", pSlider->GetValue() ) );
@@ -67,10 +65,9 @@ struct MySliderEventHandler : public Gwen::Event::Handler
{
(*m_callback)(v, m_userPointer);
}
}
void SetValue(T v)
void SetValue(T v)
{
if (v < m_pSlider->GetRangeMin())
{
@@ -79,24 +76,21 @@ struct MySliderEventHandler : public Gwen::Event::Handler
if (v > m_pSlider->GetRangeMax())
{
printf("?\n");
printf("?\n");
}
m_pSlider->SetValue(v,true);
m_pSlider->SetValue(v, true);
(*m_targetValue) = v;
float val = float(v);//todo: specialize on template type
if (m_showValue)
{
char txt[1024];
sprintf(txt,"%s : %.3f", m_variableName,val);
m_label->SetText(txt);
}
float val = float(v); //todo: specialize on template type
if (m_showValue)
{
char txt[1024];
sprintf(txt, "%s : %.3f", m_variableName, val);
m_label->SetText(txt);
}
}
};
struct GwenParameters
struct GwenParameters
{
b3AlignedObjectArray<MySliderEventHandler<btScalar>*> m_sliderEventHandlers;
b3AlignedObjectArray<Gwen::Controls::HorizontalSlider*> m_sliders;
@@ -108,113 +102,103 @@ struct GwenParameters
};
GwenParameterInterface::GwenParameterInterface(GwenInternalData* gwenInternalData)
:m_gwenInternalData(gwenInternalData)
: m_gwenInternalData(gwenInternalData)
{
m_paramInternalData = new GwenParameters;
m_paramInternalData->m_savedYposition = m_gwenInternalData->m_curYposition;
}
GwenParameterInterface::~GwenParameterInterface()
{
removeAllParameters();
delete m_paramInternalData;
}
void GwenParameterInterface::setSliderValue(int sliderIndex, double sliderValue)
{
int sliderCapped = sliderValue+4;
sliderCapped /= 8;
sliderCapped *= 8;
if (sliderIndex>=0 && sliderIndex<m_paramInternalData->m_sliders.size())
{
m_paramInternalData->m_sliders[sliderIndex]->GetRangeMin();
m_paramInternalData->m_sliders[sliderIndex]->GetRangeMax();
float mappedValue =m_paramInternalData->m_sliders[sliderIndex]->GetRangeMin()+
(m_paramInternalData->m_sliders[sliderIndex]->GetRangeMax()-
m_paramInternalData->m_sliders[sliderIndex]->GetRangeMin())*sliderCapped/128.f;
printf("mappedValue = %f\n",mappedValue);
m_paramInternalData->m_sliders[sliderIndex]->SetValue(mappedValue);
}
int sliderCapped = sliderValue + 4;
sliderCapped /= 8;
sliderCapped *= 8;
if (sliderIndex >= 0 && sliderIndex < m_paramInternalData->m_sliders.size())
{
m_paramInternalData->m_sliders[sliderIndex]->GetRangeMin();
m_paramInternalData->m_sliders[sliderIndex]->GetRangeMax();
float mappedValue = m_paramInternalData->m_sliders[sliderIndex]->GetRangeMin() +
(m_paramInternalData->m_sliders[sliderIndex]->GetRangeMax() -
m_paramInternalData->m_sliders[sliderIndex]->GetRangeMin()) *
sliderCapped / 128.f;
printf("mappedValue = %f\n", mappedValue);
m_paramInternalData->m_sliders[sliderIndex]->SetValue(mappedValue);
}
}
#include <stdio.h>
void GwenParameterInterface::registerButtonParameter(ButtonParams& params)
{
Gwen::Controls::Button* button = new Gwen::Controls::Button(m_gwenInternalData->m_demoPage->GetPage());
MyButtonEventHandler* handler = new MyButtonEventHandler(button, params.m_callback,params.m_buttonId,params.m_userPointer);
MyButtonEventHandler* handler = new MyButtonEventHandler(button, params.m_callback, params.m_buttonId, params.m_userPointer);
button->SetText(params.m_name);
button->onPress.Add( handler, &MyButtonEventHandler::onButtonPress );
button->SetIsToggle(params.m_isTrigger);
button->SetToggleState(params.m_initialState);
button->onPress.Add(handler, &MyButtonEventHandler::onButtonPress);
button->SetIsToggle(params.m_isTrigger);
button->SetToggleState(params.m_initialState);
m_paramInternalData->m_buttons.push_back(button);
m_paramInternalData->m_buttonEventHandlers.push_back(handler);
button->SetPos( 5, m_gwenInternalData->m_curYposition );
button->SetPos(5, m_gwenInternalData->m_curYposition);
button->SetWidth(220);
m_gwenInternalData->m_curYposition+=22;
m_gwenInternalData->m_curYposition += 22;
}
struct MyComboBoxHander2 :public Gwen::Event::Handler
struct MyComboBoxHander2 : public Gwen::Event::Handler
{
GwenInternalData* m_data;
int m_buttonId;
ComboBoxCallback m_callback;
void* m_userPointer;
GwenInternalData* m_data;
int m_buttonId;
ComboBoxCallback m_callback;
void* m_userPointer;
MyComboBoxHander2 (GwenInternalData* data, int buttonId,ComboBoxCallback callback, void* userPointer)
:m_data(data),
m_buttonId(buttonId),
m_callback(callback),
m_userPointer(userPointer)
MyComboBoxHander2(GwenInternalData* data, int buttonId, ComboBoxCallback callback, void* userPointer)
: m_data(data),
m_buttonId(buttonId),
m_callback(callback),
m_userPointer(userPointer)
{
}
void onSelect( Gwen::Controls::Base* pControl )
void onSelect(Gwen::Controls::Base* pControl)
{
Gwen::Controls::ComboBox* but = (Gwen::Controls::ComboBox*) pControl;
Gwen::Controls::ComboBox* but = (Gwen::Controls::ComboBox*)pControl;
Gwen::String str = Gwen::Utility::UnicodeToString( but->GetSelectedItem()->GetText());
Gwen::String str = Gwen::Utility::UnicodeToString(but->GetSelectedItem()->GetText());
if (m_callback)
(*m_callback)(m_buttonId,str.c_str(),m_userPointer);
(*m_callback)(m_buttonId, str.c_str(), m_userPointer);
}
};
void GwenParameterInterface::registerComboBox(ComboBoxParams& params)
{
Gwen::Controls::ComboBox* combobox = new Gwen::Controls::ComboBox(m_gwenInternalData->m_demoPage->GetPage());
m_paramInternalData->m_comboBoxes.push_back(combobox);
MyComboBoxHander2* handler = new MyComboBoxHander2(m_gwenInternalData, params.m_comboboxId,params.m_callback, params.m_userPointer);
MyComboBoxHander2* handler = new MyComboBoxHander2(m_gwenInternalData, params.m_comboboxId, params.m_callback, params.m_userPointer);
m_gwenInternalData->m_handlers.push_back(handler);
combobox->onSelection.Add(handler,&MyComboBoxHander2::onSelect);
combobox->onSelection.Add(handler, &MyComboBoxHander2::onSelect);
int ypos = m_gwenInternalData->m_curYposition;
m_gwenInternalData->m_curYposition+=22;
combobox->SetPos(5, ypos );
combobox->SetWidth( 220 );
m_gwenInternalData->m_curYposition += 22;
combobox->SetPos(5, ypos);
combobox->SetWidth(220);
//box->SetPos(120,130);
for (int i=0;i<params.m_numItems;i++)
for (int i = 0; i < params.m_numItems; i++)
{
Gwen::Controls::MenuItem* item = combobox->AddItem(Gwen::Utility::StringToUnicode(params.m_items[i]));
if (i==params.m_startItem)
if (i == params.m_startItem)
combobox->OnItemSelected(item);
}
}
void GwenParameterInterface::registerSliderFloatParameter(SliderParams& params)
@@ -222,99 +206,94 @@ void GwenParameterInterface::registerSliderFloatParameter(SliderParams& params)
Gwen::Controls::TextBox* label = new Gwen::Controls::TextBox(m_gwenInternalData->m_demoPage->GetPage());
m_paramInternalData->m_textLabels.push_back(label);
//m_data->m_myControls.push_back(label);
label->SetText( params.m_name);
label->SetPos( 10, 10 + 25 );
label->SetText(params.m_name);
label->SetPos(10, 10 + 25);
label->SetWidth(210);
label->SetPos(10,m_gwenInternalData->m_curYposition);
m_gwenInternalData->m_curYposition+=22;
label->SetPos(10, m_gwenInternalData->m_curYposition);
m_gwenInternalData->m_curYposition += 22;
Gwen::Controls::HorizontalSlider* pSlider = new Gwen::Controls::HorizontalSlider( m_gwenInternalData->m_demoPage->GetPage());
Gwen::Controls::HorizontalSlider* pSlider = new Gwen::Controls::HorizontalSlider(m_gwenInternalData->m_demoPage->GetPage());
m_paramInternalData->m_sliders.push_back(pSlider);
//m_data->m_myControls.push_back(pSlider);
pSlider->SetPos( 10, m_gwenInternalData->m_curYposition );
pSlider->SetSize( 200, 20 );
pSlider->SetRange( params.m_minVal, params.m_maxVal);
if (params.m_clampToIntegers)
{
pSlider->SetNotchCount( int( params.m_maxVal - params.m_minVal ) );
pSlider->SetClampToNotches( true );
}
else
{
pSlider->SetNotchCount( 16 );//float(params.m_maxVal-params.m_minVal)/100.f);
pSlider->SetClampToNotches( params.m_clampToNotches );
}
pSlider->SetValue( *params.m_paramValuePointer);//dimensions[i] );
pSlider->SetPos(10, m_gwenInternalData->m_curYposition);
pSlider->SetSize(200, 20);
pSlider->SetRange(params.m_minVal, params.m_maxVal);
if (params.m_clampToIntegers)
{
pSlider->SetNotchCount(int(params.m_maxVal - params.m_minVal));
pSlider->SetClampToNotches(true);
}
else
{
pSlider->SetNotchCount(16); //float(params.m_maxVal-params.m_minVal)/100.f);
pSlider->SetClampToNotches(params.m_clampToNotches);
}
pSlider->SetValue(*params.m_paramValuePointer); //dimensions[i] );
char labelName[1024];
sprintf(labelName,"%s",params.m_name);//axisNames[0]);
MySliderEventHandler<btScalar>* handler = new MySliderEventHandler<btScalar>(labelName,label,pSlider,params.m_paramValuePointer,params.m_callback, params.m_userPointer);
handler->m_showValue = params.m_showValues;
sprintf(labelName, "%s", params.m_name); //axisNames[0]);
MySliderEventHandler<btScalar>* handler = new MySliderEventHandler<btScalar>(labelName, label, pSlider, params.m_paramValuePointer, params.m_callback, params.m_userPointer);
handler->m_showValue = params.m_showValues;
m_paramInternalData->m_sliderEventHandlers.push_back(handler);
pSlider->onValueChanged.Add( handler, &MySliderEventHandler<btScalar>::SliderMoved );
pSlider->onValueChanged.Add(handler, &MySliderEventHandler<btScalar>::SliderMoved);
handler->SliderMoved(pSlider);
// float v = pSlider->GetValue();
m_gwenInternalData->m_curYposition+=22;
// float v = pSlider->GetValue();
m_gwenInternalData->m_curYposition += 22;
}
void GwenParameterInterface::syncParameters()
{
for (int i=0;i<m_paramInternalData->m_sliderEventHandlers.size();i++)
for (int i = 0; i < m_paramInternalData->m_sliderEventHandlers.size(); i++)
{
MySliderEventHandler<btScalar>* handler = m_paramInternalData->m_sliderEventHandlers[i];
handler->m_pSlider->SetValue(*handler->m_targetValue,true);
handler->m_pSlider->SetValue(*handler->m_targetValue, true);
}
}
void GwenParameterInterface::removeAllParameters()
{
for (int i=0;i<m_paramInternalData->m_buttons.size();i++)
for (int i = 0; i < m_paramInternalData->m_buttons.size(); i++)
{
delete m_paramInternalData->m_buttons[i];
}
m_paramInternalData->m_buttons.clear();
for (int i=0;i<m_paramInternalData->m_buttonEventHandlers.size();i++)
for (int i = 0; i < m_paramInternalData->m_buttonEventHandlers.size(); i++)
{
delete m_paramInternalData->m_buttonEventHandlers[i];
}
m_paramInternalData->m_buttonEventHandlers.clear();
m_gwenInternalData->m_curYposition+=22;
for (int i=0;i<m_paramInternalData->m_sliders.size();i++)
m_gwenInternalData->m_curYposition += 22;
for (int i = 0; i < m_paramInternalData->m_sliders.size(); i++)
{
delete m_paramInternalData->m_sliders[i];
}
m_paramInternalData->m_sliders.clear();
for (int i=0;i<m_paramInternalData->m_sliderEventHandlers.size();i++)
for (int i = 0; i < m_paramInternalData->m_sliderEventHandlers.size(); i++)
{
delete m_paramInternalData->m_sliderEventHandlers[i];
}
m_paramInternalData->m_sliderEventHandlers.clear();
for (int i=0;i<m_paramInternalData->m_textLabels.size();i++)
for (int i = 0; i < m_paramInternalData->m_textLabels.size(); i++)
{
delete m_paramInternalData->m_textLabels[i];
}
m_paramInternalData->m_textLabels.clear();
for (int i=0;i<m_paramInternalData->m_comboBoxes.size();i++)
for (int i = 0; i < m_paramInternalData->m_comboBoxes.size(); i++)
{
delete m_paramInternalData->m_comboBoxes[i];
}
m_paramInternalData->m_comboBoxes.clear();
m_gwenInternalData->m_curYposition = this->m_paramInternalData->m_savedYposition;
for (int i=0;i<m_gwenInternalData->m_handlers.size();i++)
for (int i = 0; i < m_gwenInternalData->m_handlers.size(); i++)
{
delete m_gwenInternalData->m_handlers[i];
}
m_gwenInternalData->m_handlers.clear();
}

View File

@@ -7,7 +7,7 @@ struct GwenParameterInterface : public CommonParameterInterface
{
struct GwenInternalData* m_gwenInternalData;
struct GwenParameters* m_paramInternalData;
struct GwenParameters* m_paramInternalData;
GwenParameterInterface(struct GwenInternalData* gwenInternalData);
virtual ~GwenParameterInterface();
@@ -15,12 +15,9 @@ struct GwenParameterInterface : public CommonParameterInterface
virtual void registerButtonParameter(ButtonParams& params);
virtual void registerComboBox(ComboBoxParams& params);
virtual void setSliderValue(int sliderIndex, double sliderValue);
virtual void setSliderValue(int sliderIndex, double sliderValue);
virtual void syncParameters();
virtual void removeAllParameters();
};
#endif//GWEN_PARAMETER_INTERFACE_H
#endif //GWEN_PARAMETER_INTERFACE_H

View File

@@ -3,293 +3,258 @@
#include "gwenInternalData.h"
#include "LinearMath/btQuickprof.h"
#ifndef BT_NO_PROFILE
#ifndef BT_NO_PROFILE
class MyProfileWindow : public Gwen::Controls::WindowControl
{
// Gwen::Controls::TabControl* m_TabControl;
//Gwen::Controls::ListBox* m_TextOutput;
unsigned int m_iFrames;
float m_fLastSecond;
unsigned int m_iFrames;
float m_fLastSecond;
Gwen::Controls::TreeNode* m_node;
Gwen::Controls::TreeControl* m_ctrl;
protected:
void onButtonA( Gwen::Controls::Base* pControl )
void onButtonA(Gwen::Controls::Base* pControl)
{
// OpenTissue::glut::toggleIdle();
// OpenTissue::glut::toggleIdle();
}
void SliderMoved(Gwen::Controls::Base* pControl )
void SliderMoved(Gwen::Controls::Base* pControl)
{
// Gwen::Controls::Slider* pSlider = (Gwen::Controls::Slider*)pControl;
// Gwen::Controls::Slider* pSlider = (Gwen::Controls::Slider*)pControl;
//this->m_app->scaleYoungModulus(pSlider->GetValue());
// printf("Slider Value: %.2f", pSlider->GetValue() );
}
void OnCheckChangedStiffnessWarping (Gwen::Controls::Base* pControl)
void OnCheckChangedStiffnessWarping(Gwen::Controls::Base* pControl)
{
// Gwen::Controls::CheckBox* labeled = (Gwen::Controls::CheckBox* )pControl;
// bool checked = labeled->IsChecked();
// Gwen::Controls::CheckBox* labeled = (Gwen::Controls::CheckBox* )pControl;
// bool checked = labeled->IsChecked();
//m_app->m_stiffness_warp_on = checked;
}
public:
CProfileIterator* profIter;
class MyMenuItems3* m_menuItems;
MyProfileWindow ( Gwen::Controls::Base* pParent)
: Gwen::Controls::WindowControl( pParent ),
profIter(0)
MyProfileWindow(Gwen::Controls::Base* pParent)
: Gwen::Controls::WindowControl(pParent),
profIter(0)
{
SetTitle( L"Time Profiler" );
SetSize( 450, 450 );
this->SetPos(10,400);
// this->Dock( Gwen::Pos::Bottom);
SetTitle(L"Time Profiler");
SetSize(450, 450);
this->SetPos(10, 400);
// this->Dock( Gwen::Pos::Bottom);
{
m_ctrl = new Gwen::Controls::TreeControl( this );
m_node = m_ctrl->AddNode( L"Total Parent Time" );
m_ctrl = new Gwen::Controls::TreeControl(this);
m_node = m_ctrl->AddNode(L"Total Parent Time");
//Gwen::Controls::TreeNode* pNode = ctrl->AddNode( L"Node Two" );
//pNode->AddNode( L"Node Two Inside" );
//pNode->AddNode( L"Eyes" );
//pNode->AddNode( L"Brown" )->AddNode( L"Node Two Inside" )->AddNode( L"Eyes" )->AddNode( L"Brown" );
//Gwen::Controls::TreeNode* node = ctrl->AddNode( L"Node Three" );
//m_ctrl->Dock(Gwen::Pos::Bottom);
m_ctrl->ExpandAll();
m_ctrl->SetKeyboardInputEnabled(true);
m_ctrl->SetBounds( this->GetInnerBounds().x,this->GetInnerBounds().y,this->GetInnerBounds().w,this->GetInnerBounds().h);
m_ctrl->SetKeyboardInputEnabled(true);
m_ctrl->SetBounds(this->GetInnerBounds().x, this->GetInnerBounds().y, this->GetInnerBounds().w, this->GetInnerBounds().h);
}
}
virtual ~MyProfileWindow()
{
delete m_node;
delete m_ctrl;
}
float dumpRecursive(CProfileIterator* profileIterator, Gwen::Controls::TreeNode* parentNode)
float dumpRecursive(CProfileIterator* profileIterator, Gwen::Controls::TreeNode* parentNode)
{
profileIterator->First();
if (profileIterator->Is_Done())
return 0.f;
float accumulated_time=0,parent_time = profileIterator->Is_Root() ? CProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time();
float accumulated_time = 0, parent_time = profileIterator->Is_Root() ? CProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time();
int i;
int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset();
if (0==frames_since_reset)
if (0 == frames_since_reset)
return 0.f;
//printf("Profiling: %s (total running time: %.3f ms) ---\n", profileIterator->Get_Current_Parent_Name(), parent_time );
float totalTime = 0.f;
int numChildren = 0;
Gwen::UnicodeString txt;
std::vector<Gwen::Controls::TreeNode*> nodes;
for (i = 0; !profileIterator->Is_Done(); i++,profileIterator->Next())
for (i = 0; !profileIterator->Is_Done(); i++, profileIterator->Next())
{
numChildren++;
float current_total_time = profileIterator->Get_Current_Total_Time();
accumulated_time += current_total_time;
double fraction = parent_time > SIMD_EPSILON ? (current_total_time / parent_time) * 100 : 0.f;
Gwen::String name(profileIterator->Get_Current_Name());
#ifdef _WIN32
Gwen::UnicodeString uname = Gwen::Utility::StringToUnicode(name);
txt = Gwen::Utility::Format(L"%s (%.2f %%) :: %.3f ms / frame (%d calls)",uname.c_str(), fraction,(current_total_time / (double)frames_since_reset),profileIterator->Get_Current_Total_Calls());
txt = Gwen::Utility::Format(L"%s (%.2f %%) :: %.3f ms / frame (%d calls)", uname.c_str(), fraction, (current_total_time / (double)frames_since_reset), profileIterator->Get_Current_Total_Calls());
#else
txt = Gwen::Utility::Format(L"%s (%.2f %%) :: %.3f ms / frame (%d calls)",name.c_str(), fraction,(current_total_time / (double)frames_since_reset),profileIterator->Get_Current_Total_Calls());
txt = Gwen::Utility::Format(L"%s (%.2f %%) :: %.3f ms / frame (%d calls)", name.c_str(), fraction, (current_total_time / (double)frames_since_reset), profileIterator->Get_Current_Total_Calls());
#endif
Gwen::Controls::TreeNode* childNode = (Gwen::Controls::TreeNode*)profileIterator->Get_Current_UserPointer();
if (!childNode)
{
childNode = parentNode->AddNode(L"");
profileIterator->Set_Current_UserPointer(childNode);
childNode = parentNode->AddNode(L"");
profileIterator->Set_Current_UserPointer(childNode);
}
childNode->SetText(txt);
nodes.push_back(childNode);
totalTime += current_total_time;
//recurse into children
}
for (i=0;i<numChildren;i++)
for (i = 0; i < numChildren; i++)
{
profileIterator->Enter_Child(i);
Gwen::Controls::TreeNode* curNode = nodes[i];
dumpRecursive(profileIterator, curNode);
profileIterator->Enter_Parent();
}
return accumulated_time;
}
void UpdateText(CProfileIterator* profileIterator, bool idle)
void UpdateText(CProfileIterator* profileIterator, bool idle)
{
// static bool update=true;
m_ctrl->SetBounds(0,0,this->GetInnerBounds().w,this->GetInnerBounds().h);
// if (!update)
// return;
// update=false;
// static bool update=true;
m_ctrl->SetBounds(0, 0, this->GetInnerBounds().w, this->GetInnerBounds().h);
// if (!update)
// return;
// update=false;
static int test = 1;
test++;
static double time_since_reset = 0.f;
if (!idle)
{
time_since_reset = CProfileManager::Get_Time_Since_Reset();
}
//Gwen::UnicodeString txt = Gwen::Utility::Format( L"FEM Settings %i fps", test );
{
//recompute profiling data, and store profile strings
// char blockTime[128];
// double totalTime = 0;
// int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset();
profileIterator->First();
double parent_time = profileIterator->Is_Root() ? time_since_reset : profileIterator->Get_Current_Parent_Total_Time();
// Gwen::Controls::TreeNode* curParent = m_node;
//recompute profiling data, and store profile strings
// char blockTime[128];
double accumulated_time = dumpRecursive(profileIterator,m_node);
const char* name = profileIterator->Get_Current_Parent_Name();
// double totalTime = 0;
// int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset();
profileIterator->First();
double parent_time = profileIterator->Is_Root() ? time_since_reset : profileIterator->Get_Current_Parent_Total_Time();
// Gwen::Controls::TreeNode* curParent = m_node;
double accumulated_time = dumpRecursive(profileIterator, m_node);
const char* name = profileIterator->Get_Current_Parent_Name();
#ifdef _WIN32
Gwen::UnicodeString uname = Gwen::Utility::StringToUnicode(name);
Gwen::UnicodeString txt = Gwen::Utility::Format( L"Profiling: %s total time: %.3f ms, unaccounted %.3f %% :: %.3f ms", uname.c_str(), parent_time ,
parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time);
Gwen::UnicodeString uname = Gwen::Utility::StringToUnicode(name);
Gwen::UnicodeString txt = Gwen::Utility::Format(L"Profiling: %s total time: %.3f ms, unaccounted %.3f %% :: %.3f ms", uname.c_str(), parent_time,
parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time);
#else
Gwen::UnicodeString txt = Gwen::Utility::Format( L"Profiling: %s total time: %.3f ms, unaccounted %.3f %% :: %.3f ms", name, parent_time ,
parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time);
Gwen::UnicodeString txt = Gwen::Utility::Format(L"Profiling: %s total time: %.3f ms, unaccounted %.3f %% :: %.3f ms", name, parent_time,
parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time);
#endif
//sprintf(blockTime,"--- Profiling: %s (total running time: %.3f ms) ---", profileIterator->Get_Current_Parent_Name(), parent_time );
//displayProfileString(xOffset,yStart,blockTime);
m_node->SetText(txt);
//sprintf(blockTime,"--- Profiling: %s (total running time: %.3f ms) ---", profileIterator->Get_Current_Parent_Name(), parent_time );
//displayProfileString(xOffset,yStart,blockTime);
m_node->SetText(txt);
//printf("%s (%.3f %%) :: %.3f ms\n", "Unaccounted:",);
}
static int counter=10;
static int counter = 10;
if (counter)
{
counter--;
counter--;
m_ctrl->ExpandAll();
}
}
void PrintText( const Gwen::UnicodeString& str )
void PrintText(const Gwen::UnicodeString& str)
{
}
void Render( Gwen::Skin::Base* skin )
void Render(Gwen::Skin::Base* skin)
{
m_iFrames++;
if ( m_fLastSecond < Gwen::Platform::GetTimeInSeconds() )
if (m_fLastSecond < Gwen::Platform::GetTimeInSeconds())
{
SetTitle( Gwen::Utility::Format( L"Profiler %i fps", m_iFrames ) );
SetTitle(Gwen::Utility::Format(L"Profiler %i fps", m_iFrames));
m_fLastSecond = Gwen::Platform::GetTimeInSeconds() + 1.0f;
m_iFrames = 0;
}
Gwen::Controls::WindowControl::Render( skin );
Gwen::Controls::WindowControl::Render(skin);
}
};
class MyMenuItems3 : public Gwen::Controls::Base
class MyMenuItems3 : public Gwen::Controls::Base
{
public:
class MyProfileWindow* m_profWindow;
MyMenuItems3() :Gwen::Controls::Base(0)
{
}
virtual ~MyMenuItems3() {}
void MenuItemSelect(Gwen::Controls::Base* pControl)
{
MyMenuItems3() : Gwen::Controls::Base(0)
{
}
virtual ~MyMenuItems3() {}
void MenuItemSelect(Gwen::Controls::Base* pControl)
{
if (m_profWindow->Hidden())
{
m_profWindow->SetHidden(false);
} else
}
else
{
m_profWindow->SetHidden(true);
}
}
}
};
MyProfileWindow* setupProfileWindow(GwenInternalData* data)
{
MyMenuItems3* menuItems = new MyMenuItems3;
MyProfileWindow* profWindow = new MyProfileWindow(data->pCanvas);
//profWindow->SetHidden(true);
//profWindow->SetHidden(true);
profWindow->m_menuItems = menuItems;
profWindow->profIter = CProfileManager::Get_Iterator();
data->m_viewMenu->GetMenu()->AddItem( L"Profiler", menuItems,(Gwen::Event::Handler::Function)&MyMenuItems3::MenuItemSelect);
data->m_viewMenu->GetMenu()->AddItem(L"Profiler", menuItems, (Gwen::Event::Handler::Function)&MyMenuItems3::MenuItemSelect);
menuItems->m_profWindow = profWindow;
return profWindow;
}
void processProfileData( MyProfileWindow* profWindow, bool idle)
void processProfileData(MyProfileWindow* profWindow, bool idle)
{
if (profWindow)
{
@@ -297,7 +262,7 @@ void processProfileData( MyProfileWindow* profWindow, bool idle)
{
profWindow->UpdateText(profWindow->profIter, idle);
}
}
}
}
bool isProfileWindowVisible(MyProfileWindow* window)
@@ -315,7 +280,6 @@ void destroyProfileWindow(MyProfileWindow* window)
delete window->m_menuItems;
delete window;
CProfileManager::CleanupMemory();
}
#endif //BT_NO_PROFILE
#endif //BT_NO_PROFILE

View File

@@ -8,6 +8,4 @@ bool isProfileWindowVisible(MyProfileWindow* window);
void destroyProfileWindow(MyProfileWindow* window);
#endif//GWEN_PROFILE_WINDOW_H
#endif //GWEN_PROFILE_WINDOW_H

View File

@@ -3,79 +3,70 @@
#include "gwenInternalData.h"
#include "Gwen/Controls/ImagePanel.h"
class MyGraphWindow : public Gwen::Controls::WindowControl
{
Gwen::Controls::ImagePanel* m_imgPanel;
public:
class MyMenuItems2* m_menuItems;
MyGraphWindow ( const MyGraphInput& input)
: Gwen::Controls::WindowControl( input.m_data->pCanvas ),
m_menuItems(0)
MyGraphWindow(const MyGraphInput& input)
: Gwen::Controls::WindowControl(input.m_data->pCanvas),
m_menuItems(0)
{
Gwen::UnicodeString str = Gwen::Utility::StringToUnicode(input.m_name);
SetTitle( str );
SetTitle(str);
SetPos(input.m_xPos, input.m_yPos);
SetSize(12 + input.m_width + 2 * input.m_borderWidth, 30 + input.m_height + 2 * input.m_borderWidth);
SetPos(input.m_xPos,input.m_yPos);
SetSize( 12+input.m_width+2*input.m_borderWidth, 30+input.m_height+2*input.m_borderWidth );
m_imgPanel = new Gwen::Controls::ImagePanel( this );
m_imgPanel = new Gwen::Controls::ImagePanel(this);
if (input.m_texName)
{
Gwen::UnicodeString texName = Gwen::Utility::StringToUnicode(input.m_texName);
m_imgPanel->SetImage( texName );
m_imgPanel->SetImage(texName);
}
m_imgPanel->SetBounds( input.m_borderWidth, input.m_borderWidth,
input.m_width,
input.m_height );
// this->Dock( Gwen::Pos::Bottom);
m_imgPanel->SetBounds(input.m_borderWidth, input.m_borderWidth,
input.m_width,
input.m_height);
// this->Dock( Gwen::Pos::Bottom);
}
virtual ~MyGraphWindow()
{
delete m_imgPanel;
}
};
class MyMenuItems2 : public Gwen::Controls::Base
class MyMenuItems2 : public Gwen::Controls::Base
{
MyGraphWindow* m_graphWindow;
public:
Gwen::Controls::MenuItem* m_item;
MyMenuItems2(MyGraphWindow* graphWindow)
:Gwen::Controls::Base(0),
m_graphWindow(graphWindow),
m_item(0)
{
}
void MenuItemSelect(Gwen::Controls::Base* pControl)
{
MyMenuItems2(MyGraphWindow* graphWindow)
: Gwen::Controls::Base(0),
m_graphWindow(graphWindow),
m_item(0)
{
}
void MenuItemSelect(Gwen::Controls::Base* pControl)
{
if (m_graphWindow->Hidden())
{
m_graphWindow->SetHidden(false);
//@TODO(erwincoumans) setCheck/SetCheckable drawing is broken, need to see what's wrong
// if (m_item)
// m_item->SetCheck(false);
} else
// if (m_item)
// m_item->SetCheck(false);
}
else
{
m_graphWindow->SetHidden(true);
// if (m_item)
// m_item->SetCheck(true);
// if (m_item)
// m_item->SetCheck(true);
}
}
}
};
MyGraphWindow* setupTextureWindow(const MyGraphInput& input)
@@ -83,13 +74,12 @@ MyGraphWindow* setupTextureWindow(const MyGraphInput& input)
MyGraphWindow* graphWindow = new MyGraphWindow(input);
MyMenuItems2* menuItems = new MyMenuItems2(graphWindow);
graphWindow->m_menuItems = menuItems;
Gwen::UnicodeString str = Gwen::Utility::StringToUnicode(input.m_name);
menuItems->m_item = input.m_data->m_viewMenu->GetMenu()->AddItem( str, menuItems,(Gwen::Event::Handler::Function)&MyMenuItems2::MenuItemSelect);
// menuItems->m_item->SetCheckable(true);
menuItems->m_item = input.m_data->m_viewMenu->GetMenu()->AddItem(str, menuItems, (Gwen::Event::Handler::Function)&MyMenuItems2::MenuItemSelect);
// menuItems->m_item->SetCheckable(true);
return graphWindow;
}
void destroyTextureWindow(MyGraphWindow* window)

View File

@@ -14,19 +14,18 @@ struct MyGraphInput
const char* m_name;
const char* m_texName;
MyGraphInput(struct GwenInternalData* data)
:m_data(data),
m_xPos(0),
m_yPos(0),
m_width(400),
m_height(400),
m_borderWidth(0),
m_name("GraphWindow"),
m_texName(0)
: m_data(data),
m_xPos(0),
m_yPos(0),
m_width(400),
m_height(400),
m_borderWidth(0),
m_name("GraphWindow"),
m_texName(0)
{
}
};
class MyGraphWindow* setupTextureWindow(const MyGraphInput& input);
void destroyTextureWindow(MyGraphWindow* window);
#endif //GWEN_TEXTURE_WINDOW_H
#endif //GWEN_TEXTURE_WINDOW_H

View File

@@ -28,37 +28,34 @@
//#include "Gwen/Skins/TexturedBase.h"
#include "gwenUserInterface.h"
struct GwenInternalData
{
//struct sth_stash;
//class GwenOpenGL3CoreRenderer* pRenderer;
Gwen::Renderer::Base* pRenderer;
Gwen::Skin::Simple skin;
Gwen::Controls::Canvas* pCanvas;
Gwen::Renderer::Base* pRenderer;
Gwen::Skin::Simple skin;
Gwen::Controls::Canvas* pCanvas;
//GLPrimitiveRenderer* m_primRenderer;
Gwen::Controls::TabButton* m_demoPage;
Gwen::Controls::TabButton* m_explorerPage;
Gwen::Controls::TreeControl* m_explorerTreeCtrl;
Gwen::Controls::MenuItem* m_viewMenu;
class MyMenuItems* m_menuItems;
Gwen::Controls::ListBox* m_TextOutput;
Gwen::Controls::Label* m_exampleInfoGroupBox;
Gwen::Controls::ListBox* m_exampleInfoTextOutput;
struct MyTestMenuBar* m_menubar;
Gwen::Controls::TabButton* m_demoPage;
Gwen::Controls::TabButton* m_explorerPage;
Gwen::Controls::TreeControl* m_explorerTreeCtrl;
Gwen::Controls::MenuItem* m_viewMenu;
class MyMenuItems* m_menuItems;
Gwen::Controls::ListBox* m_TextOutput;
Gwen::Controls::Label* m_exampleInfoGroupBox;
Gwen::Controls::ListBox* m_exampleInfoTextOutput;
struct MyTestMenuBar* m_menubar;
Gwen::Controls::StatusBar* m_bar;
Gwen::Controls::ScrollControl* m_windowRight;
Gwen::Controls::TabControl* m_tab;
int m_curYposition;
int m_curYposition;
Gwen::Controls::Label* m_rightStatusBar;
Gwen::Controls::Label* m_leftStatusBar;
b3AlignedObjectArray<class Gwen::Event::Handler*> m_handlers;
b3ToggleButtonCallback m_toggleButtonCallback;
b3ComboBoxCallback m_comboBoxCallback;
b3AlignedObjectArray<class Gwen::Event::Handler*> m_handlers;
b3ToggleButtonCallback m_toggleButtonCallback;
b3ComboBoxCallback m_comboBoxCallback;
};
#endif//GWEN_INTERNAL_DATA_H
#endif //GWEN_INTERNAL_DATA_H

View File

@@ -7,24 +7,20 @@
class MyGraphWindow* graphWindow = 0;
GwenUserInterface::GwenUserInterface()
{
m_data = new GwenInternalData();
m_data->m_toggleButtonCallback = 0;
m_data->m_comboBoxCallback = 0;
}
class MyMenuItems : public Gwen::Controls::Base
{
public:
b3FileOpenCallback m_fileOpenCallback;
b3QuitCallback m_quitCallback;
MyMenuItems() :Gwen::Controls::Base(0), m_fileOpenCallback(0)
MyMenuItems() : Gwen::Controls::Base(0), m_fileOpenCallback(0)
{
}
void myQuitApp(Gwen::Controls::Base* pControl)
@@ -41,20 +37,16 @@ public:
(*m_fileOpenCallback)();
}
}
};
struct MyTestMenuBar : public Gwen::Controls::MenuStrip
{
Gwen::Controls::MenuItem* m_fileMenu;
Gwen::Controls::MenuItem* m_viewMenu;
MyMenuItems* m_menuItems;
MyMenuItems* m_menuItems;
MyTestMenuBar(Gwen::Controls::Base* pParent)
:Gwen::Controls::MenuStrip(pParent)
: Gwen::Controls::MenuStrip(pParent)
{
// Gwen::Controls::MenuStrip* menu = new Gwen::Controls::MenuStrip( pParent );
{
@@ -67,18 +59,15 @@ struct MyTestMenuBar : public Gwen::Controls::MenuStrip
m_fileMenu->GetMenu()->AddItem(L"Open", m_menuItems, (Gwen::Event::Handler::Function)&MyMenuItems::fileOpen);
m_fileMenu->GetMenu()->AddItem(L"Quit", m_menuItems, (Gwen::Event::Handler::Function)&MyMenuItems::myQuitApp);
m_viewMenu = AddItem(L"View");
}
}
virtual ~MyTestMenuBar()
{
delete m_menuItems;
}
};
void GwenUserInterface::exit()
void GwenUserInterface::exit()
{
//m_data->m_menubar->RemoveAllChildren();
delete m_data->m_tab;
@@ -88,7 +77,7 @@ void GwenUserInterface::exit()
delete m_data->m_rightStatusBar;
delete m_data->m_bar;
delete m_data->m_menubar;
m_data->m_menubar = 0;
delete m_data->pCanvas;
m_data->pCanvas = 0;
@@ -96,262 +85,226 @@ void GwenUserInterface::exit()
GwenUserInterface::~GwenUserInterface()
{
for (int i=0;i<m_data->m_handlers.size();i++)
for (int i = 0; i < m_data->m_handlers.size(); i++)
{
delete m_data->m_handlers[i];
}
m_data->m_handlers.clear();
delete m_data;
}
void GwenUserInterface::resize(int width, int height)
void GwenUserInterface::resize(int width, int height)
{
m_data->pCanvas->SetSize(width,height);
m_data->pCanvas->SetSize(width, height);
}
struct MyComboBoxHander :public Gwen::Event::Handler
struct MyComboBoxHander : public Gwen::Event::Handler
{
GwenInternalData* m_data;
int m_buttonId;
GwenInternalData* m_data;
int m_buttonId;
MyComboBoxHander (GwenInternalData* data, int buttonId)
:m_data(data),
m_buttonId(buttonId)
MyComboBoxHander(GwenInternalData* data, int buttonId)
: m_data(data),
m_buttonId(buttonId)
{
}
void onSelect( Gwen::Controls::Base* pControl )
void onSelect(Gwen::Controls::Base* pControl)
{
Gwen::Controls::ComboBox* but = (Gwen::Controls::ComboBox*) pControl;
Gwen::Controls::ComboBox* but = (Gwen::Controls::ComboBox*)pControl;
Gwen::String str = Gwen::Utility::UnicodeToString( but->GetSelectedItem()->GetText());
Gwen::String str = Gwen::Utility::UnicodeToString(but->GetSelectedItem()->GetText());
if (m_data->m_comboBoxCallback)
(*m_data->m_comboBoxCallback)(m_buttonId,str.c_str());
(*m_data->m_comboBoxCallback)(m_buttonId, str.c_str());
}
};
struct MyButtonHander :public Gwen::Event::Handler
struct MyButtonHander : public Gwen::Event::Handler
{
GwenInternalData* m_data;
int m_buttonId;
GwenInternalData* m_data;
int m_buttonId;
MyButtonHander (GwenInternalData* data, int buttonId)
:m_data(data),
m_buttonId(buttonId)
MyButtonHander(GwenInternalData* data, int buttonId)
: m_data(data),
m_buttonId(buttonId)
{
}
void onButtonA( Gwen::Controls::Base* pControl )
void onButtonA(Gwen::Controls::Base* pControl)
{
Gwen::Controls::Button* but = (Gwen::Controls::Button*) pControl;
// int dep = but->IsDepressed();
Gwen::Controls::Button* but = (Gwen::Controls::Button*)pControl;
// int dep = but->IsDepressed();
int tog = but->GetToggleState();
if (m_data->m_toggleButtonCallback)
(*m_data->m_toggleButtonCallback)(m_buttonId,tog);
(*m_data->m_toggleButtonCallback)(m_buttonId, tog);
}
};
void GwenUserInterface::textOutput(const char* message)
void GwenUserInterface::textOutput(const char* message)
{
Gwen::UnicodeString msg = Gwen::Utility::StringToUnicode(message);
m_data->m_TextOutput->AddItem( msg );
m_data->m_TextOutput->AddItem(msg);
m_data->m_TextOutput->Scroller()->ScrollToBottom();
}
void GwenUserInterface::setExampleDescription(const char* message)
void GwenUserInterface::setExampleDescription(const char* message)
{
//Gwen apparently doesn't have text/word wrap, so do rudimentary brute-force implementation here.
std::string wrapmessage=message;
std::string wrapmessage = message;
int startPos = 0;
std::string lastFit = "";
bool hasSpace = false;
std::string lastFitSpace = "";
int spacePos = 0;
m_data->m_exampleInfoTextOutput->Clear();
int fixedWidth = m_data->m_exampleInfoTextOutput->GetBounds().w-25;
int fixedWidth = m_data->m_exampleInfoTextOutput->GetBounds().w - 25;
int wrapLen = int(wrapmessage.length());
for (int endPos=0;endPos<=wrapLen;endPos++)
for (int endPos = 0; endPos <= wrapLen; endPos++)
{
std::string sub = wrapmessage.substr(startPos,(endPos-startPos));
Gwen::Point pt = m_data->pRenderer->MeasureText(m_data->pCanvas->GetSkin()->GetDefaultFont(),sub);
std::string sub = wrapmessage.substr(startPos, (endPos - startPos));
Gwen::Point pt = m_data->pRenderer->MeasureText(m_data->pCanvas->GetSkin()->GetDefaultFont(), sub);
if (pt.x <= fixedWidth)
{
lastFit = sub;
if (message[endPos]==' ' ||message[endPos]=='.' || message[endPos]==',' )
if (message[endPos] == ' ' || message[endPos] == '.' || message[endPos] == ',')
{
hasSpace = true;
lastFitSpace = sub;
spacePos = endPos;
}
} else
}
else
{
//submit and
//submit and
if (hasSpace)
{
endPos = spacePos+1;
endPos = spacePos + 1;
hasSpace = false;
lastFit = lastFitSpace;
startPos = endPos;
} else
}
else
{
startPos = endPos-1;
startPos = endPos - 1;
}
Gwen::UnicodeString msg = Gwen::Utility::StringToUnicode(lastFit);
m_data->m_exampleInfoTextOutput->AddItem( msg );
m_data->m_exampleInfoTextOutput->AddItem(msg);
m_data->m_exampleInfoTextOutput->Scroller()->ScrollToBottom();
}
}
if (lastFit.length())
{
Gwen::UnicodeString msg = Gwen::Utility::StringToUnicode(lastFit);
m_data->m_exampleInfoTextOutput->AddItem( msg );
m_data->m_exampleInfoTextOutput->AddItem(msg);
m_data->m_exampleInfoTextOutput->Scroller()->ScrollToBottom();
}
}
void GwenUserInterface::setStatusBarMessage(const char* message, bool isLeft)
void GwenUserInterface::setStatusBarMessage(const char* message, bool isLeft)
{
Gwen::UnicodeString msg = Gwen::Utility::StringToUnicode(message);
if (isLeft)
{
m_data->m_leftStatusBar->SetText( msg);
} else
m_data->m_leftStatusBar->SetText(msg);
}
else
{
m_data->m_rightStatusBar->SetText( msg);
m_data->m_rightStatusBar->SetText(msg);
}
}
void GwenUserInterface::registerFileOpenCallback(b3FileOpenCallback callback)
{
m_data->m_menuItems->m_fileOpenCallback = callback;
m_data->m_menuItems->m_fileOpenCallback = callback;
}
void GwenUserInterface::registerQuitCallback(b3QuitCallback callback)
{
m_data->m_menuItems->m_quitCallback = callback;
m_data->m_menuItems->m_quitCallback = callback;
}
void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* renderer,float retinaScale)
void GwenUserInterface::init(int width, int height, Gwen::Renderer::Base* renderer, float retinaScale)
{
m_data->m_curYposition = 20;
//m_data->m_primRenderer = new GLPrimitiveRenderer(width,height);
m_data->pRenderer = renderer;//new GwenOpenGL3CoreRenderer(m_data->m_primRenderer,stash,width,height,retinaScale);
m_data->pRenderer = renderer; //new GwenOpenGL3CoreRenderer(m_data->m_primRenderer,stash,width,height,retinaScale);
m_data->skin.SetRender( m_data->pRenderer );
m_data->skin.SetRender(m_data->pRenderer);
m_data->pCanvas = new Gwen::Controls::Canvas(&m_data->skin);
m_data->pCanvas->SetSize(width, height);
m_data->pCanvas->SetDrawBackground(false);
m_data->pCanvas->SetBackgroundColor(Gwen::Color(150, 170, 170, 255));
m_data->pCanvas= new Gwen::Controls::Canvas( &m_data->skin );
m_data->pCanvas->SetSize( width,height);
m_data->pCanvas->SetDrawBackground( false);
m_data->pCanvas->SetBackgroundColor( Gwen::Color( 150, 170, 170, 255 ) );
MyTestMenuBar* menubar = new MyTestMenuBar(m_data->pCanvas);
m_data->m_viewMenu = menubar->m_viewMenu;
m_data->m_menuItems = menubar->m_menuItems;
m_data->m_menuItems = menubar->m_menuItems;
m_data->m_menubar = menubar;
Gwen::Controls::StatusBar* bar = new Gwen::Controls::StatusBar(m_data->pCanvas);
m_data->m_bar = bar;
m_data->m_rightStatusBar = new Gwen::Controls::Label( bar );
m_data->m_rightStatusBar->SetWidth(width/2);
m_data->m_rightStatusBar = new Gwen::Controls::Label(bar);
m_data->m_rightStatusBar->SetWidth(width / 2);
//m_data->m_rightStatusBar->SetText( L"Label Added to Right" );
bar->AddControl( m_data->m_rightStatusBar, true );
m_data->m_TextOutput = new Gwen::Controls::ListBox( m_data->pCanvas );
m_data->m_TextOutput->Dock( Gwen::Pos::Bottom );
m_data->m_TextOutput->SetHeight( 100 );
m_data->m_leftStatusBar = new Gwen::Controls::Label( bar );
bar->AddControl(m_data->m_rightStatusBar, true);
m_data->m_TextOutput = new Gwen::Controls::ListBox(m_data->pCanvas);
m_data->m_TextOutput->Dock(Gwen::Pos::Bottom);
m_data->m_TextOutput->SetHeight(100);
m_data->m_leftStatusBar = new Gwen::Controls::Label(bar);
//m_data->m_leftStatusBar->SetText( L"Label Added to Left" );
m_data->m_leftStatusBar->SetWidth(width/2);
bar->AddControl( m_data->m_leftStatusBar,false);
m_data->m_leftStatusBar->SetWidth(width / 2);
bar->AddControl(m_data->m_leftStatusBar, false);
//Gwen::KeyboardFocus
/*Gwen::Controls::GroupBox* box = new Gwen::Controls::GroupBox(m_data->pCanvas);
box->SetText("text");
box->SetName("name");
box->SetHeight(500);
*/
Gwen::Controls::ScrollControl* windowRight= new Gwen::Controls::ScrollControl(m_data->pCanvas);
Gwen::Controls::ScrollControl* windowRight = new Gwen::Controls::ScrollControl(m_data->pCanvas);
windowRight->Dock(Gwen::Pos::Right);
windowRight->SetWidth(250);
windowRight->SetHeight(250);
windowRight->SetScroll(false,true);
windowRight->SetScroll(false, true);
m_data->m_windowRight = windowRight;
//windowLeft->SetSkin(
Gwen::Controls::TabControl* tab = new Gwen::Controls::TabControl(windowRight);
m_data->m_tab = tab;
//tab->SetHeight(300);
tab->SetWidth(240);
tab->SetHeight(1250);
//tab->Dock(Gwen::Pos::Left);
tab->Dock( Gwen::Pos::Fill );
tab->Dock(Gwen::Pos::Fill);
//tab->SetMargin( Gwen::Margin( 2, 2, 2, 2 ) );
Gwen::UnicodeString str1(L"Params");
m_data->m_demoPage = tab->AddPage(str1);
// Gwen::UnicodeString str2(L"OpenCL");
// tab->AddPage(str2);
// Gwen::UnicodeString str2(L"OpenCL");
// tab->AddPage(str2);
//Gwen::UnicodeString str3(L"page3");
// tab->AddPage(str3);
// tab->AddPage(str3);
//but->onPress.Add(handler, &MyHander::onButtonA);
//box->Dock(Gwen::Pos::Left);
/*Gwen::Controls::WindowControl* windowBottom = new Gwen::Controls::WindowControl(m_data->pCanvas);
@@ -359,7 +312,7 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere
windowBottom->Dock(Gwen::Pos::Bottom);
windowBottom->SetTitle("bottom");
*/
// Gwen::Controls::Property::Text* prop = new Gwen::Controls::Property::Text(m_data->pCanvas);
// Gwen::Controls::Property::Text* prop = new Gwen::Controls::Property::Text(m_data->pCanvas);
//prop->Dock(Gwen::Pos::Bottom);
/*Gwen::Controls::SplitterBar* split = new Gwen::Controls::SplitterBar(m_data->pCanvas);
split->Dock(Gwen::Pos::Center);
@@ -381,19 +334,15 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere
//windowLeft->SetClosable(false);
// windowLeft->SetShouldDrawBackground(true);
windowLeft->SetTabable(true);
Gwen::Controls::TabControl* explorerTab = new Gwen::Controls::TabControl(windowLeft);
//tab->SetHeight(300);
// explorerTab->SetWidth(230);
// explorerTab->SetWidth(230);
explorerTab->SetHeight(250);
//tab->Dock(Gwen::Pos::Left);
explorerTab->Dock(Gwen::Pos::Fill);
//m_data->m_exampleInfoTextOutput->SetBounds(2, 10, 236, 400);
//windowRight
@@ -407,16 +356,16 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere
//Gwen::Controls::HSVColorPicker* color = new Gwen::Controls::HSVColorPicker(shapes->GetPage());
Gwen::Controls::ColorPicker* color = new Gwen::Controls::ColorPicker(shapes->GetPage());
color->SetKeyboardInputEnabled(true);
Gwen::Controls::TreeControl* ctrl = new Gwen::Controls::TreeControl(m_data->m_explorerPage->GetPage());
m_data->m_explorerTreeCtrl = ctrl;
ctrl->SetKeyboardInputEnabled(true);
ctrl->Focus();
ctrl->SetBounds(2, 10, 236, 300);
m_data->m_exampleInfoGroupBox = new Gwen::Controls::Label( m_data->m_explorerPage->GetPage() );
m_data->m_exampleInfoGroupBox = new Gwen::Controls::Label(m_data->m_explorerPage->GetPage());
m_data->m_exampleInfoGroupBox->SetPos(2, 314);
m_data->m_exampleInfoGroupBox->SetHeight( 15 );
m_data->m_exampleInfoGroupBox->SetHeight(15);
m_data->m_exampleInfoGroupBox->SetWidth(234);
m_data->m_exampleInfoGroupBox->SetText("Example Description");
@@ -424,14 +373,11 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere
//m_data->m_exampleInfoTextOutput->Dock( Gwen::Pos::Bottom );
m_data->m_exampleInfoTextOutput->SetPos(2, 332);
m_data->m_exampleInfoTextOutput->SetHeight( 150 );
m_data->m_exampleInfoTextOutput->SetHeight(150);
m_data->m_exampleInfoTextOutput->SetWidth(233);
}
void GwenUserInterface::forceUpdateScrollBars()
void GwenUserInterface::forceUpdateScrollBars()
{
b3Assert(m_data);
b3Assert(m_data->m_explorerTreeCtrl);
@@ -441,7 +387,7 @@ void GwenUserInterface::forceUpdateScrollBars()
}
}
void GwenUserInterface::setFocus()
void GwenUserInterface::setFocus()
{
b3Assert(m_data);
b3Assert(m_data->m_explorerTreeCtrl);
@@ -451,16 +397,16 @@ void GwenUserInterface::setFocus()
}
}
b3ToggleButtonCallback GwenUserInterface::getToggleButtonCallback()
b3ToggleButtonCallback GwenUserInterface::getToggleButtonCallback()
{
return m_data->m_toggleButtonCallback;
}
void GwenUserInterface::setToggleButtonCallback(b3ToggleButtonCallback callback)
void GwenUserInterface::setToggleButtonCallback(b3ToggleButtonCallback callback)
{
m_data->m_toggleButtonCallback = callback;
}
void GwenUserInterface::registerToggleButton2(int buttonId, const char* name)
void GwenUserInterface::registerToggleButton2(int buttonId, const char* name)
{
assert(m_data);
assert(m_data->m_demoPage);
@@ -469,21 +415,20 @@ void GwenUserInterface::registerToggleButton2(int buttonId, const char* name)
///some heuristic to find the button location
int ypos = m_data->m_curYposition;
but->SetPos(10, ypos );
but->SetWidth( 200 );
but->SetPos(10, ypos);
but->SetWidth(200);
//but->SetBounds( 200, 30, 300, 200 );
MyButtonHander* handler = new MyButtonHander(m_data, buttonId);
m_data->m_handlers.push_back(handler);
m_data->m_curYposition+=22;
m_data->m_curYposition += 22;
but->onToggle.Add(handler, &MyButtonHander::onButtonA);
but->SetIsToggle(true);
but->SetToggleState(false);
but->SetText(name);
}
void GwenUserInterface::setComboBoxCallback(b3ComboBoxCallback callback)
void GwenUserInterface::setComboBoxCallback(b3ComboBoxCallback callback)
{
m_data->m_comboBoxCallback = callback;
}
@@ -492,67 +437,61 @@ b3ComboBoxCallback GwenUserInterface::getComboBoxCallback()
{
return m_data->m_comboBoxCallback;
}
void GwenUserInterface::registerComboBox2(int comboboxId, int numItems, const char** items, int startItem)
void GwenUserInterface::registerComboBox2(int comboboxId, int numItems, const char** items, int startItem)
{
Gwen::Controls::ComboBox* combobox = new Gwen::Controls::ComboBox(m_data->m_demoPage->GetPage());
MyComboBoxHander* handler = new MyComboBoxHander(m_data, comboboxId);
m_data->m_handlers.push_back(handler);
combobox->onSelection.Add(handler,&MyComboBoxHander::onSelect);
combobox->onSelection.Add(handler, &MyComboBoxHander::onSelect);
int ypos = m_data->m_curYposition;
combobox->SetPos(10, ypos );
combobox->SetWidth( 100 );
combobox->SetPos(10, ypos);
combobox->SetWidth(100);
//box->SetPos(120,130);
for (int i=0;i<numItems;i++)
for (int i = 0; i < numItems; i++)
{
Gwen::Controls::MenuItem* item = combobox->AddItem(Gwen::Utility::StringToUnicode(items[i]));
if (i==startItem)
if (i == startItem)
combobox->OnItemSelected(item);
}
m_data->m_curYposition+=22;
m_data->m_curYposition += 22;
}
void GwenUserInterface::draw(int width, int height)
void GwenUserInterface::draw(int width, int height)
{
// printf("width = %d, height=%d\n", width,height);
// printf("width = %d, height=%d\n", width,height);
if (m_data->pCanvas)
{
m_data->pCanvas->SetSize(width,height);
m_data->pCanvas->SetSize(width, height);
//m_data->m_primRenderer->setScreenSize(width,height);
m_data->pRenderer->Resize(width,height);
m_data->pRenderer->Resize(width, height);
m_data->pCanvas->RenderCanvas();
//restoreOpenGLState();
}
}
bool GwenUserInterface::mouseMoveCallback( float x, float y)
bool GwenUserInterface::mouseMoveCallback(float x, float y)
{
bool handled = false;
bool handled = false;
static int m_lastmousepos[2] = {0,0};
static int m_lastmousepos[2] = {0, 0};
static bool isInitialized = false;
if (m_data->pCanvas)
{
if (!isInitialized)
{
isInitialized = true;
m_lastmousepos[0] = x+1;
m_lastmousepos[1] = y+1;
m_lastmousepos[0] = x + 1;
m_lastmousepos[1] = y + 1;
}
handled = m_data->pCanvas->InputMouseMoved(x,y,m_lastmousepos[0],m_lastmousepos[1]);
handled = m_data->pCanvas->InputMouseMoved(x, y, m_lastmousepos[0], m_lastmousepos[1]);
}
return handled;
}
#include "../CommonInterfaces/CommonWindowInterface.h"
bool GwenUserInterface::keyboardCallback(int bulletKey, int state)
bool GwenUserInterface::keyboardCallback(int bulletKey, int state)
{
int gwenKey = -1;
if (m_data->pCanvas)
@@ -560,96 +499,93 @@ bool GwenUserInterface::keyboardCallback(int bulletKey, int state)
//convert 'Bullet' keys into 'Gwen' keys
switch (bulletKey)
{
case B3G_RETURN:
{
gwenKey = Gwen::Key::Return;
break;
}
case B3G_LEFT_ARROW:
{
gwenKey = Gwen::Key::Left;
break;
}
case B3G_RIGHT_ARROW:
{
gwenKey = Gwen::Key::Right;
break;
}
case B3G_UP_ARROW:
{
gwenKey = Gwen::Key::Up;
break;
}
case B3G_DOWN_ARROW:
{
gwenKey = Gwen::Key::Down;
break;
}
case B3G_BACKSPACE:
{
gwenKey = Gwen::Key::Backspace;
break;
}
case B3G_DELETE:
{
gwenKey = Gwen::Key::Delete;
break;
}
case B3G_HOME:
{
gwenKey = Gwen::Key::Home;
break;
}
case B3G_END:
{
gwenKey = Gwen::Key::End;
break;
}
case B3G_SHIFT:
{
gwenKey = Gwen::Key::Shift;
break;
}
case B3G_CONTROL:
{
gwenKey = Gwen::Key::Control;
break;
}
case B3G_RETURN:
{
gwenKey = Gwen::Key::Return;
break;
}
case B3G_LEFT_ARROW:
{
gwenKey = Gwen::Key::Left;
break;
}
case B3G_RIGHT_ARROW:
{
gwenKey = Gwen::Key::Right;
break;
}
case B3G_UP_ARROW:
{
gwenKey = Gwen::Key::Up;
break;
}
case B3G_DOWN_ARROW:
{
gwenKey = Gwen::Key::Down;
break;
}
case B3G_BACKSPACE:
{
gwenKey = Gwen::Key::Backspace;
break;
}
case B3G_DELETE:
{
gwenKey = Gwen::Key::Delete;
break;
}
case B3G_HOME:
{
gwenKey = Gwen::Key::Home;
break;
}
case B3G_END:
{
gwenKey = Gwen::Key::End;
break;
}
case B3G_SHIFT:
{
gwenKey = Gwen::Key::Shift;
break;
}
case B3G_CONTROL:
{
gwenKey = Gwen::Key::Control;
break;
}
default:
{
}
default:
{
}
};
if (gwenKey>=0)
if (gwenKey >= 0)
{
return m_data->pCanvas->InputKey(gwenKey,state==1);
} else
return m_data->pCanvas->InputKey(gwenKey, state == 1);
}
else
{
if (bulletKey<256 && state)
if (bulletKey < 256 && state)
{
Gwen::UnicodeChar c = ( Gwen::UnicodeChar ) bulletKey;
Gwen::UnicodeChar c = (Gwen::UnicodeChar)bulletKey;
return m_data->pCanvas->InputCharacter(c);
}
}
}
return false;
}
bool GwenUserInterface::mouseButtonCallback(int button, int state, float x, float y)
bool GwenUserInterface::mouseButtonCallback(int button, int state, float x, float y)
{
bool handled = false;
if (m_data->pCanvas)
{
handled = m_data->pCanvas->InputMouseMoved(x,y,x, y);
handled = m_data->pCanvas->InputMouseMoved(x, y, x, y);
if (button>=0)
if (button >= 0)
{
handled = m_data->pCanvas->InputMouseButton(button,(bool)state);
handled = m_data->pCanvas->InputMouseButton(button, (bool)state);
if (handled)
{
//if (!state)

View File

@@ -3,68 +3,61 @@
struct GwenInternalData;
typedef void (*b3ComboBoxCallback) (int combobox, const char* item);
typedef void (*b3ComboBoxCallback)(int combobox, const char* item);
typedef void (*b3ToggleButtonCallback)(int button, int state);
typedef void (*b3FileOpenCallback)();
typedef void (*b3QuitCallback)();
namespace Gwen
{
namespace Renderer
{
class Base;
};
namespace Renderer
{
class Base;
};
}; // namespace Gwen
class GwenUserInterface
{
GwenInternalData* m_data;
GwenInternalData* m_data;
public:
GwenUserInterface();
virtual ~GwenUserInterface();
void init(int width, int height,Gwen::Renderer::Base* gwenRenderer,float retinaScale);
void exit();
void setFocus();
void forceUpdateScrollBars();
void draw(int width, int height);
public:
GwenUserInterface();
void resize(int width, int height);
bool mouseMoveCallback( float x, float y);
bool mouseButtonCallback(int button, int state, float x, float y);
bool keyboardCallback(int key, int state);
virtual ~GwenUserInterface();
void init(int width, int height, Gwen::Renderer::Base* gwenRenderer, float retinaScale);
void exit();
void setFocus();
void forceUpdateScrollBars();
void setToggleButtonCallback(b3ToggleButtonCallback callback);
b3ToggleButtonCallback getToggleButtonCallback();
void draw(int width, int height);
void registerToggleButton2(int buttonId, const char* name);
void resize(int width, int height);
void setComboBoxCallback(b3ComboBoxCallback callback);
b3ComboBoxCallback getComboBoxCallback();
void registerComboBox2(int buttonId, int numItems, const char** items, int startItem = 0);
void setStatusBarMessage(const char* message, bool isLeft=true);
bool mouseMoveCallback(float x, float y);
bool mouseButtonCallback(int button, int state, float x, float y);
bool keyboardCallback(int key, int state);
void textOutput(const char* msg);
void setExampleDescription(const char* msg);
void setToggleButtonCallback(b3ToggleButtonCallback callback);
b3ToggleButtonCallback getToggleButtonCallback();
void registerFileOpenCallback(b3FileOpenCallback callback);
void registerQuitCallback(b3QuitCallback callback);
GwenInternalData* getInternalData()
{
return m_data;
}
void registerToggleButton2(int buttonId, const char* name);
void setComboBoxCallback(b3ComboBoxCallback callback);
b3ComboBoxCallback getComboBoxCallback();
void registerComboBox2(int buttonId, int numItems, const char** items, int startItem = 0);
void setStatusBarMessage(const char* message, bool isLeft = true);
void textOutput(const char* msg);
void setExampleDescription(const char* msg);
void registerFileOpenCallback(b3FileOpenCallback callback);
void registerQuitCallback(b3QuitCallback callback);
GwenInternalData* getInternalData()
{
return m_data;
}
};
#endif //_GWEN_USER_INTERFACE_H
#endif //_GWEN_USER_INTERFACE_H

View File

@@ -2,12 +2,12 @@
//#define EXAMPLE_CONSOLE_ONLY
#ifdef EXAMPLE_CONSOLE_ONLY
#include "EmptyBrowser.h"
typedef EmptyBrowser DefaultBrowser;
#include "EmptyBrowser.h"
typedef EmptyBrowser DefaultBrowser;
#else
#include "OpenGLExampleBrowser.h"
typedef OpenGLExampleBrowser DefaultBrowser;
#endif //EXAMPLE_CONSOLE_ONLY
#include "OpenGLExampleBrowser.h"
typedef OpenGLExampleBrowser DefaultBrowser;
#endif //EXAMPLE_CONSOLE_ONLY
#include "Bullet3Common/b3CommandLineArgs.h"
#include "../Utils/b3Clock.h"
@@ -16,11 +16,10 @@
#include "Bullet3Common/b3Scalar.h"
#include "../SharedMemory/InProcessMemory.h"
void ExampleBrowserThreadFunc(void* userPtr,void* lsMemory);
void* ExampleBrowserMemoryFunc();
void ExampleBrowserThreadFunc(void* userPtr, void* lsMemory);
void* ExampleBrowserMemoryFunc();
void ExampleBrowserMemoryReleaseFunc(void* ptr);
#include <stdio.h>
//#include "BulletMultiThreaded/PlatformDefinitions.h"
@@ -37,50 +36,38 @@ void ExampleBrowserMemoryReleaseFunc(void* ptr);
#ifndef _WIN32
#include "../MultiThreading/b3PosixThreadSupport.h"
static b3ThreadSupportInterface* createExampleBrowserThreadSupport(int numThreads)
{
b3PosixThreadSupport::ThreadConstructionInfo constructionInfo("testThreads",
ExampleBrowserThreadFunc,
ExampleBrowserMemoryFunc,
ExampleBrowserMemoryReleaseFunc,
numThreads);
b3ThreadSupportInterface* threadSupport = new b3PosixThreadSupport(constructionInfo);
ExampleBrowserThreadFunc,
ExampleBrowserMemoryFunc,
ExampleBrowserMemoryReleaseFunc,
numThreads);
b3ThreadSupportInterface* threadSupport = new b3PosixThreadSupport(constructionInfo);
return threadSupport;
}
#elif defined( _WIN32)
#elif defined(_WIN32)
#include "../MultiThreading/b3Win32ThreadSupport.h"
b3ThreadSupportInterface* createExampleBrowserThreadSupport(int numThreads)
{
b3Win32ThreadSupport::Win32ThreadConstructionInfo threadConstructionInfo("testThreads",ExampleBrowserThreadFunc,ExampleBrowserMemoryFunc,ExampleBrowserMemoryReleaseFunc,numThreads);
b3Win32ThreadSupport::Win32ThreadConstructionInfo threadConstructionInfo("testThreads", ExampleBrowserThreadFunc, ExampleBrowserMemoryFunc, ExampleBrowserMemoryReleaseFunc, numThreads);
b3Win32ThreadSupport* threadSupport = new b3Win32ThreadSupport(threadConstructionInfo);
return threadSupport;
}
#endif
class ExampleEntriesPhysicsServer : public ExampleEntries
{
struct ExampleEntriesInternalData2* m_data;
public:
ExampleEntriesPhysicsServer();
virtual ~ExampleEntriesPhysicsServer();
static void registerExampleEntry(int menuLevel, const char* name,const char* description, CommonExampleInterface::CreateFunc* createFunc, int option=0);
static void registerExampleEntry(int menuLevel, const char* name, const char* description, CommonExampleInterface::CreateFunc* createFunc, int option = 0);
virtual void initExampleEntries();
@@ -94,54 +81,50 @@ public:
virtual const char* getExampleDescription(int index);
virtual int getExampleOption(int index);
virtual int getExampleOption(int index);
};
struct ExampleEntryPhysicsServer
{
int m_menuLevel;
const char* m_name;
const char* m_description;
CommonExampleInterface::CreateFunc* m_createFunc;
int m_option;
int m_menuLevel;
const char* m_name;
const char* m_description;
CommonExampleInterface::CreateFunc* m_createFunc;
int m_option;
ExampleEntryPhysicsServer(int menuLevel, const char* name)
:m_menuLevel(menuLevel), m_name(name), m_description(0), m_createFunc(0), m_option(0)
: m_menuLevel(menuLevel), m_name(name), m_description(0), m_createFunc(0), m_option(0)
{
}
ExampleEntryPhysicsServer(int menuLevel, const char* name,const char* description, CommonExampleInterface::CreateFunc* createFunc, int option=0)
:m_menuLevel(menuLevel), m_name(name), m_description(description), m_createFunc(createFunc), m_option(option)
ExampleEntryPhysicsServer(int menuLevel, const char* name, const char* description, CommonExampleInterface::CreateFunc* createFunc, int option = 0)
: m_menuLevel(menuLevel), m_name(name), m_description(description), m_createFunc(createFunc), m_option(option)
{
}
};
struct ExampleEntriesInternalData2
{
btAlignedObjectArray<ExampleEntryPhysicsServer> m_allExamples;
btAlignedObjectArray<ExampleEntryPhysicsServer> m_allExamples;
};
static ExampleEntryPhysicsServer gDefaultExamplesPhysicsServer[]=
{
static ExampleEntryPhysicsServer gDefaultExamplesPhysicsServer[] =
{
ExampleEntryPhysicsServer(0,"Robotics Control"),
ExampleEntryPhysicsServer(0, "Robotics Control"),
ExampleEntryPhysicsServer(1,"Physics Server", "Create a physics server that communicates with a physics client over shared memory",
PhysicsServerCreateFuncBullet2),
ExampleEntryPhysicsServer(1,"Physics Server (RTC)", "Create a physics server that communicates with a physics client over shared memory. At each update, the Physics Server will continue calling 'stepSimulation' based on the real-time clock (RTC).",
PhysicsServerCreateFuncBullet2,PHYSICS_SERVER_USE_RTC_CLOCK),
ExampleEntryPhysicsServer(1,"Physics Server (Logging)", "Create a physics server that communicates with a physics client over shared memory. It will log all commands to a file.",
PhysicsServerCreateFuncBullet2,PHYSICS_SERVER_ENABLE_COMMAND_LOGGING),
ExampleEntryPhysicsServer(1,"Physics Server (Replay Log)", "Create a physics server that replay a command log from disk.",
PhysicsServerCreateFuncBullet2,PHYSICS_SERVER_REPLAY_FROM_COMMAND_LOG),
ExampleEntryPhysicsServer(1, "Physics Server", "Create a physics server that communicates with a physics client over shared memory",
PhysicsServerCreateFuncBullet2),
ExampleEntryPhysicsServer(1, "Physics Server (RTC)", "Create a physics server that communicates with a physics client over shared memory. At each update, the Physics Server will continue calling 'stepSimulation' based on the real-time clock (RTC).",
PhysicsServerCreateFuncBullet2, PHYSICS_SERVER_USE_RTC_CLOCK),
ExampleEntryPhysicsServer(1, "Physics Server (Logging)", "Create a physics server that communicates with a physics client over shared memory. It will log all commands to a file.",
PhysicsServerCreateFuncBullet2, PHYSICS_SERVER_ENABLE_COMMAND_LOGGING),
ExampleEntryPhysicsServer(1, "Physics Server (Replay Log)", "Create a physics server that replay a command log from disk.",
PhysicsServerCreateFuncBullet2, PHYSICS_SERVER_REPLAY_FROM_COMMAND_LOG),
};
ExampleEntriesPhysicsServer::ExampleEntriesPhysicsServer()
{
m_data = new ExampleEntriesInternalData2;
@@ -160,17 +143,14 @@ void ExampleEntriesPhysicsServer::initExampleEntries()
{
m_data->m_allExamples.clear();
int numDefaultEntries = sizeof(gDefaultExamplesPhysicsServer)/sizeof(ExampleEntryPhysicsServer);
for (int i=0;i<numDefaultEntries;i++)
int numDefaultEntries = sizeof(gDefaultExamplesPhysicsServer) / sizeof(ExampleEntryPhysicsServer);
for (int i = 0; i < numDefaultEntries; i++)
{
m_data->m_allExamples.push_back(gDefaultExamplesPhysicsServer[i]);
}
}
void ExampleEntriesPhysicsServer::registerExampleEntry(int menuLevel, const char* name,const char* description, CommonExampleInterface::CreateFunc* createFunc, int option)
void ExampleEntriesPhysicsServer::registerExampleEntry(int menuLevel, const char* name, const char* description, CommonExampleInterface::CreateFunc* createFunc, int option)
{
}
@@ -199,19 +179,16 @@ const char* ExampleEntriesPhysicsServer::getExampleDescription(int index)
return m_data->m_allExamples[index].m_description;
}
struct ExampleBrowserArgs
struct ExampleBrowserArgs
{
ExampleBrowserArgs()
:m_fakeWork(1),m_argc(0)
: m_fakeWork(1), m_argc(0)
{
}
b3CriticalSection* m_cs;
float m_fakeWork;
int m_argc;
char** m_argv;
int m_argc;
char** m_argv;
};
struct ExampleBrowserThreadLocalStorage
@@ -231,32 +208,29 @@ enum TestExampleBrowserCommunicationEnums
static double gMinUpdateTimeMicroSecs = 4000.;
void ExampleBrowserThreadFunc(void* userPtr,void* lsMemory)
void ExampleBrowserThreadFunc(void* userPtr, void* lsMemory)
{
printf("ExampleBrowserThreadFunc started\n");
ExampleBrowserThreadLocalStorage* localStorage = (ExampleBrowserThreadLocalStorage*) lsMemory;
ExampleBrowserThreadLocalStorage* localStorage = (ExampleBrowserThreadLocalStorage*)lsMemory;
ExampleBrowserArgs* args = (ExampleBrowserArgs*) userPtr;
ExampleBrowserArgs* args = (ExampleBrowserArgs*)userPtr;
//int workLeft = true;
b3CommandLineArgs args2(args->m_argc,args->m_argv);
b3CommandLineArgs args2(args->m_argc, args->m_argv);
b3Clock clock;
ExampleEntriesPhysicsServer examples;
examples.initExampleEntries();
DefaultBrowser* exampleBrowser = new DefaultBrowser(&examples);
exampleBrowser->setSharedMemoryInterface(localStorage->m_sharedMem);
bool init = exampleBrowser->init(args->m_argc,args->m_argv);
bool init = exampleBrowser->init(args->m_argc, args->m_argv);
clock.reset();
if (init)
{
args->m_cs->lock();
args->m_cs->setSharedParam(0,eExampleBrowserIsInitialized);
args->m_cs->setSharedParam(0, eExampleBrowserIsInitialized);
args->m_cs->unlock();
do
@@ -264,17 +238,18 @@ void ExampleBrowserThreadFunc(void* userPtr,void* lsMemory)
clock.usleep(0);
//B3_PROFILE("ExampleBrowserThreadFunc");
float deltaTimeInSeconds = clock.getTimeMicroseconds()/1000000.f;
float deltaTimeInSeconds = clock.getTimeMicroseconds() / 1000000.f;
{
if (deltaTimeInSeconds > 0.1)
{
deltaTimeInSeconds = 0.1;
}
if (deltaTimeInSeconds < (gMinUpdateTimeMicroSecs/1e6))
if (deltaTimeInSeconds < (gMinUpdateTimeMicroSecs / 1e6))
{
//B3_PROFILE("clock.usleep");
exampleBrowser->updateGraphics();
} else
}
else
{
//B3_PROFILE("exampleBrowser->update");
clock.reset();
@@ -283,24 +258,24 @@ void ExampleBrowserThreadFunc(void* userPtr,void* lsMemory)
}
}
} while (!exampleBrowser->requestedExit() && (args->m_cs->getSharedParam(0)!=eRequestTerminateExampleBrowser));
} else
} while (!exampleBrowser->requestedExit() && (args->m_cs->getSharedParam(0) != eRequestTerminateExampleBrowser));
}
else
{
args->m_cs->lock();
args->m_cs->setSharedParam(0,eExampleBrowserInitializationFailed);
args->m_cs->setSharedParam(0, eExampleBrowserInitializationFailed);
args->m_cs->unlock();
}
delete exampleBrowser;
args->m_cs->lock();
args->m_cs->setSharedParam(0,eExampleBrowserHasTerminated);
args->m_cs->setSharedParam(0, eExampleBrowserHasTerminated);
args->m_cs->unlock();
printf("finished\n");
//do nothing
}
void* ExampleBrowserMemoryFunc()
void* ExampleBrowserMemoryFunc()
{
//don't create local store memory, just return 0
return new ExampleBrowserThreadLocalStorage;
@@ -308,14 +283,10 @@ void* ExampleBrowserMemoryFunc()
void ExampleBrowserMemoryReleaseFunc(void* ptr)
{
ExampleBrowserThreadLocalStorage* p = (ExampleBrowserThreadLocalStorage*) ptr;
ExampleBrowserThreadLocalStorage* p = (ExampleBrowserThreadLocalStorage*)ptr;
delete p;
}
struct btInProcessExampleBrowserInternalData
{
ExampleBrowserArgs m_args;
@@ -323,13 +294,10 @@ struct btInProcessExampleBrowserInternalData
SharedMemoryInterface* m_sharedMem;
};
btInProcessExampleBrowserInternalData* btCreateInProcessExampleBrowser(int argc,char** argv2, bool useInProcessMemory)
btInProcessExampleBrowserInternalData* btCreateInProcessExampleBrowser(int argc, char** argv2, bool useInProcessMemory)
{
btInProcessExampleBrowserInternalData* data = new btInProcessExampleBrowserInternalData;
data->m_sharedMem = useInProcessMemory ? new InProcessMemory : 0;
int numThreads = 1;
@@ -338,32 +306,30 @@ btInProcessExampleBrowserInternalData* btCreateInProcessExampleBrowser(int argc,
data->m_threadSupport = createExampleBrowserThreadSupport(numThreads);
printf("argc=%d\n", argc);
for (i=0;i<argc;i++)
for (i = 0; i < argc; i++)
{
printf("argv[%d] = %s\n",i,argv2[i]);
printf("argv[%d] = %s\n", i, argv2[i]);
}
for (i=0;i<data->m_threadSupport->getNumTasks();i++)
for (i = 0; i < data->m_threadSupport->getNumTasks(); i++)
{
ExampleBrowserThreadLocalStorage* storage = (ExampleBrowserThreadLocalStorage*) data->m_threadSupport->getThreadLocalMemory(i);
ExampleBrowserThreadLocalStorage* storage = (ExampleBrowserThreadLocalStorage*)data->m_threadSupport->getThreadLocalMemory(i);
b3Assert(storage);
storage->threadId = i;
storage->m_sharedMem = data->m_sharedMem;
}
data->m_args.m_cs = data->m_threadSupport->createCriticalSection();
data->m_args.m_cs->setSharedParam(0,eExampleBrowserIsUnInitialized);
data->m_args.m_argc = argc;
data->m_args.m_argv = argv2;
data->m_args.m_cs->setSharedParam(0, eExampleBrowserIsUnInitialized);
data->m_args.m_argc = argc;
data->m_args.m_argv = argv2;
for (i=0;i<numThreads;i++)
for (i = 0; i < numThreads; i++)
{
data->m_threadSupport->runTask(B3_THREAD_SCHEDULE_TASK, (void*) &data->m_args, i);
data->m_threadSupport->runTask(B3_THREAD_SCHEDULE_TASK, (void*)&data->m_args, i);
}
while (data->m_args.m_cs->getSharedParam(0)==eExampleBrowserIsUnInitialized)
while (data->m_args.m_cs->getSharedParam(0) == eExampleBrowserIsUnInitialized)
{
b3Clock::usleep(1000);
}
@@ -373,7 +339,7 @@ btInProcessExampleBrowserInternalData* btCreateInProcessExampleBrowser(int argc,
bool btIsExampleBrowserTerminated(btInProcessExampleBrowserInternalData* data)
{
return (data->m_args.m_cs->getSharedParam(0)==eExampleBrowserHasTerminated);
return (data->m_args.m_cs->getSharedParam(0) == eExampleBrowserHasTerminated);
}
SharedMemoryInterface* btGetSharedMemoryInterface(btInProcessExampleBrowserInternalData* data)
@@ -386,23 +352,23 @@ void btShutDownExampleBrowser(btInProcessExampleBrowserInternalData* data)
int numActiveThreads = 1;
data->m_args.m_cs->lock();
data->m_args.m_cs->setSharedParam(0,eRequestTerminateExampleBrowser);
data->m_args.m_cs->setSharedParam(0, eRequestTerminateExampleBrowser);
data->m_args.m_cs->unlock();
while (numActiveThreads)
{
int arg0,arg1;
if (data->m_threadSupport->isTaskCompleted(&arg0,&arg1,0))
{
numActiveThreads--;
printf("numActiveThreads = %d\n",numActiveThreads);
} else
{
// printf("polling..");
b3Clock::usleep(0);
}
};
{
int arg0, arg1;
if (data->m_threadSupport->isTaskCompleted(&arg0, &arg1, 0))
{
numActiveThreads--;
printf("numActiveThreads = %d\n", numActiveThreads);
}
else
{
// printf("polling..");
b3Clock::usleep(0);
}
};
printf("btShutDownExampleBrowser stopping threads\n");
data->m_threadSupport->deleteCriticalSection(data->m_args.m_cs);
@@ -414,46 +380,45 @@ void btShutDownExampleBrowser(btInProcessExampleBrowserInternalData* data)
struct btInProcessExampleBrowserMainThreadInternalData
{
ExampleEntriesPhysicsServer m_examples;
DefaultBrowser* m_exampleBrowser;
SharedMemoryInterface* m_sharedMem;
b3Clock m_clock;
ExampleEntriesPhysicsServer m_examples;
DefaultBrowser* m_exampleBrowser;
SharedMemoryInterface* m_sharedMem;
b3Clock m_clock;
};
btInProcessExampleBrowserMainThreadInternalData* btCreateInProcessExampleBrowserMainThread(int argc,char** argv, bool useInProcessMemory)
btInProcessExampleBrowserMainThreadInternalData* btCreateInProcessExampleBrowserMainThread(int argc, char** argv, bool useInProcessMemory)
{
btInProcessExampleBrowserMainThreadInternalData* data = new btInProcessExampleBrowserMainThreadInternalData;
data->m_examples.initExampleEntries();
data->m_exampleBrowser = new DefaultBrowser(&data->m_examples);
data->m_sharedMem = useInProcessMemory ? new InProcessMemory : 0;
data->m_exampleBrowser->setSharedMemoryInterface(data->m_sharedMem );
btInProcessExampleBrowserMainThreadInternalData* data = new btInProcessExampleBrowserMainThreadInternalData;
data->m_examples.initExampleEntries();
data->m_exampleBrowser = new DefaultBrowser(&data->m_examples);
data->m_sharedMem = useInProcessMemory ? new InProcessMemory : 0;
data->m_exampleBrowser->setSharedMemoryInterface(data->m_sharedMem);
bool init;
init = data->m_exampleBrowser->init(argc,argv);
data->m_clock.reset();
return data;
init = data->m_exampleBrowser->init(argc, argv);
data->m_clock.reset();
return data;
}
bool btIsExampleBrowserMainThreadTerminated(btInProcessExampleBrowserMainThreadInternalData* data)
{
return data->m_exampleBrowser->requestedExit();
return data->m_exampleBrowser->requestedExit();
}
void btUpdateInProcessExampleBrowserMainThread(btInProcessExampleBrowserMainThreadInternalData* data)
{
float deltaTimeInSeconds = data->m_clock.getTimeMicroseconds()/1000000.f;
data->m_clock.reset();
data->m_exampleBrowser->updateGraphics();
data->m_exampleBrowser->update(deltaTimeInSeconds);
float deltaTimeInSeconds = data->m_clock.getTimeMicroseconds() / 1000000.f;
data->m_clock.reset();
data->m_exampleBrowser->updateGraphics();
data->m_exampleBrowser->update(deltaTimeInSeconds);
}
void btShutDownExampleBrowserMainThread(btInProcessExampleBrowserMainThreadInternalData* data)
{
data->m_exampleBrowser->setSharedMemoryInterface(0);
delete data->m_exampleBrowser;
delete data;
data->m_exampleBrowser->setSharedMemoryInterface(0);
delete data->m_exampleBrowser;
delete data;
}
class SharedMemoryInterface* btGetSharedMemoryInterfaceMainThread(btInProcessExampleBrowserMainThreadInternalData* data)
{
return data->m_sharedMem;
return data->m_sharedMem;
}

View File

@@ -3,7 +3,7 @@
struct btInProcessExampleBrowserInternalData;
btInProcessExampleBrowserInternalData* btCreateInProcessExampleBrowser(int argc,char** argv2, bool useInProcessMemory);
btInProcessExampleBrowserInternalData* btCreateInProcessExampleBrowser(int argc, char** argv2, bool useInProcessMemory);
bool btIsExampleBrowserTerminated(btInProcessExampleBrowserInternalData* data);
@@ -11,13 +11,11 @@ void btShutDownExampleBrowser(btInProcessExampleBrowserInternalData* data);
class SharedMemoryInterface* btGetSharedMemoryInterface(btInProcessExampleBrowserInternalData* data);
///////////////////////
struct btInProcessExampleBrowserMainThreadInternalData;
btInProcessExampleBrowserMainThreadInternalData* btCreateInProcessExampleBrowserMainThread(int argc,char** argv, bool useInProcessMemory);
btInProcessExampleBrowserMainThreadInternalData* btCreateInProcessExampleBrowserMainThread(int argc, char** argv, bool useInProcessMemory);
bool btIsExampleBrowserMainThreadTerminated(btInProcessExampleBrowserMainThreadInternalData* data);
@@ -27,7 +25,6 @@ void btShutDownExampleBrowserMainThread(btInProcessExampleBrowserMainThreadInter
class SharedMemoryInterface* btGetSharedMemoryInterfaceMainThread(btInProcessExampleBrowserMainThreadInternalData* data);
//////////////////////
#endif //IN_PROCESS_EXAMPLE_BROWSER_H
#endif //IN_PROCESS_EXAMPLE_BROWSER_H

File diff suppressed because it is too large Load Diff

View File

@@ -5,16 +5,14 @@
class OpenGLExampleBrowser : public ExampleBrowserInterface
{
struct OpenGLExampleBrowserInternalData* m_internalData;
public:
OpenGLExampleBrowser(class ExampleEntries* examples);
virtual ~OpenGLExampleBrowser();
virtual CommonExampleInterface* getCurrentExample();
virtual bool init(int argc, char* argv[]);
virtual void update(float deltaTime);
@@ -24,8 +22,8 @@ public:
virtual bool requestedExit();
virtual void setSharedMemoryInterface(class SharedMemoryInterface* sharedMem);
static void registerFileImporter(const char* extension, CommonExampleInterface::CreateFunc* createFunc);
static void registerFileImporter(const char* extension, CommonExampleInterface::CreateFunc* createFunc);
};
#endif //OPENGL_BROWSER_GUI_H
#endif //OPENGL_BROWSER_GUI_H

File diff suppressed because it is too large Load Diff

View File

@@ -22,8 +22,8 @@ struct OpenGLGuiHelper : public GUIHelperInterface
virtual void createCollisionObjectGraphicsObject(btCollisionObject* body, const btVector3& color);
virtual int registerTexture(const unsigned char* texels, int width, int height);
virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices,int primitiveType, int textureId);
virtual int registerTexture(const unsigned char* texels, int width, int height);
virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices, int primitiveType, int textureId);
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling);
virtual void removeAllGraphicsInstances();
virtual void removeGraphicsInstance(int graphicsUid);
@@ -31,84 +31,80 @@ struct OpenGLGuiHelper : public GUIHelperInterface
virtual void changeSpecularColor(int instanceUid, const double specularColor[3]);
virtual void changeTexture(int textureUniqueId, const unsigned char* rgbTexels, int width, int height);
virtual void removeTexture(int textureUid);
virtual int getShapeIndexFromInstance(int instanceUid);
virtual int getShapeIndexFromInstance(int instanceUid);
virtual void replaceTexture(int shapeIndex, int textureUid);
virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape);
virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld);
virtual void render(const btDiscreteDynamicsWorld* rbWorld);
virtual void createPhysicsDebugDrawer(btDiscreteDynamicsWorld* rbWorld);
virtual struct Common2dCanvasInterface* get2dCanvasInterface();
virtual struct Common2dCanvasInterface* get2dCanvasInterface();
virtual CommonParameterInterface* getParameterInterface();
virtual struct CommonGraphicsApp* getAppInterface();
virtual void setUpAxis(int axis);
virtual void resetCamera(float camDist, float yaw, float pitch, float camPosX,float camPosY, float camPosZ);
virtual bool getCameraInfo(int* width, int* height, float viewMatrix[16], float projectionMatrix[16], float camUp[3], float camForward[3],float hor[3], float vert[3], float* yaw, float* pitch, float* camDist, float cameraTarget[3]) const;
virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
float* depthBuffer, int depthBufferSizeInPixels,
int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels,
int startPixelIndex, int destinationWidth,
int destinationHeight, int* numPixelsCopied);
virtual void resetCamera(float camDist, float yaw, float pitch, float camPosX, float camPosY, float camPosZ);
virtual bool getCameraInfo(int* width, int* height, float viewMatrix[16], float projectionMatrix[16], float camUp[3], float camForward[3], float hor[3], float vert[3], float* yaw, float* pitch, float* camDist, float cameraTarget[3]) const;
virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
float* depthBuffer, int depthBufferSizeInPixels,
int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels,
int startPixelIndex, int destinationWidth,
int destinationHeight, int* numPixelsCopied);
virtual void setProjectiveTextureMatrices(const float viewMatrix[16], const float projectionMatrix[16]);
virtual void setProjectiveTexture(bool useProjectiveTexture);
virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld) ;
virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld);
virtual void drawText3D( const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag);
virtual void drawText3D(const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag);
virtual void drawText3D( const char* txt, float posX, float posY, float posZ, float size);
virtual void drawText3D(const char* txt, float posX, float posY, float posZ, float size);
virtual int addUserDebugText3D( const char* txt, const double positionXYZ[3], const double textColorRGB[3], double size, double lifeTime)
{
return -1;
}
virtual int addUserDebugLine(const double debugLineFromXYZ[3], const double debugLineToXYZ[3], const double debugLineColorRGB[3], double lineWidth, double lifeTime , int trackingVisualShapeIndex, int replaceItemUid )
{
return -1;
}
virtual int addUserDebugParameter(const char* txt, double rangeMin, double rangeMax, double startValue)
virtual int addUserDebugText3D(const char* txt, const double positionXYZ[3], const double textColorRGB[3], double size, double lifeTime)
{
return -1;
}
virtual void removeUserDebugItem( int debugItemUniqueId)
virtual int addUserDebugLine(const double debugLineFromXYZ[3], const double debugLineToXYZ[3], const double debugLineColorRGB[3], double lineWidth, double lifeTime, int trackingVisualShapeIndex, int replaceItemUid)
{
return -1;
}
virtual int addUserDebugParameter(const char* txt, double rangeMin, double rangeMax, double startValue)
{
return -1;
}
virtual void removeUserDebugItem(int debugItemUniqueId)
{
}
virtual void removeAllUserDebugItems( )
virtual void removeAllUserDebugItems()
{
}
void renderInternalGl2(int pass, const btDiscreteDynamicsWorld* dynamicsWorld);
void renderInternalGl2(int pass, const btDiscreteDynamicsWorld* dynamicsWorld);
void setVRMode(bool vrMode);
void setVisualizerFlag(int flag, int enable);
virtual void setVisualizerFlagCallback(VisualizerFlagCallback callback);
virtual void setVisualizerFlagCallback(VisualizerFlagCallback callback);
virtual void dumpFramesToVideo(const char* mp4FileName);
virtual void dumpFramesToVideo(const char* mp4FileName);
int createCheckeredTexture(int r,int g, int b);
int createCheckeredTexture(int r, int g, int b);
void computeSoftBodyVertices(btCollisionShape* collisionShape,
btAlignedObjectArray<GLInstanceVertex>& gfxVertices,
btAlignedObjectArray<int>& indices);
btAlignedObjectArray<GLInstanceVertex>& gfxVertices,
btAlignedObjectArray<int>& indices);
};
#endif //OPENGL_GUI_HELPER_H
#endif //OPENGL_GUI_HELPER_H

View File

@@ -19,9 +19,8 @@
static double gMinUpdateTimeMicroSecs = 1000.;
static bool interrupted=false;
static OpenGLExampleBrowser* sExampleBrowser=0;
static bool interrupted = false;
static OpenGLExampleBrowser* sExampleBrowser = 0;
#ifndef _WIN32
#include <signal.h>
@@ -29,48 +28,50 @@ static OpenGLExampleBrowser* sExampleBrowser=0;
#include <unistd.h>
static void cleanup(int signo)
{
if (!interrupted) { // this is the second time, we're hanging somewhere
b3Printf("Aborting and deleting SharedMemoryCommon object");
delete sExampleBrowser;
if (!interrupted)
{ // this is the second time, we're hanging somewhere
b3Printf("Aborting and deleting SharedMemoryCommon object");
delete sExampleBrowser;
sleep(1);
sExampleBrowser = 0;
errx(EXIT_FAILURE, "aborted example on signal %d", signo);
} else
{
errx(EXIT_FAILURE, "aborted example on signal %d", signo);
}
else
{
b3Printf("no action");
exit(EXIT_FAILURE);
}
interrupted = true;
warnx("caught signal %d", signo);
}
interrupted = true;
warnx("caught signal %d", signo);
}
#endif//_WIN32
#endif //_WIN32
int main(int argc, char* argv[])
{
#ifndef _WIN32
struct sigaction action;
memset(&action, 0x0, sizeof(action));
action.sa_handler = cleanup;
static const int signos[] = { SIGHUP, SIGINT, SIGQUIT, SIGABRT, SIGSEGV, SIGPIPE, SIGTERM };
for (int ii(0); ii < sizeof(signos) / sizeof(*signos); ++ii) {
if (0 != sigaction(signos[ii], &action, NULL)) {
err(EXIT_FAILURE, "signal %d", signos[ii]);
}
}
struct sigaction action;
memset(&action, 0x0, sizeof(action));
action.sa_handler = cleanup;
static const int signos[] = {SIGHUP, SIGINT, SIGQUIT, SIGABRT, SIGSEGV, SIGPIPE, SIGTERM};
for (int ii(0); ii < sizeof(signos) / sizeof(*signos); ++ii)
{
if (0 != sigaction(signos[ii], &action, NULL))
{
err(EXIT_FAILURE, "signal %d", signos[ii]);
}
}
#endif
{
b3CommandLineArgs args(argc, argv);
b3Clock clock;
args.GetCmdLineArgument("minUpdateTimeMicroSecs",gMinUpdateTimeMicroSecs);
args.GetCmdLineArgument("minUpdateTimeMicroSecs", gMinUpdateTimeMicroSecs);
ExampleEntriesAll examples;
examples.initExampleEntries();
OpenGLExampleBrowser* exampleBrowser = new OpenGLExampleBrowser(&examples);
sExampleBrowser = exampleBrowser;//for <CTRL-C> etc, cleanup shared memory
sExampleBrowser = exampleBrowser; //for <CTRL-C> etc, cleanup shared memory
bool init = exampleBrowser->init(argc, argv);
exampleBrowser->registerFileImporter(".urdf", ImportURDFCreateFunc);
exampleBrowser->registerFileImporter(".sdf", ImportSDFCreateFunc);
@@ -78,7 +79,6 @@ int main(int argc, char* argv[])
exampleBrowser->registerFileImporter(".stl", ImportSTLCreateFunc);
exampleBrowser->registerFileImporter(".bullet", SerializeBulletCreateFunc);
clock.reset();
if (init)
{
@@ -89,10 +89,11 @@ int main(int argc, char* argv[])
{
deltaTimeInSeconds = 0.1;
}
if (deltaTimeInSeconds < (gMinUpdateTimeMicroSecs/1e6))
if (deltaTimeInSeconds < (gMinUpdateTimeMicroSecs / 1e6))
{
b3Clock::usleep(gMinUpdateTimeMicroSecs/10.);
} else
b3Clock::usleep(gMinUpdateTimeMicroSecs / 10.);
}
else
{
clock.reset();
exampleBrowser->update(deltaTimeInSeconds);
@@ -100,13 +101,12 @@ int main(int argc, char* argv[])
} while (!exampleBrowser->requestedExit() && !interrupted);
}
delete exampleBrowser;
}
#ifdef BT_DEBUG_MEMORY_ALLOCATIONS
int numBytesLeaked = btDumpMemoryLeaks();
btAssert(numBytesLeaked==0);
#endif//BT_DEBUG_MEMORY_ALLOCATIONS
btAssert(numBytesLeaked == 0);
#endif //BT_DEBUG_MEMORY_ALLOCATIONS
return 0;
}

View File

@@ -1,6 +1,5 @@
#include "ImplicitClothExample.h"
#include "../CommonInterfaces/CommonExampleInterface.h"
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
#include "../CommonInterfaces/CommonRenderInterface.h"
@@ -12,46 +11,41 @@
#include "Bullet3Common/b3Vector3.h"
#include "Bullet3Common/b3AlignedObjectArray.h"
#ifdef _DEBUG
int numX = 20, numY=20;
int numX = 20, numY = 20;
#else
int numX = 60, numY=60;
int numX = 60, numY = 60;
#endif
const size_t total_points = (numX)*(numY);
const size_t total_points = (numX) * (numY);
struct ImplicitClothExample : public CommonExampleInterface
struct ImplicitClothExample : public CommonExampleInterface
{
struct GUIHelperInterface* m_guiHelper;
int m_option;
Cloth* m_cloth;
public:
ImplicitClothExample(struct GUIHelperInterface* helper, int option)
:m_guiHelper(helper),
m_option(option),
m_cloth(0)
: m_guiHelper(helper),
m_option(option),
m_cloth(0)
{
}
virtual void initPhysics();
virtual void exitPhysics();
virtual void stepSimulation(float deltaTime);
virtual void renderScene();
virtual void physicsDebugDraw(int debugFlags);//for now we reuse the flags in Bullet/src/LinearMath/btIDebugDraw.h
virtual bool mouseMoveCallback(float x,float y)
virtual void initPhysics();
virtual void exitPhysics();
virtual void stepSimulation(float deltaTime);
virtual void renderScene();
virtual void physicsDebugDraw(int debugFlags); //for now we reuse the flags in Bullet/src/LinearMath/btIDebugDraw.h
virtual bool mouseMoveCallback(float x, float y)
{
return false;
}
virtual bool mouseButtonCallback(int button, int state, float x, float y)
virtual bool mouseButtonCallback(int button, int state, float x, float y)
{
return false;
}
virtual bool keyboardCallback(int key, int state)
virtual bool keyboardCallback(int key, int state)
{
return false;
}
@@ -61,69 +55,59 @@ public:
float dist = 10;
float pitch = 62;
float yaw = 33;
float targetPos[3]={-3,2.4,-3.6};
m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
float targetPos[3] = {-3, 2.4, -3.6};
m_guiHelper->resetCamera(dist, pitch, yaw, targetPos[0], targetPos[1], targetPos[2]);
}
};
void ImplicitClothExample::initPhysics()
void ImplicitClothExample::initPhysics()
{
float size=10;
float size = 10;
m_guiHelper->setUpAxis(1);
m_cloth = ClothCreate(numX,numY,size);
m_cloth = ClothCreate(numX, numY, size);
}
void ImplicitClothExample::exitPhysics()
void ImplicitClothExample::exitPhysics()
{
delete m_cloth;
m_cloth=0;
m_cloth = 0;
}
void ImplicitClothExample::stepSimulation(float deltaTime)
void ImplicitClothExample::stepSimulation(float deltaTime)
{
m_cloth->Simulate(deltaTime);
m_cloth->cloth_gravity.y = -9.8;//-9.8;//-9.8;//-9.8;//0;//-9.8;//0;//-9.8;//0;//-9.8;
m_cloth->cloth_gravity.z =-9.8;//0;//-9.8;//0;//-9.8;
m_cloth->spring_struct=10000000.0f;
m_cloth->spring_shear=10000000.0f;
m_cloth->cloth_gravity.y = -9.8; //-9.8;//-9.8;//-9.8;//0;//-9.8;//0;//-9.8;//0;//-9.8;
m_cloth->cloth_gravity.z = -9.8; //0;//-9.8;//0;//-9.8;
m_cloth->spring_struct = 10000000.0f;
m_cloth->spring_shear = 10000000.0f;
//m_cloth->spring_struct=1000000.0f;
//m_cloth->spring_shear=1000000.0f;
m_cloth->spring_damp = 0;//100;
m_cloth->spring_damp = 0; //100;
}
void ImplicitClothExample::renderScene()
void ImplicitClothExample::renderScene()
{
}
void ImplicitClothExample::physicsDebugDraw(int debugFlags)
void ImplicitClothExample::physicsDebugDraw(int debugFlags)
{
CommonRenderInterface* renderer = m_guiHelper->getRenderInterface();
b3AlignedObjectArray<unsigned int> indices;
for (int i=0;i<m_cloth->springs.count;i++)
{
indices.push_back(m_cloth->springs[i].a);
indices.push_back(m_cloth->springs[i].b);
}
float lineColor[4]={0.4,0.4,1.0,1};
renderer->drawLines(&m_cloth->X[0].x,lineColor,total_points,sizeof(float3),&indices[0],indices.size(),1);
float pointColor[4]={1,0.4,0.4,1};
// renderer->drawPoints(&m_cloth->X[0].x,pointColor,total_points,sizeof(float3),3);
b3AlignedObjectArray<unsigned int> indices;
for (int i = 0; i < m_cloth->springs.count; i++)
{
indices.push_back(m_cloth->springs[i].a);
indices.push_back(m_cloth->springs[i].b);
}
float lineColor[4] = {0.4, 0.4, 1.0, 1};
renderer->drawLines(&m_cloth->X[0].x, lineColor, total_points, sizeof(float3), &indices[0], indices.size(), 1);
float pointColor[4] = {1, 0.4, 0.4, 1};
// renderer->drawPoints(&m_cloth->X[0].x,pointColor,total_points,sizeof(float3),3);
}
class CommonExampleInterface* ImplicitClothCreateFunc(struct CommonExampleOptions& options)
class CommonExampleInterface* ImplicitClothCreateFunc(struct CommonExampleOptions& options)
{
return new ImplicitClothExample(options.m_guiHelper, options.m_option);
}

View File

@@ -1,8 +1,6 @@
#ifndef IMPLICIT_CLOTH_EXAMPLE_H
#define IMPLICIT_CLOTH_EXAMPLE_H
class CommonExampleInterface* ImplicitClothCreateFunc(struct CommonExampleOptions& options);
#endif //IMPLICIT_CLOTH_EXAMPLE_H
class CommonExampleInterface* ImplicitClothCreateFunc(struct CommonExampleOptions& options);
#endif //IMPLICIT_CLOTH_EXAMPLE_H

View File

@@ -9,62 +9,54 @@
#include "Cloth.h"
Array<Cloth*> cloths;
Array<Cloth *> cloths;
Cloth::Cloth(const char *_name,int _n):SpringNetwork(_n),
color(0,0.5f,1.0f)
Cloth::Cloth(const char *_name, int _n) : SpringNetwork(_n),
color(0, 0.5f, 1.0f)
{
cloths.Add(this);
cloths.Add(this);
}
Cloth::~Cloth()
{
cloths.Remove(this);
cloths.Remove(this);
}
//
// I/O support for serialization of our springnetwork and cloth objects.
//
int cloth_showbbox = 0; // for debug visualization shows bounding box.
float cloth_showvert = 0.025f; // size of box to put around current vert selected, 0 turns off
int cloth_showbbox = 0; // for debug visualization shows bounding box.
float cloth_showvert = 0.025f; // size of box to put around current vert selected, 0 turns off
Cloth *ClothCreate(int w,int h,float size)
Cloth *ClothCreate(int w, int h, float size)
{
// simple cloth generation routine that creates a typical square cloth.
// better to use a real pipeline to generate these, this is just for testing.
int i,j;
Cloth *cloth = new Cloth("cloth",w*h);
cloth->w=w;
cloth->h=h; // later for rendering.
for(i=0;i<h;i++)
for(j=0;j<w;j++)
{
cloth->X[i*w+j] = (float3(-0.5f,-0.5f,0)+float3((float)j/(w-1.0f),1.0f-(float)i/(h-1.0f),0)) * size;
}
for(i=0;i<h;i++)
for(j=0;j<w;j++)
{
if(i<h-1) cloth->CreateSpring(SPRING_STRUCT,i*w+j,(i+1)*w+j); // structural
if(j<w-1) cloth->CreateSpring(SPRING_STRUCT,i*w+j,i*w+(j+1)); // structural
if(j<w-1&&i<h-1) cloth->CreateSpring(SPRING_SHEAR ,i*w+j,(i+1)*w+(j+1)); // shear
if(j>0 &&i<h-1) cloth->CreateSpring(SPRING_SHEAR ,i*w+j,(i+1)*w+(j-1)); // shear
if(i<h-2) cloth->CreateSpring(SPRING_BEND ,i*w+j,(i+2)*w+j); // benders
if(j<w-2) cloth->CreateSpring(SPRING_BEND ,i*w+j,i*w+(j+2)); // benders
}
cloth->UpdateLimits();
return cloth;
// simple cloth generation routine that creates a typical square cloth.
// better to use a real pipeline to generate these, this is just for testing.
int i, j;
Cloth *cloth = new Cloth("cloth", w * h);
cloth->w = w;
cloth->h = h; // later for rendering.
for (i = 0; i < h; i++)
for (j = 0; j < w; j++)
{
cloth->X[i * w + j] = (float3(-0.5f, -0.5f, 0) + float3((float)j / (w - 1.0f), 1.0f - (float)i / (h - 1.0f), 0)) * size;
}
for (i = 0; i < h; i++)
for (j = 0; j < w; j++)
{
if (i < h - 1) cloth->CreateSpring(SPRING_STRUCT, i * w + j, (i + 1) * w + j); // structural
if (j < w - 1) cloth->CreateSpring(SPRING_STRUCT, i * w + j, i * w + (j + 1)); // structural
if (j < w - 1 && i < h - 1) cloth->CreateSpring(SPRING_SHEAR, i * w + j, (i + 1) * w + (j + 1)); // shear
if (j > 0 && i < h - 1) cloth->CreateSpring(SPRING_SHEAR, i * w + j, (i + 1) * w + (j - 1)); // shear
if (i < h - 2) cloth->CreateSpring(SPRING_BEND, i * w + j, (i + 2) * w + j); // benders
if (j < w - 2) cloth->CreateSpring(SPRING_BEND, i * w + j, i * w + (j + 2)); // benders
}
cloth->UpdateLimits();
return cloth;
}
int cloth_tess = 20;
float3 cloth_spawnpoint(0,3,5.0f);
int cloth_tess = 20;
float3 cloth_spawnpoint(0, 3, 5.0f);
/*
static void ClothDrawSprings(Cloth *cloth)
@@ -79,18 +71,17 @@ static void ClothDrawSprings(Cloth *cloth)
}
}
*/
int cloth_showsprings=0;
int cloth_showsprings = 0;
void DoCloths()
{
int i;
for(i=0;i<cloths.count;i++)
{
Cloth *cloth=cloths[i];
// cloth->Simulate((cloth->cloth_step<0)?DeltaT:cloth->cloth_step);
//if(cloth_showsprings)
// ClothDrawSprings(cloth); // debug visualization
}
int i;
for (i = 0; i < cloths.count; i++)
{
Cloth *cloth = cloths[i];
// cloth->Simulate((cloth->cloth_step<0)?DeltaT:cloth->cloth_step);
//if(cloth_showsprings)
// ClothDrawSprings(cloth); // debug visualization
}
}

View File

@@ -5,14 +5,14 @@
class Cloth : public SpringNetwork
{
public:
int w,h;
float3 color; // for debug rendering
Cloth(const char* _name,int _n);
~Cloth();
public:
int w, h;
float3 color; // for debug rendering
Cloth(const char* _name, int _n);
~Cloth();
};
Cloth *ClothCreate(int w,int h,float size);
Cloth* ClothCreate(int w, int h, float size);
#endif //STAN_CLOTH_H
#endif //STAN_CLOTH_H

View File

@@ -1,10 +1,8 @@
#include "vec3n.h"
//#include "console.h"
extern int numX;
//
// Cloth - Backward Integrated Spring Network
//
@@ -42,157 +40,144 @@ extern int numX;
//#include "object.h"
//#include "xmlparse.h"
static const float3x3 I(1, 0, 0, 0, 1, 0, 0, 0, 1);
static const float3x3 I(1,0,0,0,1,0,0,0,1);
inline float3x3 dfdx_spring(const float3 &dir,float length,float rest,float k)
inline float3x3 dfdx_spring(const float3 &dir, float length, float rest, float k)
{
// dir is unit length direction, rest is spring's restlength, k is spring constant.
return ( (I-outerprod(dir,dir))*Min(1.0f,rest/length) - I) * -k;
// dir is unit length direction, rest is spring's restlength, k is spring constant.
return ((I - outerprod(dir, dir)) * Min(1.0f, rest / length) - I) * -k;
}
inline float3x3 dfdx_damp(const float3 &dir,float length,const float3& vel,float rest,float damping)
inline float3x3 dfdx_damp(const float3 &dir, float length, const float3 &vel, float rest, float damping)
{
// inner spring damping vel is the relative velocity of the endpoints.
return (I-outerprod(dir,dir)) * (-damping * -(dot(dir,vel)/Max(length,rest)));
// inner spring damping vel is the relative velocity of the endpoints.
return (I - outerprod(dir, dir)) * (-damping * -(dot(dir, vel) / Max(length, rest)));
}
inline float3x3 dfdv_damp(const float3 &dir,float damping)
inline float3x3 dfdv_damp(const float3 &dir, float damping)
{
// derivative of force wrt velocity.
return outerprod(dir,dir) * damping;
// derivative of force wrt velocity.
return outerprod(dir, dir) * damping;
}
#include "SpringNetwork.h"
SpringNetwork::SpringNetwork(int _n):X(_n),V(_n),F(_n),dV(_n),A(_n),dFdX(_n),dFdV(_n)
SpringNetwork::SpringNetwork(int _n) : X(_n), V(_n), F(_n), dV(_n), A(_n), dFdX(_n), dFdV(_n)
{
assert(SPRING_STRUCT==0);
assert(&spring_shear == &spring_struct +SPRING_SHEAR);
assert(&spring_bend == &spring_struct +SPRING_BEND);
assert(&spring_struct== &spring_k[SPRING_STRUCT]);
assert(&spring_shear == &spring_k[SPRING_SHEAR ]);
assert(&spring_bend == &spring_k[SPRING_BEND ]);
// spring_struct=1000000.0f;
// spring_shear=1000000.0f;
spring_struct=1000.0f;
spring_shear=100.0f;
spring_bend=25.0f;
spring_damp=5.0f;
spring_air=1.0f;
spring_air=1.0f;
cloth_step = 0.25f; // delta time for cloth
cloth_gravity=float3(0,-10,0);
cloth_sleepthreshold = 0.001f;
cloth_sleepcount = 100;
awake = cloth_sleepcount;
//fix/pin two points in worldspace
float3Nx3N::Block zero;
zero.m = float3x3(0,0,0,0,0,0,0,0,0);
zero.c = 0;
zero.r = 0;
S.blocks.Add(zero);
zero.r = numX-1;
S.blocks.Add(zero);
assert(SPRING_STRUCT == 0);
assert(&spring_shear == &spring_struct + SPRING_SHEAR);
assert(&spring_bend == &spring_struct + SPRING_BEND);
assert(&spring_struct == &spring_k[SPRING_STRUCT]);
assert(&spring_shear == &spring_k[SPRING_SHEAR]);
assert(&spring_bend == &spring_k[SPRING_BEND]);
// spring_struct=1000000.0f;
// spring_shear=1000000.0f;
spring_struct = 1000.0f;
spring_shear = 100.0f;
spring_bend = 25.0f;
spring_damp = 5.0f;
spring_air = 1.0f;
spring_air = 1.0f;
cloth_step = 0.25f; // delta time for cloth
cloth_gravity = float3(0, -10, 0);
cloth_sleepthreshold = 0.001f;
cloth_sleepcount = 100;
awake = cloth_sleepcount;
//fix/pin two points in worldspace
float3Nx3N::Block zero;
zero.m = float3x3(0, 0, 0, 0, 0, 0, 0, 0, 0);
zero.c = 0;
zero.r = 0;
S.blocks.Add(zero);
zero.r = numX - 1;
S.blocks.Add(zero);
}
SpringNetwork::Spring &SpringNetwork::AddBlocks(Spring &s)
{
// Called during initial creation of springs in our spring network.
// Sets up the sparse matrices corresponding to connections.
// Note the indices (s.iab,s.iba) are also stored with spring to avoid looking them up each time a spring is applied
// All 3 matrices A,dFdX, and dFdV are contstructed identically so the block array layout will be the same for each.
s.iab = A.blocks.count; // added 'ab' blocks will have this index.
A.blocks.Add(float3Nx3N::Block(s.a,s.b));
dFdX.blocks.Add(float3Nx3N::Block(s.a,s.b));
dFdV.blocks.Add(float3Nx3N::Block(s.a,s.b));
s.iba = A.blocks.count; // added 'ba' blocks will have this index.
A.blocks.Add(float3Nx3N::Block(s.b,s.a));
dFdX.blocks.Add(float3Nx3N::Block(s.b,s.a));
dFdV.blocks.Add(float3Nx3N::Block(s.b,s.a));
return s;
// Called during initial creation of springs in our spring network.
// Sets up the sparse matrices corresponding to connections.
// Note the indices (s.iab,s.iba) are also stored with spring to avoid looking them up each time a spring is applied
// All 3 matrices A,dFdX, and dFdV are contstructed identically so the block array layout will be the same for each.
s.iab = A.blocks.count; // added 'ab' blocks will have this index.
A.blocks.Add(float3Nx3N::Block(s.a, s.b));
dFdX.blocks.Add(float3Nx3N::Block(s.a, s.b));
dFdV.blocks.Add(float3Nx3N::Block(s.a, s.b));
s.iba = A.blocks.count; // added 'ba' blocks will have this index.
A.blocks.Add(float3Nx3N::Block(s.b, s.a));
dFdX.blocks.Add(float3Nx3N::Block(s.b, s.a));
dFdV.blocks.Add(float3Nx3N::Block(s.b, s.a));
return s;
}
void SpringNetwork::PreSolveSpring(const SpringNetwork::Spring &s)
{
// Adds this spring's contribution into force vector F and force derivitves dFdX and dFdV
// One optimization would be premultiply dfdx by dt*dt and F and dFdV by dt right here in this function.
// However, for educational purposes we wont do that now and intead just follow the paper directly.
//assert(dFdX.blocks[s.a].c==s.a); // delete this assert, no bugs here
//assert(dFdX.blocks[s.a].r==s.a);
float3 extent = X[s.b] - X[s.a];
float length = magnitude(extent);
float3 dir = (length==0)?float3(0,0,0): extent * 1.0f/length;
float3 vel = V[s.b] - V[s.a];
float k = spring_k[s.type];
float3 f = dir * ((k * (length-s.restlen) ) + spring_damp * dot(vel,dir)); // spring force + damping force
F[s.a] += f;
F[s.b] -= f;
float3x3 dfdx = dfdx_spring(dir,length,s.restlen,k) + dfdx_damp(dir,length,vel,s.restlen,spring_damp);
dFdX.blocks[s.a].m -= dfdx; // diagonal chunk dFdX[a,a]
dFdX.blocks[s.b].m -= dfdx; // diagonal chunk dFdX[b,b]
dFdX.blocks[s.iab].m += dfdx; // off-diag chunk dFdX[a,b]
dFdX.blocks[s.iba].m += dfdx; // off-diag chunk dFdX[b,a]
float3x3 dfdv = dfdv_damp(dir,spring_damp);
dFdV.blocks[s.a].m -= dfdv; // diagonal chunk dFdV[a,a]
dFdV.blocks[s.b].m -= dfdv; // diagonal chunk dFdV[b,b]
dFdV.blocks[s.iab].m += dfdv; // off-diag chunk dFdV[a,b]
dFdV.blocks[s.iba].m += dfdv; // off-diag chunk dFdV[b,a]
// Adds this spring's contribution into force vector F and force derivitves dFdX and dFdV
// One optimization would be premultiply dfdx by dt*dt and F and dFdV by dt right here in this function.
// However, for educational purposes we wont do that now and intead just follow the paper directly.
//assert(dFdX.blocks[s.a].c==s.a); // delete this assert, no bugs here
//assert(dFdX.blocks[s.a].r==s.a);
float3 extent = X[s.b] - X[s.a];
float length = magnitude(extent);
float3 dir = (length == 0) ? float3(0, 0, 0) : extent * 1.0f / length;
float3 vel = V[s.b] - V[s.a];
float k = spring_k[s.type];
float3 f = dir * ((k * (length - s.restlen)) + spring_damp * dot(vel, dir)); // spring force + damping force
F[s.a] += f;
F[s.b] -= f;
float3x3 dfdx = dfdx_spring(dir, length, s.restlen, k) + dfdx_damp(dir, length, vel, s.restlen, spring_damp);
dFdX.blocks[s.a].m -= dfdx; // diagonal chunk dFdX[a,a]
dFdX.blocks[s.b].m -= dfdx; // diagonal chunk dFdX[b,b]
dFdX.blocks[s.iab].m += dfdx; // off-diag chunk dFdX[a,b]
dFdX.blocks[s.iba].m += dfdx; // off-diag chunk dFdX[b,a]
float3x3 dfdv = dfdv_damp(dir, spring_damp);
dFdV.blocks[s.a].m -= dfdv; // diagonal chunk dFdV[a,a]
dFdV.blocks[s.b].m -= dfdv; // diagonal chunk dFdV[b,b]
dFdV.blocks[s.iab].m += dfdv; // off-diag chunk dFdV[a,b]
dFdV.blocks[s.iba].m += dfdv; // off-diag chunk dFdV[b,a]
}
void SpringNetwork::CalcForces()
{
// Collect forces and derivatives: F,dFdX,dFdV
dFdX.Zero();
dFdV.InitDiagonal(-spring_air);
F.Init(cloth_gravity);
// Collect forces and derivatives: F,dFdX,dFdV
dFdX.Zero();
dFdV.InitDiagonal(-spring_air);
F.Init(cloth_gravity);
F.element[0]=float3(0,0,0);
F.element[numX-1]=float3(0,0,0);
F -= V * spring_air;
for(int i=0;i<springs.count;i++)
{
PreSolveSpring(springs[i]); // will add to F,dFdX,dFdV
}
F.element[0] = float3(0, 0, 0);
F.element[numX - 1] = float3(0, 0, 0);
F -= V * spring_air;
for (int i = 0; i < springs.count; i++)
{
PreSolveSpring(springs[i]); // will add to F,dFdX,dFdV
}
}
void SpringNetwork::Simulate(float dt)
{
// Get ready for conjugate gradient iterative solver step.
// Initialize operands.
if(!awake) return;
CalcForces();
int n=X.count; // all our big vectors are of this size
float3N dFdXmV(n); // temp to store result of matrix multiply
float3N B(n);
dV.Zero();
A.Identity(); // build up the big matrix we feed to solver
A -= dFdV * dt + dFdX * (dt*dt) ;
dFdXmV = dFdX * V;
B = F * dt + dFdXmV * (dt*dt);
ConjGradientFiltered(dV,A,B,S);
V = V + dV;
// V.element[0] = float3(0,0,0);
// V.element[numX-1] = float3(0,0,0);
// Get ready for conjugate gradient iterative solver step.
// Initialize operands.
if (!awake) return;
CalcForces();
int n = X.count; // all our big vectors are of this size
float3N dFdXmV(n); // temp to store result of matrix multiply
float3N B(n);
dV.Zero();
A.Identity(); // build up the big matrix we feed to solver
A -= dFdV * dt + dFdX * (dt * dt);
X = X + V*dt;
dFdXmV = dFdX * V;
B = F * dt + dFdXmV * (dt * dt);
UpdateLimits();
awake = (dot(V,V)<cloth_sleepthreshold)?awake-1:awake=cloth_sleepcount;
ConjGradientFiltered(dV, A, B, S);
V = V + dV;
// V.element[0] = float3(0,0,0);
// V.element[numX-1] = float3(0,0,0);
X = X + V * dt;
UpdateLimits();
awake = (dot(V, V) < cloth_sleepthreshold) ? awake - 1 : awake = cloth_sleepcount;
}

View File

@@ -4,60 +4,58 @@
#include "vec3n.h"
#define SPRING_STRUCT (0)
#define SPRING_SHEAR (1)
#define SPRING_BEND (2)
#define SPRING_SHEAR (1)
#define SPRING_BEND (2)
class SpringNetwork
{
public:
class Spring
{
public:
int type; // index into coefficients spring_k[]
float restlen;
int a,b; // spring endpoints vector indices
int iab,iba; // indices into off-diagonal blocks of sparse matrix
Spring(){}
Spring(int _type,int _a,int _b,float _restlen):type(_type),a(_a),b(_b),restlen(_restlen){iab=iba=-1;}
};
Array<Spring> springs;
float3N X; // positions of all points
float3N V; // velocities
float3N F; // force on each point
float3N dV; // change in velocity
float3Nx3N A; // big matrix we solve system with
float3Nx3N dFdX; // big matrix of derivative of force wrt position
float3Nx3N dFdV; // big matrix of derivative of force wrt velocity
float3Nx3N S; // used for our constraints - contains only some diagonal blocks as needed S[i,i]
int awake;
float3 bmin,bmax;
union
{
struct
{
float spring_struct;
float spring_shear;
float spring_bend;
};
float spring_k[3];
};
float spring_damp;
float spring_air;
float cloth_step; // delta time for cloth
float3 cloth_gravity;
float cloth_sleepthreshold;
int cloth_sleepcount;
public:
class Spring
{
public:
int type; // index into coefficients spring_k[]
float restlen;
int a, b; // spring endpoints vector indices
int iab, iba; // indices into off-diagonal blocks of sparse matrix
Spring() {}
Spring(int _type, int _a, int _b, float _restlen) : type(_type), a(_a), b(_b), restlen(_restlen) { iab = iba = -1; }
};
Array<Spring> springs;
float3N X; // positions of all points
float3N V; // velocities
float3N F; // force on each point
float3N dV; // change in velocity
float3Nx3N A; // big matrix we solve system with
float3Nx3N dFdX; // big matrix of derivative of force wrt position
float3Nx3N dFdV; // big matrix of derivative of force wrt velocity
float3Nx3N S; // used for our constraints - contains only some diagonal blocks as needed S[i,i]
int awake;
float3 bmin, bmax;
union {
struct
{
float spring_struct;
float spring_shear;
float spring_bend;
};
float spring_k[3];
};
float spring_damp;
float spring_air;
float cloth_step; // delta time for cloth
float3 cloth_gravity;
float cloth_sleepthreshold;
int cloth_sleepcount;
SpringNetwork(int _n);
Spring &AddBlocks(Spring &s);
Spring &CreateSpring(int type,int a,int b,float restlen){return AddBlocks(springs.Add(Spring(type,a,b,restlen)));}
Spring &CreateSpring(int type,int a,int b){return CreateSpring(type,a,b,magnitude(X[b]-X[a]));}
void UpdateLimits() { BoxLimits(X.element,X.count,bmin,bmax);}
void Wake(){awake=cloth_sleepcount;}
void Simulate(float dt);
void PreSolveSpring(const Spring &s);
void CalcForces();
SpringNetwork(int _n);
Spring &AddBlocks(Spring &s);
Spring &CreateSpring(int type, int a, int b, float restlen) { return AddBlocks(springs.Add(Spring(type, a, b, restlen))); }
Spring &CreateSpring(int type, int a, int b) { return CreateSpring(type, a, b, magnitude(X[b] - X[a])); }
void UpdateLimits() { BoxLimits(X.element, X.count, bmin, bmax); }
void Wake() { awake = cloth_sleepcount; }
void Simulate(float dt);
void PreSolveSpring(const Spring &s);
void CalcForces();
};
#endif //STAN_SPRING_NETWORK_H
#endif //STAN_SPRING_NETWORK_H

View File

@@ -1,41 +1,41 @@
//
// Typical template dynamic array container class.
// By S Melax 1998
//
//
// anyone is free to use, inspect, learn from, or ignore
// the code here as they see fit.
// the code here as they see fit.
//
// A very simple template array class.
// Its easiest to understand this array
// class by seeing how it is used in code.
//
// For example:
// for(i=0;i<myarray.count;i++)
// for(i=0;i<myarray.count;i++)
// myarray[i] = somefunction(i);
//
// When the array runs out of room, it
//
// When the array runs out of room, it
// reallocates memory and doubles the size of its
// storage buffer. The reason for *doubleing* the amount of
// memory is so the order of any algorithm using this class
// is the same as it would be had you used a regular C array.
// The penalty for reallocating and copying
// The penalty for reallocating and copying
// For example consider adding n elements to a list.
// Lets sum the number of times elements are "copied".
// The worst case occurs when n=2^k+1 where k is integer.
// In this case we do a big reallocation when we add the last element.
// In this case we do a big reallocation when we add the last element.
// n elements are copied once, n/2 elements are copied twice,
// n/4 elements are copied 3 times, and so on ...
// total == n* (1+1/2 + 1/4 + 1/8 + ...) == n * 2
// So we do n*2 copies. Therefore adding n
// So we do n*2 copies. Therefore adding n
// elements to an Array is still O(n).
// The memory usage is also of the same order as if a C array was used.
// An Array uses less than double the minimum needed space. Again, we
// An Array uses less than double the minimum needed space. Again, we
// see that we are within a small constant multiple.
//
// Why no "realloc" to avoid the copy when reallocating memory?
// You have a choice to either use malloc/free and friends
//
// Why no "realloc" to avoid the copy when reallocating memory?
// You have a choice to either use malloc/free and friends
// or to use new/delete. Its bad mojo to mix these. new/delete was
// chosen to be C++ish and have the array elements constructors/destructors
// chosen to be C++ish and have the array elements constructors/destructors
// invoked as expected.
//
//
@@ -46,231 +46,257 @@
#include <assert.h>
#include <stdio.h>
template <class Type> class Array {
public:
Array(int s=0);
Array(Array<Type> &array);
~Array();
void allocate(int s);
void SetSize(int s);
void Pack();
Type& Add(Type);
void AddUnique(Type);
int Contains(Type);
void Insert(Type,int);
int IndexOf(Type);
void Remove(Type);
void DelIndex(int i);
Type& DelIndexWithLast(int i);
Type * element;
int count;
int array_size;
const Type &operator[](int i) const { assert(i>=0 && i<count); return element[i]; }
Type &operator[](int i) { assert(i>=0 && i<count); return element[i]; }
Type &Pop() { assert(count); count--; return element[count]; }
template <class Type>
class Array
{
public:
Array(int s = 0);
Array(Array<Type> &array);
~Array();
void allocate(int s);
void SetSize(int s);
void Pack();
Type &Add(Type);
void AddUnique(Type);
int Contains(Type);
void Insert(Type, int);
int IndexOf(Type);
void Remove(Type);
void DelIndex(int i);
Type &DelIndexWithLast(int i);
Type *element;
int count;
int array_size;
const Type &operator[](int i) const
{
assert(i >= 0 && i < count);
return element[i];
}
Type &operator[](int i)
{
assert(i >= 0 && i < count);
return element[i];
}
Type &Pop()
{
assert(count);
count--;
return element[count];
}
Array<Type> &copy(const Array<Type> &array);
Array<Type> &operator=(Array<Type> &array);
};
template <class Type> Array<Type>::Array(int s)
template <class Type>
Array<Type>::Array(int s)
{
if(s==-1) return;
count=0;
if (s == -1) return;
count = 0;
array_size = 0;
element = NULL;
if(s)
{
if (s)
{
allocate(s);
}
}
template <class Type> Array<Type>::Array(Array<Type> &array)
template <class Type>
Array<Type>::Array(Array<Type> &array)
{
count=0;
count = 0;
array_size = 0;
element = NULL;
*this = array;
}
template <class Type> Array<Type> &Array<Type>::copy(const Array<Type> &array)
template <class Type>
Array<Type> &Array<Type>::copy(const Array<Type> &array)
{
assert(array.array_size>=0);
count=0;
for(int i=0;i<array.count;i++)
{
assert(array.array_size >= 0);
count = 0;
for (int i = 0; i < array.count; i++)
{
Add(array[i]);
}
return *this;
}
template <class Type> Array<Type> &Array<Type>::operator=( Array<Type> &array)
template <class Type>
Array<Type> &Array<Type>::operator=(Array<Type> &array)
{
if(array.array_size<0) // negative number means steal the data buffer instead of copying
if (array.array_size < 0) // negative number means steal the data buffer instead of copying
{
delete[] element;
delete[] element;
element = array.element;
array_size = -array.array_size;
count = array.count;
array.count =array.array_size = 0;
array.count = array.array_size = 0;
array.element = NULL;
return *this;
}
count=0;
for(int i=0;i<array.count;i++)
{
count = 0;
for (int i = 0; i < array.count; i++)
{
Add(array[i]);
}
return *this;
}
template <class Type> Array<Type>::~Array()
template <class Type>
Array<Type>::~Array()
{
if (element != NULL && array_size!=0)
{
delete[] element;
}
count=0;array_size=0;element=NULL;
if (element != NULL && array_size != 0)
{
delete[] element;
}
count = 0;
array_size = 0;
element = NULL;
}
template <class Type> void Array<Type>::allocate(int s)
template <class Type>
void Array<Type>::allocate(int s)
{
assert(s>0);
assert(s>=count);
if(s==array_size) return;
assert(s > 0);
assert(s >= count);
if (s == array_size) return;
Type *old = element;
array_size =s;
array_size = s;
element = new Type[array_size];
assert(element);
for(int i=0;i<count;i++)
{
element[i]=old[i];
for (int i = 0; i < count; i++)
{
element[i] = old[i];
}
if(old) delete[] old;
if (old) delete[] old;
}
template <class Type> void Array<Type>::SetSize(int s)
template <class Type>
void Array<Type>::SetSize(int s)
{
if(s==0)
{
if(element)
{
delete[] element;
element = NULL;
}
if (s == 0)
{
if (element)
{
delete[] element;
element = NULL;
}
array_size = s;
}
else
{
allocate(s);
}
count=s;
}
else
{
allocate(s);
}
count = s;
}
template <class Type> void Array<Type>::Pack()
template <class Type>
void Array<Type>::Pack()
{
allocate(count);
}
template <class Type> Type& Array<Type>::Add(Type t)
template <class Type>
Type &Array<Type>::Add(Type t)
{
assert(count<=array_size);
if(count==array_size)
{
allocate((array_size)?array_size *2:16);
assert(count <= array_size);
if (count == array_size)
{
allocate((array_size) ? array_size * 2 : 16);
}
//int i;
//for(i=0;i<count;i++) {
// dissallow duplicates
// dissallow duplicates
// assert(element[i] != t);
//}
element[count++] = t;
return element[count-1];
return element[count - 1];
}
template <class Type> int Array<Type>::Contains(Type t)
template <class Type>
int Array<Type>::Contains(Type t)
{
int i;
int found=0;
for(i=0;i<count;i++)
{
if(element[i] == t) found++;
int found = 0;
for (i = 0; i < count; i++)
{
if (element[i] == t) found++;
}
return found;
}
template <class Type> void Array<Type>::AddUnique(Type t)
template <class Type>
void Array<Type>::AddUnique(Type t)
{
if(!Contains(t)) Add(t);
if (!Contains(t)) Add(t);
}
template <class Type> void Array<Type>::DelIndex(int i)
template <class Type>
void Array<Type>::DelIndex(int i)
{
assert(i<count);
assert(i < count);
count--;
while(i<count)
{
element[i] = element[i+1];
while (i < count)
{
element[i] = element[i + 1];
i++;
}
}
template <class Type> Type& Array<Type>::DelIndexWithLast(int i)
template <class Type>
Type &Array<Type>::DelIndexWithLast(int i)
{
assert(i<count);
assert(i < count);
count--;
if(i<count)
{
Type r=element[i];
if (i < count)
{
Type r = element[i];
element[i] = element[count];
element[count]=r;
element[count] = r;
}
return element[count];
}
template <class Type> void Array<Type>::Remove(Type t)
template <class Type>
void Array<Type>::Remove(Type t)
{
int i;
for(i=0;i<count;i++)
{
if(element[i] == t)
{
for (i = 0; i < count; i++)
{
if (element[i] == t)
{
break;
}
}
assert(i<count); // assert object t is in the array.
assert(i < count); // assert object t is in the array.
DelIndex(i);
for(i=0;i<count;i++)
{
for (i = 0; i < count; i++)
{
assert(element[i] != t);
}
}
template <class Type> void Array<Type>::Insert(Type t,int k)
template <class Type>
void Array<Type>::Insert(Type t, int k)
{
int i=count;
Add(t); // to allocate space
while(i>k)
{
element[i]=element[i-1];
int i = count;
Add(t); // to allocate space
while (i > k)
{
element[i] = element[i - 1];
i--;
}
assert(i==k);
element[k]=t;
assert(i == k);
element[k] = t;
}
template <class Type> int Array<Type>::IndexOf(Type t)
template <class Type>
int Array<Type>::IndexOf(Type t)
{
int i;
for(i=0;i<count;i++)
{
if(element[i] == t)
{
for (i = 0; i < count; i++)
{
if (element[i] == t)
{
return i;
}
}
@@ -278,7 +304,4 @@ template <class Type> int Array<Type>::IndexOf(Type t)
return -1;
}
#endif

View File

@@ -1,16 +1,15 @@
//
// Big Vector and Sparse Matrix Classes
//
//
#include <float.h>
#include "vec3n.h"
float conjgrad_lasterror;
float conjgrad_epsilon = 0.1f;
int conjgrad_loopcount;
int conjgrad_looplimit = 100;
int conjgrad_loopcount;
int conjgrad_looplimit = 100;
/*EXPORTVAR(conjgrad_lasterror);
EXPORTVAR(conjgrad_epsilon );
@@ -18,135 +17,131 @@ EXPORTVAR(conjgrad_loopcount);
EXPORTVAR(conjgrad_looplimit);
*/
int ConjGradient(float3N &X, float3Nx3N &A, float3N &B)
int ConjGradient(float3N &X, float3Nx3N &A, float3N &B)
{
// Solves for unknown X in equation AX=B
conjgrad_loopcount=0;
int n=B.count;
float3N q(n),d(n),tmp(n),r(n);
r = B - Mul(tmp,A,X); // just use B if X known to be zero
d = r;
float s = dot(r,r);
float starget = s * squared(conjgrad_epsilon);
while( s>starget && conjgrad_loopcount++ < conjgrad_looplimit)
{
Mul(q,A,d); // q = A*d;
float a = s/dot(d,q);
X = X + d*a;
if(conjgrad_loopcount%50==0)
{
r = B - Mul(tmp,A,X);
}
else
{
r = r - q*a;
}
float s_prev = s;
s = dot(r,r);
d = r+d*(s/s_prev);
}
conjgrad_lasterror = s;
return conjgrad_loopcount<conjgrad_looplimit; // true means we reached desired accuracy in given time - ie stable
// Solves for unknown X in equation AX=B
conjgrad_loopcount = 0;
int n = B.count;
float3N q(n), d(n), tmp(n), r(n);
r = B - Mul(tmp, A, X); // just use B if X known to be zero
d = r;
float s = dot(r, r);
float starget = s * squared(conjgrad_epsilon);
while (s > starget && conjgrad_loopcount++ < conjgrad_looplimit)
{
Mul(q, A, d); // q = A*d;
float a = s / dot(d, q);
X = X + d * a;
if (conjgrad_loopcount % 50 == 0)
{
r = B - Mul(tmp, A, X);
}
else
{
r = r - q * a;
}
float s_prev = s;
s = dot(r, r);
d = r + d * (s / s_prev);
}
conjgrad_lasterror = s;
return conjgrad_loopcount < conjgrad_looplimit; // true means we reached desired accuracy in given time - ie stable
}
int ConjGradientMod(float3N &X, float3Nx3N &A, float3N &B,int3 hack)
int ConjGradientMod(float3N &X, float3Nx3N &A, float3N &B, int3 hack)
{
// obsolete!!!
// Solves for unknown X in equation AX=B
conjgrad_loopcount=0;
int n=B.count;
float3N q(n),d(n),tmp(n),r(n);
r = B - Mul(tmp,A,X); // just use B if X known to be zero
r[hack[0]] = r[hack[1]] = r[hack[2]] = float3(0,0,0);
d = r;
float s = dot(r,r);
float starget = s * squared(conjgrad_epsilon);
while( s>starget && conjgrad_loopcount++ < conjgrad_looplimit)
{
Mul(q,A,d); // q = A*d;
q[hack[0]] = q[hack[1]] = q[hack[2]] = float3(0,0,0);
float a = s/dot(d,q);
X = X + d*a;
if(conjgrad_loopcount%50==0)
{
r = B - Mul(tmp,A,X);
r[hack[0]] = r[hack[1]] = r[hack[2]] = float3(0,0,0);
}
else
{
r = r - q*a;
}
float s_prev = s;
s = dot(r,r);
d = r+d*(s/s_prev);
d[hack[0]] = d[hack[1]] = d[hack[2]] = float3(0,0,0);
}
conjgrad_lasterror = s;
return conjgrad_loopcount<conjgrad_looplimit; // true means we reached desired accuracy in given time - ie stable
// obsolete!!!
// Solves for unknown X in equation AX=B
conjgrad_loopcount = 0;
int n = B.count;
float3N q(n), d(n), tmp(n), r(n);
r = B - Mul(tmp, A, X); // just use B if X known to be zero
r[hack[0]] = r[hack[1]] = r[hack[2]] = float3(0, 0, 0);
d = r;
float s = dot(r, r);
float starget = s * squared(conjgrad_epsilon);
while (s > starget && conjgrad_loopcount++ < conjgrad_looplimit)
{
Mul(q, A, d); // q = A*d;
q[hack[0]] = q[hack[1]] = q[hack[2]] = float3(0, 0, 0);
float a = s / dot(d, q);
X = X + d * a;
if (conjgrad_loopcount % 50 == 0)
{
r = B - Mul(tmp, A, X);
r[hack[0]] = r[hack[1]] = r[hack[2]] = float3(0, 0, 0);
}
else
{
r = r - q * a;
}
float s_prev = s;
s = dot(r, r);
d = r + d * (s / s_prev);
d[hack[0]] = d[hack[1]] = d[hack[2]] = float3(0, 0, 0);
}
conjgrad_lasterror = s;
return conjgrad_loopcount < conjgrad_looplimit; // true means we reached desired accuracy in given time - ie stable
}
static inline void filter(float3N &V,const float3Nx3N &S)
static inline void filter(float3N &V, const float3Nx3N &S)
{
for(int i=0;i<S.blocks.count;i++)
{
V[S.blocks[i].r] = V[S.blocks[i].r]*S.blocks[i].m;
}
for (int i = 0; i < S.blocks.count; i++)
{
V[S.blocks[i].r] = V[S.blocks[i].r] * S.blocks[i].m;
}
}
int ConjGradientFiltered(float3N &X, const float3Nx3N &A, const float3N &B,const float3Nx3N &S)
int ConjGradientFiltered(float3N &X, const float3Nx3N &A, const float3N &B, const float3Nx3N &S)
{
// Solves for unknown X in equation AX=B
conjgrad_loopcount=0;
int n=B.count;
float3N q(n),d(n),tmp(n),r(n);
r = B - Mul(tmp,A,X); // just use B if X known to be zero
filter(r,S);
d = r;
float s = dot(r,r);
float starget = s * squared(conjgrad_epsilon);
while( s>starget && conjgrad_loopcount++ < conjgrad_looplimit)
{
Mul(q,A,d); // q = A*d;
filter(q,S);
float a = s/dot(d,q);
X = X + d*a;
if(conjgrad_loopcount%50==0)
{
r = B - Mul(tmp,A,X);
filter(r,S);
}
else
{
r = r - q*a;
}
float s_prev = s;
s = dot(r,r);
d = r+d*(s/s_prev);
filter(d,S);
}
conjgrad_lasterror = s;
return conjgrad_loopcount<conjgrad_looplimit; // true means we reached desired accuracy in given time - ie stable
// Solves for unknown X in equation AX=B
conjgrad_loopcount = 0;
int n = B.count;
float3N q(n), d(n), tmp(n), r(n);
r = B - Mul(tmp, A, X); // just use B if X known to be zero
filter(r, S);
d = r;
float s = dot(r, r);
float starget = s * squared(conjgrad_epsilon);
while (s > starget && conjgrad_loopcount++ < conjgrad_looplimit)
{
Mul(q, A, d); // q = A*d;
filter(q, S);
float a = s / dot(d, q);
X = X + d * a;
if (conjgrad_loopcount % 50 == 0)
{
r = B - Mul(tmp, A, X);
filter(r, S);
}
else
{
r = r - q * a;
}
float s_prev = s;
s = dot(r, r);
d = r + d * (s / s_prev);
filter(d, S);
}
conjgrad_lasterror = s;
return conjgrad_loopcount < conjgrad_looplimit; // true means we reached desired accuracy in given time - ie stable
}
// test big vector math library:
static void testfloat3N()
{
float3N a(2),b(2),c(2);
a[0] = float3(1,2,3);
a[1] = float3(4,5,6);
b[0] = float3(10,20,30);
b[1] = float3(40,50,60);
// c = a+b+b * 10.0f;
// float d = dot(a+b,-b);
int k;
k=0;
float3N a(2), b(2), c(2);
a[0] = float3(1, 2, 3);
a[1] = float3(4, 5, 6);
b[0] = float3(10, 20, 30);
b[1] = float3(40, 50, 60);
// c = a+b+b * 10.0f;
// float d = dot(a+b,-b);
int k;
k = 0;
}
class dotest{public:dotest(){testfloat3N();}}do_test_at_program_startup;
class dotest
{
public:
dotest() { testfloat3N(); }
} do_test_at_program_startup;

View File

@@ -1,33 +1,33 @@
//
// Big Vector and Sparse Matrix Classes
//
//
// (c) S Melax 2006
//
// The focus is on 3D applications, so
// The focus is on 3D applications, so
// the big vector is an array of float3s
// and the matrix class uses 3x3 blocks.
//
// This file includes both:
// - basic non-optimized version
// - an expression optimized version
// - basic non-optimized version
// - an expression optimized version
//
// Optimized Expressions
//
// We want to write sweet looking code such as V=As+Bt with big vectors.
// However, we dont want the extra overheads with allocating memory for temps and excessing copying.
// Instead of a full Template Metaprogramming approach, we explicitly write
// Instead of a full Template Metaprogramming approach, we explicitly write
// classes to specifically handle all the expressions we are likely to use.
// Most applicable lines of code will be of the same handful of basic forms,
// Most applicable lines of code will be of the same handful of basic forms,
// but with different parameters for the operands.
// In the future, if we ever need a longer expression with more operands,
// In the future, if we ever need a longer expression with more operands,
// then we will just add whatever additional building blocks that are necessary - not a big deal.
// This approach is much simpler to develop, debug and optimize (restrict keyword, simd etc)
// than template metaprogramming is. We do not rely on the implementation
// of a particular compiler to be able to expand extensive nested inline codes.
// Additionally, we reliably get our optimizations even within a debug build.
// Therefore we believe that our Optimized Expressions
// This approach is much simpler to develop, debug and optimize (restrict keyword, simd etc)
// than template metaprogramming is. We do not rely on the implementation
// of a particular compiler to be able to expand extensive nested inline codes.
// Additionally, we reliably get our optimizations even within a debug build.
// Therefore we believe that our Optimized Expressions
// are a good compromise that give us the best of both worlds.
// The code within those important algorithms, which use this library,
// The code within those important algorithms, which use this library,
// can now remain clean and readable yet still execute quickly.
//
@@ -41,111 +41,144 @@
//template <class T> void * vec4<T>::operator new[](size_t n){ return _mm_malloc(n,64); }
//template <class T> void vec4<T>::operator delete[](void *a) { _mm_free(a); }
struct HalfConstraint {
float3 n;int vi;
float s,t;
HalfConstraint(const float3& _n,int _vi,float _t):n(_n),vi(_vi),s(0),t(_t){}
HalfConstraint():vi(-1){}
struct HalfConstraint
{
float3 n;
int vi;
float s, t;
HalfConstraint(const float3 &_n, int _vi, float _t) : n(_n), vi(_vi), s(0), t(_t) {}
HalfConstraint() : vi(-1) {}
};
class float3Nx3N
{
public:
public:
class Block
{
public:
public:
float3x3 m;
int r,c;
int r, c;
float unused[16];
Block(){}
Block(short _r,short _c):r(_r),c(_c){m.x=m.y=m.z=float3(0,0,0);}
Block() {}
Block(short _r, short _c) : r(_r), c(_c) { m.x = m.y = m.z = float3(0, 0, 0); }
};
Array<Block> blocks; // the first n blocks use as the diagonal.
int n;
int n;
void Zero();
void InitDiagonal(float d);
void Identity(){InitDiagonal(1.0f);}
float3Nx3N():n(0){}
float3Nx3N(int _n):n(_n) {for(int i=0;i<n;i++) blocks.Add(Block((short)i,(short)i));}
template<class E> float3Nx3N &operator= (const E& expression) {expression.evalequals(*this);return *this;}
template<class E> float3Nx3N &operator+=(const E& expression) {expression.evalpluseq(*this);return *this;}
template<class E> float3Nx3N &operator-=(const E& expression) {expression.evalmnuseq(*this);return *this;}
void Identity() { InitDiagonal(1.0f); }
float3Nx3N() : n(0) {}
float3Nx3N(int _n) : n(_n)
{
for (int i = 0; i < n; i++) blocks.Add(Block((short)i, (short)i));
}
template <class E>
float3Nx3N &operator=(const E &expression)
{
expression.evalequals(*this);
return *this;
}
template <class E>
float3Nx3N &operator+=(const E &expression)
{
expression.evalpluseq(*this);
return *this;
}
template <class E>
float3Nx3N &operator-=(const E &expression)
{
expression.evalmnuseq(*this);
return *this;
}
};
class float3N: public Array<float3>
class float3N : public Array<float3>
{
public:
float3N(int _count=0)
float3N(int _count = 0)
{
SetSize(_count);
}
void Zero();
void Init(const float3 &v); // sets each subvector to v
template<class E> float3N &operator= (const E& expression) {expression.evalequals(*this);return *this;}
template<class E> float3N &operator+=(const E& expression) {expression.evalpluseq(*this);return *this;}
template<class E> float3N &operator-=(const E& expression) {expression.evalmnuseq(*this);return *this;}
float3N &operator=( const float3N &V) { this->copy(V); return *this;}
template <class E>
float3N &operator=(const E &expression)
{
expression.evalequals(*this);
return *this;
}
template <class E>
float3N &operator+=(const E &expression)
{
expression.evalpluseq(*this);
return *this;
}
template <class E>
float3N &operator-=(const E &expression)
{
expression.evalmnuseq(*this);
return *this;
}
float3N &operator=(const float3N &V)
{
this->copy(V);
return *this;
}
};
int ConjGradient(float3N &X, float3Nx3N &A, float3N &B);
int ConjGradientFiltered(float3N &X, const float3Nx3N &A, const float3N &B,const float3Nx3N &S,Array<HalfConstraint> &H);
int ConjGradientFiltered(float3N &X, const float3Nx3N &A, const float3N &B,const float3Nx3N &S);
int ConjGradient(float3N &X, float3Nx3N &A, float3N &B);
int ConjGradientFiltered(float3N &X, const float3Nx3N &A, const float3N &B, const float3Nx3N &S, Array<HalfConstraint> &H);
int ConjGradientFiltered(float3N &X, const float3Nx3N &A, const float3N &B, const float3Nx3N &S);
inline float3N& Mul(float3N &r,const float3Nx3N &m, const float3N &v)
inline float3N &Mul(float3N &r, const float3Nx3N &m, const float3N &v)
{
int i;
for(i=0;i<r.count;i++) r[i]=float3(0,0,0);
for(i=0;i<m.blocks.count;i++)
for (i = 0; i < r.count; i++) r[i] = float3(0, 0, 0);
for (i = 0; i < m.blocks.count; i++)
{
r[m.blocks[i].r] += m.blocks[i].m * v[m.blocks[i].c];
}
return r;
}
inline float dot(const float3N &a,const float3N &b)
inline float dot(const float3N &a, const float3N &b)
{
float d=0;
for(int i=0;i<a.count;i++)
float d = 0;
for (int i = 0; i < a.count; i++)
{
d+= dot(a[i],b[i]);
d += dot(a[i], b[i]);
}
return d;
}
inline void float3Nx3N::Zero()
{
for(int i=0;i<blocks.count;i++)
for (int i = 0; i < blocks.count; i++)
{
blocks[i].m = float3x3(0,0,0,0,0,0,0,0,0);
blocks[i].m = float3x3(0, 0, 0, 0, 0, 0, 0, 0, 0);
}
}
inline void float3Nx3N::InitDiagonal(float d)
{
for(int i=0;i<blocks.count;i++)
for (int i = 0; i < blocks.count; i++)
{
blocks[i].m = (blocks[i].c==blocks[i].r) ? float3x3(d,0,0,0,d,0,0,0,d) : float3x3(0,0,0,0,0,0,0,0,0);
blocks[i].m = (blocks[i].c == blocks[i].r) ? float3x3(d, 0, 0, 0, d, 0, 0, 0, d) : float3x3(0, 0, 0, 0, 0, 0, 0, 0, 0);
}
}
inline void float3N::Zero()
{
for(int i=0;i<count;i++)
for (int i = 0; i < count; i++)
{
element[i] = float3(0,0,0);
element[i] = float3(0, 0, 0);
}
}
inline void float3N::Init(const float3 &v)
inline void float3N::Init(const float3 &v)
{
for(int i=0;i<count;i++)
for (int i = 0; i < count; i++)
{
element[i] = v;
}
@@ -157,56 +190,55 @@ inline void float3N::Init(const float3 &v)
// Uses typical implmentation for operators +/-*=
// These operators cause lots of unnecessary construction, memory allocation, and copying.
inline float3N operator +(const float3N &a,const float3N &b)
inline float3N operator+(const float3N &a, const float3N &b)
{
float3N r(a.count);
for(int i=0;i<a.count;i++) r[i]=a[i]+b[i];
for (int i = 0; i < a.count; i++) r[i] = a[i] + b[i];
return r;
}
inline float3N operator *(const float3N &a,const float &s)
inline float3N operator*(const float3N &a, const float &s)
{
float3N r(a.count);
for(int i=0;i<a.count;i++) r[i]=a[i]*s;
for (int i = 0; i < a.count; i++) r[i] = a[i] * s;
return r;
}
inline float3N operator /(const float3N &a,const float &s)
inline float3N operator/(const float3N &a, const float &s)
{
float3N r(a.count);
return Mul(r,a, 1.0f/s );
return Mul(r, a, 1.0f / s);
}
inline float3N operator -(const float3N &a,const float3N &b)
inline float3N operator-(const float3N &a, const float3N &b)
{
float3N r(a.count);
for(int i=0;i<a.count;i++) r[i]=a[i]-b[i];
for (int i = 0; i < a.count; i++) r[i] = a[i] - b[i];
return r;
}
inline float3N operator -(const float3N &a)
inline float3N operator-(const float3N &a)
{
float3N r(a.count);
for(int i=0;i<a.count;i++) r[i]=-a[i];
for (int i = 0; i < a.count; i++) r[i] = -a[i];
return r;
}
inline float3N operator *(const float3Nx3N &m,const float3N &v)
inline float3N operator*(const float3Nx3N &m, const float3N &v)
{
float3N r(v.count);
return Mul(r,m,v);
return Mul(r, m, v);
}
inline float3N &operator-=(float3N &A, const float3N &B)
inline float3N &operator-=(float3N &A, const float3N &B)
{
assert(A.count==B.count);
for(int i=0;i<A.count;i++) A[i] -= B[i];
assert(A.count == B.count);
for (int i = 0; i < A.count; i++) A[i] -= B[i];
return A;
}
inline float3N &operator+=(float3N &A, const float3N &B)
inline float3N &operator+=(float3N &A, const float3N &B)
{
assert(A.count==B.count);
for(int i=0;i<A.count;i++) A[i] += B[i];
assert(A.count == B.count);
for (int i = 0; i < A.count; i++) A[i] += B[i];
return A;
}
#else
// Optimized Expressions
@@ -215,10 +247,19 @@ class exVneg
{
public:
const float3N &v;
exVneg(const float3N &_v): v(_v){}
void evalequals(float3N &r)const { for(int i=0;i<v.count;i++) r[i] =-v[i];}
void evalpluseq(float3N &r)const { for(int i=0;i<v.count;i++) r[i]+=-v[i];}
void evalmnuseq(float3N &r)const { for(int i=0;i<v.count;i++) r[i]-=-v[i];}
exVneg(const float3N &_v) : v(_v) {}
void evalequals(float3N &r) const
{
for (int i = 0; i < v.count; i++) r[i] = -v[i];
}
void evalpluseq(float3N &r) const
{
for (int i = 0; i < v.count; i++) r[i] += -v[i];
}
void evalmnuseq(float3N &r) const
{
for (int i = 0; i < v.count; i++) r[i] -= -v[i];
}
};
class exVaddV
@@ -226,10 +267,19 @@ class exVaddV
public:
const float3N &a;
const float3N &b;
exVaddV(const float3N &_a,const float3N &_b): a(_a),b(_b){}
void evalequals(float3N &r)const { for(int i=0;i<a.count;i++) r[i] =a[i]+b[i];}
void evalpluseq(float3N &r)const { for(int i=0;i<a.count;i++) r[i]+=a[i]+b[i];}
void evalmnuseq(float3N &r)const { for(int i=0;i<a.count;i++) r[i]-=a[i]+b[i];}
exVaddV(const float3N &_a, const float3N &_b) : a(_a), b(_b) {}
void evalequals(float3N &r) const
{
for (int i = 0; i < a.count; i++) r[i] = a[i] + b[i];
}
void evalpluseq(float3N &r) const
{
for (int i = 0; i < a.count; i++) r[i] += a[i] + b[i];
}
void evalmnuseq(float3N &r) const
{
for (int i = 0; i < a.count; i++) r[i] -= a[i] + b[i];
}
};
class exVsubV
@@ -237,104 +287,149 @@ class exVsubV
public:
const float3N &a;
const float3N &b;
exVsubV(const float3N &_a,const float3N &_b): a(_a),b(_b){}
void evalequals(float3N &r)const { for(int i=0;i<a.count;i++) r[i] =a[i]-b[i];}
void evalpluseq(float3N &r)const { for(int i=0;i<a.count;i++) r[i]+=a[i]-b[i];}
void evalmnuseq(float3N &r)const { for(int i=0;i<a.count;i++) r[i]-=a[i]-b[i];}
exVsubV(const float3N &_a, const float3N &_b) : a(_a), b(_b) {}
void evalequals(float3N &r) const
{
for (int i = 0; i < a.count; i++) r[i] = a[i] - b[i];
}
void evalpluseq(float3N &r) const
{
for (int i = 0; i < a.count; i++) r[i] += a[i] - b[i];
}
void evalmnuseq(float3N &r) const
{
for (int i = 0; i < a.count; i++) r[i] -= a[i] - b[i];
}
};
class exVs
{
public:
const float3N &v;
const float s;
exVs(const float3N &_v,const float &_s): v(_v),s(_s){}
void evalequals(float3N &r)const { for(int i=0;i<v.count;i++) r[i] =v[i]*s;}
void evalpluseq(float3N &r)const { for(int i=0;i<v.count;i++) r[i]+=v[i]*s;}
void evalmnuseq(float3N &r)const { for(int i=0;i<v.count;i++) r[i]-=v[i]*s;}
const float s;
exVs(const float3N &_v, const float &_s) : v(_v), s(_s) {}
void evalequals(float3N &r) const
{
for (int i = 0; i < v.count; i++) r[i] = v[i] * s;
}
void evalpluseq(float3N &r) const
{
for (int i = 0; i < v.count; i++) r[i] += v[i] * s;
}
void evalmnuseq(float3N &r) const
{
for (int i = 0; i < v.count; i++) r[i] -= v[i] * s;
}
};
class exAsaddB
{
public:
const float3N &a;
const float3N &b;
const float s;
exAsaddB(const float3N &_a,const float &_s,const float3N &_b): a(_a),s(_s),b(_b){}
void evalequals(float3N &r)const { for(int i=0;i<a.count;i++) r[i] =a[i]*s+b[i];}
void evalpluseq(float3N &r)const { for(int i=0;i<a.count;i++) r[i]+=a[i]*s+b[i];}
void evalmnuseq(float3N &r)const { for(int i=0;i<a.count;i++) r[i]-=a[i]*s+b[i];}
const float s;
exAsaddB(const float3N &_a, const float &_s, const float3N &_b) : a(_a), s(_s), b(_b) {}
void evalequals(float3N &r) const
{
for (int i = 0; i < a.count; i++) r[i] = a[i] * s + b[i];
}
void evalpluseq(float3N &r) const
{
for (int i = 0; i < a.count; i++) r[i] += a[i] * s + b[i];
}
void evalmnuseq(float3N &r) const
{
for (int i = 0; i < a.count; i++) r[i] -= a[i] * s + b[i];
}
};
class exAsaddBt
{
public:
const float3N &a;
const float3N &b;
const float s;
const float t;
exAsaddBt(const float3N &_a,const float &_s,const float3N &_b,const float &_t): a(_a),s(_s),b(_b),t(_t){}
void evalequals(float3N &r)const { for(int i=0;i<a.count;i++) r[i] =a[i]*s+b[i]*t;}
void evalpluseq(float3N &r)const { for(int i=0;i<a.count;i++) r[i]+=a[i]*s+b[i]*t;}
void evalmnuseq(float3N &r)const { for(int i=0;i<a.count;i++) r[i]-=a[i]*s+b[i]*t;}
const float s;
const float t;
exAsaddBt(const float3N &_a, const float &_s, const float3N &_b, const float &_t) : a(_a), s(_s), b(_b), t(_t) {}
void evalequals(float3N &r) const
{
for (int i = 0; i < a.count; i++) r[i] = a[i] * s + b[i] * t;
}
void evalpluseq(float3N &r) const
{
for (int i = 0; i < a.count; i++) r[i] += a[i] * s + b[i] * t;
}
void evalmnuseq(float3N &r) const
{
for (int i = 0; i < a.count; i++) r[i] -= a[i] * s + b[i] * t;
}
};
class exMv
{
public:
const float3Nx3N &m;
const float3N &v;
exMv(const float3Nx3N &_m,const float3N &_v): m(_m),v(_v){}
void evalequals(float3N &r)const { Mul(r,m,v);}
const float3N &v;
exMv(const float3Nx3N &_m, const float3N &_v) : m(_m), v(_v) {}
void evalequals(float3N &r) const { Mul(r, m, v); }
};
class exMs
{
public:
const float3Nx3N &m;
const float s;
exMs(const float3Nx3N &_m,const float &_s): m(_m),s(_s){}
void evalequals(float3Nx3N &r)const { for(int i=0;i<r.blocks.count;i++) r.blocks[i].m = m.blocks[i].m*s;}
void evalpluseq(float3Nx3N &r)const { for(int i=0;i<r.blocks.count;i++) r.blocks[i].m += m.blocks[i].m*s;}
void evalmnuseq(float3Nx3N &r)const { for(int i=0;i<r.blocks.count;i++) r.blocks[i].m -= m.blocks[i].m*s;}
const float s;
exMs(const float3Nx3N &_m, const float &_s) : m(_m), s(_s) {}
void evalequals(float3Nx3N &r) const
{
for (int i = 0; i < r.blocks.count; i++) r.blocks[i].m = m.blocks[i].m * s;
}
void evalpluseq(float3Nx3N &r) const
{
for (int i = 0; i < r.blocks.count; i++) r.blocks[i].m += m.blocks[i].m * s;
}
void evalmnuseq(float3Nx3N &r) const
{
for (int i = 0; i < r.blocks.count; i++) r.blocks[i].m -= m.blocks[i].m * s;
}
};
class exMAsMBt
{
public:
const float3Nx3N &a;
const float s;
const float s;
const float3Nx3N &b;
const float t;
exMAsMBt(const float3Nx3N &_a,const float &_s,const float3Nx3N &_b,const float &_t): a(_a),s(_s),b(_b),t(_t){}
void evalequals(float3Nx3N &r)const { for(int i=0;i<r.blocks.count;i++) r.blocks[i].m = a.blocks[i].m*s + b.blocks[i].m*t;}
void evalpluseq(float3Nx3N &r)const { for(int i=0;i<r.blocks.count;i++) r.blocks[i].m += a.blocks[i].m*s + b.blocks[i].m*t;}
void evalmnuseq(float3Nx3N &r)const { for(int i=0;i<r.blocks.count;i++) r.blocks[i].m -= a.blocks[i].m*s + b.blocks[i].m*t;}
const float t;
exMAsMBt(const float3Nx3N &_a, const float &_s, const float3Nx3N &_b, const float &_t) : a(_a), s(_s), b(_b), t(_t) {}
void evalequals(float3Nx3N &r) const
{
for (int i = 0; i < r.blocks.count; i++) r.blocks[i].m = a.blocks[i].m * s + b.blocks[i].m * t;
}
void evalpluseq(float3Nx3N &r) const
{
for (int i = 0; i < r.blocks.count; i++) r.blocks[i].m += a.blocks[i].m * s + b.blocks[i].m * t;
}
void evalmnuseq(float3Nx3N &r) const
{
for (int i = 0; i < r.blocks.count; i++) r.blocks[i].m -= a.blocks[i].m * s + b.blocks[i].m * t;
}
};
inline exVaddV operator +(const float3N &a,const float3N &b) {return exVaddV(a,b);}
inline exVsubV operator +(const exVneg &E,const float3N &b) {return exVsubV(b,E.v);}
inline exVsubV operator -(const float3N &a,const float3N &b) {return exVsubV(a,b);}
inline exVs operator *(const float3N &V,const float &s) {return exVs(V,s); }
inline exVs operator *(const exVs &E,const float &s) {return exVs(E.v,E.s*s); }
inline exAsaddB operator +(const exVs &E,const float3N &b) {return exAsaddB(E.v, E.s,b);}
inline exAsaddB operator +(const float3N &b,const exVs &E) {return exAsaddB(E.v, E.s,b);}
inline exAsaddB operator -(const float3N &b,const exVs &E) {return exAsaddB(E.v,-E.s,b);}
inline exAsaddBt operator +(const exVs &Ea,const exVs &Eb) {return exAsaddBt(Ea.v,Ea.s,Eb.v, Eb.s);}
inline exAsaddBt operator -(const exVs &Ea,const exVs &Eb) {return exAsaddBt(Ea.v,Ea.s,Eb.v,-Eb.s);}
inline exMv operator *(const float3Nx3N &m,const float3N &v) {return exMv(m,v); }
inline exMs operator *(const exMs &E,const float &s) {return exMs(E.m,E.s*s); }
inline exMs operator *(const float3Nx3N &m,const float &s) {return exMs(m,s); }
inline exMAsMBt operator +(const exMs &Ea,const exMs &Eb) {return exMAsMBt(Ea.m,Ea.s, Eb.m,Eb.s);}
inline exMAsMBt operator -(const exMs &Ea,const exMs &Eb) {return exMAsMBt(Ea.m,Ea.s, Eb.m,-Eb.s);}
inline exVaddV operator+(const float3N &a, const float3N &b) { return exVaddV(a, b); }
inline exVsubV operator+(const exVneg &E, const float3N &b) { return exVsubV(b, E.v); }
inline exVsubV operator-(const float3N &a, const float3N &b) { return exVsubV(a, b); }
inline exVs operator*(const float3N &V, const float &s) { return exVs(V, s); }
inline exVs operator*(const exVs &E, const float &s) { return exVs(E.v, E.s * s); }
inline exAsaddB operator+(const exVs &E, const float3N &b) { return exAsaddB(E.v, E.s, b); }
inline exAsaddB operator+(const float3N &b, const exVs &E) { return exAsaddB(E.v, E.s, b); }
inline exAsaddB operator-(const float3N &b, const exVs &E) { return exAsaddB(E.v, -E.s, b); }
inline exAsaddBt operator+(const exVs &Ea, const exVs &Eb) { return exAsaddBt(Ea.v, Ea.s, Eb.v, Eb.s); }
inline exAsaddBt operator-(const exVs &Ea, const exVs &Eb) { return exAsaddBt(Ea.v, Ea.s, Eb.v, -Eb.s); }
inline exMv operator*(const float3Nx3N &m, const float3N &v) { return exMv(m, v); }
inline exMs operator*(const exMs &E, const float &s) { return exMs(E.m, E.s * s); }
inline exMs operator*(const float3Nx3N &m, const float &s) { return exMs(m, s); }
inline exMAsMBt operator+(const exMs &Ea, const exMs &Eb) { return exMAsMBt(Ea.m, Ea.s, Eb.m, Eb.s); }
inline exMAsMBt operator-(const exMs &Ea, const exMs &Eb) { return exMAsMBt(Ea.m, Ea.s, Eb.m, -Eb.s); }
#endif
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -13,23 +13,21 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#include "Bridge.h"
#include "btBulletDynamicsCommon.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "../CommonInterfaces/CommonRigidBodyBase.h"
const int TOTAL_PLANKS = 10;
struct BridgeExample : public CommonRigidBodyBase
{
BridgeExample(struct GUIHelperInterface* helper)
:CommonRigidBodyBase(helper)
: CommonRigidBodyBase(helper)
{
}
virtual ~BridgeExample(){}
virtual ~BridgeExample() {}
virtual void initPhysics();
virtual void renderScene();
void resetCamera()
@@ -37,8 +35,8 @@ struct BridgeExample : public CommonRigidBodyBase
float dist = 41;
float pitch = -35;
float yaw = 52;
float targetPos[3]={0,0.46,0};
m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]);
float targetPos[3] = {0, 0.46, 0};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
};
@@ -47,81 +45,78 @@ void BridgeExample::initPhysics()
m_guiHelper->setUpAxis(1);
createEmptyDynamicsWorld();
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
if (m_dynamicsWorld->getDebugDrawer())
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints);
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints);
///create a few basic rigid bodies
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0,-50,0));
groundTransform.setOrigin(btVector3(0, -50, 0));
{
btScalar mass(0.);
createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1));
createRigidBody(mass, groundTransform, groundShape, btVector4(0, 0, 1, 1));
}
//create two fixed boxes to hold the planks
{
//create a few dynamic rigidbodies
// Re-using the same collision is better for memory usage and performance
btScalar plankWidth = 0.4;
btScalar plankHeight = 0.2;
btScalar plankBreadth = 1;
btScalar plankOffset = plankWidth; //distance between two planks
btScalar bridgeWidth = plankWidth*TOTAL_PLANKS + plankOffset*(TOTAL_PLANKS-1);
btScalar plankOffset = plankWidth; //distance between two planks
btScalar bridgeWidth = plankWidth * TOTAL_PLANKS + plankOffset * (TOTAL_PLANKS - 1);
btScalar bridgeHeight = 5;
btScalar halfBridgeWidth = bridgeWidth*0.5f;
btScalar halfBridgeWidth = bridgeWidth * 0.5f;
btBoxShape* colShape = createBoxShape(btVector3(plankWidth, plankHeight, plankBreadth));
btBoxShape* colShape = createBoxShape(btVector3(plankWidth,plankHeight,plankBreadth));
m_collisionShapes.push_back(colShape);
/// Create Dynamic Objects
btTransform startTransform;
startTransform.setIdentity();
btScalar mass(1.f);
btScalar mass(1.f);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0,0,0);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
colShape->calculateLocalInertia(mass,localInertia);
colShape->calculateLocalInertia(mass, localInertia);
//create a set of boxes to represent bridge
//create a set of boxes to represent bridge
btAlignedObjectArray<btRigidBody*> boxes;
int lastBoxIndex = TOTAL_PLANKS-1;
for(int i=0;i<TOTAL_PLANKS;++i) {
float t = float(i)/lastBoxIndex;
t = -(t*2-1.0f) * halfBridgeWidth;
startTransform.setOrigin(btVector3(
btScalar(t),
bridgeHeight,
btScalar(0)
)
);
boxes.push_back(createRigidBody((i==0 || i==lastBoxIndex)?0:mass,startTransform,colShape));
}
int lastBoxIndex = TOTAL_PLANKS - 1;
for (int i = 0; i < TOTAL_PLANKS; ++i)
{
float t = float(i) / lastBoxIndex;
t = -(t * 2 - 1.0f) * halfBridgeWidth;
startTransform.setOrigin(btVector3(
btScalar(t),
bridgeHeight,
btScalar(0)));
boxes.push_back(createRigidBody((i == 0 || i == lastBoxIndex) ? 0 : mass, startTransform, colShape));
}
//add N-1 spring constraints
for(int i=0;i<TOTAL_PLANKS-1;++i) {
for (int i = 0; i < TOTAL_PLANKS - 1; ++i)
{
btRigidBody* b1 = boxes[i];
btRigidBody* b2 = boxes[i+1];
btPoint2PointConstraint* leftSpring = new btPoint2PointConstraint(*b1, *b2, btVector3(-0.5,0,-0.5), btVector3(0.5,0,-0.5));
btRigidBody* b2 = boxes[i + 1];
btPoint2PointConstraint* leftSpring = new btPoint2PointConstraint(*b1, *b2, btVector3(-0.5, 0, -0.5), btVector3(0.5, 0, -0.5));
m_dynamicsWorld->addConstraint(leftSpring);
btPoint2PointConstraint* rightSpring = new btPoint2PointConstraint(*b1, *b2, btVector3(-0.5,0,0.5), btVector3(0.5,0,0.5));
btPoint2PointConstraint* rightSpring = new btPoint2PointConstraint(*b1, *b2, btVector3(-0.5, 0, 0.5), btVector3(0.5, 0, 0.5));
m_dynamicsWorld->addConstraint(rightSpring);
}
}
@@ -129,22 +124,12 @@ void BridgeExample::initPhysics()
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void BridgeExample::renderScene()
{
CommonRigidBodyBase::renderScene();
CommonRigidBodyBase::renderScene();
}
CommonExampleInterface* ET_BridgeCreateFunc(CommonExampleOptions& options)
CommonExampleInterface* ET_BridgeCreateFunc(CommonExampleOptions& options)
{
return new BridgeExample(options.m_guiHelper);
}

View File

@@ -16,7 +16,6 @@ subject to the following restrictions:
#ifndef ET_BRIDGE_EXAMPLE_H
#define ET_BRIDGE_EXAMPLE_H
class CommonExampleInterface* ET_BridgeCreateFunc(struct CommonExampleOptions& options);
class CommonExampleInterface* ET_BridgeCreateFunc(struct CommonExampleOptions& options);
#endif //ET_BRIDGE_EXAMPLE_H
#endif //ET_BRIDGE_EXAMPLE_H

View File

@@ -13,23 +13,21 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#include "Chain.h"
#include "btBulletDynamicsCommon.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "../CommonInterfaces/CommonRigidBodyBase.h"
const int TOTAL_BOXES = 10;
struct ChainExample : public CommonRigidBodyBase
{
ChainExample(struct GUIHelperInterface* helper)
:CommonRigidBodyBase(helper)
: CommonRigidBodyBase(helper)
{
}
virtual ~ChainExample(){}
virtual ~ChainExample() {}
virtual void initPhysics();
virtual void renderScene();
void resetCamera()
@@ -37,8 +35,8 @@ struct ChainExample : public CommonRigidBodyBase
float dist = 41;
float pitch = -35;
float yaw = 52;
float targetPos[3]={0,0.46,0};
m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]);
float targetPos[3] = {0, 0.46, 0};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
};
@@ -47,67 +45,66 @@ void ChainExample::initPhysics()
m_guiHelper->setUpAxis(1);
createEmptyDynamicsWorld();
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
if (m_dynamicsWorld->getDebugDrawer())
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints);
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints);
///create a few basic rigid bodies
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0,-50,0));
groundTransform.setOrigin(btVector3(0, -50, 0));
{
btScalar mass(0.);
createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1));
createRigidBody(mass, groundTransform, groundShape, btVector4(0, 0, 1, 1));
}
{
//create a few dynamic rigidbodies
// Re-using the same collision is better for memory usage and performance
btBoxShape* colShape = createBoxShape(btVector3(1,1,0.25));
btBoxShape* colShape = createBoxShape(btVector3(1, 1, 0.25));
m_collisionShapes.push_back(colShape);
/// Create Dynamic Objects
btTransform startTransform;
startTransform.setIdentity();
btScalar mass(1.f);
btScalar mass(1.f);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0,0,0);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
colShape->calculateLocalInertia(mass,localInertia);
colShape->calculateLocalInertia(mass, localInertia);
btAlignedObjectArray<btRigidBody*> boxes;
int lastBoxIndex = TOTAL_BOXES-1;
for(int i=0;i<TOTAL_BOXES;++i) {
int lastBoxIndex = TOTAL_BOXES - 1;
for (int i = 0; i < TOTAL_BOXES; ++i)
{
startTransform.setOrigin(btVector3(
btScalar(0),
btScalar(5+i*2),
btScalar(0)
)
);
boxes.push_back(createRigidBody((i==lastBoxIndex)?0:mass,startTransform,colShape));
}
btScalar(0),
btScalar(5 + i * 2),
btScalar(0)));
boxes.push_back(createRigidBody((i == lastBoxIndex) ? 0 : mass, startTransform, colShape));
}
//add N-1 spring constraints
for(int i=0;i<TOTAL_BOXES-1;++i) {
for (int i = 0; i < TOTAL_BOXES - 1; ++i)
{
btRigidBody* b1 = boxes[i];
btRigidBody* b2 = boxes[i+1];
btPoint2PointConstraint* leftSpring = new btPoint2PointConstraint(*b1, *b2, btVector3(-0.5,1,0), btVector3(-0.5,-1,0));
btRigidBody* b2 = boxes[i + 1];
btPoint2PointConstraint* leftSpring = new btPoint2PointConstraint(*b1, *b2, btVector3(-0.5, 1, 0), btVector3(-0.5, -1, 0));
m_dynamicsWorld->addConstraint(leftSpring);
btPoint2PointConstraint* rightSpring = new btPoint2PointConstraint(*b1, *b2, btVector3(0.5,1,0), btVector3(0.5,-1,0));
btPoint2PointConstraint* rightSpring = new btPoint2PointConstraint(*b1, *b2, btVector3(0.5, 1, 0), btVector3(0.5, -1, 0));
m_dynamicsWorld->addConstraint(rightSpring);
}
@@ -116,22 +113,12 @@ void ChainExample::initPhysics()
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void ChainExample::renderScene()
{
CommonRigidBodyBase::renderScene();
CommonRigidBodyBase::renderScene();
}
CommonExampleInterface* ET_ChainCreateFunc(CommonExampleOptions& options)
CommonExampleInterface* ET_ChainCreateFunc(CommonExampleOptions& options)
{
return new ChainExample(options.m_guiHelper);
}

View File

@@ -16,7 +16,6 @@ subject to the following restrictions:
#ifndef ET_CHAIN_EXAMPLE_H
#define ET_CHAIN_EXAMPLE_H
class CommonExampleInterface* ET_ChainCreateFunc(struct CommonExampleOptions& options);
class CommonExampleInterface* ET_ChainCreateFunc(struct CommonExampleOptions& options);
#endif //ET_CHAIN_EXAMPLE_H
#endif //ET_CHAIN_EXAMPLE_H

View File

@@ -13,23 +13,20 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#include "CompoundBoxes.h"
#include "btBulletDynamicsCommon.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "../CommonInterfaces/CommonRigidBodyBase.h"
struct CompoundBoxesExample : public CommonRigidBodyBase
{
CompoundBoxesExample(struct GUIHelperInterface* helper)
:CommonRigidBodyBase(helper)
: CommonRigidBodyBase(helper)
{
}
virtual ~CompoundBoxesExample(){}
virtual ~CompoundBoxesExample() {}
virtual void initPhysics();
virtual void renderScene();
void resetCamera()
@@ -37,8 +34,8 @@ struct CompoundBoxesExample : public CommonRigidBodyBase
float dist = 41;
float pitch = -35;
float yaw = 52;
float targetPos[3]={0,0.46,0};
m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]);
float targetPos[3] = {0, 0.46, 0};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
};
@@ -47,36 +44,35 @@ void CompoundBoxesExample::initPhysics()
m_guiHelper->setUpAxis(1);
createEmptyDynamicsWorld();
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
if (m_dynamicsWorld->getDebugDrawer())
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints);
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints);
///create a few basic rigid bodies
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0,-50,0));
groundTransform.setOrigin(btVector3(0, -50, 0));
{
btScalar mass(0.);
createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1));
createRigidBody(mass, groundTransform, groundShape, btVector4(0, 0, 1, 1));
}
{
//create a few dynamic rigidbodies
// Re-using the same collision is better for memory usage and performance
btBoxShape* cube = createBoxShape(btVector3(0.5,0.5,0.5));
btBoxShape* cube = createBoxShape(btVector3(0.5, 0.5, 0.5));
m_collisionShapes.push_back(cube);
// create a new compound shape for making an L-beam from `cube`s
btCompoundShape* compoundShape = new btCompoundShape();
btTransform transform;
// add cubes in an L-beam fashion to the compound shape
transform.setIdentity();
transform.setOrigin(btVector3(0, 0, 0));
@@ -90,8 +86,7 @@ void CompoundBoxesExample::initPhysics()
transform.setOrigin(btVector3(0, 0, 1));
compoundShape->addChildShape(transform, cube);
btScalar masses[3]={1, 1, 1};
btScalar masses[3] = {1, 1, 1};
btTransform principal;
btVector3 inertia;
compoundShape->calculatePrincipalAxisTransform(masses, principal, inertia);
@@ -103,9 +98,9 @@ void CompoundBoxesExample::initPhysics()
// less efficient way to add the entire compund shape
// to a new compund shape as a child
compound2->addChildShape(principal.inverse(), compoundShape);
#else
#else
// recompute the shift to make sure the compound shape is re-aligned
for (int i=0; i < compoundShape->getNumChildShapes(); i++)
for (int i = 0; i < compoundShape->getNumChildShapes(); i++)
compound2->addChildShape(compoundShape->getChildTransform(i) * principal.inverse(),
compoundShape->getChildShape(i));
#endif
@@ -113,23 +108,18 @@ void CompoundBoxesExample::initPhysics()
transform.setIdentity();
transform.setOrigin(btVector3(0, 10, 0));
createRigidBody(1.0, transform, compound2);
createRigidBody(1.0, transform, compound2);
}
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void CompoundBoxesExample::renderScene()
{
CommonRigidBodyBase::renderScene();
CommonRigidBodyBase::renderScene();
}
CommonExampleInterface* ET_CompoundBoxesCreateFunc(CommonExampleOptions& options)
CommonExampleInterface* ET_CompoundBoxesCreateFunc(CommonExampleOptions& options)
{
return new CompoundBoxesExample(options.m_guiHelper);
}

View File

@@ -16,7 +16,6 @@ subject to the following restrictions:
#ifndef ET_COMPOUND_BOXES_EXAMPLE_H
#define ET_COMPOUND_BOXES_EXAMPLE_H
class CommonExampleInterface* ET_CompoundBoxesCreateFunc(struct CommonExampleOptions& options);
class CommonExampleInterface* ET_CompoundBoxesCreateFunc(struct CommonExampleOptions& options);
#endif //ET_COMPOUND_BOXES_EXAMPLE_H
#endif //ET_COMPOUND_BOXES_EXAMPLE_H

View File

@@ -13,34 +13,30 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#include "InclinedPlane.h"
#include "btBulletDynamicsCommon.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "../CommonInterfaces/CommonRigidBodyBase.h"
#include "../CommonInterfaces/CommonParameterInterface.h"
static btScalar gTilt = 20.0f/180.0f*SIMD_PI; // tilt the ramp 20 degrees
static btScalar gTilt = 20.0f / 180.0f * SIMD_PI; // tilt the ramp 20 degrees
static btScalar gRampFriction = 1; // set ramp friction to 1
static btScalar gRampFriction = 1; // set ramp friction to 1
static btScalar gRampRestitution = 0; // set ramp restitution to 0 (no restitution)
static btScalar gRampRestitution = 0; // set ramp restitution to 0 (no restitution)
static btScalar gBoxFriction = 1; // set box friction to 1
static btScalar gBoxFriction = 1; // set box friction to 1
static btScalar gBoxRestitution = 0; // set box restitution to 0
static btScalar gBoxRestitution = 0; // set box restitution to 0
static btScalar gSphereFriction = 1; // set sphere friction to 1
static btScalar gSphereFriction = 1; // set sphere friction to 1
static btScalar gSphereRollingFriction = 1; // set sphere rolling friction to 1
static btScalar gSphereSpinningFriction = 0.3; // set sphere spinning friction to 0.3
static btScalar gSphereRollingFriction = 1; // set sphere rolling friction to 1
static btScalar gSphereSpinningFriction = 0.3; // set sphere spinning friction to 0.3
static btScalar gSphereRestitution = 0; // set sphere restitution to 0
static btScalar gSphereRestitution = 0; // set sphere restitution to 0
// handles for changes
static btRigidBody* ramp = NULL;
@@ -50,10 +46,10 @@ static btRigidBody* gSphere = NULL;
struct InclinedPlaneExample : public CommonRigidBodyBase
{
InclinedPlaneExample(struct GUIHelperInterface* helper)
:CommonRigidBodyBase(helper)
: CommonRigidBodyBase(helper)
{
}
virtual ~InclinedPlaneExample(){}
virtual ~InclinedPlaneExample() {}
virtual void initPhysics();
virtual void resetScene();
virtual void renderScene();
@@ -64,12 +60,9 @@ struct InclinedPlaneExample : public CommonRigidBodyBase
float dist = 41;
float pitch = -35;
float yaw = 52;
float targetPos[3]={0,0.46,0};
m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]);
float targetPos[3] = {0, 0.46, 0};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
};
void onBoxFrictionChanged(float friction, void* userPtr);
@@ -88,112 +81,109 @@ void onRampRestitutionChanged(float restitution, void* userPtr);
void InclinedPlaneExample::initPhysics()
{
{ // create slider to change the ramp tilt
SliderParams slider("Ramp Tilt", &gTilt);
slider.m_minVal = 0;
slider.m_maxVal = SIMD_PI / 2.0f;
slider.m_clampToNotches = false;
slider.m_callback = onRampInclinationChanged;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{ // create slider to change the ramp tilt
SliderParams slider("Ramp Tilt",&gTilt);
slider.m_minVal=0;
slider.m_maxVal=SIMD_PI/2.0f;
slider.m_clampToNotches = false;
slider.m_callback = onRampInclinationChanged;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{ // create slider to change the ramp friction
SliderParams slider("Ramp Friction", &gRampFriction);
slider.m_minVal = 0;
slider.m_maxVal = 10;
slider.m_clampToNotches = false;
slider.m_callback = onRampFrictionChanged;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{ // create slider to change the ramp friction
SliderParams slider("Ramp Friction",&gRampFriction);
slider.m_minVal=0;
slider.m_maxVal=10;
slider.m_clampToNotches = false;
slider.m_callback = onRampFrictionChanged;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{ // create slider to change the ramp restitution
SliderParams slider("Ramp Restitution", &gRampRestitution);
slider.m_minVal = 0;
slider.m_maxVal = 1;
slider.m_clampToNotches = false;
slider.m_callback = onRampRestitutionChanged;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{ // create slider to change the ramp restitution
SliderParams slider("Ramp Restitution",&gRampRestitution);
slider.m_minVal=0;
slider.m_maxVal=1;
slider.m_clampToNotches = false;
slider.m_callback = onRampRestitutionChanged;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{ // create slider to change the box friction
SliderParams slider("Box Friction", &gBoxFriction);
slider.m_minVal = 0;
slider.m_maxVal = 10;
slider.m_clampToNotches = false;
slider.m_callback = onBoxFrictionChanged;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{ // create slider to change the box friction
SliderParams slider("Box Friction",&gBoxFriction);
slider.m_minVal=0;
slider.m_maxVal=10;
slider.m_clampToNotches = false;
slider.m_callback = onBoxFrictionChanged;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{ // create slider to change the box restitution
SliderParams slider("Box Restitution", &gBoxRestitution);
slider.m_minVal = 0;
slider.m_maxVal = 1;
slider.m_clampToNotches = false;
slider.m_callback = onBoxRestitutionChanged;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{ // create slider to change the box restitution
SliderParams slider("Box Restitution",&gBoxRestitution);
slider.m_minVal=0;
slider.m_maxVal=1;
slider.m_clampToNotches = false;
slider.m_callback = onBoxRestitutionChanged;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{ // create slider to change the sphere friction
SliderParams slider("Sphere Friction", &gSphereFriction);
slider.m_minVal = 0;
slider.m_maxVal = 10;
slider.m_clampToNotches = false;
slider.m_callback = onSphereFrictionChanged;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{ // create slider to change the sphere friction
SliderParams slider("Sphere Friction",&gSphereFriction);
slider.m_minVal=0;
slider.m_maxVal=10;
slider.m_clampToNotches = false;
slider.m_callback = onSphereFrictionChanged;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{ // create slider to change the sphere rolling friction
SliderParams slider("Sphere Rolling Friction", &gSphereRollingFriction);
slider.m_minVal = 0;
slider.m_maxVal = 10;
slider.m_clampToNotches = false;
slider.m_callback = onSphereRestitutionChanged;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{ // create slider to change the sphere rolling friction
SliderParams slider("Sphere Rolling Friction",&gSphereRollingFriction);
slider.m_minVal=0;
slider.m_maxVal=10;
slider.m_clampToNotches = false;
slider.m_callback = onSphereRestitutionChanged;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{ // create slider to change the sphere rolling friction
SliderParams slider("Sphere Spinning", &gSphereSpinningFriction);
slider.m_minVal = 0;
slider.m_maxVal = 2;
slider.m_clampToNotches = false;
slider.m_callback = onSphereRestitutionChanged;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{ // create slider to change the sphere rolling friction
SliderParams slider("Sphere Spinning",&gSphereSpinningFriction);
slider.m_minVal=0;
slider.m_maxVal=2;
slider.m_clampToNotches = false;
slider.m_callback = onSphereRestitutionChanged;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{ // create slider to change the sphere restitution
SliderParams slider("Sphere Restitution", &gSphereRestitution);
slider.m_minVal = 0;
slider.m_maxVal = 1;
slider.m_clampToNotches = false;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{ // create slider to change the sphere restitution
SliderParams slider("Sphere Restitution",&gSphereRestitution);
slider.m_minVal=0;
slider.m_maxVal=1;
slider.m_clampToNotches = false;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
m_guiHelper->setUpAxis(1); // set Y axis as up axis
m_guiHelper->setUpAxis(1); // set Y axis as up axis
createEmptyDynamicsWorld();
// create debug drawer
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
if (m_dynamicsWorld->getDebugDrawer())
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints);
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints);
{ // create a static ground
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));
{ // create a static ground
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0,-50,0));
groundTransform.setOrigin(btVector3(0, -50, 0));
btScalar mass(0.);
createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1));
createRigidBody(mass, groundTransform, groundShape, btVector4(0, 0, 1, 1));
}
{ //create a static inclined plane
btBoxShape* inclinedPlaneShape = createBoxShape(btVector3(btScalar(20.),btScalar(1.),btScalar(10.)));
{ //create a static inclined plane
btBoxShape* inclinedPlaneShape = createBoxShape(btVector3(btScalar(20.), btScalar(1.), btScalar(10.)));
m_collisionShapes.push_back(inclinedPlaneShape);
btTransform startTransform;
@@ -201,24 +191,23 @@ void InclinedPlaneExample::initPhysics()
// position the inclined plane above ground
startTransform.setOrigin(btVector3(
btScalar(0),
btScalar(15),
btScalar(0)));
btScalar(0),
btScalar(15),
btScalar(0)));
btQuaternion incline;
incline.setRotation(btVector3(0,0,1),gTilt);
incline.setRotation(btVector3(0, 0, 1), gTilt);
startTransform.setRotation(incline);
btScalar mass(0.);
ramp = createRigidBody(mass,startTransform,inclinedPlaneShape);
ramp = createRigidBody(mass, startTransform, inclinedPlaneShape);
ramp->setFriction(gRampFriction);
ramp->setRestitution(gRampRestitution);
}
{ //create a cube above the inclined plane
btBoxShape* boxShape = createBoxShape(btVector3(1, 1, 1));
{ //create a cube above the inclined plane
btBoxShape* boxShape = createBoxShape(btVector3(1,1,1));
m_collisionShapes.push_back(boxShape);
btTransform startTransform;
@@ -230,13 +219,13 @@ void InclinedPlaneExample::initPhysics()
btVector3(btScalar(0), btScalar(20), btScalar(2)));
gBox = createRigidBody(boxMass, startTransform, boxShape);
gBox->forceActivationState(DISABLE_DEACTIVATION); // to prevent the box on the ramp from disabling
gBox->forceActivationState(DISABLE_DEACTIVATION); // to prevent the box on the ramp from disabling
gBox->setFriction(gBoxFriction);
gBox->setRestitution(gBoxRestitution);
}
{ //create a sphere above the inclined plane
btSphereShape* sphereShape = new btSphereShape(btScalar(1));
{ //create a sphere above the inclined plane
btSphereShape* sphereShape = new btSphereShape(btScalar(1));
m_collisionShapes.push_back(sphereShape);
@@ -249,19 +238,19 @@ void InclinedPlaneExample::initPhysics()
btVector3(btScalar(0), btScalar(20), btScalar(4)));
gSphere = createRigidBody(sphereMass, startTransform, sphereShape);
gSphere->forceActivationState(DISABLE_DEACTIVATION); // to prevent the sphere on the ramp from disabling
gSphere->forceActivationState(DISABLE_DEACTIVATION); // to prevent the sphere on the ramp from disabling
gSphere->setFriction(gSphereFriction);
gSphere->setRestitution(gSphereRestitution);
gSphere->setRollingFriction(gSphereRollingFriction);
gSphere->setSpinningFriction(gSphereSpinningFriction);
}
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void InclinedPlaneExample::resetScene() {
{ //reset a cube above the inclined plane
void InclinedPlaneExample::resetScene()
{
{ //reset a cube above the inclined plane
btTransform startTransform;
startTransform.setIdentity();
@@ -276,7 +265,7 @@ void InclinedPlaneExample::resetScene() {
gBox->clearForces();
}
{ //reset a sphere above the inclined plane
{ //reset a sphere above the inclined plane
btTransform startTransform;
startTransform.setIdentity();
@@ -297,60 +286,70 @@ void InclinedPlaneExample::stepSimulation(float deltaTime)
{
m_dynamicsWorld->stepSimulation(deltaTime);
}
}
void InclinedPlaneExample::renderScene()
{
CommonRigidBodyBase::renderScene();
}
bool InclinedPlaneExample::keyboardCallback(int key, int state) {
// b3Printf("Key pressed: %d in state %d \n",key,state);
bool InclinedPlaneExample::keyboardCallback(int key, int state)
{
// b3Printf("Key pressed: %d in state %d \n",key,state);
switch (key) {
case 32 /*ASCII for space*/: {
resetScene();
break;
}
switch (key)
{
case 32 /*ASCII for space*/:
{
resetScene();
break;
}
}
return false;
}
// GUI parameter modifiers
void onBoxFrictionChanged(float friction, void*){
if(gBox){
void onBoxFrictionChanged(float friction, void*)
{
if (gBox)
{
gBox->setFriction(friction);
// b3Printf("Friction of box changed to %f",friction );
// b3Printf("Friction of box changed to %f",friction );
}
}
void onBoxRestitutionChanged(float restitution, void*){
if(gBox){
void onBoxRestitutionChanged(float restitution, void*)
{
if (gBox)
{
gBox->setRestitution(restitution);
//b3Printf("Restitution of box changed to %f",restitution);
}
}
void onSphereFrictionChanged(float friction, void*){
if(gSphere){
void onSphereFrictionChanged(float friction, void*)
{
if (gSphere)
{
gSphere->setFriction(friction);
//b3Printf("Friction of sphere changed to %f",friction );
}
}
void onSphereRestitutionChanged(float restitution, void*){
if(gSphere){
void onSphereRestitutionChanged(float restitution, void*)
{
if (gSphere)
{
gSphere->setRestitution(restitution);
//b3Printf("Restitution of sphere changed to %f",restitution);
}
}
void onRampInclinationChanged(float inclination, void*){
if(ramp){
void onRampInclinationChanged(float inclination, void*)
{
if (ramp)
{
btTransform startTransform;
startTransform.setIdentity();
@@ -359,29 +358,32 @@ void onRampInclinationChanged(float inclination, void*){
btVector3(btScalar(0), btScalar(15), btScalar(0)));
btQuaternion incline;
incline.setRotation(btVector3(0,0,1),gTilt);
incline.setRotation(btVector3(0, 0, 1), gTilt);
startTransform.setRotation(incline);
ramp->setWorldTransform(startTransform);
//b3Printf("Inclination of ramp changed to %f",inclination );
}
}
void onRampFrictionChanged(float friction, void*){
if(ramp){
void onRampFrictionChanged(float friction, void*)
{
if (ramp)
{
ramp->setFriction(friction);
//b3Printf("Friction of ramp changed to %f \n",friction );
}
}
void onRampRestitutionChanged(float restitution, void*){
if(ramp){
void onRampRestitutionChanged(float restitution, void*)
{
if (ramp)
{
ramp->setRestitution(restitution);
//b3Printf("Restitution of ramp changed to %f \n",restitution);
}
}
CommonExampleInterface* ET_InclinedPlaneCreateFunc(CommonExampleOptions& options)
CommonExampleInterface* ET_InclinedPlaneCreateFunc(CommonExampleOptions& options)
{
return new InclinedPlaneExample(options.m_guiHelper);
}

View File

@@ -16,7 +16,6 @@ subject to the following restrictions:
#ifndef ET_INCLINED_PLANE_EXAMPLE_H
#define ET_INCLINED_PLANE_EXAMPLE_H
class CommonExampleInterface* ET_InclinedPlaneCreateFunc(struct CommonExampleOptions& options);
class CommonExampleInterface* ET_InclinedPlaneCreateFunc(struct CommonExampleOptions& options);
#endif //ET_INCLINED_PLANE_EXAMPLE_H
#endif //ET_INCLINED_PLANE_EXAMPLE_H

View File

@@ -15,7 +15,7 @@
#include "MultiPendulum.h"
#include <vector> // TODO: Should I use another data structure?
#include <vector> // TODO: Should I use another data structure?
#include <iterator>
#include "btBulletDynamicsCommon.h"
@@ -24,80 +24,84 @@
#include "../CommonInterfaces/CommonRigidBodyBase.h"
#include "../CommonInterfaces/CommonParameterInterface.h"
static btScalar gPendulaQty = 2; //TODO: This would actually be an Integer, but the Slider does not like integers, so I floor it when changed
static btScalar gPendulaQty = 2; //TODO: This would actually be an Integer, but the Slider does not like integers, so I floor it when changed
static btScalar gDisplacedPendula = 1; //TODO: This is an int as well
static btScalar gDisplacedPendula = 1; //TODO: This is an int as well
static btScalar gPendulaRestitution = 1; // Default pendulum restitution is 1 to restore all force
static btScalar gPendulaRestitution = 1; // Default pendulum restitution is 1 to restore all force
static btScalar gSphereRadius = 1; // The sphere radius
static btScalar gSphereRadius = 1; // The sphere radius
static btScalar gCurrentPendulumLength = 8;
static btScalar gInitialPendulumLength = 8; // Default pendulum length (distance between two spheres)
static btScalar gInitialPendulumLength = 8; // Default pendulum length (distance between two spheres)
static btScalar gDisplacementForce = 30; // The default force with which we move the pendulum
static btScalar gDisplacementForce = 30; // The default force with which we move the pendulum
static btScalar gForceScalar = 0; // default force scalar to apply a displacement
static btScalar gForceScalar = 0; // default force scalar to apply a displacement
struct MultiPendulumExample: public CommonRigidBodyBase {
MultiPendulumExample(struct GUIHelperInterface* helper) :
CommonRigidBodyBase(helper) {
struct MultiPendulumExample : public CommonRigidBodyBase
{
MultiPendulumExample(struct GUIHelperInterface* helper) : CommonRigidBodyBase(helper)
{
}
virtual ~MultiPendulumExample() {
virtual ~MultiPendulumExample()
{
}
virtual void initPhysics(); // build a multi pendulum
virtual void renderScene(); // render the scene to screen
virtual void createMultiPendulum(btSphereShape* colShape, btScalar pendulaQty, const btVector3& position, btScalar length, btScalar mass); // create a multi pendulum at the indicated x and y position, the specified number of pendula formed into a chain, each with indicated length and mass
virtual void changePendulaLength(btScalar length); // change the pendulum length
virtual void changePendulaRestitution(btScalar restitution); // change the pendula restitution
virtual void stepSimulation(float deltaTime); // step the simulation
virtual bool keyboardCallback(int key, int state); // handle keyboard callbacks
virtual void initPhysics(); // build a multi pendulum
virtual void renderScene(); // render the scene to screen
virtual void createMultiPendulum(btSphereShape* colShape, btScalar pendulaQty, const btVector3& position, btScalar length, btScalar mass); // create a multi pendulum at the indicated x and y position, the specified number of pendula formed into a chain, each with indicated length and mass
virtual void changePendulaLength(btScalar length); // change the pendulum length
virtual void changePendulaRestitution(btScalar restitution); // change the pendula restitution
virtual void stepSimulation(float deltaTime); // step the simulation
virtual bool keyboardCallback(int key, int state); // handle keyboard callbacks
virtual void applyPendulumForce(btScalar pendulumForce);
void resetCamera() {
void resetCamera()
{
float dist = 41;
float pitch = -35;
float yaw = 52;
float targetPos[3] = { 0, 0.46, 0 };
float targetPos[3] = {0, 0.46, 0};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1],
targetPos[2]);
targetPos[2]);
}
std::vector<btSliderConstraint*> constraints; // keep a handle to the slider constraints
std::vector<btRigidBody*> pendula; // keep a handle to the pendula
std::vector<btSliderConstraint*> constraints; // keep a handle to the slider constraints
std::vector<btRigidBody*> pendula; // keep a handle to the pendula
};
static MultiPendulumExample* mex = NULL; // Handle to the example to access it via functions. Do not use this in your simulation!
static MultiPendulumExample* mex = NULL; // Handle to the example to access it via functions. Do not use this in your simulation!
void onMultiPendulaLengthChanged(float pendulaLength, void*); // Change the pendula length
void onMultiPendulaLengthChanged(float pendulaLength, void*); // Change the pendula length
void onMultiPendulaRestitutionChanged(float pendulaRestitution, void*); // change the pendula restitution
void onMultiPendulaRestitutionChanged(float pendulaRestitution, void*); // change the pendula restitution
void applyMForceWithForceScalar(float forceScalar);
void MultiPendulumExample::initPhysics() { // Setup your physics scene
void MultiPendulumExample::initPhysics()
{ // Setup your physics scene
{ // create a slider to change the number of pendula
{ // create a slider to change the number of pendula
SliderParams slider("Number of Pendula", &gPendulaQty);
slider.m_minVal = 1;
slider.m_maxVal = 50;
slider.m_clampToIntegers = true;
slider.m_clampToIntegers = true;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
slider);
}
{ // create a slider to change the number of displaced pendula
{ // create a slider to change the number of displaced pendula
SliderParams slider("Number of Displaced Pendula", &gDisplacedPendula);
slider.m_minVal = 0;
slider.m_maxVal = 49;
slider.m_clampToIntegers = true;
slider.m_clampToIntegers = true;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
slider);
}
{ // create a slider to change the pendula restitution
{ // create a slider to change the pendula restitution
SliderParams slider("Pendula Restitution", &gPendulaRestitution);
slider.m_minVal = 0;
slider.m_maxVal = 1;
@@ -107,7 +111,7 @@ void MultiPendulumExample::initPhysics() { // Setup your physics scene
slider);
}
{ // create a slider to change the pendulum length
{ // create a slider to change the pendulum length
SliderParams slider("Pendula Length", &gCurrentPendulumLength);
slider.m_minVal = 0;
slider.m_maxVal = 49;
@@ -117,7 +121,7 @@ void MultiPendulumExample::initPhysics() { // Setup your physics scene
slider);
}
{ // create a slider to change the force to displace the lowest pendulum
{ // create a slider to change the force to displace the lowest pendulum
SliderParams slider("Displacement force", &gDisplacementForce);
slider.m_minVal = 0.1;
slider.m_maxVal = 200;
@@ -126,7 +130,7 @@ void MultiPendulumExample::initPhysics() { // Setup your physics scene
slider);
}
{ // create a slider to apply the force by slider
{ // create a slider to apply the force by slider
SliderParams slider("Apply displacement force", &gForceScalar);
slider.m_minVal = -1;
slider.m_maxVal = 1;
@@ -143,15 +147,12 @@ void MultiPendulumExample::initPhysics() { // Setup your physics scene
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
if (m_dynamicsWorld->getDebugDrawer())
m_dynamicsWorld->getDebugDrawer()->setDebugMode(
btIDebugDraw::DBG_DrawWireframe
+ btIDebugDraw::DBG_DrawContactPoints
+ btIDebugDraw::DBG_DrawConstraints
+ btIDebugDraw::DBG_DrawConstraintLimits);
btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints + btIDebugDraw::DBG_DrawConstraints + btIDebugDraw::DBG_DrawConstraintLimits);
{ // create the multipendulum starting at the indicated position below and where each pendulum has the following mass
{ // create the multipendulum starting at the indicated position below and where each pendulum has the following mass
btScalar pendulumMass(1.f);
btVector3 position(0.0f,15.0f,0.0f); // initial top-most pendulum position
btVector3 position(0.0f, 15.0f, 0.0f); // initial top-most pendulum position
// Re-using the same collision is better for memory usage and performance
btSphereShape* pendulumShape = new btSphereShape(gSphereRadius);
@@ -159,25 +160,26 @@ void MultiPendulumExample::initPhysics() { // Setup your physics scene
// create multi-pendulum
createMultiPendulum(pendulumShape, floor(gPendulaQty), position,
gInitialPendulumLength, pendulumMass);
gInitialPendulumLength, pendulumMass);
}
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void MultiPendulumExample::stepSimulation(float deltaTime) {
void MultiPendulumExample::stepSimulation(float deltaTime)
{
applyMForceWithForceScalar(gForceScalar); // apply force defined by apply force slider
applyMForceWithForceScalar(gForceScalar); // apply force defined by apply force slider
if (m_dynamicsWorld) {
if (m_dynamicsWorld)
{
m_dynamicsWorld->stepSimulation(deltaTime);
}
}
void MultiPendulumExample::createMultiPendulum(btSphereShape* colShape,
btScalar pendulaQty, const btVector3& position,
btScalar length, btScalar mass) {
btScalar pendulaQty, const btVector3& position,
btScalar length, btScalar mass)
{
// The multi-pendulum looks like this (names when built):
//..........0......./.......1...../.......2......./..etc...:pendulum build iterations
// O parentSphere
@@ -196,7 +198,7 @@ void MultiPendulumExample::createMultiPendulum(btSphereShape* colShape,
// position the top sphere
startTransform.setOrigin(position);
startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation
startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation
btRigidBody* topSphere = createRigidBody(mass, startTransform, colShape);
@@ -209,25 +211,26 @@ void MultiPendulumExample::createMultiPendulum(btSphereShape* colShape,
btPoint2PointConstraint* p2pconst = new btPoint2PointConstraint(
*topSphere, constraintPivot);
p2pconst->setDbgDrawSize(btScalar(5.f)); // set the size of the debug drawing
p2pconst->setDbgDrawSize(btScalar(5.f)); // set the size of the debug drawing
// add the constraint to the world
m_dynamicsWorld->addConstraint(p2pconst, true);
btRigidBody* parentSphere = topSphere; // set the top sphere as the parent sphere for the next sphere to be created
btRigidBody* parentSphere = topSphere; // set the top sphere as the parent sphere for the next sphere to be created
for (int i = 0; i < pendulaQty; i++) { // produce the number of pendula
for (int i = 0; i < pendulaQty; i++)
{ // produce the number of pendula
// create joint element to make the pendulum rotate it
// position the joint sphere at the same position as the top sphere
startTransform.setOrigin(position - btVector3(0,length*(i),0));
startTransform.setOrigin(position - btVector3(0, length * (i), 0));
startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation
startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation
btRigidBody* jointSphere = createRigidBody(mass, startTransform,
colShape);
jointSphere->setFriction(0); // we do not need friction here
colShape);
jointSphere->setFriction(0); // we do not need friction here
// disable the deactivation when object does not move anymore
jointSphere->setActivationState(DISABLE_DEACTIVATION);
@@ -248,25 +251,25 @@ void MultiPendulumExample::createMultiPendulum(btSphereShape* colShape,
constraintPivotInJointSphereRF.setOrigin(parentSphereInJointSphereRF);
btPoint2PointConstraint* p2pconst = new btPoint2PointConstraint(
*parentSphere,*jointSphere,constraintPivotInParentSphereRF.getOrigin(), constraintPivotInJointSphereRF.getOrigin());
*parentSphere, *jointSphere, constraintPivotInParentSphereRF.getOrigin(), constraintPivotInJointSphereRF.getOrigin());
p2pconst->setDbgDrawSize(btScalar(5.f)); // set the size of the debug drawing
p2pconst->setDbgDrawSize(btScalar(5.f)); // set the size of the debug drawing
// add the constraint to the world
m_dynamicsWorld->addConstraint(p2pconst, true);
// create a slider constraint to change the length of the pendula while it swings
startTransform.setIdentity(); // reset start transform
startTransform.setIdentity(); // reset start transform
// position the child sphere below the joint sphere
startTransform.setOrigin(position - btVector3(0,length*(i+1),0));
startTransform.setOrigin(position - btVector3(0, length * (i + 1), 0));
startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation
startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation
btRigidBody* childSphere = createRigidBody(mass, startTransform,
colShape);
childSphere->setFriction(0); // we do not need friction here
colShape);
childSphere->setFriction(0); // we do not need friction here
pendula.push_back(childSphere);
// disable the deactivation when object does not move anymore
@@ -291,13 +294,13 @@ void MultiPendulumExample::createMultiPendulum(btSphereShape* colShape,
// the slider constraint is x aligned per default, but we want it to be y aligned, therefore we rotate it
btQuaternion qt;
qt.setEuler(0, 0, -SIMD_HALF_PI);
constraintPivotInJointSphereRF.setRotation(qt); //we use Y like up Axis
constraintPivotInChildSphereRF.setRotation(qt); //we use Y like up Axis
constraintPivotInJointSphereRF.setRotation(qt); //we use Y like up Axis
constraintPivotInChildSphereRF.setRotation(qt); //we use Y like up Axis
btSliderConstraint* sliderConst = new btSliderConstraint(*jointSphere,
*childSphere, constraintPivotInJointSphereRF, constraintPivotInChildSphereRF, true);
*childSphere, constraintPivotInJointSphereRF, constraintPivotInChildSphereRF, true);
sliderConst->setDbgDrawSize(btScalar(5.f)); // set the size of the debug drawing
sliderConst->setDbgDrawSize(btScalar(5.f)); // set the size of the debug drawing
// set limits
// the initial setup of the constraint defines the origins of the limit dimensions,
@@ -314,77 +317,89 @@ void MultiPendulumExample::createMultiPendulum(btSphereShape* colShape,
}
}
void MultiPendulumExample::changePendulaLength(btScalar length) {
void MultiPendulumExample::changePendulaLength(btScalar length)
{
btScalar lowerLimit = -gInitialPendulumLength;
for (std::vector<btSliderConstraint*>::iterator sit = constraints.begin();
sit != constraints.end(); sit++) {
sit != constraints.end(); sit++)
{
btAssert((*sit) && "Null constraint");
// if the pendulum is being shortened beyond it's own length, we don't let the lower sphere to go past the upper one
if (lowerLimit <= length) {
if (lowerLimit <= length)
{
(*sit)->setLowerLinLimit(length + lowerLimit);
(*sit)->setUpperLinLimit(length + lowerLimit);
}
}
}
void MultiPendulumExample::changePendulaRestitution(btScalar restitution) {
void MultiPendulumExample::changePendulaRestitution(btScalar restitution)
{
for (std::vector<btRigidBody*>::iterator rit = pendula.begin();
rit != pendula.end(); rit++) {
rit != pendula.end(); rit++)
{
btAssert((*rit) && "Null constraint");
(*rit)->setRestitution(restitution);
}
}
void MultiPendulumExample::renderScene() {
void MultiPendulumExample::renderScene()
{
CommonRigidBodyBase::renderScene();
}
bool MultiPendulumExample::keyboardCallback(int key, int state) {
bool MultiPendulumExample::keyboardCallback(int key, int state)
{
//b3Printf("Key pressed: %d in state %d \n",key,state);
//key 1, key 2, key 3
switch (key) {
case '1' /*ASCII for 1*/: {
switch (key)
{
case '1' /*ASCII for 1*/:
{
//assumption: Sphere are aligned in Z axis
btScalar newLimit = btScalar(gCurrentPendulumLength + 0.1);
//assumption: Sphere are aligned in Z axis
btScalar newLimit = btScalar(gCurrentPendulumLength + 0.1);
changePendulaLength(newLimit);
gCurrentPendulumLength = newLimit;
b3Printf("Increase pendulum length to %f", gCurrentPendulumLength);
return true;
}
case '2' /*ASCII for 2*/: {
//assumption: Sphere are aligned in Z axis
btScalar newLimit = btScalar(gCurrentPendulumLength - 0.1);
//is being shortened beyond it's own length, we don't let the lower sphere to go over the upper one
if (0 <= newLimit) {
changePendulaLength(newLimit);
gCurrentPendulumLength = newLimit;
}
b3Printf("Decrease pendulum length to %f", gCurrentPendulumLength);
return true;
}
case '3' /*ASCII for 3*/: {
applyPendulumForce(gDisplacementForce);
return true;
}
b3Printf("Increase pendulum length to %f", gCurrentPendulumLength);
return true;
}
case '2' /*ASCII for 2*/:
{
//assumption: Sphere are aligned in Z axis
btScalar newLimit = btScalar(gCurrentPendulumLength - 0.1);
//is being shortened beyond it's own length, we don't let the lower sphere to go over the upper one
if (0 <= newLimit)
{
changePendulaLength(newLimit);
gCurrentPendulumLength = newLimit;
}
b3Printf("Decrease pendulum length to %f", gCurrentPendulumLength);
return true;
}
case '3' /*ASCII for 3*/:
{
applyPendulumForce(gDisplacementForce);
return true;
}
}
return false;
}
void MultiPendulumExample::applyPendulumForce(btScalar pendulumForce){
if(pendulumForce != 0){
b3Printf("Apply %f to pendulum",pendulumForce);
for (int i = 0; i < gDisplacedPendula; i++) {
void MultiPendulumExample::applyPendulumForce(btScalar pendulumForce)
{
if (pendulumForce != 0)
{
b3Printf("Apply %f to pendulum", pendulumForce);
for (int i = 0; i < gDisplacedPendula; i++)
{
if (gDisplacedPendula >= 0 && gDisplacedPendula <= gPendulaQty)
pendula[i]->applyCentralForce(btVector3(pendulumForce, 0, 0));
}
@@ -393,26 +408,30 @@ void MultiPendulumExample::applyPendulumForce(btScalar pendulumForce){
// GUI parameter modifiers
void onMultiPendulaLengthChanged(float pendulaLength, void*) { // Change the pendula length
if (mex){
void onMultiPendulaLengthChanged(float pendulaLength, void*)
{ // Change the pendula length
if (mex)
{
mex->changePendulaLength(pendulaLength);
}
//b3Printf("Pendula length changed to %f \n",sliderValue );
}
void onMultiPendulaRestitutionChanged(float pendulaRestitution, void*) { // change the pendula restitution
if (mex){
void onMultiPendulaRestitutionChanged(float pendulaRestitution, void*)
{ // change the pendula restitution
if (mex)
{
mex->changePendulaRestitution(pendulaRestitution);
}
}
void applyMForceWithForceScalar(float forceScalar) {
if(mex){
void applyMForceWithForceScalar(float forceScalar)
{
if (mex)
{
btScalar appliedForce = forceScalar * gDisplacementForce;
if(fabs(gForceScalar) < 0.2f)
if (fabs(gForceScalar) < 0.2f)
gForceScalar = 0;
mex->applyPendulumForce(appliedForce);
@@ -420,7 +439,8 @@ void applyMForceWithForceScalar(float forceScalar) {
}
CommonExampleInterface* ET_MultiPendulumCreateFunc(
CommonExampleOptions& options) {
CommonExampleOptions& options)
{
mex = new MultiPendulumExample(options.m_guiHelper);
return mex;
}

View File

@@ -16,7 +16,6 @@ subject to the following restrictions:
#ifndef ET_MULTI_PENDULUM_EXAMPLE_H
#define ET_MULTI_PENDULUM_EXAMPLE_H
class CommonExampleInterface* ET_MultiPendulumCreateFunc(struct CommonExampleOptions& options);
class CommonExampleInterface* ET_MultiPendulumCreateFunc(struct CommonExampleOptions& options);
#endif //ET_MULTI_PENDULUM_EXAMPLE_H
#endif //ET_MULTI_PENDULUM_EXAMPLE_H

View File

@@ -13,23 +13,21 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#include "MultipleBoxes.h"
#include "btBulletDynamicsCommon.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "../CommonInterfaces/CommonRigidBodyBase.h"
const int TOTAL_BOXES = 10;
struct MultipleBoxesExample : public CommonRigidBodyBase
{
MultipleBoxesExample(struct GUIHelperInterface* helper)
:CommonRigidBodyBase(helper)
: CommonRigidBodyBase(helper)
{
}
virtual ~MultipleBoxesExample(){}
virtual ~MultipleBoxesExample() {}
virtual void initPhysics();
virtual void renderScene();
void resetCamera()
@@ -37,8 +35,8 @@ struct MultipleBoxesExample : public CommonRigidBodyBase
float dist = 41;
float pitch = -35;
float yaw = 52;
float targetPos[3]={0,0.46,0};
m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]);
float targetPos[3] = {0, 0.46, 0};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
};
@@ -47,74 +45,63 @@ void MultipleBoxesExample::initPhysics()
m_guiHelper->setUpAxis(1);
createEmptyDynamicsWorld();
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
if (m_dynamicsWorld->getDebugDrawer())
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints);
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints);
///create a few basic rigid bodies
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0,-50,0));
groundTransform.setOrigin(btVector3(0, -50, 0));
{
btScalar mass(0.);
createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1));
createRigidBody(mass, groundTransform, groundShape, btVector4(0, 0, 1, 1));
}
{
//create a few dynamic rigidbodies
// Re-using the same collision is better for memory usage and performance
btBoxShape* colShape = createBoxShape(btVector3(1,1,1));
btBoxShape* colShape = createBoxShape(btVector3(1, 1, 1));
m_collisionShapes.push_back(colShape);
/// Create Dynamic Objects
btTransform startTransform;
startTransform.setIdentity();
btScalar mass(1.f);
btScalar mass(1.f);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0,0,0);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
colShape->calculateLocalInertia(mass,localInertia);
colShape->calculateLocalInertia(mass, localInertia);
for(int i=0;i<TOTAL_BOXES;++i) {
for (int i = 0; i < TOTAL_BOXES; ++i)
{
startTransform.setOrigin(btVector3(
btScalar(0),
btScalar(20+i*2),
btScalar(0)));
createRigidBody(mass,startTransform,colShape);
btScalar(0),
btScalar(20 + i * 2),
btScalar(0)));
createRigidBody(mass, startTransform, colShape);
}
}
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void MultipleBoxesExample::renderScene()
{
CommonRigidBodyBase::renderScene();
CommonRigidBodyBase::renderScene();
}
CommonExampleInterface* ET_MultipleBoxesCreateFunc(CommonExampleOptions& options)
CommonExampleInterface* ET_MultipleBoxesCreateFunc(CommonExampleOptions& options)
{
return new MultipleBoxesExample(options.m_guiHelper);
}

View File

@@ -16,7 +16,6 @@ subject to the following restrictions:
#ifndef ET_MULTIPLE_BOXES_EXAMPLE_H
#define ET_MULTIPLE_BOXES_EXAMPLE_H
class CommonExampleInterface* ET_MultipleBoxesCreateFunc(struct CommonExampleOptions& options);
class CommonExampleInterface* ET_MultipleBoxesCreateFunc(struct CommonExampleOptions& options);
#endif //ET_MULTIPLE_BOXES_EXAMPLE_H
#endif //ET_MULTIPLE_BOXES_EXAMPLE_H

View File

@@ -15,38 +15,40 @@
#include "NewtonsCradle.h"
#include <vector> // TODO: Should I use another data structure?
#include <vector> // TODO: Should I use another data structure?
#include <iterator>
#include "btBulletDynamicsCommon.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "../CommonInterfaces/CommonRigidBodyBase.h"
#include "../CommonInterfaces/CommonParameterInterface.h"
static btScalar gPendulaQty = 5; // Number of pendula in newton's cradle
static btScalar gPendulaQty = 5; // Number of pendula in newton's cradle
//TODO: This would actually be an Integer, but the Slider does not like integers, so I floor it when changed
static btScalar gDisplacedPendula = 1; // number of displaced pendula
static btScalar gDisplacedPendula = 1; // number of displaced pendula
//TODO: This is an int as well
static btScalar gPendulaRestitution = 1; // pendula restitution when hitting against each other
static btScalar gPendulaRestitution = 1; // pendula restitution when hitting against each other
static btScalar gSphereRadius = 1; // pendula radius
static btScalar gSphereRadius = 1; // pendula radius
static btScalar gCurrentPendulumLength = 8; // current pendula length
static btScalar gCurrentPendulumLength = 8; // current pendula length
static btScalar gInitialPendulumLength = 8; // default pendula length
static btScalar gInitialPendulumLength = 8; // default pendula length
static btScalar gDisplacementForce = 30; // default force to displace the pendula
static btScalar gDisplacementForce = 30; // default force to displace the pendula
static btScalar gForceScalar = 0; // default force scalar to apply a displacement
static btScalar gForceScalar = 0; // default force scalar to apply a displacement
struct NewtonsCradleExample: public CommonRigidBodyBase {
NewtonsCradleExample(struct GUIHelperInterface* helper) :
CommonRigidBodyBase(helper) {
struct NewtonsCradleExample : public CommonRigidBodyBase
{
NewtonsCradleExample(struct GUIHelperInterface* helper) : CommonRigidBodyBase(helper)
{
}
virtual ~NewtonsCradleExample() {
virtual ~NewtonsCradleExample()
{
}
virtual void initPhysics();
virtual void renderScene();
@@ -56,48 +58,49 @@ struct NewtonsCradleExample: public CommonRigidBodyBase {
virtual void stepSimulation(float deltaTime);
virtual bool keyboardCallback(int key, int state);
virtual void applyPendulumForce(btScalar pendulumForce);
void resetCamera() {
void resetCamera()
{
float dist = 41;
float pitch = -35;
float yaw = 52;
float targetPos[3] = { 0, 0.46, 0 };
float targetPos[3] = {0, 0.46, 0};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1],
targetPos[2]);
targetPos[2]);
}
std::vector<btSliderConstraint*> constraints; // keep a handle to the slider constraints
std::vector<btRigidBody*> pendula; // keep a handle to the pendula
std::vector<btSliderConstraint*> constraints; // keep a handle to the slider constraints
std::vector<btRigidBody*> pendula; // keep a handle to the pendula
};
static NewtonsCradleExample* nex = NULL;
void onPendulaLengthChanged(float pendulaLength, void* userPtr); // Change the pendula length
void onPendulaLengthChanged(float pendulaLength, void* userPtr); // Change the pendula length
void onPendulaRestitutionChanged(float pendulaRestitution, void* userPtr); // change the pendula restitution
void onPendulaRestitutionChanged(float pendulaRestitution, void* userPtr); // change the pendula restitution
void applyForceWithForceScalar(float forceScalar);
void NewtonsCradleExample::initPhysics() {
{ // create a slider to change the number of pendula
void NewtonsCradleExample::initPhysics()
{
{ // create a slider to change the number of pendula
SliderParams slider("Number of Pendula", &gPendulaQty);
slider.m_minVal = 1;
slider.m_maxVal = 50;
slider.m_clampToIntegers = true;
slider.m_clampToIntegers = true;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
slider);
}
{ // create a slider to change the number of displaced pendula
{ // create a slider to change the number of displaced pendula
SliderParams slider("Number of Displaced Pendula", &gDisplacedPendula);
slider.m_minVal = 0;
slider.m_maxVal = 49;
slider.m_clampToIntegers = true;
slider.m_clampToIntegers = true;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
slider);
}
{ // create a slider to change the pendula restitution
{ // create a slider to change the pendula restitution
SliderParams slider("Pendula Restitution", &gPendulaRestitution);
slider.m_minVal = 0;
slider.m_maxVal = 1;
@@ -107,7 +110,7 @@ void NewtonsCradleExample::initPhysics() {
slider);
}
{ // create a slider to change the pendulum length
{ // create a slider to change the pendulum length
SliderParams slider("Pendula Length", &gCurrentPendulumLength);
slider.m_minVal = 0;
slider.m_maxVal = 49;
@@ -117,7 +120,7 @@ void NewtonsCradleExample::initPhysics() {
slider);
}
{ // create a slider to change the force to displace the lowest pendulum
{ // create a slider to change the force to displace the lowest pendulum
SliderParams slider("Displacement force", &gDisplacementForce);
slider.m_minVal = 0.1;
slider.m_maxVal = 200;
@@ -126,7 +129,7 @@ void NewtonsCradleExample::initPhysics() {
slider);
}
{ // create a slider to apply the force by slider
{ // create a slider to apply the force by slider
SliderParams slider("Apply displacement force", &gForceScalar);
slider.m_minVal = -1;
slider.m_maxVal = 1;
@@ -143,45 +146,43 @@ void NewtonsCradleExample::initPhysics() {
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
if (m_dynamicsWorld->getDebugDrawer())
m_dynamicsWorld->getDebugDrawer()->setDebugMode(
btIDebugDraw::DBG_DrawWireframe
+ btIDebugDraw::DBG_DrawContactPoints
+ btIDebugDraw::DBG_DrawConstraints
+ btIDebugDraw::DBG_DrawConstraintLimits);
btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints + btIDebugDraw::DBG_DrawConstraints + btIDebugDraw::DBG_DrawConstraintLimits);
{ // create the pendula starting at the indicated position below and where each pendulum has the following mass
{ // create the pendula starting at the indicated position below and where each pendulum has the following mass
btScalar pendulumMass(1.f);
btVector3 position(0.0f,15.0f,0.0f); // initial left-most pendulum position
btQuaternion orientation(0,0,0,1); // orientation of the pendula
btVector3 position(0.0f, 15.0f, 0.0f); // initial left-most pendulum position
btQuaternion orientation(0, 0, 0, 1); // orientation of the pendula
// Re-using the same collision is better for memory usage and performance
btSphereShape* pendulumShape = new btSphereShape(gSphereRadius);
m_collisionShapes.push_back(pendulumShape);
for (int i = 0; i < floor(gPendulaQty); i++) {
for (int i = 0; i < floor(gPendulaQty); i++)
{
// create pendulum
createPendulum(pendulumShape, position, gInitialPendulumLength, pendulumMass);
// displace the pendula 1.05 sphere size, so that they all nearly touch (small spacings in between
position.setX(position.x()-2.1f * gSphereRadius);
position.setX(position.x() - 2.1f * gSphereRadius);
}
}
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void NewtonsCradleExample::stepSimulation(float deltaTime) {
void NewtonsCradleExample::stepSimulation(float deltaTime)
{
applyForceWithForceScalar(gForceScalar); // apply force defined by apply force slider
applyForceWithForceScalar(gForceScalar); // apply force defined by apply force slider
if (m_dynamicsWorld) {
if (m_dynamicsWorld)
{
m_dynamicsWorld->stepSimulation(deltaTime);
}
}
void NewtonsCradleExample::createPendulum(btSphereShape* colShape, const btVector3& position, btScalar length, btScalar mass) {
void NewtonsCradleExample::createPendulum(btSphereShape* colShape, const btVector3& position, btScalar length, btScalar mass)
{
// The pendulum looks like this (names when built):
// O topSphere
// |
@@ -193,32 +194,32 @@ void NewtonsCradleExample::createPendulum(btSphereShape* colShape, const btVecto
// position the top sphere above ground with a moving x position
startTransform.setOrigin(position);
startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation
startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation
btRigidBody* topSphere = createRigidBody(mass, startTransform, colShape);
// position the bottom sphere below the top sphere
startTransform.setOrigin(
btVector3(position.x(), btScalar(position.y() - length),
position.z()));
position.z()));
startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation
startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation
btRigidBody* bottomSphere = createRigidBody(mass, startTransform, colShape);
bottomSphere->setFriction(0); // we do not need friction here
bottomSphere->setFriction(0); // we do not need friction here
pendula.push_back(bottomSphere);
// disable the deactivation when objects do not move anymore
topSphere->setActivationState(DISABLE_DEACTIVATION);
bottomSphere->setActivationState(DISABLE_DEACTIVATION);
bottomSphere->setRestitution(gPendulaRestitution); // set pendula restitution
bottomSphere->setRestitution(gPendulaRestitution); // set pendula restitution
//make the top sphere position "fixed" to the world by attaching with a point to point constraint
// The pivot is defined in the reference frame of topSphere, so the attachment is exactly at the center of the topSphere
btVector3 constraintPivot(btVector3(0.0f, 0.0f, 0.0f));
btPoint2PointConstraint* p2pconst = new btPoint2PointConstraint(*topSphere,
constraintPivot);
constraintPivot);
p2pconst->setDbgDrawSize(btScalar(5.f)); // set the size of the debug drawing
p2pconst->setDbgDrawSize(btScalar(5.f)); // set the size of the debug drawing
// add the constraint to the world
m_dynamicsWorld->addConstraint(p2pconst, true);
@@ -234,8 +235,8 @@ void NewtonsCradleExample::createPendulum(btSphereShape* colShape, const btVecto
// the slider constraint is x aligned per default, but we want it to be y aligned, therefore we rotate it
btQuaternion qt;
qt.setEuler(0, 0, -SIMD_HALF_PI);
constraintPivotInTopSphereRF.setRotation(qt); //we use Y like up Axis
constraintPivotInBottomSphereRF.setRotation(qt); //we use Y like up Axis
constraintPivotInTopSphereRF.setRotation(qt); //we use Y like up Axis
constraintPivotInBottomSphereRF.setRotation(qt); //we use Y like up Axis
//Obtain the position of topSphere in local reference frame of bottomSphere (the pivot is therefore in the center of topSphere)
btVector3 topSphereInBottomSphereRF =
@@ -244,9 +245,9 @@ void NewtonsCradleExample::createPendulum(btSphereShape* colShape, const btVecto
constraintPivotInBottomSphereRF.setOrigin(topSphereInBottomSphereRF);
btSliderConstraint* sliderConst = new btSliderConstraint(*topSphere,
*bottomSphere, constraintPivotInTopSphereRF, constraintPivotInBottomSphereRF, true);
*bottomSphere, constraintPivotInTopSphereRF, constraintPivotInBottomSphereRF, true);
sliderConst->setDbgDrawSize(btScalar(5.f)); // set the size of the debug drawing
sliderConst->setDbgDrawSize(btScalar(5.f)); // set the size of the debug drawing
// set limits
// the initial setup of the constraint defines the origins of the limit dimensions,
@@ -261,76 +262,89 @@ void NewtonsCradleExample::createPendulum(btSphereShape* colShape, const btVecto
m_dynamicsWorld->addConstraint(sliderConst, true);
}
void NewtonsCradleExample::changePendulaLength(btScalar length) {
void NewtonsCradleExample::changePendulaLength(btScalar length)
{
btScalar lowerLimit = -gInitialPendulumLength;
for (std::vector<btSliderConstraint*>::iterator sit = constraints.begin();
sit != constraints.end(); sit++) {
sit != constraints.end(); sit++)
{
btAssert((*sit) && "Null constraint");
//if the pendulum is being shortened beyond it's own length, we don't let the lower sphere to go past the upper one
if (lowerLimit <= length) {
if (lowerLimit <= length)
{
(*sit)->setLowerLinLimit(length + lowerLimit);
(*sit)->setUpperLinLimit(length + lowerLimit);
}
}
}
void NewtonsCradleExample::changePendulaRestitution(btScalar restitution) {
void NewtonsCradleExample::changePendulaRestitution(btScalar restitution)
{
for (std::vector<btRigidBody*>::iterator rit = pendula.begin();
rit != pendula.end(); rit++) {
rit != pendula.end(); rit++)
{
btAssert((*rit) && "Null constraint");
(*rit)->setRestitution(restitution);
}
}
void NewtonsCradleExample::renderScene() {
void NewtonsCradleExample::renderScene()
{
CommonRigidBodyBase::renderScene();
}
bool NewtonsCradleExample::keyboardCallback(int key, int state) {
bool NewtonsCradleExample::keyboardCallback(int key, int state)
{
//b3Printf("Key pressed: %d in state %d \n",key,state);
//key 1, key 2, key 3
switch (key) {
case '1' /*ASCII for 1*/: {
switch (key)
{
case '1' /*ASCII for 1*/:
{
//assumption: Sphere are aligned in Z axis
btScalar newLimit = btScalar(gCurrentPendulumLength + 0.1);
//assumption: Sphere are aligned in Z axis
btScalar newLimit = btScalar(gCurrentPendulumLength + 0.1);
changePendulaLength(newLimit);
gCurrentPendulumLength = newLimit;
b3Printf("Increase pendulum length to %f", gCurrentPendulumLength);
return true;
}
case '2' /*ASCII for 2*/: {
//assumption: Sphere are aligned in Z axis
btScalar newLimit = btScalar(gCurrentPendulumLength - 0.1);
//is being shortened beyond it's own length, we don't let the lower sphere to go over the upper one
if (0 <= newLimit) {
changePendulaLength(newLimit);
gCurrentPendulumLength = newLimit;
}
b3Printf("Decrease pendulum length to %f", gCurrentPendulumLength);
return true;
}
case '3' /*ASCII for 3*/: {
applyPendulumForce(gDisplacementForce);
return true;
}
b3Printf("Increase pendulum length to %f", gCurrentPendulumLength);
return true;
}
case '2' /*ASCII for 2*/:
{
//assumption: Sphere are aligned in Z axis
btScalar newLimit = btScalar(gCurrentPendulumLength - 0.1);
//is being shortened beyond it's own length, we don't let the lower sphere to go over the upper one
if (0 <= newLimit)
{
changePendulaLength(newLimit);
gCurrentPendulumLength = newLimit;
}
b3Printf("Decrease pendulum length to %f", gCurrentPendulumLength);
return true;
}
case '3' /*ASCII for 3*/:
{
applyPendulumForce(gDisplacementForce);
return true;
}
}
return false;
}
void NewtonsCradleExample::applyPendulumForce(btScalar pendulumForce){
if(pendulumForce != 0){
b3Printf("Apply %f to pendulum",pendulumForce);
for (int i = 0; i < gDisplacedPendula; i++) {
void NewtonsCradleExample::applyPendulumForce(btScalar pendulumForce)
{
if (pendulumForce != 0)
{
b3Printf("Apply %f to pendulum", pendulumForce);
for (int i = 0; i < gDisplacedPendula; i++)
{
if (gDisplacedPendula >= 0 && gDisplacedPendula <= gPendulaQty)
pendula[i]->applyCentralForce(btVector3(pendulumForce, 0, 0));
}
@@ -339,24 +353,30 @@ void NewtonsCradleExample::applyPendulumForce(btScalar pendulumForce){
// GUI parameter modifiers
void onPendulaLengthChanged(float pendulaLength, void*) {
if (nex){
void onPendulaLengthChanged(float pendulaLength, void*)
{
if (nex)
{
nex->changePendulaLength(pendulaLength);
//b3Printf("Pendula length changed to %f \n",sliderValue );
}
}
void onPendulaRestitutionChanged(float pendulaRestitution, void*) {
if (nex){
void onPendulaRestitutionChanged(float pendulaRestitution, void*)
{
if (nex)
{
nex->changePendulaRestitution(pendulaRestitution);
}
}
void applyForceWithForceScalar(float forceScalar) {
if(nex){
void applyForceWithForceScalar(float forceScalar)
{
if (nex)
{
btScalar appliedForce = forceScalar * gDisplacementForce;
if(fabs(gForceScalar) < 0.2f)
if (fabs(gForceScalar) < 0.2f)
gForceScalar = 0;
nex->applyPendulumForce(appliedForce);
@@ -364,7 +384,8 @@ void applyForceWithForceScalar(float forceScalar) {
}
CommonExampleInterface* ET_NewtonsCradleCreateFunc(
CommonExampleOptions& options) {
CommonExampleOptions& options)
{
nex = new NewtonsCradleExample(options.m_guiHelper);
return nex;
}

View File

@@ -16,7 +16,6 @@ subject to the following restrictions:
#ifndef ET_NEWTONS_CRADLE_EXAMPLE_H
#define ET_NEWTONS_CRADLE_EXAMPLE_H
class CommonExampleInterface* ET_NewtonsCradleCreateFunc(struct CommonExampleOptions& options);
class CommonExampleInterface* ET_NewtonsCradleCreateFunc(struct CommonExampleOptions& options);
#endif //ET_NEWTONS_CRADLE_EXAMPLE_H
#endif //ET_NEWTONS_CRADLE_EXAMPLE_H

View File

@@ -15,12 +15,12 @@
#include "NewtonsRopeCradle.h"
#include <vector> // TODO: Should I use another data structure?
#include <vector> // TODO: Should I use another data structure?
#include <iterator>
#include "btBulletDynamicsCommon.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "../CommonInterfaces/CommonRigidBodyBase.h"
#include "BulletSoftBody/btSoftRigidDynamicsWorld.h"
@@ -28,31 +28,32 @@
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
#include "../CommonInterfaces/CommonParameterInterface.h"
static btScalar gPendulaQty = 5; // Number of pendula in newton's cradle
static btScalar gPendulaQty = 5; // Number of pendula in newton's cradle
//TODO: This would actually be an Integer, but the Slider does not like integers, so I floor it when changed
static btScalar gDisplacedPendula = 1; // number of displaced pendula
static btScalar gDisplacedPendula = 1; // number of displaced pendula
//TODO: This is an int as well
static btScalar gPendulaRestitution = 1; // pendula restition when hitting against each other
static btScalar gPendulaRestitution = 1; // pendula restition when hitting against each other
static btScalar gSphereRadius = 1; // pendula radius
static btScalar gSphereRadius = 1; // pendula radius
static btScalar gInitialPendulumWidth = 4; // default pendula width
static btScalar gInitialPendulumWidth = 4; // default pendula width
static btScalar gInitialPendulumHeight = 8; // default pendula height
static btScalar gInitialPendulumHeight = 8; // default pendula height
static btScalar gRopeResolution = 1; // default rope resolution (number of links as in a chain)
static btScalar gRopeResolution = 1; // default rope resolution (number of links as in a chain)
static btScalar gDisplacementForce = 30; // default force to displace the pendula
static btScalar gDisplacementForce = 30; // default force to displace the pendula
static btScalar gForceScalar = 0; // default force scalar to apply a displacement
static btScalar gForceScalar = 0; // default force scalar to apply a displacement
struct NewtonsRopeCradleExample : public CommonRigidBodyBase {
NewtonsRopeCradleExample(struct GUIHelperInterface* helper) :
CommonRigidBodyBase(helper) {
struct NewtonsRopeCradleExample : public CommonRigidBodyBase
{
NewtonsRopeCradleExample(struct GUIHelperInterface* helper) : CommonRigidBodyBase(helper)
{
}
virtual ~NewtonsRopeCradleExample(){}
virtual ~NewtonsRopeCradleExample() {}
virtual void initPhysics();
virtual void stepSimulation(float deltaTime);
virtual void renderScene();
@@ -60,7 +61,7 @@ struct NewtonsRopeCradleExample : public CommonRigidBodyBase {
void createEmptyDynamicsWorld()
{
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase();
@@ -76,31 +77,30 @@ struct NewtonsRopeCradleExample : public CommonRigidBodyBase {
}
virtual void createRopePendulum(btSphereShape* colShape,
const btVector3& position, const btQuaternion& pendulumOrientation, btScalar width, btScalar height, btScalar mass);
const btVector3& position, const btQuaternion& pendulumOrientation, btScalar width, btScalar height, btScalar mass);
virtual void changePendulaRestitution(btScalar restitution);
virtual void connectWithRope(btRigidBody* body1, btRigidBody* body2);
virtual bool keyboardCallback(int key, int state);
virtual btSoftRigidDynamicsWorld* getSoftDynamicsWorld()
virtual btSoftRigidDynamicsWorld* getSoftDynamicsWorld()
{
///just make it a btSoftRigidDynamicsWorld please
///or we will add type checking
return (btSoftRigidDynamicsWorld*) m_dynamicsWorld;
return (btSoftRigidDynamicsWorld*)m_dynamicsWorld;
}
void resetCamera()
{
float dist = 41;
float pitch = -35;
float yaw = 52;
float targetPos[3]={0,0.46,0};
m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]);
float targetPos[3] = {0, 0.46, 0};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
std::vector<btSliderConstraint*> constraints;
std::vector<btRigidBody*> pendula;
btSoftBodyWorldInfo softBodyWorldInfo;
btSoftBodyWorldInfo softBodyWorldInfo;
};
static NewtonsRopeCradleExample* nex = NULL;
@@ -111,26 +111,25 @@ void applyRForceWithForceScalar(float forceScalar);
void NewtonsRopeCradleExample::initPhysics()
{
{ // create a slider to change the number of pendula
{ // create a slider to change the number of pendula
SliderParams slider("Number of Pendula", &gPendulaQty);
slider.m_minVal = 1;
slider.m_maxVal = 50;
slider.m_clampToIntegers = true;
slider.m_clampToIntegers = true;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
slider);
}
{ // create a slider to change the number of displaced pendula
{ // create a slider to change the number of displaced pendula
SliderParams slider("Number of Displaced Pendula", &gDisplacedPendula);
slider.m_minVal = 0;
slider.m_maxVal = 49;
slider.m_clampToIntegers = true;
slider.m_clampToIntegers = true;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
slider);
}
{ // create a slider to change the pendula restitution
{ // create a slider to change the pendula restitution
SliderParams slider("Pendula Restitution", &gPendulaRestitution);
slider.m_minVal = 0;
slider.m_maxVal = 1;
@@ -140,16 +139,16 @@ void NewtonsRopeCradleExample::initPhysics()
slider);
}
{ // create a slider to change the rope resolution
{ // create a slider to change the rope resolution
SliderParams slider("Rope Resolution", &gRopeResolution);
slider.m_minVal = 1;
slider.m_maxVal = 20;
slider.m_clampToIntegers = true;
slider.m_clampToIntegers = true;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
slider);
}
{ // create a slider to change the pendulum width
{ // create a slider to change the pendulum width
SliderParams slider("Pendulum Width", &gInitialPendulumWidth);
slider.m_minVal = 0;
slider.m_maxVal = 40;
@@ -158,7 +157,7 @@ void NewtonsRopeCradleExample::initPhysics()
slider);
}
{ // create a slider to change the pendulum height
{ // create a slider to change the pendulum height
SliderParams slider("Pendulum Height", &gInitialPendulumHeight);
slider.m_minVal = 0;
slider.m_maxVal = 40;
@@ -167,7 +166,7 @@ void NewtonsRopeCradleExample::initPhysics()
slider);
}
{ // create a slider to change the force to displace the lowest pendulum
{ // create a slider to change the force to displace the lowest pendulum
SliderParams slider("Displacement force", &gDisplacementForce);
slider.m_minVal = 0.1;
slider.m_maxVal = 200;
@@ -175,8 +174,8 @@ void NewtonsRopeCradleExample::initPhysics()
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
slider);
}
{ // create a slider to apply the force by slider
{ // create a slider to apply the force by slider
SliderParams slider("Apply displacement force", &gForceScalar);
slider.m_minVal = -1;
slider.m_maxVal = 1;
@@ -193,29 +192,26 @@ void NewtonsRopeCradleExample::initPhysics()
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
if (m_dynamicsWorld->getDebugDrawer())
m_dynamicsWorld->getDebugDrawer()->setDebugMode(
btIDebugDraw::DBG_DrawWireframe
+ btIDebugDraw::DBG_DrawContactPoints
+ btIDebugDraw::DBG_DrawConstraints
+ btIDebugDraw::DBG_DrawConstraintLimits);
btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints + btIDebugDraw::DBG_DrawConstraints + btIDebugDraw::DBG_DrawConstraintLimits);
{ // create the pendula starting at the indicated position below and where each pendulum has the following mass
{ // create the pendula starting at the indicated position below and where each pendulum has the following mass
btScalar pendulumMass(1.0f);
btVector3 position(0.0f,15.0f,0.0f); // initial left-most pendulum position
btQuaternion orientation(0,0,0,1); // orientation of the pendula
btVector3 position(0.0f, 15.0f, 0.0f); // initial left-most pendulum position
btQuaternion orientation(0, 0, 0, 1); // orientation of the pendula
// Re-using the same collision is better for memory usage and performance
btSphereShape* pendulumShape = new btSphereShape(gSphereRadius);
m_collisionShapes.push_back(pendulumShape);
for (int i = 0; i < floor(gPendulaQty); i++) {
for (int i = 0; i < floor(gPendulaQty); i++)
{
// create pendulum
createRopePendulum(pendulumShape, position, orientation,gInitialPendulumWidth,
gInitialPendulumHeight, pendulumMass);
createRopePendulum(pendulumShape, position, orientation, gInitialPendulumWidth,
gInitialPendulumHeight, pendulumMass);
// displace the pendula 1.05 sphere size, so that they all nearly touch (small spacings in between)
position.setX(position.x()-2.1f * gSphereRadius);
position.setX(position.x() - 2.1f * gSphereRadius);
}
}
@@ -224,11 +220,11 @@ void NewtonsRopeCradleExample::initPhysics()
void NewtonsRopeCradleExample::connectWithRope(btRigidBody* body1, btRigidBody* body2)
{
btSoftBody* softBodyRope0 = btSoftBodyHelpers::CreateRope(softBodyWorldInfo,body1->getWorldTransform().getOrigin(),body2->getWorldTransform().getOrigin(),gRopeResolution,0);
btSoftBody* softBodyRope0 = btSoftBodyHelpers::CreateRope(softBodyWorldInfo, body1->getWorldTransform().getOrigin(), body2->getWorldTransform().getOrigin(), gRopeResolution, 0);
softBodyRope0->setTotalMass(0.1f);
softBodyRope0->appendAnchor(0,body1);
softBodyRope0->appendAnchor(softBodyRope0->m_nodes.size()-1,body2);
softBodyRope0->appendAnchor(0, body1);
softBodyRope0->appendAnchor(softBodyRope0->m_nodes.size() - 1, body2);
softBodyRope0->m_cfg.piterations = 5;
softBodyRope0->m_cfg.kDP = 0.005f;
@@ -239,18 +235,19 @@ void NewtonsRopeCradleExample::connectWithRope(btRigidBody* body1, btRigidBody*
getSoftDynamicsWorld()->addSoftBody(softBodyRope0);
}
void NewtonsRopeCradleExample::stepSimulation(float deltaTime) {
void NewtonsRopeCradleExample::stepSimulation(float deltaTime)
{
applyRForceWithForceScalar(gForceScalar); // apply force defined by apply force slider
applyRForceWithForceScalar(gForceScalar); // apply force defined by apply force slider
if (m_dynamicsWorld) {
if (m_dynamicsWorld)
{
m_dynamicsWorld->stepSimulation(deltaTime);
}
}
void NewtonsRopeCradleExample::createRopePendulum(btSphereShape* colShape,
const btVector3& position, const btQuaternion& pendulumOrientation, btScalar width, btScalar height, btScalar mass) {
const btVector3& position, const btQuaternion& pendulumOrientation, btScalar width, btScalar height, btScalar mass)
{
// The pendulum looks like this (names when built):
// O O topSphere1 topSphere2
// \ /
@@ -261,32 +258,31 @@ void NewtonsRopeCradleExample::createRopePendulum(btSphereShape* colShape,
startTransform.setIdentity();
// calculate sphere positions
btVector3 topSphere1RelPosition(0,0,width);
btVector3 topSphere2RelPosition(0,0,-width);
btVector3 bottomSphereRelPosition(0,-height,0);
btVector3 topSphere1RelPosition(0, 0, width);
btVector3 topSphere2RelPosition(0, 0, -width);
btVector3 bottomSphereRelPosition(0, -height, 0);
// position the top sphere above ground with appropriate orientation
startTransform.setOrigin(btVector3(0,0,0)); // no translation intitially
startTransform.setRotation(pendulumOrientation); // pendulum rotation
startTransform.setOrigin(startTransform * topSphere1RelPosition); // rotate this position
startTransform.setOrigin(position + startTransform.getOrigin()); // add non-rotated position to the relative position
btRigidBody* topSphere1 = createRigidBody(0, startTransform, colShape); // make top sphere static
startTransform.setOrigin(btVector3(0, 0, 0)); // no translation intitially
startTransform.setRotation(pendulumOrientation); // pendulum rotation
startTransform.setOrigin(startTransform * topSphere1RelPosition); // rotate this position
startTransform.setOrigin(position + startTransform.getOrigin()); // add non-rotated position to the relative position
btRigidBody* topSphere1 = createRigidBody(0, startTransform, colShape); // make top sphere static
// position the top sphere above ground with appropriate orientation
startTransform.setOrigin(btVector3(0,0,0)); // no translation intitially
startTransform.setRotation(pendulumOrientation); // pendulum rotation
startTransform.setOrigin(startTransform * topSphere2RelPosition); // rotate this position
startTransform.setOrigin(position + startTransform.getOrigin()); // add non-rotated position to the relative position
btRigidBody* topSphere2 = createRigidBody(0, startTransform, colShape); // make top sphere static
startTransform.setOrigin(btVector3(0, 0, 0)); // no translation intitially
startTransform.setRotation(pendulumOrientation); // pendulum rotation
startTransform.setOrigin(startTransform * topSphere2RelPosition); // rotate this position
startTransform.setOrigin(position + startTransform.getOrigin()); // add non-rotated position to the relative position
btRigidBody* topSphere2 = createRigidBody(0, startTransform, colShape); // make top sphere static
// position the bottom sphere below the top sphere
startTransform.setOrigin(btVector3(0,0,0)); // no translation intitially
startTransform.setRotation(pendulumOrientation); // pendulum rotation
startTransform.setOrigin(startTransform * bottomSphereRelPosition); // rotate this position
startTransform.setOrigin(position + startTransform.getOrigin()); // add non-rotated position to the relative position
startTransform.setOrigin(btVector3(0, 0, 0)); // no translation intitially
startTransform.setRotation(pendulumOrientation); // pendulum rotation
startTransform.setOrigin(startTransform * bottomSphereRelPosition); // rotate this position
startTransform.setOrigin(position + startTransform.getOrigin()); // add non-rotated position to the relative position
btRigidBody* bottomSphere = createRigidBody(mass, startTransform, colShape);
bottomSphere->setFriction(0); // we do not need friction here
bottomSphere->setFriction(0); // we do not need friction here
pendula.push_back(bottomSphere);
// disable the deactivation when objects do not move anymore
@@ -294,7 +290,7 @@ void NewtonsRopeCradleExample::createRopePendulum(btSphereShape* colShape,
topSphere2->setActivationState(DISABLE_DEACTIVATION);
bottomSphere->setActivationState(DISABLE_DEACTIVATION);
bottomSphere->setRestitution(gPendulaRestitution); // set pendula restitution
bottomSphere->setRestitution(gPendulaRestitution); // set pendula restitution
// add ropes between spheres
connectWithRope(topSphere1, bottomSphere);
@@ -306,44 +302,52 @@ void NewtonsRopeCradleExample::renderScene()
CommonRigidBodyBase::renderScene();
btSoftRigidDynamicsWorld* softWorld = getSoftDynamicsWorld();
for ( int i=0;i<softWorld->getSoftBodyArray().size();i++)
for (int i = 0; i < softWorld->getSoftBodyArray().size(); i++)
{
btSoftBody* psb = (btSoftBody*)softWorld->getSoftBodyArray()[i];
//if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe)))
{
btSoftBody* psb=(btSoftBody*)softWorld->getSoftBodyArray()[i];
//if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe)))
{
btSoftBodyHelpers::DrawFrame(psb,softWorld->getDebugDrawer());
btSoftBodyHelpers::Draw(psb,softWorld->getDebugDrawer(),softWorld->getDrawFlags());
}
btSoftBodyHelpers::DrawFrame(psb, softWorld->getDebugDrawer());
btSoftBodyHelpers::Draw(psb, softWorld->getDebugDrawer(), softWorld->getDrawFlags());
}
}
}
void NewtonsRopeCradleExample::changePendulaRestitution(btScalar restitution) {
void NewtonsRopeCradleExample::changePendulaRestitution(btScalar restitution)
{
for (std::vector<btRigidBody*>::iterator rit = pendula.begin();
rit != pendula.end(); rit++) {
rit != pendula.end(); rit++)
{
btAssert((*rit) && "Null constraint");
(*rit)->setRestitution(restitution);
}
}
bool NewtonsRopeCradleExample::keyboardCallback(int key, int state) {
bool NewtonsRopeCradleExample::keyboardCallback(int key, int state)
{
//b3Printf("Key pressed: %d in state %d \n",key,state);
// key 3
switch (key) {
case '3' /*ASCII for 3*/: {
applyPendulumForce(gDisplacementForce);
return true;
}
switch (key)
{
case '3' /*ASCII for 3*/:
{
applyPendulumForce(gDisplacementForce);
return true;
}
}
return false;
}
void NewtonsRopeCradleExample::applyPendulumForce(btScalar pendulumForce){
if(pendulumForce != 0){
b3Printf("Apply %f to pendulum",pendulumForce);
for (int i = 0; i < gDisplacedPendula; i++) {
void NewtonsRopeCradleExample::applyPendulumForce(btScalar pendulumForce)
{
if (pendulumForce != 0)
{
b3Printf("Apply %f to pendulum", pendulumForce);
for (int i = 0; i < gDisplacedPendula; i++)
{
if (gDisplacedPendula >= 0 && gDisplacedPendula <= gPendulaQty)
pendula[i]->applyCentralForce(btVector3(pendulumForce, 0, 0));
}
@@ -352,17 +356,21 @@ void NewtonsRopeCradleExample::applyPendulumForce(btScalar pendulumForce){
// GUI parameter modifiers
void onRopePendulaRestitutionChanged(float pendulaRestitution, void*) {
if (nex){
void onRopePendulaRestitutionChanged(float pendulaRestitution, void*)
{
if (nex)
{
nex->changePendulaRestitution(pendulaRestitution);
}
}
void applyRForceWithForceScalar(float forceScalar) {
if(nex){
void applyRForceWithForceScalar(float forceScalar)
{
if (nex)
{
btScalar appliedForce = forceScalar * gDisplacementForce;
if(fabs(gForceScalar) < 0.2f)
if (fabs(gForceScalar) < 0.2f)
gForceScalar = 0;
nex->applyPendulumForce(appliedForce);
@@ -370,7 +378,8 @@ void applyRForceWithForceScalar(float forceScalar) {
}
CommonExampleInterface* ET_NewtonsRopeCradleCreateFunc(
CommonExampleOptions& options) {
CommonExampleOptions& options)
{
nex = new NewtonsRopeCradleExample(options.m_guiHelper);
return nex;
}

View File

@@ -16,7 +16,6 @@ subject to the following restrictions:
#ifndef ET_NEWTONS_ROPE_CRADLE_EXAMPLE_H
#define ET_NEWTONS_ROPE_CRADLE_EXAMPLE_H
class CommonExampleInterface* ET_NewtonsRopeCradleCreateFunc(struct CommonExampleOptions& options);
class CommonExampleInterface* ET_NewtonsRopeCradleCreateFunc(struct CommonExampleOptions& options);
#endif //ET_NEWTONS_ROPE_CRADLE_EXAMPLE_H
#endif //ET_NEWTONS_ROPE_CRADLE_EXAMPLE_H

View File

@@ -13,13 +13,11 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#include "RigidBodyFromObj.h"
#include "btBulletDynamicsCommon.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "../CommonInterfaces/CommonRigidBodyBase.h"
#include "../Utils/b3ResourcePath.h"
@@ -27,17 +25,16 @@ subject to the following restrictions:
#include "../Importers/ImportObjDemo/LoadMeshFromObj.h"
#include "../OpenGLWindow/GLInstanceGraphicsShape.h"
struct RigidBodyFromObjExample : public CommonRigidBodyBase
{
int m_options;
int m_options;
RigidBodyFromObjExample(struct GUIHelperInterface* helper, int options)
:CommonRigidBodyBase(helper),
m_options(options)
: CommonRigidBodyBase(helper),
m_options(options)
{
}
virtual ~RigidBodyFromObjExample(){}
virtual ~RigidBodyFromObjExample() {}
virtual void initPhysics();
virtual void renderScene();
void resetCamera()
@@ -45,8 +42,8 @@ struct RigidBodyFromObjExample : public CommonRigidBodyBase
float dist = 11;
float pitch = -35;
float yaw = 52;
float targetPos[3]={0,0.46,0};
m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]);
float targetPos[3] = {0, 0.46, 0};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
};
@@ -55,111 +52,98 @@ void RigidBodyFromObjExample::initPhysics()
m_guiHelper->setUpAxis(1);
createEmptyDynamicsWorld();
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
//if (m_dynamicsWorld->getDebugDrawer())
// m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints);
///create a few basic rigid bodies
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0,-50,0));
groundTransform.setOrigin(btVector3(0, -50, 0));
{
btScalar mass(0.);
createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1));
createRigidBody(mass, groundTransform, groundShape, btVector4(0, 0, 1, 1));
}
//load our obj mesh
const char* fileName = "teddy.obj";//sphere8.obj";//sponza_closed.obj";//sphere8.obj";
char relativeFileName[1024];
if (b3ResourcePath::findResourcePath(fileName, relativeFileName, 1024))
{
const char* fileName = "teddy.obj"; //sphere8.obj";//sponza_closed.obj";//sphere8.obj";
char relativeFileName[1024];
if (b3ResourcePath::findResourcePath(fileName, relativeFileName, 1024))
{
char pathPrefix[1024];
b3FileUtils::extractPath(relativeFileName, pathPrefix, 1024);
}
GLInstanceGraphicsShape* glmesh = LoadMeshFromObj(relativeFileName, "");
printf("[INFO] Obj loaded: Extracted %d verticed from obj file [%s]\n", glmesh->m_numvertices, fileName);
const GLInstanceVertex& v = glmesh->m_vertices->at(0);
btConvexHullShape* shape = new btConvexHullShape((const btScalar*)(&(v.xyzw[0])), glmesh->m_numvertices, sizeof(GLInstanceVertex));
float scaling[4] = {0.1,0.1,0.1,1};
btVector3 localScaling(scaling[0],scaling[1],scaling[2]);
shape->setLocalScaling(localScaling);
if (m_options & OptimizeConvexObj)
{
shape->optimizeConvexHull();
}
float scaling[4] = {0.1, 0.1, 0.1, 1};
btVector3 localScaling(scaling[0], scaling[1], scaling[2]);
shape->setLocalScaling(localScaling);
if (m_options & OptimizeConvexObj)
{
shape->optimizeConvexHull();
}
if (m_options & ComputePolyhedralFeatures)
{
shape->initializePolyhedralFeatures();
}
if (m_options & ComputePolyhedralFeatures)
{
shape->initializePolyhedralFeatures();
}
//shape->setMargin(0.001);
m_collisionShapes.push_back(shape);
btTransform startTransform;
startTransform.setIdentity();
btScalar mass(1.f);
btScalar mass(1.f);
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0,0,0);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
shape->calculateLocalInertia(mass,localInertia);
shape->calculateLocalInertia(mass, localInertia);
float color[4] = {1,1,1,1};
float orn[4] = {0,0,0,1};
float pos[4] = {0,3,0,0};
btVector3 position(pos[0],pos[1],pos[2]);
float color[4] = {1, 1, 1, 1};
float orn[4] = {0, 0, 0, 1};
float pos[4] = {0, 3, 0, 0};
btVector3 position(pos[0], pos[1], pos[2]);
startTransform.setOrigin(position);
btRigidBody* body = createRigidBody(mass,startTransform,shape);
btRigidBody* body = createRigidBody(mass, startTransform, shape);
bool useConvexHullForRendering = ((m_options & ObjUseConvexHullForRendering) != 0);
bool useConvexHullForRendering = ((m_options & ObjUseConvexHullForRendering)!=0);
if (!useConvexHullForRendering)
{
int shapeId = m_guiHelper->registerGraphicsShape(&glmesh->m_vertices->at(0).xyzw[0],
glmesh->m_numvertices,
&glmesh->m_indices->at(0),
glmesh->m_numIndices,
B3_GL_TRIANGLES, -1);
{
int shapeId = m_guiHelper->registerGraphicsShape(&glmesh->m_vertices->at(0).xyzw[0],
glmesh->m_numvertices,
&glmesh->m_indices->at(0),
glmesh->m_numIndices,
B3_GL_TRIANGLES, -1);
shape->setUserIndex(shapeId);
int renderInstance = m_guiHelper->registerGraphicsInstance(shapeId,pos,orn,color,scaling);
int renderInstance = m_guiHelper->registerGraphicsInstance(shapeId, pos, orn, color, scaling);
body->setUserIndex(renderInstance);
}
}
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void RigidBodyFromObjExample::renderScene()
{
CommonRigidBodyBase::renderScene();
CommonRigidBodyBase::renderScene();
}
CommonExampleInterface* ET_RigidBodyFromObjCreateFunc(CommonExampleOptions& options)
CommonExampleInterface* ET_RigidBodyFromObjCreateFunc(CommonExampleOptions& options)
{
return new RigidBodyFromObjExample(options.m_guiHelper,options.m_option);
return new RigidBodyFromObjExample(options.m_guiHelper, options.m_option);
}
B3_STANDALONE_EXAMPLE(ET_RigidBodyFromObjCreateFunc)

View File

@@ -18,11 +18,10 @@ subject to the following restrictions:
enum ObjToRigidBodyOptionsEnum
{
ObjUseConvexHullForRendering=1,
OptimizeConvexObj=2,
ComputePolyhedralFeatures=4,
ObjUseConvexHullForRendering = 1,
OptimizeConvexObj = 2,
ComputePolyhedralFeatures = 4,
};
class CommonExampleInterface* ET_RigidBodyFromObjCreateFunc(struct CommonExampleOptions& options);
class CommonExampleInterface* ET_RigidBodyFromObjCreateFunc(struct CommonExampleOptions& options);
#endif //ET_RIGIDBODYFROMOBJ_EXAMPLE_H
#endif //ET_RIGIDBODYFROMOBJ_EXAMPLE_H

View File

@@ -13,23 +13,20 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#include "SimpleBox.h"
#include "btBulletDynamicsCommon.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "../CommonInterfaces/CommonRigidBodyBase.h"
struct SimpleBoxExample : public CommonRigidBodyBase
{
SimpleBoxExample(struct GUIHelperInterface* helper)
:CommonRigidBodyBase(helper)
: CommonRigidBodyBase(helper)
{
}
virtual ~SimpleBoxExample(){}
virtual ~SimpleBoxExample() {}
virtual void initPhysics();
virtual void renderScene();
void resetCamera()
@@ -37,8 +34,8 @@ struct SimpleBoxExample : public CommonRigidBodyBase
float dist = 41;
float pitch = -35;
float yaw = 52;
float targetPos[3]={0,0.46,0};
m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]);
float targetPos[3] = {0, 0.46, 0};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
};
@@ -47,72 +44,60 @@ void SimpleBoxExample::initPhysics()
m_guiHelper->setUpAxis(1);
createEmptyDynamicsWorld();
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
if (m_dynamicsWorld->getDebugDrawer())
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints);
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints);
///create a few basic rigid bodies
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0,-50,0));
groundTransform.setOrigin(btVector3(0, -50, 0));
{
btScalar mass(0.);
createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1));
createRigidBody(mass, groundTransform, groundShape, btVector4(0, 0, 1, 1));
}
{
//create a few dynamic rigidbodies
// Re-using the same collision is better for memory usage and performance
btBoxShape* colShape = createBoxShape(btVector3(1,1,1));
btBoxShape* colShape = createBoxShape(btVector3(1, 1, 1));
m_collisionShapes.push_back(colShape);
/// Create Dynamic Objects
btTransform startTransform;
startTransform.setIdentity();
btScalar mass(1.f);
btScalar mass(1.f);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0,0,0);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
colShape->calculateLocalInertia(mass,localInertia);
colShape->calculateLocalInertia(mass, localInertia);
startTransform.setOrigin(btVector3(
btScalar(0),
btScalar(20),
btScalar(0)));
createRigidBody(mass,startTransform,colShape);
btScalar(0),
btScalar(20),
btScalar(0)));
createRigidBody(mass, startTransform, colShape);
}
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void SimpleBoxExample::renderScene()
{
CommonRigidBodyBase::renderScene();
CommonRigidBodyBase::renderScene();
}
CommonExampleInterface* ET_SimpleBoxCreateFunc(CommonExampleOptions& options)
CommonExampleInterface* ET_SimpleBoxCreateFunc(CommonExampleOptions& options)
{
return new SimpleBoxExample(options.m_guiHelper);
}

View File

@@ -16,7 +16,6 @@ subject to the following restrictions:
#ifndef ET_SIMPLE_BOX_EXAMPLE_H
#define ET_SIMPLE_BOX_EXAMPLE_H
class CommonExampleInterface* ET_SimpleBoxCreateFunc(struct CommonExampleOptions& options);
class CommonExampleInterface* ET_SimpleBoxCreateFunc(struct CommonExampleOptions& options);
#endif //ET_SIMPLE_BOX_EXAMPLE_H
#endif //ET_SIMPLE_BOX_EXAMPLE_H

View File

@@ -13,13 +13,11 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#include "SimpleCloth.h"
#include "btBulletDynamicsCommon.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "../CommonInterfaces/CommonRigidBodyBase.h"
#include "BulletSoftBody/btSoftRigidDynamicsWorld.h"
@@ -29,21 +27,21 @@ subject to the following restrictions:
struct SimpleClothExample : public CommonRigidBodyBase
{
SimpleClothExample(struct GUIHelperInterface* helper)
:CommonRigidBodyBase(helper)
: CommonRigidBodyBase(helper)
{
}
virtual ~SimpleClothExample(){}
virtual ~SimpleClothExample() {}
virtual void initPhysics();
virtual void renderScene();
void createEmptyDynamicsWorld()
{
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase();
m_solver = new btSequentialImpulseConstraintSolver;
m_solver = new btSequentialImpulseConstraintSolver;
m_dynamicsWorld = new btSoftRigidDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration);
m_dynamicsWorld->setGravity(btVector3(0, -10, 0));
@@ -52,22 +50,22 @@ struct SimpleClothExample : public CommonRigidBodyBase
softBodyWorldInfo.m_gravity = m_dynamicsWorld->getGravity();
softBodyWorldInfo.m_sparsesdf.Initialize();
}
virtual btSoftRigidDynamicsWorld* getSoftDynamicsWorld()
virtual btSoftRigidDynamicsWorld* getSoftDynamicsWorld()
{
///just make it a btSoftRigidDynamicsWorld please
///or we will add type checking
return (btSoftRigidDynamicsWorld*) m_dynamicsWorld;
return (btSoftRigidDynamicsWorld*)m_dynamicsWorld;
}
void resetCamera()
{
float dist = 41;
float pitch = -35;
float yaw = 52;
float targetPos[3]={0,0.46,0};
m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]);
float targetPos[3] = {0, 0.46, 0};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
void createSoftBody(const btScalar size, const int num_x, const int num_z, const int fixed=1+2);
void createSoftBody(const btScalar size, const int num_x, const int num_z, const int fixed = 1 + 2);
btSoftBodyWorldInfo softBodyWorldInfo;
};
@@ -76,30 +74,29 @@ void SimpleClothExample::initPhysics()
m_guiHelper->setUpAxis(1);
createEmptyDynamicsWorld();
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
if (m_dynamicsWorld->getDebugDrawer())
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints);
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints);
///create a few basic rigid bodies
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0,-50,0));
groundTransform.setOrigin(btVector3(0, -50, 0));
{
btScalar mass(0.);
createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1));
createRigidBody(mass, groundTransform, groundShape, btVector4(0, 0, 1, 1));
}
{
const btScalar s=4; //size of cloth patch
const int NUM_X=31; //vertices on X axis
const int NUM_Z=31; //vertices on Z axis
createSoftBody(s,NUM_X, NUM_Z);
const btScalar s = 4; //size of cloth patch
const int NUM_X = 31; //vertices on X axis
const int NUM_Z = 31; //vertices on Z axis
createSoftBody(s, NUM_X, NUM_Z);
}
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
@@ -107,57 +104,45 @@ void SimpleClothExample::initPhysics()
void SimpleClothExample::createSoftBody(const btScalar s,
const int numX,
const int numY,
const int fixed) {
btSoftBody* cloth=btSoftBodyHelpers::CreatePatch(softBodyWorldInfo,
btVector3(-s/2,s+1,0),
btVector3(+s/2,s+1,0),
btVector3(-s/2,s+1,+s),
btVector3(+s/2,s+1,+s),
numX,numY,
fixed,true);
const int numY,
const int fixed)
{
btSoftBody* cloth = btSoftBodyHelpers::CreatePatch(softBodyWorldInfo,
btVector3(-s / 2, s + 1, 0),
btVector3(+s / 2, s + 1, 0),
btVector3(-s / 2, s + 1, +s),
btVector3(+s / 2, s + 1, +s),
numX, numY,
fixed, true);
cloth->getCollisionShape()->setMargin(0.001f);
cloth->getCollisionShape()->setUserPointer((void*)cloth);
cloth->generateBendingConstraints(2,cloth->appendMaterial());
cloth->setTotalMass(10);
cloth->getCollisionShape()->setUserPointer((void*)cloth);
cloth->generateBendingConstraints(2, cloth->appendMaterial());
cloth->setTotalMass(10);
//cloth->m_cfg.citerations = 10;
// cloth->m_cfg.diterations = 10;
// cloth->m_cfg.diterations = 10;
cloth->m_cfg.piterations = 5;
cloth->m_cfg.kDP = 0.005f;
getSoftDynamicsWorld()->addSoftBody(cloth);
}
void SimpleClothExample::renderScene()
{
CommonRigidBodyBase::renderScene();
CommonRigidBodyBase::renderScene();
btSoftRigidDynamicsWorld* softWorld = getSoftDynamicsWorld();
for ( int i=0;i<softWorld->getSoftBodyArray().size();i++)
for (int i = 0; i < softWorld->getSoftBodyArray().size(); i++)
{
btSoftBody* psb = (btSoftBody*)softWorld->getSoftBodyArray()[i];
//if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe)))
{
btSoftBody* psb=(btSoftBody*)softWorld->getSoftBodyArray()[i];
//if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe)))
{
btSoftBodyHelpers::DrawFrame(psb,softWorld->getDebugDrawer());
btSoftBodyHelpers::Draw(psb,softWorld->getDebugDrawer(),softWorld->getDrawFlags());
}
btSoftBodyHelpers::DrawFrame(psb, softWorld->getDebugDrawer());
btSoftBodyHelpers::Draw(psb, softWorld->getDebugDrawer(), softWorld->getDrawFlags());
}
}
}
CommonExampleInterface* ET_SimpleClothCreateFunc(CommonExampleOptions& options)
CommonExampleInterface* ET_SimpleClothCreateFunc(CommonExampleOptions& options)
{
return new SimpleClothExample(options.m_guiHelper);
}

View File

@@ -16,7 +16,6 @@ subject to the following restrictions:
#ifndef ET_SIMPLE_CLOTH_EXAMPLE_H
#define ET_SIMPLE_CLOTH_EXAMPLE_H
class CommonExampleInterface* ET_SimpleClothCreateFunc(struct CommonExampleOptions& options);
class CommonExampleInterface* ET_SimpleClothCreateFunc(struct CommonExampleOptions& options);
#endif //ET_SIMPLE_CLOTH_EXAMPLE_H
#endif //ET_SIMPLE_CLOTH_EXAMPLE_H

Some files were not shown because too many files have changed in this diff Show More