Merge branch 'master' into 3D-NN-walkers-example

This commit is contained in:
Benelot
2017-05-28 15:10:45 +02:00
895 changed files with 953183 additions and 13171 deletions

View File

@@ -60,7 +60,7 @@ SET(AppBasicExampleGui_SRCS
ADD_DEFINITIONS(-DB3_USE_STANDALONE_EXAMPLE)
LINK_LIBRARIES(
BulletDynamics BulletCollision LinearMath OpenGLWindow Bullet3Common ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}
BulletDynamics BulletCollision LinearMath OpenGLWindow Bullet3Common
)
#some code to support OpenGL and Glew cross platform
@@ -69,11 +69,12 @@ IF (WIN32)
${BULLET_PHYSICS_SOURCE_DIR}/btgui/OpenGLWindow/GlewWindows
)
ADD_DEFINITIONS(-DGLEW_STATIC)
LINK_LIBRARIES( ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} )
ELSE(WIN32)
IF(APPLE)
find_library(COCOA NAMES Cocoa)
MESSAGE(${COCOA})
link_libraries(${COCOA})
link_libraries(${COCOA} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY})
ELSE(APPLE)
INCLUDE_DIRECTORIES(
@@ -83,7 +84,7 @@ ELSE(WIN32)
ADD_DEFINITIONS("-DGLEW_STATIC")
ADD_DEFINITIONS("-DGLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS=1")
LINK_LIBRARIES( X11 pthread dl Xext)
LINK_LIBRARIES( pthread ${DL} )
ENDIF(APPLE)
ENDIF(WIN32)

View File

@@ -187,12 +187,14 @@ files {
"../ThirdPartyLibs/openvr/samples/shared/lodepng.h",
"../ThirdPartyLibs/openvr/samples/shared/Matrices.cpp",
"../ThirdPartyLibs/openvr/samples/shared/Matrices.h",
"../ThirdPartyLibs/openvr/samples/shared/strtools.cpp",
"../ThirdPartyLibs/openvr/samples/shared/pathtools.cpp",
"../ThirdPartyLibs/openvr/samples/shared/pathtools.h",
"../ThirdPartyLibs/openvr/samples/shared/Vectors.h",
"../Utils/b3Clock.cpp",
"../Utils/b3Clock.h",
"../Utils/ChromeTraceUtil.cpp",
"../Utils/ChromeTraceUtil.h",
}
if os.is("Windows") then

View File

@@ -210,9 +210,13 @@ public:
{
for ( int i = iBegin; i < iEnd; ++i )
{
btCollisionWorld::ClosestRayResultCallback cb(source[i], dest[i]);
cw->rayTest (source[i], dest[i], cb);
{
BT_PROFILE("cw->rayTest");
cw->rayTest(source[i], dest[i], cb);
}
if (cb.hasHit ())
{
hit[i] = cb.m_hitPointWorld;
@@ -228,9 +232,10 @@ public:
struct CastRaysLoopBody
{
btRaycastBar2* mRaycasts;
btCollisionWorld* mWorld;
CastRaysLoopBody(btCollisionWorld* cw, btRaycastBar2* rb) : mWorld(cw), mRaycasts(rb) {}
btRaycastBar2* mRaycasts;
CastRaysLoopBody(btCollisionWorld* cw, btRaycastBar2* rb) : mWorld(cw), mRaycasts(rb) {}
void forLoop( int iBegin, int iEnd ) const
{
@@ -240,6 +245,8 @@ public:
void cast (btCollisionWorld* cw, bool multiThreading = false)
{
BT_PROFILE("cast");
#ifdef USE_BT_CLOCK
frame_timer.reset ();
#endif //USE_BT_CLOCK
@@ -319,7 +326,7 @@ public:
indices.push_back(indices.size());
}
m_guiHelper->getRenderInterface()->drawLines(&points[0].m_floats[0],lineColor,points.size(),sizeof(btVector3),&indices[0],indices.size(),1);
m_guiHelper->getRenderInterface()->drawLines(&points[0].m_floats[0],lineColor,points.size(),sizeof(btVector3FloatData),&indices[0],indices.size(),1);
}
#if 0

View File

@@ -1,6 +1,17 @@
SUBDIRS( HelloWorld BasicDemo )
IF(BUILD_BULLET3)
SUBDIRS( ExampleBrowser ThirdPartyLibs/Gwen ThirdPartyLibs/BussIK OpenGLWindow )
SET(DL dl)
IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
SET(OSDEF -D_LINUX)
ELSE(CMAKE_SYSTEM_NAME MATCHES "Linux")
IF(APPLE)
SET(OSDEF -D_DARWIN)
ELSE(APPLE)
SET(OSDEF -D_BSD)
SET(DL "")
ENDIF(APPLE)
ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux")
SUBDIRS( ExampleBrowser RobotSimulator SharedMemory ThirdPartyLibs/Gwen ThirdPartyLibs/BussIK ThirdPartyLibs/clsocket OpenGLWindow )
ENDIF()
IF(BUILD_PYBULLET)
SUBDIRS(pybullet)

View File

@@ -61,8 +61,8 @@ class CollisionTutorialBullet2 : public CommonExampleInterface
plCollisionSdkHandle m_collisionSdkHandle;
plCollisionWorldHandle m_collisionWorldHandle;
int m_stage;
int m_counter;
// int m_stage;
// int m_counter;
public:
@@ -70,11 +70,11 @@ public:
:m_app(guiHelper->getAppInterface()),
m_guiHelper(guiHelper),
m_tutorialIndex(tutorialIndex),
m_timeSeriesCanvas0(0),
m_collisionSdkHandle(0),
m_collisionWorldHandle(0),
m_stage(0),
m_counter(0),
m_timeSeriesCanvas0(0)
m_collisionWorldHandle(0)
// m_stage(0),
// m_counter(0)
{
gTotalPoints = 0;

View File

@@ -6,13 +6,14 @@ struct Bullet2CollisionSdkInternalData
btCollisionConfiguration* m_collisionConfig;
btCollisionDispatcher* m_dispatcher;
btBroadphaseInterface* m_aabbBroadphase;
btCollisionWorld* m_collisionWorld;
Bullet2CollisionSdkInternalData()
:m_aabbBroadphase(0),
m_dispatcher(0),
m_collisionWorld(0)
:
m_collisionConfig(0),
m_dispatcher(0),
m_aabbBroadphase(0),
m_collisionWorld(0)
{
}
};

View File

@@ -53,13 +53,19 @@ struct RTB3CollisionWorld
b3AlignedObjectArray<b3Aabb> m_worldSpaceAabbs;
b3AlignedObjectArray<b3GpuFace> m_planeFaces;
b3AlignedObjectArray<b3CompoundOverlappingPair> m_compoundOverlappingPairs;
int m_nextFreeShapeIndex;
union
{
int m_nextFreeShapeIndex;
void* m_nextFreeShapePtr;
};
int m_nextFreeCollidableIndex;
int m_nextFreePlaneFaceIndex;
RTB3CollisionWorld()
:m_nextFreeCollidableIndex(START_COLLIDABLE_INDEX),
:
m_nextFreeShapeIndex(START_SHAPE_INDEX),
m_nextFreeCollidableIndex(START_COLLIDABLE_INDEX),
m_nextFreePlaneFaceIndex(0)//this value is never exposed to the user, so we can start from 0
{
}
@@ -125,7 +131,8 @@ plCollisionShapeHandle RealTimeBullet3CollisionSdk::createSphereShape(plCollisio
shape.m_childOrientation.setValue(0,0,0,1);
shape.m_radius = radius;
shape.m_shapeType = RTB3_SHAPE_SPHERE;
return (plCollisionShapeHandle) world->m_nextFreeShapeIndex++;
world->m_nextFreeShapeIndex++;
return (plCollisionShapeHandle) world->m_nextFreeShapePtr;
}
return 0;
}
@@ -147,7 +154,8 @@ plCollisionShapeHandle RealTimeBullet3CollisionSdk::createPlaneShape(plCollision
world->m_planeFaces[world->m_nextFreePlaneFaceIndex].m_plane = b3MakeVector4(planeNormalX,planeNormalY,planeNormalZ,planeConstant);
shape.m_shapeIndex = world->m_nextFreePlaneFaceIndex++;
shape.m_shapeType = RTB3_SHAPE_PLANE;
return (plCollisionShapeHandle) world->m_nextFreeShapeIndex++;
world->m_nextFreeShapeIndex++;
return (plCollisionShapeHandle)world->m_nextFreeShapePtr ;
}
return 0;
}
@@ -169,7 +177,8 @@ plCollisionShapeHandle RealTimeBullet3CollisionSdk::createCapsuleShape(plCollisi
shape.m_height = height;
shape.m_shapeIndex = capsuleAxis;
shape.m_shapeType = RTB3_SHAPE_CAPSULE;
return (plCollisionShapeHandle) world->m_nextFreeShapeIndex++;
world->m_nextFreeShapeIndex++;
return (plCollisionShapeHandle) world->m_nextFreeShapePtr;
}
return 0;
}
@@ -186,7 +195,8 @@ plCollisionShapeHandle RealTimeBullet3CollisionSdk::createCompoundShape(plCollis
shape.m_childOrientation.setValue(0,0,0,1);
shape.m_numChildShapes = 0;
shape.m_shapeType = RTB3_SHAPE_COMPOUND_INTERNAL;
return (plCollisionShapeHandle) world->m_nextFreeShapeIndex++;
world->m_nextFreeShapeIndex++;
return (plCollisionShapeHandle) world->m_nextFreeShapePtr;
}
return 0;
}
@@ -265,7 +275,8 @@ plCollisionObjectHandle RealTimeBullet3CollisionSdk::createCollisionObject( plC
collidable.m_shapeIndex = shape.m_shapeIndex;
break;
*/
return (plCollisionObjectHandle)world->m_nextFreeCollidableIndex++;
world->m_nextFreeCollidableIndex++;
return (plCollisionObjectHandle)world->m_nextFreeShapePtr;
}
return 0;
}

View File

@@ -0,0 +1,47 @@
#ifndef COMMON_CALLBACKS_H
#define COMMON_CALLBACKS_H
typedef void (*b3WheelCallback)(float deltax, float deltay);
typedef void (*b3ResizeCallback)( float width, float height);
typedef void (*b3MouseMoveCallback)( float x, float y);
typedef void (*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
};
#endif

View File

@@ -24,6 +24,8 @@ struct CommonCameraInterface
virtual void setCameraUpVector(float x,float y, float z) = 0;
virtual void getCameraUpVector(float up[3]) const = 0;
virtual void getCameraForwardVector(float fwd[3]) const = 0;
///the setCameraUpAxis will call the 'setCameraUpVector' and 'setCameraForwardVector'
virtual void setCameraUpAxis(int axis) = 0;
virtual int getCameraUpAxis() const = 0;
@@ -36,6 +38,9 @@ struct CommonCameraInterface
virtual void setAspectRatio(float ratio) = 0;
virtual float getAspectRatio() const = 0;
virtual float getCameraFrustumFar() const = 0;
virtual float getCameraFrustumNear() const = 0;
};
#endif //COMMON_CAMERA_INTERFACE_H

View File

@@ -37,6 +37,7 @@ public:
virtual void initPhysics()=0;
virtual void exitPhysics()=0;
virtual void updateGraphics(){}
virtual void stepSimulation(float deltaTime)=0;
virtual void renderScene()=0;
virtual void physicsDebugDraw(int debugFlags)=0;//for now we reuse the flags in Bullet/src/LinearMath/btIDebugDraw.h
@@ -48,6 +49,8 @@ public:
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 vrHMDMoveCallback(int controllerId, float pos[4], float orientation[4]){}
virtual void vrGenericTrackerMoveCallback(int controllerId, float pos[4], float orientation[4]){}
virtual void processCommandLineArgs(int argc, char* argv[]){};
};

View File

