update bullet so it actually works

Moved the addSourceDirectory for physics/Bullet into the Engine/Source/CMakeLists.txt file that way it can actually appear where we expect it to in the solution explorer.
This commit is contained in:
marauder2k7 2026-06-03 15:08:51 +01:00
parent c7be48130a
commit 13fa178cf6
5986 changed files with 1811270 additions and 453803 deletions

View file

@ -13,32 +13,30 @@ 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()
{
float dist = 41;
float pitch = 52;
float yaw = 35;
float targetPos[3]={0,0.46,0};
m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
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]);
}
};
@ -47,81 +45,78 @@ void BridgeExample::initPhysics()
m_guiHelper->setUpAxis(1);
createEmptyDynamicsWorld();
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
if (m_dynamicsWorld->getDebugDrawer())
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints);
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints);
///create a few basic rigid bodies
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0,-50,0));
groundTransform.setOrigin(btVector3(0, -50, 0));
{
btScalar mass(0.);
createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1));
createRigidBody(mass, groundTransform, groundShape, btVector4(0, 0, 1, 1));
}
//create two fixed boxes to hold the planks
{
//create a few dynamic rigidbodies
// Re-using the same collision is better for memory usage and performance
btScalar plankWidth = 0.4;
btScalar plankHeight = 0.2;
btScalar plankBreadth = 1;
btScalar plankOffset = plankWidth; //distance between two planks
btScalar bridgeWidth = plankWidth*TOTAL_PLANKS + plankOffset*(TOTAL_PLANKS-1);
btScalar plankOffset = plankWidth; //distance between two planks
btScalar bridgeWidth = plankWidth * TOTAL_PLANKS + plankOffset * (TOTAL_PLANKS - 1);
btScalar bridgeHeight = 5;
btScalar halfBridgeWidth = bridgeWidth*0.5f;
btScalar halfBridgeWidth = bridgeWidth * 0.5f;
btBoxShape* colShape = createBoxShape(btVector3(plankWidth, plankHeight, plankBreadth));
btBoxShape* colShape = createBoxShape(btVector3(plankWidth,plankHeight,plankBreadth));
m_collisionShapes.push_back(colShape);
/// Create Dynamic Objects
btTransform startTransform;
startTransform.setIdentity();
btScalar mass(1.f);
btScalar mass(1.f);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0,0,0);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
colShape->calculateLocalInertia(mass,localInertia);
colShape->calculateLocalInertia(mass, localInertia);
//create a set of boxes to represent bridge
//create a set of boxes to represent bridge
btAlignedObjectArray<btRigidBody*> boxes;
int lastBoxIndex = TOTAL_PLANKS-1;
for(int i=0;i<TOTAL_PLANKS;++i) {
float t = float(i)/lastBoxIndex;
t = -(t*2-1.0f) * halfBridgeWidth;
startTransform.setOrigin(btVector3(
btScalar(t),
bridgeHeight,
btScalar(0)
)
);
boxes.push_back(createRigidBody((i==0 || i==lastBoxIndex)?0:mass,startTransform,colShape));
}
int lastBoxIndex = TOTAL_PLANKS - 1;
for (int i = 0; i < TOTAL_PLANKS; ++i)
{
float t = float(i) / lastBoxIndex;
t = -(t * 2 - 1.0f) * halfBridgeWidth;
startTransform.setOrigin(btVector3(
btScalar(t),
bridgeHeight,
btScalar(0)));
boxes.push_back(createRigidBody((i == 0 || i == lastBoxIndex) ? 0 : mass, startTransform, colShape));
}
//add N-1 spring constraints
for(int i=0;i<TOTAL_PLANKS-1;++i) {
for (int i = 0; i < TOTAL_PLANKS - 1; ++i)
{
btRigidBody* b1 = boxes[i];
btRigidBody* b2 = boxes[i+1];
btPoint2PointConstraint* leftSpring = new btPoint2PointConstraint(*b1, *b2, btVector3(-0.5,0,-0.5), btVector3(0.5,0,-0.5));
btRigidBody* b2 = boxes[i + 1];
btPoint2PointConstraint* leftSpring = new btPoint2PointConstraint(*b1, *b2, btVector3(-0.5, 0, -0.5), btVector3(0.5, 0, -0.5));
m_dynamicsWorld->addConstraint(leftSpring);
btPoint2PointConstraint* rightSpring = new btPoint2PointConstraint(*b1, *b2, btVector3(-0.5,0,0.5), btVector3(0.5,0,0.5));
btPoint2PointConstraint* rightSpring = new btPoint2PointConstraint(*b1, *b2, btVector3(-0.5, 0, 0.5), btVector3(0.5, 0, 0.5));
m_dynamicsWorld->addConstraint(rightSpring);
}
}
@ -129,22 +124,12 @@ void BridgeExample::initPhysics()
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void BridgeExample::renderScene()
{
CommonRigidBodyBase::renderScene();
CommonRigidBodyBase::renderScene();
}
CommonExampleInterface* ET_BridgeCreateFunc(CommonExampleOptions& options)
CommonExampleInterface* ET_BridgeCreateFunc(CommonExampleOptions& options)
{
return new BridgeExample(options.m_guiHelper);
}

