Start re-organizing demos so the physics setup can be shared easier (explicit create graphics objects, init/exit physics etc)
Add B3G_RETURN key code, only implemented in Windows so far (todo: Mac, Linux) Fix Windows key management (use WM_CHAR event instead of WM_KEYUP Add Return (OnKeyReturn) key support TreeNode, so we can select an item using the return key.
This commit is contained in:
@@ -123,8 +123,8 @@ void BasicDemo::initPhysics()
|
|||||||
setShadows(true);
|
setShadows(true);
|
||||||
|
|
||||||
setCameraDistance(btScalar(SCALING*50.));
|
setCameraDistance(btScalar(SCALING*50.));
|
||||||
|
GraphicsPhysicsBridge gfxBridge;
|
||||||
m_physicsSetup.initPhysics();
|
m_physicsSetup.initPhysics(gfxBridge);
|
||||||
|
|
||||||
m_dynamicsWorld = m_physicsSetup.m_dynamicsWorld;
|
m_dynamicsWorld = m_physicsSetup.m_dynamicsWorld;
|
||||||
m_dynamicsWorld->setDebugDrawer(&gDebugDraw);
|
m_dynamicsWorld->setDebugDrawer(&gDebugDraw);
|
||||||
|
|||||||
@@ -6,28 +6,15 @@
|
|||||||
#define ARRAY_SIZE_X 5
|
#define ARRAY_SIZE_X 5
|
||||||
#define ARRAY_SIZE_Z 5
|
#define ARRAY_SIZE_Z 5
|
||||||
|
|
||||||
void BasicDemoPhysicsSetup::initPhysics()
|
void BasicDemoPhysicsSetup::initPhysics(GraphicsPhysicsBridge& gfxBridge)
|
||||||
{
|
{
|
||||||
///collision configuration contains default setup for memory, collision setup
|
createEmptyDynamicsWorld();
|
||||||
m_collisionConfiguration = new btDefaultCollisionConfiguration();
|
|
||||||
//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_broadphase = new btDbvtBroadphase();
|
|
||||||
|
|
||||||
///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
|
|
||||||
btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver;
|
|
||||||
m_solver = sol;
|
|
||||||
|
|
||||||
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
|
|
||||||
|
|
||||||
|
|
||||||
m_dynamicsWorld->setGravity(btVector3(0,-10,0));
|
|
||||||
|
|
||||||
///create a few basic rigid bodies
|
///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.)));
|
||||||
|
gfxBridge.createCollisionShapeGraphicsObject(groundShape);
|
||||||
|
|
||||||
//groundShape->initializePolyhedralFeatures();
|
//groundShape->initializePolyhedralFeatures();
|
||||||
// btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50);
|
// btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50);
|
||||||
|
|
||||||
@@ -39,7 +26,8 @@ void BasicDemoPhysicsSetup::initPhysics()
|
|||||||
|
|
||||||
{
|
{
|
||||||
btScalar mass(0.);
|
btScalar mass(0.);
|
||||||
createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1));
|
btRigidBody* body = createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1));
|
||||||
|
gfxBridge.createRigidBodyGraphicsObject(body, btVector3(0, 1, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -48,6 +36,8 @@ void BasicDemoPhysicsSetup::initPhysics()
|
|||||||
// Re-using the same collision is better for memory usage and performance
|
// 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));
|
||||||
|
gfxBridge.createCollisionShapeGraphicsObject(colShape);
|
||||||
|
|
||||||
//btCollisionShape* colShape = new btSphereShape(btScalar(1.));
|
//btCollisionShape* colShape = new btSphereShape(btScalar(1.));
|
||||||
m_collisionShapes.push_back(colShape);
|
m_collisionShapes.push_back(colShape);
|
||||||
|
|
||||||
@@ -77,7 +67,9 @@ void BasicDemoPhysicsSetup::initPhysics()
|
|||||||
btScalar(2.0*j)));
|
btScalar(2.0*j)));
|
||||||
|
|
||||||
|
|
||||||
createRigidBody(mass,startTransform,colShape);
|
btRigidBody* body = createRigidBody(mass,startTransform,colShape);
|
||||||
|
gfxBridge.createRigidBodyGraphicsObject(body, btVector3(1, 1, 0));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,84 +80,10 @@ void BasicDemoPhysicsSetup::initPhysics()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void BasicDemoPhysicsSetup::stepSimulation(float deltaTime)
|
|
||||||
{
|
|
||||||
m_dynamicsWorld->stepSimulation(deltaTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
btBoxShape* BasicDemoPhysicsSetup::createBoxShape(const btVector3& halfExtents)
|
|
||||||
{
|
|
||||||
btBoxShape* box = new btBoxShape(halfExtents);
|
|
||||||
return box;
|
|
||||||
}
|
|
||||||
|
|
||||||
btRigidBody* BasicDemoPhysicsSetup::createRigidBody(float mass, const btTransform& startTransform,btCollisionShape* shape, const btVector4& color)
|
|
||||||
{
|
|
||||||
btAssert((!shape || shape->getShapeType() != INVALID_SHAPE_PROXYTYPE));
|
|
||||||
|
|
||||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
|
||||||
bool isDynamic = (mass != 0.f);
|
|
||||||
|
|
||||||
btVector3 localInertia(0,0,0);
|
|
||||||
if (isDynamic)
|
|
||||||
shape->calculateLocalInertia(mass,localInertia);
|
|
||||||
|
|
||||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
|
||||||
|
|
||||||
#define USE_MOTIONSTATE 1
|
|
||||||
#ifdef USE_MOTIONSTATE
|
|
||||||
btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
|
|
||||||
|
|
||||||
btRigidBody::btRigidBodyConstructionInfo cInfo(mass,myMotionState,shape,localInertia);
|
|
||||||
|
|
||||||
btRigidBody* body = new btRigidBody(cInfo);
|
|
||||||
//body->setContactProcessingThreshold(m_defaultContactProcessingThreshold);
|
|
||||||
|
|
||||||
#else
|
|
||||||
btRigidBody* body = new btRigidBody(mass,0,shape,localInertia);
|
|
||||||
body->setWorldTransform(startTransform);
|
|
||||||
#endif//
|
|
||||||
|
|
||||||
body->setUserIndex(-1);
|
|
||||||
m_dynamicsWorld->addRigidBody(body);
|
|
||||||
return body;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void BasicDemoPhysicsSetup::exitPhysics()
|
|
||||||
{
|
|
||||||
//cleanup in the reverse order of creation/initialization
|
|
||||||
|
|
||||||
//remove the rigidbodies from the dynamics world and delete them
|
|
||||||
int i;
|
|
||||||
for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--)
|
|
||||||
{
|
|
||||||
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
|
|
||||||
btRigidBody* body = btRigidBody::upcast(obj);
|
|
||||||
if (body && body->getMotionState())
|
|
||||||
{
|
|
||||||
delete body->getMotionState();
|
|
||||||
}
|
|
||||||
m_dynamicsWorld->removeCollisionObject( obj );
|
|
||||||
delete obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
//delete collision shapes
|
|
||||||
for (int j=0;j<m_collisionShapes.size();j++)
|
|
||||||
{
|
|
||||||
btCollisionShape* shape = m_collisionShapes[j];
|
|
||||||
delete shape;
|
|
||||||
}
|
|
||||||
m_collisionShapes.clear();
|
|
||||||
|
|
||||||
delete m_dynamicsWorld;
|
|
||||||
|
|
||||||
delete m_solver;
|
|
||||||
|
|
||||||
delete m_broadphase;
|
|
||||||
|
|
||||||
delete m_dispatcher;
|
|
||||||
|
|
||||||
delete m_collisionConfiguration;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -16,79 +16,12 @@ class btBoxShape;
|
|||||||
#include "LinearMath/btAlignedObjectArray.h"
|
#include "LinearMath/btAlignedObjectArray.h"
|
||||||
|
|
||||||
|
|
||||||
struct BasicDemoPhysicsSetup
|
#include "../CommonRigidBodySetup.h"
|
||||||
|
|
||||||
|
struct BasicDemoPhysicsSetup : public CommonRigidBodySetup
|
||||||
{
|
{
|
||||||
//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;
|
|
||||||
|
|
||||||
virtual void initPhysics();
|
virtual void initPhysics(GraphicsPhysicsBridge& gfxBridge);
|
||||||
|
|
||||||
virtual void exitPhysics();
|
|
||||||
|
|
||||||
virtual void stepSimulation(float deltaTime);
|
|
||||||
|
|
||||||
virtual btRigidBody* createRigidBody(float mass, const btTransform& startTransform,btCollisionShape* shape, const btVector4& color=btVector4(1,0,0,1));
|
|
||||||
|
|
||||||
virtual btBoxShape* createBoxShape(const btVector3& halfExtents);
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
//bodies
|
|
||||||
virtual btRigidBody* createRigidBody(bool isDynamic, btScalar mass, const btTransform& startTransform, btCollisionShape* shape,const char* bodyName);
|
|
||||||
virtual btCollisionObject* createCollisionObject( const btTransform& startTransform, btCollisionShape* shape,const char* bodyName);
|
|
||||||
|
|
||||||
///shapes
|
|
||||||
|
|
||||||
virtual btCollisionShape* createPlaneShape(const btVector3& planeNormal,btScalar planeConstant);
|
|
||||||
|
|
||||||
virtual btCollisionShape* createSphereShape(btScalar radius);
|
|
||||||
virtual btCollisionShape* createCapsuleShapeX(btScalar radius, btScalar height);
|
|
||||||
virtual btCollisionShape* createCapsuleShapeY(btScalar radius, btScalar height);
|
|
||||||
virtual btCollisionShape* createCapsuleShapeZ(btScalar radius, btScalar height);
|
|
||||||
|
|
||||||
virtual btCollisionShape* createCylinderShapeX(btScalar radius,btScalar height);
|
|
||||||
virtual btCollisionShape* createCylinderShapeY(btScalar radius,btScalar height);
|
|
||||||
virtual btCollisionShape* createCylinderShapeZ(btScalar radius,btScalar height);
|
|
||||||
virtual btCollisionShape* createConeShapeX(btScalar radius,btScalar height);
|
|
||||||
virtual btCollisionShape* createConeShapeY(btScalar radius,btScalar height);
|
|
||||||
virtual btCollisionShape* createConeShapeZ(btScalar radius,btScalar height);
|
|
||||||
virtual class btTriangleIndexVertexArray* createTriangleMeshContainer();
|
|
||||||
virtual btBvhTriangleMeshShape* createBvhTriangleMeshShape(btStridingMeshInterface* trimesh, btOptimizedBvh* bvh);
|
|
||||||
virtual btCollisionShape* createConvexTriangleMeshShape(btStridingMeshInterface* trimesh);
|
|
||||||
virtual btGImpactMeshShape* createGimpactShape(btStridingMeshInterface* trimesh);
|
|
||||||
virtual btStridingMeshInterfaceData* createStridingMeshInterfaceData(btStridingMeshInterfaceData* interfaceData);
|
|
||||||
|
|
||||||
virtual class btConvexHullShape* createConvexHullShape();
|
|
||||||
virtual class btCompoundShape* createCompoundShape();
|
|
||||||
virtual class btScaledBvhTriangleMeshShape* createScaledTrangleMeshShape(btBvhTriangleMeshShape* meshShape,const btVector3& localScalingbtBvhTriangleMeshShape);
|
|
||||||
|
|
||||||
virtual class btMultiSphereShape* createMultiSphereShape(const btVector3* positions,const btScalar* radi,int numSpheres);
|
|
||||||
|
|
||||||
virtual btTriangleIndexVertexArray* createMeshInterface(btStridingMeshInterfaceData& meshData);
|
|
||||||
|
|
||||||
///acceleration and connectivity structures
|
|
||||||
virtual btOptimizedBvh* createOptimizedBvh();
|
|
||||||
virtual btTriangleInfoMap* createTriangleInfoMap();
|
|
||||||
|
|
||||||
///constraints
|
|
||||||
virtual btPoint2PointConstraint* createPoint2PointConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB);
|
|
||||||
virtual btPoint2PointConstraint* createPoint2PointConstraint(btRigidBody& rbA,const btVector3& pivotInA);
|
|
||||||
virtual btHingeConstraint* createHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA=false);
|
|
||||||
virtual btHingeConstraint* createHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame, bool useReferenceFrameA=false);
|
|
||||||
virtual btConeTwistConstraint* createConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB,const btTransform& rbAFrame, const btTransform& rbBFrame);
|
|
||||||
virtual btConeTwistConstraint* createConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame);
|
|
||||||
virtual btGeneric6DofConstraint* createGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA);
|
|
||||||
virtual btGeneric6DofConstraint* createGeneric6DofConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB);
|
|
||||||
virtual btGeneric6DofSpringConstraint* createGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA);
|
|
||||||
virtual btSliderConstraint* createSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA);
|
|
||||||
virtual btSliderConstraint* createSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameA);
|
|
||||||
virtual btGearConstraint* createGearConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& axisInA,const btVector3& axisInB, btScalar ratio);
|
|
||||||
*/
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -25,12 +25,17 @@ IF (WIN32)
|
|||||||
ADD_EXECUTABLE(AppCcdPhysicsDemo
|
ADD_EXECUTABLE(AppCcdPhysicsDemo
|
||||||
main.cpp
|
main.cpp
|
||||||
CcdPhysicsDemo.cpp
|
CcdPhysicsDemo.cpp
|
||||||
|
CcdPhysicsSetup.h
|
||||||
|
CcdPhysicsSetup.cpp
|
||||||
${BULLET_PHYSICS_SOURCE_DIR}/build3/bullet.rc
|
${BULLET_PHYSICS_SOURCE_DIR}/build3/bullet.rc
|
||||||
)
|
)
|
||||||
ELSE()
|
ELSE()
|
||||||
ADD_EXECUTABLE(AppCcdPhysicsDemo
|
ADD_EXECUTABLE(AppCcdPhysicsDemo
|
||||||
main.cpp
|
main.cpp
|
||||||
CcdPhysicsDemo.cpp
|
CcdPhysicsDemo.cpp
|
||||||
|
CcdPhysicsSetup.h
|
||||||
|
CcdPhysicsSetup.cpp
|
||||||
|
|
||||||
)
|
)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
|||||||
@@ -167,26 +167,11 @@ void CcdPhysicsDemo::initPhysics()
|
|||||||
m_ShootBoxInitialSpeed = 4000.f;
|
m_ShootBoxInitialSpeed = 4000.f;
|
||||||
|
|
||||||
m_defaultContactProcessingThreshold = 0.f;
|
m_defaultContactProcessingThreshold = 0.f;
|
||||||
|
GraphicsPhysicsBridge bridge;
|
||||||
///collision configuration contains default setup for memory, collision setup
|
m_physicsSetup.initPhysics(bridge);
|
||||||
m_collisionConfiguration = new btDefaultCollisionConfiguration();
|
m_dynamicsWorld = m_physicsSetup.m_dynamicsWorld;
|
||||||
// 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->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE,BOX_SHAPE_PROXYTYPE,m_collisionConfiguration->getCollisionAlgorithmCreateFunc(CONVEX_SHAPE_PROXYTYPE,CONVEX_SHAPE_PROXYTYPE));
|
|
||||||
|
|
||||||
m_broadphase = new btDbvtBroadphase();
|
|
||||||
|
|
||||||
///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
|
|
||||||
btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver;
|
|
||||||
m_solver = sol;
|
|
||||||
|
|
||||||
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
|
|
||||||
m_dynamicsWorld->getSolverInfo().m_solverMode |=SOLVER_USE_2_FRICTION_DIRECTIONS|SOLVER_RANDMIZE_ORDER;
|
m_dynamicsWorld->getSolverInfo().m_solverMode |=SOLVER_USE_2_FRICTION_DIRECTIONS|SOLVER_RANDMIZE_ORDER;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
m_dynamicsWorld ->setDebugDrawer(&sDebugDrawer);
|
m_dynamicsWorld ->setDebugDrawer(&sDebugDrawer);
|
||||||
|
|
||||||
//m_dynamicsWorld->getSolverInfo().m_splitImpulse=false;
|
//m_dynamicsWorld->getSolverInfo().m_splitImpulse=false;
|
||||||
@@ -203,108 +188,6 @@ void CcdPhysicsDemo::initPhysics()
|
|||||||
|
|
||||||
m_dynamicsWorld->setGravity(btVector3(0,-10,0));
|
m_dynamicsWorld->setGravity(btVector3(0,-10,0));
|
||||||
|
|
||||||
///create a few basic rigid bodies
|
|
||||||
btBoxShape* box = new btBoxShape(btVector3(btScalar(110.),btScalar(1.),btScalar(110.)));
|
|
||||||
// box->initializePolyhedralFeatures();
|
|
||||||
btCollisionShape* groundShape = box;
|
|
||||||
|
|
||||||
// btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50);
|
|
||||||
|
|
||||||
m_collisionShapes.push_back(groundShape);
|
|
||||||
//m_collisionShapes.push_back(new btCylinderShape (btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS)));
|
|
||||||
m_collisionShapes.push_back(new btBoxShape (btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS)));
|
|
||||||
|
|
||||||
btTransform groundTransform;
|
|
||||||
groundTransform.setIdentity();
|
|
||||||
//groundTransform.setOrigin(btVector3(5,5,5));
|
|
||||||
|
|
||||||
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
|
|
||||||
{
|
|
||||||
btScalar mass(0.);
|
|
||||||
|
|
||||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
|
||||||
bool isDynamic = (mass != 0.f);
|
|
||||||
|
|
||||||
btVector3 localInertia(0,0,0);
|
|
||||||
if (isDynamic)
|
|
||||||
groundShape->calculateLocalInertia(mass,localInertia);
|
|
||||||
|
|
||||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
|
||||||
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
|
|
||||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia);
|
|
||||||
btRigidBody* body = new btRigidBody(rbInfo);
|
|
||||||
body->setFriction(0.5);
|
|
||||||
//body->setRollingFriction(0.3);
|
|
||||||
//add the body to the dynamics world
|
|
||||||
m_dynamicsWorld->addRigidBody(body);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
//create a few dynamic rigidbodies
|
|
||||||
// Re-using the same collision is better for memory usage and performance
|
|
||||||
|
|
||||||
btCollisionShape* colShape = new btBoxShape(btVector3(1,1,1));
|
|
||||||
|
|
||||||
//btCollisionShape* colShape = new btSphereShape(btScalar(1.));
|
|
||||||
m_collisionShapes.push_back(colShape);
|
|
||||||
|
|
||||||
/// Create Dynamic Objects
|
|
||||||
btTransform startTransform;
|
|
||||||
startTransform.setIdentity();
|
|
||||||
|
|
||||||
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);
|
|
||||||
if (isDynamic)
|
|
||||||
colShape->calculateLocalInertia(mass,localInertia);
|
|
||||||
|
|
||||||
int gNumObjects = 120;//120;
|
|
||||||
int i;
|
|
||||||
for (i=0;i<gNumObjects;i++)
|
|
||||||
{
|
|
||||||
btCollisionShape* shape = m_collisionShapes[1];
|
|
||||||
|
|
||||||
btTransform trans;
|
|
||||||
trans.setIdentity();
|
|
||||||
|
|
||||||
//stack them
|
|
||||||
int colsize = 10;
|
|
||||||
int row = (i*CUBE_HALF_EXTENTS*2)/(colsize*2*CUBE_HALF_EXTENTS);
|
|
||||||
int row2 = row;
|
|
||||||
int col = (i)%(colsize)-colsize/2;
|
|
||||||
|
|
||||||
|
|
||||||
if (col>3)
|
|
||||||
{
|
|
||||||
col=11;
|
|
||||||
row2 |=1;
|
|
||||||
}
|
|
||||||
|
|
||||||
btVector3 pos(col*2*CUBE_HALF_EXTENTS + (row2%2)*CUBE_HALF_EXTENTS,
|
|
||||||
row*2*CUBE_HALF_EXTENTS+CUBE_HALF_EXTENTS+EXTRA_HEIGHT,0);
|
|
||||||
|
|
||||||
trans.setOrigin(pos);
|
|
||||||
|
|
||||||
float mass = 1.f;
|
|
||||||
|
|
||||||
btRigidBody* body = localCreateRigidBody(mass,trans,shape);
|
|
||||||
body->setAnisotropicFriction(shape->getAnisotropicRollingFrictionDirection(),btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
|
|
||||||
body->setFriction(0.5);
|
|
||||||
|
|
||||||
//body->setRollingFriction(.3);
|
|
||||||
///when using m_ccdMode
|
|
||||||
if (m_ccdMode==USE_CCD)
|
|
||||||
{
|
|
||||||
body->setCcdMotionThreshold(CUBE_HALF_EXTENTS);
|
|
||||||
body->setCcdSweptSphereRadius(0.9*CUBE_HALF_EXTENTS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CcdPhysicsDemo::clientResetScene()
|
void CcdPhysicsDemo::clientResetScene()
|
||||||
@@ -381,40 +264,8 @@ void CcdPhysicsDemo::shootBox(const btVector3& destination)
|
|||||||
|
|
||||||
void CcdPhysicsDemo::exitPhysics()
|
void CcdPhysicsDemo::exitPhysics()
|
||||||
{
|
{
|
||||||
|
m_physicsSetup.exitPhysics();
|
||||||
|
|
||||||
//cleanup in the reverse order of creation/initialization
|
|
||||||
|
|
||||||
//remove the rigidbodies from the dynamics world and delete them
|
|
||||||
int i;
|
|
||||||
for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--)
|
|
||||||
{
|
|
||||||
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
|
|
||||||
btRigidBody* body = btRigidBody::upcast(obj);
|
|
||||||
if (body && body->getMotionState())
|
|
||||||
{
|
|
||||||
delete body->getMotionState();
|
|
||||||
}
|
|
||||||
m_dynamicsWorld->removeCollisionObject( obj );
|
|
||||||
delete obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
//delete collision shapes
|
|
||||||
for (int j=0;j<m_collisionShapes.size();j++)
|
|
||||||
{
|
|
||||||
btCollisionShape* shape = m_collisionShapes[j];
|
|
||||||
delete shape;
|
|
||||||
}
|
|
||||||
m_collisionShapes.clear();
|
|
||||||
|
|
||||||
delete m_dynamicsWorld;
|
|
||||||
|
|
||||||
delete m_solver;
|
|
||||||
|
|
||||||
delete m_broadphase;
|
|
||||||
|
|
||||||
delete m_dispatcher;
|
|
||||||
|
|
||||||
delete m_collisionConfiguration;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,19 +33,14 @@ class btConstraintSolver;
|
|||||||
struct btCollisionAlgorithmCreateFunc;
|
struct btCollisionAlgorithmCreateFunc;
|
||||||
class btDefaultCollisionConfiguration;
|
class btDefaultCollisionConfiguration;
|
||||||
|
|
||||||
|
#include "CcdPhysicsSetup.h"
|
||||||
|
|
||||||
///CcdPhysicsDemo is good starting point for learning the code base and porting.
|
///CcdPhysicsDemo is good starting point for learning the code base and porting.
|
||||||
|
|
||||||
class CcdPhysicsDemo : public PlatformDemoApplication
|
class CcdPhysicsDemo : public PlatformDemoApplication
|
||||||
{
|
{
|
||||||
|
|
||||||
//keep the collision shapes, for deletion/cleanup
|
CcdPhysicsSetup m_physicsSetup;
|
||||||
btAlignedObjectArray<btCollisionShape*> m_collisionShapes;
|
|
||||||
|
|
||||||
btBroadphaseInterface* m_broadphase;
|
|
||||||
|
|
||||||
btCollisionDispatcher* m_dispatcher;
|
|
||||||
|
|
||||||
btConstraintSolver* m_solver;
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@@ -54,7 +49,6 @@ class CcdPhysicsDemo : public PlatformDemoApplication
|
|||||||
};
|
};
|
||||||
int m_ccdMode;
|
int m_ccdMode;
|
||||||
|
|
||||||
btDefaultCollisionConfiguration* m_collisionConfiguration;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|||||||
179
Demos/CcdPhysicsDemo/CcdPhysicsSetup.cpp
Normal file
179
Demos/CcdPhysicsDemo/CcdPhysicsSetup.cpp
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
|
||||||
|
#include "CcdPhysicsSetup.h"
|
||||||
|
#include "btBulletDynamicsCommon.h"
|
||||||
|
#define CUBE_HALF_EXTENTS 1.f
|
||||||
|
#define EXTRA_HEIGHT 1.f
|
||||||
|
|
||||||
|
|
||||||
|
void KinematicObjectSetup::initPhysics(GraphicsPhysicsBridge& gfxBridge)
|
||||||
|
{
|
||||||
|
createEmptyDynamicsWorld();
|
||||||
|
{
|
||||||
|
btBoxShape* box = new btBoxShape(btVector3(btScalar(10.), btScalar(1.), btScalar(10.)));
|
||||||
|
gfxBridge.createCollisionShapeGraphicsObject(box);
|
||||||
|
btTransform startTrans;
|
||||||
|
startTrans.setIdentity();
|
||||||
|
startTrans.setOrigin(btVector3(0, -1, 0));
|
||||||
|
btRigidBody* body = createRigidBody(0, startTrans, box);
|
||||||
|
body->setMotionState(0);
|
||||||
|
body->setFriction(1);
|
||||||
|
body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
|
||||||
|
body->setActivationState(DISABLE_DEACTIVATION);
|
||||||
|
|
||||||
|
gfxBridge.createRigidBodyGraphicsObject(body, btVector3(0,1,0));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
btBoxShape* box = new btBoxShape(btVector3(btScalar(1.), btScalar(1.), btScalar(1.)));
|
||||||
|
gfxBridge.createCollisionShapeGraphicsObject(box);
|
||||||
|
btTransform startTrans;
|
||||||
|
startTrans.setIdentity();
|
||||||
|
startTrans.setOrigin(btVector3(0, 1, 0));
|
||||||
|
btRigidBody* body = createRigidBody(1, startTrans, box);
|
||||||
|
body->setFriction(1);
|
||||||
|
body->setActivationState(DISABLE_DEACTIVATION);
|
||||||
|
gfxBridge.createRigidBodyGraphicsObject(body, btVector3(1, 1, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KinematicObjectSetup::stepSimulation(float deltaTime)
|
||||||
|
{
|
||||||
|
if (m_dynamicsWorld)
|
||||||
|
{
|
||||||
|
btCollisionObject* colObj = m_dynamicsWorld->getCollisionObjectArray()[0];
|
||||||
|
btRigidBody* body = btRigidBody::upcast(colObj);
|
||||||
|
if (body)
|
||||||
|
{
|
||||||
|
btMotionState* ms = body->getMotionState();
|
||||||
|
|
||||||
|
btTransform startTrans;
|
||||||
|
startTrans.setIdentity();
|
||||||
|
static float time = 0.f;
|
||||||
|
time += 0.01f;
|
||||||
|
static float xPos = 0.f;
|
||||||
|
xPos = sinf(time)*10.f;
|
||||||
|
startTrans.setOrigin(btVector3(xPos, -1, 0));
|
||||||
|
if (ms)
|
||||||
|
{
|
||||||
|
|
||||||
|
ms->setWorldTransform(startTrans);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
body->setWorldTransform(startTrans);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_dynamicsWorld->stepSimulation(deltaTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CcdPhysicsSetup::initPhysics(GraphicsPhysicsBridge& gfxBridge)
|
||||||
|
{
|
||||||
|
createEmptyDynamicsWorld();
|
||||||
|
|
||||||
|
|
||||||
|
///create a few basic rigid bodies
|
||||||
|
btBoxShape* box = new btBoxShape(btVector3(btScalar(110.), btScalar(1.), btScalar(110.)));
|
||||||
|
gfxBridge.createCollisionShapeGraphicsObject(box);
|
||||||
|
// box->initializePolyhedralFeatures();
|
||||||
|
btCollisionShape* groundShape = box;
|
||||||
|
|
||||||
|
|
||||||
|
m_collisionShapes.push_back(groundShape);
|
||||||
|
//m_collisionShapes.push_back(new btCylinderShape (btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS)));
|
||||||
|
m_collisionShapes.push_back(new btBoxShape(btVector3(CUBE_HALF_EXTENTS, CUBE_HALF_EXTENTS, CUBE_HALF_EXTENTS)));
|
||||||
|
|
||||||
|
btTransform groundTransform;
|
||||||
|
groundTransform.setIdentity();
|
||||||
|
//groundTransform.setOrigin(btVector3(5,5,5));
|
||||||
|
|
||||||
|
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
|
||||||
|
{
|
||||||
|
btScalar mass(0.);
|
||||||
|
|
||||||
|
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||||
|
bool isDynamic = (mass != 0.f);
|
||||||
|
|
||||||
|
btVector3 localInertia(0, 0, 0);
|
||||||
|
if (isDynamic)
|
||||||
|
groundShape->calculateLocalInertia(mass, localInertia);
|
||||||
|
|
||||||
|
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||||
|
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
|
||||||
|
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
|
||||||
|
btRigidBody* body = new btRigidBody(rbInfo);
|
||||||
|
gfxBridge.createRigidBodyGraphicsObject(body, btVector3(0, 1, 0));
|
||||||
|
body->setFriction(0.5);
|
||||||
|
//body->setRollingFriction(0.3);
|
||||||
|
//add the body to the dynamics world
|
||||||
|
m_dynamicsWorld->addRigidBody(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
//create a few dynamic rigidbodies
|
||||||
|
// Re-using the same collision is better for memory usage and performance
|
||||||
|
|
||||||
|
btCollisionShape* colShape = new btBoxShape(btVector3(1, 1, 1));
|
||||||
|
gfxBridge.createCollisionShapeGraphicsObject(colShape);
|
||||||
|
//btCollisionShape* colShape = new btSphereShape(btScalar(1.));
|
||||||
|
m_collisionShapes.push_back(colShape);
|
||||||
|
|
||||||
|
/// Create Dynamic Objects
|
||||||
|
btTransform startTransform;
|
||||||
|
startTransform.setIdentity();
|
||||||
|
|
||||||
|
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);
|
||||||
|
if (isDynamic)
|
||||||
|
colShape->calculateLocalInertia(mass, localInertia);
|
||||||
|
|
||||||
|
int gNumObjects = 120;//120;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i<gNumObjects; i++)
|
||||||
|
{
|
||||||
|
btCollisionShape* shape = colShape;// m_collisionShapes[1];
|
||||||
|
|
||||||
|
btTransform trans;
|
||||||
|
trans.setIdentity();
|
||||||
|
|
||||||
|
//stack them
|
||||||
|
int colsize = 10;
|
||||||
|
int row = (i*CUBE_HALF_EXTENTS * 2) / (colsize * 2 * CUBE_HALF_EXTENTS);
|
||||||
|
int row2 = row;
|
||||||
|
int col = (i) % (colsize)-colsize / 2;
|
||||||
|
|
||||||
|
|
||||||
|
if (col>3)
|
||||||
|
{
|
||||||
|
col = 11;
|
||||||
|
row2 |= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
btVector3 pos(col * 2 * CUBE_HALF_EXTENTS + (row2 % 2)*CUBE_HALF_EXTENTS,
|
||||||
|
row * 2 * CUBE_HALF_EXTENTS + CUBE_HALF_EXTENTS + EXTRA_HEIGHT, 0);
|
||||||
|
|
||||||
|
trans.setOrigin(pos);
|
||||||
|
|
||||||
|
float mass = 1.f;
|
||||||
|
|
||||||
|
btRigidBody* body = createRigidBody(mass, trans, shape);
|
||||||
|
gfxBridge.createRigidBodyGraphicsObject(body, btVector3(1, 1, 0));
|
||||||
|
|
||||||
|
body->setAnisotropicFriction(shape->getAnisotropicRollingFrictionDirection(), btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
|
||||||
|
body->setFriction(0.5);
|
||||||
|
|
||||||
|
//body->setRollingFriction(.3);
|
||||||
|
///when using m_ccdMode
|
||||||
|
//if (m_ccdMode == USE_CCD)
|
||||||
|
{
|
||||||
|
body->setCcdMotionThreshold(CUBE_HALF_EXTENTS);
|
||||||
|
body->setCcdSweptSphereRadius(0.9*CUBE_HALF_EXTENTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
23
Demos/CcdPhysicsDemo/CcdPhysicsSetup.h
Normal file
23
Demos/CcdPhysicsDemo/CcdPhysicsSetup.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
#ifndef CCD_PHYSICS_SETUP_H
|
||||||
|
#define CCD_PHYSICS_SETUP_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "../CommonRigidBodySetup.h"
|
||||||
|
|
||||||
|
struct CcdPhysicsSetup : public CommonRigidBodySetup
|
||||||
|
{
|
||||||
|
virtual void initPhysics(GraphicsPhysicsBridge& gfxBridge);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct KinematicObjectSetup : public CommonRigidBodySetup
|
||||||
|
{
|
||||||
|
virtual void initPhysics(GraphicsPhysicsBridge& gfxBridge);
|
||||||
|
|
||||||
|
virtual void stepSimulation(float deltaTime);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //CCD_PHYSICS_SETUP_H
|
||||||
53
Demos/CommonPhysicsSetup.h
Normal file
53
Demos/CommonPhysicsSetup.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
|
||||||
|
#ifndef COMMON_PHYSICS_SETUP_H
|
||||||
|
#define COMMON_PHYSICS_SETUP_H
|
||||||
|
|
||||||
|
class btRigidBody;
|
||||||
|
class btBoxShape;
|
||||||
|
class btTransform;
|
||||||
|
class btCollisionShape;
|
||||||
|
#include "LinearMath/btVector3.h"
|
||||||
|
class btDiscreteDynamicsWorld;
|
||||||
|
|
||||||
|
///The GraphicsPhysicsBridge let's the graphics engine create graphics representation and synchronize
|
||||||
|
struct GraphicsPhysicsBridge
|
||||||
|
{
|
||||||
|
virtual void createRigidBodyGraphicsObject(btRigidBody* body,const btVector3& color)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CommonPhysicsSetup
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual ~CommonPhysicsSetup() {}
|
||||||
|
|
||||||
|
virtual void initPhysics(GraphicsPhysicsBridge& gfxBridge) = 0;
|
||||||
|
|
||||||
|
virtual void exitPhysics()=0;
|
||||||
|
|
||||||
|
virtual void stepSimulation(float deltaTime)=0;
|
||||||
|
|
||||||
|
virtual bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld) = 0;
|
||||||
|
virtual bool movePickedBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)=0;
|
||||||
|
virtual void removePickingConstraint() = 0;
|
||||||
|
|
||||||
|
virtual void syncPhysicsToGraphics(GraphicsPhysicsBridge& gfxBridge) = 0;
|
||||||
|
|
||||||
|
virtual btRigidBody* createRigidBody(float mass, const btTransform& startTransform,btCollisionShape* shape, const btVector4& color=btVector4(1,0,0,1))=0;
|
||||||
|
|
||||||
|
virtual btBoxShape* createBoxShape(const btVector3& halfExtents)=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif //COMMON_PHYSICS_SETUP_H
|
||||||
|
|
||||||
|
|
||||||
@@ -11,9 +11,23 @@
|
|||||||
#include "../bullet2/RagdollDemo/RagdollDemo.h"
|
#include "../bullet2/RagdollDemo/RagdollDemo.h"
|
||||||
#include "../bullet2/LuaDemo/LuaDemo.h"
|
#include "../bullet2/LuaDemo/LuaDemo.h"
|
||||||
#include "../bullet2/ChainDemo/ChainDemo.h"
|
#include "../bullet2/ChainDemo/ChainDemo.h"
|
||||||
|
#include "../../Demos/CcdPhysicsDemo/CcdPhysicsSetup.h"
|
||||||
|
|
||||||
|
static BulletDemoInterface* MyCcdPhysicsDemoCreateFunc(SimpleOpenGL3App* app)
|
||||||
|
{
|
||||||
|
CommonPhysicsSetup* physicsSetup = new CcdPhysicsSetup();
|
||||||
|
return new BasicDemo(app, physicsSetup);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BulletDemoInterface* MyKinematicObjectCreateFunc(SimpleOpenGL3App* app)
|
||||||
|
{
|
||||||
|
CommonPhysicsSetup* physicsSetup = new KinematicObjectSetup();
|
||||||
|
return new BasicDemo(app, physicsSetup);
|
||||||
|
}
|
||||||
|
|
||||||
struct BulletDemoEntry
|
struct BulletDemoEntry
|
||||||
{
|
{
|
||||||
|
int m_menuLevel;
|
||||||
const char* m_name;
|
const char* m_name;
|
||||||
BulletDemoInterface::CreateFunc* m_createFunc;
|
BulletDemoInterface::CreateFunc* m_createFunc;
|
||||||
};
|
};
|
||||||
@@ -23,23 +37,28 @@ static BulletDemoEntry allDemos[]=
|
|||||||
{
|
{
|
||||||
|
|
||||||
//{"emptydemo",EmptyBulletDemo::MyCreateFunc},
|
//{"emptydemo",EmptyBulletDemo::MyCreateFunc},
|
||||||
{"BasicDemo",BasicDemo::MyCreateFunc},
|
{0,"API Demos", 0},
|
||||||
|
|
||||||
|
{1,"BasicDemo",BasicDemo::MyCreateFunc},
|
||||||
|
{ 1, "CcdDemo", MyCcdPhysicsDemoCreateFunc },
|
||||||
|
{ 1, "Kinematic", MyKinematicObjectCreateFunc },
|
||||||
|
|
||||||
{"ChainDemo",ChainDemo::MyCreateFunc},
|
/* {1,"ChainDemo",ChainDemo::MyCreateFunc},
|
||||||
{"SIHingeDemo",HingeDemo::SICreateFunc},
|
// {0, "Stress tests", 0 },
|
||||||
{"PGSHingeDemo",HingeDemo::PGSCreateFunc},
|
|
||||||
{"DantzigHingeDemo",HingeDemo::DantzigCreateFunc},
|
|
||||||
{"LemkeHingeDemo",HingeDemo::LemkeCreateFunc},
|
|
||||||
{"InertiaHingeDemo",HingeDemo::InertiaCreateFunc},
|
|
||||||
{"ABMHingeDemo",HingeDemo::FeatherstoneCreateFunc},
|
|
||||||
|
|
||||||
|
{1,"SIHingeDemo",HingeDemo::SICreateFunc},
|
||||||
|
{1,"PGSHingeDemo",HingeDemo::PGSCreateFunc},
|
||||||
|
{1,"DantzigHingeDemo",HingeDemo::DantzigCreateFunc},
|
||||||
|
{1,"LemkeHingeDemo",HingeDemo::LemkeCreateFunc},
|
||||||
|
{1,"InertiaHingeDemo",HingeDemo::InertiaCreateFunc},
|
||||||
|
{1,"ABMHingeDemo",HingeDemo::FeatherstoneCreateFunc},
|
||||||
|
|
||||||
{"Ragdoll",RagDollDemo::MyCreateFunc},
|
{1,"Ragdoll",RagDollDemo::MyCreateFunc},
|
||||||
{"MultiBody1",FeatherstoneDemo1::MyCreateFunc},
|
*/
|
||||||
|
{ 0, "Multibody" ,0},
|
||||||
|
{1,"MultiBody1",FeatherstoneDemo1::MyCreateFunc},
|
||||||
// {"MultiBody2",FeatherstoneDemo2::MyCreateFunc},
|
// {"MultiBody2",FeatherstoneDemo2::MyCreateFunc},
|
||||||
|
{1,"MultiDofDemo",MultiDofDemo::MyCreateFunc},
|
||||||
{"MultiDofDemo",MultiDofDemo::MyCreateFunc},
|
|
||||||
// {"LuaDemo",LuaDemo::MyCreateFunc}
|
// {"LuaDemo",LuaDemo::MyCreateFunc}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,18 +14,22 @@ SET(App_AllBullet2Demos_SRCS
|
|||||||
../bullet2/BasicDemo/Bullet2RigidBodyDemo.h
|
../bullet2/BasicDemo/Bullet2RigidBodyDemo.h
|
||||||
../../Demos/BasicDemo/BasicDemoPhysicsSetup.cpp
|
../../Demos/BasicDemo/BasicDemoPhysicsSetup.cpp
|
||||||
../../Demos/BasicDemo/BasicDemoPhysicsSetup.h
|
../../Demos/BasicDemo/BasicDemoPhysicsSetup.h
|
||||||
|
../../Demos/CcdPhysicsDemo/CcdPhysicsSetup.cpp
|
||||||
|
../../Demos/CcdPhysicsDemo/CcdPhysicsSetup.h
|
||||||
../bullet2/FeatherstoneMultiBodyDemo/BulletMultiBodyDemos.cpp
|
../bullet2/FeatherstoneMultiBodyDemo/BulletMultiBodyDemos.cpp
|
||||||
../bullet2/FeatherstoneMultiBodyDemo/BulletMultiBodyDemos.h
|
../bullet2/FeatherstoneMultiBodyDemo/BulletMultiBodyDemos.h
|
||||||
../bullet2/FeatherstoneMultiBodyDemo/MultiDofDemo.cpp
|
../bullet2/FeatherstoneMultiBodyDemo/MultiDofDemo.cpp
|
||||||
../bullet2/FeatherstoneMultiBodyDemo/MultiDofDemo.h
|
../bullet2/FeatherstoneMultiBodyDemo/MultiDofDemo.h
|
||||||
../bullet2/BasicDemo/BasicDemo.cpp
|
../bullet2/BasicDemo/BasicDemo.cpp
|
||||||
../bullet2/BasicDemo/BasicDemo.h
|
../bullet2/BasicDemo/BasicDemo.h
|
||||||
../bullet2/BasicDemo/HingeDemo.cpp
|
# the next few demos are not converted to 'newer' structure yet
|
||||||
../bullet2/BasicDemo/HingeDemo.h
|
# target is to convert all Bullet 2 demos in new structure, but need to settle down on features
|
||||||
../bullet2/ChainDemo/ChainDemo.cpp
|
# ../bullet2/BasicDemo/HingeDemo.cpp
|
||||||
../bullet2/ChainDemo/ChainDemo.h
|
# ../bullet2/BasicDemo/HingeDemo.h
|
||||||
../bullet2/RagdollDemo/RagdollDemo.cpp
|
# ../bullet2/ChainDemo/ChainDemo.cpp
|
||||||
../bullet2/RagdollDemo/RagdollDemo.h
|
# ../bullet2/ChainDemo/ChainDemo.h
|
||||||
|
# ../bullet2/RagdollDemo/RagdollDemo.cpp
|
||||||
|
# ../bullet2/RagdollDemo/RagdollDemo.h
|
||||||
# ../bullet2/LuaDemo/LuaDemo.cpp
|
# ../bullet2/LuaDemo/LuaDemo.cpp
|
||||||
# ../bullet2/LuaDemo/LuaDemo.h
|
# ../bullet2/LuaDemo/LuaDemo.h
|
||||||
../GpuDemos/gwenUserInterface.cpp
|
../GpuDemos/gwenUserInterface.cpp
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#include "Bullet3Common/b3Vector3.h"
|
#include "Bullet3Common/b3Vector3.h"
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include "../GpuDemos/gwenInternalData.h"
|
||||||
#include "../GpuDemos/gwenUserInterface.h"
|
#include "../GpuDemos/gwenUserInterface.h"
|
||||||
#include "BulletDemoEntries.h"
|
#include "BulletDemoEntries.h"
|
||||||
#include "../../btgui/Timing/b3Clock.h"
|
#include "../../btgui/Timing/b3Clock.h"
|
||||||
@@ -11,6 +11,7 @@ const char* startFileName = "bulletDemo.txt";
|
|||||||
static SimpleOpenGL3App* app=0;
|
static SimpleOpenGL3App* app=0;
|
||||||
static GwenUserInterface* gui = 0;
|
static GwenUserInterface* gui = 0;
|
||||||
static int sCurrentDemoIndex = 0;
|
static int sCurrentDemoIndex = 0;
|
||||||
|
static int sCurrentHightlighted = 0;
|
||||||
static BulletDemoInterface* sCurrentDemo = 0;
|
static BulletDemoInterface* sCurrentDemo = 0;
|
||||||
static b3AlignedObjectArray<const char*> allNames;
|
static b3AlignedObjectArray<const char*> allNames;
|
||||||
|
|
||||||
@@ -22,11 +23,18 @@ static bool pauseSimulation=false;
|
|||||||
void MyKeyboardCallback(int key, int state)
|
void MyKeyboardCallback(int key, int state)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
//printf("key=%d, state=%d\n", key, state);
|
||||||
bool handled = false;
|
bool handled = false;
|
||||||
if (sCurrentDemo)
|
if (gui)
|
||||||
|
{
|
||||||
|
|
||||||
|
handled = gui->keyboardCallback(key, state);
|
||||||
|
}
|
||||||
|
if (!handled && sCurrentDemo)
|
||||||
{
|
{
|
||||||
handled = sCurrentDemo->keyboardCallback(key,state);
|
handled = sCurrentDemo->keyboardCallback(key,state);
|
||||||
}
|
}
|
||||||
|
|
||||||
//checkout: is it desired to ignore keys, if the demo already handles them?
|
//checkout: is it desired to ignore keys, if the demo already handles them?
|
||||||
//if (handled)
|
//if (handled)
|
||||||
// return;
|
// return;
|
||||||
@@ -130,6 +138,88 @@ void MyComboBoxCallback(int comboId, const char* item)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct MyMenuItemHander :public Gwen::Event::Handler
|
||||||
|
{
|
||||||
|
int m_buttonId;
|
||||||
|
|
||||||
|
MyMenuItemHander( int buttonId)
|
||||||
|
:m_buttonId(buttonId)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void onButtonA(Gwen::Controls::Base* pControl)
|
||||||
|
{
|
||||||
|
const Gwen::String& name = pControl->GetName();
|
||||||
|
Gwen::Controls::TreeNode* node = (Gwen::Controls::TreeNode*)pControl;
|
||||||
|
Gwen::Controls::Label* l = node->GetButton();
|
||||||
|
|
||||||
|
Gwen::UnicodeString la = node->GetButton()->GetText();// node->GetButton()->GetName();// GetText();
|
||||||
|
Gwen::String laa = Gwen::Utility::UnicodeToString(la);
|
||||||
|
const char* ha = laa.c_str();
|
||||||
|
|
||||||
|
//printf("selected %s\n", ha);
|
||||||
|
//int dep = but->IsDepressed();
|
||||||
|
//int tog = but->GetToggleState();
|
||||||
|
// if (m_data->m_toggleButtonCallback)
|
||||||
|
// (*m_data->m_toggleButtonCallback)(m_buttonId, tog);
|
||||||
|
}
|
||||||
|
void onButtonB(Gwen::Controls::Base* pControl)
|
||||||
|
{
|
||||||
|
Gwen::Controls::Label* label = (Gwen::Controls::Label*) pControl;
|
||||||
|
Gwen::UnicodeString la = label->GetText();// node->GetButton()->GetName();// GetText();
|
||||||
|
Gwen::String laa = Gwen::Utility::UnicodeToString(la);
|
||||||
|
const char* ha = laa.c_str();
|
||||||
|
|
||||||
|
|
||||||
|
selectDemo(sCurrentHightlighted);
|
||||||
|
saveCurrentDemoEntry(sCurrentDemoIndex, startFileName);
|
||||||
|
}
|
||||||
|
void onButtonC(Gwen::Controls::Base* pControl)
|
||||||
|
{
|
||||||
|
Gwen::Controls::Label* label = (Gwen::Controls::Label*) pControl;
|
||||||
|
Gwen::UnicodeString la = label->GetText();// node->GetButton()->GetName();// GetText();
|
||||||
|
Gwen::String laa = Gwen::Utility::UnicodeToString(la);
|
||||||
|
const char* ha = laa.c_str();
|
||||||
|
|
||||||
|
|
||||||
|
// printf("onButtonC ! %s\n", ha);
|
||||||
|
}
|
||||||
|
void onButtonD(Gwen::Controls::Base* pControl)
|
||||||
|
{
|
||||||
|
/* Gwen::Controls::Label* label = (Gwen::Controls::Label*) pControl;
|
||||||
|
Gwen::UnicodeString la = label->GetText();// node->GetButton()->GetName();// GetText();
|
||||||
|
Gwen::String laa = Gwen::Utility::UnicodeToString(la);
|
||||||
|
const char* ha = laa.c_str();
|
||||||
|
*/
|
||||||
|
|
||||||
|
// printf("onKeyReturn ! \n");
|
||||||
|
selectDemo(sCurrentHightlighted);
|
||||||
|
saveCurrentDemoEntry(sCurrentDemoIndex, startFileName);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void onButtonE(Gwen::Controls::Base* pControl)
|
||||||
|
{
|
||||||
|
// printf("select %d\n",m_buttonId);
|
||||||
|
sCurrentHightlighted = m_buttonId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onButtonF(Gwen::Controls::Base* pControl)
|
||||||
|
{
|
||||||
|
//printf("selection changed!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void onButtonG(Gwen::Controls::Base* pControl)
|
||||||
|
{
|
||||||
|
//printf("onButtonG !\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
b3Clock clock;
|
b3Clock clock;
|
||||||
@@ -152,22 +242,66 @@ int main(int argc, char* argv[])
|
|||||||
sth_stash* fontstash=app->getFontStash();
|
sth_stash* fontstash=app->getFontStash();
|
||||||
gui = new GwenUserInterface;
|
gui = new GwenUserInterface;
|
||||||
gui->init(width,height,fontstash,app->m_window->getRetinaScale());
|
gui->init(width,height,fontstash,app->m_window->getRetinaScale());
|
||||||
|
// gui->getInternalData()->m_explorerPage
|
||||||
|
Gwen::Controls::TreeControl* tree = gui->getInternalData()->m_explorerTreeCtrl;
|
||||||
int numDemos = sizeof(allDemos)/sizeof(BulletDemoEntry);
|
int numDemos = sizeof(allDemos)/sizeof(BulletDemoEntry);
|
||||||
|
|
||||||
for (int i=0;i<numDemos;i++)
|
char nodeText[1024];
|
||||||
|
int curDemo = 0;
|
||||||
|
int selectedDemo = loadCurrentDemoEntry(startFileName);
|
||||||
|
Gwen::Controls::TreeNode* curNode = tree;
|
||||||
|
MyMenuItemHander* handler2 = new MyMenuItemHander(-1);
|
||||||
|
|
||||||
|
tree->onReturnKeyDown.Add(handler2, &MyMenuItemHander::onButtonD);
|
||||||
|
|
||||||
|
for (int d = 0; d<numDemos; d++)
|
||||||
|
{
|
||||||
|
// sprintf(nodeText, "Node %d", i);
|
||||||
|
Gwen::UnicodeString nodeUText = Gwen::Utility::StringToUnicode(allDemos[d].m_name);
|
||||||
|
if (allDemos[d].m_menuLevel==1)
|
||||||
|
{
|
||||||
|
Gwen::Controls::TreeNode* pNode = curNode->AddNode(nodeUText);
|
||||||
|
if (d == selectedDemo)
|
||||||
|
{
|
||||||
|
pNode->SetSelected(true);
|
||||||
|
tree->ExpandAll();
|
||||||
|
selectDemo(d);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
MyMenuItemHander* handler = new MyMenuItemHander(d);
|
||||||
|
pNode->onNamePress.Add(handler, &MyMenuItemHander::onButtonA);
|
||||||
|
pNode->GetButton()->onDoubleClick.Add(handler, &MyMenuItemHander::onButtonB);
|
||||||
|
pNode->GetButton()->onDown.Add(handler, &MyMenuItemHander::onButtonC);
|
||||||
|
pNode->onSelect.Add(handler, &MyMenuItemHander::onButtonE);
|
||||||
|
pNode->onReturnKeyDown.Add(handler, &MyMenuItemHander::onButtonG);
|
||||||
|
pNode->onSelectChange.Add(handler, &MyMenuItemHander::onButtonF);
|
||||||
|
// pNode->onKeyReturn.Add(handler, &MyMenuItemHander::onButtonD);
|
||||||
|
// pNode->GetButton()->onKeyboardReturn.Add(handler, &MyMenuItemHander::onButtonD);
|
||||||
|
// pNode->onNamePress.Add(handler, &MyMenuItemHander::onButtonD);
|
||||||
|
// pNode->onKeyboardPressed.Add(handler, &MyMenuItemHander::onButtonD);
|
||||||
|
// pNode->OnKeyPress
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
curNode = tree->AddNode(nodeUText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for (int i=0;i<numDemos;i++)
|
||||||
{
|
{
|
||||||
allNames.push_back(allDemos[i].m_name);
|
allNames.push_back(allDemos[i].m_name);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
selectDemo(loadCurrentDemoEntry(startFileName));
|
//selectDemo(loadCurrentDemoEntry(startFileName));
|
||||||
|
/*
|
||||||
gui->registerComboBox(DEMO_SELECTION_COMBOBOX,allNames.size(),&allNames[0],sCurrentDemoIndex);
|
gui->registerComboBox(DEMO_SELECTION_COMBOBOX,allNames.size(),&allNames[0],sCurrentDemoIndex);
|
||||||
|
|
||||||
//const char* names2[] = {"comboF", "comboG","comboH"};
|
//const char* names2[] = {"comboF", "comboG","comboH"};
|
||||||
//gui->registerComboBox(2,3,&names2[0],0);
|
//gui->registerComboBox(2,3,&names2[0],0);
|
||||||
|
|
||||||
gui->setComboBoxCallback(MyComboBoxCallback);
|
gui->setComboBoxCallback(MyComboBoxCallback);
|
||||||
|
*/
|
||||||
unsigned long int prevTimeInMicroseconds = clock.getTimeMicroseconds();
|
unsigned long int prevTimeInMicroseconds = clock.getTimeMicroseconds();
|
||||||
|
|
||||||
do
|
do
|
||||||
|
|||||||
@@ -25,21 +25,23 @@
|
|||||||
"../bullet2/BasicDemo/Bullet2RigidBodyDemo.h",
|
"../bullet2/BasicDemo/Bullet2RigidBodyDemo.h",
|
||||||
"../../Demos/BasicDemo/BasicDemoPhysicsSetup.cpp",
|
"../../Demos/BasicDemo/BasicDemoPhysicsSetup.cpp",
|
||||||
"../../Demos/BasicDemo/BasicDemoPhysicsSetup.h",
|
"../../Demos/BasicDemo/BasicDemoPhysicsSetup.h",
|
||||||
|
"../../Demos/CcdPhysicsDemo/CcdPhysicsSetup.cpp",
|
||||||
|
"../../Demos/CcdPhysicsDemo/CcdPhysicsSetup.h",
|
||||||
"../bullet2/FeatherstoneMultiBodyDemo/BulletMultiBodyDemos.cpp",
|
"../bullet2/FeatherstoneMultiBodyDemo/BulletMultiBodyDemos.cpp",
|
||||||
"../bullet2/FeatherstoneMultiBodyDemo/BulletMultiBodyDemos.h",
|
"../bullet2/FeatherstoneMultiBodyDemo/BulletMultiBodyDemos.h",
|
||||||
"../bullet2/FeatherstoneMultiBodyDemo/MultiDofDemo.cpp",
|
"../bullet2/FeatherstoneMultiBodyDemo/MultiDofDemo.cpp",
|
||||||
"../bullet2/FeatherstoneMultiBodyDemo/MultiDofDemo.h",
|
"../bullet2/FeatherstoneMultiBodyDemo/MultiDofDemo.h",
|
||||||
"../bullet2/BasicDemo/BasicDemo.cpp",
|
"../bullet2/BasicDemo/BasicDemo.cpp",
|
||||||
"../bullet2/BasicDemo/BasicDemo.h",
|
"../bullet2/BasicDemo/BasicDemo.h",
|
||||||
"../bullet2/BasicDemo/HingeDemo.cpp",
|
-- "../bullet2/BasicDemo/HingeDemo.cpp",
|
||||||
"../bullet2/BasicDemo/HingeDemo.h",
|
-- "../bullet2/BasicDemo/HingeDemo.h",
|
||||||
"../bullet2/ChainDemo/ChainDemo.cpp",
|
-- "../bullet2/ChainDemo/ChainDemo.cpp",
|
||||||
"../bullet2/ChainDemo/ChainDemo.h",
|
-- "../bullet2/ChainDemo/ChainDemo.h",
|
||||||
|
|
||||||
"../bullet2/RagdollDemo/RagdollDemo.cpp",
|
-- "../bullet2/RagdollDemo/RagdollDemo.cpp",
|
||||||
"../bullet2/RagdollDemo/RagdollDemo.h",
|
-- "../bullet2/RagdollDemo/RagdollDemo.h",
|
||||||
"../bullet2/LuaDemo/LuaDemo.cpp",
|
-- "../bullet2/LuaDemo/LuaDemo.cpp",
|
||||||
"../bullet2/LuaDemo/LuaDemo.h",
|
-- "../bullet2/LuaDemo/LuaDemo.h",
|
||||||
|
|
||||||
|
|
||||||
"../../src/Bullet3Common/**.cpp",
|
"../../src/Bullet3Common/**.cpp",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include "Gwen/Controls/ListBox.h"
|
#include "Gwen/Controls/ListBox.h"
|
||||||
#include "Gwen/Skins/Simple.h"
|
#include "Gwen/Skins/Simple.h"
|
||||||
//#include "Gwen/Skins/TexturedBase.h"
|
//#include "Gwen/Skins/TexturedBase.h"
|
||||||
|
#include "gwenUserInterface.h"
|
||||||
|
|
||||||
|
|
||||||
struct GwenInternalData
|
struct GwenInternalData
|
||||||
@@ -36,12 +37,14 @@ struct GwenInternalData
|
|||||||
Gwen::Controls::Canvas* pCanvas;
|
Gwen::Controls::Canvas* pCanvas;
|
||||||
GLPrimitiveRenderer* m_primRenderer;
|
GLPrimitiveRenderer* m_primRenderer;
|
||||||
Gwen::Controls::TabButton* m_demoPage;
|
Gwen::Controls::TabButton* m_demoPage;
|
||||||
|
Gwen::Controls::TabButton* m_explorerPage;
|
||||||
|
Gwen::Controls::TreeControl* m_explorerTreeCtrl;
|
||||||
|
|
||||||
int m_curYposition;
|
int m_curYposition;
|
||||||
|
|
||||||
Gwen::Controls::Label* m_rightStatusBar;
|
Gwen::Controls::Label* m_rightStatusBar;
|
||||||
Gwen::Controls::Label* m_leftStatusBar;
|
Gwen::Controls::Label* m_leftStatusBar;
|
||||||
|
b3AlignedObjectArray<class Gwen::Event::Handler*> m_handlers;
|
||||||
b3AlignedObjectArray<struct Gwen::Event::Handler*> m_handlers;
|
|
||||||
b3ToggleButtonCallback m_toggleButtonCallback;
|
b3ToggleButtonCallback m_toggleButtonCallback;
|
||||||
b3ComboBoxCallback m_comboBoxCallback;
|
b3ComboBoxCallback m_comboBoxCallback;
|
||||||
|
|
||||||
|
|||||||
@@ -151,29 +151,22 @@ void GwenUserInterface::init(int width, int height,struct sth_stash* stash,float
|
|||||||
//m_data->m_leftStatusBar->SetText( L"Label Added to Left" );
|
//m_data->m_leftStatusBar->SetText( L"Label Added to Left" );
|
||||||
m_data->m_leftStatusBar->SetWidth(width/2);
|
m_data->m_leftStatusBar->SetWidth(width/2);
|
||||||
bar->AddControl( m_data->m_leftStatusBar,false);
|
bar->AddControl( m_data->m_leftStatusBar,false);
|
||||||
|
//Gwen::KeyboardFocus
|
||||||
/*Gwen::Controls::GroupBox* box = new Gwen::Controls::GroupBox(m_data->pCanvas);
|
/*Gwen::Controls::GroupBox* box = new Gwen::Controls::GroupBox(m_data->pCanvas);
|
||||||
box->SetText("text");
|
box->SetText("text");
|
||||||
box->SetName("name");
|
box->SetName("name");
|
||||||
box->SetHeight(500);
|
box->SetHeight(500);
|
||||||
*/
|
*/
|
||||||
Gwen::Controls::ScrollControl* windowLeft= new Gwen::Controls::ScrollControl(m_data->pCanvas);
|
Gwen::Controls::ScrollControl* windowRight= new Gwen::Controls::ScrollControl(m_data->pCanvas);
|
||||||
windowLeft->Dock(Gwen::Pos::Right);
|
windowRight->Dock(Gwen::Pos::Right);
|
||||||
windowLeft->SetWidth(150);
|
windowRight->SetWidth(150);
|
||||||
windowLeft->SetHeight(250);
|
windowRight->SetHeight(250);
|
||||||
windowLeft->SetScroll(false,true);
|
windowRight->SetScroll(false,true);
|
||||||
|
|
||||||
|
|
||||||
/*Gwen::Controls::WindowControl* windowLeft = new Gwen::Controls::WindowControl(m_data->pCanvas);
|
|
||||||
windowLeft->Dock(Gwen::Pos::Left);
|
|
||||||
windowLeft->SetTitle("title");
|
|
||||||
windowLeft->SetWidth(150);
|
|
||||||
windowLeft->SetClosable(false);
|
|
||||||
windowLeft->SetShouldDrawBackground(true);
|
|
||||||
windowLeft->SetTabable(true);
|
|
||||||
*/
|
|
||||||
|
|
||||||
//windowLeft->SetSkin(
|
//windowLeft->SetSkin(
|
||||||
Gwen::Controls::TabControl* tab = new Gwen::Controls::TabControl(windowLeft);
|
Gwen::Controls::TabControl* tab = new Gwen::Controls::TabControl(windowRight);
|
||||||
|
|
||||||
//tab->SetHeight(300);
|
//tab->SetHeight(300);
|
||||||
tab->SetWidth(140);
|
tab->SetWidth(140);
|
||||||
@@ -217,6 +210,39 @@ void GwenUserInterface::init(int width, int height,struct sth_stash* stash,float
|
|||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
Gwen::Controls::ScrollControl* windowLeft = new Gwen::Controls::ScrollControl(m_data->pCanvas);
|
||||||
|
windowLeft->Dock(Gwen::Pos::Left);
|
||||||
|
// windowLeft->SetTitle("title");
|
||||||
|
windowLeft->SetScroll(false, false);
|
||||||
|
windowLeft->SetWidth(250);
|
||||||
|
windowLeft->SetPos(50, 50);
|
||||||
|
windowLeft->SetHeight(500);
|
||||||
|
//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->SetHeight(250);
|
||||||
|
//tab->Dock(Gwen::Pos::Left);
|
||||||
|
explorerTab->Dock(Gwen::Pos::Fill);
|
||||||
|
|
||||||
|
Gwen::UnicodeString explorerStr1(L"Explorer");
|
||||||
|
m_data->m_explorerPage = explorerTab->AddPage(explorerStr1);
|
||||||
|
Gwen::UnicodeString shapesStr1(L"Shapes");
|
||||||
|
explorerTab->AddPage(shapesStr1);
|
||||||
|
Gwen::UnicodeString testStr1(L"Test");
|
||||||
|
explorerTab->AddPage(testStr1);
|
||||||
|
|
||||||
|
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, 400);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
b3ToggleButtonCallback GwenUserInterface::getToggleButtonCallback()
|
b3ToggleButtonCallback GwenUserInterface::getToggleButtonCallback()
|
||||||
@@ -318,6 +344,47 @@ bool GwenUserInterface::mouseMoveCallback( float x, float y)
|
|||||||
return handled;
|
return handled;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#include "OpenGLWindow/b3gWindowInterface.h"
|
||||||
|
|
||||||
|
bool GwenUserInterface::keyboardCallback(int bulletKey, int state)
|
||||||
|
{
|
||||||
|
int key = -1;
|
||||||
|
if (m_data->pCanvas)
|
||||||
|
{
|
||||||
|
//convert 'Bullet' keys into 'Gwen' keys
|
||||||
|
switch (bulletKey)
|
||||||
|
{
|
||||||
|
case B3G_RETURN:
|
||||||
|
{
|
||||||
|
key = Gwen::Key::Return;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B3G_LEFT_ARROW:
|
||||||
|
key = Gwen::Key::Left;
|
||||||
|
break;
|
||||||
|
case B3G_RIGHT_ARROW:
|
||||||
|
key = Gwen::Key::Right;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B3G_UP_ARROW:
|
||||||
|
key = Gwen::Key::Up;
|
||||||
|
break;
|
||||||
|
case B3G_DOWN_ARROW:
|
||||||
|
key = Gwen::Key::Down;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
bool bDown = (state == 1);
|
||||||
|
|
||||||
|
return m_data->pCanvas->InputKey(key, bDown);
|
||||||
|
}
|
||||||
|
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;
|
bool handled = false;
|
||||||
@@ -327,7 +394,7 @@ bool GwenUserInterface::mouseButtonCallback(int button, int state, float x, floa
|
|||||||
|
|
||||||
if (button>=0)
|
if (button>=0)
|
||||||
{
|
{
|
||||||
handled = m_data->pCanvas->InputMouseButton(button,state);
|
handled = m_data->pCanvas->InputMouseButton(button,(bool)state);
|
||||||
if (handled)
|
if (handled)
|
||||||
{
|
{
|
||||||
//if (!state)
|
//if (!state)
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ 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 (*b3ToggleButtonCallback)(int button, int state);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class GwenUserInterface
|
class GwenUserInterface
|
||||||
{
|
{
|
||||||
GwenInternalData* m_data;
|
GwenInternalData* m_data;
|
||||||
@@ -24,6 +26,8 @@ class GwenUserInterface
|
|||||||
|
|
||||||
bool mouseMoveCallback( float x, float y);
|
bool mouseMoveCallback( float x, float y);
|
||||||
bool mouseButtonCallback(int button, int state, float x, float y);
|
bool mouseButtonCallback(int button, int state, float x, float y);
|
||||||
|
bool keyboardCallback(int key, int state);
|
||||||
|
|
||||||
|
|
||||||
void setToggleButtonCallback(b3ToggleButtonCallback callback);
|
void setToggleButtonCallback(b3ToggleButtonCallback callback);
|
||||||
b3ToggleButtonCallback getToggleButtonCallback();
|
b3ToggleButtonCallback getToggleButtonCallback();
|
||||||
|
|||||||
@@ -14,8 +14,8 @@
|
|||||||
|
|
||||||
static const float scaling=0.35f;
|
static const float scaling=0.35f;
|
||||||
|
|
||||||
BasicDemo::BasicDemo(SimpleOpenGL3App* app)
|
BasicDemo::BasicDemo(SimpleOpenGL3App* app, CommonPhysicsSetup* physicsSetup)
|
||||||
:Bullet2RigidBodyDemo(app)
|
:Bullet2RigidBodyDemo(app,physicsSetup)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,124 +25,6 @@ BasicDemo::~BasicDemo()
|
|||||||
|
|
||||||
void BasicDemo::createGround(int cubeShapeId)
|
void BasicDemo::createGround(int cubeShapeId)
|
||||||
{
|
{
|
||||||
{
|
|
||||||
btVector4 color(0.3,0.3,1,1);
|
|
||||||
btVector4 halfExtents(50,50,50,1);
|
|
||||||
btTransform groundTransform;
|
|
||||||
groundTransform.setIdentity();
|
|
||||||
groundTransform.setOrigin(btVector3(0,-50,0));
|
|
||||||
m_glApp->m_instancingRenderer->registerGraphicsInstance(cubeShapeId,groundTransform.getOrigin(),groundTransform.getRotation(),color,halfExtents);
|
|
||||||
|
|
||||||
btBoxShape* groundShape = new btBoxShape(btVector3(btScalar(halfExtents[0]),btScalar(halfExtents[1]),btScalar(halfExtents[2])));
|
|
||||||
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
|
|
||||||
{
|
|
||||||
btScalar mass(0.);
|
|
||||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
|
||||||
bool isDynamic = (mass != 0.f);
|
|
||||||
btVector3 localInertia(0,0,0);
|
|
||||||
if (isDynamic)
|
|
||||||
groundShape->calculateLocalInertia(mass,localInertia);
|
|
||||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
|
||||||
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
|
|
||||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia);
|
|
||||||
btRigidBody* body = new btRigidBody(rbInfo);
|
|
||||||
//add the body to the dynamics world
|
|
||||||
m_dynamicsWorld->addRigidBody(body);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void BasicDemo::initPhysics()
|
|
||||||
{
|
|
||||||
m_physicsSetup.m_glApp = m_glApp;
|
|
||||||
m_physicsSetup.initPhysics();
|
|
||||||
m_dynamicsWorld = m_physicsSetup.m_dynamicsWorld;
|
|
||||||
|
|
||||||
m_glApp->m_instancingRenderer->writeTransforms();
|
|
||||||
}
|
|
||||||
void BasicDemo::exitPhysics()
|
|
||||||
{
|
|
||||||
m_physicsSetup.exitPhysics();
|
|
||||||
m_dynamicsWorld = 0;
|
|
||||||
//Bullet2RigidBodyDemo::exitPhysics();
|
|
||||||
}
|
|
||||||
|
|
||||||
//SimpleOpenGL3App* m_glApp;
|
|
||||||
|
|
||||||
btRigidBody* MyBasicDemoPhysicsSetup::createRigidBody(float mass, const btTransform& startTransform,btCollisionShape* shape, const btVector4& color)
|
|
||||||
{
|
|
||||||
btRigidBody* body = BasicDemoPhysicsSetup::createRigidBody(mass,startTransform,shape);
|
|
||||||
int graphicsShapeId = shape->getUserIndex();
|
|
||||||
btAssert(graphicsShapeId>=0);
|
|
||||||
btVector3 localScaling = shape->getLocalScaling();
|
|
||||||
|
|
||||||
int graphicsInstanceId = m_glApp->m_instancingRenderer->registerGraphicsInstance(graphicsShapeId,startTransform.getOrigin(),startTransform.getRotation(),color,localScaling);
|
|
||||||
body->setUserIndex(graphicsInstanceId);
|
|
||||||
|
|
||||||
//todo: create graphics representation
|
|
||||||
return body;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
btBoxShape* MyBasicDemoPhysicsSetup::createBoxShape(const btVector3& halfExtents)
|
|
||||||
{
|
|
||||||
btBoxShape* box = BasicDemoPhysicsSetup::createBoxShape(halfExtents);
|
|
||||||
int cubeShapeId = m_glApp->registerCubeShape(halfExtents.x(),halfExtents.y(),halfExtents.z());
|
|
||||||
box->setUserIndex(cubeShapeId);
|
|
||||||
//todo: create graphics representation
|
|
||||||
return box;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void BasicDemo::renderScene()
|
|
||||||
{
|
|
||||||
//sync graphics -> physics world transforms
|
|
||||||
{
|
|
||||||
for (int i=0;i<m_dynamicsWorld->getNumCollisionObjects();i++)
|
|
||||||
{
|
|
||||||
btCollisionObject* colObj = m_dynamicsWorld->getCollisionObjectArray()[i];
|
|
||||||
btVector3 pos = colObj->getWorldTransform().getOrigin();
|
|
||||||
btQuaternion orn = colObj->getWorldTransform().getRotation();
|
|
||||||
int index = colObj ->getUserIndex();
|
|
||||||
if (index>=0)
|
|
||||||
{
|
|
||||||
m_glApp->m_instancingRenderer->writeSingleInstanceTransformToCPU(pos,orn,index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_glApp->m_instancingRenderer->writeTransforms();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_glApp->m_instancingRenderer->renderScene();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void BasicDemo::stepSimulation(float dt)
|
|
||||||
{
|
|
||||||
m_physicsSetup.stepSimulation(dt);
|
|
||||||
m_physicsSetup.m_dynamicsWorld->debugDrawWorld();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
//print applied force
|
|
||||||
//contact points
|
|
||||||
for (int i=0;i<m_dynamicsWorld->getDispatcher()->getNumManifolds();i++)
|
|
||||||
{
|
|
||||||
btPersistentManifold* contact = m_dynamicsWorld->getDispatcher()->getManifoldByIndexInternal(i);
|
|
||||||
for (int c=0;c<contact->getNumContacts();c++)
|
|
||||||
{
|
|
||||||
btManifoldPoint& pt = contact->getContactPoint(c);
|
|
||||||
btScalar dist = pt.getDistance();
|
|
||||||
if (dist< contact->getContactProcessingThreshold())
|
|
||||||
{
|
|
||||||
printf("normalImpulse[%d.%d] = %f\n",i,c,pt.m_appliedImpulse);
|
|
||||||
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
printf("?\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,36 +7,26 @@
|
|||||||
#include "../../../Demos/BasicDemo/BasicDemoPhysicsSetup.h"
|
#include "../../../Demos/BasicDemo/BasicDemoPhysicsSetup.h"
|
||||||
|
|
||||||
|
|
||||||
struct MyBasicDemoPhysicsSetup : public BasicDemoPhysicsSetup
|
|
||||||
{
|
|
||||||
SimpleOpenGL3App* m_glApp;
|
|
||||||
|
|
||||||
virtual btRigidBody* createRigidBody(float mass, const btTransform& startTransform,btCollisionShape* shape, const btVector4& color);
|
|
||||||
|
|
||||||
virtual btBoxShape* createBoxShape(const btVector3& halfExtents);
|
|
||||||
};
|
|
||||||
|
|
||||||
class BasicDemo : public Bullet2RigidBodyDemo
|
class BasicDemo : public Bullet2RigidBodyDemo
|
||||||
{
|
{
|
||||||
|
|
||||||
MyBasicDemoPhysicsSetup m_physicsSetup;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static BulletDemoInterface* MyCreateFunc(SimpleOpenGL3App* app)
|
static BulletDemoInterface* MyCreateFunc(SimpleOpenGL3App* app)
|
||||||
{
|
{
|
||||||
return new BasicDemo(app);
|
CommonPhysicsSetup* physicsSetup = new BasicDemoPhysicsSetup();
|
||||||
|
return new BasicDemo(app, physicsSetup);
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicDemo(SimpleOpenGL3App* app);
|
BasicDemo(SimpleOpenGL3App* app, CommonPhysicsSetup* physicsSetup);
|
||||||
virtual ~BasicDemo();
|
virtual ~BasicDemo();
|
||||||
|
|
||||||
void createGround(int cubeShapeId);
|
void createGround(int cubeShapeId);
|
||||||
|
|
||||||
virtual void initPhysics();
|
|
||||||
virtual void exitPhysics();
|
|
||||||
virtual void renderScene();
|
|
||||||
virtual void stepSimulation(float dt);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,54 +2,102 @@
|
|||||||
#include "btBulletDynamicsCommon.h"
|
#include "btBulletDynamicsCommon.h"
|
||||||
#include "OpenGLWindow/SimpleOpenGL3App.h"
|
#include "OpenGLWindow/SimpleOpenGL3App.h"
|
||||||
|
|
||||||
Bullet2RigidBodyDemo::Bullet2RigidBodyDemo(SimpleOpenGL3App* app)
|
struct MyGraphicsPhysicsBridge : public GraphicsPhysicsBridge
|
||||||
:m_glApp(app),
|
|
||||||
m_pickedBody(0),
|
|
||||||
m_pickedConstraint(0),
|
|
||||||
m_controlPressed(false),
|
|
||||||
m_altPressed(false)
|
|
||||||
{
|
{
|
||||||
m_config = 0;
|
SimpleOpenGL3App* m_glApp;
|
||||||
m_dispatcher = 0;
|
|
||||||
m_bp = 0;
|
MyGraphicsPhysicsBridge(SimpleOpenGL3App* glApp)
|
||||||
m_solver = 0;
|
:m_glApp(glApp)
|
||||||
m_dynamicsWorld = 0;
|
{
|
||||||
|
}
|
||||||
|
virtual void createRigidBodyGraphicsObject(btRigidBody* body, const btVector3& color)
|
||||||
|
{
|
||||||
|
btCollisionShape* shape = body->getCollisionShape();
|
||||||
|
btTransform startTransform = body->getWorldTransform();
|
||||||
|
int graphicsShapeId = shape->getUserIndex();
|
||||||
|
btAssert(graphicsShapeId >= 0);
|
||||||
|
btVector3 localScaling = shape->getLocalScaling();
|
||||||
|
int graphicsInstanceId = m_glApp->m_instancingRenderer->registerGraphicsInstance(graphicsShapeId, startTransform.getOrigin(), startTransform.getRotation(), color, localScaling);
|
||||||
|
body->setUserIndex(graphicsInstanceId);
|
||||||
|
}
|
||||||
|
virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape)
|
||||||
|
{
|
||||||
|
//todo: support all collision shape types
|
||||||
|
switch (collisionShape->getShapeType())
|
||||||
|
{
|
||||||
|
case BOX_SHAPE_PROXYTYPE:
|
||||||
|
{
|
||||||
|
btBoxShape* box = (btBoxShape*)collisionShape;
|
||||||
|
btVector3 halfExtents = box->getHalfExtentsWithMargin();
|
||||||
|
int cubeShapeId = m_glApp->registerCubeShape(halfExtents.x(), halfExtents.y(), halfExtents.z());
|
||||||
|
box->setUserIndex(cubeShapeId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
btAssert(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld)
|
||||||
|
{
|
||||||
|
int numCollisionObjects = rbWorld->getNumCollisionObjects();
|
||||||
|
for (int i = 0; i<numCollisionObjects; i++)
|
||||||
|
{
|
||||||
|
btCollisionObject* colObj = rbWorld->getCollisionObjectArray()[i];
|
||||||
|
btVector3 pos = colObj->getWorldTransform().getOrigin();
|
||||||
|
btQuaternion orn = colObj->getWorldTransform().getRotation();
|
||||||
|
int index = colObj->getUserIndex();
|
||||||
|
if (index >= 0)
|
||||||
|
{
|
||||||
|
m_glApp->m_instancingRenderer->writeSingleInstanceTransformToCPU(pos, orn, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_glApp->m_instancingRenderer->writeTransforms();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Bullet2RigidBodyDemo::Bullet2RigidBodyDemo(SimpleOpenGL3App* app, CommonPhysicsSetup* physicsSetup)
|
||||||
|
:m_glApp(app),
|
||||||
|
m_physicsSetup(physicsSetup),
|
||||||
|
m_controlPressed(false),
|
||||||
|
m_altPressed(false)
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
void Bullet2RigidBodyDemo::initPhysics()
|
void Bullet2RigidBodyDemo::initPhysics()
|
||||||
{
|
{
|
||||||
m_config = new btDefaultCollisionConfiguration;
|
MyGraphicsPhysicsBridge glBridge(m_glApp);
|
||||||
m_dispatcher = new btCollisionDispatcher(m_config);
|
m_physicsSetup->initPhysics(glBridge);
|
||||||
m_bp = new btDbvtBroadphase();
|
m_glApp->m_instancingRenderer->writeTransforms();
|
||||||
m_solver = new btSequentialImpulseConstraintSolver();
|
|
||||||
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_bp,m_solver,m_config);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bullet2RigidBodyDemo::exitPhysics()
|
void Bullet2RigidBodyDemo::exitPhysics()
|
||||||
{
|
{
|
||||||
delete m_dynamicsWorld;
|
|
||||||
m_dynamicsWorld=0;
|
m_physicsSetup->exitPhysics();
|
||||||
delete m_solver;
|
|
||||||
m_solver=0;
|
|
||||||
delete m_bp;
|
|
||||||
m_bp=0;
|
|
||||||
delete m_dispatcher;
|
|
||||||
m_dispatcher=0;
|
|
||||||
delete m_config;
|
|
||||||
m_config=0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bullet2RigidBodyDemo::stepSimulation(float deltaTime)
|
void Bullet2RigidBodyDemo::stepSimulation(float deltaTime)
|
||||||
{
|
{
|
||||||
m_dynamicsWorld->stepSimulation(deltaTime);
|
m_physicsSetup->stepSimulation(deltaTime);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Bullet2RigidBodyDemo::renderScene()
|
||||||
|
{
|
||||||
|
//sync graphics -> physics world transforms
|
||||||
|
|
||||||
|
MyGraphicsPhysicsBridge glBridge(m_glApp);
|
||||||
|
m_physicsSetup->syncPhysicsToGraphics(glBridge);
|
||||||
|
|
||||||
|
m_glApp->m_instancingRenderer->renderScene();
|
||||||
|
|
||||||
|
}
|
||||||
Bullet2RigidBodyDemo::~Bullet2RigidBodyDemo()
|
Bullet2RigidBodyDemo::~Bullet2RigidBodyDemo()
|
||||||
{
|
{
|
||||||
btAssert(m_config == 0);
|
|
||||||
btAssert(m_dispatcher == 0);
|
|
||||||
btAssert(m_bp == 0);
|
|
||||||
btAssert(m_solver == 0);
|
|
||||||
btAssert(m_dynamicsWorld == 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
btVector3 Bullet2RigidBodyDemo::getRayTo(int x,int y)
|
btVector3 Bullet2RigidBodyDemo::getRayTo(int x,int y)
|
||||||
@@ -115,28 +163,10 @@ btVector3 Bullet2RigidBodyDemo::getRayTo(int x,int y)
|
|||||||
|
|
||||||
bool Bullet2RigidBodyDemo::mouseMoveCallback(float x,float y)
|
bool Bullet2RigidBodyDemo::mouseMoveCallback(float x,float y)
|
||||||
{
|
{
|
||||||
//if (m_data->m_altPressed!=0 || m_data->m_controlPressed!=0)
|
btVector3 rayTo = getRayTo(x, y);
|
||||||
//return false;
|
btVector3 rayFrom;
|
||||||
|
m_glApp->m_instancingRenderer->getCameraPosition(rayFrom);
|
||||||
if (m_pickedBody && m_pickedConstraint)
|
m_physicsSetup->movePickedBody(rayFrom,rayTo);
|
||||||
{
|
|
||||||
btPoint2PointConstraint* pickCon = static_cast<btPoint2PointConstraint*>(m_pickedConstraint);
|
|
||||||
if (pickCon)
|
|
||||||
{
|
|
||||||
//keep it at the same picking distance
|
|
||||||
btVector3 newRayTo = getRayTo(x,y);
|
|
||||||
btVector3 rayFrom;
|
|
||||||
btVector3 oldPivotInB = pickCon->getPivotInB();
|
|
||||||
btVector3 newPivotB;
|
|
||||||
m_glApp->m_instancingRenderer->getCameraPosition(rayFrom);
|
|
||||||
btVector3 dir = newRayTo-rayFrom;
|
|
||||||
dir.normalize();
|
|
||||||
dir *= m_oldPickingDist;
|
|
||||||
|
|
||||||
newPivotB = rayFrom + dir;
|
|
||||||
pickCon->setPivotB(newPivotB);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -153,53 +183,15 @@ bool Bullet2RigidBodyDemo::mouseButtonCallback(int button, int state, float x, f
|
|||||||
btVector3 rayFrom = camPos;
|
btVector3 rayFrom = camPos;
|
||||||
btVector3 rayTo = getRayTo(x,y);
|
btVector3 rayTo = getRayTo(x,y);
|
||||||
|
|
||||||
btCollisionWorld::ClosestRayResultCallback rayCallback(rayFrom,rayTo);
|
bool hasPicked = m_physicsSetup->pickBody(rayFrom, rayTo);
|
||||||
m_dynamicsWorld->rayTest(rayFrom,rayTo,rayCallback);
|
|
||||||
if (rayCallback.hasHit())
|
|
||||||
{
|
|
||||||
|
|
||||||
btVector3 pickPos = rayCallback.m_hitPointWorld;
|
|
||||||
btRigidBody* body = (btRigidBody*)btRigidBody::upcast(rayCallback.m_collisionObject);
|
|
||||||
if (body)
|
|
||||||
{
|
|
||||||
//other exclusions?
|
|
||||||
if (!(body->isStaticObject() || body->isKinematicObject()))
|
|
||||||
{
|
|
||||||
m_pickedBody = body;
|
|
||||||
m_pickedBody->setActivationState(DISABLE_DEACTIVATION);
|
|
||||||
//printf("pickPos=%f,%f,%f\n",pickPos.getX(),pickPos.getY(),pickPos.getZ());
|
|
||||||
btVector3 localPivot = body->getCenterOfMassTransform().inverse() * pickPos;
|
|
||||||
btPoint2PointConstraint* p2p = new btPoint2PointConstraint(*body,localPivot);
|
|
||||||
m_dynamicsWorld->addConstraint(p2p,true);
|
|
||||||
m_pickedConstraint = p2p;
|
|
||||||
btScalar mousePickClamping = 30.f;
|
|
||||||
p2p->m_setting.m_impulseClamp = mousePickClamping;
|
|
||||||
//very weak constraint for picking
|
|
||||||
p2p->m_setting.m_tau = 0.001f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// pickObject(pickPos, rayCallback.m_collisionObject);
|
|
||||||
m_oldPickingPos = rayTo;
|
|
||||||
m_hitPos = pickPos;
|
|
||||||
m_oldPickingDist = (pickPos-rayFrom).length();
|
|
||||||
// printf("hit !\n");
|
|
||||||
//add p2p
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
if (button==0)
|
if (button==0)
|
||||||
{
|
{
|
||||||
if (m_pickedConstraint)
|
m_physicsSetup->removePickingConstraint();
|
||||||
{
|
|
||||||
m_dynamicsWorld->removeConstraint(m_pickedConstraint);
|
|
||||||
delete m_pickedConstraint;
|
|
||||||
m_pickedConstraint=0;
|
|
||||||
m_pickedBody = 0;
|
|
||||||
}
|
|
||||||
//remove p2p
|
//remove p2p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,31 +6,28 @@
|
|||||||
#include "../../AllBullet2Demos/BulletDemoInterface.h"
|
#include "../../AllBullet2Demos/BulletDemoInterface.h"
|
||||||
|
|
||||||
#include "OpenGLWindow/b3gWindowInterface.h"
|
#include "OpenGLWindow/b3gWindowInterface.h"
|
||||||
|
#include "../../../Demos/CommonPhysicsSetup.h"
|
||||||
|
|
||||||
|
|
||||||
class Bullet2RigidBodyDemo : public BulletDemoInterface
|
class Bullet2RigidBodyDemo : public BulletDemoInterface
|
||||||
{
|
{
|
||||||
public:
|
CommonPhysicsSetup* m_physicsSetup;
|
||||||
class btDiscreteDynamicsWorld* m_dynamicsWorld;
|
|
||||||
class btCollisionDispatcher* m_dispatcher;
|
public:
|
||||||
class btBroadphaseInterface* m_bp;
|
|
||||||
class btCollisionConfiguration* m_config;
|
|
||||||
class btConstraintSolver* m_solver;
|
|
||||||
|
|
||||||
class btRigidBody* m_pickedBody;
|
|
||||||
class btTypedConstraint* m_pickedConstraint;
|
|
||||||
btVector3 m_oldPickingPos;
|
|
||||||
btVector3 m_hitPos;
|
|
||||||
btScalar m_oldPickingDist;
|
|
||||||
bool m_controlPressed;
|
bool m_controlPressed;
|
||||||
bool m_altPressed;
|
bool m_altPressed;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
class SimpleOpenGL3App* m_glApp;
|
struct SimpleOpenGL3App* m_glApp;
|
||||||
|
|
||||||
Bullet2RigidBodyDemo(SimpleOpenGL3App* app);
|
Bullet2RigidBodyDemo(SimpleOpenGL3App* app, CommonPhysicsSetup* physicsSetup);
|
||||||
virtual void initPhysics();
|
virtual void initPhysics();
|
||||||
virtual void exitPhysics();
|
virtual void exitPhysics();
|
||||||
|
virtual void renderScene();
|
||||||
|
virtual void stepSimulation(float dt);
|
||||||
|
|
||||||
|
|
||||||
virtual ~Bullet2RigidBodyDemo();
|
virtual ~Bullet2RigidBodyDemo();
|
||||||
btVector3 getRayTo(int x,int y);
|
btVector3 getRayTo(int x,int y);
|
||||||
@@ -49,7 +46,6 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void stepSimulation(float deltaTime);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -343,17 +343,6 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
RagDollDemo::RagDollDemo(SimpleOpenGL3App* app)
|
|
||||||
:BasicDemo(app)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
RagDollDemo::~RagDollDemo()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void RagDollDemo::initPhysics()
|
void RagDollDemo::initPhysics()
|
||||||
|
|||||||
@@ -2,21 +2,24 @@
|
|||||||
#define RAGDOLL_DEMO_H
|
#define RAGDOLL_DEMO_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "../../Demos/CommonRigidBodySetup.h"
|
||||||
#include "../BasicDemo/BasicDemo.h"
|
#include "../BasicDemo/BasicDemo.h"
|
||||||
|
|
||||||
class RagDollDemo : public BasicDemo
|
struct BulletDemoInterface;
|
||||||
|
struct SimpleOpenGL3App;
|
||||||
|
|
||||||
|
class RagDollSetup : public CommonRigidBodySetup
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
RagDollDemo(SimpleOpenGL3App* app);
|
|
||||||
virtual ~RagDollDemo();
|
|
||||||
|
|
||||||
static BulletDemoInterface* MyCreateFunc(SimpleOpenGL3App* app)
|
static BulletDemoInterface* MyCreateFunc(SimpleOpenGL3App* app)
|
||||||
{
|
{
|
||||||
return new RagDollDemo(app);
|
CommonPhysicsSetup* physicsSetup = new RagDollSetup();
|
||||||
|
return new BasicDemo(app, physicsSetup);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void initPhysics();
|
void initPhysics(GraphicsPhysicsBridge& gfxBridge);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -49,17 +49,28 @@ namespace Gwen
|
|||||||
virtual void SetImage( const TextObject& strName, bool bCenter = false );
|
virtual void SetImage( const TextObject& strName, bool bCenter = false );
|
||||||
|
|
||||||
// You can use this to trigger OnPress directly from other controls using GWEN_CALL_EX
|
// You can use this to trigger OnPress directly from other controls using GWEN_CALL_EX
|
||||||
virtual void ReceiveEventPress( Base* /*pControl*/ ){ OnPress(); }
|
virtual void ReceiveEventPress( Base* /*pControl*/ )
|
||||||
|
{
|
||||||
|
OnPress();
|
||||||
|
}
|
||||||
|
|
||||||
virtual void SizeToContents();
|
virtual void SizeToContents();
|
||||||
virtual void Layout( Skin::Base* pSkin );
|
virtual void Layout( Skin::Base* pSkin );
|
||||||
|
|
||||||
|
virtual bool OnKeyReturn(bool bDown)
|
||||||
|
{
|
||||||
|
onKeyboardReturn.Call(this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Gwen::Event::Caller onPress;
|
Gwen::Event::Caller onPress;
|
||||||
Gwen::Event::Caller onDown;
|
Gwen::Event::Caller onDown;
|
||||||
Gwen::Event::Caller onUp;
|
Gwen::Event::Caller onUp;
|
||||||
Gwen::Event::Caller onDoubleClick;
|
Gwen::Event::Caller onDoubleClick;
|
||||||
|
Gwen::Event::Caller onKeyboardReturn;
|
||||||
|
|
||||||
Gwen::Event::Caller onToggle;
|
Gwen::Event::Caller onToggle;
|
||||||
Gwen::Event::Caller onToggleOn;
|
Gwen::Event::Caller onToggleOn;
|
||||||
Gwen::Event::Caller onToggleOff;
|
Gwen::Event::Caller onToggleOff;
|
||||||
|
|||||||
@@ -72,8 +72,10 @@ void TreeControl::OnNodeAdded( TreeNode* pNode )
|
|||||||
pNode->onNamePress.Add( this, &TreeControl::OnNodeSelection );
|
pNode->onNamePress.Add( this, &TreeControl::OnNodeSelection );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TreeControl::OnNodeSelection( Controls::Base* /*control*/ )
|
void TreeControl::OnNodeSelection( Controls::Base* /*control*/ )
|
||||||
{
|
{
|
||||||
|
//printf("TreeControl::OnNodeSelection\n");
|
||||||
if ( !m_bAllowMultipleSelection || !Gwen::Input::IsKeyDown( Key::Control ) )
|
if ( !m_bAllowMultipleSelection || !Gwen::Input::IsKeyDown( Key::Control ) )
|
||||||
DeselectAll();
|
DeselectAll();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,6 +132,13 @@ void TreeNode::PostLayout( Skin::Base* /*skin*/ )
|
|||||||
void TreeNode::SetText( const UnicodeString& text ){ m_Title->SetText( text ); };
|
void TreeNode::SetText( const UnicodeString& text ){ m_Title->SetText( text ); };
|
||||||
void TreeNode::SetText( const String& text ){ m_Title->SetText( text ); };
|
void TreeNode::SetText( const String& text ){ m_Title->SetText( text ); };
|
||||||
|
|
||||||
|
UnicodeString TreeNode::GetText() const
|
||||||
|
{
|
||||||
|
UnicodeString bla = m_Title->GetText();
|
||||||
|
return bla;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void TreeNode::Open()
|
void TreeNode::Open()
|
||||||
{
|
{
|
||||||
m_InnerPanel->Show();
|
m_InnerPanel->Show();
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ namespace Gwen
|
|||||||
|
|
||||||
virtual void SetText( const UnicodeString& text );
|
virtual void SetText( const UnicodeString& text );
|
||||||
virtual void SetText( const String& text );
|
virtual void SetText( const String& text );
|
||||||
|
UnicodeString GetText() const;
|
||||||
|
|
||||||
virtual void Open();
|
virtual void Open();
|
||||||
virtual void Close();
|
virtual void Close();
|
||||||
@@ -60,7 +61,18 @@ namespace Gwen
|
|||||||
virtual void DeselectAll();
|
virtual void DeselectAll();
|
||||||
|
|
||||||
virtual void iterate(int action, int* curIndex, int* resultIndex);
|
virtual void iterate(int action, int* curIndex, int* resultIndex);
|
||||||
|
virtual bool OnKeyReturn(bool bDown)
|
||||||
|
{
|
||||||
|
static bool prevDown = false;
|
||||||
|
if (!prevDown && bDown)
|
||||||
|
{
|
||||||
|
onReturnKeyDown.Call(this);
|
||||||
|
}
|
||||||
|
prevDown = bDown;
|
||||||
|
return Base::OnKeyReturn(bDown);
|
||||||
|
}
|
||||||
|
|
||||||
|
Event::Caller onReturnKeyDown;
|
||||||
|
|
||||||
Event::Caller onNamePress;
|
Event::Caller onNamePress;
|
||||||
Event::Caller onSelectChange;
|
Event::Caller onSelectChange;
|
||||||
|
|||||||
@@ -308,7 +308,7 @@ int main()
|
|||||||
b3gWindowConstructionInfo wci;
|
b3gWindowConstructionInfo wci;
|
||||||
wci.m_width = sWidth;
|
wci.m_width = sWidth;
|
||||||
wci.m_height = sHeight;
|
wci.m_height = sHeight;
|
||||||
wci.m_resizeCallback = MyResizeCallback;
|
// wci.m_resizeCallback = MyResizeCallback;
|
||||||
window->createWindow(wci);
|
window->createWindow(wci);
|
||||||
|
|
||||||
window->setResizeCallback(MyResizeCallback);
|
window->setResizeCallback(MyResizeCallback);
|
||||||
|
|||||||
@@ -55,8 +55,21 @@ void Win32Window::pumpMessage()
|
|||||||
int getAsciiCodeFromVirtualKeycode(int virtualKeyCode)
|
int getAsciiCodeFromVirtualKeycode(int virtualKeyCode)
|
||||||
{
|
{
|
||||||
int keycode = 0xffffffff;
|
int keycode = 0xffffffff;
|
||||||
|
if (virtualKeyCode >= '0' && virtualKeyCode <= '9')
|
||||||
|
{
|
||||||
|
return virtualKeyCode;
|
||||||
|
}
|
||||||
|
if (virtualKeyCode >= 'a' && virtualKeyCode <= 'z')
|
||||||
|
{
|
||||||
|
return virtualKeyCode;
|
||||||
|
}
|
||||||
|
if (virtualKeyCode >= 'A' && virtualKeyCode <= 'Z')
|
||||||
|
{
|
||||||
|
return virtualKeyCode;
|
||||||
|
}
|
||||||
switch (virtualKeyCode)
|
switch (virtualKeyCode)
|
||||||
{
|
{
|
||||||
|
case VK_RETURN: {keycode = B3G_RETURN; break; };
|
||||||
case VK_F1: {keycode = B3G_F1; break;}
|
case VK_F1: {keycode = B3G_F1; break;}
|
||||||
case VK_F2: {keycode = B3G_F2; break;}
|
case VK_F2: {keycode = B3G_F2; break;}
|
||||||
case VK_F3: {keycode = B3G_F3; break;}
|
case VK_F3: {keycode = B3G_F3; break;}
|
||||||
@@ -126,7 +139,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
|
|
||||||
case WM_SYSKEYUP:
|
case WM_SYSKEYUP:
|
||||||
case WM_KEYUP:
|
case WM_KEYUP:
|
||||||
{
|
{
|
||||||
|
|
||||||
int keycode = getAsciiCodeFromVirtualKeycode(wParam);
|
int keycode = getAsciiCodeFromVirtualKeycode(wParam);
|
||||||
|
|
||||||
@@ -140,12 +153,15 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
}
|
}
|
||||||
case WM_CHAR:
|
case WM_CHAR:
|
||||||
{
|
{
|
||||||
int keycode = wParam;
|
//skip 'enter' key, it is processed in WM_KEYUP/WM_KEYDOWN
|
||||||
|
int keycode = getAsciiCodeFromVirtualKeycode(wParam);
|
||||||
if (sData && sData->m_keyboardCallback && ((HIWORD(lParam) & KF_REPEAT) == 0))
|
if (keycode < 0)
|
||||||
{
|
{
|
||||||
int state = 1;
|
if (sData && sData->m_keyboardCallback && ((HIWORD(lParam) & KF_REPEAT) == 0))
|
||||||
(*sData->m_keyboardCallback)(keycode,state);
|
{
|
||||||
|
int state = 1;
|
||||||
|
(*sData->m_keyboardCallback)(wParam, state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -323,6 +339,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
|
|
||||||
default:{
|
default:{
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ enum {
|
|||||||
B3G_BACKSPACE,
|
B3G_BACKSPACE,
|
||||||
B3G_SHIFT,
|
B3G_SHIFT,
|
||||||
B3G_CONTROL,
|
B3G_CONTROL,
|
||||||
B3G_ALT
|
B3G_ALT,
|
||||||
|
B3G_RETURN
|
||||||
};
|
};
|
||||||
|
|
||||||
struct b3gWindowConstructionInfo
|
struct b3gWindowConstructionInfo
|
||||||
|
|||||||
Reference in New Issue
Block a user