* Adjustment: Initial CMake reworking.

This commit is contained in:
Robert MacGregor 2022-05-13 23:42:41 -04:00
parent 516163fd5d
commit d7cdf54661
5394 changed files with 2615532 additions and 8711 deletions

View file

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

View file

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

View file

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

View file

@ -0,0 +1,148 @@
#ifndef GUI_HELPER_INTERFACE_H
#define GUI_HELPER_INTERFACE_H
class btRigidBody;
class btVector3;
class btCollisionObject;
class btDiscreteDynamicsWorld;
class btCollisionShape;
struct Common2dCanvasInterface;
struct CommonParameterInterface;
struct CommonRenderInterface;
struct CommonGraphicsApp;
///The Bullet 2 GraphicsPhysicsBridge let's the graphics engine create graphics representation and synchronize
struct GUIHelperInterface
{
virtual ~GUIHelperInterface() {}
virtual void createRigidBodyGraphicsObject(btRigidBody* body,const btVector3& color) = 0;
virtual void createCollisionObjectGraphicsObject(btCollisionObject* obj,const btVector3& color) = 0;
virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape)=0;
virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld)=0;
virtual void render(const btDiscreteDynamicsWorld* rbWorld)=0;
virtual void createPhysicsDebugDrawer( btDiscreteDynamicsWorld* rbWorld)=0;
virtual int registerTexture(const unsigned char* texels, int width, int height)=0;
virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices,int primitiveType, int textureId) = 0;
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) =0;
virtual void removeAllGraphicsInstances()=0;
virtual Common2dCanvasInterface* get2dCanvasInterface()=0;
virtual CommonParameterInterface* getParameterInterface()=0;
virtual CommonRenderInterface* getRenderInterface()=0;
virtual CommonGraphicsApp* getAppInterface()=0;
virtual void setUpAxis(int axis)=0;
virtual void resetCamera(float camDist, float pitch, float yaw, float camPosX,float camPosY, float camPosZ)=0;
virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
float* depthBuffer, int depthBufferSizeInPixels,
int startPixelIndex, int destinationWidth, int destinationHeight, int* numPixelsCopied)
{
copyCameraImageData(viewMatrix,projectionMatrix,pixelsRGBA,rgbaBufferSizeInPixels,
depthBuffer,depthBufferSizeInPixels,
0,0,
startPixelIndex,destinationWidth,
destinationHeight,numPixelsCopied);
}
virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
float* depthBuffer, int depthBufferSizeInPixels,
int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels,
int startPixelIndex, int destinationWidth, int destinationHeight, int* numPixelsCopied)=0;
virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld) =0;
virtual void drawText3D( const char* txt, float posX, float posZY, float posZ, float size)=0;
};
///the DummyGUIHelper does nothing, so we can test the examples without GUI/graphics (in 'console mode')
struct DummyGUIHelper : public GUIHelperInterface
{
DummyGUIHelper() {}
virtual ~DummyGUIHelper() {}
virtual void createRigidBodyGraphicsObject(btRigidBody* body,const btVector3& color){}
virtual void createCollisionObjectGraphicsObject(btCollisionObject* obj,const btVector3& color) {}
virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape){}
virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld){}
virtual void render(const btDiscreteDynamicsWorld* rbWorld) {}
virtual void createPhysicsDebugDrawer( btDiscreteDynamicsWorld* rbWorld){}
virtual int registerTexture(const unsigned char* texels, int width, int height){return -1;}
virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices,int primitiveType, int textureId){return -1;}
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) {return -1;}
virtual void removeAllGraphicsInstances(){}
virtual Common2dCanvasInterface* get2dCanvasInterface()
{
return 0;
}
virtual CommonParameterInterface* getParameterInterface()
{
return 0;
}
virtual CommonRenderInterface* getRenderInterface()
{
return 0;
}
virtual CommonGraphicsApp* getAppInterface()
{
return 0;
}
virtual void setUpAxis(int axis)
{
}
virtual void resetCamera(float camDist, float pitch, float yaw, float camPosX,float camPosY, float camPosZ)
{
}
virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
float* depthBuffer, int depthBufferSizeInPixels,
int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels,
int startPixelIndex, int width, int height, int* numPixelsCopied)
{
if (numPixelsCopied)
*numPixelsCopied = 0;
}
virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld)
{
}
virtual void drawText3D( const char* txt, float posX, float posZY, float posZ, float size)
{
}
};
#endif //GUI_HELPER_INTERFACE_H

View file

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

View file