View file

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

View file

@ -13,32 +13,30 @@ 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()
{
float dist = 41;
float pitch = 52;
float yaw = 35;
float targetPos[3]={0,0.46,0};
m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
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]);
}
};
@ -47,67 +45,66 @@ void ChainExample::initPhysics()
m_guiHelper->setUpAxis(1);
createEmptyDynamicsWorld();
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
if (m_dynamicsWorld->getDebugDrawer())
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints);
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints);
///create a few basic rigid bodies
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0,-50,0));
groundTransform.setOrigin(btVector3(0, -50, 0));
{
btScalar mass(0.);
createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1));
createRigidBody(mass, groundTransform, groundShape, btVector4(0, 0, 1, 1));
}
{
//create a few dynamic rigidbodies
// Re-using the same collision is better for memory usage and performance
btBoxShape* colShape = createBoxShape(btVector3(1,1,0.25));
btBoxShape* colShape = createBoxShape(btVector3(1, 1, 0.25));
m_collisionShapes.push_back(colShape);
/// Create Dynamic Objects
btTransform startTransform;
startTransform.setIdentity();
btScalar mass(1.f);
btScalar mass(1.f);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0,0,0);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
colShape->calculateLocalInertia(mass,localInertia);
colShape->calculateLocalInertia(mass, localInertia);
btAlignedObjectArray<btRigidBody*> boxes;
int lastBoxIndex = TOTAL_BOXES-1;
for(int i=0;i<TOTAL_BOXES;++i) {
int lastBoxIndex = TOTAL_BOXES - 1;
for (int i = 0; i < TOTAL_BOXES; ++i)
{
startTransform.setOrigin(btVector3(
btScalar(0),
btScalar(5+i*2),
btScalar(0)
)
);
boxes.push_back(createRigidBody((i==lastBoxIndex)?0:mass,startTransform,colShape));
}
btScalar(0),
btScalar(5 + i * 2),
btScalar(0)));
boxes.push_back(createRigidBody((i == lastBoxIndex) ? 0 : mass, startTransform, colShape));
}
//add N-1 spring constraints
for(int i=0;i<TOTAL_BOXES-1;++i) {
for (int i = 0; i < TOTAL_BOXES - 1; ++i)
{
btRigidBody* b1 = boxes[i];
btRigidBody* b2 = boxes[i+1];
btPoint2PointConstraint* leftSpring = new btPoint2PointConstraint(*b1, *b2, btVector3(-0.5,1,0), btVector3(-0.5,-1,0));
btRigidBody* b2 = boxes[i + 1];
btPoint2PointConstraint* leftSpring = new btPoint2PointConstraint(*b1, *b2, btVector3(-0.5, 1, 0), btVector3(-0.5, -1, 0));
m_dynamicsWorld->addConstraint(leftSpring);
btPoint2PointConstraint* rightSpring = new btPoint2PointConstraint(*b1, *b2, btVector3(0.5,1,0), btVector3(0.5,-1,0));
btPoint2PointConstraint* rightSpring = new btPoint2PointConstraint(*b1, *b2, btVector3(0.5, 1, 0), btVector3(0.5, -1, 0));
m_dynamicsWorld->addConstraint(rightSpring);
}
@ -116,22 +113,12 @@ void ChainExample::initPhysics()
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void ChainExample::renderScene()
{
CommonRigidBodyBase::renderScene();
CommonRigidBodyBase::renderScene();
}
CommonExampleInterface* ET_ChainCreateFunc(CommonExampleOptions& options)
CommonExampleInterface* ET_ChainCreateFunc(CommonExampleOptions& options)
{
return new ChainExample(options.m_guiHelper);
}

View file

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

View file

@ -0,0 +1,125 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2015 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "CompoundBoxes.h"
#include "btBulletDynamicsCommon.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "../CommonInterfaces/CommonRigidBodyBase.h"
struct CompoundBoxesExample : public CommonRigidBodyBase
{
CompoundBoxesExample(struct GUIHelperInterface* helper)
: CommonRigidBodyBase(helper)
{
}
virtual ~CompoundBoxesExample() {}
virtual void initPhysics();
virtual void renderScene();
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]);
}
};
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);
///create a few basic rigid bodies
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));
{
btScalar mass(0.);
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));
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));
compoundShape->addChildShape(transform, cube);
transform.setIdentity();
transform.setOrigin(btVector3(0, -1, 0));
compoundShape->addChildShape(transform, cube);
transform.setIdentity();
transform.setOrigin(btVector3(0, 0, 1));
compoundShape->addChildShape(transform, cube);
btScalar masses[3] = {1, 1, 1};
btTransform principal;
btVector3 inertia;
compoundShape->calculatePrincipalAxisTransform(masses, principal, inertia);
// new compund shape to store
btCompoundShape* compound2 = new btCompoundShape();
m_collisionShapes.push_back(compound2);
#if 0
// less efficient way to add the entire compund shape
// to a new compund shape as a child
compound2->addChildShape(principal.inverse(), compoundShape);
#else
// recompute the shift to make sure the compound shape is re-aligned
for (int i = 0; i < compoundShape->getNumChildShapes(); i++)
compound2->addChildShape(compoundShape->getChildTransform(i) * principal.inverse(),
compoundShape->getChildShape(i));
#endif
delete compoundShape;
transform.setIdentity();
transform.setOrigin(btVector3(0, 10, 0));
createRigidBody(1.0, transform, compound2);
}
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void CompoundBoxesExample::renderScene()
{
CommonRigidBodyBase::renderScene();
}
CommonExampleInterface* ET_CompoundBoxesCreateFunc(CommonExampleOptions& options)
{
return new CompoundBoxesExample(options.m_guiHelper);
}

