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:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -13,23 +13,20 @@ subject to the following restrictions:
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "SimpleJoint.h"
|
||||
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "LinearMath/btVector3.h"
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
#include "../CommonInterfaces/CommonRigidBodyBase.h"
|
||||
|
||||
|
||||
struct SimpleJointExample : public CommonRigidBodyBase
|
||||
{
|
||||
SimpleJointExample(struct GUIHelperInterface* helper)
|
||||
:CommonRigidBodyBase(helper)
|
||||
: CommonRigidBodyBase(helper)
|
||||
{
|
||||
}
|
||||
virtual ~SimpleJointExample(){}
|
||||
virtual ~SimpleJointExample() {}
|
||||
virtual void initPhysics();
|
||||
virtual void renderScene();
|
||||
void resetCamera()
|
||||
@@ -37,8 +34,8 @@ struct SimpleJointExample : 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,63 +44,61 @@ void SimpleJointExample::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(10),
|
||||
btScalar(0)));
|
||||
btRigidBody* dynamicBox = createRigidBody(mass,startTransform,colShape);
|
||||
btScalar(0),
|
||||
btScalar(10),
|
||||
btScalar(0)));
|
||||
btRigidBody* dynamicBox = createRigidBody(mass, startTransform, colShape);
|
||||
|
||||
//create a static rigid body
|
||||
mass = 0;
|
||||
startTransform.setOrigin(btVector3(
|
||||
btScalar(0),
|
||||
btScalar(20),
|
||||
btScalar(0)));
|
||||
|
||||
btRigidBody* staticBox = createRigidBody(mass,startTransform,colShape);
|
||||
btScalar(0),
|
||||
btScalar(20),
|
||||
btScalar(0)));
|
||||
|
||||
btRigidBody* staticBox = createRigidBody(mass, startTransform, colShape);
|
||||
|
||||
//create a simple p2pjoint constraint
|
||||
btPoint2PointConstraint* p2p = new btPoint2PointConstraint(*dynamicBox, *staticBox, btVector3(0,3,0), btVector3(0,0,0));
|
||||
btPoint2PointConstraint* p2p = new btPoint2PointConstraint(*dynamicBox, *staticBox, btVector3(0, 3, 0), btVector3(0, 0, 0));
|
||||
p2p->m_setting.m_damping = 0.0625;
|
||||
p2p->m_setting.m_impulseClamp = 0.95;
|
||||
m_dynamicsWorld->addConstraint(p2p);
|
||||
@@ -112,22 +107,12 @@ void SimpleJointExample::initPhysics()
|
||||
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
|
||||
}
|
||||
|
||||
|
||||
void SimpleJointExample::renderScene()
|
||||
{
|
||||
CommonRigidBodyBase::renderScene();
|
||||
CommonRigidBodyBase::renderScene();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
CommonExampleInterface* ET_SimpleJointCreateFunc(CommonExampleOptions& options)
|
||||
CommonExampleInterface* ET_SimpleJointCreateFunc(CommonExampleOptions& options)
|
||||
{
|
||||
return new SimpleJointExample(options.m_guiHelper);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ subject to the following restrictions:
|
||||
#ifndef ET_SIMPLE_JOINT_EXAMPLE_H
|
||||
#define ET_SIMPLE_JOINT_EXAMPLE_H
|
||||
|
||||
class CommonExampleInterface* ET_SimpleJointCreateFunc(struct CommonExampleOptions& options);
|
||||
class CommonExampleInterface* ET_SimpleJointCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
|
||||
#endif //ET_SIMPLE_JOINT_EXAMPLE_H
|
||||
#endif //ET_SIMPLE_JOINT_EXAMPLE_H
|
||||
|
||||
Reference in New Issue
Block a user