@ -0,0 +1,472 @@
#ifndef COMMON_MULTI_BODY_SETUP_H
#define COMMON_MULTI_BODY_SETUP_H
#include "btBulletDynamicsCommon.h"
#include "BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h"
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
#include "BulletDynamics/Featherstone/btMultiBodyPoint2Point.h"
#include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h"
#include "btBulletDynamicsCommon.h"
#include "CommonExampleInterface.h"
#include "CommonGUIHelperInterface.h"
#include "CommonRenderInterface.h"
#include "CommonGraphicsAppInterface.h"
#include "CommonWindowInterface.h"
#include "CommonCameraInterface.h"
struct CommonMultiBodyBase : public CommonExampleInterface
{
//keep the collision shapes, for deletion/cleanup
btAlignedObjectArray<btCollisionShape*> m_collisionShapes;
btBroadphaseInterface* m_broadphase;
btCollisionDispatcher* m_dispatcher;
btMultiBodyConstraintSolver* m_solver;
btDefaultCollisionConfiguration* m_collisionConfiguration;
btMultiBodyDynamicsWorld* m_dynamicsWorld;
//data for picking objects
class btRigidBody* m_pickedBody;
class btTypedConstraint* m_pickedConstraint;
class btMultiBodyPoint2Point* m_pickingMultiBodyPoint2Point;
btVector3 m_oldPickingPos;
btVector3 m_hitPos;
btScalar m_oldPickingDist;
bool m_prevCanSleep;
struct GUIHelperInterface* m_guiHelper;
CommonMultiBodyBase(GUIHelperInterface* helper)
:m_broadphase(0),
m_dispatcher(0),
m_solver(0),
m_collisionConfiguration(0),
m_dynamicsWorld(0),
m_pickedBody(0),
m_pickedConstraint(0),
m_pickingMultiBodyPoint2Point(0),
m_prevCanSleep(false),
m_guiHelper(helper)
{
}
virtual void createEmptyDynamicsWorld()
{
///collision configuration contains default setup for memory, collision setup
m_collisionConfiguration = new btDefaultCollisionConfiguration();
//m_collisionConfiguration->setConvexConvexMultipointIterations();
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase();//btSimpleBroadphase();
m_solver = new btMultiBodyConstraintSolver;
m_dynamicsWorld = new btMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration);
m_dynamicsWorld->setGravity(btVector3(0, -10, 0));
}
virtual void stepSimulation(float deltaTime)
{
if (m_dynamicsWorld)
{
m_dynamicsWorld->stepSimulation(deltaTime);
}
}
virtual void exitPhysics()
{
removePickingConstraint();
//cleanup in the reverse order of creation/initialization
//remove the rigidbodies from the dynamics world and delete them
if (m_dynamicsWorld)
{
int i;
for (i = m_dynamicsWorld->getNumConstraints() - 1; i >= 0; i--)
{
m_dynamicsWorld->removeConstraint(m_dynamicsWorld->getConstraint(i));
}
for (i = m_dynamicsWorld->getNumMultiBodyConstraints() - 1; i >= 0; i--)
{
btMultiBodyConstraint* mbc = m_dynamicsWorld->getMultiBodyConstraint(i);
m_dynamicsWorld->removeMultiBodyConstraint(mbc);
delete mbc;
}
for (i = m_dynamicsWorld->getNumMultibodies() - 1; i >= 0; i--)
{
btMultiBody* mb = m_dynamicsWorld->getMultiBody(i);
m_dynamicsWorld->removeMultiBody(mb);
delete mb;
}
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
{
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
if (body && body->getMotionState())
{
delete body->getMotionState();
}
m_dynamicsWorld->removeCollisionObject(obj);
delete obj;
}
}
//delete collision shapes
for (int j = 0; j<m_collisionShapes.size(); j++)
{
btCollisionShape* shape = m_collisionShapes[j];
delete shape;
}
m_collisionShapes.clear();
delete m_dynamicsWorld;
m_dynamicsWorld = 0;
delete m_solver;
m_solver=0;
delete m_broadphase;
m_broadphase=0;
delete m_dispatcher;
m_dispatcher=0;
delete m_collisionConfiguration;
m_collisionConfiguration=0;
}
virtual void syncPhysicsToGraphics()
{
if (m_dynamicsWorld)
{
m_guiHelper->syncPhysicsToGraphics(m_dynamicsWorld);
}
}
virtual void renderScene()
{
if (m_dynamicsWorld)
{
m_guiHelper->syncPhysicsToGraphics(m_dynamicsWorld);
m_guiHelper->render(m_dynamicsWorld);
}
}
virtual void physicsDebugDraw(int debugDrawFlags)
{
if (m_dynamicsWorld)
{
if (m_dynamicsWorld->getDebugDrawer())
{
m_dynamicsWorld->getDebugDrawer()->setDebugMode(debugDrawFlags);
}
m_dynamicsWorld->debugDrawWorld();
}
}
virtual bool keyboardCallback(int key, int state)
{
return false;//don't handle this key
}
btVector3 getRayTo(int x,int y)
{
CommonRenderInterface* renderer = m_guiHelper->getRenderInterface();
if (!renderer)
{
btAssert(0);
return btVector3(0,0,0);
}
float top = 1.f;
float bottom = -1.f;
float nearPlane = 1.f;
float tanFov = (top-bottom)*0.5f / nearPlane;
float fov = btScalar(2.0) * btAtan(tanFov);
btVector3 camPos,camTarget;
renderer->getActiveCamera()->getCameraPosition(camPos);
renderer->getActiveCamera()->getCameraTargetPosition(camTarget);
btVector3 rayFrom = camPos;
btVector3 rayForward = (camTarget-camPos);
rayForward.normalize();
float farPlane = 10000.f;
rayForward*= farPlane;
btVector3 rightOffset;
btVector3 cameraUp=btVector3(0,0,0);
cameraUp[m_guiHelper->getAppInterface()->getUpAxis()]=1;
btVector3 vertical = cameraUp;
btVector3 hor;
hor = rayForward.cross(vertical);
hor.normalize();
vertical = hor.cross(rayForward);
vertical.normalize();
float tanfov = tanf(0.5f*fov);
hor *= 2.f * farPlane * tanfov;
vertical *= 2.f * farPlane * tanfov;
btScalar aspect;
float width = float(renderer->getScreenWidth());
float height = float (renderer->getScreenHeight());
aspect = width / height;
hor*=aspect;
btVector3 rayToCenter = rayFrom + rayForward;
btVector3 dHor = hor * 1.f/width;
btVector3 dVert = vertical * 1.f/height;
btVector3 rayTo = rayToCenter - 0.5f * hor + 0.5f * vertical;
rayTo += btScalar(x) * dHor;
rayTo -= btScalar(y) * dVert;
return rayTo;
}
virtual bool mouseMoveCallback(float x,float y)
{
CommonRenderInterface* renderer = m_guiHelper->getRenderInterface();
if (!renderer)
{
btAssert(0);
return false;
}
btVector3 rayTo = getRayTo(int(x), int(y));
btVector3 rayFrom;
renderer->getActiveCamera()->getCameraPosition(rayFrom);
movePickedBody(rayFrom,rayTo);
return false;
}
virtual bool mouseButtonCallback(int button, int state, float x, float y)
{
CommonRenderInterface* renderer = m_guiHelper->getRenderInterface();
if (!renderer)
{
btAssert(0);
return false;
}
CommonWindowInterface* window = m_guiHelper->getAppInterface()->m_window;
if (state==1)
{
if(button==0 && (!window->isModifierKeyPressed(B3G_ALT) && !window->isModifierKeyPressed(B3G_CONTROL) ))
{
btVector3 camPos;
renderer->getActiveCamera()->getCameraPosition(camPos);
btVector3 rayFrom = camPos;
btVector3 rayTo = getRayTo(int(x),int(y));
pickBody(rayFrom, rayTo);
}
} else
{
if (button==0)
{
removePickingConstraint();
//remove p2p
}
}
//printf("button=%d, state=%d\n",button,state);
return false;
}
virtual bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)
{
if (m_dynamicsWorld==0)
return false;
btCollisionWorld::ClosestRayResultCallback rayCallback(rayFromWorld, rayToWorld);
m_dynamicsWorld->rayTest(rayFromWorld, rayToWorld, rayCallback);
if (rayCallback.hasHit())
{
btVector3 pickPos = rayCallback.m_hitPointWorld;
btRigidBody* body = (btRigidBody*)btRigidBody::upcast(rayCallback.m_collisionObject);
if (body)
{
//other exclusions?
if (!(body->isStaticObject() || body->isKinematicObject()))
{
m_pickedBody = body;
m_pickedBody->setActivationState(DISABLE_DEACTIVATION);
//printf("pickPos=%f,%f,%f\n",pickPos.getX(),pickPos.getY(),pickPos.getZ());
btVector3 localPivot = body->getCenterOfMassTransform().inverse() * pickPos;
btPoint2PointConstraint* p2p = new btPoint2PointConstraint(*body, localPivot);
m_dynamicsWorld->addConstraint(p2p, true);
m_pickedConstraint = p2p;
btScalar mousePickClamping = 30.f;
p2p->m_setting.m_impulseClamp = mousePickClamping;
//very weak constraint for picking
p2p->m_setting.m_tau = 0.001f;
}
} else
{
btMultiBodyLinkCollider* multiCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(rayCallback.m_collisionObject);
if (multiCol && multiCol->m_multiBody)
{
m_prevCanSleep = multiCol->m_multiBody->getCanSleep();
multiCol->m_multiBody->setCanSleep(false);
btVector3 pivotInA = multiCol->m_multiBody->worldPosToLocal(multiCol->m_link, pickPos);
btMultiBodyPoint2Point* p2p = new btMultiBodyPoint2Point(multiCol->m_multiBody,multiCol->m_link,0,pivotInA,pickPos);
//if you add too much energy to the system, causing high angular velocities, simulation 'explodes'
//see also http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=4&t=949
//so we try to avoid it by clamping the maximum impulse (force) that the mouse pick can apply
//it is not satisfying, hopefully we find a better solution (higher order integrator, using joint friction using a zero-velocity target motor with limited force etc?)
btScalar scaling=1;
p2p->setMaxAppliedImpulse(2*scaling);
btMultiBodyDynamicsWorld* world = (btMultiBodyDynamicsWorld*) m_dynamicsWorld;
world->addMultiBodyConstraint(p2p);
m_pickingMultiBodyPoint2Point =p2p;
}
}
// pickObject(pickPos, rayCallback.m_collisionObject);
m_oldPickingPos = rayToWorld;
m_hitPos = pickPos;
m_oldPickingDist = (pickPos - rayFromWorld).length();
// printf("hit !\n");
//add p2p
}
return false;
}
virtual bool movePickedBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)
{
if (m_pickedBody && m_pickedConstraint)
{
btPoint2PointConstraint* pickCon = static_cast<btPoint2PointConstraint*>(m_pickedConstraint);
if (pickCon)
{
//keep it at the same picking distance
btVector3 dir = rayToWorld-rayFromWorld;
dir.normalize();
dir *= m_oldPickingDist;
btVector3 newPivotB = rayFromWorld + dir;
pickCon->setPivotB(newPivotB);
}
}
if (m_pickingMultiBodyPoint2Point)
{
//keep it at the same picking distance
btVector3 dir = rayToWorld-rayFromWorld;
dir.normalize();
dir *= m_oldPickingDist;
btVector3 newPivotB = rayFromWorld + dir;
m_pickingMultiBodyPoint2Point->setPivotInB(newPivotB);
}
return false;
}
virtual void removePickingConstraint()
{
if (m_pickedConstraint)
{
m_dynamicsWorld->removeConstraint(m_pickedConstraint);
delete m_pickedConstraint;
m_pickedConstraint = 0;
m_pickedBody = 0;
}
if (m_pickingMultiBodyPoint2Point)
{
m_pickingMultiBodyPoint2Point->getMultiBodyA()->setCanSleep(m_prevCanSleep);
btMultiBodyDynamicsWorld* world = (btMultiBodyDynamicsWorld*) m_dynamicsWorld;
world->removeMultiBodyConstraint(m_pickingMultiBodyPoint2Point);
delete m_pickingMultiBodyPoint2Point;
m_pickingMultiBodyPoint2Point = 0;
}
}
btBoxShape* createBoxShape(const btVector3& halfExtents)
{
btBoxShape* box = new btBoxShape(halfExtents);
return box;
}
btRigidBody* createRigidBody(float mass, const btTransform& startTransform, btCollisionShape* shape, const btVector4& color = btVector4(1, 0, 0, 1))
{
btAssert((!shape || shape->getShapeType() != INVALID_SHAPE_PROXYTYPE));
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
shape->calculateLocalInertia(mass, localInertia);
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
#define USE_MOTIONSTATE 1
#ifdef USE_MOTIONSTATE
btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
btRigidBody::btRigidBodyConstructionInfo cInfo(mass, myMotionState, shape, localInertia);
btRigidBody* body = new btRigidBody(cInfo);
//body->setContactProcessingThreshold(m_defaultContactProcessingThreshold);
#else
btRigidBody* body = new btRigidBody(mass, 0, shape, localInertia);
body->setWorldTransform(startTransform);
#endif//
body->setUserIndex(-1);
m_dynamicsWorld->addRigidBody(body);
return body;
}
};
#endif //COMMON_MULTI_BODY_SETUP_H