View file

@ -0,0 +1,21 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2015 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef ET_COMPOUND_BOXES_EXAMPLE_H
#define ET_COMPOUND_BOXES_EXAMPLE_H
class CommonExampleInterface* ET_CompoundBoxesCreateFunc(struct CommonExampleOptions& options);
#endif //ET_COMPOUND_BOXES_EXAMPLE_H

View file

@ -13,31 +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 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;
@ -47,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();
@ -59,128 +58,132 @@ struct InclinedPlaneExample : public CommonRigidBodyBase
void resetCamera()
{
float dist = 41;
float pitch = 52;
float yaw = 35;
float targetPos[3]={0,0.46,0};
m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
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]);
}
};
void onBoxFrictionChanged(float friction);
void onBoxFrictionChanged(float friction, void* userPtr);
void onBoxRestitutionChanged(float restitution);
void onBoxRestitutionChanged(float restitution, void* userPtr);
void onSphereFrictionChanged(float friction);
void onSphereFrictionChanged(float friction, void* userPtr);
void onSphereRestitutionChanged(float restitution);
void onSphereRestitutionChanged(float restitution, void* userPtr);
void onRampInclinationChanged(float inclination);
void onRampInclinationChanged(float inclination, void* userPtr);
void onRampFrictionChanged(float friction);
void onRampFrictionChanged(float friction, void* userPtr);
void onRampRestitutionChanged(float restitution);
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 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;
@ -188,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;
@ -217,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);
@ -236,17 +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();
@ -261,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();
@ -282,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){
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){
if(gBox){
void onBoxRestitutionChanged(float restitution, void*)
{
if (gBox)
{
gBox->setRestitution(restitution);
//b3Printf("Restitution of box changed to %f",restitution);
}
}
void onSphereFrictionChanged(float friction){
if(gSphere){
void onSphereFrictionChanged(float friction, void*)
{
if (gSphere)
{
gSphere->setFriction(friction);
//b3Printf("Friction of sphere changed to %f",friction );
}
}
void onSphereRestitutionChanged(float restitution){
if(gSphere){
void onSphereRestitutionChanged(float restitution, void*)
{
if (gSphere)
{
gSphere->setRestitution(restitution);
//b3Printf("Restitution of sphere changed to %f",restitution);
}
}
void onRampInclinationChanged(float inclination){
if(ramp){
void onRampInclinationChanged(float inclination, void*)
{
if (ramp)
{
btTransform startTransform;
startTransform.setIdentity();
@ -344,29 +358,32 @@ void onRampInclinationChanged(float inclination){
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){
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){
if(ramp){
void onRampRestitutionChanged(float restitution, void*)
{
if (ramp)
{
ramp->setRestitution(restitution);
//b3Printf("Restitution of ramp changed to %f \n",restitution);
}
}
CommonExampleInterface* ET_InclinedPlaneCreateFunc(CommonExampleOptions& options)
CommonExampleInterface* ET_InclinedPlaneCreateFunc(CommonExampleOptions& options)
{
return new InclinedPlaneExample(options.m_guiHelper);
}

View file

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

View file

@ -15,8 +15,9 @@
#include "MultiPendulum.h"
#include <vector> // TODO: Should I use another data structure?
#include <cmath>
#include <iterator>
#include <vector> // TODO: Should I use another data structure?
#include "btBulletDynamicsCommon.h"
#include "LinearMath/btVector3.h"
@ -24,84 +25,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 = 52;
float yaw = 35;
float targetPos[3] = { 0, 0.46, 0 };
m_guiHelper->resetCamera(dist, pitch, yaw, targetPos[0], targetPos[1],
targetPos[2]);
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]);
}
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); // Change the pendula length
void onMultiPendulaLengthChanged(float pendulaLength, void*); // Change the pendula length
void onMultiPendulaRestitutionChanged(float pendulaRestitution); // change the pendula restitution
void floorMSliderValue(float notUsed); // floor the slider values which should be integers
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_callback = floorMSliderValue; // hack to get integer values
slider.m_clampToNotches = false;
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_callback = floorMSliderValue; // hack to get integer values
slider.m_clampToNotches = false;
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;
@ -111,7 +112,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;
@ -121,7 +122,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;
@ -130,7 +131,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;
@ -147,41 +148,39 @@ 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);
m_collisionShapes.push_back(pendulumShape);
// create multi-pendulum
createMultiPendulum(pendulumShape, floor(gPendulaQty), position,
gInitialPendulumLength, pendulumMass);
createMultiPendulum(pendulumShape, std::floor(gPendulaQty), position,
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
@ -200,7 +199,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);
@ -213,25 +212,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);
@ -252,25 +252,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
@ -295,13 +295,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,
@ -318,77 +318,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));
}
@ -397,31 +409,30 @@ void MultiPendulumExample::applyPendulumForce(btScalar pendulumForce){
// GUI parameter modifiers
void onMultiPendulaLengthChanged(float pendulaLength) { // 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) { // change the pendula restitution
if (mex){
void onMultiPendulaRestitutionChanged(float pendulaRestitution, void*)
{ // change the pendula restitution
if (mex)
{
mex->changePendulaRestitution(pendulaRestitution);
}
}
void floorMSliderValue(float notUsed) { // floor the slider values which should be integers
gPendulaQty = floor(gPendulaQty);
gDisplacedPendula = floor(gDisplacedPendula);
}
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);
@ -429,7 +440,8 @@ void applyMForceWithForceScalar(float forceScalar) {
}
CommonExampleInterface* ET_MultiPendulumCreateFunc(
CommonExampleOptions& options) {
CommonExampleOptions& options)
{
mex = new MultiPendulumExample(options.m_guiHelper);
return mex;
}

View file

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

View file

@ -13,32 +13,30 @@ 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()
{
float dist = 41;
float pitch = 52;
float yaw = 35;
float targetPos[3]={0,0.46,0};
m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
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]);
}
};
@ -47,74 +45,63 @@ void MultipleBoxesExample::initPhysics()
m_guiHelper->setUpAxis(1);
createEmptyDynamicsWorld();
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
if (m_dynamicsWorld->getDebugDrawer())
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints);
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints);
///create a few basic rigid bodies
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0,-50,0));
groundTransform.setOrigin(btVector3(0, -50, 0));
{
btScalar mass(0.);
createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1));
createRigidBody(mass, groundTransform, groundShape, btVector4(0, 0, 1, 1));
}
{
//create a few dynamic rigidbodies
// Re-using the same collision is better for memory usage and performance
btBoxShape* colShape = createBoxShape(btVector3(1,1,1));
btBoxShape* colShape = createBoxShape(btVector3(1, 1, 1));
m_collisionShapes.push_back(colShape);
/// Create Dynamic Objects
btTransform startTransform;
startTransform.setIdentity();
btScalar mass(1.f);
btScalar mass(1.f);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0,0,0);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
colShape->calculateLocalInertia(mass,localInertia);
colShape->calculateLocalInertia(mass, localInertia);
for(int i=0;i<TOTAL_BOXES;++i) {
for (int i = 0; i < TOTAL_BOXES; ++i)
{
startTransform.setOrigin(btVector3(
btScalar(0),
btScalar(20+i*2),
btScalar(0)));
createRigidBody(mass,startTransform,colShape);
btScalar(0),
btScalar(20 + i * 2),
btScalar(0)));
createRigidBody(mass, startTransform, colShape);
}
}
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void MultipleBoxesExample::renderScene()
{
CommonRigidBodyBase::renderScene();
CommonRigidBodyBase::renderScene();
}
CommonExampleInterface* ET_MultipleBoxesCreateFunc(CommonExampleOptions& options)
CommonExampleInterface* ET_MultipleBoxesCreateFunc(CommonExampleOptions& options)
{
return new MultipleBoxesExample(options.m_guiHelper);
}

