Merge branch 'master' into 3D-NN-walkers-example
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
47
examples/CommonInterfaces/CommonCallbacks.h
Normal file
47
examples/CommonInterfaces/CommonCallbacks.h
Normal 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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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[]){};
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"),
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -19,6 +19,8 @@ public:
|
||||
|
||||
virtual void update(float deltaTime);
|
||||
|
||||
virtual void updateGraphics();
|
||||
|
||||
virtual bool requestedExit();
|
||||
|
||||
virtual void setSharedMemoryInterface(class SharedMemoryInterface* sharedMem);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
1942
examples/Importers/ImportMJCFDemo/BulletMJCFImporter.cpp
Normal file
1942
examples/Importers/ImportMJCFDemo/BulletMJCFImporter.cpp
Normal file
File diff suppressed because it is too large
Load Diff
84
examples/Importers/ImportMJCFDemo/BulletMJCFImporter.h
Normal file
84
examples/Importers/ImportMJCFDemo/BulletMJCFImporter.h
Normal 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
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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++)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
46
examples/Importers/ImportURDFDemo/SDFAudioTypes.h
Normal file
46
examples/Importers/ImportURDFDemo/SDFAudioTypes.h
Normal 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
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -242,7 +242,7 @@ void MultiDofDemo::initPhysics()
|
||||
|
||||
if (multibodyConstraint) {
|
||||
btVector3 pointInA = -linkHalfExtents;
|
||||
btVector3 pointInB = halfExtents;
|
||||
// btVector3 pointInB = halfExtents;
|
||||
btMatrix3x3 frameInA;
|
||||
btMatrix3x3 frameInB;
|
||||
frameInA.setIdentity();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
260
examples/OpenGLWindow/EGLOpenGLWindow.cpp
Normal file
260
examples/OpenGLWindow/EGLOpenGLWindow.cpp
Normal 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
|
||||
76
examples/OpenGLWindow/EGLOpenGLWindow.h
Normal file
76
examples/OpenGLWindow/EGLOpenGLWindow.h
Normal 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
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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};
|
||||
|
||||
195
examples/OpenGLWindow/MacOpenGLWindow.cpp
Normal file
195
examples/OpenGLWindow/MacOpenGLWindow.cpp
Normal 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__
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
77
examples/OpenGLWindow/MacOpenGLWindowObjC.h
Normal file
77
examples/OpenGLWindow/MacOpenGLWindowObjC.h
Normal 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
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
Reference in New Issue
Block a user