View file

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

View file

@ -0,0 +1,119 @@
#ifndef COMMON_RENDER_INTERFACE_H
#define COMMON_RENDER_INTERFACE_H
struct CommonCameraInterface;
enum
{
B3_GL_TRIANGLES = 1,
B3_GL_POINTS
};
enum
{
B3_DEFAULT_RENDERMODE=1,
//B3_WIREFRAME_RENDERMODE,
B3_CREATE_SHADOWMAP_RENDERMODE,
B3_USE_SHADOWMAP_RENDERMODE,
};
struct CommonRenderInterface
{
virtual void init()=0;
virtual void updateCamera(int upAxis)=0;
virtual void removeAllInstances() = 0;
virtual const CommonCameraInterface* getActiveCamera() const =0;
virtual CommonCameraInterface* getActiveCamera()=0;
virtual void setActiveCamera(CommonCameraInterface* cam)=0;
virtual void renderScene()=0;
virtual void renderSceneInternal(int renderMode=B3_DEFAULT_RENDERMODE){};
virtual int getScreenWidth() = 0;
virtual int getScreenHeight() = 0;
virtual void resize(int width, int height) = 0;
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling)=0;
virtual int registerGraphicsInstance(int shapeIndex, const double* position, const double* quaternion, const double* color, const double* scaling)=0;
virtual void drawLines(const float* positions, const float color[4], int numPoints, int pointStrideInBytes, const unsigned int* indices, int numIndices, float pointDrawSize)=0;
virtual void drawLine(const float from[4], const float to[4], const float color[4], float lineWidth) = 0;
virtual void drawLine(const double from[4], const double to[4], const double color[4], double lineWidth) = 0;
virtual void drawPoint(const float* position, const float color[4], float pointDrawSize)=0;
virtual void drawPoint(const double* position, const double color[4], double pointDrawSize)=0;
virtual int registerShape(const float* vertices, int numvertices, const int* indices, int numIndices,int primitiveType=B3_GL_TRIANGLES, int textureIndex=-1)=0;
virtual void updateShape(int shapeIndex, const float* vertices)=0;
virtual int registerTexture(const unsigned char* texels, int width, int height)=0;
virtual void updateTexture(int textureIndex, const unsigned char* texels)=0;
virtual void activateTexture(int textureIndex)=0;
virtual void writeSingleInstanceTransformToCPU(const float* position, const float* orientation, int srcIndex)=0;
virtual void writeSingleInstanceTransformToCPU(const double* position, const double* orientation, int srcIndex)=0;
virtual void writeSingleInstanceColorToCPU(float* color, int srcIndex)=0;
virtual void writeSingleInstanceColorToCPU(double* color, int srcIndex)=0;
virtual void writeSingleInstanceScaleToCPU(float* scale, int srcIndex)=0;
virtual void writeSingleInstanceScaleToCPU(double* scale, int srcIndex)=0;
virtual int getTotalNumInstances() const = 0;
virtual void writeTransforms()=0;
virtual void enableBlend(bool blend)=0;
virtual void clearZBuffer()=0;
//This is internal access to OpenGL3+ features, mainly used for OpenCL-OpenGL interop
//Only the GLInstancingRenderer supports it, just return 0 otherwise.
virtual struct GLInstanceRendererInternalData* getInternalData()=0;
};
template <typename T>
inline int projectWorldCoordToScreen(T objx, T objy, T objz,
const T modelMatrix[16],
const T projMatrix[16],
const int viewport[4],
T *winx, T *winy, T *winz)
{
int i;
T in2[4];
T tmp[4];
in2[0]=objx;
in2[1]=objy;
in2[2]=objz;
in2[3]=T(1.0);
for (i=0; i<4; i++)
{
tmp[i] = in2[0] * modelMatrix[0*4+i] + in2[1] * modelMatrix[1*4+i] +
in2[2] * modelMatrix[2*4+i] + in2[3] * modelMatrix[3*4+i];
}
T out[4];
for (i=0; i<4; i++)
{
out[i] = tmp[0] * projMatrix[0*4+i] + tmp[1] * projMatrix[1*4+i] + tmp[2] * projMatrix[2*4+i] + tmp[3] * projMatrix[3*4+i];
}
if (out[3] == T(0.0))
return 0;
out[0] /= out[3];
out[1] /= out[3];
out[2] /= out[3];
/* Map x, y and z to range 0-1 */
out[0] = out[0] * T(0.5) + T(0.5);
out[1] = out[1] * T(0.5) + T(0.5);
out[2] = out[2] * T(0.5) + T(0.5);
/* Map x,y to viewport */
out[0] = out[0] * viewport[2] + viewport[0];
out[1] = out[1] * viewport[3] + viewport[1];
*winx=out[0];
*winy=out[1];
*winz=out[2];
return 1;
}
#endif//COMMON_RENDER_INTERFACE_H