View file

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

View file

@ -15,38 +15,41 @@
#include "NewtonsCradle.h"
#include <vector> // TODO: Should I use another data structure?
#include <cmath>
#include <iterator>
#include <vector> // TODO: Should I use another data structure?
#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,52 +59,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 = 52;
float yaw = 35;
float targetPos[3] = { 0, 0.46, 0 };
m_guiHelper->resetCamera(dist, pitch, yaw, targetPos[0], targetPos[1],
targetPos[2]);
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]);
}
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); // Change the pendula length
void onPendulaLengthChanged(float pendulaLength, void* userPtr); // Change the pendula length
void onPendulaRestitutionChanged(float pendulaRestitution); // change the pendula restitution
void floorSliderValue(float notUsed); // floor the slider values which should be integers
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_callback = floorSliderValue; // hack to get integer values
slider.m_clampToNotches = false;
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_callback = floorSliderValue; // hack to get integer values
slider.m_clampToNotches = false;
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;
@ -111,7 +111,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;
@ -121,7 +121,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;
@ -130,7 +130,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;
@ -147,45 +147,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 < std::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
// |
@ -197,32 +195,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);
@ -238,8 +236,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 =
@ -248,9 +246,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,
@ -265,76 +263,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));
}
@ -343,30 +354,30 @@ void NewtonsCradleExample::applyPendulumForce(btScalar pendulumForce){
// GUI parameter modifiers
void onPendulaLengthChanged(float pendulaLength) {
if (nex){
void onPendulaLengthChanged(float pendulaLength, void*)
{
if (nex)
{
nex->changePendulaLength(pendulaLength);
//b3Printf("Pendula length changed to %f \n",sliderValue );
}
}
void onPendulaRestitutionChanged(float pendulaRestitution) {
if (nex){
void onPendulaRestitutionChanged(float pendulaRestitution, void*)
{
if (nex)
{
nex->changePendulaRestitution(pendulaRestitution);
}
}
void floorSliderValue(float notUsed) {
gPendulaQty = floor(gPendulaQty);
gDisplacedPendula = floor(gDisplacedPendula);
}
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);
@ -374,7 +385,8 @@ void applyForceWithForceScalar(float forceScalar) {
}
CommonExampleInterface* ET_NewtonsCradleCreateFunc(
CommonExampleOptions& options) {
CommonExampleOptions& options)
{
nex = new NewtonsCradleExample(options.m_guiHelper);
return nex;
}

View file

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

View file

@ -15,12 +15,13 @@
#include "NewtonsRopeCradle.h"
#include <vector> // TODO: Should I use another data structure?
#include <cmath>
#include <iterator>
#include <vector> // TODO: Should I use another data structure?
#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 +29,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 +62,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,65 +78,59 @@ 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 = 52;
float yaw = 35;
float targetPos[3]={0,0.46,0};
m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
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]);
}
std::vector<btSliderConstraint*> constraints;
std::vector<btRigidBody*> pendula;
btSoftBodyWorldInfo softBodyWorldInfo;
btSoftBodyWorldInfo softBodyWorldInfo;
};
static NewtonsRopeCradleExample* nex = NULL;
void onRopePendulaRestitutionChanged(float pendulaRestitution);
void floorRSliderValue(float notUsed);
void onRopePendulaRestitutionChanged(float pendulaRestitution, void*);
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_callback = floorRSliderValue; // hack to get integer values
slider.m_clampToNotches = false;
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_callback = floorRSliderValue; // hack to get integer values
slider.m_clampToNotches = false;
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;
@ -144,17 +140,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_clampToNotches = false;
slider.m_callback = floorRSliderValue;
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;
@ -163,7 +158,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;
@ -172,7 +167,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;
@ -180,8 +175,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;
@ -198,29 +193,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 < std::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);
}
}
@ -229,11 +221,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;
@ -244,18 +236,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
// \ /
@ -266,32 +259,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
@ -299,7 +291,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);
@ -311,44 +303,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));
}
@ -357,23 +357,21 @@ void NewtonsRopeCradleExample::applyPendulumForce(btScalar pendulumForce){
// GUI parameter modifiers
void onRopePendulaRestitutionChanged(float pendulaRestitution) {
if (nex){
void onRopePendulaRestitutionChanged(float pendulaRestitution, void*)
{
if (nex)
{
nex->changePendulaRestitution(pendulaRestitution);
}
}
void floorRSliderValue(float notUsed) {
gPendulaQty = floor(gPendulaQty);
gDisplacedPendula = floor(gDisplacedPendula);
gRopeResolution = floor(gRopeResolution);
}
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);
@ -381,7 +379,8 @@ void applyRForceWithForceScalar(float forceScalar) {
}
CommonExampleInterface* ET_NewtonsRopeCradleCreateFunc(
CommonExampleOptions& options) {
CommonExampleOptions& options)
{
nex = new NewtonsRopeCradleExample(options.m_guiHelper);
return nex;
}

View file

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

View file

@ -13,40 +13,38 @@ 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"
#include "Bullet3Common/b3FileUtils.h"
#include "../Importers/ImportObjDemo/LoadMeshFromObj.h"
#include "../OpenGLWindow/GLInstanceGraphicsShape.h"
#include "../Utils/b3BulletDefaultFileIO.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()
{
float dist = 11;
float pitch = 52;
float yaw = 35;
float targetPos[3]={0,0.46,0};
m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
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]);
}
};
@ -55,111 +53,99 @@ 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,0))
{
char pathPrefix[1024];
b3FileUtils::extractPath(relativeFileName, pathPrefix, 1024);
}
GLInstanceGraphicsShape* glmesh = LoadMeshFromObj(relativeFileName, "");
b3BulletDefaultFileIO fileIO;
GLInstanceGraphicsShape* glmesh = LoadMeshFromObj(relativeFileName, "",&fileIO);
printf("[INFO] Obj loaded: Extracted %d verticed from obj file [%s]\n", glmesh->m_numvertices, fileName);
const GLInstanceVertex& v = glmesh->m_vertices->at(0);
btConvexHullShape* shape = new btConvexHullShape((const btScalar*)(&(v.xyzw[0])), glmesh->m_numvertices, sizeof(GLInstanceVertex));
float scaling[4] = {0.1,0.1,0.1,1};
btVector3 localScaling(scaling[0],scaling[1],scaling[2]);
shape->setLocalScaling(localScaling);
if (m_options & OptimizeConvexObj)
{
shape->optimizeConvexHull();
}
float scaling[4] = {0.1, 0.1, 0.1, 1};
btVector3 localScaling(scaling[0], scaling[1], scaling[2]);
shape->setLocalScaling(localScaling);
if (m_options & OptimizeConvexObj)
{
shape->optimizeConvexHull();
}
if (m_options & ComputePolyhedralFeatures)
{
shape->initializePolyhedralFeatures();
}
if (m_options & ComputePolyhedralFeatures)
{
shape->initializePolyhedralFeatures();
}
//shape->setMargin(0.001);
m_collisionShapes.push_back(shape);
btTransform startTransform;
startTransform.setIdentity();
btScalar mass(1.f);
btScalar mass(1.f);
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0,0,0);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
shape->calculateLocalInertia(mass,localInertia);
shape->calculateLocalInertia(mass, localInertia);
float color[4] = {1,1,1,1};
float orn[4] = {0,0,0,1};
float pos[4] = {0,3,0,0};
btVector3 position(pos[0],pos[1],pos[2]);
float color[4] = {1, 1, 1, 1};
float orn[4] = {0, 0, 0, 1};
float pos[4] = {0, 3, 0, 0};
btVector3 position(pos[0], pos[1], pos[2]);
startTransform.setOrigin(position);
btRigidBody* body = createRigidBody(mass,startTransform,shape);
btRigidBody* body = createRigidBody(mass, startTransform, shape);
bool useConvexHullForRendering = ((m_options & ObjUseConvexHullForRendering) != 0);
bool useConvexHullForRendering = ((m_options & ObjUseConvexHullForRendering)!=0);
if (!useConvexHullForRendering)
{
int shapeId = m_guiHelper->registerGraphicsShape(&glmesh->m_vertices->at(0).xyzw[0],
glmesh->m_numvertices,
&glmesh->m_indices->at(0),
glmesh->m_numIndices,
B3_GL_TRIANGLES, -1);
{
int shapeId = m_guiHelper->registerGraphicsShape(&glmesh->m_vertices->at(0).xyzw[0],
glmesh->m_numvertices,
&glmesh->m_indices->at(0),
glmesh->m_numIndices,
B3_GL_TRIANGLES, -1);
shape->setUserIndex(shapeId);
int renderInstance = m_guiHelper->registerGraphicsInstance(shapeId,pos,orn,color,scaling);
int renderInstance = m_guiHelper->registerGraphicsInstance(shapeId, pos, orn, color, scaling);
body->setUserIndex(renderInstance);
}
}
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void RigidBodyFromObjExample::renderScene()
{
CommonRigidBodyBase::renderScene();
CommonRigidBodyBase::renderScene();
}
CommonExampleInterface* ET_RigidBodyFromObjCreateFunc(CommonExampleOptions& options)
CommonExampleInterface* ET_RigidBodyFromObjCreateFunc(CommonExampleOptions& options)
{
return new RigidBodyFromObjExample(options.m_guiHelper,options.m_option);
return new RigidBodyFromObjExample(options.m_guiHelper, options.m_option);
}
B3_STANDALONE_EXAMPLE(ET_RigidBodyFromObjCreateFunc)