@@ -12,6 +12,10 @@ struct CommonParameterInterface;
struct CommonRenderInterface;
struct CommonGraphicsApp;
typedef void (*VisualizerFlagCallback)(int flag, bool enable);
///The Bullet 2 GraphicsPhysicsBridge let's the graphics engine create graphics representation and synchronize
struct GUIHelperInterface
{
@@ -33,6 +37,8 @@ struct GUIHelperInterface
virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices,int primitiveType, int textureId) = 0;
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) =0;
virtual void removeAllGraphicsInstances()=0;
virtual void removeGraphicsInstance(int graphicsUid) {}
virtual void changeRGBAColor(int instanceUid, const double rgbaColor[4]) {}
virtual Common2dCanvasInterface* get2dCanvasInterface()=0;
@@ -40,12 +46,24 @@ struct GUIHelperInterface
virtual CommonRenderInterface* getRenderInterface()=0;
virtual const CommonRenderInterface* getRenderInterface() const
{
return 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 bool getCameraInfo(int* width, int* height, float viewMatrix[16], float projectionMatrix[16], float camUp[3], float camForward[3],float hor[3], float vert[3] ) const
{
return false;
}
virtual void setVisualizerFlag(int flag, int enable){};
virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
float* depthBuffer, int depthBufferSizeInPixels,
@@ -66,14 +84,20 @@ struct GUIHelperInterface
virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld) =0;
virtual void drawText3D( const char* txt, float posX, float posZY, float posZ, float size)=0;
virtual void drawText3D( const char* txt, float posX, float posY, float posZ, float size){}
virtual void drawText3D( const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag){}
virtual int addUserDebugText3D( const char* txt, const double posisionXYZ[3], const double textColorRGB[3], double size, double lifeTime)=0;
virtual int addUserDebugLine(const double debugLineFromXYZ[3], const double debugLineToXYZ[3], const double debugLineColorRGB[3], double lineWidth, double lifeTime )=0;
virtual void removeUserDebugItem( int debugItemUniqueId)=0;
virtual void removeAllUserDebugItems( )=0;
virtual int addUserDebugText3D( const char* txt, const double positionXYZ[3], const double orientation[4], const double textColorRGB[3], double size, double lifeTime, int trackingVisualShapeIndex, int optionFlags){return -1;}
virtual int addUserDebugLine(const double debugLineFromXYZ[3], const double debugLineToXYZ[3], const double debugLineColorRGB[3], double lineWidth, double lifeTime , int trackingVisualShapeIndex){return -1;};
virtual int addUserDebugParameter(const char* txt, double rangeMin, double rangeMax, double startValue){return -1;};
virtual int readUserDebugParameter(int itemUniqueId, double* value) { return 0;}
virtual void removeUserDebugItem( int debugItemUniqueId){};
virtual void removeAllUserDebugItems( ){};
virtual void setVisualizerFlagCallback(VisualizerFlagCallback callback){}
//empty name stops dumping video
virtual void dumpFramesToVideo(const char* mp4FileName) {};
};
@@ -100,7 +124,9 @@ struct DummyGUIHelper : public GUIHelperInterface
virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices,int primitiveType, int textureId){return -1;}
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) {return -1;}
virtual void removeAllGraphicsInstances(){}
virtual void removeGraphicsInstance(int graphicsUid){}
virtual void changeRGBAColor(int instanceUid, const double rgbaColor[4]) {}
virtual Common2dCanvasInterface* get2dCanvasInterface()
{
return 0;
@@ -147,12 +173,12 @@ struct DummyGUIHelper : public GUIHelperInterface
virtual void drawText3D( const char* txt, float posX, float posZY, float posZ, float size)
{
}
virtual int addUserDebugText3D( const char* txt, const double positionXYZ[3], const double textColorRGB[3], double size, double lifeTime)
virtual void drawText3D( const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag)
{
return -1;
}
virtual int addUserDebugLine(const double debugLineFromXYZ[3], const double debugLineToXYZ[3], const double debugLineColorRGB[3], double lineWidth, double lifeTime )
virtual int addUserDebugLine(const double debugLineFromXYZ[3], const double debugLineToXYZ[3], const double debugLineColorRGB[3], double lineWidth, double lifeTime , int trackingVisualShapeIndex)
{
return -1;
}

View File

@@ -37,6 +37,12 @@ enum EnumSphereLevelOfDetail
};
struct CommonGraphicsApp
{
enum drawText3DOption
{
eDrawText3D_OrtogonalFaceCamera=1,
eDrawText3D_TrueType=2,
eDrawText3D_TrackObject=4,
};
class CommonWindowInterface* m_window;
struct CommonRenderInterface* m_renderer;
struct CommonParameterInterface* m_parameterInterface;
@@ -120,8 +126,21 @@ struct CommonGraphicsApp
virtual int getUpAxis() const = 0;
virtual void swapBuffer() = 0;
virtual void drawText( const char* txt, int posX, int posY, float size = 1.0f) = 0;
virtual void drawText3D( const char* txt, float posX, float posZY, float posZ, float size)=0;
virtual void drawText( const char* txt, int posX, int posY)
{
float size=1;
float colorRGBA[4]={0,0,0,1};
drawText(txt,posX,posY, size, colorRGBA);
}
virtual void drawText( const char* txt, int posX, int posY, float size)
{
float colorRGBA[4]={0,0,0,1};
drawText(txt,posX,posY,size,colorRGBA);
}
virtual void drawText( const char* txt, int posX, int posY, float size, float colorRGBA[4]) = 0;
virtual void drawText3D( const char* txt, float posX, float posY, float posZ, float size)=0;
virtual void drawText3D( const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag)=0;
virtual void drawTexturedRect(float x0, float y0, float x1, float y1, float color[4], float u0,float v0, float u1, float v1, int useRGBA)=0;
virtual int registerCubeShape(float halfExtentsX,float halfExtentsY, float halfExtentsZ, int textureIndex = -1, float textureScaling = 1)=0;
virtual int registerGraphicsUnitSphereShape(EnumSphereLevelOfDetail lod, int textureId=-1) = 0;

View File

@@ -18,10 +18,49 @@
#include "CommonWindowInterface.h"
#include "CommonCameraInterface.h"
enum MyFilterModes
{
FILTER_GROUPAMASKB_AND_GROUPBMASKA2=0,
FILTER_GROUPAMASKB_OR_GROUPBMASKA2
};
struct MyOverlapFilterCallback2 : public btOverlapFilterCallback
{
int m_filterMode;
MyOverlapFilterCallback2()
:m_filterMode(FILTER_GROUPAMASKB_AND_GROUPBMASKA2)
{
}
virtual ~MyOverlapFilterCallback2()
{}
// return true when pairs need collision
virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
{
if (m_filterMode==FILTER_GROUPAMASKB_AND_GROUPBMASKA2)
{
bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
return collides;
}
if (m_filterMode==FILTER_GROUPAMASKB_OR_GROUPBMASKA2)
{
bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
collides = collides || (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
return collides;
}
return false;
}
};
struct CommonMultiBodyBase : public CommonExampleInterface
{
//keep the collision shapes, for deletion/cleanup
btAlignedObjectArray<btCollisionShape*> m_collisionShapes;
MyOverlapFilterCallback2* m_filterCallback;
btOverlappingPairCache* m_pairCache;
btBroadphaseInterface* m_broadphase;
btCollisionDispatcher* m_dispatcher;
btMultiBodyConstraintSolver* m_solver;
@@ -41,7 +80,9 @@ struct CommonMultiBodyBase : public CommonExampleInterface
struct GUIHelperInterface* m_guiHelper;
CommonMultiBodyBase(GUIHelperInterface* helper)
:m_broadphase(0),
:m_filterCallback(0),
m_pairCache(0),
m_broadphase(0),
m_dispatcher(0),
m_solver(0),
m_collisionConfiguration(0),
@@ -59,11 +100,16 @@ struct CommonMultiBodyBase : public CommonExampleInterface
///collision configuration contains default setup for memory, collision setup
m_collisionConfiguration = new btDefaultCollisionConfiguration();
//m_collisionConfiguration->setConvexConvexMultipointIterations();
m_filterCallback = new MyOverlapFilterCallback2();
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase();//btSimpleBroadphase();
m_pairCache = new btHashedOverlappingPairCache();
m_pairCache->setOverlapFilterCallback(m_filterCallback);
m_broadphase = new btDbvtBroadphase(m_pairCache);//btSimpleBroadphase();
m_solver = new btMultiBodyConstraintSolver;
@@ -142,7 +188,13 @@ struct CommonMultiBodyBase : public CommonExampleInterface
delete m_dispatcher;
m_dispatcher=0;
delete m_pairCache;
m_pairCache = 0;
delete m_filterCallback;
m_filterCallback = 0;
delete m_collisionConfiguration;
m_collisionConfiguration=0;
}

View File

@@ -26,7 +26,7 @@ struct SliderParams
m_callback(0),
m_paramValuePointer(targetValuePointer),
m_userPointer(0),
m_clampToNotches(true),
m_clampToNotches(false),
m_clampToIntegers(false),
m_showValues(true)
{
@@ -43,6 +43,7 @@ struct ButtonParams
int m_buttonId;
void* m_userPointer;
bool m_isTrigger;
bool m_initialState;
ButtonParamChangedCallback m_callback;
ButtonParams(const char* name, int buttonId, bool isTrigger)
@@ -50,6 +51,7 @@ struct ButtonParams
m_buttonId(buttonId),
m_userPointer(0),
m_isTrigger(isTrigger),
m_initialState(false),
m_callback(0)
{
}

View File

@@ -17,17 +17,36 @@ enum
B3_USE_SHADOWMAP_RENDERMODE,
};
struct GfxVertexFormat0
{
float x,y,z,w;
float unused0,unused1,unused2,unused3;
float u,v;
};
struct GfxVertexFormat1
{
float x,y,z,w;
float nx,ny,nz;
float u,v;
};
struct CommonRenderInterface
{
virtual ~CommonRenderInterface() {}
virtual void init()=0;
virtual void updateCamera(int upAxis)=0;
virtual void removeAllInstances() = 0;
virtual void removeGraphicsInstance(int instanceUid) = 0;
virtual const CommonCameraInterface* getActiveCamera() const =0;
virtual CommonCameraInterface* getActiveCamera()=0;
virtual void setActiveCamera(CommonCameraInterface* cam)=0;
virtual void setLightPosition(const float lightPos[3]) = 0;
virtual void setLightPosition(const double lightPos[3]) = 0;
virtual void renderScene()=0;
virtual void renderSceneInternal(int renderMode=B3_DEFAULT_RENDERMODE){};
@@ -43,19 +62,23 @@ struct CommonRenderInterface
virtual void drawLine(const double from[4], const double to[4], const double color[4], double lineWidth) = 0;
virtual void drawPoint(const float* position, const float color[4], float pointDrawSize)=0;
virtual void drawPoint(const double* position, const double color[4], double pointDrawSize)=0;
virtual void drawTexturedTriangleMesh(float worldPosition[3], float worldOrientation[4], const float* vertices, int numvertices, const unsigned int* indices, int numIndices, float color[4], int textureIndex=-1, int vertexLayout=0)=0;
virtual 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 int registerTexture(const unsigned char* texels, int width, int height, bool flipPixelsY=true)=0;
virtual void updateTexture(int textureIndex, const unsigned char* texels, bool flipPixelsY=true)=0;
virtual void activateTexture(int textureIndex)=0;
virtual bool readSingleInstanceTransformToCPU(float* position, float* orientation, int srcIndex)=0;
virtual void writeSingleInstanceTransformToCPU(const float* position, const float* orientation, int srcIndex)=0;
virtual void writeSingleInstanceTransformToCPU(const double* position, const double* orientation, int srcIndex)=0;
virtual void writeSingleInstanceColorToCPU(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 void writeSingleInstanceColorToCPU(const float* color, int srcIndex)=0;
virtual void writeSingleInstanceColorToCPU(const double* color, int srcIndex)=0;
virtual void writeSingleInstanceScaleToCPU(const float* scale, int srcIndex)=0;
virtual void writeSingleInstanceScaleToCPU(const double* scale, int srcIndex)=0;
virtual int getTotalNumInstances() const = 0;

View File

@@ -410,6 +410,18 @@ struct CommonRigidBodyBase : public CommonExampleInterface
return box;
}
void deleteRigidBody(btRigidBody* body)
{
int graphicsUid = body->getUserIndex();
m_guiHelper->removeGraphicsInstance(graphicsUid);
m_dynamicsWorld->removeRigidBody(body);
btMotionState* ms = body->getMotionState();
delete body;
delete ms;
}
btRigidBody* createRigidBody(float mass, const btTransform& startTransform, btCollisionShape* shape, const btVector4& color = btVector4(1, 0, 0, 1))
{
btAssert((!shape || shape->getShapeType() != INVALID_SHAPE_PROXYTYPE));

View File

@@ -1,47 +1,8 @@
#ifndef B3G_WINDOW_INTERFACE_H
#define B3G_WINDOW_INTERFACE_H
#include "CommonCallbacks.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
{
@@ -127,4 +88,4 @@ class CommonWindowInterface
};
#endif //B3G_WINDOW_INTERFACE_H
#endif //B3G_WINDOW_INTERFACE_H

View File

@@ -56,7 +56,7 @@ class AllConstraintDemo : public CommonRigidBodyBase
m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
}
virtual void keyboardCallback(unsigned char key, int x, int y);
virtual bool keyboardCallback(int key, int state);
// for cone-twist motor driving
float m_Time;
@@ -66,7 +66,6 @@ class AllConstraintDemo : public CommonRigidBodyBase
const int numObjects = 3;
#define ENABLE_ALL_DEMOS 1
@@ -839,10 +838,11 @@ void AllConstraintDemo::displayCallback(void) {
}
#endif
void AllConstraintDemo::keyboardCallback(unsigned char key, int x, int y)
bool AllConstraintDemo::keyboardCallback(int key, int state)
{
(void)x;
(void)y;
bool handled = false;
switch (key)
{
case 'O' :
@@ -870,6 +870,7 @@ void AllConstraintDemo::keyboardCallback(unsigned char key, int x, int y)
printf("Slider6Dof %s frame offset\n", offectOnOff ? "uses" : "does not use");
}
}
handled = true;
break;
default :
{
@@ -877,6 +878,8 @@ void AllConstraintDemo::keyboardCallback(unsigned char key, int x, int y)
}
break;
}
return handled;
}
class CommonExampleInterface* AllConstraintCreateFunc(struct CommonExampleOptions& options)

View File

@@ -443,8 +443,6 @@ void Dof6Spring2Setup::animate()
/////// servo motor: flip its target periodically
#ifdef USE_6DOF2
static float servoNextFrame = -1;
btScalar pos = m_data->m_ServoMotorConstraint->getRotationalLimitMotor(2)->m_currentPosition;
btScalar target = m_data->m_ServoMotorConstraint->getRotationalLimitMotor(2)->m_servoTarget;
if(servoNextFrame < 0)
{
m_data->m_ServoMotorConstraint->getRotationalLimitMotor(2)->m_servoTarget *= -1;

View File

@@ -4,8 +4,8 @@
#include "../CommonInterfaces/CommonRigidBodyBase.h"
#include "../CommonInterfaces/CommonParameterInterface.h"
short collisionFilterGroup = short(btBroadphaseProxy::CharacterFilter);
short collisionFilterMask = short(btBroadphaseProxy::AllFilter ^ (btBroadphaseProxy::CharacterFilter));
int collisionFilterGroup = int(btBroadphaseProxy::CharacterFilter);
int collisionFilterMask = int(btBroadphaseProxy::AllFilter ^ (btBroadphaseProxy::CharacterFilter));
static btScalar radius(0.2);
struct TestHingeTorque : public CommonRigidBodyBase
@@ -123,9 +123,7 @@ void TestHingeTorque::initPhysics()
{ // create a door using hinge constraint attached to the world
int numLinks = 2;
bool spherical = false; //set it ot false -to use 1DoF hinges instead of 3DoF sphericals
bool canSleep = false;
bool selfCollide = false;
// bool selfCollide = false;
btVector3 linkHalfExtents(0.05, 0.37, 0.1);
btVector3 baseHalfExtents(0.05, 0.37, 0.1);
@@ -223,7 +221,7 @@ void TestHingeTorque::initPhysics()
btTransform start; start.setIdentity();
btVector3 groundOrigin(-0.4f, 3.f, 0.f);
btVector3 basePosition = btVector3(-0.4f, 3.f, 0.f);
// btVector3 basePosition = btVector3(-0.4f, 3.f, 0.f);
btQuaternion groundOrn(btVector3(0,1,0),0.25*SIMD_PI);
groundOrigin[upAxis] -=.5;

View File

@@ -15,6 +15,12 @@ subject to the following restrictions:
#include "NN3DWalkers.h"
#include "btBulletDynamicsCommon.h"
#include "LinearMath/btIDebugDraw.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "LinearMath/btHashMap.h"
class btBroadphaseInterface;
class btCollisionShape;
class btOverlappingPairCache;
@@ -24,15 +30,12 @@ struct btCollisionAlgorithmCreateFunc;
class btDefaultCollisionConfiguration;
class NNWalker;
#include "btBulletDynamicsCommon.h"
#include "LinearMath/btIDebugDraw.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "LinearMath/btHashMap.h"
#include "NN3DWalkersTimeWarpBase.h"
#include "../CommonInterfaces/CommonParameterInterface.h"
#include "../Utils/b3ReferenceFrameHelper.hpp"
#include "../Utils/b3Clock.h"
#include "../RenderingExamples/TimeSeriesCanvas.h"
#include "NN3DWalkersTimeWarpBase.h"
// #### configurable parameters ####
#ifndef NUM_WALKER_LEGS
@@ -1268,10 +1271,10 @@ void NN3DWalkersExample::scheduleEvaluations() {
m_walkersInEvaluation++;
if(REBUILD_WALKER){ // deletes and recreates the walker in the position
m_guiHelper->removeAllGraphicsInstances();
m_ground->setUserIndex(-1); // reset to get a new graphics object
m_ground->setUserIndex2(-1); // reset to get a new graphics object
m_ground->getCollisionShape()->setUserIndex(-1); // reset to get a new graphics object
// m_guiHelper->removeAllGraphicsInstances();
// m_ground->setUserIndex(-1); // reset to get a new graphics object
// m_ground->setUserIndex2(-1); // reset to get a new graphics object
// m_ground->getCollisionShape()->setUserIndex(-1); // reset to get a new graphics object
resetWalkerAt(i, m_resetPosition);
}

View File

@@ -595,6 +595,7 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase {
if(mLoopTimer.getTimeSeconds() - speedUpPrintTimeStamp > 1){
// on reset, we calculate the performed speed up
double speedUp = ((double)performedTime*1000.0)/((double)(mLoopTimer.getTimeMilliseconds()-performanceTimestamp));
// b3Printf("Avg Effective speedup: %f",speedUp);
performedTime = 0;
performanceTimestamp = mLoopTimer.getTimeMilliseconds();
speedUpPrintTimeStamp = mLoopTimer.getTimeSeconds();

View File

@@ -34,6 +34,8 @@ ADD_LIBRARY(BulletExampleBrowserLib
CollisionShape2TriangleMesh.h
../Utils/b3Clock.cpp
../Utils/b3Clock.h
../Utils/ChromeTraceUtil.cpp
../Utils/ChromeTraceUtil.h
../Utils/b3ResourcePath.cpp
../Utils/b3ResourcePath.h
../Utils/b3ERPCFMHelper.hpp
@@ -63,7 +65,7 @@ IF (BUILD_SHARED_LIBS)
TARGET_LINK_LIBRARIES(
BulletExampleBrowserLib Bullet3Common BulletSoftBody BulletDynamics BulletCollision BulletInverseDynamicsUtils
BulletInverseDynamics LinearMath OpenGLWindow gwen BussIK
pthread dl
pthread ${DL}
)
ENDIF(APPLE)
ENDIF(WIN32)
@@ -104,7 +106,7 @@ ELSE(WIN32)
ADD_DEFINITIONS("-DGLEW_STATIC")
ADD_DEFINITIONS("-DGLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS=1")
INCLUDE_DIRECTORIES( ${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/Glew )
LINK_LIBRARIES( pthread dl)
LINK_LIBRARIES( pthread ${DL})
ENDIF(APPLE)
ENDIF(WIN32)
@@ -189,6 +191,10 @@ SET(BulletExampleBrowser_SRCS
../SharedMemory/PhysicsLoopBackC_API.h
../SharedMemory/PhysicsServerCommandProcessor.cpp
../SharedMemory/PhysicsServerCommandProcessor.h
../SharedMemory/SharedMemoryCommands.h
../SharedMemory/SharedMemoryPublic.h
../RobotSimulator/b3RobotSimulatorClientAPI.cpp
../RobotSimulator/b3RobotSimulatorClientAPI.h
../BasicDemo/BasicExample.cpp
../BasicDemo/BasicExample.h
../InverseDynamics/InverseDynamicsExample.cpp
@@ -250,8 +256,6 @@ SET(BulletExampleBrowser_SRCS
../RoboticsLearning/GripperGraspExample.cpp
../RoboticsLearning/GripperGraspExample.h
../RoboticsLearning/b3RobotSimAPI.cpp
../RoboticsLearning/b3RobotSimAPI.h
../RoboticsLearning/R2D2GraspExample.cpp
../RoboticsLearning/R2D2GraspExample.h
../RoboticsLearning/KukaGraspExample.cpp
@@ -295,6 +299,11 @@ SET(BulletExampleBrowser_SRCS
../Importers/ImportURDFDemo/ImportURDFSetup.h
../Importers/ImportURDFDemo/URDF2Bullet.h
../Importers/ImportURDFDemo/urdf_samples.h
../Importers/ImportURDFDemo/urdf_samples.h
../Importers/ImportMJCFDemo/BulletMJCFImporter.cpp
../Importers/ImportMJCFDemo/BulletMJCFImporter.h
../Importers/ImportMJCFDemo/ImportMJCFSetup.cpp
../Importers/ImportMJCFDemo/ImportMJCFSetup.h
../Importers/ImportBsp/BspConverter.cpp
../Importers/ImportBsp/BspLoader.cpp
../Importers/ImportBsp/ImportBspExample.cpp
@@ -310,6 +319,8 @@ SET(BulletExampleBrowser_SRCS
../Importers/ImportURDFDemo/MyMultiBodyCreator.cpp
../Importers/ImportURDFDemo/MyMultiBodyCreator.h
../Importers/ImportURDFDemo/UrdfParser.cpp
../Utils/RobotLoggingUtil.cpp
../Utils/RobotLoggingUtil.h
../Importers/ImportURDFDemo/urdfStringSplit.cpp
../Importers/ImportURDFDemo/urdfStringSplit.h
../Importers/ImportURDFDemo/BulletUrdfImporter.cpp

View File

@@ -111,18 +111,21 @@ void CollisionShape2TriangleMesh(btCollisionShape* collisionShape, const btTrans
vertices.push_back(triangleVerts[2]);
btVector3 triNormal = (triangleVerts[1]-triangleVerts[0]).cross(triangleVerts[2]-triangleVerts[0]);
triNormal.normalize();
btScalar dot = triNormal.dot(triNormal);
for (int v=0;v<3;v++)
//cull degenerate triangles
if (dot >= SIMD_EPSILON*SIMD_EPSILON)
{
btVector3 pos =parentTransform*triangleVerts[v];
indicesOut.push_back(vertexPositions.size());
vertexPositions.push_back(pos);
vertexNormals.push_back(triNormal);
triNormal /= btSqrt(dot);
for (int v = 0; v < 3; v++)
{
btVector3 pos = parentTransform*triangleVerts[v];
indicesOut.push_back(vertexPositions.size());
vertexPositions.push_back(pos);
vertexNormals.push_back(triNormal);
}
}
}
}

View File

@@ -18,6 +18,7 @@
#include "../Importers/ImportSTLDemo/ImportSTLSetup.h"
#include "../Importers/ImportURDFDemo/ImportURDFSetup.h"
#include "../Importers/ImportSDFDemo/ImportSDFSetup.h"
#include "../Importers/ImportMJCFDemo/ImportMJCFSetup.h"
#include "../Collision/CollisionTutorialBullet2.h"
#include "../GyroscopicDemo/GyroscopicSetup.h"
#include "../Constraints/Dof6Spring2Setup.h"
@@ -51,6 +52,10 @@
#include "../RoboticsLearning/GripperGraspExample.h"
#include "../InverseKinematics/InverseKinematicsExample.h"
#ifdef B3_ENABLE_TINY_AUDIO
#include "../TinyAudio/TinyAudioExample.h"
#endif //B3_ENABLE_TINY_AUDIO
#ifdef ENABLE_LUA
#include "../LuaDemo/LuaPhysicsSetup.h"
#endif
@@ -99,7 +104,6 @@ struct ExampleEntry
static ExampleEntry gDefaultExamples[]=
{
ExampleEntry(0,"API"),
ExampleEntry(1,"Basic Example","Create some rigid bodies using box collision shapes. This is a good example to familiarize with the basic initialization of Bullet. The Basic Example can also be compiled without graphical user interface, as a console application. Press W for wireframe, A to show AABBs, I to suspend/restart physics simulation. Press D to toggle auto-deactivation of the simulation. ", BasicExampleCreateFunc),
@@ -132,6 +136,17 @@ static ExampleEntry gDefaultExamples[]=
ExampleEntry(1,"Inverted Pendulum PD","Keep an inverted pendulum up using open loop PD control", InvertedPendulumPDControlCreateFunc),
ExampleEntry(1,"MultiBody Soft Contact", "Using the error correction parameter (ERP) and constraint force mixing (CFM) values for contacts to simulate compliant contact.",MultiBodySoftContactCreateFunc,0),
ExampleEntry(0,"Physics Client-Server"),
ExampleEntry(1,"Physics Server", "Create a physics server that communicates with a physics client over shared memory. You can connect to the server using pybullet, a PhysicsClient or a UDP/TCP Bridge.",
PhysicsServerCreateFunc),
ExampleEntry(1, "Physics Client (Shared Mem)", "Create a physics client that can communicate with a physics server over shared memory.", PhysicsClientCreateFunc),
// ExampleEntry(1,"Physics Server (Logging)", "Create a physics server that communicates with a physics client over shared memory. It will log all commands to a file.",
// PhysicsServerCreateFunc,PHYSICS_SERVER_ENABLE_COMMAND_LOGGING),
// ExampleEntry(1,"Physics Server (Replay Log)", "Create a physics server that replay a command log from disk.",
// PhysicsServerCreateFunc,PHYSICS_SERVER_REPLAY_FROM_COMMAND_LOG),
//
// ExampleEntry(1, "Physics Client (Direct)", "Create a physics client that can communicate with a physics server directly in-process.", PhysicsClientCreateFunc,eCLIENTEXAMPLE_DIRECT),
ExampleEntry(0,"Inverse Dynamics"),
ExampleEntry(1,"Inverse Dynamics URDF", "Create a btMultiBody from URDF. Create an inverse MultiBodyTree model from that. Use either decoupled PD control or computed torque control using the inverse model to track joint position targets", InverseDynamicsExampleCreateFunc,BT_ID_LOAD_URDF),
@@ -231,6 +246,8 @@ static ExampleEntry gDefaultExamples[]=
ExampleEntry(1,"URDF (RigidBody)", "Import a URDF file, and create rigid bodies (btRigidBody) connected by constraints.", ImportURDFCreateFunc, 0),
ExampleEntry(1,"URDF (MultiBody)", "Import a URDF file and create a single multibody (btMultiBody) with tree hierarchy of links (mobilizers).",
ImportURDFCreateFunc, 1),
ExampleEntry(1,"MJCF (MultiBody)", "Import a MJCF xml file, create multiple multibodies etc", ImportMJCFCreateFunc),
ExampleEntry(1,"SDF (MultiBody)", "Import an SDF file, create multiple multibodies etc", ImportSDFCreateFunc),
ExampleEntry(0,"Vehicles"),
@@ -248,19 +265,10 @@ static ExampleEntry gDefaultExamples[]=
ExampleEntry(0,"Experiments"),
ExampleEntry(1,"Robot Control", "Create a physics client and server to create and control robots.",
PhysicsClientCreateFunc, eCLIENTEXAMPLE_SERVER),
ExampleEntry(1,"Physics Server", "Create a physics server that communicates with a physics client over shared memory",
PhysicsServerCreateFunc),
ExampleEntry(1,"Physics Server (RTC)", "Create a physics server that communicates with a physics client over shared memory. At each update, the Physics Server will continue calling 'stepSimulation' based on the real-time clock (RTC).",
PhysicsServerCreateFunc,PHYSICS_SERVER_USE_RTC_CLOCK),
ExampleEntry(1,"Physics Server (Logging)", "Create a physics server that communicates with a physics client over shared memory. It will log all commands to a file.",
PhysicsServerCreateFunc,PHYSICS_SERVER_ENABLE_COMMAND_LOGGING),
ExampleEntry(1,"Physics Server (Replay Log)", "Create a physics server that replay a command log from disk.",
PhysicsServerCreateFunc,PHYSICS_SERVER_REPLAY_FROM_COMMAND_LOG),
ExampleEntry(1, "Physics Client (Shared Mem)", "Create a physics client that can communicate with a physics server over shared memory.", PhysicsClientCreateFunc),
ExampleEntry(1, "Physics Client (Direct)", "Create a physics client that can communicate with a physics server directly in-process.", PhysicsClientCreateFunc,eCLIENTEXAMPLE_DIRECT),
ExampleEntry(1,"R2D2 Grasp","Load the R2D2 robot from URDF file and control it to grasp objects", R2D2GraspExampleCreateFunc, eROBOTIC_LEARN_GRASP),
ExampleEntry(1,"Kuka IK","Control a Kuka IIWA robot to follow a target using IK. This IK is not setup properly yet.", KukaGraspExampleCreateFunc,0),
@@ -269,9 +277,10 @@ static ExampleEntry gDefaultExamples[]=
ExampleEntry(1,"Gripper Grasp","Grasp experiment with a gripper to improve contact model", GripperGraspExampleCreateFunc,eGRIPPER_GRASP),
ExampleEntry(1,"Two Point Grasp","Grasp experiment with two point contact to test rolling friction", GripperGraspExampleCreateFunc, eTWO_POINT_GRASP),
ExampleEntry(1,"One Motor Gripper Grasp","Grasp experiment with a gripper with one motor to test slider constraint for closed loop structure", GripperGraspExampleCreateFunc, eONE_MOTOR_GRASP),
ExampleEntry(1,"Grasp Soft Body","Grasp soft body experiment", GripperGraspExampleCreateFunc, eGRASP_SOFT_BODY),
ExampleEntry(1,"Softbody Multibody Coupling","Two way coupling between soft body and multibody experiment", GripperGraspExampleCreateFunc, eSOFTBODY_MULTIBODY_COUPLING),
#ifdef USE_SOFT_BODY_MULTI_BODY_DYNAMICS_WORLD
ExampleEntry(1,"Grasp Soft Body","Grasp soft body experiment", GripperGraspExampleCreateFunc, eGRASP_SOFT_BODY),
ExampleEntry(1,"Softbody Multibody Coupling","Two way coupling between soft body and multibody experiment", GripperGraspExampleCreateFunc, eSOFTBODY_MULTIBODY_COUPLING),
#endif //USE_SOFT_BODY_MULTI_BODY_DYNAMICS_WORLD
#ifdef ENABLE_LUA
ExampleEntry(1,"Lua Script", "Create the dynamics world, collision shapes and rigid bodies using Lua scripting",
@@ -302,7 +311,11 @@ static ExampleEntry gDefaultExamples[]=
ExampleEntry(1,"TinyRenderer", "Very small software renderer.", TinyRendererCreateFunc),
ExampleEntry(1,"Dynamic Texture", "Dynamic updated textured applied to a cube.", DynamicTexturedCubeDemoCreateFunc),
#ifdef B3_ENABLE_TINY_AUDIO
ExampleEntry(0,"Audio"),
ExampleEntry(1,"Simple Audio","Play some sound", TinyAudioExampleCreateFunc),
#endif
//Extended Tutorials Added by Mobeen
ExampleEntry(0,"Extended Tutorials"),

View File

@@ -3,12 +3,14 @@
struct MyButtonEventHandler : public Gwen::Event::Handler
{
Gwen::Controls::Button* m_buttonControl;
ButtonParamChangedCallback m_callback;
void* m_userPointer;
int m_buttonId;
MyButtonEventHandler(ButtonParamChangedCallback callback, int buttonId, void* userPointer)
:m_callback(callback),
MyButtonEventHandler(Gwen::Controls::Button* buttonControl, ButtonParamChangedCallback callback, int buttonId, void* userPointer)
:m_buttonControl(buttonControl),
m_callback(callback),
m_userPointer(userPointer),
m_buttonId(buttonId)
{
@@ -18,7 +20,12 @@ struct MyButtonEventHandler : public Gwen::Event::Handler
{
if (m_callback)
{
(*m_callback)(m_buttonId, true, m_userPointer);
bool buttonState = true;
if (m_buttonControl->IsToggle())
{
buttonState = m_buttonControl->GetToggleState();
}
( *m_callback )( m_buttonId, buttonState, m_userPointer );
}
}
};
@@ -36,12 +43,13 @@ struct MySliderEventHandler : public Gwen::Event::Handler
bool m_showValue;
MySliderEventHandler(const char* varName, Gwen::Controls::TextBox* label, Gwen::Controls::Slider* pSlider,T* target, SliderParamChangedCallback callback, void* userPtr)
:m_label(label),
: m_callback(callback),
m_userPointer(userPtr),
m_label(label),
m_pSlider(pSlider),
m_targetValue(target),
m_showValue(true),
m_callback(callback),
m_userPointer(userPtr)
m_targetValue(target),
m_showValue(true)
{
memcpy(m_variableName,varName,strlen(varName)+1);
}
@@ -140,10 +148,11 @@ void GwenParameterInterface::registerButtonParameter(ButtonParams& params)
{
Gwen::Controls::Button* button = new Gwen::Controls::Button(m_gwenInternalData->m_demoPage->GetPage());
MyButtonEventHandler* handler = new MyButtonEventHandler(params.m_callback,params.m_buttonId,params.m_userPointer);
MyButtonEventHandler* handler = new MyButtonEventHandler(button, params.m_callback,params.m_buttonId,params.m_userPointer);
button->SetText(params.m_name);
button->onPress.Add( handler, &MyButtonEventHandler::onButtonPress );
button->SetIsToggle(params.m_isTrigger);
button->SetToggleState(params.m_initialState);
m_paramInternalData->m_buttons.push_back(button);
m_paramInternalData->m_buttonEventHandlers.push_back(handler);

View File

@@ -44,8 +44,8 @@ public:
CProfileIterator* profIter;
class MyMenuItems* m_menuItems;
class MyMenuItems3* m_menuItems;
MyProfileWindow ( Gwen::Controls::Base* pParent)
: Gwen::Controls::WindowControl( pParent ),
profIter(0)
@@ -192,7 +192,8 @@ public:
// Gwen::Controls::TreeNode* curParent = m_node;
double accumulated_time = dumpRecursive(profileIterator,m_node);
const char* name = profileIterator->Get_Current_Parent_Name();
@@ -246,16 +247,17 @@ public:
};
class MyMenuItems : public Gwen::Controls::Base
class MyMenuItems3 : public Gwen::Controls::Base
{
public:
class MyProfileWindow* m_profWindow;
MyMenuItems() :Gwen::Controls::Base(0)
MyMenuItems3() :Gwen::Controls::Base(0)
{
}
virtual ~MyMenuItems3() {}
void MenuItemSelect(Gwen::Controls::Base* pControl)
{
if (m_profWindow->Hidden())
@@ -272,14 +274,14 @@ public:
MyProfileWindow* setupProfileWindow(GwenInternalData* data)
{
MyMenuItems* menuItems = new MyMenuItems;
MyMenuItems3* menuItems = new MyMenuItems3;
MyProfileWindow* profWindow = new MyProfileWindow(data->pCanvas);
//profWindow->SetHidden(true);
profWindow->m_menuItems = menuItems;
//profWindow->profIter = CProfileManager::Get_Iterator();
data->m_viewMenu->GetMenu()->AddItem( L"Profiler", menuItems,(Gwen::Event::Handler::Function)&MyMenuItems::MenuItemSelect);
profWindow->profIter = CProfileManager::Get_Iterator();
data->m_viewMenu->GetMenu()->AddItem( L"Profiler", menuItems,(Gwen::Event::Handler::Function)&MyMenuItems3::MenuItemSelect);
menuItems->m_profWindow = profWindow;
@@ -291,11 +293,18 @@ void processProfileData( MyProfileWindow* profWindow, bool idle)
{
if (profWindow)
{
profWindow->UpdateText(profWindow->profIter, idle);
if (profWindow->profIter)
{
profWindow->UpdateText(profWindow->profIter, idle);
}
}
}
bool isProfileWindowVisible(MyProfileWindow* window)
{
return !window->Hidden();
}
void profileWindowSetVisible(MyProfileWindow* window, bool visible)
{
window->SetHidden(!visible);
@@ -303,7 +312,10 @@ void profileWindowSetVisible(MyProfileWindow* window, bool visible)
void destroyProfileWindow(MyProfileWindow* window)
{
CProfileManager::Release_Iterator(window->profIter);
delete window->m_menuItems;
delete window;
CProfileManager::CleanupMemory();
}
#endif //BT_NO_PROFILE
#endif //BT_NO_PROFILE

View File

@@ -4,6 +4,8 @@
class MyProfileWindow* setupProfileWindow(struct GwenInternalData* data);
void processProfileData(MyProfileWindow* window, bool idle);
void profileWindowSetVisible(MyProfileWindow* window, bool visible);
bool isProfileWindowVisible(MyProfileWindow* window);
void destroyProfileWindow(MyProfileWindow* window);
#endif//GWEN_PROFILE_WINDOW_H

View File

@@ -224,6 +224,8 @@ enum TestExampleBrowserCommunicationEnums
eExampleBrowserHasTerminated
};
static double gMinUpdateTimeMicroSecs = 4000.;
void ExampleBrowserThreadFunc(void* userPtr,void* lsMemory)
{
printf("ExampleBrowserThreadFunc started\n");
@@ -231,7 +233,7 @@ void ExampleBrowserThreadFunc(void* userPtr,void* lsMemory)
ExampleBrowserThreadLocalStorage* localStorage = (ExampleBrowserThreadLocalStorage*) lsMemory;
ExampleBrowserArgs* args = (ExampleBrowserArgs*) userPtr;
int workLeft = true;
//int workLeft = true;
b3CommandLineArgs args2(args->m_argc,args->m_argv);
b3Clock clock;
@@ -253,9 +255,25 @@ void ExampleBrowserThreadFunc(void* userPtr,void* lsMemory)
do
{
B3_PROFILE("ExampleBrowserThreadFunc");
float deltaTimeInSeconds = clock.getTimeMicroseconds()/1000000.f;
clock.reset();
exampleBrowser->update(deltaTimeInSeconds);
{
if (deltaTimeInSeconds > 0.1)
{
deltaTimeInSeconds = 0.1;
}
if (deltaTimeInSeconds < (gMinUpdateTimeMicroSecs/1e6))
{
B3_PROFILE("clock.usleep");
clock.usleep(gMinUpdateTimeMicroSecs/10.);
exampleBrowser->updateGraphics();
} else
{
B3_PROFILE("exampleBrowser->update");
clock.reset();
exampleBrowser->update(deltaTimeInSeconds);
}
}
} while (!exampleBrowser->requestedExit() && (args->m_cs->getSharedParam(0)!=eRequestTerminateExampleBrowser));
} else
@@ -372,6 +390,8 @@ void btShutDownExampleBrowser(btInProcessExampleBrowserInternalData* data)
};
printf("btShutDownExampleBrowser stopping threads\n");
data->m_threadSupport->deleteCriticalSection(data->m_args.m_cs);
delete data->m_threadSupport;
delete data->m_sharedMem;
delete data;
@@ -392,7 +412,8 @@ btInProcessExampleBrowserMainThreadInternalData* btCreateInProcessExampleBrowser
data->m_exampleBrowser = new DefaultBrowser(&data->m_examples);
data->m_sharedMem = new InProcessMemory;
data->m_exampleBrowser->setSharedMemoryInterface(data->m_sharedMem );
bool init = data->m_exampleBrowser->init(argc,argv);
bool init;
init = data->m_exampleBrowser->init(argc,argv);
data->m_clock.reset();
return data;
}

View File

@@ -13,19 +13,26 @@
#include "../OpenGLWindow/Win32OpenGLWindow.h"
#else
//let's cross the fingers it is Linux/X11
#ifdef BT_USE_EGL
#include "../OpenGLWindow/EGLOpenGLWindow.h"
#else
#include "../OpenGLWindow/X11OpenGLWindow.h"
#endif //BT_USE_EGL
#endif //_WIN32
#endif//__APPLE__
#include "../ThirdPartyLibs/Gwen/Renderers/OpenGL_DebugFont.h"
#include "LinearMath/btThreads.h"
#include "Bullet3Common/b3Vector3.h"
#include "assert.h"
#include <stdio.h>
#include "GwenGUISupport/gwenInternalData.h"
#include "GwenGUISupport/gwenUserInterface.h"
#include "../Utils/b3Clock.h"
#include "../Utils/ChromeTraceUtil.h"
#include "GwenGUISupport/GwenParameterInterface.h"
#ifndef BT_NO_PROFILE
#include "GwenGUISupport/GwenProfileWindow.h"
#endif
#include "GwenGUISupport/GwenTextureWindow.h"
#include "GwenGUISupport/GraphingTexture.h"
#include "../CommonInterfaces/Common2dCanvasInterface.h"
@@ -41,7 +48,6 @@
//quick test for file import, @todo(erwincoumans) make it more general and add other file formats
#include "../Importers/ImportURDFDemo/ImportURDFSetup.h"
#include "../Importers/ImportBullet/SerializeSetup.h"
#include "Bullet3Common/b3HashMap.h"
struct GL3TexLoader : public MyTextureLoader
@@ -68,7 +74,9 @@ struct OpenGLExampleBrowserInternalData
{
Gwen::Renderer::Base* m_gwenRenderer;
CommonGraphicsApp* m_app;
// MyProfileWindow* m_profWindow;
#ifndef BT_NO_PROFILE
MyProfileWindow* m_profWindow;
#endif //BT_NO_PROFILE
btAlignedObjectArray<Gwen::Controls::TreeNode*> m_nodes;
GwenUserInterface* m_gui;
GL3TexLoader* m_myTexLoader;
@@ -93,7 +101,9 @@ static CommonWindowInterface* s_window = 0;
static CommonParameterInterface* s_parameterInterface=0;
static CommonRenderInterface* s_instancingRenderer=0;
static OpenGLGuiHelper* s_guiHelper=0;
//static MyProfileWindow* s_profWindow =0;
#ifndef BT_NO_PROFILE
static MyProfileWindow* s_profWindow =0;
#endif //BT_NO_PROFILE
static SharedMemoryInterface* sSharedMem = 0;
#define DEMO_SELECTION_COMBOBOX 13
@@ -110,15 +120,14 @@ bool gAllowRetina = true;
bool gDisableDemoSelection = false;
static class ExampleEntries* gAllExamples=0;
bool sUseOpenGL2 = false;
bool drawGUI=true;
#ifndef USE_OPENGL3
extern bool useShadowMap;
#endif
static bool visualWireframe=false;
bool visualWireframe=false;
static bool renderVisualGeometry=true;
static bool renderGrid = true;
static bool renderGui = true;
bool renderGui = true;
static bool enable_experimental_opencl = false;
int gDebugDrawFlags = 0;
@@ -143,7 +152,6 @@ int gGpuArraySizeZ=45;
void deleteDemo()
{
if (sCurrentDemo)
@@ -154,6 +162,8 @@ void deleteDemo()
sCurrentDemo=0;
delete s_guiHelper;
s_guiHelper = 0;
// CProfileManager::CleanupMemory();
}
}
@@ -170,10 +180,12 @@ void MyKeyboardCallback(int key, int state)
//b3Printf("key=%d, state=%d", key, state);
bool handled = false;
if (gui2 && !handled )
if (renderGui)
{
handled = gui2->keyboardCallback(key, state);
if (gui2 && !handled )
{
handled = gui2->keyboardCallback(key, state);
}
}
if (!handled && sCurrentDemo)
@@ -188,83 +200,99 @@ void MyKeyboardCallback(int key, int state)
//if (handled)
// return;
if (key=='a' && state)
//if (s_window && s_window->isModifierKeyPressed(B3G_CONTROL))
{
gDebugDrawFlags ^= btIDebugDraw::DBG_DrawAabb;
}
if (key=='c' && state)
{
gDebugDrawFlags ^= btIDebugDraw::DBG_DrawContactPoints;
}
if (key == 'd' && state)
{
gDebugDrawFlags ^= btIDebugDraw::DBG_NoDeactivation;
gDisableDeactivation = ((gDebugDrawFlags & btIDebugDraw::DBG_NoDeactivation) != 0);
}
if (key == 'k' && state)
{
gDebugDrawFlags ^= btIDebugDraw::DBG_DrawConstraints;
}
if (key=='l' && state)
{
gDebugDrawFlags ^= btIDebugDraw::DBG_DrawConstraintLimits;
}
if (key=='w' && state)
{
visualWireframe=!visualWireframe;
gDebugDrawFlags ^= btIDebugDraw::DBG_DrawWireframe;
}
if (key=='v' && state)
{
renderVisualGeometry = !renderVisualGeometry;
}
if (key=='g' && state)
{
renderGrid = !renderGrid;
renderGui = !renderGui;
}
if (key=='i' && state)
{
pauseSimulation = !pauseSimulation;
}
if (key == 'o' && state)
{
singleStepSimulation = true;
}
#ifndef NO_OPENGL3
if (key=='s' && state)
{
useShadowMap=!useShadowMap;
}
#endif
if (key==B3G_F1)
{
static int count=0;
if (state)
if (key=='a' && state)
{
b3Printf("F1 pressed %d", count++);
gDebugDrawFlags ^= btIDebugDraw::DBG_DrawAabb;
}
if (key=='c' && state)
{
gDebugDrawFlags ^= btIDebugDraw::DBG_DrawContactPoints;
}
if (key == 'd' && state)
{
gDebugDrawFlags ^= btIDebugDraw::DBG_NoDeactivation;
gDisableDeactivation = ((gDebugDrawFlags & btIDebugDraw::DBG_NoDeactivation) != 0);
}
if (key == 'k' && state)
{
gDebugDrawFlags ^= btIDebugDraw::DBG_DrawConstraints;
}
if (gPngFileName)
if (key=='l' && state)
{
gDebugDrawFlags ^= btIDebugDraw::DBG_DrawConstraintLimits;
}
if (key=='w' && state)
{
visualWireframe=!visualWireframe;
gDebugDrawFlags ^= btIDebugDraw::DBG_DrawWireframe;
}
if (key=='v' && state)
{
renderVisualGeometry = !renderVisualGeometry;
}
if (key=='g' && state)
{
renderGrid = !renderGrid;
renderGui = !renderGui;
}
if (key=='i' && state)
{
pauseSimulation = !pauseSimulation;
}
if (key == 'o' && state)
{
singleStepSimulation = true;
}
if (key=='p')
{
#ifndef BT_NO_PROFILE
if (state)
{
b3Printf("disable image dump");
b3ChromeUtilsStartTimings();
gPngFileName=0;
} else
{
gPngFileName = gAllExamples->getExampleName(sCurrentDemoIndex);
b3Printf("enable image dump %s",gPngFileName);
b3ChromeUtilsStopTimingsAndWriteJsonFile("timings");
}
} else
#endif //BT_NO_PROFILE
}
#ifndef NO_OPENGL3
if (key=='s' && state)
{
b3Printf("F1 released %d",count++);
useShadowMap=!useShadowMap;
}
#endif
if (key==B3G_F1)
{
static int count=0;
if (state)
{
b3Printf("F1 pressed %d", count++);
if (gPngFileName)
{
b3Printf("disable image dump");
gPngFileName=0;
} else
{
gPngFileName = gAllExamples->getExampleName(sCurrentDemoIndex);
b3Printf("enable image dump %s",gPngFileName);
}
} else
{
b3Printf("F1 released %d",count++);
}
}
}
if (key==B3G_ESCAPE && s_window)
@@ -284,8 +312,11 @@ static void MyMouseMoveCallback( float x, float y)
bool handled = false;
if (sCurrentDemo)
handled = sCurrentDemo->mouseMoveCallback(x,y);
if (!handled && gui2)
handled = gui2->mouseMoveCallback(x,y);
if (renderGui)
{
if (!handled && gui2)
handled = gui2->mouseMoveCallback(x,y);
}
if (!handled)
{
if (prevMouseMoveCallback)
@@ -302,9 +333,11 @@ static void MyMouseButtonCallback(int button, int state, float x, float y)
if (sCurrentDemo)
handled = sCurrentDemo->mouseButtonCallback(button,state,x,y);
if (!handled && gui2)
handled = gui2->mouseButtonCallback(button,state,x,y);
if (renderGui)
{
if (!handled && gui2)
handled = gui2->mouseButtonCallback(button,state,x,y);
}
if (!handled)
{
if (prevMouseButtonCallback )
@@ -329,21 +362,34 @@ void OpenGLExampleBrowser::registerFileImporter(const char* extension, CommonExa
fi.m_createFunc = createFunc;
gFileImporterByExtension.push_back(fi);
}
#include "../SharedMemory/SharedMemoryPublic.h"
void OpenGLExampleBrowserVisualizerFlagCallback(int flag, bool enable)
{
if (flag == COV_ENABLE_SHADOWS)
{
useShadowMap = enable;
}
if (flag == COV_ENABLE_GUI)
{
renderGui = enable;
renderGrid = enable;
}
if (flag == COV_ENABLE_WIREFRAME)
{
visualWireframe = enable;
}
}
void openFileDemo(const char* filename)
{
if (sCurrentDemo)
{
sCurrentDemo->exitPhysics();
s_instancingRenderer->removeAllInstances();
delete sCurrentDemo;
sCurrentDemo=0;
delete s_guiHelper;
s_guiHelper = 0;
}
deleteDemo();
s_guiHelper= new OpenGLGuiHelper(s_app, sUseOpenGL2);
s_guiHelper->setVisualizerFlagCallback(OpenGLExampleBrowserVisualizerFlagCallback);
s_parameterInterface->removeAllParameters();
@@ -387,6 +433,7 @@ void selectDemo(int demoIndex)
demoIndex = 0;
}
deleteDemo();
CommonExampleInterface::CreateFunc* func = gAllExamples->getExampleCreateFunc(demoIndex);
if (func)
@@ -397,6 +444,8 @@ void selectDemo(int demoIndex)
}
int option = gAllExamples->getExampleOption(demoIndex);
s_guiHelper= new OpenGLGuiHelper(s_app, sUseOpenGL2);
s_guiHelper->setVisualizerFlagCallback(OpenGLExampleBrowserVisualizerFlagCallback);
CommonExampleOptions options(s_guiHelper, option);
options.m_sharedMem = sSharedMem;
sCurrentDemo = (*func)(options);
@@ -448,10 +497,10 @@ static void saveCurrentSettings(int currentEntry,const char* startFileName)
{
fprintf(f,"--enable_experimental_opencl\n");
}
if (sUseOpenGL2 )
{
fprintf(f,"--opengl2\n");
}
// if (sUseOpenGL2 )
// {
// fprintf(f,"--opengl2\n");
// }
fclose(f);
}
@@ -459,7 +508,7 @@ static void saveCurrentSettings(int currentEntry,const char* startFileName)
static void loadCurrentSettings(const char* startFileName, b3CommandLineArgs& args)
{
int currentEntry= 0;
//int currentEntry= 0;
FILE* f = fopen(startFileName,"r");
if (f)
{
@@ -497,11 +546,13 @@ void MyComboBoxCallback(int comboId, const char* item)
}
//in case of multi-threading, don't submit messages while the GUI is rendering (causing crashes)
static bool gBlockGuiMessages = false;
void MyGuiPrintf(const char* msg)
{
printf("b3Printf: %s\n",msg);
if (!gDisableDemoSelection)
if (!gDisableDemoSelection && !gBlockGuiMessages)
{
gui2->textOutput(msg);
gui2->forceUpdateScrollBars();
@@ -513,7 +564,7 @@ void MyGuiPrintf(const char* msg)
void MyStatusBarPrintf(const char* msg)
{
printf("b3Printf: %s\n", msg);
if (!gDisableDemoSelection)
if (!gDisableDemoSelection && !gBlockGuiMessages)
{
bool isLeft = true;
gui2->setStatusBarMessage(msg,isLeft);
@@ -524,7 +575,7 @@ void MyStatusBarPrintf(const char* msg)
void MyStatusBarError(const char* msg)
{
printf("Warning: %s\n", msg);
if (!gDisableDemoSelection)
if (!gDisableDemoSelection && !gBlockGuiMessages)
{
bool isLeft = false;
gui2->setStatusBarMessage(msg,isLeft);
@@ -751,9 +802,15 @@ OpenGLExampleBrowser::~OpenGLExampleBrowser()
delete s_app->m_2dCanvasInterface;
s_app->m_2dCanvasInterface = 0;
#ifndef BT_NO_PROFILE
destroyProfileWindow(m_internalData->m_profWindow);
#endif
m_internalData->m_gui->exit();
delete m_internalData->m_gui;
delete m_internalData->m_gwenRenderer;
delete m_internalData->m_myTexLoader;
@@ -766,15 +823,19 @@ OpenGLExampleBrowser::~OpenGLExampleBrowser()
s_app = 0;
// delete m_internalData->m_profWindow;
delete m_internalData;
gFileImporterByExtension.clear();
gAllExamples = 0;
}
#include "EmptyExample.h"
bool OpenGLExampleBrowser::init(int argc, char* argv[])
@@ -782,7 +843,15 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
b3CommandLineArgs args(argc,argv);
loadCurrentSettings(startFileName, args);
if (args.CheckCmdLineFlag("nogui"))
{
renderGrid = false;
renderGui = false;
}
if (args.CheckCmdLineFlag("tracing"))
{
b3ChromeUtilsStartTimings();
}
args.GetCmdLineArgument("fixed_timestep",gFixedTimeStep);
args.GetCmdLineArgument("png_skip_frames", gPngSkipFrames);
///The OpenCL rigid body pipeline is experimental and
@@ -795,6 +864,7 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
enable_experimental_opencl = true;
gAllExamples->initOpenCLExampleEntries();
}
if (args.CheckCmdLineFlag("disable_retina"))
{
gAllowRetina = false;
@@ -803,6 +873,16 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
int width = 1024;
int height=768;
if (args.CheckCmdLineFlag("width"))
{
args.GetCmdLineArgument("width",width );
}
if (args.CheckCmdLineFlag("height"))
{
args.GetCmdLineArgument("height",height);
}
#ifndef NO_OPENGL3
SimpleOpenGL3App* simpleApp=0;
sUseOpenGL2 =args.CheckCmdLineFlag("opengl2");
@@ -886,6 +966,7 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
b3SetCustomPrintfFunc(MyGuiPrintf);
b3SetCustomErrorMessageFunc(MyStatusBarError);
assert(glGetError()==GL_NO_ERROR);
@@ -940,10 +1021,11 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
//gui->getInternalData()->pRenderer->setTextureLoader(myTexLoader);
// s_profWindow= setupProfileWindow(gui2->getInternalData());
//m_internalData->m_profWindow = s_profWindow;
// profileWindowSetVisible(s_profWindow,false);
#ifndef BT_NO_PROFILE
s_profWindow= setupProfileWindow(gui2->getInternalData());
m_internalData->m_profWindow = s_profWindow;
profileWindowSetVisible(s_profWindow,false);
#endif //BT_NO_PROFILE
gui2->setFocus();
s_parameterInterface = s_app->m_parameterInterface = new GwenParameterInterface(gui2->getInternalData());
@@ -1073,7 +1155,6 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
}
CommonExampleInterface* OpenGLExampleBrowser::getCurrentExample()
{
btAssert(sCurrentDemo);
@@ -1085,8 +1166,22 @@ bool OpenGLExampleBrowser::requestedExit()
return s_window->requestedExit();
}
void OpenGLExampleBrowser::updateGraphics()
{
if (sCurrentDemo)
{
if (!pauseSimulation || singleStepSimulation)
{
B3_PROFILE("sCurrentDemo->updateGraphics");
sCurrentDemo->updateGraphics();
}
}
}
void OpenGLExampleBrowser::update(float deltaTime)
{
b3ChromeUtilsEnableProfiling();
B3_PROFILE("OpenGLExampleBrowser::update");
assert(glGetError()==GL_NO_ERROR);
s_instancingRenderer->init();
@@ -1136,7 +1231,7 @@ void OpenGLExampleBrowser::update(float deltaTime)
{
if (!pauseSimulation || singleStepSimulation)
{
singleStepSimulation = false;
//printf("---------------------------------------------------\n");
//printf("Framecount = %d\n",frameCount);
B3_PROFILE("sCurrentDemo->stepSimulation");
@@ -1154,8 +1249,8 @@ void OpenGLExampleBrowser::update(float deltaTime)
if (renderGrid)
{
BT_PROFILE("Draw Grid");
glPolygonOffset(3.0, 3);
glEnable(GL_POLYGON_OFFSET_FILL);
//glPolygonOffset(3.0, 3);
//glEnable(GL_POLYGON_OFFSET_FILL);
s_app->drawGrid(dg);
}
@@ -1167,7 +1262,8 @@ void OpenGLExampleBrowser::update(float deltaTime)
}
BT_PROFILE("Render Scene");
sCurrentDemo->renderScene();
} else
}
//else
{
B3_PROFILE("physicsDebugDraw");
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
@@ -1198,9 +1294,18 @@ void OpenGLExampleBrowser::update(float deltaTime)
if (renderGui)
{
B3_PROFILE("renderGui");
// if (!pauseSimulation)
// processProfileData(s_profWindow,false);
#ifndef BT_NO_PROFILE
if (!pauseSimulation || singleStepSimulation)
{
if (isProfileWindowVisible(s_profWindow))
{
processProfileData(s_profWindow,false);
}
}
#endif //#ifndef BT_NO_PROFILE
if (sUseOpenGL2)
{
@@ -1209,7 +1314,11 @@ void OpenGLExampleBrowser::update(float deltaTime)
if (m_internalData->m_gui)
{
gBlockGuiMessages = true;
m_internalData->m_gui->draw(s_instancingRenderer->getScreenWidth(), s_instancingRenderer->getScreenHeight());
gBlockGuiMessages = false;
}
if (sUseOpenGL2)
@@ -1219,7 +1328,7 @@ void OpenGLExampleBrowser::update(float deltaTime)
}
singleStepSimulation = false;
toggle=1-toggle;

View File

@@ -19,6 +19,8 @@ public:
virtual void update(float deltaTime);
virtual void updateGraphics();
virtual bool requestedExit();
virtual void setSharedMemoryInterface(class SharedMemoryInterface* sharedMem);

View File

@@ -7,11 +7,10 @@
#include "Bullet3Common/b3Scalar.h"
#include "CollisionShape2TriangleMesh.h"
#include "../OpenGLWindow/ShapeData.h"
#include "../OpenGLWindow/SimpleCamera.h"
#include "../OpenGLWindow/GLInstanceGraphicsShape.h"
//backwards compatibility
#include "GL_ShapeDrawer.h"
#define BT_LINE_BATCH_SIZE 512
@@ -29,17 +28,21 @@ struct MyDebugVec3
float y;
float z;
};
class MyDebugDrawer : public btIDebugDraw
ATTRIBUTE_ALIGNED16( class )MyDebugDrawer : public btIDebugDraw
{
CommonGraphicsApp* m_glApp;
int m_debugMode;
btAlignedObjectArray<MyDebugVec3> m_linePoints;
btAlignedObjectArray<unsigned int> m_lineIndices;
btVector3 m_currentLineColor;
DefaultColors m_ourColors;
public:
BT_DECLARE_ALIGNED_ALLOCATOR();
MyDebugDrawer(CommonGraphicsApp* app)
: m_glApp(app)
@@ -48,6 +51,10 @@ public:
{
}
virtual ~MyDebugDrawer()
{
}
virtual DefaultColors getDefaultColors() const
{
@@ -133,28 +140,90 @@ public:
static btVector4 sColors[4] =
{
btVector4(0.3,0.3,1,1),
btVector4(0.6,0.6,1,1),
btVector4(0,1,0,1),
btVector4(0,1,1,1),
btVector4(60./256.,186./256.,84./256.,1),
btVector4(244./256.,194./256.,13./256.,1),
btVector4(219./256.,50./256.,54./256.,1),
btVector4(72./256.,133./256.,237./256.,1),
//btVector4(1,1,0,1),
};
struct MyHashShape
{
int m_shapeKey;
int m_shapeType;
btVector3 m_sphere0Pos;
btVector3 m_sphere1Pos;
btScalar m_radius0;
btScalar m_radius1;
btTransform m_childTransform;
int m_deformFunc;
int m_upAxis;
btScalar m_halfHeight;
MyHashShape()
:m_shapeKey(0),
m_shapeType(0),
m_sphere0Pos(btVector3(0,0,0)),
m_sphere1Pos(btVector3(0,0,0)),
m_radius0(0),
m_radius1(0),
m_deformFunc(0),
m_upAxis(-1),
m_halfHeight(0)
{
m_childTransform.setIdentity();
}
bool equals(const MyHashShape& other) const
{
bool sameShapeType = m_shapeType==other.m_shapeType;
bool sameSphere0= m_sphere0Pos == other.m_sphere0Pos;
bool sameSphere1= m_sphere1Pos == other.m_sphere1Pos;
bool sameRadius0 = m_radius0== other.m_radius0;
bool sameRadius1 = m_radius1== other.m_radius1;
bool sameTransform = m_childTransform== other.m_childTransform;
bool sameUpAxis = m_upAxis == other.m_upAxis;
bool sameHalfHeight = m_halfHeight == other.m_halfHeight;
return sameShapeType && sameSphere0 && sameSphere1 && sameRadius0 && sameRadius1 && sameTransform && sameUpAxis && sameHalfHeight;
}
//to our success
SIMD_FORCE_INLINE unsigned int getHash()const
{
unsigned int key = m_shapeKey;
// Thomas Wang's hash
key += ~(key << 15); key ^= (key >> 10); key += (key << 3); key ^= (key >> 6); key += ~(key << 11); key ^= (key >> 16);
return key;
}
};
struct OpenGLGuiHelperInternalData
{
struct CommonGraphicsApp* m_glApp;
class MyDebugDrawer* m_debugDraw;
GL_ShapeDrawer* m_gl2ShapeDrawer;
bool m_vrMode;
int m_vrSkipShadowPass;
btAlignedObjectArray<unsigned char> m_rgbaPixelBuffer1;
btAlignedObjectArray<float> m_depthBuffer1;
btHashMap<MyHashShape, int> m_hashShapes;
VisualizerFlagCallback m_visualizerFlagCallback;
int m_checkedTexture;
int m_checkedTextureGrey;
OpenGLGuiHelperInternalData()
:m_vrMode(false),
m_vrSkipShadowPass(0)
m_vrSkipShadowPass(0),
m_visualizerFlagCallback(0),
m_checkedTexture(-1),
m_checkedTextureGrey(-1)
{
}
@@ -174,19 +243,13 @@ OpenGLGuiHelper::OpenGLGuiHelper(CommonGraphicsApp* glApp, bool useOpenGL2)
m_data->m_glApp = glApp;
m_data->m_debugDraw = 0;
m_data->m_gl2ShapeDrawer = 0;
if (useOpenGL2)
{
m_data->m_gl2ShapeDrawer = new GL_ShapeDrawer();
}
}
OpenGLGuiHelper::~OpenGLGuiHelper()
{
delete m_data->m_debugDraw;
delete m_data->m_gl2ShapeDrawer;
delete m_data;
}
@@ -195,6 +258,11 @@ struct CommonRenderInterface* OpenGLGuiHelper::getRenderInterface()
return m_data->m_glApp->m_renderer;
}
const struct CommonRenderInterface* OpenGLGuiHelper::getRenderInterface() const
{
return m_data->m_glApp->m_renderer;
}
void OpenGLGuiHelper::createRigidBodyGraphicsObject(btRigidBody* body, const btVector3& color)
{
createCollisionObjectGraphicsObject(body,color);
@@ -238,19 +306,538 @@ int OpenGLGuiHelper::registerGraphicsInstance(int shapeIndex, const float* posit
void OpenGLGuiHelper::removeAllGraphicsInstances()
{
m_data->m_hashShapes.clear();
m_data->m_glApp->m_renderer->removeAllInstances();
}
void OpenGLGuiHelper::removeGraphicsInstance(int graphicsUid)
{
if (graphicsUid>=0)
{
m_data->m_glApp->m_renderer->removeGraphicsInstance(graphicsUid);
};
}
void OpenGLGuiHelper::changeRGBAColor(int instanceUid, const double rgbaColor[4])
{
if (instanceUid>=0)
{
m_data->m_glApp->m_renderer->writeSingleInstanceColorToCPU(rgbaColor,instanceUid);
};
}
int OpenGLGuiHelper::createCheckeredTexture(int red,int green, int blue)
{
int texWidth=1024;
int texHeight=1024;
btAlignedObjectArray<unsigned char> texels;
texels.resize(texWidth*texHeight*3);
for (int i=0;i<texWidth*texHeight*3;i++)
texels[i]=255;
for (int i=0;i<texWidth;i++)
{
for (int j=0;j<texHeight;j++)
{
int a = i<texWidth/2? 1 : 0;
int b = j<texWidth/2? 1 : 0;
if (a==b)
{
texels[(i+j*texWidth)*3+0] = red;
texels[(i+j*texWidth)*3+1] = green;
texels[(i+j*texWidth)*3+2] = blue;
// texels[(i+j*texWidth)*4+3] = 255;
}
/*else
{
texels[i*3+0+j*texWidth] = 255;
texels[i*3+1+j*texWidth] = 255;
texels[i*3+2+j*texWidth] = 255;
}
*/
}
}
int texId = registerTexture(&texels[0],texWidth,texHeight);
return texId;
}
void OpenGLGuiHelper::createCollisionShapeGraphicsObject(btCollisionShape* collisionShape)
{
//already has a graphics object?
if (collisionShape->getUserIndex()>=0)
return;
btAlignedObjectArray<GLInstanceVertex> gfxVertices;
if (m_data->m_checkedTexture<0)
{
m_data->m_checkedTexture = createCheckeredTexture(192,192,255);
}
if (m_data->m_checkedTextureGrey<0)
{
m_data->m_checkedTextureGrey = createCheckeredTexture(192,192,192);
}
btAlignedObjectArray<GLInstanceVertex> gfxVertices;
btAlignedObjectArray<int> indices;
int strideInBytes = 9*sizeof(float);
//if (collisionShape->getShapeType()==BOX_SHAPE_PROXYTYPE)
{
}
if (collisionShape->getShapeType()==MULTI_SPHERE_SHAPE_PROXYTYPE)
{
btMultiSphereShape* ms = (btMultiSphereShape*) collisionShape;
if (ms->getSphereCount()==2)
{
btAlignedObjectArray<float> transformedVertices;
int numVertices = sizeof(textured_detailed_sphere_vertices)/strideInBytes;
transformedVertices.resize(numVertices*9);
btVector3 sphere0Pos = ms->getSpherePosition(0);
btVector3 sphere1Pos = ms->getSpherePosition(1);
btVector3 fromTo = sphere1Pos-sphere0Pos;
MyHashShape shape;
shape.m_sphere0Pos = sphere0Pos;
shape.m_sphere1Pos = sphere1Pos;
shape.m_radius0 = 2.*ms->getSphereRadius(0);
shape.m_radius1 = 2.*ms->getSphereRadius(1);
shape.m_deformFunc = 1;//vert.dot(fromTo)
int graphicsShapeIndex = -1;
int* graphicsShapeIndexPtr = m_data->m_hashShapes[shape];
if (graphicsShapeIndexPtr)
{
//cache hit
graphicsShapeIndex = *graphicsShapeIndexPtr;
} else
{
//cache miss
for (int i=0;i<numVertices;i++)
{
btVector3 vert;
vert.setValue(textured_detailed_sphere_vertices[i*9+0],
textured_detailed_sphere_vertices[i*9+1],
textured_detailed_sphere_vertices[i*9+2]);
btVector3 trVer(0,0,0);
if (vert.dot(fromTo)>0)
{
btScalar radiusScale = 2.*ms->getSphereRadius(1);
trVer = radiusScale*vert;
trVer+=sphere1Pos;
} else
{
btScalar radiusScale = 2.*ms->getSphereRadius(0);
trVer = radiusScale*vert;
trVer+=sphere0Pos;
}
transformedVertices[i*9+0] = trVer[0];
transformedVertices[i*9+1] = trVer[1];
transformedVertices[i*9+2] = trVer[2];
transformedVertices[i*9+3] =textured_detailed_sphere_vertices[i*9+3];
transformedVertices[i*9+4] =textured_detailed_sphere_vertices[i*9+4];
transformedVertices[i*9+5] =textured_detailed_sphere_vertices[i*9+5];
transformedVertices[i*9+6] =textured_detailed_sphere_vertices[i*9+6];
transformedVertices[i*9+7] =textured_detailed_sphere_vertices[i*9+7];
transformedVertices[i*9+8] =textured_detailed_sphere_vertices[i*9+8];
}
int numIndices = sizeof(textured_detailed_sphere_indices)/sizeof(int);
graphicsShapeIndex = registerGraphicsShape(&transformedVertices[0],numVertices,textured_detailed_sphere_indices,numIndices,B3_GL_TRIANGLES,m_data->m_checkedTextureGrey);
m_data->m_hashShapes.insert(shape,graphicsShapeIndex);
}
collisionShape->setUserIndex(graphicsShapeIndex);
return;
}
}
if (collisionShape->getShapeType()==SPHERE_SHAPE_PROXYTYPE)
{
btSphereShape* sphereShape = (btSphereShape*) collisionShape;
btScalar radius = sphereShape->getRadius();
btScalar sphereSize = 2.*radius;
btVector3 radiusScale(sphereSize,sphereSize,sphereSize);
btAlignedObjectArray<float> transformedVertices;
MyHashShape shape;
shape.m_radius0 = sphereSize;
shape.m_deformFunc = 0;////no deform
int graphicsShapeIndex = -1;
int* graphicsShapeIndexPtr = m_data->m_hashShapes[shape];
if (graphicsShapeIndexPtr)
{
graphicsShapeIndex = *graphicsShapeIndexPtr;
} else
{
int numVertices = sizeof(textured_detailed_sphere_vertices)/strideInBytes;
transformedVertices.resize(numVertices*9);
for (int i=0;i<numVertices;i++)
{
btVector3 vert;
vert.setValue(textured_detailed_sphere_vertices[i*9+0],
textured_detailed_sphere_vertices[i*9+1],
textured_detailed_sphere_vertices[i*9+2]);
btVector3 trVer = radiusScale*vert;
transformedVertices[i*9+0] = trVer[0];
transformedVertices[i*9+1] = trVer[1];
transformedVertices[i*9+2] = trVer[2];
transformedVertices[i*9+3] =textured_detailed_sphere_vertices[i*9+3];
transformedVertices[i*9+4] =textured_detailed_sphere_vertices[i*9+4];
transformedVertices[i*9+5] =textured_detailed_sphere_vertices[i*9+5];
transformedVertices[i*9+6] =textured_detailed_sphere_vertices[i*9+6];
transformedVertices[i*9+7] =textured_detailed_sphere_vertices[i*9+7];
transformedVertices[i*9+8] =textured_detailed_sphere_vertices[i*9+8];
}
int numIndices = sizeof(textured_detailed_sphere_indices)/sizeof(int);
graphicsShapeIndex = registerGraphicsShape(&transformedVertices[0],numVertices,textured_detailed_sphere_indices,numIndices,B3_GL_TRIANGLES,m_data->m_checkedTextureGrey);
m_data->m_hashShapes.insert(shape,graphicsShapeIndex);
}
collisionShape->setUserIndex(graphicsShapeIndex);
return;
}
if (collisionShape->getShapeType()==COMPOUND_SHAPE_PROXYTYPE)
{
btCompoundShape* compound = (btCompoundShape*)collisionShape;
if (compound->getNumChildShapes()==1)
{
if (compound->getChildShape(0)->getShapeType()==SPHERE_SHAPE_PROXYTYPE)
{
btSphereShape* sphereShape = (btSphereShape*) compound->getChildShape(0);
btScalar radius = sphereShape->getRadius();
btScalar sphereSize = 2.*radius;
btVector3 radiusScale(sphereSize,sphereSize,sphereSize);
MyHashShape shape;
shape.m_radius0 = sphereSize;
shape.m_deformFunc = 0;//no deform
shape.m_childTransform = compound->getChildTransform(0);
int graphicsShapeIndex = -1;
int* graphicsShapeIndexPtr = m_data->m_hashShapes[shape];
if (graphicsShapeIndexPtr)
{
graphicsShapeIndex = *graphicsShapeIndexPtr;
}
else
{
btAlignedObjectArray<float> transformedVertices;
int numVertices = sizeof(textured_detailed_sphere_vertices)/strideInBytes;
transformedVertices.resize(numVertices*9);
for (int i=0;i<numVertices;i++)
{
btVector3 vert;
vert.setValue(textured_detailed_sphere_vertices[i*9+0],
textured_detailed_sphere_vertices[i*9+1],
textured_detailed_sphere_vertices[i*9+2]);
btVector3 trVer = compound->getChildTransform(0)*(radiusScale*vert);
transformedVertices[i*9+0] = trVer[0];
transformedVertices[i*9+1] = trVer[1];
transformedVertices[i*9+2] = trVer[2];
transformedVertices[i*9+3] =textured_detailed_sphere_vertices[i*9+3];
transformedVertices[i*9+4] =textured_detailed_sphere_vertices[i*9+4];
transformedVertices[i*9+5] =textured_detailed_sphere_vertices[i*9+5];
transformedVertices[i*9+6] =textured_detailed_sphere_vertices[i*9+6];
transformedVertices[i*9+7] =textured_detailed_sphere_vertices[i*9+7];
transformedVertices[i*9+8] =textured_detailed_sphere_vertices[i*9+8];
}
int numIndices = sizeof(textured_detailed_sphere_indices)/sizeof(int);
graphicsShapeIndex = registerGraphicsShape(&transformedVertices[0],numVertices,textured_detailed_sphere_indices,numIndices,B3_GL_TRIANGLES,m_data->m_checkedTextureGrey);
m_data->m_hashShapes.insert(shape,graphicsShapeIndex);
}
collisionShape->setUserIndex(graphicsShapeIndex);
return;
}
if (compound->getChildShape(0)->getShapeType()==CAPSULE_SHAPE_PROXYTYPE)
{
btCapsuleShape* sphereShape = (btCapsuleShape*) compound->getChildShape(0);
int up = sphereShape->getUpAxis();
btScalar halfHeight = sphereShape->getHalfHeight();
btScalar radius = sphereShape->getRadius();
btScalar sphereSize = 2.*radius;
btVector3 radiusScale = btVector3(sphereSize,sphereSize,sphereSize);
MyHashShape shape;
shape.m_radius0 = sphereSize;
shape.m_deformFunc = 2;//no deform
shape.m_childTransform = compound->getChildTransform(0);
shape.m_upAxis = up;
int graphicsShapeIndex = -1;
int* graphicsShapeIndexPtr = m_data->m_hashShapes[shape];
if (graphicsShapeIndexPtr)
{
graphicsShapeIndex = *graphicsShapeIndexPtr;
}
else
{
btAlignedObjectArray<float> transformedVertices;
int numVertices = sizeof(textured_detailed_sphere_vertices)/strideInBytes;
transformedVertices.resize(numVertices*9);
for (int i=0;i<numVertices;i++)
{
btVector3 vert;
vert.setValue(textured_detailed_sphere_vertices[i*9+0],
textured_detailed_sphere_vertices[i*9+1],
textured_detailed_sphere_vertices[i*9+2]);
btVector3 trVer = compound->getChildTransform(0)*(radiusScale*vert);
if (trVer[up]>0)
trVer[up]+=halfHeight;
else
trVer[up]-=halfHeight;
transformedVertices[i*9+0] = trVer[0];
transformedVertices[i*9+1] = trVer[1];
transformedVertices[i*9+2] = trVer[2];
transformedVertices[i*9+3] =textured_detailed_sphere_vertices[i*9+3];
transformedVertices[i*9+4] =textured_detailed_sphere_vertices[i*9+4];
transformedVertices[i*9+5] =textured_detailed_sphere_vertices[i*9+5];
transformedVertices[i*9+6] =textured_detailed_sphere_vertices[i*9+6];
transformedVertices[i*9+7] =textured_detailed_sphere_vertices[i*9+7];
transformedVertices[i*9+8] =textured_detailed_sphere_vertices[i*9+8];
}
int numIndices = sizeof(textured_detailed_sphere_indices)/sizeof(int);
graphicsShapeIndex = registerGraphicsShape(&transformedVertices[0],numVertices,textured_detailed_sphere_indices,numIndices,B3_GL_TRIANGLES,m_data->m_checkedTextureGrey);
m_data->m_hashShapes.insert(shape,graphicsShapeIndex);
}
collisionShape->setUserIndex(graphicsShapeIndex);
return;
}
if (compound->getChildShape(0)->getShapeType()==MULTI_SPHERE_SHAPE_PROXYTYPE)
{
btMultiSphereShape* ms = (btMultiSphereShape*) compound->getChildShape(0);
if (ms->getSphereCount()==2)
{
btAlignedObjectArray<float> transformedVertices;
int numVertices = sizeof(textured_detailed_sphere_vertices)/strideInBytes;
transformedVertices.resize(numVertices*9);
btVector3 sphere0Pos = ms->getSpherePosition(0);
btVector3 sphere1Pos = ms->getSpherePosition(1);
btVector3 fromTo = sphere1Pos-sphere0Pos;
btScalar radiusScale1 = 2.0*ms->getSphereRadius(1);
btScalar radiusScale0 = 2.0*ms->getSphereRadius(0);
MyHashShape shape;
shape.m_radius0 = radiusScale0;
shape.m_radius1 = radiusScale1;
shape.m_deformFunc = 4;
shape.m_sphere0Pos = sphere0Pos;
shape.m_sphere1Pos = sphere1Pos;
shape.m_childTransform = compound->getChildTransform(0);
int graphicsShapeIndex = -1;
int* graphicsShapeIndexPtr = m_data->m_hashShapes[shape];
if (graphicsShapeIndexPtr)
{
graphicsShapeIndex = *graphicsShapeIndexPtr;
}
else
{
for (int i=0;i<numVertices;i++)
{
btVector3 vert;
vert.setValue(textured_detailed_sphere_vertices[i*9+0],
textured_detailed_sphere_vertices[i*9+1],
textured_detailed_sphere_vertices[i*9+2]);
btVector3 trVer(0,0,0);
if (vert.dot(fromTo)>0)
{
trVer = vert*radiusScale1;
trVer+=sphere1Pos;
trVer = compound->getChildTransform(0)*trVer;
} else
{
trVer = vert*radiusScale0;
trVer+=sphere0Pos;
trVer=compound->getChildTransform(0)*trVer;
}
transformedVertices[i*9+0] = trVer[0];
transformedVertices[i*9+1] = trVer[1];
transformedVertices[i*9+2] = trVer[2];
transformedVertices[i*9+3] =textured_detailed_sphere_vertices[i*9+3];
transformedVertices[i*9+4] =textured_detailed_sphere_vertices[i*9+4];
transformedVertices[i*9+5] =textured_detailed_sphere_vertices[i*9+5];
transformedVertices[i*9+6] =textured_detailed_sphere_vertices[i*9+6];
transformedVertices[i*9+7] =textured_detailed_sphere_vertices[i*9+7];
transformedVertices[i*9+8] =textured_detailed_sphere_vertices[i*9+8];
}
int numIndices = sizeof(textured_detailed_sphere_indices)/sizeof(int);
graphicsShapeIndex = registerGraphicsShape(&transformedVertices[0],numVertices,textured_detailed_sphere_indices,numIndices,B3_GL_TRIANGLES,m_data->m_checkedTextureGrey);
m_data->m_hashShapes.insert(shape,graphicsShapeIndex);
}
collisionShape->setUserIndex(graphicsShapeIndex);
return;
}
}
}
}
if (collisionShape->getShapeType()==CAPSULE_SHAPE_PROXYTYPE)
{
btCapsuleShape* sphereShape = (btCapsuleShape*) collisionShape;//Y up
int up = sphereShape->getUpAxis();
btScalar halfHeight = sphereShape->getHalfHeight();
btScalar radius = sphereShape->getRadius();
btScalar sphereSize = 2.*radius;
btVector3 radiusScale(sphereSize,sphereSize,sphereSize);
MyHashShape shape;
shape.m_radius0 = sphereSize;
shape.m_deformFunc = 3;
shape.m_upAxis = up;
shape.m_halfHeight = halfHeight;
int graphicsShapeIndex = -1;
int* graphicsShapeIndexPtr = m_data->m_hashShapes[shape];
if (graphicsShapeIndexPtr)
{
graphicsShapeIndex = *graphicsShapeIndexPtr;
}
else
{
btAlignedObjectArray<float> transformedVertices;
int numVertices = sizeof(textured_detailed_sphere_vertices)/strideInBytes;
transformedVertices.resize(numVertices*9);
for (int i=0;i<numVertices;i++)
{
btVector3 vert;
vert.setValue(textured_detailed_sphere_vertices[i*9+0],
textured_detailed_sphere_vertices[i*9+1],
textured_detailed_sphere_vertices[i*9+2]);
btVector3 trVer = radiusScale*vert;
if (trVer[up]>0)
trVer[up]+=halfHeight;
else
trVer[up]-=halfHeight;
transformedVertices[i*9+0] = trVer[0];
transformedVertices[i*9+1] = trVer[1];
transformedVertices[i*9+2] = trVer[2];
transformedVertices[i*9+3] =textured_detailed_sphere_vertices[i*9+3];
transformedVertices[i*9+4] =textured_detailed_sphere_vertices[i*9+4];
transformedVertices[i*9+5] =textured_detailed_sphere_vertices[i*9+5];
transformedVertices[i*9+6] =textured_detailed_sphere_vertices[i*9+6];
transformedVertices[i*9+7] =textured_detailed_sphere_vertices[i*9+7];
transformedVertices[i*9+8] =textured_detailed_sphere_vertices[i*9+8];
}
int numIndices = sizeof(textured_detailed_sphere_indices)/sizeof(int);
graphicsShapeIndex = registerGraphicsShape(&transformedVertices[0],numVertices,textured_detailed_sphere_indices,numIndices,B3_GL_TRIANGLES,m_data->m_checkedTextureGrey);
m_data->m_hashShapes.insert(shape,graphicsShapeIndex);
}
collisionShape->setUserIndex(graphicsShapeIndex);
return;
}
if (collisionShape->getShapeType()==STATIC_PLANE_PROXYTYPE)
{
const btStaticPlaneShape* staticPlaneShape = static_cast<const btStaticPlaneShape*>(collisionShape);
btScalar planeConst = staticPlaneShape->getPlaneConstant();
const btVector3& planeNormal = staticPlaneShape->getPlaneNormal();
btVector3 planeOrigin = planeNormal * planeConst;
btVector3 vec0,vec1;
btPlaneSpace1(planeNormal,vec0,vec1);
btScalar vecLen = 128;
btVector3 verts[4];
verts[0] = planeOrigin + vec0*vecLen + vec1*vecLen;
verts[1] = planeOrigin - vec0*vecLen + vec1*vecLen;
verts[2] = planeOrigin - vec0*vecLen - vec1*vecLen;
verts[3] = planeOrigin + vec0*vecLen - vec1*vecLen;
int startIndex = 0;
indices.push_back(startIndex+0);
indices.push_back(startIndex+1);
indices.push_back(startIndex+2);
indices.push_back(startIndex+0);
indices.push_back(startIndex+2);
indices.push_back(startIndex+3);
btTransform parentTransform;
parentTransform.setIdentity();
btVector3 triNormal = parentTransform.getBasis()*planeNormal;
gfxVertices.resize(4);
for (int i=0;i<4;i++)
{
btVector3 vtxPos;
btVector3 pos =parentTransform*verts[i];
gfxVertices[i].xyzw[0] = pos[0];
gfxVertices[i].xyzw[1] = pos[1];
gfxVertices[i].xyzw[2] = pos[2];
gfxVertices[i].xyzw[3] = 1;
gfxVertices[i].normal[0] = triNormal[0];
gfxVertices[i].normal[1] = triNormal[1];
gfxVertices[i].normal[2] = triNormal[2];
}
//verts[0] = planeOrigin + vec0*vecLen + vec1*vecLen;
//verts[1] = planeOrigin - vec0*vecLen + vec1*vecLen;
//verts[2] = planeOrigin - vec0*vecLen - vec1*vecLen;
//verts[3] = planeOrigin + vec0*vecLen - vec1*vecLen;
gfxVertices[0].uv[0] = vecLen/2;
gfxVertices[0].uv[1] = vecLen/2;
gfxVertices[1].uv[0] = -vecLen/2;
gfxVertices[1].uv[1] = vecLen/2;
gfxVertices[2].uv[0] = -vecLen/2;
gfxVertices[2].uv[1] = -vecLen/2;
gfxVertices[3].uv[0] = vecLen/2;
gfxVertices[3].uv[1] = -vecLen/2;
int shapeId = registerGraphicsShape(&gfxVertices[0].xyzw[0],gfxVertices.size(),&indices[0],indices.size(),B3_GL_TRIANGLES,m_data->m_checkedTexture);
collisionShape->setUserIndex(shapeId);
return;
}
btTransform startTrans;startTrans.setIdentity();
//todo: create some textured objects for popular objects, like plane, cube, sphere, capsule
{
btAlignedObjectArray<btVector3> vertexPositions;
@@ -333,17 +920,17 @@ void OpenGLGuiHelper::render(const btDiscreteDynamicsWorld* rbWorld)
m_data->m_glApp->m_renderer->renderScene();
}
//backwards compatible OpenGL2 rendering
if (m_data->m_gl2ShapeDrawer && rbWorld)
{
m_data->m_gl2ShapeDrawer->enableTexture(true);
m_data->m_gl2ShapeDrawer->drawScene(rbWorld,true, m_data->m_glApp->getUpAxis());
}
}
void OpenGLGuiHelper::createPhysicsDebugDrawer(btDiscreteDynamicsWorld* rbWorld)
{
btAssert(rbWorld);
if (m_data->m_debugDraw)
{
delete m_data->m_debugDraw;
m_data->m_debugDraw = 0;
}
m_data->m_debugDraw = new MyDebugDrawer(m_data->m_glApp);
rbWorld->setDebugDrawer(m_data->m_debugDraw );
@@ -372,6 +959,20 @@ void OpenGLGuiHelper::setUpAxis(int axis)
}
void OpenGLGuiHelper::setVisualizerFlagCallback(VisualizerFlagCallback callback)
{
m_data->m_visualizerFlagCallback = callback;
}
void OpenGLGuiHelper::setVisualizerFlag(int flag, int enable)
{
if (m_data->m_visualizerFlagCallback)
(m_data->m_visualizerFlagCallback)(flag,enable);
}
void OpenGLGuiHelper::resetCamera(float camDist, float pitch, float yaw, float camPosX,float camPosY, float camPosZ)
{
if (getRenderInterface() && getRenderInterface()->getActiveCamera())
@@ -383,6 +984,57 @@ void OpenGLGuiHelper::resetCamera(float camDist, float pitch, float yaw, float c
}
}
bool OpenGLGuiHelper::getCameraInfo(int* width, int* height, float viewMatrix[16], float projectionMatrix[16], float camUp[3], float camForward[3],float hor[3], float vert[3] ) const
{
if (getRenderInterface() && getRenderInterface()->getActiveCamera())
{
*width = m_data->m_glApp->m_window->getWidth()*m_data->m_glApp->m_window->getRetinaScale();
*height = m_data->m_glApp->m_window->getHeight()*m_data->m_glApp->m_window->getRetinaScale();
getRenderInterface()->getActiveCamera()->getCameraViewMatrix(viewMatrix);
getRenderInterface()->getActiveCamera()->getCameraProjectionMatrix(projectionMatrix);
getRenderInterface()->getActiveCamera()->getCameraUpVector(camUp);
getRenderInterface()->getActiveCamera()->getCameraForwardVector(camForward);
float frustumNearPlane = getRenderInterface()->getActiveCamera()->getCameraFrustumNear();
float frustumFarPlane = getRenderInterface()->getActiveCamera()->getCameraFrustumFar();
float top = 1.f;
float bottom = -1.f;
float tanFov = (top-bottom)*0.5f / frustumNearPlane;
float fov = btScalar(2.0) * btAtan(tanFov);
btVector3 camPos,camTarget;
getRenderInterface()->getActiveCamera()->getCameraPosition(camPos);
getRenderInterface()->getActiveCamera()->getCameraTargetPosition(camTarget);
btVector3 rayFrom = camPos;
btVector3 rayForward = (camTarget-camPos);
rayForward.normalize();
float farPlane = 10000.f;
rayForward*= farPlane;
btVector3 rightOffset;
btVector3 cameraUp=btVector3(camUp[0],camUp[1],camUp[2]);
btVector3 vertical = cameraUp;
btVector3 hori;
hori = rayForward.cross(vertical);
hori.normalize();
vertical = hori.cross(rayForward);
vertical.normalize();
float tanfov = tanf(0.5f*fov);
hori *= 2.f * farPlane * tanfov;
vertical *= 2.f * farPlane * tanfov;
btScalar aspect = *width / *height;
hori*=aspect;
//compute 'hor' and 'vert' vectors, useful to generate raytracer rays
hor[0] = hori[0];
hor[1] = hori[1];
hor[2] = hori[2];
vert[0] = vertical[0];
vert[1] = vertical[1];
vert[2] = vertical[2];
return true;
}
return false;
}
void OpenGLGuiHelper::copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
@@ -409,42 +1061,67 @@ void OpenGLGuiHelper::copyCameraImageData(const float viewMatrix[16], const floa
SimpleCamera tempCam;
getRenderInterface()->setActiveCamera(&tempCam);
getRenderInterface()->getActiveCamera()->setVRCamera(viewMatrix,projectionMatrix);
getRenderInterface()->renderScene();
{
BT_PROFILE("renderScene");
getRenderInterface()->renderScene();
}
getRenderInterface()->setActiveCamera(oldCam);
{
BT_PROFILE("copy pixels");
btAlignedObjectArray<unsigned char> sourceRgbaPixelBuffer;
btAlignedObjectArray<float> sourceDepthBuffer;
//copy the image into our local cache
sourceRgbaPixelBuffer.resize(sourceWidth*sourceHeight*numBytesPerPixel);
sourceDepthBuffer.resize(sourceWidth*sourceHeight);
m_data->m_glApp->getScreenPixels(&(sourceRgbaPixelBuffer[0]),sourceRgbaPixelBuffer.size(), &sourceDepthBuffer[0],sizeof(float)*sourceDepthBuffer.size());
{
BT_PROFILE("getScreenPixels");
m_data->m_glApp->getScreenPixels(&(sourceRgbaPixelBuffer[0]),sourceRgbaPixelBuffer.size(), &sourceDepthBuffer[0],sizeof(float)*sourceDepthBuffer.size());
}
m_data->m_rgbaPixelBuffer1.resize(destinationWidth*destinationHeight*numBytesPerPixel);
m_data->m_depthBuffer1.resize(destinationWidth*destinationHeight);
//rescale and flip
for (int i=0;i<destinationWidth;i++)
{
for (int j=0;j<destinationHeight;j++)
{
int xIndex = int(float(i)*(float(sourceWidth)/float(destinationWidth)));
int yIndex = int(float(destinationHeight-1-j)*(float(sourceHeight)/float(destinationHeight)));
btClamp(xIndex,0,sourceWidth);
btClamp(yIndex,0,sourceHeight);
int bytesPerPixel = 4; //RGBA
{
BT_PROFILE("resize and flip");
for (int j=0;j<destinationHeight;j++)
{
for (int i=0;i<destinationWidth;i++)
{
int xIndex = int(float(i)*(float(sourceWidth)/float(destinationWidth)));
int yIndex = int(float(destinationHeight-1-j)*(float(sourceHeight)/float(destinationHeight)));
btClamp(xIndex,0,sourceWidth);
btClamp(yIndex,0,sourceHeight);
int bytesPerPixel = 4; //RGBA
int sourcePixelIndex = (xIndex+yIndex*sourceWidth)*bytesPerPixel;
m_data->m_rgbaPixelBuffer1[(i+j*destinationWidth)*4+0] = sourceRgbaPixelBuffer[sourcePixelIndex+0];
m_data->m_rgbaPixelBuffer1[(i+j*destinationWidth)*4+1] = sourceRgbaPixelBuffer[sourcePixelIndex+1];
m_data->m_rgbaPixelBuffer1[(i+j*destinationWidth)*4+2] = sourceRgbaPixelBuffer[sourcePixelIndex+2];
m_data->m_rgbaPixelBuffer1[(i+j*destinationWidth)*4+3] = 255;
}
int sourcePixelIndex = (xIndex+yIndex*sourceWidth)*bytesPerPixel;
int sourceDepthIndex = xIndex+yIndex*sourceWidth;
#define COPY4PIXELS 1
#ifdef COPY4PIXELS
int* dst = (int*)&m_data->m_rgbaPixelBuffer1[(i+j*destinationWidth)*4+0];
int* src = (int*)&sourceRgbaPixelBuffer[sourcePixelIndex+0];
*dst = *src;
#else
m_data->m_rgbaPixelBuffer1[(i+j*destinationWidth)*4+0] = sourceRgbaPixelBuffer[sourcePixelIndex+0];
m_data->m_rgbaPixelBuffer1[(i+j*destinationWidth)*4+1] = sourceRgbaPixelBuffer[sourcePixelIndex+1];
m_data->m_rgbaPixelBuffer1[(i+j*destinationWidth)*4+2] = sourceRgbaPixelBuffer[sourcePixelIndex+2];
m_data->m_rgbaPixelBuffer1[(i+j*destinationWidth)*4+3] = 255;
#endif
if (depthBuffer)
{
m_data->m_depthBuffer1[i+j*destinationWidth] = sourceDepthBuffer[sourceDepthIndex];
}
}
}
}
}
}
if (pixelsRGBA)
{
BT_PROFILE("copy rgba pixels");
for (int i=0;i<numRequestedPixels*numBytesPerPixel;i++)
{
pixelsRGBA[i] = m_data->m_rgbaPixelBuffer1[i+startPixelIndex*numBytesPerPixel];
@@ -452,9 +1129,11 @@ void OpenGLGuiHelper::copyCameraImageData(const float viewMatrix[16], const floa
}
if (depthBuffer)
{
BT_PROFILE("copy depth buffer pixels");
for (int i=0;i<numRequestedPixels;i++)
{
depthBuffer[i] = m_data->m_depthBuffer1[i];
depthBuffer[i] = m_data->m_depthBuffer1[i+startPixelIndex];
}
}
if (numPixelsCopied)
@@ -495,7 +1174,7 @@ void OpenGLGuiHelper::autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWor
btCollisionObject* colObj = rbWorld->getCollisionObjectArray()[i];
sortedObjects.push_back(colObj);
}
sortedObjects.quickSort(shapePointerCompareFunc);
//sortedObjects.quickSort(shapePointerCompareFunc);
for (int i=0;i<sortedObjects.size();i++)
{
btCollisionObject* colObj = sortedObjects[i];
@@ -504,12 +1183,26 @@ void OpenGLGuiHelper::autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWor
createCollisionShapeGraphicsObject(colObj->getCollisionShape());
int colorIndex = colObj->getBroadphaseHandle()->getUid() & 3;
btVector3 color= sColors[colorIndex];
btVector4 color;
color = sColors[colorIndex];
if (colObj->getCollisionShape()->getShapeType()==STATIC_PLANE_PROXYTYPE)
{
color.setValue(1,1,1,1);
}
createCollisionObjectGraphicsObject(colObj,color);
}
}
void OpenGLGuiHelper::drawText3D( const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlags)
{
B3_PROFILE("OpenGLGuiHelper::drawText3D");
btAssert(m_data->m_glApp);
m_data->m_glApp->drawText3D(txt,position, orientation, color,size, optionFlags);
}
void OpenGLGuiHelper::drawText3D( const char* txt, float posX, float posY, float posZ, float size)
{
B3_PROFILE("OpenGLGuiHelper::drawText3D");
@@ -523,3 +1216,10 @@ struct CommonGraphicsApp* OpenGLGuiHelper::getAppInterface()
return m_data->m_glApp;
}
void OpenGLGuiHelper::dumpFramesToVideo(const char* mp4FileName)
{
if (m_data->m_glApp)
{
m_data->m_glApp->dumpFramesToVideo(mp4FileName);
}
}

View File

@@ -15,6 +15,7 @@ struct OpenGLGuiHelper : public GUIHelperInterface
virtual ~OpenGLGuiHelper();
virtual struct CommonRenderInterface* getRenderInterface();
virtual const struct CommonRenderInterface* getRenderInterface() const;
virtual void createRigidBodyGraphicsObject(btRigidBody* body, const btVector3& color);
@@ -24,6 +25,8 @@ struct OpenGLGuiHelper : public GUIHelperInterface
virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices,int primitiveType, int textureId);
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling);
virtual void removeAllGraphicsInstances();
virtual void removeGraphicsInstance(int graphicsUid);
virtual void changeRGBAColor(int instanceUid, const double rgbaColor[4]);
virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape);
@@ -42,8 +45,10 @@ struct OpenGLGuiHelper : public GUIHelperInterface
virtual void setUpAxis(int axis);
virtual void resetCamera(float camDist, float pitch, float yaw, float camPosX,float camPosY, float camPosZ);
virtual bool getCameraInfo(int* width, int* height, float viewMatrix[16], float projectionMatrix[16], float camUp[3], float camForward[3],float hor[3], float vert[3] ) const;
virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
float* depthBuffer, int depthBufferSizeInPixels,
@@ -52,8 +57,10 @@ struct OpenGLGuiHelper : public GUIHelperInterface
int destinationHeight, int* numPixelsCopied);
virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld) ;
virtual void drawText3D( const char* txt, float posX, float posY, float posZ, float size);
virtual void drawText3D( const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag);
virtual void drawText3D( const char* txt, float posX, float posY, float posZ, float size);
virtual int addUserDebugText3D( const char* txt, const double positionXYZ[3], const double textColorRGB[3], double size, double lifeTime)
{
@@ -63,6 +70,11 @@ struct OpenGLGuiHelper : public GUIHelperInterface
{
return -1;
}
virtual int addUserDebugParameter(const char* txt, double rangeMin, double rangeMax, double startValue)
{
return -1;
}
virtual void removeUserDebugItem( int debugItemUniqueId)
{
}
@@ -75,7 +87,13 @@ struct OpenGLGuiHelper : public GUIHelperInterface
void setVRMode(bool vrMode);
void setVisualizerFlag(int flag, int enable);
virtual void setVisualizerFlagCallback(VisualizerFlagCallback callback);
virtual void dumpFramesToVideo(const char* mp4FileName);
int createCheckeredTexture(int r,int g, int b);
};
#endif //OPENGL_GUI_HELPER_H

View File

@@ -1,5 +1,3 @@
#include "OpenGLExampleBrowser.h"
#include "Bullet3Common/b3CommandLineArgs.h"
@@ -19,13 +17,15 @@
#include "LinearMath/btAlignedAllocator.h"
static double gMinUpdateTimeMicroSecs = 1000.;
int main(int argc, char* argv[])
{
{
b3CommandLineArgs args(argc, argv);
b3Clock clock;
args.GetCmdLineArgument("minUpdateTimeMicroSecs",gMinUpdateTimeMicroSecs);
ExampleEntriesAll examples;
examples.initExampleEntries();
@@ -45,9 +45,18 @@ int main(int argc, char* argv[])
do
{
float deltaTimeInSeconds = clock.getTimeMicroseconds() / 1000000.f;
clock.reset();
exampleBrowser->update(deltaTimeInSeconds);
if (deltaTimeInSeconds > 0.1)
{
deltaTimeInSeconds = 0.1;
}
if (deltaTimeInSeconds < (gMinUpdateTimeMicroSecs/1e6))
{
b3Clock::usleep(gMinUpdateTimeMicroSecs/10.);
} else
{
clock.reset();
exampleBrowser->update(deltaTimeInSeconds);
}
} while (!exampleBrowser->requestedExit());
}
delete exampleBrowser;

View File

@@ -35,6 +35,28 @@ project "App_BulletExampleBrowser"
}
end
if _OPTIONS["audio"] then
files {"../TinyAudio/*.cpp"}
defines {"B3_ENABLE_TINY_AUDIO"}
if os.is("Windows") then
links {"winmm","Wsock32","dsound"}
defines {"WIN32","__WINDOWS_MM__","__WINDOWS_DS__"}
end
if os.is("Linux") then initX11()
defines {"__OS_LINUX__","__LINUX_ALSA__"}
links {"asound","pthread"}
end
if os.is("MacOSX") then
links{"Cocoa.framework"}
links{"CoreAudio.framework", "coreMIDI.framework", "Cocoa.framework"}
defines {"__OS_MACOSX__","__MACOSX_CORE__"}
end
end
if _OPTIONS["lua"] then
includedirs{"../ThirdPartyLibs/lua-5.2.3/src"}
links {"lua-5.2.3"}
@@ -88,15 +110,21 @@ project "App_BulletExampleBrowser"
"../SharedMemory/PhysicsServerCommandProcessor.h",
"../SharedMemory/TinyRendererVisualShapeConverter.cpp",
"../SharedMemory/TinyRendererVisualShapeConverter.h",
"../SharedMemory/SharedMemoryCommands.h",
"../SharedMemory/SharedMemoryPublic.h",
"../MultiThreading/MultiThreadingExample.cpp",
"../MultiThreading/b3PosixThreadSupport.cpp",
"../MultiThreading/b3Win32ThreadSupport.cpp",
"../MultiThreading/b3ThreadSupportInterface.cpp",
"../InverseDynamics/InverseDynamicsExample.cpp",
"../InverseDynamics/InverseDynamicsExample.h",
"../RobotSimulator/b3RobotSimulatorClientAPI.cpp",
"../RobotSimulator/b3RobotSimulatorClientAPI.h",
"../BasicDemo/BasicExample.*",
"../Tutorial/*",
"../ExtendedTutorials/*",
"../Utils/RobotLoggingUtil.cpp",
"../Utils/RobotLoggingUtil.h",
"../Evolution/NN3DWalkers.cpp",
"../Evolution/NN3DWalkers.h",
"../Collision/*",
@@ -180,6 +208,8 @@ project "BulletExampleBrowserLib"
files {"../LuaDemo/LuaPhysicsSetup.cpp"}
end
initOpenGL()
initGlew()
@@ -193,6 +223,9 @@ project "BulletExampleBrowserLib"
"OpenGLGuiHelper.cpp",
"OpenGLExampleBrowser.cpp",
"../Utils/b3Clock.cpp",
"../Utils/b3Clock.h",
"../Utils/ChromeTraceUtil.cpp",
"../Utils/ChromeTraceUtil.h",
"*.h",
"GwenGUISupport/*.cpp",
"GwenGUISupport/*.h",

View File

@@ -36,6 +36,9 @@ static btScalar gBoxRestitution = 0; // set box restitution to 0
static btScalar gSphereFriction = 1; // set sphere friction to 1
static btScalar gSphereRollingFriction = 1; // set sphere rolling friction to 1
static btScalar gSphereSpinningFriction = 0.3; // set sphere spinning friction to 0.3
static btScalar gSphereRestitution = 0; // set sphere restitution to 0
@@ -149,6 +152,16 @@ void InclinedPlaneExample::initPhysics()
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;
@@ -240,6 +253,8 @@ void InclinedPlaneExample::initPhysics()
gSphere->setFriction(gSphereFriction);
gSphere->setRestitution(gSphereRestitution);
gSphere->setRollingFriction(gSphereRollingFriction);
gSphere->setSpinningFriction(gSphereSpinningFriction);
}
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);

View File

@@ -46,6 +46,7 @@ class btCollisionShape;
class ForkLiftDemo : public CommonExampleInterface
{
public:
GUIHelperInterface* m_guiHelper;
/* extra stuff*/
btVector3 m_cameraPosition;
@@ -57,7 +58,6 @@ class ForkLiftDemo : public CommonExampleInterface
btRigidBody* m_carChassis;
btRigidBody* localCreateRigidBody(btScalar mass, const btTransform& worldTransform, btCollisionShape* colSape);
GUIHelperInterface* m_guiHelper;
int m_wheelInstances[4];
//----------------------------
@@ -195,8 +195,6 @@ bool useMCLPSolver = true;
#include "ForkLiftDemo.h"
const int maxProxies = 32766;
const int maxOverlap = 65535;
///btRaycastVehicle is the interface for the constraint that implements the raycast vehicle
///notice that for higher-quality slow-moving vehicles, another approach might be better

View File

@@ -529,7 +529,7 @@ void btFractureDynamicsWorld::fractureCallback( )
{
int j=f0;
btCollisionObject* colOb = (btCollisionObject*)manifold->getBody1();
// btCollisionObject* colOb = (btCollisionObject*)manifold->getBody1();
// btRigidBody* otherOb = btRigidBody::upcast(colOb);
// if (!otherOb->getInvMass())
// continue;
@@ -562,8 +562,8 @@ void btFractureDynamicsWorld::fractureCallback( )
{
int j=f1;
{
btCollisionObject* colOb = (btCollisionObject*)manifold->getBody0();
btRigidBody* otherOb = btRigidBody::upcast(colOb);
//btCollisionObject* colOb = (btCollisionObject*)manifold->getBody0();
//btRigidBody* otherOb = btRigidBody::upcast(colOb);
// if (!otherOb->getInvMass())
// continue;

View File

@@ -30,7 +30,7 @@ int main(int argc, char** argv)
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
///btDbvtBroadphase is a good general purpose broadphase. You can also try out btAxis3Sweep.
btBroadphaseInterface* overlappingPairCache = new btDbvtBroadphase();
@@ -38,9 +38,9 @@ int main(int argc, char** argv)
///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,overlappingPairCache,solver,collisionConfiguration);
btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration);
dynamicsWorld->setGravity(btVector3(0,-10,0));
dynamicsWorld->setGravity(btVector3(0, -10, 0));
///-----initialization_end-----
@@ -48,39 +48,37 @@ int main(int argc, char** argv)
//make sure to re-use collision shapes among rigid bodies whenever possible!
btAlignedObjectArray<btCollisionShape*> collisionShapes;
///create a few basic rigid bodies
//the ground is a cube of side 100 at position y = -56.
//the sphere will hit it at y = -6, with center at -5
{
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.)));
collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0,-56,0));
groundTransform.setOrigin(btVector3(0, -56, 0));
btScalar mass(0.);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0,0,0);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
groundShape->calculateLocalInertia(mass,localInertia);
groundShape->calculateLocalInertia(mass, localInertia);
//using motionstate is optional, it provides interpolation capabilities, and only synchronizes 'active' objects
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
//add the body to the dynamics world
dynamicsWorld->addRigidBody(body);
}
{
//create a dynamic rigidbody
@@ -92,37 +90,34 @@ int main(int argc, char** argv)
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(2,10,0));
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,colShape,localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
startTransform.setOrigin(btVector3(2, 10, 0));
dynamicsWorld->addRigidBody(body);
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, colShape, localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
dynamicsWorld->addRigidBody(body);
}
/// Do some simulation
/// Do some simulation
///-----stepsimulation_start-----
for (i=0;i<150;i++)
for (i = 0; i < 150; i++)
{
dynamicsWorld->stepSimulation(1.f/60.f,10);
dynamicsWorld->stepSimulation(1.f / 60.f, 10);
//print positions of all objects
for (int j=dynamicsWorld->getNumCollisionObjects()-1; j>=0 ;j--)
for (int j = dynamicsWorld->getNumCollisionObjects() - 1; j >= 0; j--)
{
btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[j];
btRigidBody* body = btRigidBody::upcast(obj);
@@ -130,23 +125,23 @@ int main(int argc, char** argv)
if (body && body->getMotionState())
{
body->getMotionState()->getWorldTransform(trans);
} else
}
else
{
trans = obj->getWorldTransform();
}
printf("world pos object %d = %f,%f,%f\n",j,float(trans.getOrigin().getX()),float(trans.getOrigin().getY()),float(trans.getOrigin().getZ()));
printf("world pos object %d = %f,%f,%f\n", j, float(trans.getOrigin().getX()), float(trans.getOrigin().getY()), float(trans.getOrigin().getZ()));
}
}
///-----stepsimulation_end-----
//cleanup in the reverse order of creation/initialization
///-----cleanup_start-----
//remove the rigidbodies from the dynamics world and delete them
for (i=dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--)
for (i = dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
{
btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
@@ -154,12 +149,12 @@ int main(int argc, char** argv)
{
delete body->getMotionState();
}
dynamicsWorld->removeCollisionObject( obj );
dynamicsWorld->removeCollisionObject(obj);
delete obj;
}
//delete collision shapes
for (int j=0;j<collisionShapes.size();j++)
for (int j = 0; j < collisionShapes.size(); j++)
{
btCollisionShape* shape = collisionShapes[j];
collisionShapes[j] = 0;
@@ -183,4 +178,3 @@ int main(int argc, char** argv)
//next line is optional: it will be cleared by the destructor when the array goes out of scope
collisionShapes.clear();
}

View File

@@ -336,9 +336,7 @@ void readLibraryGeometries(TiXmlDocument& doc, btAlignedObjectArray<GLInstanceGr
void readNodeHierarchy(TiXmlElement* node,btHashMap<btHashString,int>& name2Shape, btAlignedObjectArray<ColladaGraphicsInstance>& visualShapeInstances, const btMatrix4x4& parentTransMat)
{
const char* nodeName = node->Attribute("id");
//printf("processing node %s\n", nodeName);
btMatrix4x4 nodeTrans;
nodeTrans.setIdentity();

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,84 @@
#ifndef BULLET_MJCF_IMPORTER_H
#define BULLET_MJCF_IMPORTER_H
#include "../ImportURDFDemo/URDFImporterInterface.h"
#include "../ImportURDFDemo/LinkVisualShapesConverter.h"
struct MJCFErrorLogger
{
virtual void reportError(const char* error)=0;
virtual void reportWarning(const char* warning)=0;
virtual void printMessage(const char* msg)=0;
};
class BulletMJCFImporter : public URDFImporterInterface
{
struct BulletMJCFImporterInternalData* m_data;
public:
BulletMJCFImporter(struct GUIHelperInterface* helper, LinkVisualShapesConverter* customConverter);
virtual ~BulletMJCFImporter();
virtual bool parseMJCFString(const char* xmlString, MJCFErrorLogger* logger);
virtual bool loadMJCF(const char* fileName, MJCFErrorLogger* logger, bool forceFixedBase = false);
virtual bool loadURDF(const char* fileName, bool forceFixedBase = false)
{
return false;
}
virtual bool loadSDF(const char* fileName, bool forceFixedBase = false) { return false;}
virtual const char* getPathPrefix();
///return >=0 for the root link index, -1 if there is no root link
virtual int getRootLinkIndex() const;
///pure virtual interfaces, precondition is a valid linkIndex (you can assert/terminate if the linkIndex is out of range)
virtual std::string getLinkName(int linkIndex) const;
virtual std::string getBodyName() const;
/// optional method to provide the link color. return true if the color is available and copied into colorRGBA, return false otherwise
virtual bool getLinkColor(int linkIndex, btVector4& colorRGBA) const;
//optional method to get collision group (type) and mask (affinity)
virtual int getCollisionGroupAndMask(int linkIndex, int& colGroup, int& colMask) const ;
///this API will likely change, don't override it!
virtual bool getLinkContactInfo(int linkIndex, URDFLinkContactInfo& contactInfo ) const;
virtual std::string getJointName(int linkIndex) const;
//fill mass and inertial data. If inertial data is missing, please initialize mass, inertia to sensitive values, and inertialFrame to identity.
virtual void getMassAndInertia(int urdfLinkIndex, btScalar& mass,btVector3& localInertiaDiagonal, btTransform& inertialFrame) const;
///fill an array of child link indices for this link, btAlignedObjectArray behaves like a std::vector so just use push_back and resize(0) if needed
virtual void getLinkChildIndices(int urdfLinkIndex, btAlignedObjectArray<int>& childLinkIndices) const;
virtual bool getJointInfo(int urdfLinkIndex, btTransform& parent2joint, btTransform& linkTransformInWorld, btVector3& jointAxisInJointSpace, int& jointType, btScalar& jointLowerLimit, btScalar& jointUpperLimit, btScalar& jointDamping, btScalar& jointFriction) const;
virtual bool getJointInfo2(int urdfLinkIndex, btTransform& parent2joint, btTransform& linkTransformInWorld, btVector3& jointAxisInJointSpace, int& jointType, btScalar& jointLowerLimit, btScalar& jointUpperLimit, btScalar& jointDamping, btScalar& jointFriction, btScalar& jointMaxForce, btScalar& jointMaxVelocity) const;
virtual bool getRootTransformInWorld(btTransform& rootTransformInWorld) const;
virtual int convertLinkVisualShapes(int linkIndex, const char* pathPrefix, const btTransform& inertialFrame) const;
virtual void convertLinkVisualShapes2(int linkIndex, int urdfIndex, const char* pathPrefix, const btTransform& inertialFrame, class btCollisionObject* colObj, int objectIndex) const;
virtual void setBodyUniqueId(int bodyId);
virtual int getBodyUniqueId() const;
virtual class btCompoundShape* convertLinkCollisionShapes(int linkIndex, const char* pathPrefix, const btTransform& localInertiaFrame) const ;
virtual int getNumAllocatedCollisionShapes() const;
virtual class btCollisionShape* getAllocatedCollisionShape(int index);
virtual int getNumModels() const;
virtual void activateModel(int modelIndex);
};
#endif //BULLET_MJCF_IMPORTER_H

View File

@@ -14,6 +14,8 @@
#include "../CommonInterfaces/CommonMultiBodyBase.h"
#include "../ImportURDFDemo/MyMultiBodyCreator.h"
#include "BulletMJCFImporter.h"
#include "../ImportURDFDemo/URDF2Bullet.h"
class ImportMJCFSetup : public CommonMultiBodyBase
{
@@ -49,6 +51,8 @@ static btAlignedObjectArray<std::string> gMCFJFileNameArray;
#define MAX_NUM_MOTORS 1024
struct ImportMJCFInternalData
{
ImportMJCFInternalData()
@@ -63,7 +67,7 @@ struct ImportMJCFInternalData
}
btScalar m_motorTargetVelocities[MAX_NUM_MOTORS];
btScalar m_motorTargetPositions[MAX_NUM_MOTORS];
btMultiBodyJointMotor* m_jointMotors [MAX_NUM_MOTORS];
btGeneric6DofSpring2Constraint* m_generic6DofJointMotors [MAX_NUM_MOTORS];
int m_numMotors;
@@ -75,19 +79,13 @@ struct ImportMJCFInternalData
ImportMJCFSetup::ImportMJCFSetup(struct GUIHelperInterface* helper, int option, const char* fileName)
:CommonMultiBodyBase(helper),
m_grav(0),
m_grav(-10),
m_upAxis(2)
{
m_data = new ImportMJCFInternalData;
if (option==1)
{
m_useMultiBody = true;
} else
{
m_useMultiBody = false;
}
m_useMultiBody = true;
static int count = 0;
if (fileName)
{
@@ -121,8 +119,26 @@ ImportMJCFSetup::ImportMJCFSetup(struct GUIHelperInterface* helper, int option,
if (gMCFJFileNameArray.size()==0)
{
gMCFJFileNameArray.push_back("quadruped/quadruped.mjcf");
gMCFJFileNameArray.push_back("MPL/MPL.xml");
gMCFJFileNameArray.push_back("mjcf/humanoid.xml");
gMCFJFileNameArray.push_back("mjcf/inverted_pendulum.xml");
gMCFJFileNameArray.push_back("mjcf/ant.xml");
gMCFJFileNameArray.push_back("mjcf/hello_mjcf.xml");
gMCFJFileNameArray.push_back("mjcf/cylinder.xml");
gMCFJFileNameArray.push_back("mjcf/cylinder_fromtoX.xml");
gMCFJFileNameArray.push_back("mjcf/cylinder_fromtoY.xml");
gMCFJFileNameArray.push_back("mjcf/cylinder_fromtoZ.xml");
gMCFJFileNameArray.push_back("mjcf/capsule.xml");
gMCFJFileNameArray.push_back("mjcf/capsule_fromtoX.xml");
gMCFJFileNameArray.push_back("mjcf/capsule_fromtoY.xml");
gMCFJFileNameArray.push_back("mjcf/capsule_fromtoZ.xml");
gMCFJFileNameArray.push_back("mjcf/hopper.xml");
gMCFJFileNameArray.push_back("mjcf/swimmer.xml");
gMCFJFileNameArray.push_back("mjcf/reacher.xml");
}
int numFileNames = gMCFJFileNameArray.size();
@@ -145,31 +161,29 @@ ImportMJCFSetup::~ImportMJCFSetup()
delete m_data;
}
static btVector4 colors[4] =
{
btVector4(1,0,0,1),
btVector4(0,1,0,1),
btVector4(0,1,1,1),
btVector4(1,1,0,1),
};
static btVector3 selectColor()
{
static int curColor = 0;
btVector4 color = colors[curColor];
curColor++;
curColor&=3;
return color;
}
void ImportMJCFSetup::setFileName(const char* mjcfFileName)
{
memcpy(m_fileName,mjcfFileName,strlen(mjcfFileName)+1);
}
struct MyMJCFLogger : public MJCFErrorLogger
{
virtual void reportError(const char* error)
{
b3Error(error);
}
virtual void reportWarning(const char* warning)
{
b3Warning(warning);
}
virtual void printMessage(const char* msg)
{
b3Printf(msg);
}
};
void ImportMJCFSetup::initPhysics()
@@ -178,14 +192,19 @@ void ImportMJCFSetup::initPhysics()
m_guiHelper->setUpAxis(m_upAxis);
this->createEmptyDynamicsWorld();
createEmptyDynamicsWorld();
//MuJoCo uses a slightly different collision filter mode, use the FILTER_GROUPAMASKB_OR_GROUPBMASKA2
//@todo also use the modified collision filter for raycast and other collision related queries
m_filterCallback->m_filterMode = FILTER_GROUPAMASKB_OR_GROUPBMASKA2;
//m_dynamicsWorld->getSolverInfo().m_numIterations = 100;
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
m_dynamicsWorld->getDebugDrawer()->setDebugMode(
btIDebugDraw::DBG_DrawConstraints
+btIDebugDraw::DBG_DrawContactPoints
+btIDebugDraw::DBG_DrawAabb
);//+btIDebugDraw::DBG_DrawConstraintLimits);
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
m_dynamicsWorld->getDebugDrawer()->setDebugMode(
btIDebugDraw::DBG_DrawConstraints
+btIDebugDraw::DBG_DrawContactPoints
+btIDebugDraw::DBG_DrawAabb
);//+btIDebugDraw::DBG_DrawConstraintLimits);
if (m_guiHelper->getParameterInterface())
@@ -195,8 +214,138 @@ void ImportMJCFSetup::initPhysics()
slider.m_maxVal = 10;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
BulletMJCFImporter importer(m_guiHelper, 0);
MyMJCFLogger logger;
bool result = importer.loadMJCF(m_fileName,&logger);
if (result)
{
btTransform rootTrans;
rootTrans.setIdentity();
for (int m =0; m<importer.getNumModels();m++)
{
importer.activateModel(m);
// normally used with PhysicsServerCommandProcessor that allocates unique ids to multibodies,
// emulate this behavior here:
importer.setBodyUniqueId(m);
btMultiBody* mb = 0;
//todo: move these internal API called inside the 'ConvertURDF2Bullet' call, hidden from the user
//int rootLinkIndex = importer.getRootLinkIndex();
//b3Printf("urdf root link index = %d\n",rootLinkIndex);
MyMultiBodyCreator creation(m_guiHelper);
rootTrans.setIdentity();
importer.getRootTransformInWorld(rootTrans);
ConvertURDF2Bullet(importer,creation, rootTrans,m_dynamicsWorld,m_useMultiBody,importer.getPathPrefix(),CUF_USE_MJCF);
mb = creation.getBulletMultiBody();
if (mb)
{
std::string* name =
new std::string(importer.getLinkName(
importer.getRootLinkIndex()));
m_nameMemory.push_back(name);
#ifdef TEST_MULTIBODY_SERIALIZATION
s->registerNameForPointer(name->c_str(),name->c_str());
#endif//TEST_MULTIBODY_SERIALIZATION
mb->setBaseName(name->c_str());
//create motors for each btMultiBody joint
int numLinks = mb->getNumLinks();
for (int i=0;i<numLinks;i++)
{
int mbLinkIndex = i;
int urdfLinkIndex = creation.m_mb2urdfLink[mbLinkIndex];
std::string* jointName = new std::string(importer.getJointName(urdfLinkIndex));
std::string* linkName = new std::string(importer.getLinkName(urdfLinkIndex).c_str());
#ifdef TEST_MULTIBODY_SERIALIZATION
s->registerNameForPointer(jointName->c_str(),jointName->c_str());
s->registerNameForPointer(linkName->c_str(),linkName->c_str());
#endif//TEST_MULTIBODY_SERIALIZATION
m_nameMemory.push_back(jointName);
m_nameMemory.push_back(linkName);
mb->getLink(i).m_linkName = linkName->c_str();
mb->getLink(i).m_jointName = jointName->c_str();
if (mb->getLink(mbLinkIndex).m_jointType==btMultibodyLink::eRevolute
||mb->getLink(mbLinkIndex).m_jointType==btMultibodyLink::ePrismatic
)
{
if (m_data->m_numMotors<MAX_NUM_MOTORS)
{
char motorName[1024];
sprintf(motorName,"%s q ", jointName->c_str());
btScalar* motorPos = &m_data->m_motorTargetPositions[m_data->m_numMotors];
*motorPos = 0.f;
SliderParams slider(motorName,motorPos);
slider.m_minVal=-4;
slider.m_maxVal=4;
slider.m_clampToIntegers = false;
slider.m_clampToNotches = false;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
float maxMotorImpulse = 5.f;
btMultiBodyJointMotor* motor = new btMultiBodyJointMotor(mb,mbLinkIndex,0,0,maxMotorImpulse);
motor->setErp(0.1);
//motor->setMaxAppliedImpulse(0);
m_data->m_jointMotors[m_data->m_numMotors]=motor;
m_dynamicsWorld->addMultiBodyConstraint(motor);
m_data->m_numMotors++;
}
}
}
} else
{
// not multibody
if (1)
{
//create motors for each generic joint
int num6Dof = creation.getNum6DofConstraints();
for (int i=0;i<num6Dof;i++)
{
btGeneric6DofSpring2Constraint* c = creation.get6DofConstraint(i);
if (c->getUserConstraintPtr())
{
GenericConstraintUserInfo* jointInfo = (GenericConstraintUserInfo*)c->getUserConstraintPtr();
if ((jointInfo->m_urdfJointType ==URDFRevoluteJoint) ||
(jointInfo->m_urdfJointType ==URDFPrismaticJoint) ||
(jointInfo->m_urdfJointType ==URDFContinuousJoint))
{
int urdfLinkIndex = jointInfo->m_urdfIndex;
std::string jointName = importer.getJointName(urdfLinkIndex);
char motorName[1024];
sprintf(motorName,"%s q'", jointName.c_str());
btScalar* motorVel = &m_data->m_motorTargetPositions[m_data->m_numMotors];
*motorVel = 0.f;
SliderParams slider(motorName,motorVel);
slider.m_minVal=-4;
slider.m_maxVal=4;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
m_data->m_generic6DofJointMotors[m_data->m_numMotors]=c;
bool motorOn = true;
c->enableMotor(jointInfo->m_jointAxisIndex,motorOn);
c->setMaxMotorForce(jointInfo->m_jointAxisIndex,10000);
c->setTargetVelocity(jointInfo->m_jointAxisIndex,0);
m_data->m_numMotors++;
}
}
}
}
}
}
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
}
@@ -206,7 +355,7 @@ void ImportMJCFSetup::stepSimulation(float deltaTime)
{
if (m_dynamicsWorld)
{
btVector3 gravity(0, 0, 0);
btVector3 gravity(0, 0, -10);
gravity[m_upAxis] = m_grav;
m_dynamicsWorld->setGravity(gravity);
@@ -214,13 +363,12 @@ void ImportMJCFSetup::stepSimulation(float deltaTime)
{
if (m_data->m_jointMotors[i])
{
m_data->m_jointMotors[i]->setVelocityTarget(m_data->m_motorTargetVelocities[i]);
m_data->m_jointMotors[i]->setPositionTarget(m_data->m_motorTargetPositions[i]);
}
if (m_data->m_generic6DofJointMotors[i])
{
GenericConstraintUserInfo* jointInfo = (GenericConstraintUserInfo*)m_data->m_generic6DofJointMotors[i]->getUserConstraintPtr();
m_data->m_generic6DofJointMotors[i]->setTargetVelocity(jointInfo->m_jointAxisIndex,m_data->m_motorTargetVelocities[i]);
//jointInfo->
m_data->m_generic6DofJointMotors[i]->setTargetVelocity(jointInfo->m_jointAxisIndex,m_data->m_motorTargetPositions[i]);
}
}

View File

@@ -7,11 +7,10 @@
#include "../../Utils/b3ResourcePath.h"
#include "Bullet3Common/b3FileUtils.h"
#include "../../ThirdPartyLibs/stb_image/stb_image.h"
#include "../ImportObjDemo/LoadMeshFromObj.h"
bool b3ImportMeshUtility::loadAndRegisterMeshFromFileInternal(const std::string& fileName, b3ImportMeshData& meshData)
{
B3_PROFILE("loadAndRegisterMeshFromFileInternal");
meshData.m_gfxShape = 0;
meshData.m_textureImage = 0;
meshData.m_textureHeight = 0;
@@ -27,11 +26,15 @@ bool b3ImportMeshUtility::loadAndRegisterMeshFromFileInternal(const std::string&
btVector3 shift(0,0,0);
std::vector<tinyobj::shape_t> shapes;
std::string err = tinyobj::LoadObj(shapes, relativeFileName, pathPrefix);
{
B3_PROFILE("tinyobj::LoadObj");
std::string err = LoadFromCachedOrFromObj(shapes, relativeFileName, pathPrefix);
//std::string err = tinyobj::LoadObj(shapes, relativeFileName, pathPrefix);
}
GLInstanceGraphicsShape* gfxShape = btgCreateGraphicsShapeFromWavefrontObj(shapes);
int textureIndex = -1;
//int textureIndex = -1;
//try to load some texture
for (int i=0;i<shapes.size();i++)
{

View File

@@ -1,17 +1,69 @@
#include "LoadMeshFromObj.h"
#include"../../ThirdPartyLibs/Wavefront/tiny_obj_loader.h"
#include "../../OpenGLWindow/GLInstanceGraphicsShape.h"
#include <stdio.h> //fopen
#include "Bullet3Common/b3AlignedObjectArray.h"
#include <string>
#include <vector>
#include "Wavefront2GLInstanceGraphicsShape.h"
#include "Bullet3Common/b3HashMap.h"
struct CachedObjResult
{
std::string m_msg;
std::vector<tinyobj::shape_t> m_shapes;
};
static b3HashMap<b3HashString, CachedObjResult> gCachedObjResults;
static int gEnableFileCaching = 1;
void b3EnableFileCaching(int enable)
{
gEnableFileCaching = enable;
if (enable==0)
{
gCachedObjResults.clear();
}
}
std::string LoadFromCachedOrFromObj(
std::vector<tinyobj::shape_t>& shapes, // [output]
const char* filename,
const char* mtl_basepath)
{
CachedObjResult* resultPtr = gCachedObjResults[filename];
if (resultPtr)
{
const CachedObjResult& result = *resultPtr;
shapes = result.m_shapes;
return result.m_msg;
}
std::string err = tinyobj::LoadObj(shapes, filename, mtl_basepath);
CachedObjResult result;
result.m_msg = err;
result.m_shapes = shapes;
if (gEnableFileCaching)
{
gCachedObjResults.insert(filename,result);
}
return err;
}
GLInstanceGraphicsShape* LoadMeshFromObj(const char* relativeFileName, const char* materialPrefixPath)
{
B3_PROFILE("LoadMeshFromObj");
std::vector<tinyobj::shape_t> shapes;
std::string err = tinyobj::LoadObj(shapes, relativeFileName, materialPrefixPath);
GLInstanceGraphicsShape* gfxShape = btgCreateGraphicsShapeFromWavefrontObj(shapes);
return gfxShape;
{
B3_PROFILE("tinyobj::LoadObj2");
std::string err = LoadFromCachedOrFromObj(shapes, relativeFileName, materialPrefixPath);
}
{
B3_PROFILE("btgCreateGraphicsShapeFromWavefrontObj");
GLInstanceGraphicsShape* gfxShape = btgCreateGraphicsShapeFromWavefrontObj(shapes);
return gfxShape;
}
}

View File

@@ -4,6 +4,14 @@
struct GLInstanceGraphicsShape;
#include"../../ThirdPartyLibs/Wavefront/tiny_obj_loader.h"
void b3EnableFileCaching(int enable);
std::string LoadFromCachedOrFromObj(
std::vector<tinyobj::shape_t>& shapes, // [output]
const char* filename,
const char* mtl_basepath);
GLInstanceGraphicsShape* LoadMeshFromObj(const char* relativeFileName, const char* materialPrefixPath);

View File

@@ -33,7 +33,7 @@ GLInstanceGraphicsShape* btgCreateGraphicsShapeFromWavefrontObj(std::vector<tiny
int vtxBaseIndex = vertices->size();
if (f<0 && f>=shape.mesh.indices.size())
if (f<0 && f>=int(shape.mesh.indices.size()))
{
continue;
}
@@ -49,7 +49,7 @@ GLInstanceGraphicsShape* btgCreateGraphicsShapeFromWavefrontObj(std::vector<tiny
{
int uv0Index = shape.mesh.indices[f]*2+0;
int uv1Index = shape.mesh.indices[f]*2+1;
if (uv0Index>=0 && uv1Index>=0 && (uv0Index < shape.mesh.texcoords.size()) && (uv1Index < shape.mesh.texcoords.size()))
if (uv0Index>=0 && uv1Index>=0 && (uv0Index < int(shape.mesh.texcoords.size()) && (uv1Index < shape.mesh.texcoords.size())))
{
vtx0.uv[0] = shape.mesh.texcoords[uv0Index];
vtx0.uv[1] = shape.mesh.texcoords[uv1Index];

View File

@@ -155,25 +155,8 @@ ImportSDFSetup::~ImportSDFSetup()
delete m_data;
}
static btVector4 colors[4] =
{
btVector4(1,0,0,1),
btVector4(0,1,0,1),
btVector4(0,1,1,1),
btVector4(1,1,0,1),
};
static btVector3 selectColor()
{
static int curColor = 0;
btVector4 color = colors[curColor];
curColor++;
curColor&=3;
return color;
}
void ImportSDFSetup::setFileName(const char* urdfFileName)
{
memcpy(m_fileName,urdfFileName,strlen(urdfFileName)+1);
@@ -227,7 +210,7 @@ void ImportSDFSetup::initPhysics()
//todo: move these internal API called inside the 'ConvertURDF2Bullet' call, hidden from the user
int rootLinkIndex = u2b.getRootLinkIndex();
//int rootLinkIndex = u2b.getRootLinkIndex();
//b3Printf("urdf root link index = %d\n",rootLinkIndex);
MyMultiBodyCreator creation(m_guiHelper);

View File

@@ -46,6 +46,7 @@ static GLInstanceGraphicsShape* LoadMeshFromSTL(const char* relativeFileName)
int expectedBinaryFileSize = numTriangles* 50 + 84;
if (expectedBinaryFileSize != size)
{
delete[] memoryBuffer;
return 0;
}
@@ -98,8 +99,11 @@ static GLInstanceGraphicsShape* LoadMeshFromSTL(const char* relativeFileName)
}
fclose(file);
}
shape->m_numIndices = shape->m_indices->size();
shape->m_numvertices = shape->m_vertices->size();
if (shape)
{
shape->m_numIndices = shape->m_indices->size();
shape->m_numvertices = shape->m_vertices->size();
}
return shape;
}

File diff suppressed because it is too large Load Diff

View File

@@ -34,24 +34,29 @@ public:
virtual int getRootLinkIndex() const;
virtual void getLinkChildIndices(int linkIndex, btAlignedObjectArray<int>& childLinkIndices) const;
virtual std::string getBodyName() const;
virtual std::string getLinkName(int linkIndex) const;
virtual bool getLinkColor(int linkIndex, btVector4& colorRGBA) const;
virtual bool getLinkContactInfo(int linkIndex, URDFLinkContactInfo& contactInfo ) const;
virtual bool getLinkContactInfo(int urdflinkIndex, URDFLinkContactInfo& contactInfo ) const;
virtual bool getLinkAudioSource(int linkIndex, SDFAudioSource& audioSource) const;
virtual std::string getJointName(int linkIndex) const;
virtual void getMassAndInertia(int linkIndex, btScalar& mass,btVector3& localInertiaDiagonal, btTransform& inertialFrame) const;
virtual bool getJointInfo(int urdfLinkIndex, btTransform& parent2joint, btTransform& linkTransformInWorld, btVector3& jointAxisInJointSpace, int& jointType, btScalar& jointLowerLimit, btScalar& jointUpperLimit, btScalar& jointDamping, btScalar& jointFriction) const;
virtual bool getJointInfo2(int urdfLinkIndex, btTransform& parent2joint, btTransform& linkTransformInWorld, btVector3& jointAxisInJointSpace, int& jointType, btScalar& jointLowerLimit, btScalar& jointUpperLimit, btScalar& jointDamping, btScalar& jointFriction, btScalar& jointMaxForce, btScalar& jointMaxVelocity) const;
virtual bool getRootTransformInWorld(btTransform& rootTransformInWorld) const;
virtual int convertLinkVisualShapes(int linkIndex, const char* pathPrefix, const btTransform& inertialFrame) const;
virtual void convertLinkVisualShapes2(int linkIndex, const char* pathPrefix, const btTransform& inertialFrame, class btCollisionObject* colObj, int bodyUniqueId) const;
virtual void convertLinkVisualShapes2(int linkIndex, int urdfIndex, const char* pathPrefix, const btTransform& inertialFrame, class btCollisionObject* colObj, int bodyUniqueId) const;
///todo(erwincoumans) refactor this convertLinkCollisionShapes/memory allocation

View File

@@ -89,7 +89,7 @@ struct ImportUrdfInternalData
ImportUrdfSetup::ImportUrdfSetup(struct GUIHelperInterface* helper, int option, const char* fileName)
:CommonMultiBodyBase(helper),
m_grav(0),
m_grav(-10),
m_upAxis(2)
{
m_data = new ImportUrdfInternalData;
@@ -135,7 +135,7 @@ ImportUrdfSetup::ImportUrdfSetup(struct GUIHelperInterface* helper, int option,
if (gFileNameArray.size()==0)
{
gFileNameArray.push_back("quadruped/quadruped.urdf");
gFileNameArray.push_back("r2d2.urdf");
}
@@ -159,25 +159,8 @@ ImportUrdfSetup::~ImportUrdfSetup()
delete m_data;
}
static btVector4 colors[4] =
{
btVector4(1,0,0,1),
btVector4(0,1,0,1),
btVector4(0,1,1,1),
btVector4(1,1,0,1),
};
static btVector3 selectColor()
{
static int curColor = 0;
btVector4 color = colors[curColor];
curColor++;
curColor&=3;
return color;
}
void ImportUrdfSetup::setFileName(const char* urdfFileName)
{
memcpy(m_fileName,urdfFileName,strlen(urdfFileName)+1);
@@ -237,7 +220,7 @@ void ImportUrdfSetup::initPhysics()
//todo: move these internal API called inside the 'ConvertURDF2Bullet' call, hidden from the user
int rootLinkIndex = u2b.getRootLinkIndex();
//int rootLinkIndex = u2b.getRootLinkIndex();
//b3Printf("urdf root link index = %d\n",rootLinkIndex);
MyMultiBodyCreator creation(m_guiHelper);

View File

@@ -1,9 +1,17 @@
#ifndef LINK_VISUAL_SHAPES_CONVERTER_H
#define LINK_VISUAL_SHAPES_CONVERTER_H
struct UrdfLink;
struct UrdfModel;
class btTransform;
class btCollisionObject;
struct LinkVisualShapesConverter
{
virtual void convertVisualShapes(int linkIndex, const char* pathPrefix, const class btTransform& localInertiaFrame, const struct UrdfModel& model, class btCollisionObject* colObj, int objectIndex)=0;
virtual void convertVisualShapes(int linkIndex, const char* pathPrefix, const btTransform& localInertiaFrame, const UrdfLink* linkPtr, const UrdfModel* model, class btCollisionObject* colShape, int objectIndex) =0;
virtual void removeVisualShape(class btCollisionObject* colObj)=0;
};
#endif //LINK_VISUAL_SHAPES_CONVERTER_H

View File

@@ -4,6 +4,7 @@
#include "MultiBodyCreationInterface.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "LinearMath/btHashMap.h"
struct GUIHelperInterface;
class btMultiBody;
@@ -28,7 +29,6 @@ protected:
struct GUIHelperInterface* m_guiHelper;
btAlignedObjectArray<btGeneric6DofSpring2Constraint*> m_6DofConstraints;
public:

View File

@@ -0,0 +1,46 @@
#ifndef SDF_AUDIO_TYPES_H
#define SDF_AUDIO_TYPES_H
#include <string>
///See audio_source element in http://sdformat.org/spec?ver=1.6&elem=link
struct SDFAudioSource
{
enum
{
SDFAudioSourceValid=1,
SDFAudioSourceLooping=2,
};
int m_flags; //repeat mode (0 = no repeat, 1 = loop forever)
std::string m_uri; //media filename of the sound, .wav file
double m_pitch; //1 = regular rate, -1 play in reverse
double m_gain; //normalized volume in range [0..1] where 0 is silent, 1 is most loud
double m_attackRate;
double m_decayRate;
double m_sustainLevel;
double m_releaseRate;
double m_collisionForceThreshold; //force that will trigger the audio, in Newton. If < 0, audio source is invalid
int m_userIndex;
SDFAudioSource()
: m_flags(0),
m_pitch(1),
m_gain(1),
m_attackRate(0.0001),
m_decayRate(0.00001),
m_sustainLevel(0.5),
m_releaseRate(0.0005),
m_collisionForceThreshold(0.5),
m_userIndex(-1)
{
}
};
#endif //SDF_AUDIO_TYPES_H

View File

@@ -11,8 +11,8 @@
#include "MultiBodyCreationInterface.h"
#include <string>
static int bodyCollisionFilterGroup=btBroadphaseProxy::CharacterFilter;
static int bodyCollisionFilterMask=btBroadphaseProxy::AllFilter&(~btBroadphaseProxy::CharacterFilter);
//static int bodyCollisionFilterGroup=btBroadphaseProxy::CharacterFilter;
//static int bodyCollisionFilterMask=btBroadphaseProxy::AllFilter&(~btBroadphaseProxy::CharacterFilter);
static bool enableConstraints = true;
static btVector4 colors[4] =
@@ -71,7 +71,7 @@ struct URDF2BulletCachedData
}
void registerMultiBody( int urdfLinkIndex, class btMultiBody* body, const btTransform& worldTransform, btScalar mass, const btVector3& localInertiaDiagonal, const class btCompoundShape* compound, const btTransform& localInertialFrame)
void registerMultiBody( int urdfLinkIndex, class btMultiBody* body, const btTransform& worldTransform, btScalar mass, const btVector3& localInertiaDiagonal, const class btCollisionShape* compound, const btTransform& localInertialFrame)
{
m_urdfLinkLocalInertialFrames[urdfLinkIndex] = localInertialFrame;
}
@@ -81,7 +81,7 @@ struct URDF2BulletCachedData
return m_urdfLink2rigidBodies[urdfLinkIndex];
}
void registerRigidBody( int urdfLinkIndex, class btRigidBody* body, const btTransform& worldTransform, btScalar mass, const btVector3& localInertiaDiagonal, const class btCompoundShape* compound, const btTransform& localInertialFrame)
void registerRigidBody( int urdfLinkIndex, class btRigidBody* body, const btTransform& worldTransform, btScalar mass, const btVector3& localInertiaDiagonal, const class btCollisionShape* compound, const btTransform& localInertialFrame)
{
btAssert(m_urdfLink2rigidBodies[urdfLinkIndex]==0);
@@ -166,6 +166,10 @@ void processContactParameters(const URDFLinkContactInfo& contactInfo, btCollisio
{
col->setContactStiffnessAndDamping(contactInfo.m_contactStiffness, contactInfo.m_contactDamping);
}
if ((contactInfo.m_flags & URDF_CONTACT_HAS_FRICTION_ANCHOR) != 0)
{
col->setCollisionFlags(col->getCollisionFlags() | btCollisionObject::CF_HAS_FRICTION_ANCHOR);
}
}
@@ -228,21 +232,36 @@ void ConvertURDF2BulletInternal(
btScalar jointUpperLimit;
btScalar jointDamping;
btScalar jointFriction;
btScalar jointMaxForce;
btScalar jointMaxVelocity;
bool hasParentJoint = u2b.getJointInfo(urdfLinkIndex, parent2joint, linkTransformInWorldSpace, jointAxisInJointSpace, jointType,jointLowerLimit,jointUpperLimit, jointDamping, jointFriction);
bool hasParentJoint = u2b.getJointInfo2(urdfLinkIndex, parent2joint, linkTransformInWorldSpace, jointAxisInJointSpace, jointType,jointLowerLimit,jointUpperLimit, jointDamping, jointFriction,jointMaxForce,jointMaxVelocity);
std::string linkName = u2b.getLinkName(urdfLinkIndex);
if (flags & CUF_USE_SDF)
{
parent2joint =parentTransformInWorldSpace.inverse()*linkTransformInWorldSpace;
}
else
{
linkTransformInWorldSpace =parentTransformInWorldSpace*parent2joint;
if (flags & CUF_USE_MJCF)
{
linkTransformInWorldSpace =parentTransformInWorldSpace*linkTransformInWorldSpace;
} else
{
linkTransformInWorldSpace =parentTransformInWorldSpace*parent2joint;
}
}
btCompoundShape* compoundShape = u2b.convertLinkCollisionShapes(urdfLinkIndex,pathPrefix,localInertialFrame);
btCompoundShape* tmpShape = u2b.convertLinkCollisionShapes(urdfLinkIndex,pathPrefix,localInertialFrame);
btCollisionShape* compoundShape = tmpShape;
if (tmpShape->getNumChildShapes() == 1 && tmpShape->getChildTransform(0)==btTransform::getIdentity())
{
compoundShape = tmpShape->getChildShape(0);
}
int graphicsIndex = u2b.convertLinkVisualShapes(urdfLinkIndex,pathPrefix,localInertialFrame);
@@ -266,6 +285,9 @@ void ConvertURDF2BulletInternal(
if (!(flags & CUF_USE_URDF_INERTIA))
{
compoundShape->calculateLocalInertia(mass, localInertiaDiagonal);
btAssert(localInertiaDiagonal[0] < 1e10);
btAssert(localInertiaDiagonal[1] < 1e10);
btAssert(localInertiaDiagonal[2] < 1e10);
}
URDFLinkContactInfo contactInfo;
u2b.getLinkContactInfo(urdfLinkIndex,contactInfo);
@@ -298,7 +320,7 @@ void ConvertURDF2BulletInternal(
//untested: u2b.convertLinkVisualShapes2(urdfLinkIndex,pathPrefix,localInertialFrame,body);
//untested: u2b.convertLinkVisualShapes2(linkIndex,urdfLinkIndex,pathPrefix,localInertialFrame,body);
} else
{
if (cache.m_bulletMultiBody==0)
@@ -308,7 +330,11 @@ void ConvertURDF2BulletInternal(
bool isFixedBase = (mass==0);//todo: figure out when base is fixed
int totalNumJoints = cache.m_totalNumJoints1;
cache.m_bulletMultiBody = creation.allocateMultiBody(urdfLinkIndex, totalNumJoints,mass, localInertiaDiagonal, isFixedBase, canSleep);
if (flags & CUF_USE_MJCF)
{
cache.m_bulletMultiBody->setBaseWorldTransform(linkTransformInWorldSpace);
}
cache.registerMultiBody(urdfLinkIndex, cache.m_bulletMultiBody, inertialFrameInWorldSpace, mass, localInertiaDiagonal, compoundShape, localInertialFrame);
}
@@ -323,10 +349,27 @@ void ConvertURDF2BulletInternal(
btQuaternion parentRotToThis = offsetInB.getRotation() * offsetInA.inverse().getRotation();
bool disableParentCollision = true;
if (createMultiBody && cache.m_bulletMultiBody)
{
cache.m_bulletMultiBody->getLink(mbLinkIndex).m_jointDamping = jointDamping;
cache.m_bulletMultiBody->getLink(mbLinkIndex).m_jointFriction = jointFriction;
cache.m_bulletMultiBody->getLink(mbLinkIndex).m_jointLowerLimit = jointLowerLimit;
cache.m_bulletMultiBody->getLink(mbLinkIndex).m_jointUpperLimit = jointUpperLimit;
cache.m_bulletMultiBody->getLink(mbLinkIndex).m_jointMaxForce = jointMaxForce;
cache.m_bulletMultiBody->getLink(mbLinkIndex).m_jointMaxVelocity = jointMaxVelocity;
}
switch (jointType)
{
case URDFFloatingJoint:
case URDFPlanarJoint:
case URDFFixedJoint:
{
if ((jointType==URDFFloatingJoint)||(jointType==URDFPlanarJoint))
{
printf("Warning: joint unsupported, creating a fixed joint instead.");
}
if (createMultiBody)
{
//todo: adjust the center of mass transform and pivot axis properly
@@ -353,8 +396,6 @@ void ConvertURDF2BulletInternal(
parentRotToThis, quatRotate(offsetInB.getRotation(),jointAxisInJointSpace), offsetInA.getOrigin(),//parent2joint.getOrigin(),
-offsetInB.getOrigin(),
disableParentCollision);
cache.m_bulletMultiBody->getLink(mbLinkIndex).m_jointDamping = jointDamping;
cache.m_bulletMultiBody->getLink(mbLinkIndex).m_jointFriction= jointFriction;
creation.addLinkMapping(urdfLinkIndex,mbLinkIndex);
if (jointType == URDFRevoluteJoint && jointLowerLimit <= jointUpperLimit) {
//std::string name = u2b.getLinkName(urdfLinkIndex);
@@ -434,16 +475,26 @@ void ConvertURDF2BulletInternal(
//base and fixed? -> static, otherwise flag as dynamic
bool isDynamic = (mbLinkIndex<0 && cache.m_bulletMultiBody->hasFixedBase())? false : true;
short collisionFilterGroup = isDynamic? short(btBroadphaseProxy::DefaultFilter) : short(btBroadphaseProxy::StaticFilter);
short collisionFilterMask = isDynamic? short(btBroadphaseProxy::AllFilter) : short(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
int collisionFilterGroup = isDynamic? int(btBroadphaseProxy::DefaultFilter) : int(btBroadphaseProxy::StaticFilter);
int collisionFilterMask = isDynamic? int(btBroadphaseProxy::AllFilter) : int(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
int colGroup=0, colMask=0;
int collisionFlags = u2b.getCollisionGroupAndMask(urdfLinkIndex,colGroup, colMask);
if (collisionFlags & URDF_HAS_COLLISION_GROUP)
{
collisionFilterGroup = colGroup;
}
if (collisionFlags & URDF_HAS_COLLISION_MASK)
{
collisionFilterMask = colMask;
}
world1->addCollisionObject(col,collisionFilterGroup,collisionFilterMask);
btVector4 color = selectColor2();//(0.0,0.0,0.5);
u2b.getLinkColor(urdfLinkIndex,color);
creation.createCollisionObjectGraphicsInstance(urdfLinkIndex,col,color);
u2b.convertLinkVisualShapes2(urdfLinkIndex,pathPrefix,localInertialFrame,col, u2b.getBodyUniqueId());
u2b.convertLinkVisualShapes2(mbLinkIndex, urdfLinkIndex, pathPrefix, localInertialFrame,col, u2b.getBodyUniqueId());
URDFLinkContactInfo contactInfo;
u2b.getLinkContactInfo(urdfLinkIndex,contactInfo);
@@ -453,6 +504,14 @@ void ConvertURDF2BulletInternal(
if (mbLinkIndex>=0) //???? double-check +/- 1
{
cache.m_bulletMultiBody->getLink(mbLinkIndex).m_collider=col;
if (flags&CUF_USE_SELF_COLLISION_EXCLUDE_PARENT)
{
cache.m_bulletMultiBody->getLink(mbLinkIndex).m_flags |= BT_MULTIBODYLINKFLAGS_DISABLE_PARENT_COLLISION;
}
if (flags&CUF_USE_SELF_COLLISION_EXCLUDE_ALL_PARENTS)
{
cache.m_bulletMultiBody->getLink(mbLinkIndex).m_flags |= BT_MULTIBODYLINKFLAGS_DISABLE_ALL_PARENT_COLLISION;
}
} else
{
cache.m_bulletMultiBody->setBaseCollider(col);
@@ -460,7 +519,7 @@ void ConvertURDF2BulletInternal(
}
} else
{
//u2b.convertLinkVisualShapes2(urdfLinkIndex,pathPrefix,localInertialFrame,compoundShape);
//u2b.convertLinkVisualShapes2(urdfLinkIndex,urdfIndex,pathPrefix,localInertialFrame,compoundShape);
}
}
@@ -494,12 +553,19 @@ void ConvertURDF2Bullet(
if (world1 && cache.m_bulletMultiBody)
{
btMultiBody* mb = cache.m_bulletMultiBody;
mb->setHasSelfCollision(false);
mb->setHasSelfCollision((flags&CUF_USE_SELF_COLLISION)!=0);
mb->finalizeMultiDof();
btTransform localInertialFrameRoot = cache.m_urdfLinkLocalInertialFrames[urdfLinkIndex];
mb->setBaseWorldTransform(rootTransformInWorldSpace*localInertialFrameRoot);
if (flags & CUF_USE_MJCF)
{
} else
{
mb->setBaseWorldTransform(rootTransformInWorldSpace*localInertialFrameRoot);
}
btAlignedObjectArray<btQuaternion> scratch_q;
btAlignedObjectArray<btVector3> scratch_m;
mb->forwardKinematics(scratch_q,scratch_m);

View File

@@ -17,7 +17,11 @@ class MultiBodyCreationInterface;
enum ConvertURDFFlags {
CUF_USE_SDF = 1,
// Use inertia values in URDF instead of recomputing them from collision shape.
CUF_USE_URDF_INERTIA = 2
CUF_USE_URDF_INERTIA = 2,
CUF_USE_MJCF = 4,
CUF_USE_SELF_COLLISION=8,
CUF_USE_SELF_COLLISION_EXCLUDE_PARENT=16,
CUF_USE_SELF_COLLISION_EXCLUDE_ALL_PARENTS=32,
};
void ConvertURDF2Bullet(const URDFImporterInterface& u2b,

View File

@@ -5,7 +5,7 @@
#include "LinearMath/btAlignedObjectArray.h"
#include "LinearMath/btTransform.h"
#include "URDFJointTypes.h"
#include "SDFAudioTypes.h"
class URDFImporterInterface
{
@@ -15,7 +15,6 @@ public:
virtual ~URDFImporterInterface() {}
virtual bool loadURDF(const char* fileName, bool forceFixedBase = false)=0;
virtual bool loadSDF(const char* fileName, bool forceFixedBase = false) { return false;}
@@ -27,12 +26,22 @@ public:
///pure virtual interfaces, precondition is a valid linkIndex (you can assert/terminate if the linkIndex is out of range)
virtual std::string getLinkName(int linkIndex) const =0;
//various derived class in internal source code break with new pure virtual methods, so provide some default implementation
virtual std::string getBodyName() const
{
return "";
}
/// optional method to provide the link color. return true if the color is available and copied into colorRGBA, return false otherwise
virtual bool getLinkColor(int linkIndex, btVector4& colorRGBA) const { return false;}
virtual int getCollisionGroupAndMask(int linkIndex, int& colGroup, int& colMask) const { return 0;}
///this API will likely change, don't override it!
virtual bool getLinkContactInfo(int linkIndex, URDFLinkContactInfo& contactInfo ) const { return false;}
virtual bool getLinkAudioSource(int linkIndex, SDFAudioSource& audioSource) const { return false;}
virtual std::string getJointName(int linkIndex) const = 0;
//fill mass and inertial data. If inertial data is missing, please initialize mass, inertia to sensitive values, and inertialFrame to identity.
@@ -42,17 +51,32 @@ public:
virtual void getLinkChildIndices(int urdfLinkIndex, btAlignedObjectArray<int>& childLinkIndices) const =0;
virtual bool getJointInfo(int urdfLinkIndex, btTransform& parent2joint, btTransform& linkTransformInWorld, btVector3& jointAxisInJointSpace, int& jointType, btScalar& jointLowerLimit, btScalar& jointUpperLimit, btScalar& jointDamping, btScalar& jointFriction) const =0;
virtual bool getJointInfo2(int urdfLinkIndex, btTransform& parent2joint, btTransform& linkTransformInWorld, btVector3& jointAxisInJointSpace, int& jointType, btScalar& jointLowerLimit, btScalar& jointUpperLimit, btScalar& jointDamping, btScalar& jointFriction, btScalar& jointMaxForce, btScalar& jointMaxVelocity) const
{
//backwards compatibility for custom file importers
jointMaxForce = 0;
jointMaxVelocity = 0;
return getJointInfo(urdfLinkIndex, parent2joint, linkTransformInWorld, jointAxisInJointSpace, jointType, jointLowerLimit, jointUpperLimit, jointDamping, jointFriction);
};
virtual bool getRootTransformInWorld(btTransform& rootTransformInWorld) const =0;
///quick hack: need to rethink the API/dependencies of this
virtual int convertLinkVisualShapes(int linkIndex, const char* pathPrefix, const btTransform& inertialFrame) const { return -1;}
virtual void convertLinkVisualShapes2(int linkIndex, const char* pathPrefix, const btTransform& inertialFrame, class btCollisionObject* colObj, int objectIndex) const { }
virtual void convertLinkVisualShapes2(int linkIndex, int urdfIndex, const char* pathPrefix, const btTransform& inertialFrame, class btCollisionObject* colObj, int objectIndex) const { }
virtual void setBodyUniqueId(int bodyId) {}
virtual int getBodyUniqueId() const { return 0;}
//default implementation for backward compatibility
virtual class btCompoundShape* convertLinkCollisionShapes(int linkIndex, const char* pathPrefix, const btTransform& localInertiaFrame) const = 0;
virtual int getNumAllocatedCollisionShapes() const { return 0;}
virtual class btCollisionShape* getAllocatedCollisionShape(int /*index*/ ) {return 0;}
virtual int getNumModels() const {return 0;}
virtual void activateModel(int /*modelIndex*/) { }
};
#endif //URDF_IMPORTER_INTERFACE_H

View File

@@ -23,7 +23,8 @@ enum URDF_LinkContactFlags
URDF_CONTACT_HAS_ROLLING_FRICTION=32,
URDF_CONTACT_HAS_SPINNING_FRICTION=64,
URDF_CONTACT_HAS_RESTITUTION=128,
URDF_CONTACT_HAS_FRICTION_ANCHOR=256,
};
struct URDFLinkContactInfo
@@ -55,5 +56,11 @@ struct URDFLinkContactInfo
}
};
enum UrdfCollisionFlags
{
URDF_FORCE_CONCAVE_TRIMESH=1,
URDF_HAS_COLLISION_GROUP=2,
URDF_HAS_COLLISION_MASK=4,
};
#endif //URDF_JOINT_TYPES_H

View File

@@ -8,52 +8,15 @@ UrdfParser::UrdfParser()
:m_parseSDF(false),
m_activeSdfModel(-1)
{
m_urdf2Model.m_sourceFile = "IN_MEMORY_STRING"; // if loadUrdf() called later, source file name will be replaced with real
}
UrdfParser::~UrdfParser()
{
cleanModel(&m_urdf2Model);
for (int i=0;i<m_tmpModels.size();i++)
{
cleanModel(m_tmpModels[i]);
}
m_sdfModels.clear();
m_tmpModels.clear();
}
void UrdfParser::cleanModel(UrdfModel* model)
{
for (int i=0;i<model->m_materials.size();i++)
{
UrdfMaterial** matPtr = model->m_materials.getAtIndex(i);
if (matPtr)
{
UrdfMaterial* mat = *matPtr;
delete mat;
}
}
for (int i=0;i<model->m_links.size();i++)
{
UrdfLink** linkPtr = model->m_links.getAtIndex(i);
if (linkPtr)
{
UrdfLink* link = *linkPtr;
delete link;
}
}
for (int i=0;i<model->m_joints.size();i++)
{
UrdfJoint** jointPtr = model->m_joints.getAtIndex(i);
if (jointPtr)
{
UrdfJoint* joint = *jointPtr;
delete joint;
}
}
for (int i=0;i<m_tmpModels.size();i++)
{
delete m_tmpModels[i];
}
}
static bool parseVector4(btVector4& vec4, const std::string& vector_str)
@@ -294,8 +257,19 @@ bool UrdfParser::parseInertia(UrdfInertia& inertia, TiXmlElement* config, ErrorL
inertia.m_izz = urdfLexicalCast<double>(izz->GetText());
} else
{
logger->reportError("Inertial: inertia element must have ixx,ixy,ixz,iyy,iyz,izz child elements");
return false;
if (ixx && iyy && izz)
{
inertia.m_ixx = urdfLexicalCast<double>(ixx->GetText());
inertia.m_ixy = 0;
inertia.m_ixz = 0;
inertia.m_iyy = urdfLexicalCast<double>(iyy->GetText());
inertia.m_iyz = 0;
inertia.m_izz = urdfLexicalCast<double>(izz->GetText());
} else
{
logger->reportError("Inertial: inertia element must have ixx,ixy,ixz,iyy,iyz,izz child elements");
return false;
}
}
} else
{
@@ -303,15 +277,29 @@ bool UrdfParser::parseInertia(UrdfInertia& inertia, TiXmlElement* config, ErrorL
inertia_xml->Attribute("iyy") && inertia_xml->Attribute("iyz") &&
inertia_xml->Attribute("izz")))
{
logger->reportError("Inertial: inertia element must have ixx,ixy,ixz,iyy,iyz,izz attributes");
return false;
}
inertia.m_ixx = urdfLexicalCast<double>(inertia_xml->Attribute("ixx"));
inertia.m_ixy = urdfLexicalCast<double>(inertia_xml->Attribute("ixy"));
inertia.m_ixz = urdfLexicalCast<double>(inertia_xml->Attribute("ixz"));
inertia.m_iyy = urdfLexicalCast<double>(inertia_xml->Attribute("iyy"));
inertia.m_iyz = urdfLexicalCast<double>(inertia_xml->Attribute("iyz"));
inertia.m_izz = urdfLexicalCast<double>(inertia_xml->Attribute("izz"));
if ((inertia_xml->Attribute("ixx") && inertia_xml->Attribute("iyy") &&
inertia_xml->Attribute("izz")))
{
inertia.m_ixx = urdfLexicalCast<double>(inertia_xml->Attribute("ixx"));
inertia.m_ixy = 0;
inertia.m_ixz = 0;
inertia.m_iyy = urdfLexicalCast<double>(inertia_xml->Attribute("iyy"));
inertia.m_iyz = 0;
inertia.m_izz = urdfLexicalCast<double>(inertia_xml->Attribute("izz"));
} else
{
logger->reportError("Inertial: inertia element must have ixx,ixy,ixz,iyy,iyz,izz attributes");
return false;
}
} else
{
inertia.m_ixx = urdfLexicalCast<double>(inertia_xml->Attribute("ixx"));
inertia.m_ixy = urdfLexicalCast<double>(inertia_xml->Attribute("ixy"));
inertia.m_ixz = urdfLexicalCast<double>(inertia_xml->Attribute("ixz"));
inertia.m_iyy = urdfLexicalCast<double>(inertia_xml->Attribute("iyy"));
inertia.m_iyz = urdfLexicalCast<double>(inertia_xml->Attribute("iyz"));
inertia.m_izz = urdfLexicalCast<double>(inertia_xml->Attribute("izz"));
}
}
return true;
@@ -375,55 +363,78 @@ bool UrdfParser::parseGeometry(UrdfGeometry& geom, TiXmlElement* g, ErrorLogger*
logger->reportError("Cylinder shape must have both length and radius attributes");
return false;
}
geom.m_cylinderRadius = urdfLexicalCast<double>(shape->Attribute("radius"));
geom.m_cylinderLength = urdfLexicalCast<double>(shape->Attribute("length"));
geom.m_hasFromTo = false;
geom.m_capsuleRadius = urdfLexicalCast<double>(shape->Attribute("radius"));
geom.m_capsuleHeight = urdfLexicalCast<double>(shape->Attribute("length"));
}
else if (type_name == "mesh")
{
geom.m_type = URDF_GEOM_MESH;
if (m_parseSDF)
{
TiXmlElement* scale = shape->FirstChildElement("scale");
if (0==scale)
{
geom.m_meshScale.setValue(1,1,1);
}
else
{
parseVector3(geom.m_meshScale,scale->GetText(),logger);
}
TiXmlElement* filename = shape->FirstChildElement("uri");
geom.m_meshFileName = filename->GetText();
}
else
{
if (!shape->Attribute("filename")) {
logger->reportError("Mesh must contain a filename attribute");
return false;
}
geom.m_meshFileName = shape->Attribute("filename");
geom.m_meshScale.setValue(1,1,1);
else if (type_name == "capsule")
{
geom.m_type = URDF_GEOM_CAPSULE;
if (!shape->Attribute("length") ||
!shape->Attribute("radius"))
{
logger->reportError("Capsule shape must have both length and radius attributes");
return false;
}
geom.m_hasFromTo = false;
geom.m_capsuleRadius = urdfLexicalCast<double>(shape->Attribute("radius"));
geom.m_capsuleHeight = urdfLexicalCast<double>(shape->Attribute("length"));
}
else if (type_name == "mesh")
{
geom.m_type = URDF_GEOM_MESH;
geom.m_meshScale.setValue(1,1,1);
std::string fn;
if (shape->Attribute("scale"))
{
if (!parseVector3(geom.m_meshScale,shape->Attribute("scale"),logger))
{
logger->reportWarning("scale should be a vector3, not single scalar. Workaround activated.\n");
std::string scalar_str = shape->Attribute("scale");
double scaleFactor = urdfLexicalCast<double>(scalar_str.c_str());
if (scaleFactor)
{
geom.m_meshScale.setValue(scaleFactor,scaleFactor,scaleFactor);
}
}
} else
{
}
}
if (m_parseSDF)
{
if (TiXmlElement* scale = shape->FirstChildElement("scale"))
{
parseVector3(geom.m_meshScale,scale->GetText(),logger);
}
if (TiXmlElement* filename = shape->FirstChildElement("uri"))
{
fn = filename->GetText();
}
}
else
{
// URDF
if (shape->Attribute("filename"))
{
fn = shape->Attribute("filename");
}
if (shape->Attribute("scale"))
{
if (!parseVector3(geom.m_meshScale, shape->Attribute("scale"), logger))
{
logger->reportWarning("Scale should be a vector3, not single scalar. Workaround activated.\n");
std::string scalar_str = shape->Attribute("scale");
double scaleFactor = urdfLexicalCast<double>(scalar_str.c_str());
if (scaleFactor)
{
geom.m_meshScale.setValue(scaleFactor, scaleFactor, scaleFactor);
}
}
}
}
if (fn.empty())
{
logger->reportError("Mesh filename is empty");
return false;
}
geom.m_meshFileName = fn;
bool success = findExistingMeshFile(
m_urdf2Model.m_sourceFile, fn, sourceFileLocation(shape),
&geom.m_meshFileName, &geom.m_meshFileType);
if (!success)
{
// warning already printed
return false;
}
}
else
{
@@ -527,7 +538,7 @@ bool UrdfParser::parseVisual(UrdfModel& model, UrdfVisual& visual, TiXmlElement*
if (name_char)
visual.m_name = name_char;
visual.m_hasLocalMaterial = false;
visual.m_geometry.m_hasLocalMaterial = false;
// Material
TiXmlElement *mat = config->FirstChildElement("material");
@@ -540,15 +551,16 @@ bool UrdfParser::parseVisual(UrdfModel& model, UrdfVisual& visual, TiXmlElement*
matPtr->m_name = "mat";
if (name_char)
matPtr->m_name = name_char;
model.m_materials.insert(matPtr->m_name.c_str(),matPtr);
TiXmlElement *diffuse = mat->FirstChildElement("diffuse");
if (diffuse) {
std::string diffuseText = diffuse->GetText();
btVector4 rgba(1,0,0,1);
parseVector4(rgba,diffuseText);
matPtr->m_rgbaColor = rgba;
model.m_materials.insert(matPtr->m_name.c_str(),matPtr);
visual.m_materialName = matPtr->m_name;
visual.m_hasLocalMaterial = true;
visual.m_geometry.m_hasLocalMaterial = true;
}
}
else
@@ -567,11 +579,20 @@ bool UrdfParser::parseVisual(UrdfModel& model, UrdfVisual& visual, TiXmlElement*
TiXmlElement *c = mat->FirstChildElement("color");
if (t||c)
{
if (parseMaterial(visual.m_localMaterial, mat,logger))
if (parseMaterial(visual.m_geometry.m_localMaterial, mat,logger))
{
UrdfMaterial* matPtr = new UrdfMaterial(visual.m_localMaterial);
UrdfMaterial* matPtr = new UrdfMaterial(visual.m_geometry.m_localMaterial);
UrdfMaterial** oldMatPtrPtr = model.m_materials[matPtr->m_name.c_str()];
if (oldMatPtrPtr)
{
UrdfMaterial* oldMatPtr = *oldMatPtrPtr;
model.m_materials.remove(matPtr->m_name.c_str());
if (oldMatPtr)
delete oldMatPtr;
}
model.m_materials.insert(matPtr->m_name.c_str(),matPtr);
visual.m_hasLocalMaterial = true;
visual.m_geometry.m_hasLocalMaterial = true;
}
}
}
@@ -604,6 +625,82 @@ bool UrdfParser::parseLink(UrdfModel& model, UrdfLink& link, TiXmlElement *confi
}
}
{
//optional 'audio_source' parameters
//modified version of SDF audio_source specification in //http://sdformat.org/spec?ver=1.6&elem=link
#if 0
<audio_source>
<uri>file://media/audio/cheer.mp3</uri>
<pitch>2.0</pitch>
<gain>1.0</gain>
<loop>false</loop>
<contact>
<collision>collision</collision>
</contact>
</audio_source>
#endif
TiXmlElement* ci = config->FirstChildElement("audio_source");
if (ci)
{
link.m_audioSource.m_flags |= SDFAudioSource::SDFAudioSourceValid;
const char* fn = ci->Attribute("filename");
if (fn)
{
link.m_audioSource.m_uri = fn;
} else
{
if (TiXmlElement* filename_xml = ci->FirstChildElement("uri"))
{
link.m_audioSource.m_uri = filename_xml->GetText();
}
}
if (TiXmlElement* pitch_xml = ci->FirstChildElement("pitch"))
{
link.m_audioSource.m_pitch = urdfLexicalCast<double>(pitch_xml->GetText());
}
if (TiXmlElement* gain_xml = ci->FirstChildElement("gain"))
{
link.m_audioSource.m_gain = urdfLexicalCast<double>(gain_xml->GetText());
}
if (TiXmlElement* attack_rate_xml = ci->FirstChildElement("attack_rate"))
{
link.m_audioSource.m_attackRate = urdfLexicalCast<double>(attack_rate_xml->GetText());
}
if (TiXmlElement* decay_rate_xml = ci->FirstChildElement("decay_rate"))
{
link.m_audioSource.m_decayRate = urdfLexicalCast<double>(decay_rate_xml->GetText());
}
if (TiXmlElement* sustain_level_xml = ci->FirstChildElement("sustain_level"))
{
link.m_audioSource.m_sustainLevel = urdfLexicalCast<double>(sustain_level_xml->GetText());
}
if (TiXmlElement* release_rate_xml = ci->FirstChildElement("release_rate"))
{
link.m_audioSource.m_releaseRate = urdfLexicalCast<double>(release_rate_xml->GetText());
}
if (TiXmlElement* loop_xml = ci->FirstChildElement("loop"))
{
std::string looptxt = loop_xml->GetText();
if (looptxt == "true")
{
link.m_audioSource.m_flags |= SDFAudioSource::SDFAudioSourceLooping;
}
}
if (TiXmlElement* forceThreshold_xml = ci->FirstChildElement("collision_force_threshold"))
{
link.m_audioSource.m_collisionForceThreshold= urdfLexicalCast<double>(forceThreshold_xml->GetText());
}
//todo: see other audio_source children
//pitch, gain, loop, contact
}
}
{
//optional 'contact' parameters
TiXmlElement* ci = config->FirstChildElement("contact");
@@ -718,6 +815,13 @@ bool UrdfParser::parseLink(UrdfModel& model, UrdfLink& link, TiXmlElement *confi
}
}
}
{
TiXmlElement *friction_anchor = ci->FirstChildElement("friction_anchor");
if (friction_anchor)
{
link.m_contactInfo.m_flags |= URDF_CONTACT_HAS_FRICTION_ANCHOR;
}
}
{
@@ -805,7 +909,8 @@ bool UrdfParser::parseLink(UrdfModel& model, UrdfLink& link, TiXmlElement *confi
for (TiXmlElement* vis_xml = config->FirstChildElement("visual"); vis_xml; vis_xml = vis_xml->NextSiblingElement("visual"))
{
UrdfVisual visual;
visual.m_sourceFileLocation = sourceFileLocation(vis_xml);
if (parseVisual(model, visual, vis_xml,logger))
{
link.m_visualArray.push_back(visual);
@@ -824,6 +929,8 @@ bool UrdfParser::parseLink(UrdfModel& model, UrdfLink& link, TiXmlElement *confi
for (TiXmlElement* col_xml = config->FirstChildElement("collision"); col_xml; col_xml = col_xml->NextSiblingElement("collision"))
{
UrdfCollision col;
col.m_sourceFileLocation = sourceFileLocation(col_xml);
if (parseCollision(col, col_xml,logger))
{
link.m_collisionArray.push_back(col);
@@ -1326,6 +1433,7 @@ bool UrdfParser::loadUrdf(const char* urdfText, ErrorLogger* logger, bool forceF
UrdfMaterial** mat =m_urdf2Model.m_materials.find(material->m_name.c_str());
if (mat)
{
delete material;
logger->reportWarning("Duplicate material");
} else
{
@@ -1349,6 +1457,7 @@ bool UrdfParser::loadUrdf(const char* urdfText, ErrorLogger* logger, bool forceF
{
logger->reportError("Link name is not unique, link names in the same model have to be unique");
logger->reportError(link->m_name.c_str());
delete link;
return false;
} else
{
@@ -1356,12 +1465,12 @@ bool UrdfParser::loadUrdf(const char* urdfText, ErrorLogger* logger, bool forceF
for (int i=0;i<link->m_visualArray.size();i++)
{
UrdfVisual& vis = link->m_visualArray.at(i);
if (!vis.m_hasLocalMaterial && vis.m_materialName.c_str())
if (!vis.m_geometry.m_hasLocalMaterial && vis.m_materialName.c_str())
{
UrdfMaterial** mat = m_urdf2Model.m_materials.find(vis.m_materialName.c_str());
if (mat && *mat)
{
vis.m_localMaterial = **mat;
vis.m_geometry.m_localMaterial = **mat;
} else
{
//logger->reportError("Cannot find material with name:");
@@ -1397,6 +1506,7 @@ bool UrdfParser::loadUrdf(const char* urdfText, ErrorLogger* logger, bool forceF
{
logger->reportError("joint '%s' is not unique.");
logger->reportError(joint->m_name.c_str());
delete joint;
return false;
}
else
@@ -1407,6 +1517,7 @@ bool UrdfParser::loadUrdf(const char* urdfText, ErrorLogger* logger, bool forceF
else
{
logger->reportError("joint xml is not initialized correctly");
delete joint;
return false;
}
}
@@ -1521,7 +1632,8 @@ bool UrdfParser::loadSDF(const char* sdfText, ErrorLogger* logger)
UrdfMaterial** mat =localModel->m_materials.find(material->m_name.c_str());
if (mat)
{
logger->reportWarning("Duplicate material");
logger->reportWarning("Duplicate material");
delete material;
} else
{
localModel->m_materials.insert(material->m_name.c_str(),material);
@@ -1544,6 +1656,7 @@ bool UrdfParser::loadSDF(const char* sdfText, ErrorLogger* logger)
{
logger->reportError("Link name is not unique, link names in the same model have to be unique");
logger->reportError(link->m_name.c_str());
delete link;
return false;
} else
{
@@ -1551,12 +1664,12 @@ bool UrdfParser::loadSDF(const char* sdfText, ErrorLogger* logger)
for (int i=0;i<link->m_visualArray.size();i++)
{
UrdfVisual& vis = link->m_visualArray.at(i);
if (!vis.m_hasLocalMaterial && vis.m_materialName.c_str())
if (!vis.m_geometry.m_hasLocalMaterial && vis.m_materialName.c_str())
{
UrdfMaterial** mat = localModel->m_materials.find(vis.m_materialName.c_str());
if (mat && *mat)
{
vis.m_localMaterial = **mat;
vis.m_geometry.m_localMaterial = **mat;
} else
{
//logger->reportError("Cannot find material with name:");
@@ -1592,6 +1705,7 @@ bool UrdfParser::loadSDF(const char* sdfText, ErrorLogger* logger)
{
logger->reportError("joint '%s' is not unique.");
logger->reportError(joint->m_name.c_str());
delete joint;
return false;
}
else
@@ -1602,6 +1716,7 @@ bool UrdfParser::loadSDF(const char* sdfText, ErrorLogger* logger)
else
{
logger->reportError("joint xml is not initialized correctly");
delete joint;
return false;
}
}
@@ -1617,3 +1732,19 @@ bool UrdfParser::loadSDF(const char* sdfText, ErrorLogger* logger)
return true;
}
std::string UrdfParser::sourceFileLocation(TiXmlElement* e)
{
#if 0
//no C++11 etc, no snprintf
char buf[1024];
snprintf(buf, sizeof(buf), "%s:%i", m_urdf2Model.m_sourceFile.c_str(), e->Row());
return buf;
#else
char row[1024];
sprintf(row,"%d",e->Row());
std::string str = m_urdf2Model.m_sourceFile.c_str() + std::string(":") + std::string(row);
return str;
#endif
}

View File

@@ -5,6 +5,7 @@
#include "LinearMath/btAlignedObjectArray.h"
#include "LinearMath/btHashMap.h"
#include "URDFJointTypes.h"
#include "SDFAudioTypes.h"
#define btArray btAlignedObjectArray
#include <string>
@@ -18,19 +19,26 @@ struct ErrorLogger
struct UrdfMaterial
{
std::string m_name;
std::string m_name;
std::string m_textureFilename;
btVector4 m_rgbaColor;
btVector4 m_rgbaColor; // [0]==r [1]==g [2]==b [3]==a
UrdfMaterial():
m_rgbaColor(0.8, 0.8, 0.8, 1)
{
}
};
struct UrdfInertia
{
btTransform m_linkLocalFrame;
bool m_hasLinkLocalFrame;
double m_mass;
double m_ixx,m_ixy,m_ixz,m_iyy,m_iyz,m_izz;
UrdfInertia()
{
m_hasLinkLocalFrame = false;
m_linkLocalFrame.setIdentity();
m_mass = 0.f;
m_ixx=m_ixy=m_ixz=m_iyy=m_iyz=m_izz=0.f;
@@ -43,8 +51,9 @@ enum UrdfGeomTypes
URDF_GEOM_BOX,
URDF_GEOM_CYLINDER,
URDF_GEOM_MESH,
URDF_GEOM_PLANE,
URDF_GEOM_PLANE,
URDF_GEOM_CAPSULE, //non-standard URDF?
URDF_GEOM_UNKNOWN,
};
@@ -56,37 +65,66 @@ struct UrdfGeometry
btVector3 m_boxSize;
double m_cylinderRadius;
double m_cylinderLength;
double m_capsuleRadius;
double m_capsuleHeight;
int m_hasFromTo;
btVector3 m_capsuleFrom;
btVector3 m_capsuleTo;
btVector3 m_planeNormal;
btVector3 m_planeNormal;
enum {
FILE_STL =1,
FILE_COLLADA =2,
FILE_OBJ =3,
};
int m_meshFileType;
std::string m_meshFileName;
btVector3 m_meshScale;
};
btVector3 m_meshScale;
struct UrdfVisual
{
btTransform m_linkLocalFrame;
UrdfGeometry m_geometry;
std::string m_name;
std::string m_materialName;
bool m_hasLocalMaterial;
UrdfMaterial m_localMaterial;
bool m_hasLocalMaterial;
UrdfGeometry()
:m_type(URDF_GEOM_UNKNOWN),
m_sphereRadius(1),
m_boxSize(1,1,1),
m_capsuleRadius(1),
m_capsuleHeight(1),
m_hasFromTo(0),
m_capsuleFrom(0,1,0),
m_capsuleTo(1,0,0),
m_planeNormal(0,0,1),
m_meshFileType(0),
m_meshScale(1,1,1),
m_hasLocalMaterial(false)
{
}
};
enum UrdfCollisionFlags
{
URDF_FORCE_CONCAVE_TRIMESH=1,
};
bool findExistingMeshFile(const std::string& urdf_path, std::string fn,
const std::string& error_message_prefix,
std::string* out_found_filename, int* out_type); // intended to fill UrdfGeometry::m_meshFileName and Type, but can be used elsewhere
struct UrdfCollision
struct UrdfShape
{
std::string m_sourceFileLocation;
btTransform m_linkLocalFrame;
UrdfGeometry m_geometry;
std::string m_name;
};
struct UrdfVisual: UrdfShape
{
std::string m_materialName;
};
struct UrdfCollision: UrdfShape
{
int m_flags;
int m_collisionGroup;
int m_collisionMask;
UrdfCollision()
:m_flags(0)
{
@@ -112,6 +150,8 @@ struct UrdfLink
URDFLinkContactInfo m_contactInfo;
SDFAudioSource m_audioSource;
UrdfLink()
:m_parentLink(0),
m_parentJoint(0)
@@ -150,6 +190,7 @@ struct UrdfJoint
struct UrdfModel
{
std::string m_name;
std::string m_sourceFile;
btTransform m_rootTransformInWorld;
btHashMap<btHashString, UrdfMaterial*> m_materials;
btHashMap<btHashString, UrdfLink*> m_links;
@@ -163,7 +204,37 @@ struct UrdfModel
{
m_rootTransformInWorld.setIdentity();
}
~UrdfModel()
{
for (int i = 0; i < m_materials.size(); i++)
{
UrdfMaterial** ptr = m_materials.getAtIndex(i);
if (ptr)
{
UrdfMaterial* t = *ptr;
delete t;
}
}
for (int i = 0; i < m_links.size(); i++)
{
UrdfLink** ptr = m_links.getAtIndex(i);
if (ptr)
{
UrdfLink* t = *ptr;
delete t;
}
}
for (int i = 0; i < m_joints.size(); i++)
{
UrdfJoint** ptr = m_joints.getAtIndex(i);
if (ptr)
{
UrdfJoint* t = *ptr;
delete t;
}
}
}
};
class UrdfParser
@@ -178,7 +249,6 @@ protected:
int m_activeSdfModel;
void cleanModel(UrdfModel* model);
bool parseInertia(UrdfInertia& inertia, class TiXmlElement* config, ErrorLogger* logger);
bool parseGeometry(UrdfGeometry& geom, class TiXmlElement* g, ErrorLogger* logger);
bool parseVisual(UrdfModel& model, UrdfVisual& visual, class TiXmlElement* config, ErrorLogger* logger);
@@ -195,7 +265,7 @@ public:
UrdfParser();
virtual ~UrdfParser();
void setParseSDF(bool useSDF)
{
m_parseSDF = useSDF;
@@ -254,6 +324,13 @@ public:
}
return m_urdf2Model;
}
std::string sourceFileLocation(TiXmlElement* e);
void setSourceFile(const std::string& sourceFile)
{
m_urdf2Model.m_sourceFile = sourceFile;
}
};
#endif

View File

@@ -225,13 +225,13 @@ void InverseDynamicsExample::initPhysics()
{
qd[dof] = 0;
char tmp[25];
sprintf(tmp,"q_desired[%u]",dof);
sprintf(tmp,"q_desired[%lu]",dof);
qd_name[dof] = tmp;
SliderParams slider(qd_name[dof].c_str(),&qd[dof]);
slider.m_minVal=-3.14;
slider.m_maxVal=3.14;
sprintf(tmp,"q[%u]",dof);
sprintf(tmp,"q[%lu]",dof);
q_name[dof] = tmp;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
btVector4 color = sJointCurveColors[dof&7];
@@ -343,6 +343,7 @@ void InverseDynamicsExample::stepSimulation(float deltaTime)
btAlignedObjectArray<btQuaternion> scratch_q;
btAlignedObjectArray<btVector3> scratch_m;
m_multiBody->forwardKinematics(scratch_q, scratch_m);
#if 0
for (int i = 0; i < m_multiBody->getNumLinks(); i++)
{
//btVector3 pos = m_multiBody->getLink(i).m_cachedWorldTransform.getOrigin();
@@ -355,6 +356,7 @@ void InverseDynamicsExample::stepSimulation(float deltaTime)
}
#endif
}
}

View File

@@ -155,10 +155,7 @@ class InverseKinematicsExample : public CommonExampleInterface
b3AlignedObjectArray<Node*> m_ikNodes;
Jacobian* m_ikJacobian;
float m_x;
float m_y;
float m_z;
b3AlignedObjectArray<int> m_movingInstances;
b3AlignedObjectArray<int> m_movingInstances;
int m_targetInstance;
enum
{
@@ -169,12 +166,9 @@ public:
InverseKinematicsExample(CommonGraphicsApp* app, int option)
:m_app(app),
m_x(0),
m_y(0),
m_z(0),
m_targetInstance(-1),
m_ikMethod(option)
{
m_ikMethod(option),
m_targetInstance(-1)
{
m_app->setUpAxis(2);
{
@@ -336,7 +330,7 @@ public:
void InverseKinematicsExample::BuildKukaIIWAShape()
{
const VectorR3& unitx = VectorR3::UnitX;
//const VectorR3& unitx = VectorR3::UnitX;
const VectorR3& unity = VectorR3::UnitY;
const VectorR3& unitz = VectorR3::UnitZ;
const VectorR3 unit1(sqrt(14.0) / 8.0, 1.0 / 8.0, 7.0 / 8.0);

View File

@@ -211,11 +211,11 @@ btMultiBody* createInvertedPendulumMultiBody(btMultiBodyDynamicsWorld* world, GU
local_origin.resize(pMultiBody->getNumLinks() + 1);
world_to_local[0] = pMultiBody->getWorldToBaseRot();
local_origin[0] = pMultiBody->getBasePos();
double friction = 1;
// double friction = 1;
{
// float pos[4]={local_origin[0].x(),local_origin[0].y(),local_origin[0].z(),1};
float quat[4]={-world_to_local[0].x(),-world_to_local[0].y(),-world_to_local[0].z(),world_to_local[0].w()};
// float quat[4]={-world_to_local[0].x(),-world_to_local[0].y(),-world_to_local[0].z(),world_to_local[0].w()};
if (1)
@@ -238,8 +238,8 @@ btMultiBody* createInvertedPendulumMultiBody(btMultiBodyDynamicsWorld* world, GU
col->setWorldTransform(tr);
bool isDynamic = (baseMass > 0 && !fixedBase);
short collisionFilterGroup = isDynamic? short(btBroadphaseProxy::DefaultFilter) : short(btBroadphaseProxy::StaticFilter);
short collisionFilterMask = isDynamic? short(btBroadphaseProxy::AllFilter) : short(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
int collisionFilterGroup = isDynamic? int(btBroadphaseProxy::DefaultFilter) : int(btBroadphaseProxy::StaticFilter);
int collisionFilterMask = isDynamic? int(btBroadphaseProxy::AllFilter) : int(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
world->addCollisionObject(col,collisionFilterGroup,collisionFilterMask);//, 2,1+2);
@@ -291,8 +291,8 @@ btMultiBody* createInvertedPendulumMultiBody(btMultiBodyDynamicsWorld* world, GU
col->setWorldTransform(tr);
// col->setFriction(friction);
bool isDynamic = 1;//(linkMass > 0);
short collisionFilterGroup = isDynamic? short(btBroadphaseProxy::DefaultFilter) : short(btBroadphaseProxy::StaticFilter);
short collisionFilterMask = isDynamic? short(btBroadphaseProxy::AllFilter) : short(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
int collisionFilterGroup = isDynamic? int(btBroadphaseProxy::DefaultFilter) : int(btBroadphaseProxy::StaticFilter);
int collisionFilterMask = isDynamic? int(btBroadphaseProxy::AllFilter) : int(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
//if (i==0||i>numLinks-2)
{
@@ -450,7 +450,7 @@ void InvertedPendulumPDControl::stepSimulation(float deltaTime)
m_multiBody->getBaseOmega()[2]
);
*/
btScalar jointVel =m_multiBody->getJointVel(0);
// btScalar jointVel =m_multiBody->getJointVel(0);
// b3Printf("child angvel = %f",jointVel);

View File

@@ -91,7 +91,7 @@ void MultiBodyConstraintFeedbackSetup::initPhysics()
m_guiHelper->createCollisionShapeGraphicsObject(box);
btTransform start; start.setIdentity();
btVector3 groundOrigin(-0.4f, 3.f, 0.f);
btVector3 basePosition = btVector3(-0.4f, 3.f, 0.f);
//btVector3 basePosition = btVector3(-0.4f, 3.f, 0.f);
groundOrigin[upAxis] -=.5;
groundOrigin[2]-=0.6;
start.setOrigin(groundOrigin);
@@ -263,11 +263,11 @@ void MultiBodyConstraintFeedbackSetup::initPhysics()
local_origin.resize(pMultiBody->getNumLinks() + 1);
world_to_local[0] = pMultiBody->getWorldToBaseRot();
local_origin[0] = pMultiBody->getBasePos();
double friction = 1;
// double friction = 1;
{
// float pos[4]={local_origin[0].x(),local_origin[0].y(),local_origin[0].z(),1};
float quat[4]={-world_to_local[0].x(),-world_to_local[0].y(),-world_to_local[0].z(),world_to_local[0].w()};
// float quat[4]={-world_to_local[0].x(),-world_to_local[0].y(),-world_to_local[0].z(),world_to_local[0].w()};
if (1)
@@ -290,8 +290,8 @@ void MultiBodyConstraintFeedbackSetup::initPhysics()
col->setWorldTransform(tr);
bool isDynamic = (baseMass > 0 && floating);
short collisionFilterGroup = isDynamic? short(btBroadphaseProxy::DefaultFilter) : short(btBroadphaseProxy::StaticFilter);
short collisionFilterMask = isDynamic? short(btBroadphaseProxy::AllFilter) : short(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
int collisionFilterGroup = isDynamic? int(btBroadphaseProxy::DefaultFilter) : int(btBroadphaseProxy::StaticFilter);
int collisionFilterMask = isDynamic? int(btBroadphaseProxy::AllFilter) : int(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
world->addCollisionObject(col,collisionFilterGroup,collisionFilterMask);//, 2,1+2);
@@ -343,8 +343,8 @@ void MultiBodyConstraintFeedbackSetup::initPhysics()
col->setWorldTransform(tr);
// col->setFriction(friction);
bool isDynamic = 1;//(linkMass > 0);
short collisionFilterGroup = isDynamic? short(btBroadphaseProxy::DefaultFilter) : short(btBroadphaseProxy::StaticFilter);
short collisionFilterMask = isDynamic? short(btBroadphaseProxy::AllFilter) : short(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
int collisionFilterGroup = isDynamic? int(btBroadphaseProxy::DefaultFilter) : int(btBroadphaseProxy::StaticFilter);
int collisionFilterMask = isDynamic? int(btBroadphaseProxy::AllFilter) : int(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
//if (i==0||i>numLinks-2)
{
@@ -416,7 +416,7 @@ void MultiBodyConstraintFeedbackSetup::stepSimulation(float deltaTime)
m_multiBody->getBaseOmega()[2]
);
*/
btScalar jointVel =m_multiBody->getJointVel(0);
// btScalar jointVel =m_multiBody->getJointVel(0);
// b3Printf("child angvel = %f",jointVel);

View File

@@ -7,7 +7,7 @@
#include "../CommonInterfaces/CommonMultiBodyBase.h"
#include "../Utils/b3ResourcePath.h"
static btScalar radius(0.2);
//static btScalar radius(0.2);
struct MultiBodySoftContact : public CommonMultiBodyBase
{
@@ -126,8 +126,8 @@ void MultiBodySoftContact::initPhysics()
col->setCollisionShape(childShape);
pMultiBody->setBaseCollider(col);
bool isDynamic = (mass > 0 && !isFixed);
short collisionFilterGroup = isDynamic? short(btBroadphaseProxy::DefaultFilter) : short(btBroadphaseProxy::StaticFilter);
short collisionFilterMask = isDynamic? short(btBroadphaseProxy::AllFilter) : short(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
int collisionFilterGroup = isDynamic? int(btBroadphaseProxy::DefaultFilter) : int(btBroadphaseProxy::StaticFilter);
int collisionFilterMask = isDynamic? int(btBroadphaseProxy::AllFilter) : int(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
m_dynamicsWorld->addCollisionObject(col,collisionFilterGroup,collisionFilterMask);//, 2,1+2);

View File

@@ -242,7 +242,7 @@ void MultiDofDemo::initPhysics()
if (multibodyConstraint) {
btVector3 pointInA = -linkHalfExtents;
btVector3 pointInB = halfExtents;
// btVector3 pointInB = halfExtents;
btMatrix3x3 frameInA;
btMatrix3x3 frameInB;
frameInA.setIdentity();

View File

@@ -150,8 +150,8 @@ void Pendulum::initPhysics()
btMultiBodyLinkCollider* col = new btMultiBodyLinkCollider(pMultiBody, i);
col->setCollisionShape(shape);
bool isDynamic = 1;
short collisionFilterGroup = isDynamic? short(btBroadphaseProxy::DefaultFilter) : short(btBroadphaseProxy::StaticFilter);
short collisionFilterMask = isDynamic? short(btBroadphaseProxy::AllFilter) : short(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
int collisionFilterGroup = isDynamic? int(btBroadphaseProxy::DefaultFilter) : int(btBroadphaseProxy::StaticFilter);
int collisionFilterMask = isDynamic? int(btBroadphaseProxy::AllFilter) : int(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
world->addCollisionObject(col,collisionFilterGroup,collisionFilterMask);//,2,1+2);
btVector4 color(1,0,0,1);
m_guiHelper->createCollisionObjectGraphicsObject(col,color);

View File

@@ -294,8 +294,8 @@ void TestJointTorqueSetup::initPhysics()
col->setWorldTransform(tr);
bool isDynamic = (baseMass > 0 && floating);
short collisionFilterGroup = isDynamic? short(btBroadphaseProxy::DefaultFilter) : short(btBroadphaseProxy::StaticFilter);
short collisionFilterMask = isDynamic? short(btBroadphaseProxy::AllFilter) : short(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
int collisionFilterGroup = isDynamic? int(btBroadphaseProxy::DefaultFilter) : int(btBroadphaseProxy::StaticFilter);
int collisionFilterMask = isDynamic? int(btBroadphaseProxy::AllFilter) : int(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
world->addCollisionObject(col,collisionFilterGroup,collisionFilterMask);//, 2,1+2);
@@ -347,8 +347,8 @@ void TestJointTorqueSetup::initPhysics()
col->setWorldTransform(tr);
// col->setFriction(friction);
bool isDynamic = 1;//(linkMass > 0);
short collisionFilterGroup = isDynamic? short(btBroadphaseProxy::DefaultFilter) : short(btBroadphaseProxy::StaticFilter);
short collisionFilterMask = isDynamic? short(btBroadphaseProxy::AllFilter) : short(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
int collisionFilterGroup = isDynamic? int(btBroadphaseProxy::DefaultFilter) : int(btBroadphaseProxy::StaticFilter);
int collisionFilterMask = isDynamic? int(btBroadphaseProxy::AllFilter) : int(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
//if (i==0||i>numLinks-2)
{

View File

@@ -30,6 +30,11 @@ class btCollisionShape;
#include "BulletDynamics/Dynamics/btSimulationIslandManagerMt.h" // for setSplitIslands()
#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorldMt.h"
#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
#include "BulletDynamics/ConstraintSolver/btNNCGConstraintSolver.h"
#include "BulletDynamics/MLCPSolvers/btMLCPSolver.h"
#include "BulletDynamics/MLCPSolvers/btSolveProjectedGaussSeidel.h"
#include "BulletDynamics/MLCPSolvers/btDantzigSolver.h"
#include "BulletDynamics/MLCPSolvers/btLemkeSolver.h"
TaskManager gTaskMgr;
@@ -46,6 +51,8 @@ TaskManager gTaskMgr;
#define BT_OVERRIDE
#endif
static int gNumIslands = 0;
class Profiler
{
@@ -434,8 +441,6 @@ struct UpdateIslandDispatcher
}
};
static int gNumIslands = 0;
void parallelIslandDispatch( btAlignedObjectArray<btSimulationIslandManagerMt::Island*>* islandsPtr, btSimulationIslandManagerMt::IslandCallback* callback )
{
ProfileHelper prof(Profiler::kRecordDispatchIslands);
@@ -583,15 +588,56 @@ public:
) :
btDiscreteDynamicsWorldMt( dispatcher, pairCache, constraintSolver, collisionConfiguration )
{
#if USE_PARALLEL_ISLAND_SOLVER
btSimulationIslandManagerMt* islandMgr = static_cast<btSimulationIslandManagerMt*>( m_islandManager );
islandMgr->setIslandDispatchFunction( parallelIslandDispatch );
#endif //#if USE_PARALLEL_ISLAND_SOLVER
}
};
btConstraintSolver* createSolverByType( SolverType t )
{
btMLCPSolverInterface* mlcpSolver = NULL;
switch ( t )
{
case SOLVER_TYPE_SEQUENTIAL_IMPULSE:
return new btSequentialImpulseConstraintSolver();
case SOLVER_TYPE_NNCG:
return new btNNCGConstraintSolver();
case SOLVER_TYPE_MLCP_PGS:
mlcpSolver = new btSolveProjectedGaussSeidel();
break;
case SOLVER_TYPE_MLCP_DANTZIG:
mlcpSolver = new btDantzigSolver();
break;
case SOLVER_TYPE_MLCP_LEMKE:
mlcpSolver = new btLemkeSolver();
break;
default: {}
}
if (mlcpSolver)
{
return new btMLCPSolver(mlcpSolver);
}
return NULL;
}
static bool gMultithreadedWorld = false;
static bool gDisplayProfileInfo = false;
static btScalar gSliderNumThreads = 1.0f; // should be int
static SolverType gSolverType = SOLVER_TYPE_SEQUENTIAL_IMPULSE;
static int gSolverMode = SOLVER_SIMD |
SOLVER_USE_WARMSTARTING |
// SOLVER_RANDMIZE_ORDER |
// SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS |
// SOLVER_USE_2_FRICTION_DIRECTIONS |
0;
static btScalar gSliderSolverIterations = 10.0f; // should be int
static btScalar gSliderNumThreads = 1.0f; // should be int
////////////////////////////////////
CommonRigidBodyMTBase::CommonRigidBodyMTBase( struct GUIHelperInterface* helper )
@@ -622,6 +668,33 @@ void boolPtrButtonCallback(int buttonId, bool buttonState, void* userPointer)
}
}
void toggleSolverModeCallback(int buttonId, bool buttonState, void* userPointer)
{
if (buttonState)
{
gSolverMode |= buttonId;
}
else
{
gSolverMode &= ~buttonId;
}
if (CommonRigidBodyMTBase* crb = reinterpret_cast<CommonRigidBodyMTBase*>(userPointer))
{
if (crb->m_dynamicsWorld)
{
crb->m_dynamicsWorld->getSolverInfo().m_solverMode = gSolverMode;
}
}
}
void setSolverTypeCallback(int buttonId, bool buttonState, void* userPointer)
{
if (buttonId >= 0 && buttonId < SOLVER_TYPE_COUNT)
{
gSolverType = static_cast<SolverType>(buttonId);
}
}
void apiSelectButtonCallback(int buttonId, bool buttonState, void* userPointer)
{
gTaskMgr.setApi(static_cast<TaskManager::Api>(buttonId));
@@ -658,6 +731,7 @@ void setSolverIterationCountCallback(float val, void* userPtr)
void CommonRigidBodyMTBase::createEmptyDynamicsWorld()
{
gNumIslands = 0;
m_solverType = gSolverType;
#if BT_THREADSAFE && (BT_USE_OPENMP || BT_USE_PPL || BT_USE_TBB)
m_multithreadCapable = true;
#endif
@@ -677,21 +751,22 @@ void CommonRigidBodyMTBase::createEmptyDynamicsWorld()
m_broadphase = new btDbvtBroadphase();
#if USE_PARALLEL_ISLAND_SOLVER
m_solver = new MyConstraintSolverPool( TaskManager::getMaxNumThreads() );
#if BT_THREADSAFE && USE_PARALLEL_ISLAND_SOLVER
{
btConstraintSolver* solvers[ BT_MAX_THREAD_COUNT ];
int maxThreadCount = btMin( int(BT_MAX_THREAD_COUNT), TaskManager::getMaxNumThreads() );
for ( int i = 0; i < maxThreadCount; ++i )
{
solvers[ i ] = createSolverByType( m_solverType );
}
m_solver = new MyConstraintSolverPool( solvers, maxThreadCount );
}
#else
m_solver = new btSequentialImpulseConstraintSolver();
m_solver = createSolverByType( m_solverType );
#endif //#if USE_PARALLEL_ISLAND_SOLVER
btDiscreteDynamicsWorld* world = new MyDiscreteDynamicsWorld( m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration );
m_dynamicsWorld = world;
#if USE_PARALLEL_ISLAND_SOLVER
if ( btSimulationIslandManagerMt* islandMgr = dynamic_cast<btSimulationIslandManagerMt*>( world->getSimulationIslandManager() ) )
{
islandMgr->setIslandDispatchFunction( parallelIslandDispatch );
m_multithreadedWorld = true;
}
#endif //#if USE_PARALLEL_ISLAND_SOLVER
m_multithreadedWorld = true;
}
else
{
@@ -707,15 +782,14 @@ void CommonRigidBodyMTBase::createEmptyDynamicsWorld()
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_solver = createSolverByType( m_solverType );
m_dynamicsWorld = new btDiscreteDynamicsWorld( m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration );
}
m_dynamicsWorld->setInternalTickCallback( profileBeginCallback, NULL, true );
m_dynamicsWorld->setInternalTickCallback( profileEndCallback, NULL, false );
m_dynamicsWorld->setGravity( btVector3( 0, -10, 0 ) );
m_dynamicsWorld->getSolverInfo().m_solverMode = gSolverMode;
createDefaultParameters();
}
@@ -726,18 +800,33 @@ void CommonRigidBodyMTBase::createDefaultParameters()
{
// create a button to toggle multithreaded world
ButtonParams button( "Multithreaded world enable", 0, true );
button.m_initialState = gMultithreadedWorld;
button.m_userPointer = &gMultithreadedWorld;
button.m_callback = boolPtrButtonCallback;
m_guiHelper->getParameterInterface()->registerButtonParameter( button );
}
{
// create a button to toggle profile printing
ButtonParams button( "Display profile timings", 0, true );
ButtonParams button( "Display solver info", 0, true );
button.m_initialState = gDisplayProfileInfo;
button.m_userPointer = &gDisplayProfileInfo;
button.m_callback = boolPtrButtonCallback;
m_guiHelper->getParameterInterface()->registerButtonParameter( button );
}
// add buttons for switching to different solver types
for (int i = 0; i < SOLVER_TYPE_COUNT; ++i)
{
char buttonName[256];
SolverType solverType = static_cast<SolverType>(i);
sprintf(buttonName, "Solver Type %s", getSolverTypeName(solverType));
ButtonParams button( buttonName, 0, false );
button.m_buttonId = solverType;
button.m_callback = setSolverTypeCallback;
m_guiHelper->getParameterInterface()->registerButtonParameter( button );
}
{
// a slider for the number of solver iterations
SliderParams slider( "Solver iterations", &gSliderSolverIterations );
slider.m_minVal = 1.0f;
slider.m_maxVal = 30.0f;
@@ -746,6 +835,54 @@ void CommonRigidBodyMTBase::createDefaultParameters()
slider.m_clampToIntegers = true;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter( slider );
}
{
ButtonParams button( "Solver use SIMD", 0, true );
button.m_buttonId = SOLVER_SIMD;
button.m_initialState = !! (gSolverMode & button.m_buttonId);
button.m_callback = toggleSolverModeCallback;
button.m_userPointer = this;
m_guiHelper->getParameterInterface()->registerButtonParameter( button );
}
{
ButtonParams button( "Solver randomize order", 0, true );
button.m_buttonId = SOLVER_RANDMIZE_ORDER;
button.m_initialState = !! (gSolverMode & button.m_buttonId);
button.m_callback = toggleSolverModeCallback;
button.m_userPointer = this;
m_guiHelper->getParameterInterface()->registerButtonParameter( button );
}
{
ButtonParams button( "Solver interleave contact/friction", 0, true );
button.m_buttonId = SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS;
button.m_initialState = !! (gSolverMode & button.m_buttonId);
button.m_callback = toggleSolverModeCallback;
button.m_userPointer = this;
m_guiHelper->getParameterInterface()->registerButtonParameter( button );
}
{
ButtonParams button( "Solver 2 friction directions", 0, true );
button.m_buttonId = SOLVER_USE_2_FRICTION_DIRECTIONS;
button.m_initialState = !! (gSolverMode & button.m_buttonId);
button.m_callback = toggleSolverModeCallback;
button.m_userPointer = this;
m_guiHelper->getParameterInterface()->registerButtonParameter( button );
}
{
ButtonParams button( "Solver friction dir caching", 0, true );
button.m_buttonId = SOLVER_ENABLE_FRICTION_DIRECTION_CACHING;
button.m_initialState = !! (gSolverMode & button.m_buttonId);
button.m_callback = toggleSolverModeCallback;
button.m_userPointer = this;
m_guiHelper->getParameterInterface()->registerButtonParameter( button );
}
{
ButtonParams button( "Solver warmstarting", 0, true );
button.m_buttonId = SOLVER_USE_WARMSTARTING;
button.m_initialState = !! (gSolverMode & button.m_buttonId);
button.m_callback = toggleSolverModeCallback;
button.m_userPointer = this;
m_guiHelper->getParameterInterface()->registerButtonParameter( button );
}
if (m_multithreadedWorld)
{
// create a button for each supported threading API
@@ -774,17 +911,19 @@ void CommonRigidBodyMTBase::createDefaultParameters()
}
}
void CommonRigidBodyMTBase::physicsDebugDraw(int debugFlags)
void CommonRigidBodyMTBase::drawScreenText()
{
if (m_dynamicsWorld && m_dynamicsWorld->getDebugDrawer())
{
m_dynamicsWorld->getDebugDrawer()->setDebugMode(debugFlags);
m_dynamicsWorld->debugDrawWorld();
}
char msg[ 1024 ];
int xCoord = 400;
int yCoord = 30;
int yStep = 30;
if (m_solverType != gSolverType)
{
sprintf( msg, "restart example to change solver type" );
m_guiHelper->getAppInterface()->drawText( msg, 300, yCoord, 0.4f );
yCoord += yStep;
}
if (m_multithreadCapable)
{
if ( m_multithreadedWorld != gMultithreadedWorld )
@@ -819,7 +958,20 @@ void CommonRigidBodyMTBase::physicsDebugDraw(int debugFlags)
m_guiHelper->getAppInterface()->drawText( msg, 100, yCoord, 0.4f );
yCoord += yStep;
}
{
int sm = gSolverMode;
sprintf( msg, "solver %s mode [%s%s%s%s%s%s]",
getSolverTypeName(m_solverType),
sm & SOLVER_SIMD ? "SIMD" : "",
sm & SOLVER_RANDMIZE_ORDER ? " randomize" : "",
sm & SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS ? " interleave" : "",
sm & SOLVER_USE_2_FRICTION_DIRECTIONS ? " friction2x" : "",
sm & SOLVER_ENABLE_FRICTION_DIRECTION_CACHING ? " frictionDirCaching" : "",
sm & SOLVER_USE_WARMSTARTING ? " warm" : ""
);
m_guiHelper->getAppInterface()->drawText( msg, xCoord, yCoord, 0.4f );
yCoord += yStep;
}
sprintf( msg, "internalSimStep %5.3f ms",
gProfiler.getAverageTime( Profiler::kRecordInternalTimeStep )*0.001f
);
@@ -866,3 +1018,21 @@ void CommonRigidBodyMTBase::physicsDebugDraw(int debugFlags)
}
}
void CommonRigidBodyMTBase::physicsDebugDraw(int debugFlags)
{
if (m_dynamicsWorld && m_dynamicsWorld->getDebugDrawer())
{
m_dynamicsWorld->getDebugDrawer()->setDebugMode(debugFlags);
m_dynamicsWorld->debugDrawWorld();
}
drawScreenText();
}
void CommonRigidBodyMTBase::renderScene()
{
m_guiHelper->syncPhysicsToGraphics(m_dynamicsWorld);
m_guiHelper->render(m_dynamicsWorld);
drawScreenText();
}

View File

@@ -11,6 +11,32 @@
#include "../CommonInterfaces/CommonGraphicsAppInterface.h"
#include "../CommonInterfaces/CommonWindowInterface.h"
enum SolverType
{
SOLVER_TYPE_SEQUENTIAL_IMPULSE,
SOLVER_TYPE_NNCG,
SOLVER_TYPE_MLCP_PGS,
SOLVER_TYPE_MLCP_DANTZIG,
SOLVER_TYPE_MLCP_LEMKE,
SOLVER_TYPE_COUNT
};
inline const char* getSolverTypeName( SolverType t )
{
switch (t)
{
case SOLVER_TYPE_SEQUENTIAL_IMPULSE: return "SequentialImpulse";
case SOLVER_TYPE_NNCG: return "NNCG";
case SOLVER_TYPE_MLCP_PGS: return "MLCP ProjectedGaussSeidel";
case SOLVER_TYPE_MLCP_DANTZIG: return "MLCP Dantzig";
case SOLVER_TYPE_MLCP_LEMKE: return "MLCP Lemke";
default:{}
}
btAssert( !"unhandled solver type in switch" );
return "???";
}
struct CommonRigidBodyMTBase : public CommonExampleInterface
{
//keep the collision shapes, for deletion/cleanup
@@ -20,6 +46,7 @@ struct CommonRigidBodyMTBase : public CommonExampleInterface
btConstraintSolver* m_solver;
btDefaultCollisionConfiguration* m_collisionConfiguration;
btDiscreteDynamicsWorld* m_dynamicsWorld;
SolverType m_solverType;
bool m_multithreadedWorld;
bool m_multithreadCapable;
@@ -52,6 +79,8 @@ struct CommonRigidBodyMTBase : public CommonExampleInterface
}
}
virtual void drawScreenText();
virtual void renderScene();
virtual void physicsDebugDraw(int debugFlags);
virtual void exitPhysics()
@@ -418,19 +447,7 @@ struct CommonRigidBodyMTBase : public CommonExampleInterface
return body;
}
virtual void renderScene()
{
{
m_guiHelper->syncPhysicsToGraphics(m_dynamicsWorld);
}
{
m_guiHelper->render(m_dynamicsWorld);
}
}
};
#endif //#define COMMON_RIGID_BODY_MT_BASE_H

View File

@@ -224,12 +224,12 @@ private:
extern TaskManager gTaskMgr;
static void initTaskScheduler()
inline static void initTaskScheduler()
{
gTaskMgr.init();
}
static void cleanupTaskScheduler()
inline static void cleanupTaskScheduler()
{
gTaskMgr.shutdown();
}

View File

@@ -163,8 +163,6 @@ void* SamplelsMemoryFunc()
class MultiThreadingExample : public CommonExampleInterface
{
CommonGraphicsApp* m_app;
GUIHelperInterface* m_guiHelper;
int m_exampleIndex;
b3ThreadSupportInterface* m_threadSupport;
btAlignedObjectArray<SampleJob1*> m_jobs;
int m_numThreads;
@@ -172,12 +170,10 @@ public:
MultiThreadingExample(GUIHelperInterface* guiHelper, int tutorialIndex)
:m_app(guiHelper->getAppInterface()),
m_guiHelper(guiHelper),
m_exampleIndex(tutorialIndex),
m_threadSupport(0),
m_numThreads(8)
{
int numBodies = 1;
//int numBodies = 1;
m_app->setUpAxis(1);
m_app->m_renderer->enableBlend(true);

View File

@@ -279,7 +279,9 @@ void b3Win32ThreadSupport::startThreads(const Win32ThreadConstructionInfo& threa
}
SetThreadAffinityMask(handle, 1<<i);
DWORD mask = 1;
mask = 1<<mask;
SetThreadAffinityMask(handle, mask);
threadStatus.m_taskId = i;
threadStatus.m_commandId = 0;
@@ -311,6 +313,7 @@ void b3Win32ThreadSupport::stopThreads()
WaitForSingleObject(threadStatus.m_eventCompletetHandle, INFINITE);
}
delete threadStatus.m_lsMemory;
threadStatus.m_userPtr = 0;
SetEvent(threadStatus.m_eventStartHandle);

View File

@@ -43,8 +43,8 @@ struct CommonOpenCLBase : public CommonExampleInterface
virtual void initCL(int preferredDeviceIndex, int preferredPlatformIndex)
{
void* glCtx=0;
void* glDC = 0;
// void* glCtx=0;
// void* glDC = 0;

View File

@@ -208,9 +208,6 @@ void PairBench::initPhysics()
useShadowMap = false;
int startItem = 0;
initCL(gPreferredOpenCLDeviceIndex,gPreferredOpenCLPlatformIndex);
if (m_clData->m_clContext)
@@ -298,7 +295,7 @@ void PairBench::createBroadphase(int arraySizeX, int arraySizeY, int arraySizeZ)
char * patloc;
for (oriptr = buf; patloc = strstr(oriptr, pattern); oriptr = patloc + patlen)
for (oriptr = buf; (patloc = strstr(oriptr, pattern)); oriptr = patloc + patlen)
{
if (patloc)
{
@@ -335,12 +332,14 @@ void PairBench::createBroadphase(int arraySizeX, int arraySizeY, int arraySizeZ)
if (l>500)
{
b3Vector4 color=b3MakeVector4(0,1,0,0.1);
int id = m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId,position,orn,color,scaling);
int id;
id = m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId,position,orn,color,scaling);
m_data->m_broadphaseGPU->createLargeProxy(aabbMin,aabbMax,index,group,mask);
} else
{
b3Vector4 color=b3MakeVector4(1,0,0,1);
int id = m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId,position,orn,color,scaling);
int id;
id = m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId,position,orn,color,scaling);
m_data->m_broadphaseGPU->createProxy(aabbMin,aabbMax,index,group,mask);
index++;
}
@@ -403,7 +402,8 @@ void PairBench::createBroadphase(int arraySizeX, int arraySizeY, int arraySizeZ)
}*/
int id = m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId,position,orn,color,scaling);
int id;
id = m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId,position,orn,color,scaling);
b3Vector3 aabbMin = position-scaling;
@@ -486,7 +486,7 @@ void PairBench::stepSimulation(float deltaTime)
return;
bool animate=true;
//bool animate=true;
int numObjects= 0;
{
B3_PROFILE("Num Objects");
@@ -503,7 +503,7 @@ void PairBench::stepSimulation(float deltaTime)
int arraySizeInBytes = numObjects * (3)*sizeof(b3Vector4);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
cl_bool blocking= CL_TRUE;
// cl_bool blocking= CL_TRUE;
char* hostPtr= 0;
{
B3_PROFILE("glMapBufferRange");
@@ -583,7 +583,7 @@ void PairBench::stepSimulation(float deltaTime)
B3_PROFILE("updateOnCpu");
if (!gPairBenchFileName)
{
int allAabbs = m_data->m_broadphaseGPU->getAllAabbsCPU().size();
// int allAabbs = m_data->m_broadphaseGPU->getAllAabbsCPU().size();
b3AlignedObjectArray<b3Vector4> posOrnColorsCpu;
@@ -625,11 +625,12 @@ void PairBench::stepSimulation(float deltaTime)
b3Clock cl;
dt = cl.getTimeMicroseconds();
B3_PROFILE("calculateOverlappingPairs");
int sz = sizeof(b3Int4)*64*numObjects;
//int sz = sizeof(b3Int4)*64*numObjects;
m_data->m_broadphaseGPU->calculateOverlappingPairs(maxOverlap);
int numPairs = m_data->m_broadphaseGPU->getNumOverlap();
int numPairs;
numPairs = m_data->m_broadphaseGPU->getNumOverlap();
//printf("numPairs = %d\n", numPairs);
dt = cl.getTimeMicroseconds()-dt;

View File

@@ -223,8 +223,8 @@ int GpuConvexScene::createDynamicsObjects2( const float* vertices, int numVertic
}
int shapeId = m_guiHelper->getRenderInterface()->registerShape(&vertices[0],numVertices,indices,numIndices,B3_GL_TRIANGLES,textureIndex);
int group=1;
int mask=1;
//int group=1;
//int mask=1;
int index=0;
@@ -237,7 +237,7 @@ int GpuConvexScene::createDynamicsObjects2( const float* vertices, int numVertic
int curColor = 0;
float scaling[4] = {1,1,1,1};
int prevBody = -1;
int insta = 0;
//int insta = 0;
b3ConvexUtility* utilPtr = new b3ConvexUtility();
@@ -290,9 +290,11 @@ int GpuConvexScene::createDynamicsObjects2( const float* vertices, int numVertic
b3Vector4 color = colors[curColor];
curColor++;
curColor&=3;
b3Vector4 scalin=b3MakeVector4(1,1,1,1);
int id = m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId,position,orn,color,scaling);
int pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(mass,position,orn,colIndex,index,false);
// b3Vector4 scaling=b3MakeVector4(1,1,1,1);
int id;
id= m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId,position,orn,color,scaling);
int pid;
pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(mass,position,orn,colIndex,index,false);
if (prevBody>=0)
@@ -319,8 +321,8 @@ void GpuConvexScene::createStaticEnvironment()
int numIndices = sizeof(cube_indices)/sizeof(int);
//int shapeId = ci.m_instancingRenderer->registerShape(&cube_vertices[0],numVertices,cube_indices,numIndices);
int shapeId = m_instancingRenderer->registerShape(&cube_vertices[0],numVertices,cube_indices,numIndices);
int group=1;
int mask=1;
//int group=1;
//int mask=1;
int index=0;
@@ -332,8 +334,10 @@ void GpuConvexScene::createStaticEnvironment()
b3Vector4 color=b3MakeVector4(0,0,1,1);
int id = m_instancingRenderer->registerGraphicsInstance(shapeId,position,orn,color,scaling);
int pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(0.f,position,orn,colIndex,index,false);
int id;
id = m_instancingRenderer->registerGraphicsInstance(shapeId,position,orn,color,scaling);
int pid;
pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(0.f,position,orn,colIndex,index,false);
}
}
@@ -345,8 +349,8 @@ void GpuConvexPlaneScene::createStaticEnvironment()
int numIndices = sizeof(cube_indices)/sizeof(int);
//int shapeId = ci.m_instancingRenderer->registerShape(&cube_vertices[0],numVertices,cube_indices,numIndices);
int shapeId = m_guiHelper->getRenderInterface()->registerShape(&cube_vertices[0],numVertices,cube_indices,numIndices);
int group=1;
int mask=1;
// int group=1;
// int mask=1;
int index=0;
@@ -358,8 +362,10 @@ void GpuConvexPlaneScene::createStaticEnvironment()
b3Vector4 color=b3MakeVector4(0,0,1,1);
int id = m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId,position,orn,color,scaling);
int pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(0.f,position,orn,colIndex,index,false);
int id;
id = m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId,position,orn,color,scaling);
int pid;
pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(0.f,position,orn,colIndex,index,false);
}
@@ -535,8 +541,8 @@ void GpuTetraScene::createFromTetGenData(const char* ele,
int numVertices = sizeof(mytetra_vertices)/strideInBytes;
int numIndices = sizeof(mytetra_indices)/sizeof(int);
int shapeId = m_instancingRenderer->registerShape(&mytetra_vertices[0],numVertices,mytetra_indices,numIndices);
int group=1;
int mask=1;
// int group=1;
// int mask=1;
@@ -553,8 +559,10 @@ void GpuTetraScene::createFromTetGenData(const char* ele,
b3Vector4 color = colors[curColor++];
curColor&=3;
int id = m_instancingRenderer->registerGraphicsInstance(shapeId,position,orn,color,scaling);
int pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(1.f,position,orn,colIndex,0,false);
int id;
id = m_instancingRenderer->registerGraphicsInstance(shapeId,position,orn,color,scaling);
int pid;
pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(1.f,position,orn,colIndex,0,false);
//rigidBodyIds.push_back(pid);
}
@@ -620,7 +628,8 @@ void GpuTetraScene::createFromTetGenData(const char* ele,
bool useGPU = true;
if (useGPU)
{
int cid = m_data->m_rigidBodyPipeline->createFixedConstraint(bodyIndexA,bodyIndexB,pivotInA,pivotInB,relTargetAB,breakingThreshold);
int cid;
cid = m_data->m_rigidBodyPipeline->createFixedConstraint(bodyIndexA,bodyIndexB,pivotInA,pivotInB,relTargetAB,breakingThreshold);
} else
{
b3FixedConstraint* c = new b3FixedConstraint(bodyIndexA,bodyIndexB,frameInA,frameInB);

View File

@@ -233,7 +233,7 @@ void GpuRigidBodyDemo::stepSimulation(float deltaTime)
GLuint vbo = m_instancingRenderer->getInternalData()->m_vbo;
int arraySizeInBytes = numObjects * (3)*sizeof(b3Vector4);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
cl_bool blocking= CL_TRUE;
// cl_bool blocking= CL_TRUE;
positions= (b3Vector4*)glMapBufferRange( GL_ARRAY_BUFFER,m_instancingRenderer->getMaxShapeCapacity(),arraySizeInBytes, GL_MAP_READ_BIT );//GL_READ_WRITE);//GL_WRITE_ONLY
GLint err = glGetError();
assert(err==GL_NO_ERROR);
@@ -296,7 +296,7 @@ void GpuRigidBodyDemo::stepSimulation(float deltaTime)
int arraySizeInBytes = numObjects * (3)*sizeof(b3Vector4);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
cl_bool blocking= CL_TRUE;
// cl_bool blocking= CL_TRUE;
positions= (b3Vector4*)glMapBufferRange( GL_ARRAY_BUFFER,m_instancingRenderer->getMaxShapeCapacity(),arraySizeInBytes, GL_MAP_WRITE_BIT );//GL_READ_WRITE);//GL_WRITE_ONLY
err = glGetError();
assert(err==GL_NO_ERROR);
@@ -329,7 +329,7 @@ b3Vector3 GpuRigidBodyDemo::getRayTo(int x,int y)
float farPlane = 10000.f;
rayForward*= farPlane;
b3Vector3 rightOffset;
// b3Vector3 rightOffset;
b3Vector3 m_cameraUp=b3MakeVector3(0,1,0);
b3Vector3 vertical = m_cameraUp;
@@ -401,7 +401,7 @@ bool GpuRigidBodyDemo::mouseMoveCallback(float x,float y)
m_data->m_rigidBodyPipeline->removeConstraintByUid(m_data->m_pickConstraint);
b3Vector3 newRayTo = getRayTo(x,y);
b3Vector3 rayFrom;
b3Vector3 oldPivotInB = m_data->m_pickPivotInB;
// b3Vector3 oldPivotInB = m_data->m_pickPivotInB;
b3Vector3 newPivotB;
m_guiHelper->getRenderInterface()->getActiveCamera()->getCameraPosition(rayFrom);
b3Vector3 dir = newRayTo-rayFrom;

View File

@@ -6,7 +6,8 @@ INCLUDE_DIRECTORIES(
FILE(GLOB OpenGLWindow_HDRS "*.h" )
FILE(GLOB OpenGLWindowMac_CPP "Mac*.mm")
FILE(GLOB OpenGLWindowMac_CPP "Mac*.cpp")
FILE(GLOB OpenGLWindowMacObjC_CPP "Mac*.m")
FILE(GLOB OpenGLWindowWin32_CPP "Win32*.cpp")
FILE(GLOB OpenGLWindowLinux_CPP "X11*.cpp")
@@ -16,6 +17,7 @@ LIST(REMOVE_ITEM OpenGLWindowCommon_CPP ${OpenGLWindowMac_CPP} )
LIST(REMOVE_ITEM OpenGLWindowCommon_CPP ${OpenGLWindowWin32_CPP} )
LIST(REMOVE_ITEM OpenGLWindowCommon_CPP ${OpenGLWindowLinux_CPP} )
LIST(REMOVE_ITEM OpenGLWindowCommon_CPP X11OpenGLWindow.cpp )
LIST(REMOVE_ITEM OpenGLWindowCommon_CPP MacOpenGLWindow.cpp )
#MESSAGE (${OpenGLWindowCommon_CPP})
IF (WIN32)
@@ -27,7 +29,7 @@ IF (WIN32)
ENDIF(WIN32)
IF (APPLE)
SET(OpenGLWindow_SRCS ${OpenGLWindowMac_CPP} ${OpenGLWindowCommon_CPP} )
SET(OpenGLWindow_SRCS ${OpenGLWindowMac_CPP} ${OpenGLWindowMacObjC_CPP} ${OpenGLWindowCommon_CPP} )
ENDIF(APPLE)
#no Linux detection?
@@ -59,7 +61,7 @@ if (BUILD_SHARED_LIBS)
else()
set (CMAKE_THREAD_PREFER_PTHREAD TRUE)
FIND_PACKAGE(Threads)
target_link_libraries(OpenGLWindow dl ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(OpenGLWindow ${DL} ${CMAKE_THREAD_LIBS_INIT})
endif()
endif()

View File

@@ -0,0 +1,260 @@
// portions of this file are copied from GLFW egl_context.c/egl_context.h
//========================================================================
// GLFW 3.3 EGL - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.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.
//
//========================================================================
#ifdef BT_USE_EGL
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "OpenGLInclude.h"
#include "third_party/GL/EGL/egl.h"
#include "third_party/GL/gl/include/EGL/eglext.h"
#include "third_party/GL/gl/include/GL/gl.h"
#include "EGLOpenGLWindow.h"
struct EGLInternalData2 {
bool m_isInitialized;
int m_windowWidth;
int m_windowHeight;
b3KeyboardCallback m_keyboardCallback;
b3WheelCallback m_wheelCallback;
b3ResizeCallback m_resizeCallback;
b3MouseButtonCallback m_mouseButtonCallback;
b3MouseMoveCallback m_mouseMoveCallback;
EGLBoolean success;
EGLint num_configs;
EGLConfig egl_config;
EGLSurface egl_surface;
EGLContext egl_context;
EGLDisplay egl_display;
EGLInternalData2()
: m_isInitialized(false),
m_windowWidth(0),
m_windowHeight(0),
m_keyboardCallback(0),
m_wheelCallback(0),
m_resizeCallback(0),
m_mouseButtonCallback(0),
m_mouseMoveCallback(0) {}
};
EGLOpenGLWindow::EGLOpenGLWindow() { m_data = new EGLInternalData2(); }
EGLOpenGLWindow::~EGLOpenGLWindow() { delete m_data; }
void EGLOpenGLWindow::createWindow(const b3gWindowConstructionInfo& ci) {
m_data->m_windowWidth = ci.m_width;
m_data->m_windowHeight = ci.m_height;
EGLint egl_config_attribs[] = {EGL_RED_SIZE,
8,
EGL_GREEN_SIZE,
8,
EGL_BLUE_SIZE,
8,
EGL_DEPTH_SIZE,
8,
EGL_SURFACE_TYPE,
EGL_PBUFFER_BIT,
EGL_RENDERABLE_TYPE,
EGL_OPENGL_BIT,
EGL_NONE};
EGLint egl_pbuffer_attribs[] = {
EGL_WIDTH, m_data->m_windowWidth, EGL_HEIGHT, m_data->m_windowHeight,
EGL_NONE,
};
// Initialize EGL display
PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT =
(PFNEGLQUERYDEVICESEXTPROC)eglGetProcAddress("eglQueryDevicesEXT");
if (eglQueryDevicesEXT == nullptr) m_data->egl_display = EGL_NO_DISPLAY;
PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT =
(PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress(
"eglGetPlatformDisplayEXT");
if (eglGetPlatformDisplayEXT == nullptr) m_data->egl_display = EGL_NO_DISPLAY;
const int max_devices = 32;
EGLDeviceEXT egl_devices[max_devices];
EGLint num_devices = 0;
EGLint egl_error = eglGetError();
if (!eglQueryDevicesEXT(max_devices, egl_devices, &num_devices) ||
egl_error != EGL_SUCCESS) {
printf("eglQueryDevicesEXT Failed.\n");
m_data->egl_display = EGL_NO_DISPLAY;
}
for (EGLint i = 0; i < num_devices; ++i) {
EGLDisplay display = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT,
egl_devices[i], nullptr);
if (eglGetError() == EGL_SUCCESS && display != EGL_NO_DISPLAY) {
int major, minor;
EGLBoolean initialized = eglInitialize(display, &major, &minor);
if (eglGetError() == EGL_SUCCESS && initialized == EGL_TRUE) {
m_data->egl_display = display;
}
}
}
m_data->success = eglBindAPI(EGL_OPENGL_API);
if (!m_data->success) {
printf("Failed to bind OpenGL API.\n");
exit(0);
}
m_data->success =
eglChooseConfig(m_data->egl_display, egl_config_attribs,
&m_data->egl_config, 1, &m_data->num_configs);
if (!m_data->success) {
printf("Failed to choose a valid an EGLConfig.\n");
exit(0);
}
m_data->egl_surface = eglCreatePbufferSurface(
m_data->egl_display, m_data->egl_config, egl_pbuffer_attribs);
m_data->egl_context = eglCreateContext(
m_data->egl_display, m_data->egl_config, EGL_NO_CONTEXT, nullptr);
eglMakeCurrent(m_data->egl_display, m_data->egl_surface, m_data->egl_surface,
m_data->egl_context);
printf("Finish creating EGL OpenGL window.\n");
const GLubyte* ven = glGetString(GL_VENDOR);
printf("GL_VENDOR=%s\n", ven);
const GLubyte* ren = glGetString(GL_RENDERER);
printf("GL_RENDERER=%s\n", ren);
const GLubyte* ver = glGetString(GL_VERSION);
printf("GL_VERSION=%s\n", ver);
const GLubyte* sl = glGetString(GL_SHADING_LANGUAGE_VERSION);
printf("GL_SHADING_LANGUAGE_VERSION=%s\n", sl);
int i = pthread_getconcurrency();
printf("pthread_getconcurrency()=%d\n", i);
}
void EGLOpenGLWindow::closeWindow() {
eglMakeCurrent(m_data->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
EGL_NO_CONTEXT);
eglDestroySurface(m_data->egl_display, m_data->egl_surface);
eglDestroyContext(m_data->egl_display, m_data->egl_context);
printf("Destroy EGL OpenGL window.\n");
}
void EGLOpenGLWindow::runMainLoop() {}
float EGLOpenGLWindow::getTimeInSeconds() { return 0.; }
bool EGLOpenGLWindow::requestedExit() const { return false; }
void EGLOpenGLWindow::setRequestExit() {}
void EGLOpenGLWindow::startRendering() {
// printf("EGL window start rendering.\n");
glViewport(0, 0, m_data->m_windowWidth, m_data->m_windowHeight);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
}
void EGLOpenGLWindow::endRendering() {
// printf("EGL window end rendering.\n");
eglSwapBuffers(m_data->egl_display, m_data->egl_surface);
}
bool EGLOpenGLWindow::isModifierKeyPressed(int key) { return false; }
void EGLOpenGLWindow::setMouseMoveCallback(b3MouseMoveCallback mouseCallback) {
m_data->m_mouseMoveCallback = mouseCallback;
}
b3MouseMoveCallback EGLOpenGLWindow::getMouseMoveCallback() {
return m_data->m_mouseMoveCallback;
}
void EGLOpenGLWindow::setMouseButtonCallback(
b3MouseButtonCallback mouseCallback) {
m_data->m_mouseButtonCallback = mouseCallback;
}
b3MouseButtonCallback EGLOpenGLWindow::getMouseButtonCallback() {
return m_data->m_mouseButtonCallback;
}
void EGLOpenGLWindow::setResizeCallback(b3ResizeCallback resizeCallback) {
m_data->m_resizeCallback = resizeCallback;
}
b3ResizeCallback EGLOpenGLWindow::getResizeCallback() {
return m_data->m_resizeCallback;
}
void EGLOpenGLWindow::setWheelCallback(b3WheelCallback wheelCallback) {
m_data->m_wheelCallback = wheelCallback;
}
b3WheelCallback EGLOpenGLWindow::getWheelCallback() {
return m_data->m_wheelCallback;
}
void EGLOpenGLWindow::setKeyboardCallback(b3KeyboardCallback keyboardCallback) {
m_data->m_keyboardCallback = keyboardCallback;
}
b3KeyboardCallback EGLOpenGLWindow::getKeyboardCallback() {
return m_data->m_keyboardCallback;
}
void EGLOpenGLWindow::setRenderCallback(b3RenderCallback renderCallback) {}
void EGLOpenGLWindow::setWindowTitle(const char* title) {}
float EGLOpenGLWindow::getRetinaScale() const { return 1.f; }
void EGLOpenGLWindow::setAllowRetina(bool allow) {}
int EGLOpenGLWindow::getWidth() const { return m_data->m_windowWidth; }
int EGLOpenGLWindow::getHeight() const { return m_data->m_windowHeight; }
int EGLOpenGLWindow::fileOpenDialog(char* fileName, int maxFileNameLength) {
return 0;
}
#endif // BT_USE_EGL

View File

@@ -0,0 +1,76 @@
#ifndef EGL_OPENGL_WINDOW_H
#define EGL_OPENGL_WINDOW_H
#ifdef BT_USE_EGL
#define b3gDefaultOpenGLWindow EGLOpenGLWindow
#include "../CommonInterfaces/CommonWindowInterface.h"
class EGLOpenGLWindow : public CommonWindowInterface
{
struct EGLInternalData2* m_data;
bool m_OpenGLInitialized;
bool m_requestedExit;
public:
EGLOpenGLWindow();
virtual ~EGLOpenGLWindow();
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);
virtual void closeWindow();
virtual void runMainLoop();
virtual float getTimeInSeconds();
virtual bool requestedExit() const;
virtual void setRequestExit();
virtual void startRendering();
virtual void endRendering();
virtual bool isModifierKeyPressed(int key);
virtual void setMouseMoveCallback(b3MouseMoveCallback mouseCallback);
virtual b3MouseMoveCallback getMouseMoveCallback();
virtual void setMouseButtonCallback(b3MouseButtonCallback mouseCallback);
virtual b3MouseButtonCallback getMouseButtonCallback();
virtual void setResizeCallback(b3ResizeCallback resizeCallback);
virtual b3ResizeCallback getResizeCallback();
virtual void setWheelCallback(b3WheelCallback wheelCallback);
virtual b3WheelCallback getWheelCallback();
virtual void setKeyboardCallback( b3KeyboardCallback keyboardCallback);
virtual b3KeyboardCallback getKeyboardCallback();
virtual void setRenderCallback( b3RenderCallback renderCallback);
virtual void setWindowTitle(const char* title);
virtual float getRetinaScale() const;
virtual void setAllowRetina(bool allow);
virtual int getWidth() const;
virtual int getHeight() const;
virtual int fileOpenDialog(char* fileName, int maxFileNameLength);
};
#endif //BT_USE_EGL
#endif //EGL_OPENGL_WINDOW_H

File diff suppressed because it is too large Load Diff

View File

@@ -41,10 +41,10 @@ class GLInstancingRenderer : public CommonRenderInterface
int m_upAxis;
bool m_enableBlend;
int registerGraphicsInstanceInternal(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling);
void rebuildGraphicsInstances();
public:
GLInstancingRenderer(int m_maxObjectCapacity, int maxShapeCapacityInBytes = 56*1024*1024);
virtual ~GLInstancingRenderer();
@@ -57,14 +57,15 @@ public:
void InitShaders();
void CleanupShaders();
virtual void removeAllInstances();
virtual void removeGraphicsInstance(int instanceUid);
virtual void updateShape(int shapeIndex, const float* vertices);
///vertices must be in the format x,y,z, nx,ny,nz, u,v
virtual int registerShape(const float* vertices, int numvertices, const int* indices, int numIndices, int primitiveType=B3_GL_TRIANGLES, int textureIndex=-1);
virtual int registerTexture(const unsigned char* texels, int width, int height);
virtual void updateTexture(int textureIndex, const unsigned char* texels);
virtual int registerTexture(const unsigned char* texels, int width, int height, bool flipPixelsY=true);
virtual void updateTexture(int textureIndex, const unsigned char* texels, bool flipPixelsY=true);
virtual void activateTexture(int textureIndex);
@@ -72,9 +73,11 @@ public:
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling);
virtual int registerGraphicsInstance(int shapeIndex, const double* position, const double* quaternion, const double* color, const double* scaling);
void writeTransforms();
virtual bool readSingleInstanceTransformToCPU(float* position, float* orientation, int srcIndex);
virtual void writeSingleInstanceTransformToCPU(const float* position, const float* orientation, int srcIndex);
virtual void writeSingleInstanceTransformToCPU(const double* position, const double* orientation, int srcIndex)
{
@@ -96,11 +99,11 @@ public:
virtual void writeSingleInstanceTransformToGPU(float* position, float* orientation, int srcIndex);
virtual void writeSingleInstanceColorToCPU(float* color, int srcIndex);
virtual void writeSingleInstanceColorToCPU(double* color, int srcIndex);
virtual void writeSingleInstanceColorToCPU(const float* color, int srcIndex);
virtual void writeSingleInstanceColorToCPU(const double* color, int srcIndex);
virtual void writeSingleInstanceScaleToCPU(float* scale, int srcIndex);
virtual void writeSingleInstanceScaleToCPU(double* scale, int srcIndex);
virtual void writeSingleInstanceScaleToCPU(const float* scale, int srcIndex);
virtual void writeSingleInstanceScaleToCPU(const double* scale, int srcIndex);
virtual struct GLInstanceRendererInternalData* getInternalData();
@@ -111,13 +114,17 @@ public:
virtual void drawPoints(const float* positions, const float color[4], int numPoints, int pointStrideInBytes, float pointDrawSize);
virtual void drawPoint(const float* position, const float color[4], float pointSize=1);
virtual void drawPoint(const double* position, const double color[4], double pointDrawSize=1);
virtual void drawTexturedTriangleMesh(float worldPosition[3], float worldOrientation[4], const float* vertices, int numvertices, const unsigned int* indices, int numIndices, float color[4], int textureIndex=-1, int vertexLayout=0);
virtual void updateCamera(int upAxis=1);
virtual const CommonCameraInterface* getActiveCamera() const;
virtual CommonCameraInterface* getActiveCamera();
virtual void setActiveCamera(CommonCameraInterface* cam);
virtual void setLightPosition(const float lightPos[3]);
virtual void setLightPosition(const double lightPos[3]);
virtual void resize(int width, int height);
virtual int getScreenWidth()
{

View File

@@ -13,8 +13,13 @@ struct PrimInternalData
GLint m_positionAttribute;
GLint m_textureAttribute;
GLuint m_vertexBuffer;
GLuint m_vertexArrayObject;
GLuint m_vertexBuffer2;
GLuint m_vertexArrayObject;
GLuint m_vertexArrayObject2;
GLuint m_indexBuffer;
GLuint m_indexBuffer2;
GLuint m_texturehandle;
};

View File

@@ -48,10 +48,20 @@ static const char* fragmentShader3D= \
static unsigned int s_indexData[6] = {0,1,2,0,2,3};
#define MAX_VERTICES2 8192
struct PrimInternalData2
{
PrimInternalData2()
:m_numVerticesText(0),
m_numVerticesRect(0)
{
}
int m_numVerticesText;
int m_numVerticesRect;
PrimVertex m_verticesText[MAX_VERTICES2];
PrimVertex m_verticesRect[MAX_VERTICES2];
};
GLPrimitiveRenderer::GLPrimitiveRenderer(int screenWidth, int screenHeight)
:m_screenWidth(screenWidth),
@@ -59,6 +69,7 @@ m_screenHeight(screenHeight)
{
m_data = new PrimInternalData;
m_data2 = new PrimInternalData2;
m_data->m_shaderProg = gltLoadShaderPair(vertexShader3D,fragmentShader3D);
@@ -95,10 +106,10 @@ void GLPrimitiveRenderer::loadBufferData()
{
PrimVertex vertexData[4] = {
{ PrimVec4(-1, -1, 0.0, 1.0 ), PrimVec4( 1.0, 0.0, 0.0, 1.0 ) ,PrimVec2(0,0)},
{ PrimVec4(-1, 1, 0.0, 1.0 ), PrimVec4( 0.0, 1.0, 0.0, 1.0 ) ,PrimVec2(0,1)},
{ PrimVec4( 1, 1, 0.0, 1.0 ), PrimVec4( 0.0, 0.0, 1.0, 1.0 ) ,PrimVec2(1,1)},
{ PrimVec4( 1, -1, 0.0, 1.0 ), PrimVec4( 1.0, 1.0, 1.0, 1.0 ) ,PrimVec2(1,0)}
PrimVertex( PrimVec4(-1, -1, 0.0, 1.0 ), PrimVec4( 1.0, 0.0, 0.0, 1.0 ) ,PrimVec2(0,0)),
PrimVertex( PrimVec4(-1, 1, 0.0, 1.0 ), PrimVec4( 0.0, 1.0, 0.0, 1.0 ) ,PrimVec2(0,1)),
PrimVertex( PrimVec4( 1, 1, 0.0, 1.0 ), PrimVec4( 0.0, 0.0, 1.0, 1.0 ) ,PrimVec2(1,1)),
PrimVertex( PrimVec4( 1, -1, 0.0, 1.0 ), PrimVec4( 1.0, 1.0, 1.0, 1.0 ) ,PrimVec2(1,0))
};
@@ -109,6 +120,13 @@ void GLPrimitiveRenderer::loadBufferData()
glBindBuffer(GL_ARRAY_BUFFER, m_data->m_vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(PrimVertex), vertexData, GL_DYNAMIC_DRAW);
glGenVertexArrays(1, &m_data->m_vertexArrayObject2);
glBindVertexArray(m_data->m_vertexArrayObject2);
glGenBuffers(1, &m_data->m_vertexBuffer2);
glBindBuffer(GL_ARRAY_BUFFER, m_data->m_vertexBuffer2);
glBufferData(GL_ARRAY_BUFFER, MAX_VERTICES2 * sizeof(PrimVertex), 0, GL_DYNAMIC_DRAW);
assert(glGetError()==GL_NO_ERROR);
@@ -116,7 +134,23 @@ void GLPrimitiveRenderer::loadBufferData()
glGenBuffers(1, &m_data->m_indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_data->m_indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,6*sizeof(int), s_indexData,GL_STATIC_DRAW);
unsigned int indexData[MAX_VERTICES2*2];
int count=0;
for (int i=0;i<MAX_VERTICES2;i+=4)
{
indexData[count++]=i;
indexData[count++]=i+1;
indexData[count++]=i+2;
indexData[count++]=i;
indexData[count++]=i+2;
indexData[count++]=i+3;
}
glGenBuffers(1, &m_data->m_indexBuffer2);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_data->m_indexBuffer2);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,count*sizeof(int), indexData,GL_STATIC_DRAW);
glEnableVertexAttribArray(m_data->m_positionAttribute);
glEnableVertexAttribArray(m_data->m_colourAttribute);
assert(glGetError()==GL_NO_ERROR);
@@ -182,6 +216,7 @@ GLPrimitiveRenderer::~GLPrimitiveRenderer()
glBindTexture(GL_TEXTURE_2D,0);
glDeleteProgram(m_data->m_shaderProg);
delete m_data;
delete m_data2;
}
void GLPrimitiveRenderer::drawLine()
@@ -299,6 +334,180 @@ void GLPrimitiveRenderer::drawTexturedRect3D(const PrimVertex& v0,const PrimVert
}
void GLPrimitiveRenderer::drawTexturedRect3D2Text( bool useRGBA)
{
drawTexturedRect3D2(&m_data2->m_verticesText[0],m_data2->m_numVerticesText,useRGBA);
m_data2->m_numVerticesText = 0;
}
void GLPrimitiveRenderer::drawTexturedRect3D2( PrimVertex* vertices, int numVertices, bool useRGBA)
{
//B3_PROFILE("drawTexturedRect3D2");
if (numVertices==0)
{
return;
}
//B3_PROFILE("GLPrimitiveRenderer::drawTexturedRect3D");
assert(glGetError()==GL_NO_ERROR);
float identity[16]={1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1};
glUseProgram(m_data->m_shaderProg);
glUniformMatrix4fv(m_data->m_viewmatUniform, 1, false, identity);
glUniformMatrix4fv(m_data->m_projMatUniform, 1, false, identity);
assert(glGetError()==GL_NO_ERROR);
glBindBuffer(GL_ARRAY_BUFFER, m_data->m_vertexBuffer2);
glBindVertexArray(m_data->m_vertexArrayObject2);
bool useFiltering = false;
if (useFiltering)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
} else
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
/* PrimVertex vertexData[4] = {
v0,v1,v2,v3
};
*/
glBufferSubData(GL_ARRAY_BUFFER, 0,numVertices * sizeof(PrimVertex), vertices);
assert(glGetError()==GL_NO_ERROR);
PrimVec2 p( 0.f,0.f);//?b?0.5f * sinf(timeValue), 0.5f * cosf(timeValue) );
if (useRGBA)
{
p.p[0] = 1.f;
p.p[1] = 1.f;
}
glUniform2fv(m_data->m_positionUniform, 1, (const GLfloat *)&p);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
assert(glGetError()==GL_NO_ERROR);
glEnableVertexAttribArray(m_data->m_positionAttribute);
assert(glGetError()==GL_NO_ERROR);
glEnableVertexAttribArray(m_data->m_colourAttribute);
assert(glGetError()==GL_NO_ERROR);
glEnableVertexAttribArray(m_data->m_textureAttribute);
glVertexAttribPointer(m_data->m_positionAttribute, 4, GL_FLOAT, GL_FALSE, sizeof(PrimVertex), (const GLvoid *)0);
glVertexAttribPointer(m_data->m_colourAttribute , 4, GL_FLOAT, GL_FALSE, sizeof(PrimVertex), (const GLvoid *)sizeof(PrimVec4));
glVertexAttribPointer(m_data->m_textureAttribute , 2, GL_FLOAT, GL_FALSE, sizeof(PrimVertex), (const GLvoid *)(sizeof(PrimVec4)+sizeof(PrimVec4)));
assert(glGetError()==GL_NO_ERROR);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_data->m_indexBuffer2);
//glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
int indexCount = (numVertices/4)*6;
assert(glGetError()==GL_NO_ERROR);
glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, 0);
assert(glGetError()==GL_NO_ERROR);
glBindVertexArray(0);
assert(glGetError()==GL_NO_ERROR);
glBindBuffer(GL_ARRAY_BUFFER, 0);
assert(glGetError()==GL_NO_ERROR);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
assert(glGetError()==GL_NO_ERROR);
//glDisableVertexAttribArray(m_data->m_textureAttribute);
assert(glGetError()==GL_NO_ERROR);
glUseProgram(0);
assert(glGetError()==GL_NO_ERROR);
}
void GLPrimitiveRenderer::drawTexturedRect2a(float x0, float y0, float x1, float y1, float color[4], float u0,float v0, float u1, float v1, int useRGBA)
{
PrimVertex vertexData[4] = {
PrimVertex( PrimVec4(-1.f+2.f*x0/float(m_screenWidth), 1.f-2.f*y0/float(m_screenHeight), 0.f, 1.f ), PrimVec4( color[0], color[1], color[2], color[3] ) ,PrimVec2(u0,v0)),
PrimVertex( PrimVec4(-1.f+2.f*x0/float(m_screenWidth), 1.f-2.f*y1/float(m_screenHeight), 0.f, 1.f ), PrimVec4( color[0], color[1], color[2], color[3] ) ,PrimVec2(u0,v1)),
PrimVertex(PrimVec4( -1.f+2.f*x1/float(m_screenWidth), 1.f-2.f*y1/float(m_screenHeight), 0.f, 1.f ), PrimVec4(color[0], color[1], color[2], color[3]) ,PrimVec2(u1,v1)),
PrimVertex( PrimVec4( -1.f+2.f*x1/float(m_screenWidth), 1.f-2.f*y0/float(m_screenHeight), 0.f, 1.f ), PrimVec4( color[0], color[1], color[2], color[3] ) ,PrimVec2(u1,v0))
};
// int sz = m_data2->m_numVerticesText;
m_data2->m_verticesRect[m_data2->m_numVerticesRect++]=vertexData[0];
m_data2->m_verticesRect[m_data2->m_numVerticesRect++]=vertexData[1];
m_data2->m_verticesRect[m_data2->m_numVerticesRect++]=vertexData[2];
m_data2->m_verticesRect[m_data2->m_numVerticesRect++]=vertexData[3];
if (m_data2->m_numVerticesRect>=MAX_VERTICES2)
{
flushBatchedRects();
}
}
void GLPrimitiveRenderer::flushBatchedRects()
{
if (m_data2->m_numVerticesRect==0)
return;
glActiveTexture(GL_TEXTURE0);
assert(glGetError()==GL_NO_ERROR);
glBindTexture(GL_TEXTURE_2D,m_data->m_texturehandle);
drawTexturedRect3D2(m_data2->m_verticesRect, m_data2->m_numVerticesRect,0);
m_data2->m_numVerticesRect=0;
}
void GLPrimitiveRenderer::drawTexturedRect2(float x0, float y0, float x1, float y1, float color[4], float u0,float v0, float u1, float v1, int useRGBA)
{
PrimVertex vertexData[4] = {
PrimVertex( PrimVec4(-1.f+2.f*x0/float(m_screenWidth), 1.f-2.f*y0/float(m_screenHeight), 0.f, 1.f ), PrimVec4( color[0], color[1], color[2], color[3] ) ,PrimVec2(u0,v0)),
PrimVertex( PrimVec4(-1.f+2.f*x0/float(m_screenWidth), 1.f-2.f*y1/float(m_screenHeight), 0.f, 1.f ), PrimVec4( color[0], color[1], color[2], color[3] ) ,PrimVec2(u0,v1)),
PrimVertex( PrimVec4( -1.f+2.f*x1/float(m_screenWidth), 1.f-2.f*y1/float(m_screenHeight), 0.f, 1.f ), PrimVec4(color[0], color[1], color[2], color[3]) ,PrimVec2(u1,v1)),
PrimVertex( PrimVec4( -1.f+2.f*x1/float(m_screenWidth), 1.f-2.f*y0/float(m_screenHeight), 0.f, 1.f ), PrimVec4( color[0], color[1], color[2], color[3] ) ,PrimVec2(u1,v0))
};
// int sz = m_data2->m_numVerticesText;
m_data2->m_verticesText[m_data2->m_numVerticesText++]=vertexData[0];
m_data2->m_verticesText[m_data2->m_numVerticesText++]=vertexData[1];
m_data2->m_verticesText[m_data2->m_numVerticesText++]=vertexData[2];
m_data2->m_verticesText[m_data2->m_numVerticesText++]=vertexData[3];
if (m_data2->m_numVerticesText>=MAX_VERTICES2)
{
drawTexturedRect3D2(m_data2->m_verticesText, m_data2->m_numVerticesText,useRGBA);
m_data2->m_numVerticesText=0;
}
}
void GLPrimitiveRenderer::drawTexturedRect(float x0, float y0, float x1, float y1, float color[4], float u0,float v0, float u1, float v1, int useRGBA)
{
@@ -307,10 +516,10 @@ void GLPrimitiveRenderer::drawTexturedRect(float x0, float y0, float x1, float y
0,0,1,0,
0,0,0,1};
PrimVertex vertexData[4] = {
{ PrimVec4(-1.f+2.f*x0/float(m_screenWidth), 1.f-2.f*y0/float(m_screenHeight), 0.f, 1.f ), PrimVec4( color[0], color[1], color[2], color[3] ) ,PrimVec2(u0,v0)},
{ PrimVec4(-1.f+2.f*x0/float(m_screenWidth), 1.f-2.f*y1/float(m_screenHeight), 0.f, 1.f ), PrimVec4( color[0], color[1], color[2], color[3] ) ,PrimVec2(u0,v1)},
{ PrimVec4( -1.f+2.f*x1/float(m_screenWidth), 1.f-2.f*y1/float(m_screenHeight), 0.f, 1.f ), PrimVec4(color[0], color[1], color[2], color[3]) ,PrimVec2(u1,v1)},
{ PrimVec4( -1.f+2.f*x1/float(m_screenWidth), 1.f-2.f*y0/float(m_screenHeight), 0.f, 1.f ), PrimVec4( color[0], color[1], color[2], color[3] ) ,PrimVec2(u1,v0)}
PrimVertex( PrimVec4(-1.f+2.f*x0/float(m_screenWidth), 1.f-2.f*y0/float(m_screenHeight), 0.f, 1.f ), PrimVec4( color[0], color[1], color[2], color[3] ) ,PrimVec2(u0,v0)),
PrimVertex( PrimVec4(-1.f+2.f*x0/float(m_screenWidth), 1.f-2.f*y1/float(m_screenHeight), 0.f, 1.f ), PrimVec4( color[0], color[1], color[2], color[3] ) ,PrimVec2(u0,v1)),
PrimVertex( PrimVec4( -1.f+2.f*x1/float(m_screenWidth), 1.f-2.f*y1/float(m_screenHeight), 0.f, 1.f ), PrimVec4(color[0], color[1], color[2], color[3]) ,PrimVec2(u1,v1)),
PrimVertex( PrimVec4( -1.f+2.f*x1/float(m_screenWidth), 1.f-2.f*y0/float(m_screenHeight), 0.f, 1.f ), PrimVec4( color[0], color[1], color[2], color[3] ) ,PrimVec2(u1,v0))
};
drawTexturedRect3D(vertexData[0],vertexData[1],vertexData[2],vertexData[3],identity,identity,useRGBA);

View File

@@ -5,6 +5,8 @@
struct PrimVec2
{
PrimVec2()
{}
PrimVec2(float x, float y)
{
p[0] = x;
@@ -28,12 +30,21 @@ struct PrimVec4
float p[4];
};
typedef struct
struct PrimVertex
{
PrimVertex(const PrimVec4 & p, const PrimVec4 & c, const PrimVec2& u)
:position(p),
colour(c),
uv(u)
{
}
PrimVertex()
{}
PrimVec4 position;
PrimVec4 colour;
PrimVec2 uv;
} PrimVertex;
} ;
class GLPrimitiveRenderer
@@ -42,7 +53,7 @@ class GLPrimitiveRenderer
int m_screenHeight;
struct PrimInternalData* m_data;
struct PrimInternalData2* m_data2;
void loadBufferData();
public:
@@ -56,6 +67,14 @@ public:
void drawLine();//float from[4], float to[4], float color[4]);
void setScreenSize(int width, int height);
void drawTexturedRect2(float x0, float y0, float x1, float y1, float color[4], float u0,float v0, float u1, float v1, int useRGBA=0);
void drawTexturedRect2a(float x0, float y0, float x1, float y1, float color[4], float u0,float v0, float u1, float v1, int useRGBA=0);
void flushBatchedRects();
void drawTexturedRect3D2Text(bool useRGBA = true);
void drawTexturedRect3D2(PrimVertex* vertices, int numVertices, bool useRGBA = true);
PrimInternalData* getData()
{
return m_data;

View File

@@ -161,6 +161,7 @@ public:
virtual void StartClip()
{
if (m_useTrueTypeFont)
sth_flush_draw(m_font);
Gwen::Rect rect = ClipRegion();
@@ -181,6 +182,7 @@ public:
virtual void EndClip()
{
if (m_useTrueTypeFont)
sth_flush_draw(m_font);
glDisable( GL_SCISSOR_TEST );
@@ -196,16 +198,23 @@ public:
}
virtual void DrawFilledRect( Gwen::Rect rect )
{
// BT_PROFILE("GWEN_DrawFilledRect");
Translate( rect );
m_primitiveRenderer->drawRect(rect.x, rect.y+m_yOffset, rect.x+rect.w, rect.y+rect.h+m_yOffset, m_currentColor);
m_primitiveRenderer->drawRect(rect.x, rect.y+m_yOffset,
rect.x+rect.w, rect.y+rect.h+m_yOffset, m_currentColor);
// m_primitiveRenderer->drawTexturedRect2a(rect.x, rect.y+m_yOffset,
// rect.x+rect.w, rect.y+rect.h+m_yOffset, m_currentColor,0,0,1,1);
// m_yOffset+=rect.h+10;
}
void RenderText( Gwen::Font* pFont, Gwen::Point rasterPos, const Gwen::UnicodeString& text )
{
// BT_PROFILE("GWEN_RenderText");
Gwen::String str = Gwen::Utility::UnicodeToString(text);
const char* unicodeText = (const char*)str.c_str();
@@ -246,32 +255,33 @@ public:
glBindTexture(GL_TEXTURE_2D,m_fontTextureId);
float width = r.x;
while (unicodeText[pos])
{
int c = unicodeText[pos];
r.h = m_currentFont->m_CharHeight;
r.w = m_currentFont->m_CharWidth[c]+extraSpacing;
Gwen::Rect rect = r;
Translate( rect );
m_primitiveRenderer->drawTexturedRect(rect.x, rect.y+m_yOffset, rect.x+rect.w, rect.y+rect.h+m_yOffset, m_currentColor,m_currentFont->m_CharU0[c],m_currentFont->m_CharV0[c],m_currentFont->m_CharU1[c],m_currentFont->m_CharV1[c]);
m_primitiveRenderer->drawTexturedRect2(rect.x, rect.y+m_yOffset, rect.x+rect.w, rect.y+rect.h+m_yOffset, m_currentColor,m_currentFont->m_CharU0[c],m_currentFont->m_CharV0[c],m_currentFont->m_CharU1[c],m_currentFont->m_CharV1[c]);
//DrawTexturedRect(0,r,m_currentFont->m_CharU0[c],m_currentFont->m_CharV0[c],m_currentFont->m_CharU1[c],m_currentFont->m_CharV1[c]);
// DrawFilledRect(r);
width += r.w;
r.x = width;
pos++;
}
{
m_primitiveRenderer->drawTexturedRect3D2Text(false);
}
glBindTexture(GL_TEXTURE_2D,0);
}
}
Gwen::Point MeasureText( Gwen::Font* pFont, const Gwen::UnicodeString& text )
{
// BT_PROFILE("GWEN_MeasureText");
Gwen::String str = Gwen::Utility::UnicodeToString(text);
const char* unicodeText = (const char*)str.c_str();
@@ -341,7 +351,7 @@ public:
virtual void DrawTexturedRect( Gwen::Texture* pTexture, Gwen::Rect rect, float u1=0.0f, float v1=0.0f, float u2=1.0f, float v2=1.0f )
{
// BT_PROFILE("DrawTexturedRect");
Translate( rect );
//float eraseColor[4] = {0,0,0,0};

View File

@@ -0,0 +1,195 @@
#ifdef __APPLE__
#include "MacOpenGLWindow.h"
#include "OpenGLInclude.h"
#include "MacOpenGLWindowObjC.h"
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <string.h>
MacOpenGLWindow::MacOpenGLWindow()
:m_internalData(0)
{
m_internalData = Mac_createData();
}
MacOpenGLWindow::~MacOpenGLWindow()
{
Mac_destroyData(m_internalData);
}
void MacOpenGLWindow::closeWindow()
{
Mac_destroyData(m_internalData);
m_internalData = Mac_createData();
}
bool MacOpenGLWindow::isModifierKeyPressed(int key)
{
return Mac_isModifierKeyPressed(m_internalData, key);
}
float MacOpenGLWindow::getTimeInSeconds()
{
return 0.f;
}
void MacOpenGLWindow::setRenderCallback( b3RenderCallback renderCallback)
{
}
void MacOpenGLWindow::setWindowTitle(const char* windowTitle)
{
Mac_setWindowTitle(m_internalData, windowTitle);
}
void MacOpenGLWindow::createWindow(const b3gWindowConstructionInfo& ci)
{
MacWindowConstructionInfo windowCI;
windowCI.m_width = ci.m_width;
windowCI.m_height = ci.m_height;
windowCI.m_fullscreen = ci.m_fullscreen;
windowCI.m_colorBitsPerPixel = ci.m_colorBitsPerPixel;
windowCI.m_windowHandle = ci.m_windowHandle;
windowCI.m_title = ci.m_title;
windowCI.m_openglVersion = ci.m_openglVersion;
windowCI.m_allowRetina = true;
Mac_createWindow(m_internalData,&windowCI);
}
void MacOpenGLWindow::runMainLoop()
{
}
void MacOpenGLWindow::startRendering()
{
Mac_updateWindow(m_internalData);
}
void MacOpenGLWindow::endRendering()
{
Mac_swapBuffer(m_internalData);
}
bool MacOpenGLWindow::requestedExit() const
{
return Mac_requestedExit(m_internalData);
}
void MacOpenGLWindow::setRequestExit()
{
Mac_setRequestExit(m_internalData);
}
int MacOpenGLWindow::fileOpenDialog(char* filename, int maxNameLength)
{
return Mac_fileOpenDialog(filename, maxNameLength);
}
void MacOpenGLWindow::getMouseCoordinates(int& x, int& y)
{
int* xPtr=&x;
int* yPtr=&y;
Mac_getMouseCoordinates(m_internalData,xPtr,yPtr);
}
int MacOpenGLWindow::getWidth() const
{
return Mac_getWidth(m_internalData);
}
int MacOpenGLWindow::getHeight() const
{
return Mac_getHeight(m_internalData);
}
void MacOpenGLWindow::setResizeCallback(b3ResizeCallback resizeCallback)
{
Mac_setResizeCallback(m_internalData,resizeCallback);
}
b3ResizeCallback MacOpenGLWindow::getResizeCallback()
{
return Mac_getResizeCallback(m_internalData);
}
void MacOpenGLWindow::setMouseButtonCallback(b3MouseButtonCallback mouseCallback)
{
Mac_setMouseButtonCallback(m_internalData, mouseCallback);
}
void MacOpenGLWindow::setMouseMoveCallback(b3MouseMoveCallback mouseCallback)
{
Mac_setMouseMoveCallback(m_internalData,mouseCallback);
}
void MacOpenGLWindow::setKeyboardCallback( b3KeyboardCallback keyboardCallback)
{
Mac_setKeyboardCallback(m_internalData,keyboardCallback);
}
b3MouseMoveCallback MacOpenGLWindow::getMouseMoveCallback()
{
return Mac_getMouseMoveCallback(m_internalData);
}
b3MouseButtonCallback MacOpenGLWindow::getMouseButtonCallback()
{
return Mac_getMouseButtonCallback(m_internalData);
}
void MacOpenGLWindow::setWheelCallback (b3WheelCallback wheelCallback)
{
Mac_setWheelCallback(m_internalData,wheelCallback);
}
b3WheelCallback MacOpenGLWindow::getWheelCallback()
{
return Mac_getWheelCallback(m_internalData);
}
b3KeyboardCallback MacOpenGLWindow::getKeyboardCallback()
{
return Mac_getKeyboardCallback(m_internalData);
}
float MacOpenGLWindow::getRetinaScale() const
{
return Mac_getRetinaScale(m_internalData);
}
void MacOpenGLWindow::setAllowRetina(bool allow)
{
Mac_setAllowRetina(m_internalData, allow);
}
#endif //__APPLE__

View File

@@ -8,18 +8,6 @@
class MacOpenGLWindow : public CommonWindowInterface
{
struct MacOpenGLWindowInternalData* m_internalData;
float m_mouseX;
float m_mouseY;
int m_modifierFlags;
b3MouseButtonCallback m_mouseButtonCallback;
b3MouseMoveCallback m_mouseMoveCallback;
b3WheelCallback m_wheelCallback;
b3KeyboardCallback m_keyboardCallback;
b3RenderCallback m_renderCallback;
float m_retinaScaleFactor;
bool m_allowRetina;
public:
@@ -34,7 +22,7 @@ public:
void endRendering();//swap buffers
virtual bool requestedExit() const;
virtual bool requestedExit() const;
virtual void setRequestExit();
@@ -42,59 +30,32 @@ public:
void runMainLoop();
virtual bool isModifierKeyPressed(int key);
virtual bool isModifierKeyPressed(int key);
void setMouseButtonCallback(b3MouseButtonCallback mouseCallback)
{
m_mouseButtonCallback = mouseCallback;
}
void setMouseButtonCallback(b3MouseButtonCallback mouseCallback);
void setMouseMoveCallback(b3MouseMoveCallback mouseCallback)
{
m_mouseMoveCallback = mouseCallback;
}
void setMouseMoveCallback(b3MouseMoveCallback mouseCallback);
void setResizeCallback(b3ResizeCallback resizeCallback);
void setKeyboardCallback( b3KeyboardCallback keyboardCallback)
{
m_keyboardCallback = keyboardCallback;
}
void setKeyboardCallback( b3KeyboardCallback keyboardCallback);
virtual b3MouseMoveCallback getMouseMoveCallback();
virtual b3MouseButtonCallback getMouseButtonCallback();
virtual b3MouseMoveCallback getMouseMoveCallback()
{
return m_mouseMoveCallback;
}
virtual b3MouseButtonCallback getMouseButtonCallback()
{
return m_mouseButtonCallback;
}
virtual b3ResizeCallback getResizeCallback();
virtual b3WheelCallback getWheelCallback()
{
return m_wheelCallback;
}
virtual b3WheelCallback getWheelCallback();
b3KeyboardCallback getKeyboardCallback()
{
return m_keyboardCallback;
}
b3KeyboardCallback getKeyboardCallback();
void setWheelCallback (b3WheelCallback wheelCallback);
float getRetinaScale() const;
void setWheelCallback (b3WheelCallback wheelCallback)
{
m_wheelCallback = wheelCallback;
}
float getRetinaScale() const
{
return m_retinaScaleFactor;
}
virtual void setAllowRetina(bool allow)
{
m_allowRetina = allow;
}
virtual void setAllowRetina(bool allow);
virtual void createWindow(const b3gWindowConstructionInfo& ci);

View File

@@ -0,0 +1,77 @@
#ifndef MAC_OPENGL_WINDOW_OBJC_H
#define MAC_OPENGL_WINDOW_OBJC_H
struct MacOpenGLWindowInternalData;
#include "../CommonInterfaces/CommonCallbacks.h"
struct MacWindowConstructionInfo
{
int m_width;
int m_height;
int m_fullscreen;
int m_colorBitsPerPixel;
void* m_windowHandle;
const char* m_title;
int m_openglVersion;
int m_allowRetina;
};
enum
{
MY_MAC_ALTKEY=1,
MY_MAC_SHIFTKEY=2,
MY_MAC_CONTROL_KEY=4
};
#ifdef __cplusplus
extern "C" {
#endif
struct MacOpenGLWindowInternalData* Mac_createData();
void Mac_destroyData(struct MacOpenGLWindowInternalData* data);
int Mac_createWindow(struct MacOpenGLWindowInternalData* m_internalData,struct MacWindowConstructionInfo* ci);
void Mac_setWindowTitle(struct MacOpenGLWindowInternalData* data, const char* windowTitle);
int Mac_updateWindow(struct MacOpenGLWindowInternalData* m_internalData);
void Mac_swapBuffer(struct MacOpenGLWindowInternalData* m_internalData);
int Mac_requestedExit(struct MacOpenGLWindowInternalData* m_internalData);
void Mac_setRequestExit(struct MacOpenGLWindowInternalData* m_internalData);
float Mac_getRetinaScale(struct MacOpenGLWindowInternalData* m_internalData);
void Mac_setAllowRetina(struct MacOpenGLWindowInternalData* m_internalData, int allow);
int Mac_getWidth(struct MacOpenGLWindowInternalData* m_internalData);
int Mac_getHeight(struct MacOpenGLWindowInternalData* m_internalData);
int Mac_fileOpenDialog(char* filename, int maxNameLength);
void Mac_setKeyboardCallback( struct MacOpenGLWindowInternalData* m_internalData, b3KeyboardCallback keyboardCallback);
b3KeyboardCallback Mac_getKeyboardCallback(struct MacOpenGLWindowInternalData* m_internalData);
int Mac_isModifierKeyPressed(struct MacOpenGLWindowInternalData* m_internalData, int key);
void Mac_setMouseButtonCallback(struct MacOpenGLWindowInternalData* m_internalData, b3MouseButtonCallback mouseCallback);
b3MouseButtonCallback Mac_getMouseButtonCallback(struct MacOpenGLWindowInternalData* m_internalData);
void Mac_getMouseCoordinates(struct MacOpenGLWindowInternalData* m_internalData, int* xPtr, int* yPtr);
void Mac_setMouseMoveCallback(struct MacOpenGLWindowInternalData* m_internalData, b3MouseMoveCallback mouseCallback);
b3MouseMoveCallback Mac_getMouseMoveCallback(struct MacOpenGLWindowInternalData* m_internalData);
void Mac_setWheelCallback(struct MacOpenGLWindowInternalData* m_internalData, b3WheelCallback wheelCallback);
b3WheelCallback Mac_getWheelCallback(struct MacOpenGLWindowInternalData* m_internalData);
void Mac_setResizeCallback(struct MacOpenGLWindowInternalData* m_internalData, b3ResizeCallback resizeCallback);
b3ResizeCallback Mac_getResizeCallback(struct MacOpenGLWindowInternalData* m_internalData);
//void Mac_setRenderCallback(struct MacOpenGLWindowInternalData* m_internalData, b3RenderCallback renderCallback);
#ifdef __cplusplus
}
#endif
#endif //MAC_OPENGL_WINDOW_OBJC_H

View File

@@ -27,8 +27,14 @@ subject to the following restrictions:
#ifdef GLEW_STATIC
#include "CustomGL/glew.h"
#else
#ifdef NO_GLEW
#define GL_GLEXT_LEGACY
#include "third_party/GL/gl/include/GL/gl.h"
#include "third_party/GL/gl/include/GL/glext.h"
#else
#include <GL/glew.h>
#endif//GLEW_STATIC
#endif //NO_GLEW
#endif //GLEW_STATIC
#ifdef _WINDOWS
#include <windows.h>

View File

@@ -34,7 +34,13 @@ subject to the following restrictions:
#ifdef GLEW_STATIC
#include "CustomGL/glew.h"
#else
#ifdef NO_GLEW
#define GL_GLEXT_LEGACY
#include "third_party/GL/gl/include/GL/gl.h"
#include "third_party/GL/gl/include/GL/glext.h"
#else
#include <GL/glew.h>
#endif //NO_GLEW
#endif //GLEW_STATIC
#ifdef _WINDOWS

View File

@@ -23,10 +23,12 @@ out vec4 color;
void main(void)
{
vec4 texel = fragment.color*texture(Diffuse,vert.texcoord);
vec4 texel = fragment.color*texture(Diffuse,vert.texcoord);
vec3 ct,cf;
float intensity,at,af;
if (fragment.color.w==0)
discard;
intensity = 0.5+0.5*clamp( dot( normalize(normal),lightDir ), -1,1 );
af = 1.0;
@@ -39,10 +41,11 @@ void main(void)
float visibility = texture(shadowMap, vec3(ShadowCoord.xy,(ShadowCoord.z)/ShadowCoord.w));
if (intensity<0.5)
visibility = 0;
intensity = 0.7*intensity + 0.3*intensity*visibility;
cf = intensity*(vec3(1.0,1.0,1.0)-ambient)+ambient;
color = vec4(ct * cf, fragment.color.w);
}

View File

@@ -17,10 +17,11 @@ static const char* useShadowMapInstancingFragmentShader= \
"out vec4 color;\n"
"void main(void)\n"
"{\n"
" vec4 texel = fragment.color*texture(Diffuse,vert.texcoord);\n"
" vec4 texel = fragment.color*texture(Diffuse,vert.texcoord);\n"
" vec3 ct,cf;\n"
" float intensity,at,af;\n"
" \n"
" if (fragment.color.w==0)\n"
" discard;\n"
" intensity = 0.5+0.5*clamp( dot( normalize(normal),lightDir ), -1,1 );\n"
" \n"
" af = 1.0;\n"
@@ -32,11 +33,11 @@ static const char* useShadowMapInstancingFragmentShader= \
" \n"
" \n"
" float visibility = texture(shadowMap, vec3(ShadowCoord.xy,(ShadowCoord.z)/ShadowCoord.w));\n"
" \n"
" if (intensity<0.5)\n"
" visibility = 0;\n"
" intensity = 0.7*intensity + 0.3*intensity*visibility;\n"
" \n"
" cf = intensity*(vec3(1.0,1.0,1.0)-ambient)+ambient;\n"
" \n"
" color = vec4(ct * cf, fragment.color.w);\n"
"}\n"
;

File diff suppressed because it is too large Load Diff

View File

@@ -68,9 +68,26 @@ void SimpleCamera::setVRCamera(const float viewMat[16], const float projectionMa
{
m_data->m_viewMatrixVR[i] = viewMat[i];
m_data->m_projectionMatrixVR[i] = projectionMatrix[i];
m_data->m_frustumZNear = m_data->m_projectionMatrixVR[14]/(m_data->m_projectionMatrixVR[10]-1);
m_data->m_frustumZFar = m_data->m_projectionMatrixVR[14]/(m_data->m_projectionMatrixVR[10]+1);
}
}
bool SimpleCamera::getVRCamera(float viewMat[16], float projectionMatrix[16])
{
if (m_data->m_enableVR)
{
for (int i=0;i<16;i++)
{
viewMat[i] = m_data->m_viewMatrixVR[i];
projectionMatrix[i] = m_data->m_projectionMatrixVR[i];
}
}
return false;
}
void SimpleCamera::disableVRCamera()
{
m_data->m_enableVR = false;
@@ -331,11 +348,37 @@ void SimpleCamera::setCameraUpVector(float x,float y ,float z)
void SimpleCamera::getCameraUpVector(float up[3]) const
{
up[0] = float(m_data->m_cameraUp[0]);
up[1] = float(m_data->m_cameraUp[1]);
up[2] = float(m_data->m_cameraUp[2]);
if (m_data->m_enableVR)
{
float viewMatTotal[16];
getCameraViewMatrix(viewMatTotal);
up[0] = viewMatTotal[0];
up[1] = viewMatTotal[4];
up[2] = viewMatTotal[8];
} else
{
up[0] = float(m_data->m_cameraUp[0]);
up[1] = float(m_data->m_cameraUp[1]);
up[2] = float(m_data->m_cameraUp[2]);
}
}
void SimpleCamera::getCameraForwardVector(float fwd[3]) const
{
if (m_data->m_enableVR)
{
float viewMatTotal[16];
getCameraViewMatrix(viewMatTotal);
fwd[0] = viewMatTotal[2];
fwd[1] = viewMatTotal[6];
fwd[2] = viewMatTotal[10];
} else
{
fwd[0] = float(m_data->m_cameraForward[0]);
fwd[1] = float(m_data->m_cameraForward[1]);
fwd[2] = float(m_data->m_cameraForward[2]);
}
}
void SimpleCamera::setCameraYaw(float yaw)
{
@@ -368,3 +411,23 @@ float SimpleCamera::getAspectRatio() const
{
return m_data->m_aspect;
}
float SimpleCamera::getCameraFrustumFar() const
{
return m_data->m_frustumZFar;
}
float SimpleCamera::getCameraFrustumNear() const
{
return m_data->m_frustumZNear;
}
void SimpleCamera::setCameraFrustumFar(float far)
{
m_data->m_frustumZFar = far;
}
void SimpleCamera::setCameraFrustumNear(float near)
{
m_data->m_frustumZNear = near;
}

View File

@@ -15,6 +15,8 @@ struct SimpleCamera : public CommonCameraInterface
virtual void getCameraViewMatrix(float m[16]) const;
virtual void setVRCamera(const float viewMat[16], const float projectionMatrix[16]);
virtual bool getVRCamera(float viewMat[16], float projectionMatrix[16]);
virtual void setVRCameraOffsetTransform(const float offset[16]);
virtual void disableVRCamera();
@@ -33,6 +35,10 @@ struct SimpleCamera : public CommonCameraInterface
virtual void setCameraUpVector(float x,float y, float z);
void getCameraUpVector(float up[3]) const;
void getCameraForwardVector(float fwd[3]) const;
///the setCameraUpAxis will call the 'setCameraUpVector' and 'setCameraForwardVector'
virtual void setCameraUpAxis(int axis);
virtual int getCameraUpAxis() const;
@@ -45,6 +51,12 @@ struct SimpleCamera : public CommonCameraInterface
virtual void setAspectRatio(float ratio);
virtual float getAspectRatio() const;
virtual float getCameraFrustumFar() const;
virtual float getCameraFrustumNear() const;
virtual void setCameraFrustumFar(float far);
virtual void setCameraFrustumNear(float near);
};
#endif //SIMPLE_CAMERA_H
#endif //SIMPLE_CAMERA_H

View File

@@ -1,15 +1,18 @@
#include "SimpleOpenGL2App.h"
#define USE_OPENGL2
#include "OpenGLInclude.h"
#include "ShapeData.h"
#include "Bullet3Common/b3Logging.h"//b3Assert?
#include "Bullet3Common/b3Scalar.h"
#include "Bullet3Common/b3AlignedObjectArray.h"
#include "Bullet3Common/b3Vector3.h"
#include "Bullet3Common/b3Quaternion.h"
#include "../CommonInterfaces/CommonRenderInterface.h"
#include "../OpenGLWindow/GLPrimitiveRenderer.h"
#include "GLInstanceGraphicsShape.h"
#include "stdlib.h"
#include "TwFonts.h"
#include "SimpleOpenGL2Renderer.h"
#ifdef __APPLE__
#include "MacOpenGLWindow.h"
#else
@@ -20,7 +23,11 @@
#include "Win32OpenGLWindow.h"
#else
//let's cross the fingers it is Linux/X11
#ifdef BT_USE_EGL
#include "EGLOpenGLWindow.h"
#else
#include "X11OpenGLWindow.h"
#endif //BT_USE_EGL
#endif //_WIN32
#endif//__APPLE__
#include <stdio.h>
@@ -115,25 +122,27 @@ SimpleOpenGL2App::SimpleOpenGL2App(const char* title, int width, int height)
m_window->setWindowTitle(title);
#ifndef NO_GLEW
#ifndef __APPLE__
#ifndef _WIN32
//some Linux implementations need the 'glewExperimental' to be true
//some Linux implementations need the 'glewExperimental' to be true
glewExperimental = GL_TRUE;
#endif
#endif //_WIN32
if (glewInit() != GLEW_OK)
{
{
b3Error("glewInit failed");
exit(1);
}
exit(1);
}
if (!GLEW_VERSION_2_1) // check that the machine supports the 2.1 API.
{
b3Error("GLEW_VERSION_2_1 needs to support 2_1");
exit(1); // or handle the error in a nicer way
}
#endif
{
b3Error("GLEW_VERSION_2_1 needs to support 2_1");
exit(1); // or handle the error in a nicer way
}
#endif //__APPLE__
#endif //NO_GLEW
TwGenerateDefaultFonts();
@@ -155,13 +164,13 @@ SimpleOpenGL2App::SimpleOpenGL2App(const char* title, int width, int height)
b3Assert(glGetError() ==GL_NO_ERROR);
//m_instancingRenderer = new GLInstancingRenderer(128*1024,32*1024*1024);
//m_instancingRenderer->init();
//m_instancingRenderer->resize(width,height);
//m_renderer = new GLInstancingRenderer(128*1024,32*1024*1024);
//m_renderer->init();
//m_renderer->resize(width,height);
b3Assert(glGetError() ==GL_NO_ERROR);
//m_instancingRenderer->InitShaders();
//m_renderer->InitShaders();
m_window->setMouseMoveCallback(Simple2MouseMoveCallback);
m_window->setMouseButtonCallback(Simple2MouseButtonCallback);
@@ -169,6 +178,8 @@ SimpleOpenGL2App::SimpleOpenGL2App(const char* title, int width, int height)
m_window->setWheelCallback(Simple2WheelCallback);
m_window->setResizeCallback(Simple2ResizeCallback);
m_renderer = new SimpleOpenGL2Renderer(width,height);
}
SimpleOpenGL2App::~SimpleOpenGL2App()
@@ -269,7 +280,7 @@ void SimpleOpenGL2App::drawGrid(DrawGridData data)
//we don't use drawPoints because all points would have the same color
// b3Vector3 points[3] = { b3MakeVector3(1, 0, 0), b3MakeVector3(0, 1, 0), b3MakeVector3(0, 0, 1) };
// m_instancingRenderer->drawPoints(&points[0].x, b3MakeVector3(1, 0, 0), 3, sizeof(b3Vector3), 6);
// m_renderer->drawPoints(&points[0].x, b3MakeVector3(1, 0, 0), 3, sizeof(b3Vector3), 6);
}
void SimpleOpenGL2App::setUpAxis(int axis)
{
@@ -286,13 +297,14 @@ void SimpleOpenGL2App::swapBuffer()
m_window->startRendering();
}
void SimpleOpenGL2App::drawText( const char* txt, int posX, int posY, float size)
void SimpleOpenGL2App::drawText( const char* txt, int posXi, int posYi, float size, float colorRGBA[4])
{
}
static void restoreOpenGLState()
static void restoreOpenGLState()
{
@@ -328,6 +340,11 @@ void SimpleOpenGL2App::drawText( const char* txt, int posX, int posY, float size
}
void SimpleOpenGL2App::drawText3D( const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag)
{
}
void SimpleOpenGL2App::drawText3D( const char* txt, float worldPosX, float worldPosY, float worldPosZ, float size1)
{
saveOpenGLState(gApp2->m_renderer->getScreenWidth(),gApp2->m_renderer->getScreenHeight());
@@ -420,10 +437,10 @@ void SimpleOpenGL2App::drawText3D( const char* txt, float worldPosX, float world
0,0,0,1};
*/
PrimVertex vertexData[4] = {
{ PrimVec4(-1.f+2.f*x0/float(screenWidth), 1.f-2.f*y0/float(screenHeight), z, 1.f ), PrimVec4( color[0], color[1], color[2], color[3] ) ,PrimVec2(u0,v0)},
{ PrimVec4(-1.f+2.f*x0/float(screenWidth), 1.f-2.f*y1/float(screenHeight), z, 1.f ), PrimVec4( color[0], color[1], color[2], color[3] ) ,PrimVec2(u0,v1)},
{ PrimVec4( -1.f+2.f*x1/float(screenWidth), 1.f-2.f*y1/float(screenHeight), z, 1.f ), PrimVec4(color[0], color[1], color[2], color[3]) ,PrimVec2(u1,v1)},
{ PrimVec4( -1.f+2.f*x1/float(screenWidth), 1.f-2.f*y0/float(screenHeight), z, 1.f ), PrimVec4( color[0], color[1], color[2], color[3] ) ,PrimVec2(u1,v0)}
PrimVertex( PrimVec4(-1.f+2.f*x0/float(screenWidth), 1.f-2.f*y0/float(screenHeight), z, 1.f ), PrimVec4( color[0], color[1], color[2], color[3] ) ,PrimVec2(u0,v0)),
PrimVertex( PrimVec4(-1.f+2.f*x0/float(screenWidth), 1.f-2.f*y1/float(screenHeight), z, 1.f ), PrimVec4( color[0], color[1], color[2], color[3] ) ,PrimVec2(u0,v1)),
PrimVertex(PrimVec4( -1.f+2.f*x1/float(screenWidth), 1.f-2.f*y1/float(screenHeight), z, 1.f ), PrimVec4(color[0], color[1], color[2], color[3]) ,PrimVec2(u1,v1)),
PrimVertex( PrimVec4( -1.f+2.f*x1/float(screenWidth), 1.f-2.f*y0/float(screenHeight), z, 1.f ), PrimVec4( color[0], color[1], color[2], color[3] ) ,PrimVec2(u1,v0))
};
glBegin(GL_TRIANGLES);
@@ -460,8 +477,106 @@ void SimpleOpenGL2App::drawText3D( const char* txt, float worldPosX, float world
restoreOpenGLState();
}
void SimpleOpenGL2App::registerGrid(int xres, int yres, float color0[4], float color1[4])
void SimpleOpenGL2App::registerGrid(int cells_x, int cells_z, float color0[4], float color1[4])
{
b3Vector3 cubeExtents=b3MakeVector3(0.5,0.5,0.5);
cubeExtents[m_data->m_upAxis] = 0;
int cubeId = registerCubeShape(cubeExtents[0],cubeExtents[1],cubeExtents[2]);
b3Quaternion orn(0,0,0,1);
b3Vector3 center=b3MakeVector3(0,0,0,1);
b3Vector3 scaling=b3MakeVector3(1,1,1,1);
for ( int i = 0; i < cells_x; i++)
{
for (int j = 0; j < cells_z; j++)
{
float* color =0;
if ((i + j) % 2 == 0)
{
color = (float*)color0;
} else {
color = (float*)color1;
}
if (this->m_data->m_upAxis==1)
{
center =b3MakeVector3((i + 0.5f) - cells_x * 0.5f, 0.f, (j + 0.5f) - cells_z * 0.5f);
} else
{
center =b3MakeVector3((i + 0.5f) - cells_x * 0.5f, (j + 0.5f) - cells_z * 0.5f,0.f );
}
m_renderer->registerGraphicsInstance(cubeId,center,orn,color,scaling);
}
}
}
int SimpleOpenGL2App::registerGraphicsUnitSphereShape(EnumSphereLevelOfDetail lod, int textureId)
{
int strideInBytes = 9*sizeof(float);
int graphicsShapeIndex = -1;
switch (lod)
{
case SPHERE_LOD_POINT_SPRITE:
{
int numVertices = sizeof(point_sphere_vertices)/strideInBytes;
int numIndices = sizeof(point_sphere_indices)/sizeof(int);
graphicsShapeIndex = m_renderer->registerShape(&point_sphere_vertices[0],numVertices,point_sphere_indices,numIndices,B3_GL_POINTS,textureId);
break;
}
case SPHERE_LOD_LOW:
{
int numVertices = sizeof(low_sphere_vertices)/strideInBytes;
int numIndices = sizeof(low_sphere_indices)/sizeof(int);
graphicsShapeIndex = m_renderer->registerShape(&low_sphere_vertices[0],numVertices,low_sphere_indices,numIndices,B3_GL_TRIANGLES,textureId);
break;
}
case SPHERE_LOD_MEDIUM:
{
int numVertices = sizeof(medium_sphere_vertices)/strideInBytes;
int numIndices = sizeof(medium_sphere_indices)/sizeof(int);
graphicsShapeIndex = m_renderer->registerShape(&medium_sphere_vertices[0],numVertices,medium_sphere_indices,numIndices,B3_GL_TRIANGLES,textureId);
break;
}
case SPHERE_LOD_HIGH:
default:
{
int numVertices = sizeof(detailed_sphere_vertices)/strideInBytes;
int numIndices = sizeof(detailed_sphere_indices)/sizeof(int);
graphicsShapeIndex = m_renderer->registerShape(&detailed_sphere_vertices[0],numVertices,detailed_sphere_indices,numIndices,B3_GL_TRIANGLES,textureId);
break;
}
};
return graphicsShapeIndex;
}
int SimpleOpenGL2App::registerCubeShape(float halfExtentsX,float halfExtentsY, float halfExtentsZ, int textureIndex, float textureScaling )
{
int strideInBytes = 9*sizeof(float);
int numVertices = sizeof(cube_vertices_textured)/strideInBytes;
int numIndices = sizeof(cube_indices)/sizeof(int);
b3AlignedObjectArray<GLInstanceVertex> verts;
verts.resize(numVertices);
for (int i=0;i<numVertices;i++)
{
verts[i].xyzw[0] = halfExtentsX*cube_vertices_textured[i*9];
verts[i].xyzw[1] = halfExtentsY*cube_vertices_textured[i*9+1];
verts[i].xyzw[2] = halfExtentsZ*cube_vertices_textured[i*9+2];
verts[i].xyzw[3] = cube_vertices_textured[i*9+3];
verts[i].normal[0] = cube_vertices_textured[i*9+4];
verts[i].normal[1]= cube_vertices_textured[i*9+5];
verts[i].normal[2] = cube_vertices_textured[i*9+6];
verts[i].uv[0] = cube_vertices_textured[i*9+7]*textureScaling;
verts[i].uv[1] = cube_vertices_textured[i*9+8]*textureScaling;
}
int shapeId = m_renderer->registerShape(&verts[0].xyzw[0],numVertices,cube_indices,numIndices,B3_GL_TRIANGLES,textureIndex);
return shapeId;
}

View File

@@ -17,18 +17,16 @@ public:
virtual int getUpAxis() const;
virtual void swapBuffer();
virtual void drawText( const char* txt, int posX, int posY, float size);
virtual void drawText( const char* txt, int posX, int posY, float size, float colorRGBA[4]);
virtual void drawTexturedRect(float x0, float y0, float x1, float y1, float color[4], float u0,float v0, float u1, float v1, int useRGBA){};
virtual void setBackgroundColor(float red, float green, float blue);
virtual int registerCubeShape(float halfExtentsX,float halfExtentsY, float halfExtentsZ, int textureIndex = -1, float textureScaling = 1)
{
return 0;
}
virtual int registerGraphicsUnitSphereShape(EnumSphereLevelOfDetail lod, int textureId=-1)
{
return 0;
}
virtual int registerCubeShape(float halfExtentsX,float halfExtentsY, float halfExtentsZ, int textureIndex = -1, float textureScaling = 1);
virtual int registerGraphicsUnitSphereShape(EnumSphereLevelOfDetail lod, int textureId=-1);
virtual void drawText3D( const char* txt, float posX, float posZY, float posZ, float size);
virtual void drawText3D( const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag);
virtual void registerGrid(int xres, int yres, float color0[4], float color1[4]);

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