View file

@ -0,0 +1,462 @@
#ifndef COMMON_RIGID_BODY_BASE_H
#define COMMON_RIGID_BODY_BASE_H
#include "btBulletDynamicsCommon.h"
#include "CommonExampleInterface.h"
#include "CommonGUIHelperInterface.h"
#include "CommonRenderInterface.h"
#include "CommonCameraInterface.h"
#include "CommonGraphicsAppInterface.h"
#include "CommonWindowInterface.h"
struct CommonRigidBodyBase : public CommonExampleInterface
{
//keep the collision shapes, for deletion/cleanup
btAlignedObjectArray<btCollisionShape*> m_collisionShapes;
btBroadphaseInterface* m_broadphase;
btCollisionDispatcher* m_dispatcher;
btConstraintSolver* m_solver;
btDefaultCollisionConfiguration* m_collisionConfiguration;
btDiscreteDynamicsWorld* m_dynamicsWorld;
//data for picking objects
class btRigidBody* m_pickedBody;
class btTypedConstraint* m_pickedConstraint;
int m_savedState;
btVector3 m_oldPickingPos;
btVector3 m_hitPos;
btScalar m_oldPickingDist;
struct GUIHelperInterface* m_guiHelper;
CommonRigidBodyBase(struct GUIHelperInterface* helper)
:m_broadphase(0),
m_dispatcher(0),
m_solver(0),
m_collisionConfiguration(0),
m_dynamicsWorld(0),
m_pickedBody(0),
m_pickedConstraint(0),
m_guiHelper(helper)
{
}
virtual ~CommonRigidBodyBase()
{
}
btDiscreteDynamicsWorld* getDynamicsWorld()
{
return m_dynamicsWorld;
}
virtual void createEmptyDynamicsWorld()
{
///collision configuration contains default setup for memory, collision setup
m_collisionConfiguration = new btDefaultCollisionConfiguration();
//m_collisionConfiguration->setConvexConvexMultipointIterations();
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase();
///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver;
m_solver = sol;
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration);
m_dynamicsWorld->setGravity(btVector3(0, -10, 0));
}
virtual void stepSimulation(float deltaTime)
{
if (m_dynamicsWorld)
{
m_dynamicsWorld->stepSimulation(deltaTime);
}
}
virtual void physicsDebugDraw(int debugFlags)
{
if (m_dynamicsWorld && m_dynamicsWorld->getDebugDrawer())
{
m_dynamicsWorld->getDebugDrawer()->setDebugMode(debugFlags);
m_dynamicsWorld->debugDrawWorld();
}
}
virtual void exitPhysics()
{
removePickingConstraint();
//cleanup in the reverse order of creation/initialization
//remove the rigidbodies from the dynamics world and delete them
if (m_dynamicsWorld)
{
int i;
for (i = m_dynamicsWorld->getNumConstraints() - 1; i >= 0; i--)
{
m_dynamicsWorld->removeConstraint(m_dynamicsWorld->getConstraint(i));
}
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
{
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
if (body && body->getMotionState())
{
delete body->getMotionState();
}
m_dynamicsWorld->removeCollisionObject(obj);
delete obj;
}
}
//delete collision shapes
for (int j = 0; j<m_collisionShapes.size(); j++)
{
btCollisionShape* shape = m_collisionShapes[j];
delete shape;
}
m_collisionShapes.clear();
delete m_dynamicsWorld;
m_dynamicsWorld=0;
delete m_solver;
m_solver=0;
delete m_broadphase;
m_broadphase=0;
delete m_dispatcher;
m_dispatcher=0;
delete m_collisionConfiguration;
m_collisionConfiguration=0;
}
virtual void debugDraw(int debugDrawFlags)
{
if (m_dynamicsWorld)
{
if (m_dynamicsWorld->getDebugDrawer())
{
m_dynamicsWorld->getDebugDrawer()->setDebugMode(debugDrawFlags);
}
m_dynamicsWorld->debugDrawWorld();
}
}
virtual bool keyboardCallback(int key, int state)
{
if ((key==B3G_F3) && state && m_dynamicsWorld)
{
btDefaultSerializer* serializer = new btDefaultSerializer();
m_dynamicsWorld->serialize(serializer);
FILE* file = fopen("testFile.bullet","wb");
fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1, file);
fclose(file);
//b3Printf("btDefaultSerializer wrote testFile.bullet");
delete serializer;
return true;
}
return false;//don't handle this key
}
btVector3 getRayTo(int x,int y)
{
CommonRenderInterface* renderer = m_guiHelper->getRenderInterface();
if (!renderer)
{
btAssert(0);
return btVector3(0,0,0);
}
float top = 1.f;
float bottom = -1.f;
float nearPlane = 1.f;
float tanFov = (top-bottom)*0.5f / nearPlane;
float fov = btScalar(2.0) * btAtan(tanFov);
btVector3 camPos,camTarget;
renderer->getActiveCamera()->getCameraPosition(camPos);
renderer->getActiveCamera()->getCameraTargetPosition(camTarget);
btVector3 rayFrom = camPos;
btVector3 rayForward = (camTarget-camPos);
rayForward.normalize();
float farPlane = 10000.f;
rayForward*= farPlane;
btVector3 rightOffset;
btVector3 cameraUp=btVector3(0,0,0);
cameraUp[m_guiHelper->getAppInterface()->getUpAxis()]=1;
btVector3 vertical = cameraUp;
btVector3 hor;
hor = rayForward.cross(vertical);
hor.safeNormalize();
vertical = hor.cross(rayForward);
vertical.safeNormalize();
float tanfov = tanf(0.5f*fov);
hor *= 2.f * farPlane * tanfov;
vertical *= 2.f * farPlane * tanfov;
btScalar aspect;
float width = float(renderer->getScreenWidth());
float height = float (renderer->getScreenHeight());
aspect = width / height;
hor*=aspect;
btVector3 rayToCenter = rayFrom + rayForward;
btVector3 dHor = hor * 1.f/width;
btVector3 dVert = vertical * 1.f/height;
btVector3 rayTo = rayToCenter - 0.5f * hor + 0.5f * vertical;
rayTo += btScalar(x) * dHor;
rayTo -= btScalar(y) * dVert;
return rayTo;
}
virtual bool mouseMoveCallback(float x,float y)
{
CommonRenderInterface* renderer = m_guiHelper->getRenderInterface();
if (!renderer)
{
btAssert(0);
return false;
}
btVector3 rayTo = getRayTo(int(x), int(y));
btVector3 rayFrom;
renderer->getActiveCamera()->getCameraPosition(rayFrom);
movePickedBody(rayFrom,rayTo);
return false;
}
virtual bool mouseButtonCallback(int button, int state, float x, float y)
{
CommonRenderInterface* renderer = m_guiHelper->getRenderInterface();
if (!renderer)
{
btAssert(0);
return false;
}
CommonWindowInterface* window = m_guiHelper->getAppInterface()->m_window;
#if 0
if (window->isModifierKeyPressed(B3G_ALT))
{
printf("ALT pressed\n");
} else
{
printf("NO ALT pressed\n");
}
if (window->isModifierKeyPressed(B3G_SHIFT))
{
printf("SHIFT pressed\n");
} else
{
printf("NO SHIFT pressed\n");
}
if (window->isModifierKeyPressed(B3G_CONTROL))
{
printf("CONTROL pressed\n");
} else
{
printf("NO CONTROL pressed\n");
}
#endif
if (state==1)
{
if(button==0 && (!window->isModifierKeyPressed(B3G_ALT) && !window->isModifierKeyPressed(B3G_CONTROL) ))
{
btVector3 camPos;
renderer->getActiveCamera()->getCameraPosition(camPos);
btVector3 rayFrom = camPos;
btVector3 rayTo = getRayTo(int(x),int(y));
pickBody(rayFrom, rayTo);
}
} else
{
if (button==0)
{
removePickingConstraint();
//remove p2p
}
}
//printf("button=%d, state=%d\n",button,state);
return false;
}
virtual bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)
{
if (m_dynamicsWorld==0)
return false;
btCollisionWorld::ClosestRayResultCallback rayCallback(rayFromWorld, rayToWorld);
m_dynamicsWorld->rayTest(rayFromWorld, rayToWorld, rayCallback);
if (rayCallback.hasHit())
{
btVector3 pickPos = rayCallback.m_hitPointWorld;
btRigidBody* body = (btRigidBody*)btRigidBody::upcast(rayCallback.m_collisionObject);
if (body)
{
//other exclusions?
if (!(body->isStaticObject() || body->isKinematicObject()))
{
m_pickedBody = body;
m_savedState = m_pickedBody->getActivationState();
m_pickedBody->setActivationState(DISABLE_DEACTIVATION);
//printf("pickPos=%f,%f,%f\n",pickPos.getX(),pickPos.getY(),pickPos.getZ());
btVector3 localPivot = body->getCenterOfMassTransform().inverse() * pickPos;
btPoint2PointConstraint* p2p = new btPoint2PointConstraint(*body, localPivot);
m_dynamicsWorld->addConstraint(p2p, true);
m_pickedConstraint = p2p;
btScalar mousePickClamping = 30.f;
p2p->m_setting.m_impulseClamp = mousePickClamping;
//very weak constraint for picking
p2p->m_setting.m_tau = 0.001f;
}
}
// pickObject(pickPos, rayCallback.m_collisionObject);
m_oldPickingPos = rayToWorld;
m_hitPos = pickPos;
m_oldPickingDist = (pickPos - rayFromWorld).length();
// printf("hit !\n");
//add p2p
}
return false;
}
virtual bool movePickedBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)
{
if (m_pickedBody && m_pickedConstraint)
{
btPoint2PointConstraint* pickCon = static_cast<btPoint2PointConstraint*>(m_pickedConstraint);
if (pickCon)
{
//keep it at the same picking distance
btVector3 newPivotB;
btVector3 dir = rayToWorld - rayFromWorld;
dir.normalize();
dir *= m_oldPickingDist;
newPivotB = rayFromWorld + dir;
pickCon->setPivotB(newPivotB);
return true;
}
}
return false;
}
virtual void removePickingConstraint()
{
if (m_pickedConstraint)
{
m_pickedBody->forceActivationState(m_savedState);
m_pickedBody->activate();
m_dynamicsWorld->removeConstraint(m_pickedConstraint);
delete m_pickedConstraint;
m_pickedConstraint = 0;
m_pickedBody = 0;
}
}
btBoxShape* createBoxShape(const btVector3& halfExtents)
{
btBoxShape* box = new btBoxShape(halfExtents);
return box;
}
btRigidBody* createRigidBody(float mass, const btTransform& startTransform, btCollisionShape* shape, const btVector4& color = btVector4(1, 0, 0, 1))
{
btAssert((!shape || shape->getShapeType() != INVALID_SHAPE_PROXYTYPE));
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
shape->calculateLocalInertia(mass, localInertia);
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
#define USE_MOTIONSTATE 1
#ifdef USE_MOTIONSTATE
btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
btRigidBody::btRigidBodyConstructionInfo cInfo(mass, myMotionState, shape, localInertia);
btRigidBody* body = new btRigidBody(cInfo);
//body->setContactProcessingThreshold(m_defaultContactProcessingThreshold);
#else
btRigidBody* body = new btRigidBody(mass, 0, shape, localInertia);
body->setWorldTransform(startTransform);
#endif//
body->setUserIndex(-1);
m_dynamicsWorld->addRigidBody(body);
return body;
}
virtual void renderScene()
{
{
m_guiHelper->syncPhysicsToGraphics(m_dynamicsWorld);
}
{
m_guiHelper->render(m_dynamicsWorld);
}
}
};
#endif //COMMON_RIGID_BODY_SETUP_H