View file

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

View file

@ -13,32 +13,29 @@ 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()
{
float dist = 41;
float pitch = 52;
float yaw = 35;
float targetPos[3]={0,0.46,0};
m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
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]);
}
};
@ -47,72 +44,60 @@ void SimpleBoxExample::initPhysics()
m_guiHelper->setUpAxis(1);
createEmptyDynamicsWorld();
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
if (m_dynamicsWorld->getDebugDrawer())
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints);
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints);
///create a few basic rigid bodies
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0,-50,0));
groundTransform.setOrigin(btVector3(0, -50, 0));
{
btScalar mass(0.);
createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1));
createRigidBody(mass, groundTransform, groundShape, btVector4(0, 0, 1, 1));
}
{
//create a few dynamic rigidbodies
// Re-using the same collision is better for memory usage and performance
btBoxShape* colShape = createBoxShape(btVector3(1,1,1));
btBoxShape* colShape = createBoxShape(btVector3(1, 1, 1));
m_collisionShapes.push_back(colShape);
/// Create Dynamic Objects
btTransform startTransform;
startTransform.setIdentity();
btScalar mass(1.f);
btScalar mass(1.f);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0,0,0);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
colShape->calculateLocalInertia(mass,localInertia);
colShape->calculateLocalInertia(mass, localInertia);
startTransform.setOrigin(btVector3(
btScalar(0),
btScalar(20),
btScalar(0)));
createRigidBody(mass,startTransform,colShape);
btScalar(0),
btScalar(20),
btScalar(0)));
createRigidBody(mass, startTransform, colShape);
}
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void SimpleBoxExample::renderScene()
{
CommonRigidBodyBase::renderScene();
CommonRigidBodyBase::renderScene();
}
CommonExampleInterface* ET_SimpleBoxCreateFunc(CommonExampleOptions& options)
CommonExampleInterface* ET_SimpleBoxCreateFunc(CommonExampleOptions& options)
{
return new SimpleBoxExample(options.m_guiHelper);
}