View file

@ -0,0 +1,130 @@
#ifndef B3G_WINDOW_INTERFACE_H
#define B3G_WINDOW_INTERFACE_H
typedef void (*b3WheelCallback)(float deltax, float deltay);
typedef void (*b3ResizeCallback)( float width, float height);
typedef void (*b3MouseMoveCallback)( float x, float y);
typedef void (*b3MouseButtonCallback)(int button, int state, float x, float y);
typedef void (*b3KeyboardCallback)(int keycode, int state);
typedef void (*b3RenderCallback) ();
enum {
B3G_ESCAPE = 27,
B3G_F1 = 0xff00,
B3G_F2,
B3G_F3,
B3G_F4,
B3G_F5,
B3G_F6,
B3G_F7,
B3G_F8,
B3G_F9,
B3G_F10,
B3G_F11,
B3G_F12,
B3G_F13,
B3G_F14,
B3G_F15,
B3G_LEFT_ARROW,
B3G_RIGHT_ARROW,
B3G_UP_ARROW,
B3G_DOWN_ARROW,
B3G_PAGE_UP,
B3G_PAGE_DOWN,
B3G_END,
B3G_HOME,
B3G_INSERT,
B3G_DELETE,
B3G_BACKSPACE,
B3G_SHIFT,
B3G_CONTROL,
B3G_ALT,
B3G_RETURN
};
struct b3gWindowConstructionInfo
{
int m_width;
int m_height;
bool m_fullscreen;
int m_colorBitsPerPixel;
void* m_windowHandle;
const char* m_title;
int m_openglVersion;
b3gWindowConstructionInfo(int width=1024, int height=768)
:m_width(width),
m_height(height),
m_fullscreen(false),
m_colorBitsPerPixel(32),
m_windowHandle(0),
m_title("title"),
m_openglVersion(3)
{
}
};
class CommonWindowInterface
{
public:
virtual ~CommonWindowInterface()
{
}
virtual void createDefaultWindow(int width, int height, const char* title)
{
b3gWindowConstructionInfo ci(width,height);
ci.m_title = title;
createWindow(ci);
}
virtual void createWindow(const b3gWindowConstructionInfo& ci)=0;
virtual void closeWindow()=0;
virtual void runMainLoop()=0;
virtual float getTimeInSeconds()=0;
virtual bool requestedExit() const = 0;
virtual void setRequestExit() = 0;
virtual void startRendering()=0;
virtual void endRendering()=0;
virtual bool isModifierKeyPressed(int key) = 0;
virtual void setMouseMoveCallback(b3MouseMoveCallback mouseCallback)=0;
virtual b3MouseMoveCallback getMouseMoveCallback()=0;
virtual void setMouseButtonCallback(b3MouseButtonCallback mouseCallback)=0;
virtual b3MouseButtonCallback getMouseButtonCallback()=0;
virtual void setResizeCallback(b3ResizeCallback resizeCallback)=0;
virtual b3ResizeCallback getResizeCallback()=0;
virtual void setWheelCallback(b3WheelCallback wheelCallback)=0;
virtual b3WheelCallback getWheelCallback()=0;
virtual void setKeyboardCallback( b3KeyboardCallback keyboardCallback)=0;
virtual b3KeyboardCallback getKeyboardCallback()=0;
virtual void setRenderCallback( b3RenderCallback renderCallback) = 0;
virtual void setWindowTitle(const char* title)=0;
virtual float getRetinaScale() const =0;
virtual void setAllowRetina(bool allow) =0;
virtual int getWidth() const = 0;
virtual int getHeight() const = 0;
virtual int fileOpenDialog(char* fileName, int maxFileNameLength) = 0;
};
#endif //B3G_WINDOW_INTERFACE_H