View file

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

View file

@ -13,13 +13,11 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#include "SimpleCloth.h"
#include "btBulletDynamicsCommon.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "../CommonInterfaces/CommonRigidBodyBase.h"
#include "BulletSoftBody/btSoftRigidDynamicsWorld.h"
@ -29,21 +27,21 @@ subject to the following restrictions:
struct SimpleClothExample : public CommonRigidBodyBase
{
SimpleClothExample(struct GUIHelperInterface* helper)
:CommonRigidBodyBase(helper)
: CommonRigidBodyBase(helper)
{
}
virtual ~SimpleClothExample(){}
virtual ~SimpleClothExample() {}
virtual void initPhysics();
virtual void renderScene();
void createEmptyDynamicsWorld()
{
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase();
m_solver = new btSequentialImpulseConstraintSolver;
m_solver = new btSequentialImpulseConstraintSolver;
m_dynamicsWorld = new btSoftRigidDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration);
m_dynamicsWorld->setGravity(btVector3(0, -10, 0));
@ -52,22 +50,22 @@ struct SimpleClothExample : public CommonRigidBodyBase
softBodyWorldInfo.m_gravity = m_dynamicsWorld->getGravity();
softBodyWorldInfo.m_sparsesdf.Initialize();
}
virtual btSoftRigidDynamicsWorld* getSoftDynamicsWorld()
virtual btSoftRigidDynamicsWorld* getSoftDynamicsWorld()
{
///just make it a btSoftRigidDynamicsWorld please
///or we will add type checking
return (btSoftRigidDynamicsWorld*) m_dynamicsWorld;
return (btSoftRigidDynamicsWorld*)m_dynamicsWorld;
}
void resetCamera()
{
float dist = 41;
float pitch = 52;
float yaw = 35;
float targetPos[3]={0,0.46,0};
m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
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]);
}
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,56 +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->generateBendingConstraints(2,cloth->appendMaterial());
cloth->setTotalMass(10);
cloth->getCollisionShape()->setUserPointer((void*)cloth);
cloth->generateBendingConstraints(2, cloth->appendMaterial());
cloth->setTotalMass(10);
//cloth->m_cfg.citerations = 10;
// cloth->m_cfg.diterations = 10;
// cloth->m_cfg.diterations = 10;
cloth->m_cfg.piterations = 5;
cloth->m_cfg.kDP = 0.005f;
getSoftDynamicsWorld()->addSoftBody(cloth);
}
void SimpleClothExample::renderScene()
{
CommonRigidBodyBase::renderScene();
CommonRigidBodyBase::renderScene();
btSoftRigidDynamicsWorld* softWorld = getSoftDynamicsWorld();
for ( int i=0;i<softWorld->getSoftBodyArray().size();i++)
for (int i = 0; i < softWorld->getSoftBodyArray().size(); i++)
{
btSoftBody* psb = (btSoftBody*)softWorld->getSoftBodyArray()[i];
//if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe)))
{
btSoftBody* psb=(btSoftBody*)softWorld->getSoftBodyArray()[i];
//if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe)))
{
btSoftBodyHelpers::DrawFrame(psb,softWorld->getDebugDrawer());
btSoftBodyHelpers::Draw(psb,softWorld->getDebugDrawer(),softWorld->getDrawFlags());
}
btSoftBodyHelpers::DrawFrame(psb, softWorld->getDebugDrawer());
btSoftBodyHelpers::Draw(psb, softWorld->getDebugDrawer(), softWorld->getDrawFlags());
}
}
}
CommonExampleInterface* ET_SimpleClothCreateFunc(CommonExampleOptions& options)
CommonExampleInterface* ET_SimpleClothCreateFunc(CommonExampleOptions& options)
{
return new SimpleClothExample(options.m_guiHelper);
}

View file

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

View file

@ -13,32 +13,29 @@ 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()
{
float dist = 41;
float pitch = 52;
float yaw = 35;
float targetPos[3]={0,0.46,0};
m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
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]);
}
};
@ -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);
}

View file

@ -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

View file

@ -17,6 +17,7 @@ language "C++"
files {
"RigidBodyFromObj.cpp",
"../CommonInterfaces/*",
"**.h",
"../StandaloneMain/main_console_single_example.cpp",
"../Utils/b3ResourcePath.cpp",
@ -24,10 +25,10 @@ files {
"../RenderingExamples/TimeSeriesCanvas.cpp",
"../RenderingExamples/TimeSeriesFontData.cpp",
"../MultiBody/InvertedPendulumPDControl.cpp",
"../ThirdPartyLibs/tinyxml/tinystr.cpp",
"../ThirdPartyLibs/tinyxml/tinyxml.cpp",
"../ThirdPartyLibs/tinyxml/tinyxmlerror.cpp",
"../ThirdPartyLibs/tinyxml/tinyxmlparser.cpp",
"../ThirdPartyLibs/tinyxml2/tinystr.cpp",
"../ThirdPartyLibs/tinyxml2/tinyxml.cpp",
"../ThirdPartyLibs/tinyxml2/tinyxmlerror.cpp",
"../ThirdPartyLibs/tinyxml2/tinyxmlparser.cpp",
"../ThirdPartyLibs/Wavefront/tiny_obj_loader.cpp",
"../ThirdPartyLibs/Wavefront/tiny_obj_loader.h",
"../Importers/ImportColladaDemo/LoadMeshFromCollada.cpp",
@ -68,6 +69,7 @@ files {
"RigidBodyFromObj.cpp",
"*.h",
"../StandaloneMain/main_opengl_single_example.cpp",
"../CommonInterfaces/*",
"../ExampleBrowser/OpenGLGuiHelper.cpp",
"../ExampleBrowser/GL_ShapeDrawer.cpp",
"../ExampleBrowser/CollisionShape2TriangleMesh.cpp",
@ -76,10 +78,10 @@ files {
"../RenderingExamples/TimeSeriesCanvas.cpp",
"../RenderingExamples/TimeSeriesFontData.cpp",
"../MultiBody/InvertedPendulumPDControl.cpp",
"../ThirdPartyLibs/tinyxml/tinystr.cpp",
"../ThirdPartyLibs/tinyxml/tinyxml.cpp",
"../ThirdPartyLibs/tinyxml/tinyxmlerror.cpp",
"../ThirdPartyLibs/tinyxml/tinyxmlparser.cpp",
"../ThirdPartyLibs/tinyxml2/tinystr.cpp",
"../ThirdPartyLibs/tinyxml2/tinyxml.cpp",
"../ThirdPartyLibs/tinyxml2/tinyxmlerror.cpp",
"../ThirdPartyLibs/tinyxml2/tinyxmlparser.cpp",
"../ThirdPartyLibs/Wavefront/tiny_obj_loader.cpp",
"../ThirdPartyLibs/Wavefront/tiny_obj_loader.h",
"../Importers/ImportColladaDemo/LoadMeshFromCollada.cpp",
@ -132,6 +134,7 @@ files {
"../ExampleBrowser/OpenGLGuiHelper.cpp",
"../ExampleBrowser/GL_ShapeDrawer.cpp",
"../ExampleBrowser/CollisionShape2TriangleMesh.cpp",
"../CommonInterfaces/*",
"../TinyRenderer/geometry.cpp",
"../TinyRenderer/model.cpp",
"../TinyRenderer/tgaimage.cpp",
@ -143,10 +146,10 @@ files {
"../RenderingExamples/TimeSeriesCanvas.cpp",
"../RenderingExamples/TimeSeriesFontData.cpp",
"../MultiBody/InvertedPendulumPDControl.cpp",
"../ThirdPartyLibs/tinyxml/tinystr.cpp",
"../ThirdPartyLibs/tinyxml/tinyxml.cpp",
"../ThirdPartyLibs/tinyxml/tinyxmlerror.cpp",
"../ThirdPartyLibs/tinyxml/tinyxmlparser.cpp",
"../ThirdPartyLibs/tinyxml2/tinystr.cpp",
"../ThirdPartyLibs/tinyxml2/tinyxml.cpp",
"../ThirdPartyLibs/tinyxml2/tinyxmlerror.cpp",
"../ThirdPartyLibs/tinyxml2/tinyxmlparser.cpp",
"../ThirdPartyLibs/Wavefront/tiny_obj_loader.cpp",
"../ThirdPartyLibs/Wavefront/tiny_obj_loader.h",
"../Importers/ImportColladaDemo/LoadMeshFromCollada.cpp",
@ -193,6 +196,7 @@ files {
"../StandaloneMain/main_tinyrenderer_single_example.cpp",
"../OpenGLWindow/SimpleCamera.cpp",
"../ExampleBrowser/CollisionShape2TriangleMesh.cpp",
"../CommonInterfaces/*",
"../TinyRenderer/geometry.cpp",
"../TinyRenderer/model.cpp",
"../TinyRenderer/tgaimage.cpp",
@ -204,10 +208,10 @@ files {
"../RenderingExamples/TimeSeriesCanvas.cpp",
"../RenderingExamples/TimeSeriesFontData.cpp",
"../MultiBody/InvertedPendulumPDControl.cpp",
"../ThirdPartyLibs/tinyxml/tinystr.cpp",
"../ThirdPartyLibs/tinyxml/tinyxml.cpp",
"../ThirdPartyLibs/tinyxml/tinyxmlerror.cpp",
"../ThirdPartyLibs/tinyxml/tinyxmlparser.cpp",
"../ThirdPartyLibs/tinyxml2/tinystr.cpp",
"../ThirdPartyLibs/tinyxml2/tinyxml.cpp",
"../ThirdPartyLibs/tinyxml2/tinyxmlerror.cpp",
"../ThirdPartyLibs/tinyxml2/tinyxmlparser.cpp",
"../ThirdPartyLibs/Wavefront/tiny_obj_loader.cpp",
"../ThirdPartyLibs/Wavefront/tiny_obj_loader.h",
"../Importers/ImportColladaDemo/LoadMeshFromCollada.cpp",