Merge commit.

This commit is contained in:
Benjamin Ellenberger
2016-07-31 16:22:50 +02:00
273 changed files with 47372 additions and 1771 deletions

View File

@@ -39,10 +39,10 @@ struct BasicExample : public CommonRigidBodyBase
virtual void renderScene();
void resetCamera()
{
float dist = 41;
float dist = 4;
float pitch = 52;
float yaw = 35;
float targetPos[3]={0,0.46,0};
float targetPos[3]={0,0,0};
m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
}
};
@@ -81,7 +81,7 @@ void BasicExample::initPhysics()
//create a few dynamic rigidbodies
// Re-using the same collision is better for memory usage and performance
btBoxShape* colShape = createBoxShape(btVector3(1,1,1));
btBoxShape* colShape = createBoxShape(btVector3(.1,.1,.1));
//btCollisionShape* colShape = new btSphereShape(btScalar(1.));
@@ -108,9 +108,9 @@ void BasicExample::initPhysics()
for(int j = 0;j<ARRAY_SIZE_Z;j++)
{
startTransform.setOrigin(btVector3(
btScalar(2.0*i),
btScalar(20+2.0*k),
btScalar(2.0*j)));
btScalar(0.2*i),
btScalar(2+.2*k),
btScalar(0.2*j)));
createRigidBody(mass,startTransform,colShape);
@@ -121,7 +121,9 @@ void BasicExample::initPhysics()
}
}
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}

View File

@@ -53,6 +53,7 @@ SET(AppBasicExampleGui_SRCS
../ExampleBrowser/OpenGLGuiHelper.cpp
../ExampleBrowser/GL_ShapeDrawer.cpp
../ExampleBrowser/CollisionShape2TriangleMesh.cpp
../Utils/b3Clock.cpp
)
#this define maps StandaloneExampleCreateFunc to the right 'CreateFunc'

View File

@@ -49,6 +49,8 @@ files {
"../ExampleBrowser/OpenGLGuiHelper.cpp",
"../ExampleBrowser/GL_ShapeDrawer.cpp",
"../ExampleBrowser/CollisionShape2TriangleMesh.cpp",
"../Utils/b3Clock.cpp",
"../Utils/b3Clock.h",
}
if os.is("Linux") then initX11() end
@@ -59,6 +61,7 @@ end
project "App_BasicExampleGuiWithSoftwareRenderer"
if _OPTIONS["ios"] then
@@ -92,7 +95,9 @@ files {
"../TinyRenderer/tgaimage.cpp",
"../TinyRenderer/our_gl.cpp",
"../TinyRenderer/TinyRenderer.cpp",
"../Utils/b3ResourcePath.cpp"
"../Utils/b3ResourcePath.cpp",
"../Utils/b3Clock.cpp",
"../Utils/b3Clock.h",
}
if os.is("Linux") then initX11() end
@@ -131,5 +136,68 @@ files {
"../TinyRenderer/tgaimage.cpp",
"../TinyRenderer/our_gl.cpp",
"../TinyRenderer/TinyRenderer.cpp",
"../Utils/b3ResourcePath.cpp"
"../Utils/b3ResourcePath.cpp",
"../Utils/b3Clock.cpp",
"../Utils/b3Clock.h",
}
if _OPTIONS["enable_openvr"] then
project "App_BasicExampleVR"
if _OPTIONS["ios"] then
kind "WindowedApp"
else
kind "ConsoleApp"
end
defines {"B3_USE_STANDALONE_EXAMPLE","BT_ENABLE_VR"}
includedirs {"../../src",
"../ThirdPartyLibs/openvr/headers",
"../ThirdPartyLibs/openvr/samples/shared"}
links {
"BulletDynamics","BulletCollision", "LinearMath", "OpenGL_Window","Bullet3Common", "openvr_api"
}
initOpenGL()
initGlew()
language "C++"
files {
"BasicExample.cpp",
"*.h",
"../StandaloneMain/hellovr_opengl_main.cpp",
"../ExampleBrowser/OpenGLGuiHelper.cpp",
"../ExampleBrowser/GL_ShapeDrawer.cpp",
"../ExampleBrowser/CollisionShape2TriangleMesh.cpp",
"../ThirdPartyLibs/openvr/samples/shared/lodepng.cpp",
"../ThirdPartyLibs/openvr/samples/shared/lodepng.h",
"../ThirdPartyLibs/openvr/samples/shared/Matrices.cpp",
"../ThirdPartyLibs/openvr/samples/shared/Matrices.h",
"../ThirdPartyLibs/openvr/samples/shared/pathtools.cpp",
"../ThirdPartyLibs/openvr/samples/shared/pathtools.h",
"../ThirdPartyLibs/openvr/samples/shared/Vectors.h",
"../Utils/b3Clock.cpp",
"../Utils/b3Clock.h",
}
if os.is("Windows") then
libdirs {"../ThirdPartyLibs/openvr/lib/win32"}
end
if os.is("Linux") then initX11() end
if os.is("MacOSX") then
links{"Cocoa.framework"}
end
end

View File

@@ -1273,7 +1273,7 @@ void BenchmarkDemo::exitPhysics()
struct CommonExampleInterface* BenchmarkCreateFunc(struct CommonExampleOptions& options)
CommonExampleInterface* BenchmarkCreateFunc(struct CommonExampleOptions& options)
{
return new BenchmarkDemo(options.m_guiHelper,options.m_option);
}

View File

@@ -265,8 +265,9 @@ public:
virtual void stepSimulation(float deltaTime)
{
#ifndef BT_NO_PROFILE
CProfileManager::Reset();
#endif
@@ -314,7 +315,9 @@ public:
m_app->m_renderer->writeTransforms();
#ifndef BT_NO_PROFILE
CProfileManager::Increment_Frame_Counter();
#endif
}
virtual void renderScene()
{

View File

@@ -6,7 +6,9 @@ struct CommonCameraInterface
virtual void getCameraProjectionMatrix(float m[16])const = 0;
virtual void getCameraViewMatrix(float m[16]) const = 0;
virtual void setVRCamera(const float viewMat[16], const float projectionMatrix[16])=0;
virtual void setVRCamera(const float viewMat[16], const float projectionMatrix[16])=0;
virtual void disableVRCamera()=0;
virtual bool isVRCamera() const =0;
virtual void getCameraTargetPosition(float pos[3]) const = 0;
virtual void getCameraPosition(float pos[3]) const = 0;

View File

@@ -46,6 +46,8 @@ public:
virtual bool mouseButtonCallback(int button, int state, float x, float y)=0;
virtual bool keyboardCallback(int key, int state)=0;
virtual void vrControllerMoveCallback(int controllerId, float pos[4], float orientation[4]) {}
virtual void vrControllerButtonCallback(int controllerId, int button, int state, float pos[4], float orientation[4]){}
};
class ExampleEntries

View File

@@ -29,10 +29,11 @@ struct GUIHelperInterface
virtual void createPhysicsDebugDrawer( btDiscreteDynamicsWorld* rbWorld)=0;
virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices) =0;
virtual int registerTexture(const unsigned char* texels, int width, int height)=0;
virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices,int primitiveType, int textureId) = 0;
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) =0;
virtual void removeAllGraphicsInstances()=0;
virtual Common2dCanvasInterface* get2dCanvasInterface()=0;
virtual CommonParameterInterface* getParameterInterface()=0;
@@ -45,7 +46,7 @@ struct GUIHelperInterface
virtual void resetCamera(float camDist, float pitch, float yaw, float camPosX,float camPosY, float camPosZ)=0;
virtual void copyCameraImageData(unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels, float* depthBuffer, int depthBufferSizeInPixels, int startPixelIndex, int* width, int* height, int* numPixelsCopied)=0;
virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16], unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels, float* depthBuffer, int depthBufferSizeInPixels, int startPixelIndex, int destinationWidth, int destinationHeight, int* numPixelsCopied)=0;
virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld) =0;
@@ -73,10 +74,11 @@ struct DummyGUIHelper : public GUIHelperInterface
virtual void createPhysicsDebugDrawer( btDiscreteDynamicsWorld* rbWorld){}
virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices) { return -1; }
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) { return -1;}
virtual int registerTexture(const unsigned char* texels, int width, int height){return -1;}
virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices,int primitiveType, int textureId){return -1;}
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) {return -1;}
virtual void removeAllGraphicsInstances(){}
virtual Common2dCanvasInterface* get2dCanvasInterface()
{
return 0;
@@ -105,12 +107,8 @@ struct DummyGUIHelper : public GUIHelperInterface
{
}
virtual void copyCameraImageData(unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels, float* depthBuffer, int depthBufferSizeInPixels, int startPixelIndex, int* width, int* height, int* numPixelsCopied)
virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16], unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels, float* depthBuffer, int depthBufferSizeInPixels, int startPixelIndex, int width, int height, int* numPixelsCopied)
{
if (width)
*width = 0;
if (height)
*height = 0;
if (numPixelsCopied)
*numPixelsCopied = 0;
}

View File

@@ -77,7 +77,7 @@ struct CommonGraphicsApp
virtual void dumpNextFrameToPng(const char* pngFilename){}
virtual void dumpFramesToVideo(const char* mp4Filename){}
virtual void getScreenPixels(unsigned char* rgbaBuffer, int bufferSizeInBytes){};
virtual void getScreenPixels(unsigned char* rgbaBuffer, int bufferSizeInBytes, float* depthBuffer, int depthBufferSizeInBytes){}
virtual void getBackgroundColor(float* red, float* green, float* blue) const
{

View File

@@ -63,7 +63,7 @@ struct CommonMultiBodyBase : public CommonExampleInterface
///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();
m_broadphase = new btDbvtBroadphase();//btSimpleBroadphase();
m_solver = new btMultiBodyConstraintSolver;
@@ -97,6 +97,20 @@ struct CommonMultiBodyBase : public CommonExampleInterface
{
m_dynamicsWorld->removeConstraint(m_dynamicsWorld->getConstraint(i));
}
for (i = m_dynamicsWorld->getNumMultiBodyConstraints() - 1; i >= 0; i--)
{
btMultiBodyConstraint* mbc = m_dynamicsWorld->getMultiBodyConstraint(i);
m_dynamicsWorld->removeMultiBodyConstraint(mbc);
delete mbc;
}
for (i = m_dynamicsWorld->getNumMultibodies() - 1; i >= 0; i--)
{
btMultiBody* mb = m_dynamicsWorld->getMultiBody(i);
m_dynamicsWorld->removeMultiBody(mb);
delete mb;
}
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
{
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];

View File

@@ -22,7 +22,7 @@ struct CommonRenderInterface
virtual void init()=0;
virtual void updateCamera(int upAxis)=0;
virtual void removeAllInstances() = 0;
virtual const CommonCameraInterface* getActiveCamera() const =0;
virtual CommonCameraInterface* getActiveCamera()=0;
virtual void setActiveCamera(CommonCameraInterface* cam)=0;
@@ -52,6 +52,10 @@ struct CommonRenderInterface
virtual void writeSingleInstanceTransformToCPU(const double* position, const double* orientation, int srcIndex)=0;
virtual void writeSingleInstanceColorToCPU(float* color, int srcIndex)=0;
virtual void writeSingleInstanceColorToCPU(double* color, int srcIndex)=0;
virtual void writeSingleInstanceScaleToCPU(float* scale, int srcIndex)=0;
virtual void writeSingleInstanceScaleToCPU(double* scale, int srcIndex)=0;
virtual int getTotalNumInstances() const = 0;
virtual void writeTransforms()=0;
virtual void enableBlend(bool blend)=0;

View File

@@ -165,6 +165,8 @@ SET(BulletExampleBrowser_SRCS
../BasicDemo/BasicExample.h
../InverseDynamics/InverseDynamicsExample.cpp
../InverseDynamics/InverseDynamicsExample.h
../InverseKinematics/InverseKinematicsExample.cpp
../InverseKinematics/InverseKinematicsExample.h
../ForkLift/ForkLiftDemo.cpp
../ForkLift/ForkLiftDemo.h
../Tutorial/Tutorial.cpp
@@ -173,6 +175,8 @@ SET(BulletExampleBrowser_SRCS
../Tutorial/Dof6ConstraintTutorial.h
../Evolution/NN3DWalkers.cpp
../Evolution/NN3DWalkers.h
../ExtendedTutorials/NewtonsRopeCradle.cpp
../ExtendedTutorials/NewtonsRopeCradle.h
../Collision/CollisionSdkC_Api.cpp
../Collision/CollisionSdkC_Api.h
../Collision/CollisionTutorialBullet2.cpp
@@ -204,7 +208,12 @@ SET(BulletExampleBrowser_SRCS
../RenderingExamples/TimeSeriesCanvas.h
../RenderingExamples/TimeSeriesFontData.cpp
../RenderingExamples/TimeSeriesFontData.h
../RoboticsLearning/GripperGraspExample.cpp
../RoboticsLearning/GripperGraspExample.h
../RoboticsLearning/b3RobotSimAPI.cpp
../RoboticsLearning/b3RobotSimAPI.h
../RoboticsLearning/R2D2GraspExample.cpp
../RoboticsLearning/R2D2GraspExample.h
../RenderingExamples/CoordinateSystemDemo.cpp
../RenderingExamples/CoordinateSystemDemo.h
../RenderingExamples/RaytracerSetup.cpp
@@ -291,6 +300,17 @@ SET(BulletExampleBrowser_SRCS
../ThirdPartyLibs/stb_image/stb_image.cpp
../ThirdPartyLibs/stb_image/stb_image.h
../ThirdPartyLibs/BussIK/Jacobian.cpp
../ThirdPartyLibs/BussIK/Tree.cpp
../ThirdPartyLibs/BussIK/Node.cpp
../ThirdPartyLibs/BussIK/LinearR2.cpp
../ThirdPartyLibs/BussIK/LinearR3.cpp
../ThirdPartyLibs/BussIK/LinearR4.cpp
../ThirdPartyLibs/BussIK/MatrixRmn.cpp
../ThirdPartyLibs/BussIK/VectorRn.cpp
../ThirdPartyLibs/BussIK/Misc.cpp
../ThirdPartyLibs/Wavefront/tiny_obj_loader.cpp
../ThirdPartyLibs/tinyxml/tinystr.cpp

View File

@@ -167,6 +167,7 @@ void CollisionShape2TriangleMesh(btCollisionShape* collisionShape, const btTrans
}
}
}
delete hull;
}
} else
{

View File

@@ -45,6 +45,10 @@
#include "../Tutorial/Dof6ConstraintTutorial.h"
#include "../MultiThreading/MultiThreadingExample.h"
#include "../InverseDynamics/InverseDynamicsExample.h"
#include "../RoboticsLearning/R2D2GraspExample.h"
#include "../RoboticsLearning/GripperGraspExample.h"
#include "../InverseKinematics/InverseKinematicsExample.h"
#ifdef ENABLE_LUA
#include "../LuaDemo/LuaPhysicsSetup.h"
#endif
@@ -66,6 +70,7 @@
#include "../ExtendedTutorials/RigidBodyFromObj.h"
#include "../ExtendedTutorials/InclinedPlane.h"
#include "../ExtendedTutorials/NewtonsCradle.h"
#include "../ExtendedTutorials/NewtonsRopeCradle.h"
#include "../ExtendedTutorials/MultiPendulum.h"
#include "../Evolution/NN3DWalkers.h"
@@ -97,7 +102,6 @@ static ExampleEntry gDefaultExamples[]=
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),
ExampleEntry(1,"Rolling Friction", "Damping is often not good enough to keep rounded objects from rolling down a sloped surface. Instead, you can set the rolling friction of a rigid body. Generally it is best to leave the rolling friction to zero, to avoid artifacts.", RollingFrictionCreateFunc),
ExampleEntry(1,"Constraints","Show the use of the various constraints in Bullet. Press the L key to visualize the constraint limits. Press the C key to visualize the constraint frames.",
@@ -117,21 +121,30 @@ static ExampleEntry gDefaultExamples[]=
ExampleEntry(1,"Soft Contact", "Using the error correction parameter (ERP) and constraint force mixing (CFM) values for contacts to simulate compliant contact.",RigidBodySoftContactCreateFunc),
ExampleEntry(0,"MultiBody"),
ExampleEntry(1,"MultiDofCreateFunc","Create a basic btMultiBody with 3-DOF spherical joints (mobilizers). The demo uses a fixed base or a floating base at restart.", MultiDofCreateFunc),
ExampleEntry(1,"TestJointTorque","Apply a torque to a btMultiBody with 1-DOF joints (mobilizers). This setup is similar to API/TestHingeTorque.", TestJointTorqueCreateFunc),
ExampleEntry(1,"TestPendulum","Simulate a pendulum using btMultiBody with a constant joint torque applied. The same code is also used as a unit test comparing Bullet with the numerical solution of second-order non-linear differential equation stored in pendulum_gold.h", TestPendulumCreateFunc),
ExampleEntry(1,"Constraint Feedback", "The example shows how to receive joint reaction forces in a btMultiBody. Also the applied impulse is available for a btMultiBodyJointMotor", MultiBodyConstraintFeedbackCreateFunc),
ExampleEntry(1,"Constraint Feedback", "The example shows how to receive joint reaction forces in a btMultiBody. Also the applied impulse is available for a btMultiBodyJointMotor", MultiBodyConstraintFeedbackCreateFunc),
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(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,"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),
ExampleEntry(1,"Inverse Dynamics Prog", "Create a btMultiBody programatically. 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_PROGRAMMATICALLY),
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),
ExampleEntry(1,"Inverse Dynamics Prog", "Create a btMultiBody programatically. 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_PROGRAMMATICALLY),
ExampleEntry(0, "Inverse Kinematics"),
ExampleEntry(1, "SDLS", "Selectively Damped Least Squares by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_SDLS),
ExampleEntry(1, "DLS", "Damped Least Squares by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_DLS),
ExampleEntry(1, "DLS-SVD", "Damped Least Squares with Singular Value Decomposition by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_DLS_SVD),
ExampleEntry(1, "Jacobi Transpose", "Jacobi Transpose by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_JACOB_TRANS),
ExampleEntry(1, "Jacobi Pseudo Inv", "Jacobi Pseudo Inverse Method by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_PURE_PSEUDO),
ExampleEntry(0,"Tutorial"),
ExampleEntry(1,"Constant Velocity","Free moving rigid body, without external or constraint forces", TutorialCreateFunc,TUT_VELOCITY),
@@ -187,7 +200,7 @@ static ExampleEntry gDefaultExamples[]=
#endif //INCLUDE_CLOTH_DEMOS
///we disable the benchmarks in debug mode, they are way too slow and benchmarking in debug mode is not recommended
#ifndef _DEBUG
//#ifndef _DEBUG
ExampleEntry(0,"Benchmarks"),
ExampleEntry(1,"3000 boxes", "Benchmark a stack of 3000 boxes. It will stress the collision detection, a specialized box-box implementation based on the separating axis test, and the constraint solver. ", BenchmarkCreateFunc, 1),
ExampleEntry(1,"1000 stack", "Benchmark a stack of 3000 boxes. It will stress the collision detection, a specialized box-box implementation based on the separating axis test, and the constraint solver. ",
@@ -197,7 +210,7 @@ static ExampleEntry gDefaultExamples[]=
ExampleEntry(1,"Prim vs Mesh", "Benchmark the performance and stability of rigid bodies using primitive collision shapes (btSphereShape, btBoxShape), resting on a triangle mesh, btBvhTriangleMeshShape.", BenchmarkCreateFunc, 5),
ExampleEntry(1,"Convex vs Mesh", "Benchmark the performance and stability of rigid bodies using convex hull collision shapes (btConvexHullShape), resting on a triangle mesh, btBvhTriangleMeshShape.", BenchmarkCreateFunc, 6),
ExampleEntry(1,"Raycast", "Benchmark the performance of the btCollisionWorld::rayTest. Note that currently the rays are not rendered.", BenchmarkCreateFunc, 7),
#endif
//#endif
@@ -244,8 +257,13 @@ static ExampleEntry gDefaultExamples[]=
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, "Physics Client", "Create a physics client that can communicate with a physics server over shared memory", PhysicsClientCreateFunc),
ExampleEntry(1,"R2D2 Grasp","Load the R2D2 robot from URDF file and control it to grasp objects", R2D2GraspExampleCreateFunc, eROBOTIC_LEARN_GRASP),
ExampleEntry(1,"URDF Compliant Contact","Work-in-progress, experiment/improve compliant rigid contact using parameters from URDF file (contact_cfm, contact_erp, lateral_friction, rolling_friction)", R2D2GraspExampleCreateFunc,eROBOTIC_LEARN_COMPLIANT_CONTACT),
ExampleEntry(1,"Contact for Grasp","Grasp experiment to improve contact model", GripperGraspExampleCreateFunc),
#ifdef ENABLE_LUA
@@ -279,8 +297,9 @@ static ExampleEntry gDefaultExamples[]=
ExampleEntry(1,"Simple Chain", "Create a simple chain using a pair of point2point/distance constraints. You may click and drag any box to see the chain respond.", ET_ChainCreateFunc),
ExampleEntry(1,"Simple Bridge", "Create a simple bridge using a pair of point2point/distance constraints. You may click and drag any plank to see the bridge respond.", ET_BridgeCreateFunc),
ExampleEntry(1,"Inclined Plane", "Create an inclined plane to show restitution and different types of friction. Use the sliders to vary restitution and friction and press space to reset the scene.", ET_InclinedPlaneCreateFunc),
ExampleEntry(1,"Newton's Cradle", "Create a Newton's Cradle using a pair of point2point/slider constraints. Press 1/2 to lengthen/shorten the pendula, press 3 to displace pendula. Use the sliders to select the number of pendula in total (reset simulation), the number of displaced pendula and other options.", ET_NewtonsCradleCreateFunc),
ExampleEntry(1,"Multi-Pendulum", "Create a Multi-Pendulum using point2point/slider constraints. Press 1/2 to lengthen/shorten the pendula, press 3 to displace pendula. Use the sliders to select the number of pendula in total (reset simulation), the number of displaced pendula and other options.",ET_MultiPendulumCreateFunc),
ExampleEntry(1,"Newton's Cradle", "Create a Newton's Cradle using a pair of point2point/slider constraints. Press 1/2 to lengthen/shorten the pendula, press 3 to displace pendula. Use the sliders to select the number (reset simulation), length and restitution of pendula, the number of displaced pendula and apply the displacement force.", ET_NewtonsCradleCreateFunc),
ExampleEntry(1,"Newton's Rope Cradle", "Create a Newton's Cradle using ropes. Press 3 to displace pendula. Use the sliders to select the number (reset simulation), length and restitution of pendula and the number of displaced pendula and apply the displacement force.",ET_NewtonsRopeCradleCreateFunc),
ExampleEntry(1,"Multi-Pendulum", "Create a Multi-Pendulum using point2point/slider constraints. Press 1/2 to lengthen/shorten the pendula, press 3 to displace pendula. Use the sliders to select the number (reset simulation), length and restitution of pendula, the number of displaced pendula and apply the displacement force.",ET_MultiPendulumCreateFunc),
ExampleEntry(9,"Evolution"),
ExampleEntry(1,"Neural Network 3D Walkers","A simple example of using evolution to make a creature walk.",ET_NN3DWalkersCreateFunc),

View File

@@ -21,6 +21,7 @@ void GraphingTexture::destroy()
m_height=0;
glDeleteTextures(1,(GLuint*)&m_textureId);
m_textureId=0;
}
bool GraphingTexture::create(int texWidth, int texHeight)

View File

@@ -4,7 +4,7 @@
#include "LinearMath/btQuickprof.h"
#ifndef BT_NO_PROFILE
class MyProfileWindow : public Gwen::Controls::WindowControl
@@ -42,9 +42,10 @@ protected:
}
public:
CProfileIterator* profIter;
class MyMenuItems* m_menuItems;
MyProfileWindow ( Gwen::Controls::Base* pParent)
: Gwen::Controls::WindowControl( pParent ),
profIter(0)
@@ -83,6 +84,12 @@ public:
}
virtual ~MyProfileWindow()
{
delete m_node;
delete m_ctrl;
}
float dumpRecursive(CProfileIterator* profileIterator, Gwen::Controls::TreeNode* parentNode)
{
@@ -266,11 +273,16 @@ public:
MyProfileWindow* setupProfileWindow(GwenInternalData* data)
{
MyMenuItems* menuItems = new MyMenuItems;
MyProfileWindow* profWindow = new MyProfileWindow(data->pCanvas);
//profWindow->SetHidden(true);
profWindow->profIter = CProfileManager::Get_Iterator();
profWindow->m_menuItems = menuItems;
//profWindow->profIter = CProfileManager::Get_Iterator();
data->m_viewMenu->GetMenu()->AddItem( L"Profiler", menuItems,(Gwen::Event::Handler::Function)&MyMenuItems::MenuItemSelect);
menuItems->m_profWindow = profWindow;
return profWindow;
}
@@ -290,5 +302,8 @@ void profileWindowSetVisible(MyProfileWindow* window, bool visible)
}
void destroyProfileWindow(MyProfileWindow* window)
{
CProfileManager::Release_Iterator(window->profIter);
delete window;
}
#endif //BT_NO_PROFILE

View File

@@ -45,7 +45,10 @@ struct GwenInternalData
Gwen::Controls::ListBox* m_TextOutput;
Gwen::Controls::Label* m_exampleInfoGroupBox;
Gwen::Controls::ListBox* m_exampleInfoTextOutput;
struct MyTestMenuBar* m_menubar;
Gwen::Controls::StatusBar* m_bar;
Gwen::Controls::ScrollControl* m_windowRight;
Gwen::Controls::TabControl* m_tab;
int m_curYposition;

View File

@@ -17,6 +17,83 @@ GwenUserInterface::GwenUserInterface()
}
class MyMenuItems : public Gwen::Controls::Base
{
public:
b3FileOpenCallback m_fileOpenCallback;
b3QuitCallback m_quitCallback;
MyMenuItems() :Gwen::Controls::Base(0), m_fileOpenCallback(0)
{
}
void myQuitApp(Gwen::Controls::Base* pControl)
{
if (m_quitCallback)
{
(*m_quitCallback)();
}
}
void fileOpen(Gwen::Controls::Base* pControl)
{
if (m_fileOpenCallback)
{
(*m_fileOpenCallback)();
}
}
};
struct MyTestMenuBar : public Gwen::Controls::MenuStrip
{
Gwen::Controls::MenuItem* m_fileMenu;
Gwen::Controls::MenuItem* m_viewMenu;
MyMenuItems* m_menuItems;
MyTestMenuBar(Gwen::Controls::Base* pParent)
:Gwen::Controls::MenuStrip(pParent)
{
// Gwen::Controls::MenuStrip* menu = new Gwen::Controls::MenuStrip( pParent );
{
m_menuItems = new MyMenuItems();
m_menuItems->m_fileOpenCallback = 0;
m_menuItems->m_quitCallback = 0;
m_fileMenu = AddItem(L"File");
m_fileMenu->GetMenu()->AddItem(L"Open", m_menuItems, (Gwen::Event::Handler::Function)&MyMenuItems::fileOpen);
m_fileMenu->GetMenu()->AddItem(L"Quit", m_menuItems, (Gwen::Event::Handler::Function)&MyMenuItems::myQuitApp);
m_viewMenu = AddItem(L"View");
}
}
virtual ~MyTestMenuBar()
{
delete m_menuItems;
}
};
void GwenUserInterface::exit()
{
//m_data->m_menubar->RemoveAllChildren();
delete m_data->m_tab;
delete m_data->m_windowRight;
delete m_data->m_leftStatusBar;
delete m_data->m_TextOutput;
delete m_data->m_rightStatusBar;
delete m_data->m_bar;
delete m_data->m_menubar;
m_data->m_menubar = 0;
delete m_data->pCanvas;
m_data->pCanvas = 0;
}
GwenUserInterface::~GwenUserInterface()
{
for (int i=0;i<m_data->m_handlers.size();i++)
@@ -26,72 +103,15 @@ GwenUserInterface::~GwenUserInterface()
m_data->m_handlers.clear();
delete m_data->pCanvas;
delete m_data;
}
class MyMenuItems : public Gwen::Controls::Base
{
public:
b3FileOpenCallback m_fileOpenCallback;
b3QuitCallback m_quitCallback;
MyMenuItems() :Gwen::Controls::Base(0),m_fileOpenCallback(0)
{
}
void myQuitApp( Gwen::Controls::Base* pControl )
{
if (m_quitCallback)
{
(*m_quitCallback)();
}
}
void fileOpen( Gwen::Controls::Base* pControl )
{
if (m_fileOpenCallback)
{
(*m_fileOpenCallback)();
}
}
};
struct MyTestMenuBar : public Gwen::Controls::MenuStrip
{
Gwen::Controls::MenuItem* m_fileMenu;
Gwen::Controls::MenuItem* m_viewMenu;
MyMenuItems* m_menuItems;
MyTestMenuBar(Gwen::Controls::Base* pParent)
:Gwen::Controls::MenuStrip(pParent)
{
// Gwen::Controls::MenuStrip* menu = new Gwen::Controls::MenuStrip( pParent );
{
m_menuItems = new MyMenuItems();
m_menuItems->m_fileOpenCallback = 0;
m_menuItems->m_quitCallback = 0;
m_fileMenu = AddItem( L"File" );
m_fileMenu->GetMenu()->AddItem(L"Open",m_menuItems,(Gwen::Event::Handler::Function)&MyMenuItems::fileOpen);
m_fileMenu->GetMenu()->AddItem(L"Quit",m_menuItems,(Gwen::Event::Handler::Function)&MyMenuItems::myQuitApp);
m_viewMenu = AddItem( L"View" );
}
}
};
void GwenUserInterface::resize(int width, int height)
{
@@ -232,6 +252,7 @@ void GwenUserInterface::setStatusBarMessage(const char* message, bool isLeft)
}
}
void GwenUserInterface::registerFileOpenCallback(b3FileOpenCallback callback)
{
m_data->m_menuItems->m_fileOpenCallback = callback;
@@ -249,35 +270,43 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere
m_data->pRenderer = renderer;//new GwenOpenGL3CoreRenderer(m_data->m_primRenderer,stash,width,height,retinaScale);
m_data->skin.SetRender( m_data->pRenderer );
m_data->pCanvas= new Gwen::Controls::Canvas( &m_data->skin );
m_data->pCanvas->SetSize( width,height);
m_data->pCanvas->SetDrawBackground( false);
m_data->pCanvas->SetBackgroundColor( Gwen::Color( 150, 170, 170, 255 ) );
MyTestMenuBar* menubar = new MyTestMenuBar(m_data->pCanvas);
m_data->m_viewMenu = menubar->m_viewMenu;
m_data->m_menuItems = menubar->m_menuItems;
m_data->m_menubar = menubar;
Gwen::Controls::StatusBar* bar = new Gwen::Controls::StatusBar(m_data->pCanvas);
m_data->m_bar = bar;
m_data->m_rightStatusBar = new Gwen::Controls::Label( bar );
m_data->m_rightStatusBar->SetWidth(width/2);
//m_data->m_rightStatusBar->SetText( L"Label Added to Right" );
bar->AddControl( m_data->m_rightStatusBar, true );
m_data->m_TextOutput = new Gwen::Controls::ListBox( m_data->pCanvas );
m_data->m_TextOutput->Dock( Gwen::Pos::Bottom );
m_data->m_TextOutput->SetHeight( 100 );
m_data->m_leftStatusBar = new Gwen::Controls::Label( bar );
//m_data->m_leftStatusBar->SetText( L"Label Added to Left" );
m_data->m_leftStatusBar->SetWidth(width/2);
bar->AddControl( m_data->m_leftStatusBar,false);
//Gwen::KeyboardFocus
/*Gwen::Controls::GroupBox* box = new Gwen::Controls::GroupBox(m_data->pCanvas);
box->SetText("text");
@@ -289,11 +318,14 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere
windowRight->SetWidth(250);
windowRight->SetHeight(250);
windowRight->SetScroll(false,true);
m_data->m_windowRight = windowRight;
//windowLeft->SetSkin(
Gwen::Controls::TabControl* tab = new Gwen::Controls::TabControl(windowRight);
m_data->m_tab = tab;
//tab->SetHeight(300);
tab->SetWidth(240);
@@ -304,7 +336,8 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere
Gwen::UnicodeString str1(L"Params");
m_data->m_demoPage = tab->AddPage(str1);
@@ -348,7 +381,7 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere
//windowLeft->SetClosable(false);
// windowLeft->SetShouldDrawBackground(true);
windowLeft->SetTabable(true);
Gwen::Controls::TabControl* explorerTab = new Gwen::Controls::TabControl(windowLeft);
//tab->SetHeight(300);
@@ -388,7 +421,6 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere
m_data->m_exampleInfoGroupBox->SetText("Example Description");
m_data->m_exampleInfoTextOutput = new Gwen::Controls::ListBox(m_data->m_explorerPage->GetPage());
//m_data->m_exampleInfoTextOutput->Dock( Gwen::Pos::Bottom );
m_data->m_exampleInfoTextOutput->SetPos(2, 332);

View File

@@ -26,6 +26,7 @@ class GwenUserInterface
virtual ~GwenUserInterface();
void init(int width, int height,Gwen::Renderer::Base* gwenRenderer,float retinaScale);
void exit();
void setFocus();
void forceUpdateScrollBars();

View File

@@ -226,7 +226,7 @@ enum TestExampleBrowserCommunicationEnums
void ExampleBrowserThreadFunc(void* userPtr,void* lsMemory)
{
printf("thread started\n");
printf("ExampleBrowserThreadFunc started\n");
ExampleBrowserThreadLocalStorage* localStorage = (ExampleBrowserThreadLocalStorage*) lsMemory;
@@ -369,7 +369,7 @@ void btShutDownExampleBrowser(btInProcessExampleBrowserInternalData* data)
}
};
printf("stopping threads\n");
printf("btShutDownExampleBrowser stopping threads\n");
delete data->m_threadSupport;
delete data->m_sharedMem;
delete data;

View File

@@ -42,19 +42,65 @@
#include "../Importers/ImportURDFDemo/ImportURDFSetup.h"
#include "../Importers/ImportBullet/SerializeSetup.h"
#include "Bullet3Common/b3HashMap.h"
struct GL3TexLoader : public MyTextureLoader
{
b3HashMap<b3HashString, GLint> m_hashMap;
virtual void LoadTexture(Gwen::Texture* pTexture)
{
Gwen::String namestr = pTexture->name.Get();
const char* n = namestr.c_str();
GLint* texIdPtr = m_hashMap[n];
if (texIdPtr)
{
pTexture->m_intData = *texIdPtr;
}
}
virtual void FreeTexture(Gwen::Texture* pTexture)
{
}
};
struct OpenGLExampleBrowserInternalData
{
Gwen::Renderer::Base* m_gwenRenderer;
CommonGraphicsApp* m_app;
// MyProfileWindow* m_profWindow;
btAlignedObjectArray<Gwen::Controls::TreeNode*> m_nodes;
GwenUserInterface* m_gui;
GL3TexLoader* m_myTexLoader;
struct MyMenuItemHander* m_handler2;
btAlignedObjectArray<MyMenuItemHander*> m_handlers;
OpenGLExampleBrowserInternalData()
: m_gwenRenderer(0),
m_app(0),
// m_profWindow(0),
m_gui(0),
m_myTexLoader(0),
m_handler2(0)
{
}
};
static CommonGraphicsApp* s_app=0;
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;
//static MyProfileWindow* s_profWindow =0;
static SharedMemoryInterface* sSharedMem = 0;
#define DEMO_SELECTION_COMBOBOX 13
const char* startFileName = "0_Bullet3Demo.txt";
char staticPngFileName[1024];
static GwenUserInterface* gui = 0;
//static GwenUserInterface* gui = 0;
static GwenUserInterface* gui2 = 0;
static int sCurrentDemoIndex = -1;
static int sCurrentHightlighted = 0;
static CommonExampleInterface* sCurrentDemo = 0;
@@ -111,6 +157,7 @@ void deleteDemo()
}
const char* gPngFileName = 0;
int gPngSkipFrames = 0;
@@ -123,9 +170,9 @@ void MyKeyboardCallback(int key, int state)
//b3Printf("key=%d, state=%d", key, state);
bool handled = false;
if (gui && !handled )
if (gui2 && !handled )
{
handled = gui->keyboardCallback(key, state);
handled = gui2->keyboardCallback(key, state);
}
if (!handled && sCurrentDemo)
@@ -223,11 +270,11 @@ void MyKeyboardCallback(int key, int state)
b3MouseMoveCallback prevMouseMoveCallback = 0;
static void MyMouseMoveCallback( float x, float y)
{
bool handled = false;
bool handled = false;
if (sCurrentDemo)
handled = sCurrentDemo->mouseMoveCallback(x,y);
if (!handled && gui)
handled = gui->mouseMoveCallback(x,y);
if (!handled && gui2)
handled = gui2->mouseMoveCallback(x,y);
if (!handled)
{
if (prevMouseMoveCallback)
@@ -244,8 +291,8 @@ static void MyMouseButtonCallback(int button, int state, float x, float y)
if (sCurrentDemo)
handled = sCurrentDemo->mouseButtonCallback(button,state,x,y);
if (!handled && gui)
handled = gui->mouseButtonCallback(button,state,x,y);
if (!handled && gui2)
handled = gui2->mouseButtonCallback(button,state,x,y);
if (!handled)
{
@@ -333,7 +380,10 @@ void selectDemo(int demoIndex)
CommonExampleInterface::CreateFunc* func = gAllExamples->getExampleCreateFunc(demoIndex);
if (func)
{
s_parameterInterface->removeAllParameters();
if (s_parameterInterface)
{
s_parameterInterface->removeAllParameters();
}
int option = gAllExamples->getExampleOption(demoIndex);
s_guiHelper= new OpenGLGuiHelper(s_app, sUseOpenGL2);
CommonExampleOptions options(s_guiHelper, option);
@@ -341,12 +391,15 @@ void selectDemo(int demoIndex)
sCurrentDemo = (*func)(options);
if (sCurrentDemo)
{
if (gui)
if (gui2)
{
gui->setStatusBarMessage("Status: OK", false);
gui2->setStatusBarMessage("Status: OK", false);
}
b3Printf("Selected demo: %s",gAllExamples->getExampleName(demoIndex));
gui->setExampleDescription(gAllExamples->getExampleDescription(demoIndex));
if (gui2)
{
gui2->setExampleDescription(gAllExamples->getExampleDescription(demoIndex));
}
sCurrentDemo->initPhysics();
if(resetCamera)
@@ -399,7 +452,6 @@ static void loadCurrentSettings(const char* startFileName, b3CommandLineArgs& ar
FILE* f = fopen(startFileName,"r");
if (f)
{
int result;
char oneline[1024];
char* argv[] = {0,&oneline[0]};
@@ -438,10 +490,10 @@ void MyComboBoxCallback(int comboId, const char* item)
void MyGuiPrintf(const char* msg)
{
printf("b3Printf: %s\n",msg);
if (gui)
if (gui2)
{
gui->textOutput(msg);
gui->forceUpdateScrollBars();
gui2->textOutput(msg);
gui2->forceUpdateScrollBars();
}
}
@@ -450,10 +502,10 @@ void MyGuiPrintf(const char* msg)
void MyStatusBarPrintf(const char* msg)
{
printf("b3Printf: %s\n", msg);
if (gui)
if (gui2)
{
bool isLeft = true;
gui->setStatusBarMessage(msg,isLeft);
gui2->setStatusBarMessage(msg,isLeft);
}
}
@@ -461,13 +513,15 @@ void MyStatusBarPrintf(const char* msg)
void MyStatusBarError(const char* msg)
{
printf("Warning: %s\n", msg);
if (gui)
if (gui2)
{
bool isLeft = false;
gui->setStatusBarMessage(msg,isLeft);
gui->textOutput(msg);
gui->forceUpdateScrollBars();
gui2->setStatusBarMessage(msg,isLeft);
gui2->textOutput(msg);
gui2->forceUpdateScrollBars();
}
btAssert(0);
}
struct MyMenuItemHander :public Gwen::Event::Handler
@@ -535,7 +589,7 @@ struct MyMenuItemHander :public Gwen::Event::Handler
{
// printf("select %d\n",m_buttonId);
sCurrentHightlighted = m_buttonId;
gui->setExampleDescription(gAllExamples->getExampleDescription(sCurrentHightlighted));
gui2->setExampleDescription(gAllExamples->getExampleDescription(sCurrentHightlighted));
}
void onButtonF(Gwen::Controls::Base* pControl)
@@ -550,26 +604,6 @@ struct MyMenuItemHander :public Gwen::Event::Handler
};
#include "Bullet3Common/b3HashMap.h"
struct GL3TexLoader : public MyTextureLoader
{
b3HashMap<b3HashString,GLint> m_hashMap;
virtual void LoadTexture( Gwen::Texture* pTexture )
{
Gwen::String namestr = pTexture->name.Get();
const char* n = namestr.c_str();
GLint* texIdPtr = m_hashMap[n];
if (texIdPtr)
{
pTexture->m_intData = *texIdPtr;
}
}
virtual void FreeTexture( Gwen::Texture* pTexture )
{
}
};
void quitCallback()
@@ -624,7 +658,7 @@ struct QuickCanvas : public Common2dCanvasInterface
m_curNumGraphWindows++;
MyGraphInput input(gui->getInternalData());
MyGraphInput input(gui2->getInternalData());
input.m_width=width;
input.m_height=height;
input.m_xPos = 10000;//GUI will clamp it to the right//300;
@@ -644,7 +678,10 @@ struct QuickCanvas : public Common2dCanvasInterface
virtual void destroyCanvas(int canvasId)
{
btAssert(canvasId>=0);
delete m_gt[canvasId];
m_gt[canvasId] = 0;
destroyTextureWindow(m_gw[canvasId]);
m_gw[canvasId] = 0;
m_curNumGraphWindows--;
}
virtual void setPixel(int canvasId, int x, int y, unsigned char red, unsigned char green,unsigned char blue, unsigned char alpha)
@@ -670,12 +707,51 @@ struct QuickCanvas : public Common2dCanvasInterface
OpenGLExampleBrowser::OpenGLExampleBrowser(class ExampleEntries* examples)
{
m_internalData = new OpenGLExampleBrowserInternalData;
gAllExamples = examples;
}
OpenGLExampleBrowser::~OpenGLExampleBrowser()
{
deleteDemo();
deleteDemo();
for (int i = 0; i < m_internalData->m_nodes.size(); i++)
{
delete m_internalData->m_nodes[i];
}
delete m_internalData->m_handler2;
for (int i = 0; i < m_internalData->m_handlers.size(); i++)
{
delete m_internalData->m_handlers[i];
}
m_internalData->m_handlers.clear();
m_internalData->m_nodes.clear();
delete s_parameterInterface;
s_parameterInterface = 0;
delete s_app->m_2dCanvasInterface;
s_app->m_2dCanvasInterface = 0;
m_internalData->m_gui->exit();
delete m_internalData->m_gui;
delete m_internalData->m_gwenRenderer;
delete m_internalData->m_myTexLoader;
delete m_internalData->m_app;
s_app = 0;
// delete m_internalData->m_profWindow;
delete m_internalData;
gFileImporterByExtension.clear();
gAllExamples = 0;
}
@@ -688,7 +764,7 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
loadCurrentSettings(startFileName, args);
args.GetCmdLineArgument("fixed_timestep",gFixedTimeStep);
args.GetCmdLineArgument("png_skip_frames", gPngSkipFrames);
///The OpenCL rigid body pipeline is experimental and
///most OpenCL drivers and OpenCL compilers have issues with our kernels.
///If you have a high-end desktop GPU such as AMD 7970 or better, or NVIDIA GTX 680 with up-to-date drivers
@@ -727,17 +803,17 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
s_app = new SimpleOpenGL2App(title,width,height);
s_app->m_renderer = new SimpleOpenGL2Renderer(width,height);
}
#ifndef NO_OPENGL3
else
{
char title[1024];
sprintf(title,"%s using OpenGL3+. %s", appTitle,optMode);
simpleApp = new SimpleOpenGL3App(title,width,height, gAllowRetina);
s_app = simpleApp;
}
#endif
m_internalData->m_app = s_app;
char* gVideoFileName = 0;
args.GetCmdLineArgument("mp4",gVideoFileName);
#ifndef NO_OPENGL3
@@ -793,43 +869,67 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
assert(glGetError()==GL_NO_ERROR);
{
GL3TexLoader* myTexLoader = new GL3TexLoader;
m_internalData->m_myTexLoader = myTexLoader;
gui = new GwenUserInterface;
GL3TexLoader* myTexLoader = new GL3TexLoader;
Gwen::Renderer::Base* gwenRenderer = 0;
if (sUseOpenGL2 )
{
gwenRenderer = new Gwen::Renderer::OpenGL_DebugFont();
}
sth_stash* fontstash = simpleApp->getFontStash();
if (sUseOpenGL2)
{
m_internalData->m_gwenRenderer = new Gwen::Renderer::OpenGL_DebugFont();
}
#ifndef NO_OPENGL3
else
{
sth_stash* fontstash=simpleApp->getFontStash();
gwenRenderer = new GwenOpenGL3CoreRenderer(simpleApp->m_primRenderer,fontstash,width,height,s_window->getRetinaScale(),myTexLoader);
}
else
{
sth_stash* fontstash = simpleApp->getFontStash();
m_internalData->m_gwenRenderer = new GwenOpenGL3CoreRenderer(simpleApp->m_primRenderer, fontstash, width, height, s_window->getRetinaScale(), myTexLoader);
}
#endif
gui2 = new GwenUserInterface;
m_internalData->m_gui = gui2;
m_internalData->m_myTexLoader = myTexLoader;
gui2->init(width, height, m_internalData->m_gwenRenderer, s_window->getRetinaScale());
}
//gui = 0;// new GwenUserInterface;
GL3TexLoader* myTexLoader = m_internalData->m_myTexLoader;
// = myTexLoader;
//
gui->init(width,height,gwenRenderer,s_window->getRetinaScale());
// gui->getInternalData()->m_explorerPage
Gwen::Controls::TreeControl* tree = gui->getInternalData()->m_explorerTreeCtrl;
if (gui2)
{
// gui->getInternalData()->m_explorerPage
Gwen::Controls::TreeControl* tree = gui2->getInternalData()->m_explorerTreeCtrl;
//gui->getInternalData()->pRenderer->setTextureLoader(myTexLoader);
// s_profWindow= setupProfileWindow(gui2->getInternalData());
//m_internalData->m_profWindow = s_profWindow;
// profileWindowSetVisible(s_profWindow,false);
gui2->setFocus();
s_parameterInterface = s_app->m_parameterInterface = new GwenParameterInterface(gui2->getInternalData());
s_app->m_2dCanvasInterface = new QuickCanvas(myTexLoader);
//gui->getInternalData()->pRenderer->setTextureLoader(myTexLoader);
s_profWindow= setupProfileWindow(gui->getInternalData());
profileWindowSetVisible(s_profWindow,false);
gui->setFocus();
s_parameterInterface = s_app->m_parameterInterface = new GwenParameterInterface(gui->getInternalData());
s_app->m_2dCanvasInterface = new QuickCanvas(myTexLoader);
///add some demos to the gAllExamples
@@ -840,7 +940,7 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
//int curDemo = 0;
int selectedDemo = 0;
Gwen::Controls::TreeNode* curNode = tree;
MyMenuItemHander* handler2 = new MyMenuItemHander(-1);
m_internalData->m_handler2 = new MyMenuItemHander(-1);
char* demoNameFromCommandOption = 0;
args.GetCmdLineArgument("start_demo_name", demoNameFromCommandOption);
@@ -848,7 +948,7 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
selectedDemo = -1;
}
tree->onReturnKeyDown.Add(handler2, &MyMenuItemHander::onButtonD);
tree->onReturnKeyDown.Add(m_internalData->m_handler2, &MyMenuItemHander::onButtonD);
int firstAvailableDemoIndex=-1;
Gwen::Controls::TreeNode* firstNode=0;
@@ -895,13 +995,18 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
}
}
#if 1
MyMenuItemHander* handler = new MyMenuItemHander(d);
m_internalData->m_handlers.push_back(handler);
pNode->onNamePress.Add(handler, &MyMenuItemHander::onButtonA);
pNode->GetButton()->onDoubleClick.Add(handler, &MyMenuItemHander::onButtonB);
pNode->GetButton()->onDown.Add(handler, &MyMenuItemHander::onButtonC);
pNode->onSelect.Add(handler, &MyMenuItemHander::onButtonE);
pNode->onReturnKeyDown.Add(handler, &MyMenuItemHander::onButtonG);
pNode->onSelectChange.Add(handler, &MyMenuItemHander::onButtonF);
#endif
// pNode->onKeyReturn.Add(handler, &MyMenuItemHander::onButtonD);
// pNode->GetButton()->onKeyboardReturn.Add(handler, &MyMenuItemHander::onButtonD);
// pNode->onNamePress.Add(handler, &MyMenuItemHander::onButtonD);
@@ -911,6 +1016,7 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
else
{
curNode = tree->AddNode(nodeUText);
m_internalData->m_nodes.push_back(curNode);
}
}
@@ -929,6 +1035,9 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
}
}
free(demoNameFromCommandOption);
demoNameFromCommandOption = 0;
btAssert(sCurrentDemo!=0);
if (sCurrentDemo==0)
{
@@ -936,9 +1045,11 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
exit(0);
}
gui->registerFileOpenCallback(fileOpenCallback);
gui->registerQuitCallback(quitCallback);
gui2->registerFileOpenCallback(fileOpenCallback);
gui2->registerQuitCallback(quitCallback);
}
return true;
}
@@ -971,14 +1082,7 @@ void OpenGLExampleBrowser::update(float deltaTime)
s_instancingRenderer->updateCamera(dg.upAxis);
}
if (renderGrid)
{
BT_PROFILE("Draw Grid");
glPolygonOffset(3.0, 3);
glEnable(GL_POLYGON_OFFSET_FILL);
s_app->drawGrid(dg);
}
static int frameCount = 0;
frameCount++;
@@ -998,24 +1102,6 @@ void OpenGLExampleBrowser::update(float deltaTime)
//printf("---------------------------------------------------\n");
//printf("Framecount = %d\n",frameCount);
if (gPngFileName)
{
static int skip = 0;
skip++;
if (skip>4)
{
skip=0;
//printf("gPngFileName=%s\n",gPngFileName);
static int s_frameCount = 100;
sprintf(staticPngFileName,"%s%d.png",gPngFileName,s_frameCount++);
//b3Printf("Made screenshot %s",staticPngFileName);
s_app->dumpNextFrameToPng(staticPngFileName);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
}
if (gFixedTimeStep>0)
{
@@ -1026,6 +1112,14 @@ void OpenGLExampleBrowser::update(float deltaTime)
}
}
if (renderGrid)
{
BT_PROFILE("Draw Grid");
glPolygonOffset(3.0, 3);
glEnable(GL_POLYGON_OFFSET_FILL);
s_app->drawGrid(dg);
}
if (renderVisualGeometry && ((gDebugDrawFlags&btIDebugDraw::DBG_DrawWireframe)==0))
{
if (visualWireframe)
@@ -1042,9 +1136,28 @@ void OpenGLExampleBrowser::update(float deltaTime)
}
}
if (gPngFileName)
{
static int skip = 0;
skip--;
if (skip<0)
{
skip=gPngSkipFrames;
//printf("gPngFileName=%s\n",gPngFileName);
static int s_frameCount = 100;
sprintf(staticPngFileName,"%s%d.png",gPngFileName,s_frameCount++);
//b3Printf("Made screenshot %s",staticPngFileName);
s_app->dumpNextFrameToPng(staticPngFileName);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
}
{
if (s_guiHelper && s_guiHelper->getRenderInterface() && s_guiHelper->getRenderInterface()->getActiveCamera())
if (gui2 && s_guiHelper && s_guiHelper->getRenderInterface() && s_guiHelper->getRenderInterface()->getActiveCamera())
{
char msg[1024];
float camDist = s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraDistance();
@@ -1053,7 +1166,7 @@ void OpenGLExampleBrowser::update(float deltaTime)
float camTarget[3];
s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraTargetPosition(camTarget);
sprintf(msg,"dist=%f, pitch=%f, yaw=%f,target=%f,%f,%f", camDist,pitch,yaw,camTarget[0],camTarget[1],camTarget[2]);
gui->setStatusBarMessage(msg, true);
gui2->setStatusBarMessage(msg, true);
}
}
@@ -1061,16 +1174,24 @@ void OpenGLExampleBrowser::update(float deltaTime)
static int toggle = 1;
if (renderGui)
{
if (!pauseSimulation)
processProfileData(s_profWindow,false);
// if (!pauseSimulation)
// processProfileData(s_profWindow,false);
if (sUseOpenGL2)
if (sUseOpenGL2)
{
saveOpenGLState(s_instancingRenderer->getScreenWidth(),s_instancingRenderer->getScreenHeight());
saveOpenGLState(s_instancingRenderer->getScreenWidth(), s_instancingRenderer->getScreenHeight());
}
BT_PROFILE("Draw Gwen GUI");
gui->draw(s_instancingRenderer->getScreenWidth(),s_instancingRenderer->getScreenHeight());
BT_PROFILE("Draw Gwen GUI");
if (m_internalData->m_gui)
{
m_internalData->m_gui->draw(s_instancingRenderer->getScreenWidth(), s_instancingRenderer->getScreenHeight());
}
if (gui2)
{
gui2->draw(s_instancingRenderer->getScreenWidth(), s_instancingRenderer->getScreenHeight());
}
if (sUseOpenGL2)
{
restoreOpenGLState();
@@ -1084,14 +1205,20 @@ void OpenGLExampleBrowser::update(float deltaTime)
toggle=1-toggle;
{
BT_PROFILE("Sync Parameters");
s_parameterInterface->syncParameters();
if (s_parameterInterface)
{
s_parameterInterface->syncParameters();
}
}
{
BT_PROFILE("Swap Buffers");
s_app->swapBuffer();
}
gui->forceUpdateScrollBars();
if (gui2)
{
gui2->forceUpdateScrollBars();
}
}

View File

@@ -5,6 +5,9 @@
class OpenGLExampleBrowser : public ExampleBrowserInterface
{
struct OpenGLExampleBrowserInternalData* m_internalData;
public:
OpenGLExampleBrowser(class ExampleEntries* examples);

View File

@@ -8,7 +8,7 @@
#include "CollisionShape2TriangleMesh.h"
#include "../OpenGLWindow/SimpleCamera.h"
#include "../OpenGLWindow/GLInstanceGraphicsShape.h"
//backwards compatibility
#include "GL_ShapeDrawer.h"
@@ -144,8 +144,8 @@ struct OpenGLGuiHelperInternalData
class MyDebugDrawer* m_debugDraw;
GL_ShapeDrawer* m_gl2ShapeDrawer;
btAlignedObjectArray<unsigned char> m_rgbaPixelBuffer;
btAlignedObjectArray<float> m_depthBuffer;
btAlignedObjectArray<unsigned char> m_rgbaPixelBuffer1;
btAlignedObjectArray<float> m_depthBuffer1;
};
@@ -167,6 +167,7 @@ OpenGLGuiHelper::OpenGLGuiHelper(CommonGraphicsApp* glApp, bool useOpenGL2)
OpenGLGuiHelper::~OpenGLGuiHelper()
{
delete m_data->m_debugDraw;
delete m_data->m_gl2ShapeDrawer;
delete m_data;
}
@@ -199,9 +200,16 @@ void OpenGLGuiHelper::createCollisionObjectGraphicsObject(btCollisionObject* bod
}
}
int OpenGLGuiHelper::registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices)
int OpenGLGuiHelper::registerTexture(const unsigned char* texels, int width, int height)
{
int shapeId = m_data->m_glApp->m_renderer->registerShape(vertices, numvertices,indices,numIndices);
int textureId = m_data->m_glApp->m_renderer->registerTexture(texels,width,height);
return textureId;
}
int OpenGLGuiHelper::registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices,int primitiveType, int textureId)
{
int shapeId = m_data->m_glApp->m_renderer->registerShape(vertices, numvertices,indices,numIndices,primitiveType, textureId);
return shapeId;
}
@@ -210,6 +218,10 @@ int OpenGLGuiHelper::registerGraphicsInstance(int shapeIndex, const float* posit
return m_data->m_glApp->m_renderer->registerGraphicsInstance(shapeIndex,position,quaternion,color,scaling);
}
void OpenGLGuiHelper::removeAllGraphicsInstances()
{
m_data->m_glApp->m_renderer->removeAllInstances();
}
void OpenGLGuiHelper::createCollisionShapeGraphicsObject(btCollisionShape* collisionShape)
{
@@ -247,7 +259,7 @@ void OpenGLGuiHelper::createCollisionShapeGraphicsObject(btCollisionShape* colli
if (gfxVertices.size() && indices.size())
{
int shapeId = registerGraphicsShape(&gfxVertices[0].xyzw[0],gfxVertices.size(),&indices[0],indices.size());
int shapeId = registerGraphicsShape(&gfxVertices[0].xyzw[0],gfxVertices.size(),&indices[0],indices.size(),B3_GL_TRIANGLES,-1);
collisionShape->setUserIndex(shapeId);
}
@@ -326,19 +338,15 @@ void OpenGLGuiHelper::resetCamera(float camDist, float pitch, float yaw, float c
}
void OpenGLGuiHelper::copyCameraImageData(unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels, float* depthBuffer, int depthBufferSizeInPixels, int startPixelIndex, int* widthPtr, int* heightPtr, int* numPixelsCopied)
void OpenGLGuiHelper::copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16], unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels, float* depthBuffer, int depthBufferSizeInPixels, int startPixelIndex, int destinationWidth, int destinationHeight, int* numPixelsCopied)
{
int w = m_data->m_glApp->m_window->getWidth()*m_data->m_glApp->m_window->getRetinaScale();
int h = m_data->m_glApp->m_window->getHeight()*m_data->m_glApp->m_window->getRetinaScale();
int sourceWidth = m_data->m_glApp->m_window->getWidth()*m_data->m_glApp->m_window->getRetinaScale();
int sourceHeight = m_data->m_glApp->m_window->getHeight()*m_data->m_glApp->m_window->getRetinaScale();
if (widthPtr)
*widthPtr = w;
if (heightPtr)
*heightPtr = h;
if (numPixelsCopied)
*numPixelsCopied = 0;
int numTotalPixels = w*h;
int numTotalPixels = destinationWidth*destinationHeight;
int numRemainingPixels = numTotalPixels - startPixelIndex;
int numBytesPerPixel = 4;//RGBA
int numRequestedPixels = btMin(rgbaBufferSizeInPixels,numRemainingPixels);
@@ -346,22 +354,58 @@ void OpenGLGuiHelper::copyCameraImageData(unsigned char* pixelsRGBA, int rgbaBuf
{
if (startPixelIndex==0)
{
//quick test: render the scene
CommonCameraInterface* oldCam = getRenderInterface()->getActiveCamera();
SimpleCamera tempCam;
getRenderInterface()->setActiveCamera(&tempCam);
getRenderInterface()->getActiveCamera()->setVRCamera(viewMatrix,projectionMatrix);
getRenderInterface()->renderScene();
//copy the image into our local cache
m_data->m_rgbaPixelBuffer.resize(w*h*numBytesPerPixel);
m_data->m_depthBuffer.resize(w*h);
m_data->m_glApp->getScreenPixels(&(m_data->m_rgbaPixelBuffer[0]),m_data->m_rgbaPixelBuffer.size());
}
for (int i=0;i<numRequestedPixels*numBytesPerPixel;i++)
{
if (pixelsRGBA)
{
pixelsRGBA[i] = m_data->m_rgbaPixelBuffer[i+startPixelIndex*numBytesPerPixel];
getRenderInterface()->setActiveCamera(oldCam);
{
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());
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
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;
}
}
}
}
if (pixelsRGBA)
{
for (int i=0;i<numRequestedPixels*numBytesPerPixel;i++)
{
pixelsRGBA[i] = m_data->m_rgbaPixelBuffer1[i+startPixelIndex*numBytesPerPixel];
}
}
if (depthBuffer)
{
for (int i=0;i<numRequestedPixels;i++)
{
depthBuffer[i] = m_data->m_depthBuffer1[i];
}
}
if (numPixelsCopied)
*numPixelsCopied = numRequestedPixels;

View File

@@ -20,12 +20,11 @@ struct OpenGLGuiHelper : public GUIHelperInterface
virtual void createCollisionObjectGraphicsObject(btCollisionObject* body, const btVector3& color);
virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices);
virtual int registerTexture(const unsigned char* texels, int width, int height);
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 createCollisionShapeGraphicsObject(btCollisionShape* collisionShape);
virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld);
@@ -45,7 +44,7 @@ struct OpenGLGuiHelper : public GUIHelperInterface
virtual void resetCamera(float camDist, float pitch, float yaw, float camPosX,float camPosY, float camPosZ);
virtual void copyCameraImageData(unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels, float* depthBuffer, int depthBufferSizeInPixels, int startPixelIndex, int* width, int* height, int* numPixelsCopied);
virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16], unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels, float* depthBuffer, int depthBufferSizeInPixels, int startPixelIndex, int destinationWidth, int destinationHeight, int* numPixelsCopied);
virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld) ;

View File

@@ -1,4 +1,5 @@
#include "OpenGLExampleBrowser.h"
#include "Bullet3Common/b3CommandLineArgs.h"
@@ -13,36 +14,46 @@
#include "../Importers/ImportSTLDemo/ImportSTLSetup.h"
#include "../Importers/ImportURDFDemo/ImportURDFSetup.h"
#include "../Importers/ImportSDFDemo/ImportSDFSetup.h"
#include "../Importers/ImportSTLDemo/ImportSTLSetup.h"
#include "LinearMath/btAlignedAllocator.h"
int main(int argc, char* argv[])
{
b3CommandLineArgs args(argc,argv);
b3Clock clock;
ExampleEntriesAll examples;
examples.initExampleEntries();
OpenGLExampleBrowser* exampleBrowser = new OpenGLExampleBrowser(&examples);
bool init = exampleBrowser->init(argc,argv);
exampleBrowser->registerFileImporter(".urdf",ImportURDFCreateFunc);
exampleBrowser->registerFileImporter(".sdf",ImportSDFCreateFunc);
exampleBrowser->registerFileImporter(".obj",ImportObjCreateFunc);
clock.reset();
if (init)
{
do
{
float deltaTimeInSeconds = clock.getTimeMicroseconds()/1000000.f;
clock.reset();
exampleBrowser->update(deltaTimeInSeconds);
b3CommandLineArgs args(argc, argv);
b3Clock clock;
ExampleEntriesAll examples;
examples.initExampleEntries();
OpenGLExampleBrowser* exampleBrowser = new OpenGLExampleBrowser(&examples);
bool init = exampleBrowser->init(argc, argv);
exampleBrowser->registerFileImporter(".urdf", ImportURDFCreateFunc);
exampleBrowser->registerFileImporter(".sdf", ImportSDFCreateFunc);
exampleBrowser->registerFileImporter(".obj", ImportObjCreateFunc);
exampleBrowser->registerFileImporter(".stl", ImportSTLCreateFunc);
clock.reset();
if (init)
{
do
{
float deltaTimeInSeconds = clock.getTimeMicroseconds() / 1000000.f;
clock.reset();
exampleBrowser->update(deltaTimeInSeconds);
} while (!exampleBrowser->requestedExit());
}
delete exampleBrowser;
} while (!exampleBrowser->requestedExit());
}
delete exampleBrowser;
#ifdef BT_DEBUG_MEMORY_ALLOCATIONS
int numBytesLeaked = btDumpMemoryLeaks();
btAssert(numBytesLeaked==0);
#endif//BT_DEBUG_MEMORY_ALLOCATIONS
return 0;
}

View File

@@ -45,9 +45,10 @@ project "App_BulletExampleBrowser"
defines {"INCLUDE_CLOTH_DEMOS"}
files {
"main.cpp",
"ExampleEntries.cpp",
"../InverseKinematics/*",
"../TinyRenderer/geometry.cpp",
"../TinyRenderer/model.cpp",
"../TinyRenderer/tgaimage.cpp",
@@ -86,16 +87,11 @@ project "App_BulletExampleBrowser"
"../InverseDynamics/InverseDynamicsExample.h",
"../BasicDemo/BasicExample.*",
"../Tutorial/*",
"../ExtendedTutorials/SimpleBox.cpp",
"../ExtendedTutorials/MultipleBoxes.cpp",
"../ExtendedTutorials/SimpleJoint.cpp",
"../ExtendedTutorials/SimpleCloth.cpp",
"../ExtendedTutorials/Chain.cpp",
"../ExtendedTutorials/Bridge.cpp",
"../ExtendedTutorials/RigidBodyFromObj.cpp",
"../ExtendedTutorials/*",
"../Evolution/NN3DWalkers.cpp",
"../Evolution/NN3DWalkers.h",
"../Collision/*",
"../RoboticsLearning/*",
"../Collision/Internal/*",
"../Benchmarks/*",
"../CommonInterfaces/*",
@@ -123,6 +119,7 @@ project "App_BulletExampleBrowser"
"../ThirdPartyLibs/stb_image/*",
"../ThirdPartyLibs/Wavefront/tiny_obj_loader.*",
"../ThirdPartyLibs/tinyxml/*",
"../ThirdPartyLibs/BussIK/*",
"../GyroscopicDemo/GyroscopicSetup.cpp",
"../GyroscopicDemo/GyroscopicSetup.h",
"../ThirdPartyLibs/tinyxml/tinystr.cpp",

View File

@@ -89,7 +89,7 @@ void InclinedPlaneExample::initPhysics()
{ // create slider to change the ramp tilt
SliderParams slider("Ramp Tilt",&gTilt);
slider.m_minVal=0;
slider.m_maxVal=M_PI/2.0f;
slider.m_maxVal=SIMD_PI/2.0f;
slider.m_clampToNotches = false;
slider.m_callback = onRampInclinationChanged;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);

View File

@@ -38,6 +38,8 @@ static btScalar gInitialPendulumLength = 8; // Default pendulum length (distance
static btScalar gDisplacementForce = 30; // The default force with which we move the pendulum
static btScalar gForceScalar = 0; // default force scalar to apply a displacement
struct MultiPendulumExample: public CommonRigidBodyBase {
MultiPendulumExample(struct GUIHelperInterface* helper) :
CommonRigidBodyBase(helper) {
@@ -47,21 +49,13 @@ struct MultiPendulumExample: public CommonRigidBodyBase {
}
virtual void initPhysics(); // build a multi pendulum
virtual void renderScene(); // render the scene to screen
virtual void createMultiPendulum(btSphereShape* colShape,
btScalar pendulaQty, btScalar xPosition, btScalar yPosition,btScalar zPosition,
btScalar length, btScalar mass); // create a multi pendulum at the indicated x and y position, the specified number of pendula formed into a chain, each with indicated length and mass
virtual void createMultiPendulum(btSphereShape* colShape, btScalar pendulaQty, const btVector3& position, btScalar length, btScalar mass); // create a multi pendulum at the indicated x and y position, the specified number of pendula formed into a chain, each with indicated length and mass
virtual void changePendulaLength(btScalar length); // change the pendulum length
virtual void changePendulaRestitution(btScalar restitution); // change the pendula restitution
virtual void stepSimulation(float deltaTime); // step the simulation
virtual bool keyboardCallback(int key, int state); // handle keyboard callbacks
virtual void applyPendulumForce(btScalar pendulumForce);
void resetCamera() {
float dist = 41;
float pitch = 52;
@@ -72,7 +66,6 @@ struct MultiPendulumExample: public CommonRigidBodyBase {
}
std::vector<btSliderConstraint*> constraints; // keep a handle to the slider constraints
std::vector<btRigidBody*> pendula; // keep a handle to the pendula
};
@@ -84,6 +77,8 @@ void onMultiPendulaRestitutionChanged(float pendulaRestitution); // change the p
void floorMSliderValue(float notUsed); // floor the slider values which should be integers
void applyMForceWithForceScalar(float forceScalar);
void MultiPendulumExample::initPhysics() { // Setup your physics scene
{ // create a slider to change the number of pendula
@@ -135,6 +130,15 @@ void MultiPendulumExample::initPhysics() { // Setup your physics scene
slider);
}
{ // create a slider to apply the force by slider
SliderParams slider("Apply displacement force", &gForceScalar);
slider.m_minVal = -1;
slider.m_maxVal = 1;
slider.m_clampToNotches = false;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
slider);
}
m_guiHelper->setUpAxis(1);
createEmptyDynamicsWorld();
@@ -151,16 +155,14 @@ void MultiPendulumExample::initPhysics() { // Setup your physics scene
{ // create the multipendulum starting at the indicated position below and where each pendulum has the following mass
btScalar pendulumMass(1.f);
btScalar xPosition(0.0f); // initial top-most pendulum position
btScalar yPosition(15.0f);
btScalar zPosition(0.0f);
btVector3 position(0.0f,15.0f,0.0f); // initial top-most pendulum position
// Re-using the same collision is better for memory usage and performance
btSphereShape* pendulumShape = new btSphereShape(gSphereRadius);
m_collisionShapes.push_back(pendulumShape);
// create multi-pendulum
createMultiPendulum(pendulumShape, floor(gPendulaQty), xPosition, yPosition,zPosition,
createMultiPendulum(pendulumShape, floor(gPendulaQty), position,
gInitialPendulumLength, pendulumMass);
}
@@ -168,14 +170,16 @@ void MultiPendulumExample::initPhysics() { // Setup your physics scene
}
void MultiPendulumExample::stepSimulation(float deltaTime) {
applyMForceWithForceScalar(gForceScalar); // apply force defined by apply force slider
if (m_dynamicsWorld) {
m_dynamicsWorld->stepSimulation(deltaTime);
}
}
void MultiPendulumExample::createMultiPendulum(btSphereShape* colShape,
btScalar pendulaQty, btScalar xPosition, btScalar yPosition, btScalar zPosition,
btScalar pendulaQty, const btVector3& position,
btScalar length, btScalar mass) {
// The multi-pendulum looks like this (names when built):
@@ -194,8 +198,7 @@ void MultiPendulumExample::createMultiPendulum(btSphereShape* colShape,
startTransform.setIdentity();
// position the top sphere
startTransform.setOrigin(
btVector3(btScalar(xPosition), btScalar(yPosition), btScalar(zPosition)));
startTransform.setOrigin(position);
startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation
@@ -222,9 +225,7 @@ void MultiPendulumExample::createMultiPendulum(btSphereShape* colShape,
// create joint element to make the pendulum rotate it
// position the joint sphere at the same position as the top sphere
startTransform.setOrigin(
btVector3(btScalar(xPosition), btScalar(yPosition - length*(i)),
btScalar(0)));
startTransform.setOrigin(position - btVector3(0,length*(i),0));
startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation
@@ -263,9 +264,7 @@ void MultiPendulumExample::createMultiPendulum(btSphereShape* colShape,
startTransform.setIdentity(); // reset start transform
// position the child sphere below the joint sphere
startTransform.setOrigin(
btVector3(btScalar(xPosition), btScalar(yPosition - length*(i+1)),
btScalar(0)));
startTransform.setOrigin(position - btVector3(0,length*(i+1),0));
startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation
@@ -352,10 +351,10 @@ bool MultiPendulumExample::keyboardCallback(int key, int state) {
//key 1, key 2, key 3
switch (key) {
case 49 /*ASCII for 1*/: {
case '1' /*ASCII for 1*/: {
//assumption: Sphere are aligned in Z axis
btScalar newLimit = gCurrentPendulumLength + 0.1;
btScalar newLimit = btScalar(gCurrentPendulumLength + 0.1);
changePendulaLength(newLimit);
gCurrentPendulumLength = newLimit;
@@ -363,10 +362,10 @@ bool MultiPendulumExample::keyboardCallback(int key, int state) {
b3Printf("Increase pendulum length to %f", gCurrentPendulumLength);
return true;
}
case 50 /*ASCII for 2*/: {
case '2' /*ASCII for 2*/: {
//assumption: Sphere are aligned in Z axis
btScalar newLimit = gCurrentPendulumLength - 0.1;
btScalar newLimit = btScalar(gCurrentPendulumLength - 0.1);
//is being shortened beyond it's own length, we don't let the lower sphere to go over the upper one
if (0 <= newLimit) {
@@ -377,11 +376,8 @@ bool MultiPendulumExample::keyboardCallback(int key, int state) {
b3Printf("Decrease pendulum length to %f", gCurrentPendulumLength);
return true;
}
case 51 /*ASCII for 3*/: {
for (int i = gPendulaQty-1; i >= gPendulaQty-gDisplacedPendula; i--) {
if (gDisplacedPendula >= 0 && gDisplacedPendula < gPendulaQty)
pendula[i]->applyCentralForce(btVector3(gDisplacementForce, 0, 0));
}
case '3' /*ASCII for 3*/: {
applyPendulumForce(gDisplacementForce);
return true;
}
}
@@ -389,6 +385,16 @@ bool MultiPendulumExample::keyboardCallback(int key, int state) {
return false;
}
void MultiPendulumExample::applyPendulumForce(btScalar pendulumForce){
if(pendulumForce != 0){
b3Printf("Apply %f to pendulum",pendulumForce);
for (int i = 0; i < gDisplacedPendula; i++) {
if (gDisplacedPendula >= 0 && gDisplacedPendula <= gPendulaQty)
pendula[i]->applyCentralForce(btVector3(pendulumForce, 0, 0));
}
}
}
// GUI parameter modifiers
void onMultiPendulaLengthChanged(float pendulaLength) { // Change the pendula length
@@ -411,6 +417,17 @@ void floorMSliderValue(float notUsed) { // floor the slider values which should
gDisplacedPendula = floor(gDisplacedPendula);
}
void applyMForceWithForceScalar(float forceScalar) {
if(mex){
btScalar appliedForce = forceScalar * gDisplacementForce;
if(fabs(gForceScalar) < 0.2f)
gForceScalar = 0;
mex->applyPendulumForce(appliedForce);
}
}
CommonExampleInterface* ET_MultiPendulumCreateFunc(
CommonExampleOptions& options) {
mex = new MultiPendulumExample(options.m_guiHelper);

View File

@@ -30,7 +30,7 @@ static btScalar gPendulaQty = 5; // Number of pendula in newton's cradle
static btScalar gDisplacedPendula = 1; // number of displaced pendula
//TODO: This is an int as well
static btScalar gPendulaRestitution = 1; // pendula restition when hitting against each other
static btScalar gPendulaRestitution = 1; // pendula restitution when hitting against each other
static btScalar gSphereRadius = 1; // pendula radius
@@ -38,7 +38,9 @@ static btScalar gCurrentPendulumLength = 8; // current pendula length
static btScalar gInitialPendulumLength = 8; // default pendula length
static btScalar gForcingForce = 30; // default force to displace the pendula
static btScalar gDisplacementForce = 30; // default force to displace the pendula
static btScalar gForceScalar = 0; // default force scalar to apply a displacement
struct NewtonsCradleExample: public CommonRigidBodyBase {
NewtonsCradleExample(struct GUIHelperInterface* helper) :
@@ -48,12 +50,12 @@ struct NewtonsCradleExample: public CommonRigidBodyBase {
}
virtual void initPhysics();
virtual void renderScene();
virtual void createPendulum(btSphereShape* colShape, btScalar xPosition,
btScalar yPosition, btScalar zPosition, btScalar length, btScalar mass);
virtual void createPendulum(btSphereShape* colShape, const btVector3& position, btScalar length, btScalar mass);
virtual void changePendulaLength(btScalar length);
virtual void changePendulaRestitution(btScalar restitution);
virtual void stepSimulation(float deltaTime);
virtual bool keyboardCallback(int key, int state);
virtual void applyPendulumForce(btScalar pendulumForce);
void resetCamera() {
float dist = 41;
float pitch = 52;
@@ -63,17 +65,19 @@ struct NewtonsCradleExample: public CommonRigidBodyBase {
targetPos[2]);
}
std::vector<btSliderConstraint*> constraints;
std::vector<btRigidBody*> pendula;
std::vector<btSliderConstraint*> constraints; // keep a handle to the slider constraints
std::vector<btRigidBody*> pendula; // keep a handle to the pendula
};
static NewtonsCradleExample* nex = NULL;
void onPendulaLengthChanged(float pendulaLength);
void onPendulaLengthChanged(float pendulaLength); // Change the pendula length
void onPendulaRestitutionChanged(float pendulaRestitution);
void onPendulaRestitutionChanged(float pendulaRestitution); // change the pendula restitution
void floorSliderValue(float notUsed);
void floorSliderValue(float notUsed); // floor the slider values which should be integers
void applyForceWithForceScalar(float forceScalar);
void NewtonsCradleExample::initPhysics() {
@@ -118,7 +122,7 @@ void NewtonsCradleExample::initPhysics() {
}
{ // create a slider to change the force to displace the lowest pendulum
SliderParams slider("Displacement force", &gForcingForce);
SliderParams slider("Displacement force", &gDisplacementForce);
slider.m_minVal = 0.1;
slider.m_maxVal = 200;
slider.m_clampToNotches = false;
@@ -126,6 +130,15 @@ void NewtonsCradleExample::initPhysics() {
slider);
}
{ // create a slider to apply the force by slider
SliderParams slider("Apply displacement force", &gForceScalar);
slider.m_minVal = -1;
slider.m_maxVal = 1;
slider.m_clampToNotches = false;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
slider);
}
m_guiHelper->setUpAxis(1);
createEmptyDynamicsWorld();
@@ -139,12 +152,11 @@ void NewtonsCradleExample::initPhysics() {
+ btIDebugDraw::DBG_DrawConstraints
+ btIDebugDraw::DBG_DrawConstraintLimits);
{ // create the pendulum starting at the indicated position below and where each pendulum has the following mass
{ // create the pendula starting at the indicated position below and where each pendulum has the following mass
btScalar pendulumMass(1.f);
btScalar xPosition(0.0f); // initial left-most pendulum position
btScalar yPosition(15.0f);
btScalar zPosition(0.0f);
btVector3 position(0.0f,15.0f,0.0f); // initial left-most pendulum position
btQuaternion orientation(0,0,0,1); // orientation of the pendula
// Re-using the same collision is better for memory usage and performance
btSphereShape* pendulumShape = new btSphereShape(gSphereRadius);
@@ -153,11 +165,10 @@ void NewtonsCradleExample::initPhysics() {
for (int i = 0; i < floor(gPendulaQty); i++) {
// create pendulum
createPendulum(pendulumShape, xPosition, yPosition,zPosition,
gInitialPendulumLength, pendulumMass);
createPendulum(pendulumShape, position, gInitialPendulumLength, pendulumMass);
// displace the pendula 1.05 sphere size, so that they all nearly touch (small spacings in between
xPosition -= 2.1f * gSphereRadius;
position.setX(position.x()-2.1f * gSphereRadius);
}
}
@@ -165,14 +176,15 @@ void NewtonsCradleExample::initPhysics() {
}
void NewtonsCradleExample::stepSimulation(float deltaTime) {
applyForceWithForceScalar(gForceScalar); // apply force defined by apply force slider
if (m_dynamicsWorld) {
m_dynamicsWorld->stepSimulation(deltaTime);
}
}
void NewtonsCradleExample::createPendulum(btSphereShape* colShape,
btScalar xPosition, btScalar yPosition, btScalar zPosition, btScalar length, btScalar mass) {
void NewtonsCradleExample::createPendulum(btSphereShape* colShape, const btVector3& position, btScalar length, btScalar mass) {
// The pendulum looks like this (names when built):
// O topSphere
@@ -184,15 +196,14 @@ void NewtonsCradleExample::createPendulum(btSphereShape* colShape,
startTransform.setIdentity();
// position the top sphere above ground with a moving x position
startTransform.setOrigin(
btVector3(btScalar(xPosition), btScalar(yPosition), btScalar(zPosition)));
startTransform.setOrigin(position);
startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation
btRigidBody* topSphere = createRigidBody(mass, startTransform, colShape);
// position the bottom sphere below the top sphere
startTransform.setOrigin(
btVector3(btScalar(xPosition), btScalar(yPosition - length),
btScalar(zPosition)));
btVector3(position.x(), btScalar(position.y() - length),
position.z()));
startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation
btRigidBody* bottomSphere = createRigidBody(mass, startTransform, colShape);
@@ -286,10 +297,10 @@ bool NewtonsCradleExample::keyboardCallback(int key, int state) {
//key 1, key 2, key 3
switch (key) {
case 49 /*ASCII for 1*/: {
case '1' /*ASCII for 1*/: {
//assumption: Sphere are aligned in Z axis
btScalar newLimit = gCurrentPendulumLength + 0.1;
btScalar newLimit = btScalar(gCurrentPendulumLength + 0.1);
changePendulaLength(newLimit);
gCurrentPendulumLength = newLimit;
@@ -297,10 +308,10 @@ bool NewtonsCradleExample::keyboardCallback(int key, int state) {
b3Printf("Increase pendulum length to %f", gCurrentPendulumLength);
return true;
}
case 50 /*ASCII for 2*/: {
case '2' /*ASCII for 2*/: {
//assumption: Sphere are aligned in Z axis
btScalar newLimit = gCurrentPendulumLength - 0.1;
btScalar newLimit = btScalar(gCurrentPendulumLength - 0.1);
//is being shortened beyond it's own length, we don't let the lower sphere to go over the upper one
if (0 <= newLimit) {
@@ -311,11 +322,8 @@ bool NewtonsCradleExample::keyboardCallback(int key, int state) {
b3Printf("Decrease pendulum length to %f", gCurrentPendulumLength);
return true;
}
case 51 /*ASCII for 3*/: {
for (int i = 0; i < gDisplacedPendula; i++) {
if (gDisplacedPendula >= 0 && gDisplacedPendula <= gPendulaQty)
pendula[i]->applyCentralForce(btVector3(gForcingForce, 0, 0));
}
case '3' /*ASCII for 3*/: {
applyPendulumForce(gDisplacementForce);
return true;
}
}
@@ -323,6 +331,16 @@ bool NewtonsCradleExample::keyboardCallback(int key, int state) {
return false;
}
void NewtonsCradleExample::applyPendulumForce(btScalar pendulumForce){
if(pendulumForce != 0){
b3Printf("Apply %f to pendulum",pendulumForce);
for (int i = 0; i < gDisplacedPendula; i++) {
if (gDisplacedPendula >= 0 && gDisplacedPendula <= gPendulaQty)
pendula[i]->applyCentralForce(btVector3(pendulumForce, 0, 0));
}
}
}
// GUI parameter modifiers
void onPendulaLengthChanged(float pendulaLength) {
@@ -341,6 +359,18 @@ void onPendulaRestitutionChanged(float pendulaRestitution) {
void floorSliderValue(float notUsed) {
gPendulaQty = floor(gPendulaQty);
gDisplacedPendula = floor(gDisplacedPendula);
}
void applyForceWithForceScalar(float forceScalar) {
if(nex){
btScalar appliedForce = forceScalar * gDisplacementForce;
if(fabs(gForceScalar) < 0.2f)
gForceScalar = 0;
nex->applyPendulumForce(appliedForce);
}
}
CommonExampleInterface* ET_NewtonsCradleCreateFunc(

View File

@@ -13,10 +13,10 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef ET_NEWTONIAN_PENDULUM_EXAMPLE_H
#define ET_NEWTONIAN_PENDULUM_EXAMPLE_H
#ifndef ET_NEWTONS_CRADLE_EXAMPLE_H
#define ET_NEWTONS_CRADLE_EXAMPLE_H
class CommonExampleInterface* ET_NewtonsCradleCreateFunc(struct CommonExampleOptions& options);
#endif //ET_NEWTONIAN_PENDULUM_EXAMPLE_H
#endif //ET_NEWTONS_CRADLE_EXAMPLE_H

View File

@@ -0,0 +1,387 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2015 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "NewtonsRopeCradle.h"
#include <vector> // TODO: Should I use another data structure?
#include <iterator>
#include "btBulletDynamicsCommon.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "../CommonInterfaces/CommonRigidBodyBase.h"
#include "BulletSoftBody/btSoftRigidDynamicsWorld.h"
#include "BulletSoftBody/btSoftBodyHelpers.h"
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
#include "../CommonInterfaces/CommonParameterInterface.h"
static btScalar gPendulaQty = 5; // Number of pendula in newton's cradle
//TODO: This would actually be an Integer, but the Slider does not like integers, so I floor it when changed
static btScalar gDisplacedPendula = 1; // number of displaced pendula
//TODO: This is an int as well
static btScalar gPendulaRestitution = 1; // pendula restition when hitting against each other
static btScalar gSphereRadius = 1; // pendula radius
static btScalar gInitialPendulumWidth = 4; // default pendula width
static btScalar gInitialPendulumHeight = 8; // default pendula height
static btScalar gRopeResolution = 1; // default rope resolution (number of links as in a chain)
static btScalar gDisplacementForce = 30; // default force to displace the pendula
static btScalar gForceScalar = 0; // default force scalar to apply a displacement
struct NewtonsRopeCradleExample : public CommonRigidBodyBase {
NewtonsRopeCradleExample(struct GUIHelperInterface* helper) :
CommonRigidBodyBase(helper) {
}
virtual ~NewtonsRopeCradleExample(){}
virtual void initPhysics();
virtual void stepSimulation(float deltaTime);
virtual void renderScene();
virtual void applyPendulumForce(btScalar pendulumForce);
void createEmptyDynamicsWorld()
{
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase();
m_solver = new btSequentialImpulseConstraintSolver;
m_dynamicsWorld = new btSoftRigidDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration);
m_dynamicsWorld->setGravity(btVector3(0, -10, 0));
softBodyWorldInfo.m_broadphase = m_broadphase;
softBodyWorldInfo.m_dispatcher = m_dispatcher;
softBodyWorldInfo.m_gravity = m_dynamicsWorld->getGravity();
softBodyWorldInfo.m_sparsesdf.Initialize();
}
virtual void createRopePendulum(btSphereShape* colShape,
const btVector3& position, const btQuaternion& pendulumOrientation, btScalar width, btScalar height, btScalar mass);
virtual void changePendulaRestitution(btScalar restitution);
virtual void connectWithRope(btRigidBody* body1, btRigidBody* body2);
virtual bool keyboardCallback(int key, int state);
virtual btSoftRigidDynamicsWorld* getSoftDynamicsWorld()
{
///just make it a btSoftRigidDynamicsWorld please
///or we will add type checking
return (btSoftRigidDynamicsWorld*) m_dynamicsWorld;
}
void resetCamera()
{
float dist = 41;
float pitch = 52;
float yaw = 35;
float targetPos[3]={0,0.46,0};
m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
}
std::vector<btSliderConstraint*> constraints;
std::vector<btRigidBody*> pendula;
btSoftBodyWorldInfo softBodyWorldInfo;
};
static NewtonsRopeCradleExample* nex = NULL;
void onRopePendulaRestitutionChanged(float pendulaRestitution);
void floorRSliderValue(float notUsed);
void applyRForceWithForceScalar(float forceScalar);
void NewtonsRopeCradleExample::initPhysics()
{
{ // create a slider to change the number of pendula
SliderParams slider("Number of Pendula", &gPendulaQty);
slider.m_minVal = 1;
slider.m_maxVal = 50;
slider.m_callback = floorRSliderValue; // hack to get integer values
slider.m_clampToNotches = false;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
slider);
}
{ // create a slider to change the number of displaced pendula
SliderParams slider("Number of Displaced Pendula", &gDisplacedPendula);
slider.m_minVal = 0;
slider.m_maxVal = 49;
slider.m_callback = floorRSliderValue; // hack to get integer values
slider.m_clampToNotches = false;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
slider);
}
{ // create a slider to change the pendula restitution
SliderParams slider("Pendula Restitution", &gPendulaRestitution);
slider.m_minVal = 0;
slider.m_maxVal = 1;
slider.m_clampToNotches = false;
slider.m_callback = onRopePendulaRestitutionChanged;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
slider);
}
{ // create a slider to change the rope resolution
SliderParams slider("Rope Resolution", &gRopeResolution);
slider.m_minVal = 1;
slider.m_maxVal = 20;
slider.m_clampToNotches = false;
slider.m_callback = floorRSliderValue;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
slider);
}
{ // create a slider to change the pendulum width
SliderParams slider("Pendulum Width", &gInitialPendulumWidth);
slider.m_minVal = 0;
slider.m_maxVal = 40;
slider.m_clampToNotches = false;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
slider);
}
{ // create a slider to change the pendulum height
SliderParams slider("Pendulum Height", &gInitialPendulumHeight);
slider.m_minVal = 0;
slider.m_maxVal = 40;
slider.m_clampToNotches = false;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
slider);
}
{ // create a slider to change the force to displace the lowest pendulum
SliderParams slider("Displacement force", &gDisplacementForce);
slider.m_minVal = 0.1;
slider.m_maxVal = 200;
slider.m_clampToNotches = false;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
slider);
}
{ // create a slider to apply the force by slider
SliderParams slider("Apply displacement force", &gForceScalar);
slider.m_minVal = -1;
slider.m_maxVal = 1;
slider.m_clampToNotches = false;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
slider);
}
m_guiHelper->setUpAxis(1);
createEmptyDynamicsWorld();
// create a debug drawer
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
if (m_dynamicsWorld->getDebugDrawer())
m_dynamicsWorld->getDebugDrawer()->setDebugMode(
btIDebugDraw::DBG_DrawWireframe
+ btIDebugDraw::DBG_DrawContactPoints
+ btIDebugDraw::DBG_DrawConstraints
+ btIDebugDraw::DBG_DrawConstraintLimits);
{ // create the pendula starting at the indicated position below and where each pendulum has the following mass
btScalar pendulumMass(1.0f);
btVector3 position(0.0f,15.0f,0.0f); // initial left-most pendulum position
btQuaternion orientation(0,0,0,1); // orientation of the pendula
// Re-using the same collision is better for memory usage and performance
btSphereShape* pendulumShape = new btSphereShape(gSphereRadius);
m_collisionShapes.push_back(pendulumShape);
for (int i = 0; i < floor(gPendulaQty); i++) {
// create pendulum
createRopePendulum(pendulumShape, position, orientation,gInitialPendulumWidth,
gInitialPendulumHeight, pendulumMass);
// displace the pendula 1.05 sphere size, so that they all nearly touch (small spacings in between)
position.setX(position.x()-2.1f * gSphereRadius);
}
}
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void NewtonsRopeCradleExample::connectWithRope(btRigidBody* body1, btRigidBody* body2)
{
btSoftBody* softBodyRope0 = btSoftBodyHelpers::CreateRope(softBodyWorldInfo,body1->getWorldTransform().getOrigin(),body2->getWorldTransform().getOrigin(),gRopeResolution,0);
softBodyRope0->setTotalMass(0.1f);
softBodyRope0->appendAnchor(0,body1);
softBodyRope0->appendAnchor(softBodyRope0->m_nodes.size()-1,body2);
softBodyRope0->m_cfg.piterations = 5;
softBodyRope0->m_cfg.kDP = 0.005f;
softBodyRope0->m_cfg.kSHR = 1;
softBodyRope0->m_cfg.kCHR = 1;
softBodyRope0->m_cfg.kKHR = 1;
getSoftDynamicsWorld()->addSoftBody(softBodyRope0);
}
void NewtonsRopeCradleExample::stepSimulation(float deltaTime) {
applyRForceWithForceScalar(gForceScalar); // apply force defined by apply force slider
if (m_dynamicsWorld) {
m_dynamicsWorld->stepSimulation(deltaTime);
}
}
void NewtonsRopeCradleExample::createRopePendulum(btSphereShape* colShape,
const btVector3& position, const btQuaternion& pendulumOrientation, btScalar width, btScalar height, btScalar mass) {
// The pendulum looks like this (names when built):
// O O topSphere1 topSphere2
// \ /
// O bottomSphere
//create a dynamic pendulum
btTransform startTransform;
startTransform.setIdentity();
// calculate sphere positions
btVector3 topSphere1RelPosition(0,0,width);
btVector3 topSphere2RelPosition(0,0,-width);
btVector3 bottomSphereRelPosition(0,-height,0);
// position the top sphere above ground with appropriate orientation
startTransform.setOrigin(btVector3(0,0,0)); // no translation intitially
startTransform.setRotation(pendulumOrientation); // pendulum rotation
startTransform.setOrigin(startTransform * topSphere1RelPosition); // rotate this position
startTransform.setOrigin(position + startTransform.getOrigin()); // add non-rotated position to the relative position
btRigidBody* topSphere1 = createRigidBody(0, startTransform, colShape); // make top sphere static
// position the top sphere above ground with appropriate orientation
startTransform.setOrigin(btVector3(0,0,0)); // no translation intitially
startTransform.setRotation(pendulumOrientation); // pendulum rotation
startTransform.setOrigin(startTransform * topSphere2RelPosition); // rotate this position
startTransform.setOrigin(position + startTransform.getOrigin()); // add non-rotated position to the relative position
btRigidBody* topSphere2 = createRigidBody(0, startTransform, colShape); // make top sphere static
// position the bottom sphere below the top sphere
startTransform.setOrigin(btVector3(0,0,0)); // no translation intitially
startTransform.setRotation(pendulumOrientation); // pendulum rotation
startTransform.setOrigin(startTransform * bottomSphereRelPosition); // rotate this position
startTransform.setOrigin(position + startTransform.getOrigin()); // add non-rotated position to the relative position
btRigidBody* bottomSphere = createRigidBody(mass, startTransform, colShape);
bottomSphere->setFriction(0); // we do not need friction here
pendula.push_back(bottomSphere);
// disable the deactivation when objects do not move anymore
topSphere1->setActivationState(DISABLE_DEACTIVATION);
topSphere2->setActivationState(DISABLE_DEACTIVATION);
bottomSphere->setActivationState(DISABLE_DEACTIVATION);
bottomSphere->setRestitution(gPendulaRestitution); // set pendula restitution
// add ropes between spheres
connectWithRope(topSphere1, bottomSphere);
connectWithRope(topSphere2, bottomSphere);
}
void NewtonsRopeCradleExample::renderScene()
{
CommonRigidBodyBase::renderScene();
btSoftRigidDynamicsWorld* softWorld = getSoftDynamicsWorld();
for ( int i=0;i<softWorld->getSoftBodyArray().size();i++)
{
btSoftBody* psb=(btSoftBody*)softWorld->getSoftBodyArray()[i];
//if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe)))
{
btSoftBodyHelpers::DrawFrame(psb,softWorld->getDebugDrawer());
btSoftBodyHelpers::Draw(psb,softWorld->getDebugDrawer(),softWorld->getDrawFlags());
}
}
}
void NewtonsRopeCradleExample::changePendulaRestitution(btScalar restitution) {
for (std::vector<btRigidBody*>::iterator rit = pendula.begin();
rit != pendula.end(); rit++) {
btAssert((*rit) && "Null constraint");
(*rit)->setRestitution(restitution);
}
}
bool NewtonsRopeCradleExample::keyboardCallback(int key, int state) {
//b3Printf("Key pressed: %d in state %d \n",key,state);
// key 3
switch (key) {
case '3' /*ASCII for 3*/: {
applyPendulumForce(gDisplacementForce);
return true;
}
}
return false;
}
void NewtonsRopeCradleExample::applyPendulumForce(btScalar pendulumForce){
if(pendulumForce != 0){
b3Printf("Apply %f to pendulum",pendulumForce);
for (int i = 0; i < gDisplacedPendula; i++) {
if (gDisplacedPendula >= 0 && gDisplacedPendula <= gPendulaQty)
pendula[i]->applyCentralForce(btVector3(pendulumForce, 0, 0));
}
}
}
// GUI parameter modifiers
void onRopePendulaRestitutionChanged(float pendulaRestitution) {
if (nex){
nex->changePendulaRestitution(pendulaRestitution);
}
}
void floorRSliderValue(float notUsed) {
gPendulaQty = floor(gPendulaQty);
gDisplacedPendula = floor(gDisplacedPendula);
gRopeResolution = floor(gRopeResolution);
}
void applyRForceWithForceScalar(float forceScalar) {
if(nex){
btScalar appliedForce = forceScalar * gDisplacementForce;
if(fabs(gForceScalar) < 0.2f)
gForceScalar = 0;
nex->applyPendulumForce(appliedForce);
}
}
CommonExampleInterface* ET_NewtonsRopeCradleCreateFunc(
CommonExampleOptions& options) {
nex = new NewtonsRopeCradleExample(options.m_guiHelper);
return nex;
}

View File

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

View File

@@ -134,7 +134,8 @@ void RigidBodyFromObjExample::initPhysics()
int shapeId = m_guiHelper->registerGraphicsShape(&glmesh->m_vertices->at(0).xyzw[0],
glmesh->m_numvertices,
&glmesh->m_indices->at(0),
glmesh->m_numIndices);
glmesh->m_numIndices,
B3_GL_TRIANGLES, -1);
shape->setUserIndex(shapeId);
int renderInstance = m_guiHelper->registerGraphicsInstance(shapeId,pos,orn,color,scaling);
body->setUserIndex(renderInstance);

View File

@@ -38,7 +38,8 @@ files {
"../Importers/ImportURDFDemo/URDF2Bullet.cpp",
"../Importers/ImportURDFDemo/UrdfParser.cpp",
"../Importers/ImportURDFDemo/urdfStringSplit.cpp",
"../Importers/ImportMeshUtility/b3ImportMeshUtility.cpp",
"../ThirdPartyLibs/stb_image/stb_image.cpp",
}
@@ -89,7 +90,10 @@ files {
"../Importers/ImportURDFDemo/URDF2Bullet.cpp",
"../Importers/ImportURDFDemo/UrdfParser.cpp",
"../Importers/ImportURDFDemo/urdfStringSplit.cpp",
"../Importers/ImportMeshUtility/b3ImportMeshUtility.cpp",
"../ThirdPartyLibs/stb_image/stb_image.cpp",
"../Utils/b3Clock.cpp",
"../Utils/b3Clock.h",
}
if os.is("Linux") then initX11() end
@@ -153,7 +157,8 @@ files {
"../Importers/ImportURDFDemo/URDF2Bullet.cpp",
"../Importers/ImportURDFDemo/UrdfParser.cpp",
"../Importers/ImportURDFDemo/urdfStringSplit.cpp",
"../Importers/ImportMeshUtility/b3ImportMeshUtility.cpp",
"../ThirdPartyLibs/stb_image/stb_image.cpp",
}
if os.is("Linux") then initX11() end
@@ -213,6 +218,7 @@ files {
"../Importers/ImportURDFDemo/URDF2Bullet.cpp",
"../Importers/ImportURDFDemo/UrdfParser.cpp",
"../Importers/ImportURDFDemo/urdfStringSplit.cpp",
"../Importers/ImportMeshUtility/b3ImportMeshUtility.cpp",
"../ThirdPartyLibs/stb_image/stb_image.cpp",
}

View File

@@ -285,7 +285,7 @@ char* makeExeToBspFilename(const char* lpCmdLine)
}
struct CommonExampleInterface* ImportBspCreateFunc(struct CommonExampleOptions& options)
CommonExampleInterface* ImportBspCreateFunc(struct CommonExampleOptions& options)
{
BspDemo* demo = new BspDemo(options.m_guiHelper);

View File

@@ -1,15 +1,12 @@
#include "b3ImportMeshUtility.h"
#include <vector>
#include "../../OpenGLWindow/GLInstancingRenderer.h"
#include"Wavefront/tiny_obj_loader.h"
#include "../../OpenGLWindow/GLInstanceGraphicsShape.h"
#include "btBulletDynamicsCommon.h"
#include "../../OpenGLWindow/SimpleOpenGL3App.h"
#include"../../ThirdPartyLibs/Wavefront/tiny_obj_loader.h"
#include "LinearMath/btVector3.h"
#include "../ImportObjDemo/Wavefront2GLInstanceGraphicsShape.h"
#include "../../Utils/b3ResourcePath.h"
#include "Bullet3Common/b3FileUtils.h"
#include "stb_image/stb_image.h"
#include "../../ThirdPartyLibs/stb_image/stb_image.h"
bool b3ImportMeshUtility::loadAndRegisterMeshFromFileInternal(const std::string& fileName, b3ImportMeshData& meshData)
@@ -88,28 +85,4 @@ bool b3ImportMeshUtility::loadAndRegisterMeshFromFileInternal(const std::string&
return false;
}
int b3ImportMeshUtility::loadAndRegisterMeshFromFile(const std::string& fileName, CommonRenderInterface* renderer)
{
int shapeId = -1;
b3ImportMeshData meshData;
if (b3ImportMeshUtility::loadAndRegisterMeshFromFileInternal(fileName, meshData))
{
int textureIndex = -1;
if (meshData.m_textureImage)
{
textureIndex = renderer->registerTexture(meshData.m_textureImage,meshData.m_textureWidth,meshData.m_textureHeight);
}
shapeId = renderer->registerShape(&meshData.m_gfxShape->m_vertices->at(0).xyzw[0],
meshData.m_gfxShape->m_numvertices,
&meshData.m_gfxShape->m_indices->at(0),
meshData.m_gfxShape->m_numIndices,
B3_GL_TRIANGLES,
textureIndex);
delete meshData.m_gfxShape;
delete meshData.m_textureImage;
}
return shapeId;
}

View File

@@ -15,7 +15,6 @@ struct b3ImportMeshData
class b3ImportMeshUtility
{
public:
static int loadAndRegisterMeshFromFile(const std::string& fileName, class CommonRenderInterface* renderer);
static bool loadAndRegisterMeshFromFileInternal(const std::string& fileName, b3ImportMeshData& meshData);

View File

@@ -56,7 +56,31 @@ ImportObjSetup::~ImportObjSetup()
int loadAndRegisterMeshFromFile2(const std::string& fileName, CommonRenderInterface* renderer)
{
int shapeId = -1;
b3ImportMeshData meshData;
if (b3ImportMeshUtility::loadAndRegisterMeshFromFileInternal(fileName, meshData))
{
int textureIndex = -1;
if (meshData.m_textureImage)
{
textureIndex = renderer->registerTexture(meshData.m_textureImage,meshData.m_textureWidth,meshData.m_textureHeight);
}
shapeId = renderer->registerShape(&meshData.m_gfxShape->m_vertices->at(0).xyzw[0],
meshData.m_gfxShape->m_numvertices,
&meshData.m_gfxShape->m_indices->at(0),
meshData.m_gfxShape->m_numIndices,
B3_GL_TRIANGLES,
textureIndex);
delete meshData.m_gfxShape;
delete meshData.m_textureImage;
}
return shapeId;
}
@@ -77,7 +101,7 @@ void ImportObjSetup::initPhysics()
btVector3 scaling(1,1,1);
btVector3 color(1,1,1);
int shapeId = b3ImportMeshUtility::loadAndRegisterMeshFromFile(m_fileName, m_guiHelper->getRenderInterface());
int shapeId = loadAndRegisterMeshFromFile2(m_fileName, m_guiHelper->getRenderInterface());
if (shapeId>=0)
{
//int id =

View File

@@ -235,6 +235,60 @@ void ImportSDFSetup::initPhysics()
ConvertURDF2Bullet(u2b,creation, rootTrans,m_dynamicsWorld,m_useMultiBody,u2b.getPathPrefix(),true);
mb = creation.getBulletMultiBody();
if (m_useMultiBody && mb )
{
std::string* name = new std::string(u2b.getLinkName(u2b.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(u2b.getJointName(urdfLinkIndex));
std::string* linkName = new std::string(u2b.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* motorVel = &m_data->m_motorTargetVelocities[m_data->m_numMotors];
*motorVel = 0.f;
SliderParams slider(motorName,motorVel);
slider.m_minVal=-4;
slider.m_maxVal=4;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
float maxMotorImpulse = 10.1f;
btMultiBodyJointMotor* motor = new btMultiBodyJointMotor(mb,mbLinkIndex,0,0,maxMotorImpulse);
//motor->setMaxAppliedImpulse(0);
m_data->m_jointMotors[m_data->m_numMotors]=motor;
m_dynamicsWorld->addMultiBodyConstraint(motor);
m_data->m_numMotors++;
}
}
}
}
}

View File

@@ -13,9 +13,12 @@
class ImportSTLSetup : public CommonRigidBodyBase
{
const char* m_fileName;
btVector3 m_scaling;
public:
ImportSTLSetup(struct GUIHelperInterface* helper);
ImportSTLSetup(struct GUIHelperInterface* helper, const char* fileName);
virtual ~ImportSTLSetup();
virtual void initPhysics();
@@ -31,10 +34,19 @@ public:
};
ImportSTLSetup::ImportSTLSetup(struct GUIHelperInterface* helper)
:CommonRigidBodyBase(helper)
ImportSTLSetup::ImportSTLSetup(struct GUIHelperInterface* helper, const char* fileName)
:CommonRigidBodyBase(helper),
m_scaling(btVector3(10,10,10))
{
if (fileName)
{
m_fileName = fileName;
m_scaling = btVector3(0.01,0.01,0.01);
} else
{
m_fileName = "l_finger_tip.stl";
}
}
ImportSTLSetup::~ImportSTLSetup()
@@ -51,17 +63,16 @@ void ImportSTLSetup::initPhysics()
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe);
const char* fileName = "l_finger_tip.stl";
char relativeFileName[1024];
if (!b3ResourcePath::findResourcePath(fileName, relativeFileName, 1024))
if (!b3ResourcePath::findResourcePath(m_fileName, relativeFileName, 1024))
{
b3Warning("Cannot find file %s\n", fileName);
b3Warning("Cannot find file %s\n", m_fileName);
return;
}
btVector3 shift(0,0,0);
btVector3 scaling(10,10,10);
// int index=10;
{
@@ -81,12 +92,12 @@ void ImportSTLSetup::initPhysics()
m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId,position,orn,color,scaling);
m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId,position,orn,color,m_scaling);
}
}
class CommonExampleInterface* ImportSTLCreateFunc(struct CommonExampleOptions& options)
{
return new ImportSTLSetup(options.m_guiHelper);
return new ImportSTLSetup(options.m_guiHelper, options.m_fileName);
}

View File

@@ -66,17 +66,18 @@ static GLInstanceGraphicsShape* LoadMeshFromSTL(const char* relativeFileName)
for (int i=0;i<numTriangles;i++)
{
char* curPtr = &memoryBuffer[84+i*50];
MySTLTriangle* tri = (MySTLTriangle*) curPtr;
MySTLTriangle tmp;
memcpy(&tmp,curPtr,sizeof(MySTLTriangle));
GLInstanceVertex v0,v1,v2;
v0.uv[0] = v1.uv[0] = v2.uv[0] = 0.5;
v0.uv[1] = v1.uv[1] = v2.uv[1] = 0.5;
for (int v=0;v<3;v++)
{
v0.xyzw[v] = tri->vertex0[v];
v1.xyzw[v] = tri->vertex1[v];
v2.xyzw[v] = tri->vertex2[v];
v0.normal[v] = v1.normal[v] = v2.normal[v] = tri->normal[v];
v0.xyzw[v] = tmp.vertex0[v];
v1.xyzw[v] = tmp.vertex1[v];
v2.xyzw[v] = tmp.vertex2[v];
v0.normal[v] = v1.normal[v] = v2.normal[v] = tmp.normal[v];
}
v0.xyzw[3] = v1.xyzw[3] = v2.xyzw[3] = 0.f;

View File

@@ -13,7 +13,7 @@ subject to the following restrictions:
#include "BulletUrdfImporter.h"
#include "../../CommonInterfaces/CommonRenderInterface.h"
#include "URDFImporterInterface.h"
#include "btBulletCollisionCommon.h"
@@ -26,12 +26,20 @@ subject to the following restrictions:
#include <string>
#include "../../Utils/b3ResourcePath.h"
#include "../ImportMeshUtility/b3ImportMeshUtility.h"
#include <iostream>
#include <fstream>
#include "UrdfParser.h"
struct MyTexture
{
int m_width;
int m_height;
unsigned char* textureData;
};
struct BulletURDFInternalData
{
UrdfParser m_urdfParser;
@@ -100,7 +108,8 @@ struct BulletErrorLogger : public ErrorLogger
bool BulletURDFImporter::loadURDF(const char* fileName, bool forceFixedBase)
{
if (strlen(fileName)==0)
return false;
//int argc=0;
char relativeFileName[1024];
@@ -124,7 +133,7 @@ bool BulletURDFImporter::loadURDF(const char* fileName, bool forceFixedBase)
std::fstream xml_file(relativeFileName, std::fstream::in);
while ( xml_file.good() )
while ( xml_file.good())
{
std::string line;
std::getline( xml_file, line);
@@ -166,7 +175,7 @@ bool BulletURDFImporter::loadSDF(const char* fileName, bool forceFixedBase)
m_data->m_pathPrefix[0] = 0;
if (!fileFound){
std::cerr << "URDF file not found" << std::endl;
std::cerr << "SDF file not found" << std::endl;
return false;
} else
{
@@ -267,14 +276,25 @@ void BulletURDFImporter::getMassAndInertia(int linkIndex, btScalar& mass,btVect
//the link->m_inertia is NOT necessarily aligned with the inertial frame
//so an additional transform might need to be computed
UrdfLink* const* linkPtr = m_data->m_urdfParser.getModel().m_links.getAtIndex(linkIndex);
btAssert(linkPtr);
if (linkPtr)
{
UrdfLink* link = *linkPtr;
mass = link->m_inertia.m_mass;
if (link->m_parentJoint==0 && m_data->m_urdfParser.getModel().m_overrideFixedBase)
{
mass = 0.f;
localInertiaDiagonal.setValue(0,0,0);
}
else
{
mass = link->m_inertia.m_mass;
localInertiaDiagonal.setValue(link->m_inertia.m_ixx,link->m_inertia.m_iyy,
link->m_inertia.m_izz);
}
inertialFrame = link->m_inertia.m_linkLocalFrame;
localInertiaDiagonal.setValue(link->m_inertia.m_ixx,link->m_inertia.m_iyy,
link->m_inertia.m_izz);
}
else
{
@@ -578,7 +598,7 @@ btCollisionShape* convertURDFToCollisionShape(const UrdfCollision* collision, co
}
static void convertURDFToVisualShapeInternal(const UrdfVisual* visual, const char* urdfPathPrefix, const btTransform& visualTransform, btAlignedObjectArray<GLInstanceVertex>& verticesOut, btAlignedObjectArray<int>& indicesOut)
static void convertURDFToVisualShapeInternal(const UrdfVisual* visual, const char* urdfPathPrefix, const btTransform& visualTransform, btAlignedObjectArray<GLInstanceVertex>& verticesOut, btAlignedObjectArray<int>& indicesOut, btAlignedObjectArray<MyTexture>& texturesOut)
{
@@ -682,7 +702,23 @@ static void convertURDFToVisualShapeInternal(const UrdfVisual* visual, const cha
{
case FILE_OBJ:
{
glmesh = LoadMeshFromObj(fullPath,visualPathPrefix);
// glmesh = LoadMeshFromObj(fullPath,visualPathPrefix);
b3ImportMeshData meshData;
if (b3ImportMeshUtility::loadAndRegisterMeshFromFileInternal(fullPath, meshData))
{
if (meshData.m_textureImage)
{
MyTexture texData;
texData.m_width = meshData.m_textureWidth;
texData.m_height = meshData.m_textureHeight;
texData.textureData = meshData.m_textureImage;
texturesOut.push_back(texData);
}
glmesh = meshData.m_gfxShape;
}
break;
}
@@ -903,7 +939,8 @@ int BulletURDFImporter::convertLinkVisualShapes(int linkIndex, const char* pathP
btAlignedObjectArray<GLInstanceVertex> vertices;
btAlignedObjectArray<int> indices;
btTransform startTrans; startTrans.setIdentity();
btAlignedObjectArray<MyTexture> textures;
const UrdfModel& model = m_data->m_urdfParser.getModel();
UrdfLink* const* linkPtr = model.m_links.getAtIndex(linkIndex);
if (linkPtr)
@@ -923,14 +960,35 @@ int BulletURDFImporter::convertLinkVisualShapes(int linkIndex, const char* pathP
//printf("UrdfMaterial %s, rgba = %f,%f,%f,%f\n",mat->m_name.c_str(),mat->m_rgbaColor[0],mat->m_rgbaColor[1],mat->m_rgbaColor[2],mat->m_rgbaColor[3]);
m_data->m_linkColors.insert(linkIndex,mat->m_rgbaColor);
}
convertURDFToVisualShapeInternal(&vis, pathPrefix, localInertiaFrame.inverse()*childTrans, vertices, indices);
convertURDFToVisualShapeInternal(&vis, pathPrefix, localInertiaFrame.inverse()*childTrans, vertices, indices,textures);
}
}
if (vertices.size() && indices.size())
{
graphicsIndex = m_data->m_guiHelper->registerGraphicsShape(&vertices[0].xyzw[0], vertices.size(), &indices[0], indices.size());
// graphicsIndex = m_data->m_guiHelper->registerGraphicsShape(&vertices[0].xyzw[0], vertices.size(), &indices[0], indices.size());
//graphicsIndex = m_data->m_guiHelper->registerGraphicsShape(&vertices[0].xyzw[0], vertices.size(), &indices[0], indices.size());
//CommonRenderInterface* renderer = m_data->m_guiHelper->getRenderInterface();
if (1)
{
int textureIndex = -1;
if (textures.size())
{
textureIndex = m_data->m_guiHelper->registerTexture(textures[0].textureData,textures[0].m_width,textures[0].m_height);
}
graphicsIndex = m_data->m_guiHelper->registerGraphicsShape(&vertices[0].xyzw[0], vertices.size(), &indices[0], indices.size(),B3_GL_TRIANGLES,textureIndex);
}
}
//delete textures
for (int i=0;i<textures.size();i++)
{
delete textures[i].textureData;
}
return graphicsIndex;
}
@@ -947,6 +1005,17 @@ bool BulletURDFImporter::getLinkColor(int linkIndex, btVector4& colorRGBA) const
return false;
}
bool BulletURDFImporter::getLinkContactInfo(int linkIndex, URDFLinkContactInfo& contactInfo ) const
{
UrdfLink* const* linkPtr = m_data->m_urdfParser.getModel().m_links.getAtIndex(linkIndex);
if (linkPtr)
{
const UrdfLink* link = *linkPtr;
contactInfo = link->m_contactInfo;
return true;
}
return false;
}
void BulletURDFImporter::convertLinkVisualShapes2(int linkIndex, const char* pathPrefix, const btTransform& localInertiaFrame, class btCollisionObject* colObj) const
{
@@ -989,13 +1058,14 @@ btCollisionShape* BulletURDFImporter::getAllocatedCollisionShape(int index)
{
const UrdfCollision& col = link->m_collisionArray[v];
btCollisionShape* childShape = convertURDFToCollisionShape(&col ,pathPrefix);
m_data->m_allocatedCollisionShapes.push_back(childShape);
if (childShape)
{
btTransform childTrans = col.m_linkLocalFrame;
compoundShape->addChildShape(localInertiaFrame.inverse()*childTrans,childShape);
}
}
}
}

View File

@@ -37,6 +37,8 @@ public:
virtual std::string getLinkName(int linkIndex) const;
virtual bool getLinkColor(int linkIndex, btVector4& colorRGBA) const;
virtual bool getLinkContactInfo(int linkIndex, URDFLinkContactInfo& contactInfo ) const;
virtual std::string getJointName(int linkIndex) const;

View File

@@ -65,7 +65,8 @@ btAlignedObjectArray<std::string> gFileNameArray;
struct ImportUrdfInternalData
{
ImportUrdfInternalData()
:m_numMotors(0)
:m_numMotors(0),
m_mb(0)
{
for (int i=0;i<MAX_NUM_MOTORS;i++)
{
@@ -74,10 +75,13 @@ struct ImportUrdfInternalData
}
}
btScalar m_motorTargetVelocities[MAX_NUM_MOTORS];
btMultiBodyJointMotor* m_jointMotors [MAX_NUM_MOTORS];
btGeneric6DofSpring2Constraint* m_generic6DofJointMotors [MAX_NUM_MOTORS];
int m_numMotors;
btMultiBody* m_mb;
btRigidBody* m_rb;
};
@@ -203,7 +207,7 @@ void ImportUrdfSetup::initPhysics()
BulletURDFImporter u2b(m_guiHelper, 0);
bool loadOk = u2b.loadURDF(m_fileName);
bool loadOk = u2b.loadURDF(m_fileName);
#ifdef TEST_MULTIBODY_SERIALIZATION
//test to serialize a multibody to disk or shared memory, with base, link and joint names
@@ -223,7 +227,6 @@ void ImportUrdfSetup::initPhysics()
{
btMultiBody* mb = 0;
//todo: move these internal API called inside the 'ConvertURDF2Bullet' call, hidden from the user
@@ -232,7 +235,13 @@ void ImportUrdfSetup::initPhysics()
MyMultiBodyCreator creation(m_guiHelper);
ConvertURDF2Bullet(u2b,creation, identityTrans,m_dynamicsWorld,m_useMultiBody,u2b.getPathPrefix());
mb = creation.getBulletMultiBody();
m_data->m_rb = creation.getRigidBody();
m_data->m_mb = creation.getBulletMultiBody();
btMultiBody* mb = m_data->m_mb;
for (int i = 0; i < u2b.getNumAllocatedCollisionShapes(); i++)
{
m_collisionShapes.push_back(u2b.getAllocatedCollisionShape(i));
}
if (m_useMultiBody && mb )
{
@@ -343,6 +352,7 @@ void ImportUrdfSetup::initPhysics()
btVector3 groundHalfExtents(20,20,20);
groundHalfExtents[upAxis]=1.f;
btBoxShape* box = new btBoxShape(groundHalfExtents);
m_collisionShapes.push_back(box);
box->initializePolyhedralFeatures();
m_guiHelper->createCollisionShapeGraphicsObject(box);
@@ -357,8 +367,7 @@ void ImportUrdfSetup::initPhysics()
m_guiHelper->createRigidBodyGraphicsObject(body,color);
}
///this extra stepSimulation call makes sure that all the btMultibody transforms are properly propagates.
m_dynamicsWorld->stepSimulation(1. / 240., 0);// 1., 10, 1. / 240.);
}
#ifdef TEST_MULTIBODY_SERIALIZATION

View File

@@ -13,6 +13,7 @@
MyMultiBodyCreator::MyMultiBodyCreator(GUIHelperInterface* guiHelper)
:m_bulletMultiBody(0),
m_rigidBody(0),
m_guiHelper(guiHelper)
{
}
@@ -31,10 +32,10 @@ class btRigidBody* MyMultiBodyCreator::allocateRigidBody(int urdfLinkIndex, btSc
{
btRigidBody::btRigidBodyConstructionInfo rbci(mass, 0, colShape, localInertiaDiagonal);
rbci.m_startWorldTransform = initialWorldTrans;
btRigidBody* body = new btRigidBody(rbci);
body->forceActivationState(DISABLE_DEACTIVATION);
m_rigidBody = new btRigidBody(rbci);
m_rigidBody->forceActivationState(DISABLE_DEACTIVATION);
return body;
return m_rigidBody;
}
class btMultiBodyLinkCollider* MyMultiBodyCreator::allocateMultiBodyLinkCollider(int /*urdfLinkIndex*/, int mbLinkIndex, btMultiBody* multiBody)

View File

@@ -24,6 +24,7 @@ class MyMultiBodyCreator : public MultiBodyCreationInterface
protected:
btMultiBody* m_bulletMultiBody;
btRigidBody* m_rigidBody;
struct GUIHelperInterface* m_guiHelper;
@@ -62,6 +63,10 @@ public:
virtual void addLinkMapping(int urdfLinkIndex, int mbLinkIndex);
btMultiBody* getBulletMultiBody();
btRigidBody* getRigidBody()
{
return m_rigidBody;
}
int getNum6DofConstraints() const
{

View File

@@ -232,6 +232,13 @@ void ConvertURDF2BulletInternal(const URDFImporterInterface& u2b, MultiBodyCreat
if (mass)
{
compoundShape->calculateLocalInertia(mass, localInertiaDiagonal);
URDFLinkContactInfo contactInfo;
u2b.getLinkContactInfo(urdfLinkIndex,contactInfo);
//temporary inertia scaling until we load inertia from URDF
if (contactInfo.m_flags & URDF_CONTACT_HAS_INERTIA_SCALING)
{
localInertiaDiagonal*=contactInfo.m_inertiaScaling;
}
}
btRigidBody* linkRigidBody = 0;
@@ -392,9 +399,18 @@ void ConvertURDF2BulletInternal(const URDFImporterInterface& u2b, MultiBodyCreat
u2b.convertLinkVisualShapes2(urdfLinkIndex,pathPrefix,localInertialFrame,col);
btScalar friction = 0.5f;
URDFLinkContactInfo contactInfo;
u2b.getLinkContactInfo(urdfLinkIndex,contactInfo);
col->setFriction(friction);
if ((contactInfo.m_flags & URDF_CONTACT_HAS_LATERAL_FRICTION)!=0)
{
col->setFriction(contactInfo.m_lateralFriction);
}
if ((contactInfo.m_flags & URDF_CONTACT_HAS_ROLLING_FRICTION)!=0)
{
col->setRollingFriction(contactInfo.m_rollingFriction);
}
if (mbLinkIndex>=0) //???? double-check +/- 1
{

View File

@@ -6,6 +6,7 @@
#include "LinearMath/btTransform.h"
#include "URDFJointTypes.h"
class URDFImporterInterface
{
@@ -28,6 +29,9 @@ public:
virtual std::string getLinkName(int linkIndex) const =0;
/// 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;}
///this API will likely change, don't override it!
virtual bool getLinkContactInfo(int linkIndex, URDFLinkContactInfo& contactInfo ) const { return false;}
virtual std::string getJointName(int linkIndex) const = 0;

View File

@@ -11,6 +11,36 @@ enum UrdfJointTypes
URDFPlanarJoint,
URDFFixedJoint,
};
#include "LinearMath/btScalar.h"
enum URDF_LinkContactFlags
{
URDF_CONTACT_HAS_LATERAL_FRICTION=1,
URDF_CONTACT_HAS_ROLLING_FRICTION=2,
URDF_CONTACT_HAS_INERTIA_SCALING=2,
URDF_CONTACT_HAS_CONTACT_CFM=4,
URDF_CONTACT_HAS_CONTACT_ERP=8
};
struct URDFLinkContactInfo
{
btScalar m_lateralFriction;
btScalar m_rollingFriction;
btScalar m_inertiaScaling;
btScalar m_contactCfm;
btScalar m_contactErp;
int m_flags;
URDFLinkContactInfo()
:m_lateralFriction(0.5),
m_rollingFriction(0),
m_inertiaScaling(1),
m_contactCfm(0),
m_contactErp(0)
{
m_flags = URDF_CONTACT_HAS_LATERAL_FRICTION;
}
};
#endif //URDF_JOINT_TYPES_H

View File

@@ -61,7 +61,9 @@ static bool parseVector4(btVector4& vec4, const std::string& vector_str)
vec4.setZero();
btArray<std::string> pieces;
btArray<float> rgba;
urdfStringSplit(pieces, vector_str, urdfIsAnyOf(" "));
btAlignedObjectArray<std::string> strArray;
urdfIsAnyOf(" ", strArray);
urdfStringSplit(pieces, vector_str, strArray);
for (int i = 0; i < pieces.size(); ++i)
{
if (!pieces[i].empty())
@@ -82,7 +84,9 @@ static bool parseVector3(btVector3& vec3, const std::string& vector_str, ErrorLo
vec3.setZero();
btArray<std::string> pieces;
btArray<float> rgba;
urdfStringSplit(pieces, vector_str, urdfIsAnyOf(" "));
btAlignedObjectArray<std::string> strArray;
urdfIsAnyOf(" ", strArray);
urdfStringSplit(pieces, vector_str, strArray);
for (int i = 0; i < pieces.size(); ++i)
{
if (!pieces[i].empty())
@@ -225,6 +229,15 @@ bool UrdfParser::parseInertia(UrdfInertia& inertia, TiXmlElement* config, ErrorL
{
inertia.m_linkLocalFrame.setIdentity();
inertia.m_mass = 0.f;
if(m_parseSDF)
{
TiXmlElement* pose = config->FirstChildElement("pose");
if (pose)
{
parseTransform(inertia.m_linkLocalFrame, pose,logger,m_parseSDF);
}
}
// Origin
@@ -393,13 +406,22 @@ bool UrdfParser::parseGeometry(UrdfGeometry& geom, TiXmlElement* g, ErrorLogger*
}
geom.m_meshFileName = shape->Attribute("filename");
if (shape->Attribute("scale"))
geom.m_meshScale.setValue(1,1,1);
if (shape->Attribute("scale"))
{
parseVector3(geom.m_meshScale,shape->Attribute("scale"),logger);
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
{
geom.m_meshScale.setValue(1,1,1);
}
}
}
@@ -439,6 +461,15 @@ bool UrdfParser::parseCollision(UrdfCollision& collision, TiXmlElement* config,
collision.m_linkLocalFrame.setIdentity();
if(m_parseSDF)
{
TiXmlElement* pose = config->FirstChildElement("pose");
if (pose)
{
parseTransform(collision.m_linkLocalFrame, pose,logger,m_parseSDF);
}
}
// Origin
TiXmlElement *o = config->FirstChildElement("origin");
if (o)
@@ -465,7 +496,15 @@ bool UrdfParser::parseCollision(UrdfCollision& collision, TiXmlElement* config,
bool UrdfParser::parseVisual(UrdfModel& model, UrdfVisual& visual, TiXmlElement* config, ErrorLogger* logger)
{
visual.m_linkLocalFrame.setIdentity();
if(m_parseSDF)
{
TiXmlElement* pose = config->FirstChildElement("pose");
if (pose)
{
parseTransform(visual.m_linkLocalFrame, pose,logger,m_parseSDF);
}
}
// Origin
TiXmlElement *o = config->FirstChildElement("origin");
if (o)
@@ -490,29 +529,49 @@ bool UrdfParser::parseVisual(UrdfModel& model, UrdfVisual& visual, TiXmlElement*
// Material
TiXmlElement *mat = config->FirstChildElement("material");
//todo(erwincoumans) skip materials in SDF for now (due to complexity)
if (mat && !m_parseSDF)
if (mat)
{
// get material name
if (!mat->Attribute("name"))
{
logger->reportError("Visual material must contain a name attribute");
return false;
}
visual.m_materialName = mat->Attribute("name");
// try to parse material element in place
TiXmlElement *t = mat->FirstChildElement("texture");
TiXmlElement *c = mat->FirstChildElement("color");
if (t||c)
{
if (parseMaterial(visual.m_localMaterial, mat,logger))
{
UrdfMaterial* matPtr = new UrdfMaterial(visual.m_localMaterial);
model.m_materials.insert(matPtr->m_name.c_str(),matPtr);
visual.m_hasLocalMaterial = true;
}
}
if (m_parseSDF)
{
UrdfMaterial* matPtr = new UrdfMaterial;
matPtr->m_name = "mat";
if (name_char)
matPtr->m_name = name_char;
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;
}
}
else
{
// get material name
if (!mat->Attribute("name"))
{
logger->reportError("Visual material must contain a name attribute");
return false;
}
visual.m_materialName = mat->Attribute("name");
// try to parse material element in place
TiXmlElement *t = mat->FirstChildElement("texture");
TiXmlElement *c = mat->FirstChildElement("color");
if (t||c)
{
if (parseMaterial(visual.m_localMaterial, mat,logger))
{
UrdfMaterial* matPtr = new UrdfMaterial(visual.m_localMaterial);
model.m_materials.insert(matPtr->m_name.c_str(),matPtr);
visual.m_hasLocalMaterial = true;
}
}
}
}
return true;
@@ -529,6 +588,8 @@ bool UrdfParser::parseLink(UrdfModel& model, UrdfLink& link, TiXmlElement *confi
link.m_name = linkName;
if (m_parseSDF) {
TiXmlElement* pose = config->FirstChildElement("pose");
if (0==pose)
{
@@ -540,6 +601,54 @@ bool UrdfParser::parseLink(UrdfModel& model, UrdfLink& link, TiXmlElement *confi
}
}
{
//optional 'contact' parameters
TiXmlElement* ci = config->FirstChildElement("contact");
if (ci)
{
TiXmlElement *damping_xml = ci->FirstChildElement("inertia_scaling");
if (damping_xml)
{
if (m_parseSDF)
{
link.m_contactInfo.m_inertiaScaling = urdfLexicalCast<double>(damping_xml->GetText());
link.m_contactInfo.m_flags |= URDF_CONTACT_HAS_INERTIA_SCALING;
} else
{
if (!damping_xml->Attribute("value"))
{
logger->reportError("Link/contact: damping element must have value attribute");
return false;
}
link.m_contactInfo.m_inertiaScaling = urdfLexicalCast<double>(damping_xml->Attribute("value"));
link.m_contactInfo.m_flags |= URDF_CONTACT_HAS_INERTIA_SCALING;
}
}
{
TiXmlElement *friction_xml = ci->FirstChildElement("lateral_friction");
if (friction_xml)
{
if (m_parseSDF)
{
link.m_contactInfo.m_lateralFriction = urdfLexicalCast<double>(friction_xml->GetText());
} else
{
if (!friction_xml->Attribute("value"))
{
logger->reportError("Link/contact: lateral_friction element must have value attribute");
return false;
}
link.m_contactInfo.m_lateralFriction = urdfLexicalCast<double>(friction_xml->Attribute("value"));
}
}
}
}
}
// Inertial (optional)
TiXmlElement *i = config->FirstChildElement("inertial");
if (i)
@@ -572,7 +681,7 @@ bool UrdfParser::parseLink(UrdfModel& model, UrdfLink& link, TiXmlElement *confi
logger->reportWarning(link.m_name.c_str());
}
}
// Multiple Visuals (optional)
for (TiXmlElement* vis_xml = config->FirstChildElement("visual"); vis_xml; vis_xml = vis_xml->NextSiblingElement("visual"))
{
@@ -616,6 +725,8 @@ bool UrdfParser::parseJointLimits(UrdfJoint& joint, TiXmlElement* config, ErrorL
joint.m_upperLimit = 0.f;
joint.m_effortLimit = 0.f;
joint.m_velocityLimit = 0.f;
joint.m_jointDamping = 0.f;
joint.m_jointFriction = 0.f;
if (m_parseSDF)
{
@@ -872,7 +983,7 @@ bool UrdfParser::parseJoint(UrdfJoint& joint, TiXmlElement *config, ErrorLogger*
return false;
}
TiXmlElement *prop_xml = config->FirstChildElement("dynamics");
TiXmlElement *prop_xml = axis_xml->FirstChildElement("dynamics");
if (prop_xml)
{
if (!parseJointDynamics(joint, prop_xml,logger))
@@ -1227,19 +1338,36 @@ bool UrdfParser::loadSDF(const char* sdfText, ErrorLogger* logger)
return false;
}
TiXmlElement *world_xml = sdf_xml->FirstChildElement("world");
if (!world_xml)
{
logger->reportError("expected a world element");
return false;
}
//apparently, SDF doesn't require a "world" element, optional? URDF does.
TiXmlElement *world_xml = sdf_xml->FirstChildElement("world");
TiXmlElement* robot_xml = 0;
if (!world_xml)
{
logger->reportWarning("expected a world element, continuing without it.");
robot_xml = sdf_xml->FirstChildElement("model");
} else
{
robot_xml = world_xml->FirstChildElement("model");
}
// Get all model (robot) elements
for (TiXmlElement* robot_xml = world_xml->FirstChildElement("model"); robot_xml; robot_xml = robot_xml->NextSiblingElement("model"))
for (; robot_xml; robot_xml = robot_xml->NextSiblingElement("model"))
{
UrdfModel* localModel = new UrdfModel;
m_tmpModels.push_back(localModel);
TiXmlElement* stat = robot_xml->FirstChildElement("static");
if (0!=stat)
{
int val = int(atof(stat->GetText()));
if (val==1)
{
localModel->m_overrideFixedBase = true;
}
}
// Get robot name
const char *name = robot_xml->Attribute("name");

View File

@@ -99,6 +99,8 @@ struct UrdfLink
int m_linkIndex;
URDFLinkContactInfo m_contactInfo;
UrdfLink()
:m_parentLink(0),
m_parentJoint(0)
@@ -123,6 +125,15 @@ struct UrdfJoint
double m_jointDamping;
double m_jointFriction;
UrdfJoint()
:m_lowerLimit(0),
m_upperLimit(0),
m_effortLimit(0),
m_velocityLimit(0),
m_jointDamping(0),
m_jointFriction(0)
{
}
};
struct UrdfModel
@@ -134,6 +145,13 @@ struct UrdfModel
btHashMap<btHashString, UrdfJoint*> m_joints;
btArray<UrdfLink*> m_rootLinks;
bool m_overrideFixedBase;
UrdfModel()
:m_overrideFixedBase(false)
{
m_rootTransformInWorld.setIdentity();
}
};

View File

@@ -8,7 +8,7 @@
#include "urdfStringSplit.h"
void urdfStringSplit( btAlignedObjectArray<std::string>&pieces, const std::string& vector_str, btAlignedObjectArray<std::string> separators)
void urdfStringSplit( btAlignedObjectArray<std::string>&pieces, const std::string& vector_str, const btAlignedObjectArray<std::string>& separators)
{
assert(separators.size()==1);
if (separators.size()==1)
@@ -20,10 +20,9 @@ void urdfStringSplit( btAlignedObjectArray<std::string>&pieces, const std::strin
urdfStrArrayFree(strArray);
}
}
btAlignedObjectArray<std::string> urdfIsAnyOf(const char* seps)
void urdfIsAnyOf(const char* seps, btAlignedObjectArray<std::string>& strArray)
{
btAlignedObjectArray<std::string> strArray;
int numSeps = strlen(seps);
for (int i=0;i<numSeps;i++)
{
@@ -32,8 +31,6 @@ void urdfStringSplit( btAlignedObjectArray<std::string>&pieces, const std::strin
sep2[0] = seps[i];
strArray.push_back(sep2);
}
return strArray;
}

View File

@@ -7,9 +7,9 @@
#include "LinearMath/btAlignedObjectArray.h"
void urdfStringSplit( btAlignedObjectArray<std::string>&pieces, const std::string& vector_str, btAlignedObjectArray<std::string> separators);
void urdfStringSplit( btAlignedObjectArray<std::string>&pieces, const std::string& vector_str, const btAlignedObjectArray<std::string>& separators);
btAlignedObjectArray<std::string> urdfIsAnyOf(const char* seps);
void urdfIsAnyOf(const char* seps, btAlignedObjectArray<std::string>& strArray);
///The string split C code is by Lars Wirzenius
///See http://stackoverflow.com/questions/2531605/how-to-split-a-string-with-a-delimiter-larger-than-one-single-char

View File

@@ -105,7 +105,7 @@ InverseDynamicsExample::InverseDynamicsExample(struct GUIHelperInterface* helper
InverseDynamicsExample::~InverseDynamicsExample()
{
delete m_multiBody;
delete m_inverseModel;
delete m_timeSeriesCanvas;
}
@@ -157,7 +157,7 @@ void InverseDynamicsExample::initPhysics()
BulletURDFImporter u2b(m_guiHelper,0);
bool loadOk = u2b.loadURDF("kuka_lwr/kuka.urdf");
bool loadOk = u2b.loadURDF("kuka_iiwa/model.urdf");// lwr / kuka.urdf");
if (loadOk)
{
int rootLinkIndex = u2b.getRootLinkIndex();
@@ -166,6 +166,10 @@ void InverseDynamicsExample::initPhysics()
btTransform identityTrans;
identityTrans.setIdentity();
ConvertURDF2Bullet(u2b,creation, identityTrans,m_dynamicsWorld,true,u2b.getPathPrefix());
for (int i = 0; i < u2b.getNumAllocatedCollisionShapes(); i++)
{
m_collisionShapes.push_back(u2b.getAllocatedCollisionShape(i));
}
m_multiBody = creation.getBulletMultiBody();
if (m_multiBody)
{
@@ -221,13 +225,13 @@ void InverseDynamicsExample::initPhysics()
{
qd[dof] = 0;
char tmp[25];
sprintf(tmp,"q_desired[%zu]",dof);
sprintf(tmp,"q_desired[%u]",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[%zu]",dof);
sprintf(tmp,"q[%u]",dof);
q_name[dof] = tmp;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
btVector4 color = sJointCurveColors[dof&7];
@@ -336,6 +340,21 @@ void InverseDynamicsExample::stepSimulation(float deltaTime)
// todo(thomas) check that this is correct:
// want to advance by 10ms, with 1ms timesteps
m_dynamicsWorld->stepSimulation(1e-3,0);//,1e-3);
btAlignedObjectArray<btQuaternion> scratch_q;
btAlignedObjectArray<btVector3> scratch_m;
m_multiBody->forwardKinematics(scratch_q, scratch_m);
for (int i = 0; i < m_multiBody->getNumLinks(); i++)
{
//btVector3 pos = m_multiBody->getLink(i).m_cachedWorldTransform.getOrigin();
btTransform tr = m_multiBody->getLink(i).m_cachedWorldTransform;
btVector3 pos = tr.getOrigin() - quatRotate(tr.getRotation(), m_multiBody->getLink(i).m_dVector);
btVector3 localAxis = m_multiBody->getLink(i).m_axes[0].m_topVec;
//printf("link %d: %f,%f,%f, local axis:%f,%f,%f\n", i, pos.x(), pos.y(), pos.z(), localAxis.x(), localAxis.y(), localAxis.z());
}
}
}

View File

@@ -38,7 +38,8 @@ files {
"../Importers/ImportURDFDemo/URDF2Bullet.cpp",
"../Importers/ImportURDFDemo/UrdfParser.cpp",
"../Importers/ImportURDFDemo/urdfStringSplit.cpp",
"../Importers/ImportMeshUtility/b3ImportMeshUtility.cpp",
"../ThirdPartyLibs/stb_image/stb_image.cpp",
}
@@ -89,7 +90,9 @@ files {
"../Importers/ImportURDFDemo/URDF2Bullet.cpp",
"../Importers/ImportURDFDemo/UrdfParser.cpp",
"../Importers/ImportURDFDemo/urdfStringSplit.cpp",
"../Importers/ImportMeshUtility/b3ImportMeshUtility.cpp",
"../ThirdPartyLibs/stb_image/stb_image.cpp",
"../Utils/b3Clock.cpp",
}
if os.is("Linux") then initX11() end
@@ -153,7 +156,8 @@ files {
"../Importers/ImportURDFDemo/URDF2Bullet.cpp",
"../Importers/ImportURDFDemo/UrdfParser.cpp",
"../Importers/ImportURDFDemo/urdfStringSplit.cpp",
"../Importers/ImportMeshUtility/b3ImportMeshUtility.cpp",
"../ThirdPartyLibs/stb_image/stb_image.cpp",
}
if os.is("Linux") then initX11() end
@@ -211,6 +215,7 @@ files {
"../Importers/ImportURDFDemo/URDF2Bullet.cpp",
"../Importers/ImportURDFDemo/UrdfParser.cpp",
"../Importers/ImportURDFDemo/urdfStringSplit.cpp",
"../Importers/ImportMeshUtility/b3ImportMeshUtility.cpp",
"../ThirdPartyLibs/stb_image/stb_image.cpp",
}

View File

@@ -0,0 +1,385 @@
#include "InverseKinematicsExample.h"
#include "../CommonInterfaces/CommonGraphicsAppInterface.h"
#include "Bullet3Common/b3Quaternion.h"
#include "Bullet3Common/b3Transform.h"
#include "Bullet3Common/b3AlignedObjectArray.h"
#include "../CommonInterfaces/CommonRenderInterface.h"
#include "../CommonInterfaces/CommonExampleInterface.h"
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
#include "../OpenGLWindow/OpenGLInclude.h"
#include "BussIK/Node.h"
#include "BussIK/Tree.h"
#include "BussIK/Jacobian.h"
#include "BussIK/VectorRn.h"
#define RADIAN(X) ((X)*RadiansToDegrees)
#define MAX_NUM_NODE 1000
#define MAX_NUM_THETA 1000
#define MAX_NUM_EFFECT 100
double T = 0;
VectorR3 target1[MAX_NUM_EFFECT];
// Make slowdown factor larger to make the simulation take larger, less frequent steps
// Make the constant factor in Tstep larger to make time pass more quickly
//const int SlowdownFactor = 40;
const int SlowdownFactor = 0; // Make higher to take larger steps less frequently
const int SleepsPerStep=SlowdownFactor;
int SleepCounter=0;
//const double Tstep = 0.0005*(double)SlowdownFactor; // Time step
int AxesList; /* list to hold the axes */
int AxesOn; /* ON or OFF */
float Scale, Scale2; /* scaling factors */
int JointLimitsOn;
int RestPositionOn;
int UseJacobianTargets1;
int numIteration = 1;
double error = 0.0;
double errorDLS = 0.0;
double errorSDLS = 0.0;
double sumError = 0.0;
double sumErrorDLS = 0.0;
double sumErrorSDLS = 0.0;
#ifdef _DYNAMIC
bool initMaxDist = true;
extern double Excess[];
extern double dsnorm[];
#endif
void Reset(Tree &tree, Jacobian* m_ikJacobian)
{
AxesOn = false;
Scale = 1.0;
Scale2 = 0.0; /* because add 1. to it in Display() */
JointLimitsOn = true;
RestPositionOn = false;
UseJacobianTargets1 = false;
tree.Init();
tree.Compute();
m_ikJacobian->Reset();
}
// Update target positions
void UpdateTargets( double T2, Tree & treeY) {
double T = T2 / 5.;
target1[0].Set(0.6*b3Sin(0), 0.6*b3Cos(0), 0.5+0.4*b3Sin(3 * T));
}
// Does a single update (on one kind of tree)
void DoUpdateStep(double Tstep, Tree & treeY, Jacobian *jacob, int ikMethod) {
if ( SleepCounter==0 ) {
T += Tstep;
UpdateTargets( T , treeY);
}
if ( UseJacobianTargets1 ) {
jacob->SetJtargetActive();
}
else {
jacob->SetJendActive();
}
jacob->ComputeJacobian(); // Set up Jacobian and deltaS vectors
// Calculate the change in theta values
switch (ikMethod) {
case IK_JACOB_TRANS:
jacob->CalcDeltaThetasTranspose(); // Jacobian transpose method
break;
case IK_DLS:
jacob->CalcDeltaThetasDLS(); // Damped least squares method
break;
case IK_DLS_SVD:
jacob->CalcDeltaThetasDLSwithSVD();
break;
case IK_PURE_PSEUDO:
jacob->CalcDeltaThetasPseudoinverse(); // Pure pseudoinverse method
break;
case IK_SDLS:
jacob->CalcDeltaThetasSDLS(); // Selectively damped least squares method
break;
default:
jacob->ZeroDeltaThetas();
break;
}
if ( SleepCounter==0 ) {
jacob->UpdateThetas(); // Apply the change in the theta values
jacob->UpdatedSClampValue();
SleepCounter = SleepsPerStep;
}
else {
SleepCounter--;
}
}
///quick demo showing the right-handed coordinate system and positive rotations around each axis
class InverseKinematicsExample : public CommonExampleInterface
{
CommonGraphicsApp* m_app;
int m_ikMethod;
Tree m_ikTree;
b3AlignedObjectArray<Node*> m_ikNodes;
Jacobian* m_ikJacobian;
float m_x;
float m_y;
float m_z;
b3AlignedObjectArray<int> m_movingInstances;
int m_targetInstance;
enum
{
numCubesX = 20,
numCubesY = 20
};
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_app->setUpAxis(2);
{
b3Vector3 extents=b3MakeVector3(100,100,100);
extents[m_app->getUpAxis()]=1;
int xres = 20;
int yres = 20;
b3Vector4 color0=b3MakeVector4(0.4, 0.4, 0.4,1);
b3Vector4 color1=b3MakeVector4(0.6, 0.6, 0.6,1);
m_app->registerGrid(xres, yres, color0, color1);
}
///create some graphics proxy for the tracking target
///the endeffector tries to track it using Inverse Kinematics
{
int sphereId = m_app->registerGraphicsUnitSphereShape(SPHERE_LOD_MEDIUM);
b3Vector3 pos = b3MakeVector3(1,1,1);
pos[app->getUpAxis()] = 1;
b3Quaternion orn(0, 0, 0, 1);
b3Vector4 color = b3MakeVector4(1., 0.3, 0.3, 1);
b3Vector3 scaling = b3MakeVector3(.02, .02, .02);
m_targetInstance = m_app->m_renderer->registerGraphicsInstance(sphereId, pos, orn, color, scaling);
}
m_app->m_renderer->writeTransforms();
}
virtual ~InverseKinematicsExample()
{
m_app->m_renderer->enableBlend(false);
}
virtual void physicsDebugDraw(int debugDrawMode)
{
}
virtual void initPhysics()
{
BuildKukaIIWAShape();
m_ikJacobian = new Jacobian(&m_ikTree);
Reset(m_ikTree,m_ikJacobian);
}
virtual void exitPhysics()
{
delete m_ikJacobian;
m_ikJacobian = 0;
}
void BuildKukaIIWAShape();
void getLocalTransform(const Node* node, b3Transform& act)
{
b3Vector3 axis = b3MakeVector3(node->v.x, node->v.y, node->v.z);
b3Quaternion rot(0, 0, 0, 1);
if (axis.length())
{
rot = b3Quaternion (axis, node->theta);
}
act.setIdentity();
act.setRotation(rot);
act.setOrigin(b3MakeVector3(node->r.x, node->r.y, node->r.z));
}
void MyDrawTree(Node* node, const b3Transform& tr)
{
b3Vector3 lineColor = b3MakeVector3(0, 0, 0);
int lineWidth = 2;
if (node != 0) {
// glPushMatrix();
b3Vector3 pos = b3MakeVector3(tr.getOrigin().x, tr.getOrigin().y, tr.getOrigin().z);
b3Vector3 color = b3MakeVector3(0, 1, 0);
int pointSize = 10;
m_app->m_renderer->drawPoint(pos, color, pointSize);
m_app->m_renderer->drawLine(pos, pos+ 0.05*tr.getBasis().getColumn(0), b3MakeVector3(1,0,0), lineWidth);
m_app->m_renderer->drawLine(pos, pos + 0.05*tr.getBasis().getColumn(1), b3MakeVector3(0, 1, 0), lineWidth);
m_app->m_renderer->drawLine(pos, pos + 0.05*tr.getBasis().getColumn(2), b3MakeVector3(0, 0, 1), lineWidth);
b3Vector3 axisLocal = b3MakeVector3(node->v.x, node->v.y, node->v.z);
b3Vector3 axisWorld = tr.getBasis()*axisLocal;
m_app->m_renderer->drawLine(pos, pos + 0.1*axisWorld, b3MakeVector3(.2, 0.2, 0.7), 5);
//node->DrawNode(node == root); // Recursively draw node and update ModelView matrix
if (node->left) {
b3Transform act;
getLocalTransform(node->left, act);
b3Transform trl = tr*act;
m_app->m_renderer->drawLine(tr.getOrigin(), trl.getOrigin(), lineColor, lineWidth);
MyDrawTree(node->left, trl); // Draw tree of children recursively
}
// glPopMatrix();
if (node->right) {
b3Transform act;
getLocalTransform(node->right, act);
b3Transform trr = tr*act;
m_app->m_renderer->drawLine(tr.getOrigin(), trr.getOrigin(), lineColor, lineWidth);
MyDrawTree(node->right,trr); // Draw right siblings recursively
}
}
}
virtual void stepSimulation(float deltaTime)
{
DoUpdateStep(deltaTime, m_ikTree, m_ikJacobian, m_ikMethod);
}
virtual void renderScene()
{
b3Transform act;
getLocalTransform(m_ikTree.GetRoot(), act);
MyDrawTree(m_ikTree.GetRoot(), act);
b3Vector3 pos = b3MakeVector3(target1[0].x, target1[0].y, target1[0].z);
b3Quaternion orn(0, 0, 0, 1);
m_app->m_renderer->writeSingleInstanceTransformToCPU(pos, orn, m_targetInstance);
m_app->m_renderer->writeTransforms();
m_app->m_renderer->renderScene();
}
virtual void physicsDebugDraw()
{
}
virtual bool mouseMoveCallback(float x,float y)
{
return false;
}
virtual bool mouseButtonCallback(int button, int state, float x, float y)
{
return false;
}
virtual bool keyboardCallback(int key, int state)
{
return false;
}
virtual void resetCamera()
{
float dist = 1.3;
float pitch = 120;
float yaw = 13;
float targetPos[3]={-0.35,0.14,0.25};
if (m_app->m_renderer && m_app->m_renderer->getActiveCamera())
{
m_app->m_renderer->getActiveCamera()->setCameraDistance(dist);
m_app->m_renderer->getActiveCamera()->setCameraPitch(pitch);
m_app->m_renderer->getActiveCamera()->setCameraYaw(yaw);
m_app->m_renderer->getActiveCamera()->setCameraTargetPosition(targetPos[0],targetPos[1],targetPos[2]);
}
}
};
void InverseKinematicsExample::BuildKukaIIWAShape()
{
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);
const VectorR3& zero = VectorR3::Zero;
float minTheta = -4 * PI;
float maxTheta = 4 * PI;
m_ikNodes.resize(8);//7DOF+additional endeffector
m_ikNodes[0] = new Node(VectorR3(0.100000, 0.000000, 0.087500), unitz, 0.08, JOINT, -1e30, 1e30, RADIAN(0.));
m_ikTree.InsertRoot(m_ikNodes[0]);
m_ikNodes[1] = new Node(VectorR3(0.100000, -0.000000, 0.290000), unity, 0.08, JOINT, -0.5, 0.4, RADIAN(0.));
m_ikTree.InsertLeftChild(m_ikNodes[0], m_ikNodes[1]);
m_ikNodes[2] = new Node(VectorR3(0.100000, -0.000000, 0.494500), unitz, 0.08, JOINT, minTheta, maxTheta, RADIAN(0.));
m_ikTree.InsertLeftChild(m_ikNodes[1], m_ikNodes[2]);
m_ikNodes[3] = new Node(VectorR3(0.100000, 0.000000, 0.710000), -unity, 0.08, JOINT, minTheta, maxTheta, RADIAN(0.));
m_ikTree.InsertLeftChild(m_ikNodes[2], m_ikNodes[3]);
m_ikNodes[4] = new Node(VectorR3(0.100000, 0.000000, 0.894500), unitz, 0.08, JOINT, minTheta, maxTheta, RADIAN(0.));
m_ikTree.InsertLeftChild(m_ikNodes[3], m_ikNodes[4]);
m_ikNodes[5] = new Node(VectorR3(0.100000, 0.000000, 1.110000), unity, 0.08, JOINT, minTheta, maxTheta, RADIAN(0.));
m_ikTree.InsertLeftChild(m_ikNodes[4], m_ikNodes[5]);
m_ikNodes[6] = new Node(VectorR3(0.100000, 0.000000, 1.191000), unitz, 0.08, JOINT, minTheta, maxTheta, RADIAN(0.));
m_ikTree.InsertLeftChild(m_ikNodes[5], m_ikNodes[6]);
m_ikNodes[7] = new Node(VectorR3(0.100000, 0.000000, 1.20000), zero, 0.08, EFFECTOR);
m_ikTree.InsertLeftChild(m_ikNodes[6], m_ikNodes[7]);
}
class CommonExampleInterface* InverseKinematicsExampleCreateFunc(struct CommonExampleOptions& options)
{
return new InverseKinematicsExample(options.m_guiHelper->getAppInterface(), options.m_option);
}

View File

@@ -0,0 +1,8 @@
#ifndef INVERSE_KINEMATICSEXAMPLE_H
#define INVERSE_KINEMATICSEXAMPLE_H
enum Method {IK_JACOB_TRANS=0, IK_PURE_PSEUDO, IK_DLS, IK_SDLS , IK_DLS_SVD};
class CommonExampleInterface* InverseKinematicsExampleCreateFunc(struct CommonExampleOptions& options);
#endif //INVERSE_KINEMATICSEXAMPLE_H

View File

@@ -367,9 +367,8 @@ void TestJointTorqueSetup::initPhysics()
btSerializer* s = new btDefaultSerializer;
m_dynamicsWorld->serialize(s);
b3ResourcePath p;
char resourcePath[1024];
if (p.findResourcePath("multibody.bullet",resourcePath,1024))
if (b3ResourcePath::findResourcePath("multibody.bullet",resourcePath,1024))
{
FILE* f = fopen(resourcePath,"wb");
fwrite(s->getBufferPointer(),s->getCurrentBufferSize(),1,f);

View File

@@ -119,7 +119,7 @@ struct SampleThreadLocalStorage
void SampleThreadFunc(void* userPtr,void* lsMemory)
{
printf("thread started\n");
printf("SampleThreadFunc thread started\n");
SampleThreadLocalStorage* localStorage = (SampleThreadLocalStorage*) lsMemory;

View File

@@ -44,8 +44,6 @@ b3PosixThreadSupport::~b3PosixThreadSupport()
#define NAMED_SEMAPHORES
#endif
// this semaphore will signal, if and how many threads are finished with their work
static sem_t* mainSemaphore=0;
static sem_t* createSem(const char* baseName)
{
@@ -53,7 +51,7 @@ static sem_t* createSem(const char* baseName)
#ifdef NAMED_SEMAPHORES
/// Named semaphore begin
char name[32];
snprintf(name, 32, "/%s-%d-%4.4d", baseName, getpid(), semCount++);
snprintf(name, 32, "/%8.s-%4.d-%4.4d", baseName, getpid(), semCount++);
sem_t* tempSem = sem_open(name, O_CREAT, 0600, 0);
if (tempSem != reinterpret_cast<sem_t *>(SEM_FAILED))
@@ -100,12 +98,12 @@ static void *threadFunction(void *argument)
b3Assert(status->m_status);
status->m_userThreadFunc(userPtr,status->m_lsMemory);
status->m_status = 2;
checkPThreadFunction(sem_post(mainSemaphore));
checkPThreadFunction(sem_post(status->m_mainSemaphore));
status->threadUsed++;
} else {
//exit Thread
status->m_status = 3;
checkPThreadFunction(sem_post(mainSemaphore));
checkPThreadFunction(sem_post(status->m_mainSemaphore));
printf("Thread with taskId %i exiting\n",status->m_taskId);
break;
}
@@ -160,13 +158,14 @@ bool b3PosixThreadSupport::isTaskCompleted(int *puiArgument0, int *puiArgument1,
b3Assert(m_activeThreadStatus.size());
// wait for any of the threads to finish
int result = sem_trywait(mainSemaphore);
int result = sem_trywait(m_mainSemaphore);
if (result==0)
{
// get at least one thread which has finished
size_t last = -1;
for(size_t t=0; t < size_t(m_activeThreadStatus.size()); ++t) {
int last = -1;
int status = -1;
for(int t=0; t < int (m_activeThreadStatus.size()); ++t) {
status = m_activeThreadStatus[t].m_status;
if(2 == m_activeThreadStatus[t].m_status) {
last = t;
break;
@@ -200,7 +199,7 @@ void b3PosixThreadSupport::waitForResponse( int *puiArgument0, int *puiArgument
b3Assert(m_activeThreadStatus.size());
// wait for any of the threads to finish
checkPThreadFunction(sem_wait(mainSemaphore));
checkPThreadFunction(sem_wait(m_mainSemaphore));
// get at least one thread which has finished
size_t last = -1;
@@ -231,7 +230,7 @@ void b3PosixThreadSupport::startThreads(ThreadConstructionInfo& threadConstructi
printf("%s creating %i threads.\n", __FUNCTION__, threadConstructionInfo.m_numThreads);
m_activeThreadStatus.resize(threadConstructionInfo.m_numThreads);
mainSemaphore = createSem("main");
m_mainSemaphore = createSem("main");
//checkPThreadFunction(sem_wait(mainSemaphore));
for (int i=0;i < threadConstructionInfo.m_numThreads;i++)
@@ -249,6 +248,7 @@ void b3PosixThreadSupport::startThreads(ThreadConstructionInfo& threadConstructi
spuStatus.m_taskId = i;
spuStatus.m_commandId = 0;
spuStatus.m_status = 0;
spuStatus.m_mainSemaphore = m_mainSemaphore;
spuStatus.m_lsMemory = threadConstructionInfo.m_lsMemoryFunc();
spuStatus.m_userThreadFunc = threadConstructionInfo.m_userThreadFunc;
spuStatus.threadUsed = 0;
@@ -271,7 +271,7 @@ void b3PosixThreadSupport::stopThreads()
spuStatus.m_userPtr = 0;
checkPThreadFunction(sem_post(spuStatus.startSemaphore));
checkPThreadFunction(sem_wait(mainSemaphore));
checkPThreadFunction(sem_wait(m_mainSemaphore));
printf("destroy semaphore\n");
destroySem(spuStatus.startSemaphore);
@@ -280,7 +280,7 @@ void b3PosixThreadSupport::stopThreads()
}
printf("destroy main semaphore\n");
destroySem(mainSemaphore);
destroySem(m_mainSemaphore);
printf("main semaphore destroyed\n");
m_activeThreadStatus.clear();
}

View File

@@ -57,14 +57,22 @@ public:
void* m_userPtr; //for taskDesc etc
void* m_lsMemory; //initialized using PosixLocalStoreMemorySetupFunc
pthread_t thread;
sem_t* startSemaphore;
pthread_t thread;
//each tread will wait until this signal to start its work
sem_t* startSemaphore;
// this is a copy of m_mainSemaphore,
//each tread will signal once it is finished with its work
sem_t* m_mainSemaphore;
unsigned long threadUsed;
};
private:
b3AlignedObjectArray<b3ThreadStatus> m_activeThreadStatus;
// m_mainSemaphoresemaphore will signal, if and how many threads are finished with their work
sem_t* m_mainSemaphore;
public:
///Setup and initialize SPU/CELL/Libspe2

View File

@@ -223,7 +223,8 @@ bool b3Win32ThreadSupport::isTaskCompleted(int *puiArgument0, int *puiArgument1,
void b3Win32ThreadSupport::startThreads(const Win32ThreadConstructionInfo& threadConstructionInfo)
{
static int uniqueId = 0;
uniqueId++;
m_activeThreadStatus.resize(threadConstructionInfo.m_numThreads);
m_completeHandles.resize(threadConstructionInfo.m_numThreads);
@@ -244,18 +245,40 @@ void b3Win32ThreadSupport::startThreads(const Win32ThreadConstructionInfo& threa
threadStatus.m_userPtr=0;
sprintf(threadStatus.m_eventStartHandleName,"eventStart%s%d",threadConstructionInfo.m_uniqueName,i);
sprintf(threadStatus.m_eventStartHandleName,"es%.8s%d%d",threadConstructionInfo.m_uniqueName,uniqueId,i);
threadStatus.m_eventStartHandle = CreateEventA (0,false,false,threadStatus.m_eventStartHandleName);
sprintf(threadStatus.m_eventCompletetHandleName,"eventComplete%s%d",threadConstructionInfo.m_uniqueName,i);
sprintf(threadStatus.m_eventCompletetHandleName,"ec%.8s%d%d",threadConstructionInfo.m_uniqueName,uniqueId,i);
threadStatus.m_eventCompletetHandle = CreateEventA (0,false,false,threadStatus.m_eventCompletetHandleName);
m_completeHandles[i] = threadStatus.m_eventCompletetHandle;
HANDLE handle = CreateThread(lpThreadAttributes,dwStackSize,lpStartAddress,lpParameter, dwCreationFlags,lpThreadId);
//SetThreadPriority(handle,THREAD_PRIORITY_HIGHEST);
SetThreadPriority(handle,THREAD_PRIORITY_TIME_CRITICAL);
switch(threadConstructionInfo.m_priority)
{
case 0:
{
SetThreadPriority(handle,THREAD_PRIORITY_HIGHEST);
break;
}
case 1:
{
SetThreadPriority(handle,THREAD_PRIORITY_TIME_CRITICAL);
break;
}
case 2:
{
SetThreadPriority(handle,THREAD_PRIORITY_BELOW_NORMAL);
break;
}
default:
{
}
}
SetThreadAffinityMask(handle, 1<<i);
threadStatus.m_taskId = i;
@@ -265,7 +288,7 @@ void b3Win32ThreadSupport::startThreads(const Win32ThreadConstructionInfo& threa
threadStatus.m_lsMemory = threadConstructionInfo.m_lsMemoryFunc();
threadStatus.m_userThreadFunc = threadConstructionInfo.m_userThreadFunc;
printf("started thread %d with threadHandle %p\n",i,handle);
printf("started %s thread %d with threadHandle %p\n",threadConstructionInfo.m_uniqueName,i,handle);
}

View File

@@ -74,7 +74,8 @@ public:
m_userThreadFunc(userThreadFunc),
m_lsMemoryFunc(lsMemoryFunc),
m_numThreads(numThreads),
m_threadStackSize(threadStackSize)
m_threadStackSize(threadStackSize),
m_priority(0)
{
}
@@ -84,6 +85,7 @@ public:
b3Win32lsMemorySetupFunc m_lsMemoryFunc;
int m_numThreads;
int m_threadStackSize;
int m_priority;
};

View File

@@ -16,10 +16,10 @@ subject to the following restrictions:
///todo: make this configurable in the gui
bool useShadowMap=true;//false;//true;
int shadowMapWidth=8192;
int shadowMapHeight=8192;
float shadowMapWorldSize=50;
bool useShadowMap = true;// true;//false;//true;
int shadowMapWidth=4096;//8192;
int shadowMapHeight= 4096;
float shadowMapWorldSize=25;
#define MAX_POINTS_IN_BATCH 1024
#define MAX_LINES_IN_BATCH 1024
@@ -75,7 +75,7 @@ float shadowMapWorldSize=50;
static InternalDataRenderer* sData2;
GLint lineWidthRange[2]={1,1};
static b3Vector3 gLightPos=b3MakeVector3(-5,200,-40);
static b3Vector3 gLightPos=b3MakeVector3(-5,12,-4);
struct b3GraphicsInstance
{
@@ -146,8 +146,9 @@ struct InternalTextureHandle
struct InternalDataRenderer : public GLInstanceRendererInternalData
{
SimpleCamera m_defaultCamera;
SimpleCamera m_defaultCamera1;
CommonCameraInterface* m_activeCamera;
GLfloat m_projectionMatrix[16];
GLfloat m_viewMatrix[16];
@@ -158,10 +159,14 @@ struct InternalDataRenderer : public GLInstanceRendererInternalData
GLRenderToTexture* m_shadowMap;
GLuint m_shadowTexture;
GLuint m_renderFrameBuffer;
InternalDataRenderer() :
m_shadowMap(0),
m_shadowTexture(0)
m_shadowTexture(0),
m_renderFrameBuffer(0),
m_activeCamera(&m_defaultCamera1)
{
//clear to zero to make it obvious if the matrix is used uninitialized
for (int i=0;i<16;i++)
@@ -258,6 +263,8 @@ GLInstancingRenderer::GLInstancingRenderer(int maxNumObjectCapacity, int maxShap
void GLInstancingRenderer::removeAllInstances()
{
m_data->m_totalNumInstances = 0;
for (int i=0;i<m_graphicsInstances.size();i++)
{
if (m_graphicsInstances[i]->m_index_vbo)
@@ -273,6 +280,7 @@ void GLInstancingRenderer::removeAllInstances()
m_graphicsInstances.clear();
}
GLInstancingRenderer::~GLInstancingRenderer()
{
delete m_data->m_shadowMap;
@@ -320,6 +328,7 @@ void GLInstancingRenderer::writeSingleInstanceTransformToCPU(const float* positi
*/
}
void GLInstancingRenderer::writeSingleInstanceColorToCPU(double* color, int srcIndex)
{
m_data->m_instance_colors_ptr[srcIndex*4+0]=float(color[0]);
@@ -337,12 +346,24 @@ void GLInstancingRenderer::writeSingleInstanceColorToCPU(float* color, int srcIn
m_data->m_instance_colors_ptr[srcIndex*4+3]=color[3];
}
void GLInstancingRenderer::writeSingleInstanceScaleToCPU(float* scale, int srcIndex)
{
m_data->m_instance_scale_ptr[srcIndex*3+0]=scale[0];
m_data->m_instance_scale_ptr[srcIndex*3+1]=scale[1];
m_data->m_instance_scale_ptr[srcIndex*3+2]=scale[2];
}
void GLInstancingRenderer::writeSingleInstanceScaleToCPU(double* scale, int srcIndex)
{
m_data->m_instance_scale_ptr[srcIndex*3+0]=scale[0];
m_data->m_instance_scale_ptr[srcIndex*3+1]=scale[1];
m_data->m_instance_scale_ptr[srcIndex*3+2]=scale[2];
}
void GLInstancingRenderer::writeSingleInstanceTransformToGPU(float* position, float* orientation, int objectIndex)
{
glBindBuffer(GL_ARRAY_BUFFER, m_data->m_vbo);
glFlush();
//glFlush();
char* orgBase = (char*)glMapBuffer( GL_ARRAY_BUFFER,GL_READ_WRITE);
//b3GraphicsInstance* gfxObj = m_graphicsInstances[k];
@@ -372,7 +393,7 @@ void GLInstancingRenderer::writeSingleInstanceTransformToGPU(float* position, fl
orientations [objectIndex*4+3] = orientation[3];
glUnmapBuffer( GL_ARRAY_BUFFER);
glFlush();
//glFlush();
}
@@ -383,25 +404,46 @@ void GLInstancingRenderer::writeTransforms()
glBindBuffer(GL_ARRAY_BUFFER, m_data->m_vbo);
glFlush();
//glFlush();
b3Assert(glGetError() ==GL_NO_ERROR);
#ifdef B3_DEBUG
{
int totalNumInstances= 0;
for (int k=0;k<m_graphicsInstances.size();k++)
{
b3GraphicsInstance* gfxObj = m_graphicsInstances[k];
totalNumInstances+=gfxObj->m_numGraphicsInstances;
}
b3Assert(m_data->m_totalNumInstances == totalNumInstances);
}
#endif//B3_DEBUG
int POSITION_BUFFER_SIZE = (m_data->m_totalNumInstances*sizeof(float)*4);
int ORIENTATION_BUFFER_SIZE = (m_data->m_totalNumInstances*sizeof(float)*4);
int COLOR_BUFFER_SIZE = (m_data->m_totalNumInstances*sizeof(float)*4);
// int SCALE_BUFFER_SIZE = (totalNumInstances*sizeof(float)*3);
#if 1
glBufferSubData( GL_ARRAY_BUFFER,m_data->m_maxShapeCapacityInBytes,m_data->m_totalNumInstances*sizeof(float)*4,
&m_data->m_instance_positions_ptr[0]);
glBufferSubData( GL_ARRAY_BUFFER,m_data->m_maxShapeCapacityInBytes+POSITION_BUFFER_SIZE,m_data->m_totalNumInstances*sizeof(float)*4,
&m_data->m_instance_quaternion_ptr[0]);
glBufferSubData( GL_ARRAY_BUFFER,m_data->m_maxShapeCapacityInBytes+ POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE, m_data->m_totalNumInstances*sizeof(float)*4,
&m_data->m_instance_colors_ptr[0]);
glBufferSubData( GL_ARRAY_BUFFER, m_data->m_maxShapeCapacityInBytes+POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE+COLOR_BUFFER_SIZE,m_data->m_totalNumInstances*sizeof(float)*3,
&m_data->m_instance_scale_ptr[0]);
#else
char* orgBase = (char*)glMapBuffer( GL_ARRAY_BUFFER,GL_READ_WRITE);
if (orgBase)
{
int totalNumInstances= 0;
for (int k=0;k<m_graphicsInstances.size();k++)
{
b3GraphicsInstance* gfxObj = m_graphicsInstances[k];
totalNumInstances+=gfxObj->m_numGraphicsInstances;
}
m_data->m_totalNumInstances = totalNumInstances;
for (int k=0;k<m_graphicsInstances.size();k++)
{
@@ -410,10 +452,7 @@ void GLInstancingRenderer::writeTransforms()
int POSITION_BUFFER_SIZE = (totalNumInstances*sizeof(float)*4);
int ORIENTATION_BUFFER_SIZE = (totalNumInstances*sizeof(float)*4);
int COLOR_BUFFER_SIZE = (totalNumInstances*sizeof(float)*4);
// int SCALE_BUFFER_SIZE = (totalNumInstances*sizeof(float)*3);
char* base = orgBase;
@@ -461,7 +500,10 @@ void GLInstancingRenderer::writeTransforms()
glUnmapBuffer( GL_ARRAY_BUFFER);
//if this glFinish is removed, the animation is not always working/blocks
//@todo: figure out why
glFlush();
//glFlush();
#endif
glBindBuffer(GL_ARRAY_BUFFER, 0);//m_data->m_vbo);
b3Assert(glGetError() ==GL_NO_ERROR);
@@ -879,18 +921,18 @@ void GLInstancingRenderer::resize(int width, int height)
const CommonCameraInterface* GLInstancingRenderer::getActiveCamera() const
{
return &m_data->m_defaultCamera;
return m_data->m_activeCamera;
}
CommonCameraInterface* GLInstancingRenderer::getActiveCamera()
{
return &m_data->m_defaultCamera;
return m_data->m_activeCamera;
}
void GLInstancingRenderer::setActiveCamera(CommonCameraInterface* cam)
{
b3Assert(0);//not supported yet
m_data->m_activeCamera = cam;
}
@@ -911,14 +953,12 @@ void GLInstancingRenderer::updateCamera(int upAxis)
b3Assert(0);
};
m_data->m_defaultCamera.setCameraUpAxis(upAxis);
m_data->m_defaultCamera.setAspectRatio((float)m_screenWidth/(float)m_screenHeight);
m_data->m_defaultCamera.update();
m_data->m_activeCamera->setCameraUpAxis(upAxis);
m_data->m_activeCamera->setAspectRatio((float)m_screenWidth/(float)m_screenHeight);
m_data->m_defaultCamera1.update();
m_data->m_activeCamera->getCameraProjectionMatrix(m_data->m_projectionMatrix);
m_data->m_activeCamera->getCameraViewMatrix(m_data->m_viewMatrix);
m_data->m_defaultCamera.getCameraProjectionMatrix(m_data->m_projectionMatrix);
m_data->m_defaultCamera.getCameraViewMatrix(m_data->m_viewMatrix);
}
@@ -997,13 +1037,13 @@ void GLInstancingRenderer::renderScene()
//avoid some Intel driver on a Macbook Pro to lock-up
//todo: figure out what is going on on that machine
glFlush();
//glFlush();
if (useShadowMap)
{
renderSceneInternal(B3_CREATE_SHADOWMAP_RENDERMODE);
// glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
//glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
renderSceneInternal(B3_USE_SHADOWMAP_RENDERMODE);
} else
@@ -1072,6 +1112,9 @@ void GLInstancingRenderer::drawPoints(const float* positions, const float color[
void GLInstancingRenderer::drawLines(const float* positions, const float color[4], int numPoints, int pointStrideInBytes, const unsigned int* indices, int numIndices, float lineWidthIn)
{
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,0);
float lineWidth = lineWidthIn;
b3Clamp(lineWidth,(float)lineWidthRange[0],(float)lineWidthRange[1]);
glLineWidth(lineWidth);
@@ -1446,7 +1489,7 @@ void GLInstancingRenderer::renderSceneInternal(int renderMode)
float depthViewMatrix[4][4];
b3Vector3 center = b3MakeVector3(0,0,0);
float upf[3];
m_data->m_defaultCamera.getCameraUpVector(upf);
m_data->m_activeCamera->getCameraUpVector(upf);
b3Vector3 up = b3MakeVector3(upf[0],upf[1],upf[2]);
b3CreateLookAt(gLightPos,center,up,&depthViewMatrix[0][0]);
//b3CreateLookAt(lightPos,m_data->m_cameraTargetPosition,b3Vector3(0,1,0),(float*)depthModelViewMatrix2);
@@ -1483,6 +1526,9 @@ void GLInstancingRenderer::renderSceneInternal(int renderMode)
{
B3_PROFILE("updateCamera");
// updateCamera();
m_data->m_activeCamera->getCameraProjectionMatrix(m_data->m_projectionMatrix);
m_data->m_activeCamera->getCameraViewMatrix(m_data->m_viewMatrix);
}
b3Assert(glGetError() ==GL_NO_ERROR);
@@ -1493,7 +1539,7 @@ b3Assert(glGetError() ==GL_NO_ERROR);
B3_PROFILE("glFlush2");
glBindBuffer(GL_ARRAY_BUFFER, m_data->m_vbo);
glFlush();
//glFlush();
}
b3Assert(glGetError() ==GL_NO_ERROR);
@@ -1507,7 +1553,7 @@ b3Assert(glGetError() ==GL_NO_ERROR);
int curOffset = 0;
//GLuint lastBindTexture = 0;
for (int i=0;i<m_graphicsInstances.size();i++)
{
@@ -1631,6 +1677,7 @@ b3Assert(glGetError() ==GL_NO_ERROR);
printf("gfxObj->m_numGraphicsInstances=%d\n",gfxObj->m_numGraphicsInstances);
printf("indexCount=%d\n",indexCount);
*/
glUseProgram(createShadowMapInstancingShader);
glUniformMatrix4fv(createShadow_depthMVP, 1, false, &depthMVP[0][0]);
glDrawElementsInstanced(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, indexOffset, gfxObj->m_numGraphicsInstances);
@@ -1663,7 +1710,8 @@ b3Assert(glGetError() ==GL_NO_ERROR);
{
glDisable (GL_BLEND);
}
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,0);
break;
}
default:
@@ -1682,12 +1730,13 @@ b3Assert(glGetError() ==GL_NO_ERROR);
{
B3_PROFILE("glFlush");
glFlush();
//glFlush();
}
if (renderMode==B3_CREATE_SHADOWMAP_RENDERMODE)
{
// writeTextureToPng(shadowMapWidth,shadowMapHeight,"shadowmap.png",4);
m_data->m_shadowMap->disable();
glBindFramebuffer( GL_FRAMEBUFFER, m_data->m_renderFrameBuffer);
glViewport(dims[0],dims[1],dims[2],dims[3]);
}
@@ -1733,4 +1782,16 @@ int GLInstancingRenderer::getInstanceCapacity() const
{
return m_data->m_maxNumObjectCapacity;
}
void GLInstancingRenderer::setRenderFrameBuffer(unsigned int renderFrameBuffer)
{
m_data->m_renderFrameBuffer = (GLuint) renderFrameBuffer;
}
int GLInstancingRenderer::getTotalNumInstances() const
{
return m_data->m_totalNumInstances;
}
#endif //NO_OPENGL3

View File

@@ -56,7 +56,7 @@ public:
void InitShaders();
void CleanupShaders();
virtual void removeAllInstances();
virtual void updateShape(int shapeIndex, const float* vertices);
///vertices must be in the format x,y,z, nx,ny,nz, u,v
@@ -95,6 +95,9 @@ public:
virtual void writeSingleInstanceColorToCPU(float* color, int srcIndex);
virtual void writeSingleInstanceColorToCPU(double* color, int srcIndex);
virtual void writeSingleInstanceScaleToCPU(float* scale, int srcIndex);
virtual void writeSingleInstanceScaleToCPU(double* scale, int srcIndex);
virtual struct GLInstanceRendererInternalData* getInternalData();
@@ -125,6 +128,8 @@ public:
virtual int getInstanceCapacity() const;
virtual int getTotalNumInstances() const;
virtual void enableShadowMap();
virtual void enableBlend(bool blend)
{
@@ -132,6 +137,7 @@ public:
}
virtual void clearZBuffer();
virtual void setRenderFrameBuffer(unsigned int renderFrameBuffer);
};
#endif //GL_INSTANCING_RENDERER_H

View File

@@ -102,11 +102,11 @@ float loop;
}
-(void)drawRect:(NSRect)rect
{
if (([self frame].size.width != m_lastWidth) || ([self frame].size.height != m_lastHeight))
{
m_lastWidth = [self frame].size.width;
m_lastHeight = [self frame].size.height;
// Only needed on resize:
[m_context clearDrawable];
@@ -114,7 +114,6 @@ float loop;
float width = [self frame].size.width;
float height = [self frame].size.height;
// Get view dimensions in pixels
// glViewport(0,0,10,10);
@@ -209,16 +208,12 @@ struct MacOpenGLWindowInternalData
m_myview = 0;
m_pool = 0;
m_window = 0;
m_width = -1;
m_height = -1;
m_exitRequested = false;
}
NSApplication* m_myApp;
TestView* m_myview;
NSAutoreleasePool* m_pool;
NSWindow* m_window;
int m_width;
int m_height;
bool m_exitRequested;
};
@@ -294,8 +289,6 @@ void MacOpenGLWindow::createWindow(const b3gWindowConstructionInfo& ci)
if (m_internalData)
closeWindow();
int width = ci.m_width;
int height = ci.m_height;
const char* windowTitle = ci.m_title;
@@ -303,9 +296,7 @@ void MacOpenGLWindow::createWindow(const b3gWindowConstructionInfo& ci)
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
m_internalData = new MacOpenGLWindowInternalData;
m_internalData->m_width = width;
m_internalData->m_height = height;
m_internalData->m_pool = [NSAutoreleasePool new];
m_internalData->m_myApp = [NSApplication sharedApplication];
//myApp = [MyApp sharedApplication];
@@ -373,7 +364,7 @@ void MacOpenGLWindow::createWindow(const b3gWindowConstructionInfo& ci)
[newItem release];
*/
NSRect frame = NSMakeRect(0., 0., width, height);
NSRect frame = NSMakeRect(0., 0., ci.m_width, ci.m_height);
m_internalData->m_window = [NSWindow alloc];
[m_internalData->m_window initWithContentRect:frame
@@ -423,9 +414,7 @@ void MacOpenGLWindow::createWindow(const b3gWindowConstructionInfo& ci)
[m_internalData->m_window makeKeyAndOrderFront: nil];
[m_internalData->m_myview MakeCurrent];
m_internalData->m_width = m_internalData->m_myview.GetWindowWidth;
m_internalData->m_height = m_internalData->m_myview.GetWindowHeight;
[NSApp activateIgnoringOtherApps:YES];
@@ -1035,13 +1024,13 @@ void MacOpenGLWindow::startRendering()
float aspect;
//b3Vector3 extents;
if (m_internalData->m_width > m_internalData->m_height)
if (getWidth() > getHeight())
{
aspect = (float)m_internalData->m_width / (float)m_internalData->m_height;
aspect = (float)getWidth() / (float)getHeight();
//extents.setValue(aspect * 1.0f, 1.0f,0);
} else
{
aspect = (float)m_internalData->m_height / (float)m_internalData->m_width;
aspect = (float)getHeight() / (float)getWidth();
//extents.setValue(1.0f, aspect*1.f,0);
}
@@ -1082,7 +1071,7 @@ int MacOpenGLWindow::fileOpenDialog(char* filename, int maxNameLength)
NSOpenGLContext *foo = [NSOpenGLContext currentContext];
// get the url of a .txt file
NSOpenPanel * zOpenPanel = [NSOpenPanel openPanel];
NSArray * zAryOfExtensions = [NSArray arrayWithObjects:@"urdf",@"bullet",@"obj",@"sdf",nil];
NSArray * zAryOfExtensions = [NSArray arrayWithObjects:@"urdf",@"bullet",@"obj",@"sdf",@"stl",nil];
[zOpenPanel setAllowedFileTypes:zAryOfExtensions];
NSInteger zIntResult = [zOpenPanel runModal];
@@ -1136,6 +1125,7 @@ int MacOpenGLWindow::getWidth() const
{
if (m_internalData && m_internalData->m_myview && m_internalData->m_myview.GetWindowWidth)
return m_internalData->m_myview.GetWindowWidth;
return 0;
}
@@ -1152,7 +1142,7 @@ void MacOpenGLWindow::setResizeCallback(b3ResizeCallback resizeCallback)
[m_internalData->m_myview setResizeCallback:resizeCallback];
if (resizeCallback)
{
(resizeCallback)(m_internalData->m_width,m_internalData->m_height);
(resizeCallback)(getWidth(), getHeight());
}
}

View File

@@ -25,7 +25,8 @@ void main(void)
vec4 texel = fragment.color*texture(Diffuse,vert.texcoord);//fragment.color;
vec3 ct,cf;
float intensity,at,af;
intensity = max(dot(lightDir,normalize(normal)),0);
intensity = 0.5+0.5*clamp( dot( normalize(normal),lightDir ), -1,1 );
cf = intensity*(vec3(1.0,1.0,1.0)-ambient)+ambient;
af = 1.0;

View File

@@ -22,7 +22,8 @@ static const char* instancingFragmentShader= \
" vec4 texel = fragment.color*texture(Diffuse,vert.texcoord);//fragment.color;\n"
" vec3 ct,cf;\n"
" float intensity,at,af;\n"
" intensity = max(dot(lightDir,normalize(normal)),0);\n"
" \n"
" intensity = 0.5+0.5*clamp( dot( normalize(normal),lightDir ), -1,1 );\n"
" cf = intensity*(vec3(1.0,1.0,1.0)-ambient)+ambient;\n"
" af = 1.0;\n"
" \n"

View File

@@ -61,7 +61,7 @@ out vec3 lightDir,normal,ambient;
void main(void)
{
vec4 q = instance_quaternion;
ambient = vec3(0.6,.6,0.6);
ambient = vec3(0.5,.5,0.5);
vec4 worldNormal = (quatRotate3( vertexnormal,q));
normal = normalize(worldNormal).xyz;

View File

@@ -52,7 +52,7 @@ static const char* instancingVertexShader= \
"void main(void)\n"
"{\n"
" vec4 q = instance_quaternion;\n"
" ambient = vec3(0.6,.6,0.6);\n"
" ambient = vec3(0.5,.5,0.5);\n"
" \n"
" vec4 worldNormal = (quatRotate3( vertexnormal,q));\n"
" normal = normalize(worldNormal).xyz;\n"

View File

@@ -27,8 +27,7 @@ void main(void)
vec3 ct,cf;
float intensity,at,af;
intensity = clamp( dot( normalize(normal),lightDir ), 0,1 );
intensity = 0.5+0.5*clamp( dot( normalize(normal),lightDir ), -1,1 );
af = 1.0;

View File

@@ -21,8 +21,7 @@ static const char* useShadowMapInstancingFragmentShader= \
" vec3 ct,cf;\n"
" float intensity,at,af;\n"
" \n"
" intensity = clamp( dot( normalize(normal),lightDir ), 0,1 );\n"
" \n"
" intensity = 0.5+0.5*clamp( dot( normalize(normal),lightDir ), -1,1 );\n"
" \n"
" af = 1.0;\n"
" \n"

View File

@@ -65,7 +65,7 @@ out vec3 lightDir,normal,ambient;
void main(void)
{
vec4 q = instance_quaternion;
ambient = vec3(0.6,.6,0.6);
ambient = vec3(0.5,.5,0.5);
vec4 worldNormal = (quatRotate3( vertexnormal,q));

View File

@@ -55,7 +55,7 @@ static const char* useShadowMapInstancingVertexShader= \
"void main(void)\n"
"{\n"
" vec4 q = instance_quaternion;\n"
" ambient = vec3(0.6,.6,0.6);\n"
" ambient = vec3(0.5,.5,0.5);\n"
" \n"
" vec4 worldNormal = (quatRotate3( vertexnormal,q));\n"
" \n"

View File

@@ -62,6 +62,16 @@ void SimpleCamera::setVRCamera(const float viewMat[16], const float projectionMa
}
}
void SimpleCamera::disableVRCamera()
{
m_data->m_enableVR = false;
}
bool SimpleCamera::isVRCamera() const
{
return m_data->m_enableVR ;
}
static void b3CreateFrustum(
float left,

View File

@@ -15,6 +15,8 @@ struct SimpleCamera : public CommonCameraInterface
virtual void getCameraViewMatrix(float m[16]) const;
virtual void setVRCamera(const float viewMat[16], const float projectionMatrix[16]);
virtual void disableVRCamera();
virtual bool isVRCamera() const;
virtual void getCameraTargetPosition(float pos[3]) const;
virtual void getCameraPosition(float pos[3]) const;

View File

@@ -64,6 +64,20 @@ void SimpleOpenGL2Renderer::writeSingleInstanceColorToCPU(double* color, int src
{
}
void SimpleOpenGL2Renderer::writeSingleInstanceScaleToCPU(float* scale, int srcIndex)
{
}
void SimpleOpenGL2Renderer::writeSingleInstanceScaleToCPU(double* scale, int srcIndex)
{
}
int SimpleOpenGL2Renderer::getTotalNumInstances() const
{
return 0;
}
void SimpleOpenGL2Renderer::getCameraViewMatrix(float viewMat[16]) const
{
b3Assert(0);

View File

@@ -32,6 +32,8 @@ struct SimpleOpenGL2Renderer : public CommonRenderInterface
virtual void writeSingleInstanceColorToCPU(float* color, int srcIndex);
virtual void writeSingleInstanceColorToCPU(double* color, int srcIndex);
virtual void writeSingleInstanceScaleToCPU(float* scale, int srcIndex);
virtual void writeSingleInstanceScaleToCPU(double* scale, int srcIndex);
virtual void getCameraViewMatrix(float viewMat[16]) const;
virtual void getCameraProjectionMatrix(float projMat[16]) const;
@@ -68,6 +70,8 @@ struct SimpleOpenGL2Renderer : public CommonRenderInterface
virtual void writeSingleInstanceTransformToCPU(const double* position, const double* orientation, int srcIndex);
virtual int getTotalNumInstances() const;
virtual void writeTransforms();
virtual void drawLine(const double from[4], const double to[4], const double color[4], double lineWidth);
@@ -82,6 +86,7 @@ struct SimpleOpenGL2Renderer : public CommonRenderInterface
virtual void clearZBuffer();
virtual struct GLInstanceRendererInternalData* getInternalData()
{
return 0;

View File

@@ -650,14 +650,19 @@ void SimpleOpenGL3App::setBackgroundColor(float red, float green, float blue)
SimpleOpenGL3App::~SimpleOpenGL3App()
{
delete m_instancingRenderer;
delete m_primRenderer ;
sth_delete(m_data->m_fontStash);
delete m_data->m_renderCallbacks;
TwDeleteDefaultFonts();
m_window->closeWindow();
delete m_window;
delete m_data ;
}
void SimpleOpenGL3App::getScreenPixels(unsigned char* rgbaBuffer, int bufferSizeInBytes)
void SimpleOpenGL3App::getScreenPixels(unsigned char* rgbaBuffer, int bufferSizeInBytes, float* depthBuffer, int depthBufferSizeInBytes)
{
int width = (int)m_window->getRetinaScale()*m_instancingRenderer->getScreenWidth();
@@ -668,6 +673,12 @@ void SimpleOpenGL3App::getScreenPixels(unsigned char* rgbaBuffer, int bufferSize
int glstat = glGetError();
b3Assert(glstat==GL_NO_ERROR);
}
if ((width*height*sizeof(float)) == depthBufferSizeInBytes)
{
glReadPixels(0,0,width, height, GL_DEPTH_COMPONENT, GL_FLOAT, depthBuffer);
int glstat = glGetError();
b3Assert(glstat==GL_NO_ERROR);
}
}
@@ -739,11 +750,13 @@ static void writeTextureToFile(int textureWidth, int textureHeight, const char*
void SimpleOpenGL3App::swapBuffer()
{
m_window->endRendering();
if (m_data->m_frameDumpPngFileName)
{
writeTextureToFile((int)m_window->getRetinaScale()*m_instancingRenderer->getScreenWidth(),
(int) m_window->getRetinaScale()*this->m_instancingRenderer->getScreenHeight(),m_data->m_frameDumpPngFileName,
int width = (int)m_window->getRetinaScale()*m_instancingRenderer->getScreenWidth();
int height = (int) m_window->getRetinaScale()*this->m_instancingRenderer->getScreenHeight();
writeTextureToFile(width,
height,m_data->m_frameDumpPngFileName,
m_data->m_ffmpegFile);
m_data->m_renderTexture->disable();
if (m_data->m_ffmpegFile==0)
@@ -751,7 +764,8 @@ void SimpleOpenGL3App::swapBuffer()
m_data->m_frameDumpPngFileName = 0;
}
}
m_window->startRendering();
m_window->endRendering();
m_window->startRendering();
}
// see also http://blog.mmacklin.com/2013/06/11/real-time-video-capture-with-ffmpeg/
@@ -762,12 +776,15 @@ void SimpleOpenGL3App::dumpFramesToVideo(const char* mp4FileName)
char cmd[8192];
#ifdef _WIN32
sprintf(cmd, "ffmpeg -r 60 -f rawvideo -pix_fmt rgba -s %dx%d -i - "
"-y -crf 0 -b:v 1500000 -an -vcodec h264 -vf vflip %s", width, height, mp4FileName);
sprintf(cmd, "ffmpeg -r 60 -f rawvideo -pix_fmt rgba -s %dx%d -i - "
"-threads 0 -y -b 50000k -t 20 -c:v libx264 -preset slow -crf 22 -an -pix_fmt yuv420p -vf vflip %s", width, height, mp4FileName);
//sprintf(cmd, "ffmpeg -r 60 -f rawvideo -pix_fmt rgba -s %dx%d -i - "
// "-y -crf 0 -b:v 1500000 -an -vcodec h264 -vf vflip %s", width, height, mp4FileName);
#else
sprintf(cmd, "ffmpeg -r 60 -f rawvideo -pix_fmt rgba -s %dx%d -i - "
"-threads 0 -y -crf 0 -b 50000k -vf vflip %s", width, height, mp4FileName);
"-threads 0 -y -b 50000k -t 20 -c:v libx264 -preset slow -crf 22 -an -pix_fmt yuv420p -vf vflip %s", width, height, mp4FileName);
#endif
//sprintf(cmd,"ffmpeg -r 60 -f rawvideo -pix_fmt rgba -s %dx%d -i - "

View File

@@ -24,7 +24,7 @@ struct SimpleOpenGL3App : public CommonGraphicsApp
virtual void registerGrid(int xres, int yres, float color0[4], float color1[4]);
void dumpNextFrameToPng(const char* pngFilename);
void dumpFramesToVideo(const char* mp4Filename);
void getScreenPixels(unsigned char* rgbaBuffer, int bufferSizeInBytes);
void getScreenPixels(unsigned char* rgbaBuffer, int bufferSizeInBytes, float* depthBuffer, int depthBufferSizeInBytes);
void drawGrid(DrawGridData data=DrawGridData());
virtual void setUpAxis(int axis);

View File

@@ -4883,18 +4883,33 @@ static const unsigned char s_FontFixed1[] = {
void TwGenerateDefaultFonts()
{
g_DefaultSmallFont = TwGenerateFont(s_Font0, FONT0_BM_W, FONT0_BM_H);
assert(g_DefaultSmallFont && g_DefaultSmallFont->m_NbCharRead==224);
if (g_DefaultSmallFont == 0)
{
g_DefaultSmallFont = TwGenerateFont(s_Font0, FONT0_BM_W, FONT0_BM_H);
assert(g_DefaultSmallFont && g_DefaultSmallFont->m_NbCharRead == 224);
}
g_DefaultNormalFont = TwGenerateFont(s_Font1, FONT1_BM_W, FONT1_BM_H);
assert(g_DefaultNormalFont && g_DefaultNormalFont->m_NbCharRead==224);
if (g_DefaultNormalFont == 0)
{
g_DefaultNormalFont = TwGenerateFont(s_Font1, FONT1_BM_W, FONT1_BM_H);
assert(g_DefaultNormalFont && g_DefaultNormalFont->m_NbCharRead == 224);
}
g_DefaultNormalFontAA = TwGenerateFont(s_Font1AA, FONT1AA_BM_W, FONT1AA_BM_H);
assert(g_DefaultNormalFontAA && g_DefaultNormalFontAA->m_NbCharRead==224);
g_DefaultLargeFont = TwGenerateFont(s_Font2AA, FONT2AA_BM_W, FONT2AA_BM_H);
assert(g_DefaultLargeFont && g_DefaultLargeFont->m_NbCharRead==224);
g_DefaultFixed1Font = TwGenerateFont(s_FontFixed1, FONTFIXED1_BM_W, FONTFIXED1_BM_H);
assert(g_DefaultFixed1Font && g_DefaultFixed1Font->m_NbCharRead==224);
if (g_DefaultNormalFontAA == 0)
{
g_DefaultNormalFontAA = TwGenerateFont(s_Font1AA, FONT1AA_BM_W, FONT1AA_BM_H);
assert(g_DefaultNormalFontAA && g_DefaultNormalFontAA->m_NbCharRead == 224);
}
if (g_DefaultLargeFont == 0)
{
g_DefaultLargeFont = TwGenerateFont(s_Font2AA, FONT2AA_BM_W, FONT2AA_BM_H);
assert(g_DefaultLargeFont && g_DefaultLargeFont->m_NbCharRead == 224);
}
if (g_DefaultFixed1Font == 0)
{
g_DefaultFixed1Font = TwGenerateFont(s_FontFixed1, FONTFIXED1_BM_W, FONTFIXED1_BM_H);
assert(g_DefaultFixed1Font && g_DefaultFixed1Font->m_NbCharRead == 224);
}
}
// ---------------------------------------------------------------------------

View File

@@ -435,11 +435,10 @@ void Win32Window::setWindowTitle(const char* titleChar)
wchar_t windowTitle[1024];
swprintf(windowTitle, 1024, L"%hs", titleChar);
DWORD dwResult;
#ifdef _WIN64
SetWindowTextW(m_data->m_hWnd, windowTitle);
#else
DWORD dwResult;
SendMessageTimeoutW(m_data->m_hWnd, WM_SETTEXT, 0,
reinterpret_cast<LPARAM>(windowTitle),
SMTO_ABORTIFHUNG, 2000, &dwResult);

View File

@@ -516,6 +516,9 @@ void X11OpenGLWindow::createWindow(const b3gWindowConstructionInfo& ci)
m_data->m_dpy = MyXOpenDisplay(NULL);
m_data->m_glWidth = ci.m_width;
m_data->m_glHeight = ci.m_height;
if(m_data->m_dpy == NULL) {
printf("\n\tcannot connect to X server\n\n");
exit(0);

View File

@@ -156,7 +156,7 @@ public:
}
};
struct CommonExampleInterface* CoordinateSystemCreateFunc(struct CommonExampleOptions& options)
CommonExampleInterface* CoordinateSystemCreateFunc(struct CommonExampleOptions& options)
{
return new CoordinateSystemDemo(options.m_guiHelper->getAppInterface());
}

View File

@@ -295,7 +295,7 @@ void RaytracerPhysicsSetup::stepSimulation(float deltaTime)
for (x=0;x<m_internalData->m_width;x++)
{
for (int y=0;y<m_internalData->m_height;y++)
for (y=0;y<m_internalData->m_height;y++)
{
btVector4 rgba(0,0,0,0);
btVector3 rayTo = rayToCenter - 0.5f * hor + 0.5f * vertical;

View File

@@ -147,7 +147,9 @@ TinyRendererSetup::TinyRendererSetup(struct GUIHelperInterface* gui)
m_internalData = new TinyRendererSetupInternalData(gui->getAppInterface()->m_window->getWidth(),gui->getAppInterface()->m_window->getHeight());
m_app->m_renderer->enableBlend(true);
const char* fileName = "teddy.obj";//cube.obj";//textured_sphere_smooth.obj";//cube.obj";
const char* fileName = "textured_sphere_smooth.obj";
fileName = "cube.obj";
{
@@ -181,7 +183,7 @@ TinyRendererSetup::TinyRendererSetup(struct GUIHelperInterface* gui)
m_guiHelper->getRenderInterface()->writeTransforms();
m_internalData->m_shapePtr.push_back(0);
TinyRenderObjectData* ob = new TinyRenderObjectData(m_internalData->m_width,m_internalData->m_height,
TinyRenderObjectData* ob = new TinyRenderObjectData(
m_internalData->m_rgbColorBuffer,
m_internalData->m_depthBuffer);
//ob->loadModel("cube.obj");

View File

@@ -0,0 +1,231 @@
#include "GripperGraspExample.h"
#include "../CommonInterfaces/CommonGraphicsAppInterface.h"
#include "Bullet3Common/b3Quaternion.h"
#include "Bullet3Common/b3AlignedObjectArray.h"
#include "../CommonInterfaces/CommonRenderInterface.h"
#include "../CommonInterfaces/CommonExampleInterface.h"
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
#include "../SharedMemory/PhysicsServerSharedMemory.h"
#include "../SharedMemory/PhysicsClientC_API.h"
#include "../CommonInterfaces/CommonParameterInterface.h"
#include <string>
#include "b3RobotSimAPI.h"
#include "../Utils/b3Clock.h"
static btScalar sGripperVerticalVelocity = -0.2f;
static btScalar sGripperClosingTargetVelocity = 0.5f;
class GripperGraspExample : public CommonExampleInterface
{
CommonGraphicsApp* m_app;
GUIHelperInterface* m_guiHelper;
b3RobotSimAPI m_robotSim;
int m_options;
int m_r2d2Index;
int m_gripperIndex;
float m_x;
float m_y;
float m_z;
b3AlignedObjectArray<int> m_movingInstances;
enum
{
numCubesX = 20,
numCubesY = 20
};
public:
GripperGraspExample(GUIHelperInterface* helper, int options)
:m_app(helper->getAppInterface()),
m_guiHelper(helper),
m_options(options),
m_r2d2Index(-1),
m_gripperIndex(-1),
m_x(0),
m_y(0),
m_z(0)
{
m_app->setUpAxis(2);
}
virtual ~GripperGraspExample()
{
m_app->m_renderer->enableBlend(false);
}
virtual void physicsDebugDraw(int debugDrawMode)
{
}
virtual void initPhysics()
{
bool connected = m_robotSim.connect(m_guiHelper);
b3Printf("robotSim connected = %d",connected);
{
{
SliderParams slider("Vertical velocity",&sGripperVerticalVelocity);
slider.m_minVal=-2;
slider.m_maxVal=2;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{
SliderParams slider("Closing velocity",&sGripperClosingTargetVelocity
);
slider.m_minVal=-1;
slider.m_maxVal=1;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{
b3RobotSimLoadFileArgs args("");
args.m_fileName = "gripper/wsg50_with_r2d2_gripper.sdf";
args.m_fileType = B3_SDF_FILE;
b3RobotSimLoadFileResults results;
if (m_robotSim.loadFile(args, results) && results.m_uniqueObjectIds.size()==1)
{
m_gripperIndex = results.m_uniqueObjectIds[0];
int numJoints = m_robotSim.getNumJoints(m_gripperIndex);
b3Printf("numJoints = %d",numJoints);
for (int i=0;i<numJoints;i++)
{
b3JointInfo jointInfo;
m_robotSim.getJointInfo(m_gripperIndex,i,&jointInfo);
b3Printf("joint[%d].m_jointName=%s",i,jointInfo.m_jointName);
}
/*
int fingerJointIndices[2]={1,3};
double fingerTargetPositions[2]={-0.04,0.04};
for (int i=0;i<2;i++)
{
b3JointMotorArgs controlArgs(CONTROL_MODE_POSITION_VELOCITY_PD);
controlArgs.m_targetPosition = fingerTargetPositions[i];
controlArgs.m_kp = 5.0;
controlArgs.m_kd = 3.0;
controlArgs.m_maxTorqueValue = 1.0;
m_robotSim.setJointMotorControl(m_gripperIndex,fingerJointIndices[i],controlArgs);
}
*/
int fingerJointIndices[3]={0,1,3};
double fingerTargetVelocities[3]={-0.2,.5,-.5};
double maxTorqueValues[3]={40.0,50.0,50.0};
for (int i=0;i<3;i++)
{
b3JointMotorArgs controlArgs(CONTROL_MODE_VELOCITY);
controlArgs.m_targetVelocity = fingerTargetVelocities[i];
controlArgs.m_maxTorqueValue = maxTorqueValues[i];
controlArgs.m_kd = 1.;
m_robotSim.setJointMotorControl(m_gripperIndex,fingerJointIndices[i],controlArgs);
}
}
}
{
b3RobotSimLoadFileArgs args("");
b3RobotSimLoadFileResults results;
args.m_fileName = "cube_small.urdf";
args.m_startPosition.setValue(0,0,.107);
args.m_startOrientation.setEulerZYX(0,0,0);
m_robotSim.loadFile(args,results);
}
if (1)
{
b3RobotSimLoadFileArgs args("");
args.m_fileName = "plane.urdf";
args.m_startPosition.setValue(0,0,0);
args.m_startOrientation.setEulerZYX(0,0,0);
args.m_forceOverrideFixedBase = true;
b3RobotSimLoadFileResults results;
m_robotSim.loadFile(args,results);
}
m_robotSim.setGravity(b3MakeVector3(0,0,-10));
}
}
virtual void exitPhysics()
{
m_robotSim.disconnect();
}
virtual void stepSimulation(float deltaTime)
{
if ((m_gripperIndex>=0))
{
int fingerJointIndices[3]={0,1,3};
double fingerTargetVelocities[3]={sGripperVerticalVelocity,sGripperClosingTargetVelocity
,-sGripperClosingTargetVelocity
};
double maxTorqueValues[3]={40.0,50.0,50.0};
for (int i=0;i<3;i++)
{
b3JointMotorArgs controlArgs(CONTROL_MODE_VELOCITY);
controlArgs.m_targetVelocity = fingerTargetVelocities[i];
controlArgs.m_maxTorqueValue = maxTorqueValues[i];
controlArgs.m_kd = 1.;
m_robotSim.setJointMotorControl(m_gripperIndex,fingerJointIndices[i],controlArgs);
}
}
m_robotSim.stepSimulation();
}
virtual void renderScene()
{
m_robotSim.renderScene();
//m_app->m_renderer->renderScene();
}
virtual void physicsDebugDraw()
{
}
virtual bool mouseMoveCallback(float x,float y)
{
return false;
}
virtual bool mouseButtonCallback(int button, int state, float x, float y)
{
return false;
}
virtual bool keyboardCallback(int key, int state)
{
return false;
}
virtual void resetCamera()
{
float dist = 1.5;
float pitch = 12;
float yaw = -10;
float targetPos[3]={-0.2,0.8,0.3};
if (m_app->m_renderer && m_app->m_renderer->getActiveCamera())
{
m_app->m_renderer->getActiveCamera()->setCameraDistance(dist);
m_app->m_renderer->getActiveCamera()->setCameraPitch(pitch);
m_app->m_renderer->getActiveCamera()->setCameraYaw(yaw);
m_app->m_renderer->getActiveCamera()->setCameraTargetPosition(targetPos[0],targetPos[1],targetPos[2]);
}
}
};
class CommonExampleInterface* GripperGraspExampleCreateFunc(struct CommonExampleOptions& options)
{
return new GripperGraspExample(options.m_guiHelper, options.m_option);
}

View File

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

View File

@@ -0,0 +1,204 @@
#include "R2D2GraspExample.h"
#include "../CommonInterfaces/CommonGraphicsAppInterface.h"
#include "Bullet3Common/b3Quaternion.h"
#include "Bullet3Common/b3AlignedObjectArray.h"
#include "../CommonInterfaces/CommonRenderInterface.h"
#include "../CommonInterfaces/CommonExampleInterface.h"
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
#include "../SharedMemory/PhysicsServerSharedMemory.h"
#include "../SharedMemory/PhysicsClientC_API.h"
#include <string>
#include "b3RobotSimAPI.h"
#include "../Utils/b3Clock.h"
///quick demo showing the right-handed coordinate system and positive rotations around each axis
class R2D2GraspExample : public CommonExampleInterface
{
CommonGraphicsApp* m_app;
GUIHelperInterface* m_guiHelper;
b3RobotSimAPI m_robotSim;
int m_options;
int m_r2d2Index;
float m_x;
float m_y;
float m_z;
b3AlignedObjectArray<int> m_movingInstances;
enum
{
numCubesX = 20,
numCubesY = 20
};
public:
R2D2GraspExample(GUIHelperInterface* helper, int options)
:m_app(helper->getAppInterface()),
m_guiHelper(helper),
m_options(options),
m_r2d2Index(-1),
m_x(0),
m_y(0),
m_z(0)
{
m_app->setUpAxis(2);
}
virtual ~R2D2GraspExample()
{
m_app->m_renderer->enableBlend(false);
}
virtual void physicsDebugDraw(int debugDrawMode)
{
}
virtual void initPhysics()
{
bool connected = m_robotSim.connect(m_guiHelper);
b3Printf("robotSim connected = %d",connected);
if ((m_options & eROBOTIC_LEARN_GRASP)!=0)
{
{
b3RobotSimLoadFileArgs args("");
args.m_fileName = "r2d2.urdf";
args.m_startPosition.setValue(0,0,.5);
b3RobotSimLoadFileResults results;
if (m_robotSim.loadFile(args, results) && results.m_uniqueObjectIds.size()==1)
{
int m_r2d2Index = results.m_uniqueObjectIds[0];
int numJoints = m_robotSim.getNumJoints(m_r2d2Index);
b3Printf("numJoints = %d",numJoints);
for (int i=0;i<numJoints;i++)
{
b3JointInfo jointInfo;
m_robotSim.getJointInfo(m_r2d2Index,i,&jointInfo);
b3Printf("joint[%d].m_jointName=%s",i,jointInfo.m_jointName);
}
int wheelJointIndices[4]={2,3,6,7};
int wheelTargetVelocities[4]={-10,-10,-10,-10};
for (int i=0;i<4;i++)
{
b3JointMotorArgs controlArgs(CONTROL_MODE_VELOCITY);
controlArgs.m_targetVelocity = wheelTargetVelocities[i];
controlArgs.m_maxTorqueValue = 1e30;
m_robotSim.setJointMotorControl(m_r2d2Index,wheelJointIndices[i],controlArgs);
}
}
}
{
b3RobotSimLoadFileArgs args("");
args.m_fileName = "kiva_shelf/model.sdf";
args.m_startPosition.setValue(0,0,.5);
args.m_startOrientation = b3Quaternion(0,B3_HALF_PI,0);
args.m_forceOverrideFixedBase = true;
args.m_fileType = B3_SDF_FILE;
//args.m_startOrientation = b3Quaternion()
b3RobotSimLoadFileResults results;
m_robotSim.loadFile(args,results);
}
{
b3RobotSimLoadFileArgs args("");
args.m_fileName = "plane.urdf";
args.m_startPosition.setValue(0,0,0);
args.m_forceOverrideFixedBase = true;
b3RobotSimLoadFileResults results;
m_robotSim.loadFile(args,results);
m_robotSim.setGravity(b3MakeVector3(0,0,-10));
}
}
if ((m_options & eROBOTIC_LEARN_COMPLIANT_CONTACT)!=0)
{
b3RobotSimLoadFileArgs args("");
b3RobotSimLoadFileResults results;
{
args.m_fileName = "cube.urdf";
args.m_startPosition.setValue(0,0,2.5);
args.m_startOrientation.setEulerZYX(0,0.2,0);
m_robotSim.loadFile(args,results);
}
{
args.m_fileName = "cube_no_friction.urdf";
args.m_startPosition.setValue(0,2,2.5);
args.m_startOrientation.setEulerZYX(0,0.2,0);
m_robotSim.loadFile(args,results);
}
{
b3RobotSimLoadFileArgs args("");
args.m_fileName = "plane.urdf";
args.m_startPosition.setValue(0,0,0);
args.m_startOrientation.setEulerZYX(0,0.2,0);
args.m_forceOverrideFixedBase = true;
b3RobotSimLoadFileResults results;
m_robotSim.loadFile(args,results);
m_robotSim.setGravity(b3MakeVector3(0,0,-10));
}
}
}
virtual void exitPhysics()
{
m_robotSim.disconnect();
}
virtual void stepSimulation(float deltaTime)
{
m_robotSim.stepSimulation();
}
virtual void renderScene()
{
m_robotSim.renderScene();
//m_app->m_renderer->renderScene();
}
virtual void physicsDebugDraw()
{
}
virtual bool mouseMoveCallback(float x,float y)
{
return false;
}
virtual bool mouseButtonCallback(int button, int state, float x, float y)
{
return false;
}
virtual bool keyboardCallback(int key, int state)
{
return false;
}
virtual void resetCamera()
{
float dist = 3;
float pitch = -75;
float yaw = 30;
float targetPos[3]={-0.2,0.8,0.3};
if (m_app->m_renderer && m_app->m_renderer->getActiveCamera())
{
m_app->m_renderer->getActiveCamera()->setCameraDistance(dist);
m_app->m_renderer->getActiveCamera()->setCameraPitch(pitch);
m_app->m_renderer->getActiveCamera()->setCameraYaw(yaw);
m_app->m_renderer->getActiveCamera()->setCameraTargetPosition(targetPos[0],targetPos[1],targetPos[2]);
}
}
};
class CommonExampleInterface* R2D2GraspExampleCreateFunc(struct CommonExampleOptions& options)
{
return new R2D2GraspExample(options.m_guiHelper, options.m_option);
}

View File

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

View File

@@ -0,0 +1,762 @@
#include "b3RobotSimAPI.h"
//#include "../CommonInterfaces/CommonGraphicsAppInterface.h"
#include "Bullet3Common/b3Quaternion.h"
#include "Bullet3Common/b3AlignedObjectArray.h"
#include "../CommonInterfaces/CommonRenderInterface.h"
//#include "../CommonInterfaces/CommonExampleInterface.h"
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
#include "../SharedMemory/PhysicsServerSharedMemory.h"
#include "../SharedMemory/PhysicsClientC_API.h"
#include <string>
#include "../Utils/b3Clock.h"
#include "../MultiThreading/b3ThreadSupportInterface.h"
void RobotThreadFunc(void* userPtr,void* lsMemory);
void* RobotlsMemoryFunc();
#define MAX_ROBOT_NUM_THREADS 1
enum
{
numCubesX = 20,
numCubesY = 20
};
enum TestRobotSimCommunicationEnums
{
eRequestTerminateRobotSim= 13,
eRobotSimIsUnInitialized,
eRobotSimIsInitialized,
eRobotSimInitializationFailed,
eRobotSimHasTerminated
};
enum MultiThreadedGUIHelperCommunicationEnums
{
eRobotSimGUIHelperIdle= 13,
eRobotSimGUIHelperRegisterTexture,
eRobotSimGUIHelperRegisterGraphicsShape,
eRobotSimGUIHelperRegisterGraphicsInstance,
eRobotSimGUIHelperCreateCollisionShapeGraphicsObject,
eRobotSimGUIHelperCreateCollisionObjectGraphicsObject,
eRobotSimGUIHelperRemoveAllGraphicsInstances,
};
#include <stdio.h>
//#include "BulletMultiThreaded/PlatformDefinitions.h"
#ifndef _WIN32
#include "../MultiThreading/b3PosixThreadSupport.h"
b3ThreadSupportInterface* createRobotSimThreadSupport(int numThreads)
{
b3PosixThreadSupport::ThreadConstructionInfo constructionInfo("RobotSimThreads",
RobotThreadFunc,
RobotlsMemoryFunc,
numThreads);
b3ThreadSupportInterface* threadSupport = new b3PosixThreadSupport(constructionInfo);
return threadSupport;
}
#elif defined( _WIN32)
#include "../MultiThreading/b3Win32ThreadSupport.h"
b3ThreadSupportInterface* createRobotSimThreadSupport(int numThreads)
{
b3Win32ThreadSupport::Win32ThreadConstructionInfo threadConstructionInfo("RobotSimThreads",RobotThreadFunc,RobotlsMemoryFunc,numThreads);
b3Win32ThreadSupport* threadSupport = new b3Win32ThreadSupport(threadConstructionInfo);
return threadSupport;
}
#endif
struct RobotSimArgs
{
RobotSimArgs()
:m_physicsServerPtr(0)
{
}
b3CriticalSection* m_cs;
PhysicsServerSharedMemory* m_physicsServerPtr;
b3AlignedObjectArray<b3Vector3> m_positions;
};
struct RobotSimThreadLocalStorage
{
int threadId;
};
void RobotThreadFunc(void* userPtr,void* lsMemory)
{
printf("RobotThreadFunc thread started\n");
RobotSimThreadLocalStorage* localStorage = (RobotSimThreadLocalStorage*) lsMemory;
RobotSimArgs* args = (RobotSimArgs*) userPtr;
int workLeft = true;
b3Clock clock;
clock.reset();
bool init = true;
if (init)
{
args->m_cs->lock();
args->m_cs->setSharedParam(0,eRobotSimIsInitialized);
args->m_cs->unlock();
do
{
//todo(erwincoumans): do we want some sleep to reduce CPU resources in this thread?
#if 0
double deltaTimeInSeconds = double(clock.getTimeMicroseconds())/1000000.;
if (deltaTimeInSeconds<(1./260.))
{
if (deltaTimeInSeconds<.001)
continue;
}
clock.reset();
#endif //
args->m_physicsServerPtr->processClientCommands();
} while (args->m_cs->getSharedParam(0)!=eRequestTerminateRobotSim);
} else
{
args->m_cs->lock();
args->m_cs->setSharedParam(0,eRobotSimInitializationFailed);
args->m_cs->unlock();
}
//do nothing
}
void* RobotlsMemoryFunc()
{
//don't create local store memory, just return 0
return new RobotSimThreadLocalStorage;
}
ATTRIBUTE_ALIGNED16(class) MultiThreadedOpenGLGuiHelper : public GUIHelperInterface
{
CommonGraphicsApp* m_app;
b3CriticalSection* m_cs;
public:
BT_DECLARE_ALIGNED_ALLOCATOR();
GUIHelperInterface* m_childGuiHelper;
const unsigned char* m_texels;
int m_textureWidth;
int m_textureHeight;
int m_shapeIndex;
const float* m_position;
const float* m_quaternion;
const float* m_color;
const float* m_scaling;
const float* m_vertices;
int m_numvertices;
const int* m_indices;
int m_numIndices;
int m_primitiveType;
int m_textureId;
int m_instanceId;
MultiThreadedOpenGLGuiHelper(CommonGraphicsApp* app, GUIHelperInterface* guiHelper)
:m_app(app)
,m_cs(0),
m_texels(0),
m_textureId(-1)
{
m_childGuiHelper = guiHelper;;
}
virtual ~MultiThreadedOpenGLGuiHelper()
{
delete m_childGuiHelper;
}
void setCriticalSection(b3CriticalSection* cs)
{
m_cs = cs;
}
b3CriticalSection* getCriticalSection()
{
return m_cs;
}
virtual void createRigidBodyGraphicsObject(btRigidBody* body,const btVector3& color){}
btCollisionObject* m_obj;
btVector3 m_color2;
virtual void createCollisionObjectGraphicsObject(btCollisionObject* obj,const btVector3& color)
{
m_obj = obj;
m_color2 = color;
m_cs->lock();
m_cs->setSharedParam(1,eRobotSimGUIHelperCreateCollisionObjectGraphicsObject);
m_cs->unlock();
while (m_cs->getSharedParam(1)!=eRobotSimGUIHelperIdle)
{
}
}
btCollisionShape* m_colShape;
virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape)
{
m_colShape = collisionShape;
m_cs->lock();
m_cs->setSharedParam(1,eRobotSimGUIHelperCreateCollisionShapeGraphicsObject);
m_cs->unlock();
while (m_cs->getSharedParam(1)!=eRobotSimGUIHelperIdle)
{
}
}
virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld)
{
//this check is to prevent a crash, in case we removed all graphics instances, but there are still physics objects.
//the check will be obsolete, once we have a better/safer way of synchronizing physics->graphics transforms
if ( m_childGuiHelper->getRenderInterface()->getTotalNumInstances()>0)
{
m_childGuiHelper->syncPhysicsToGraphics(rbWorld);
}
}
virtual void render(const btDiscreteDynamicsWorld* rbWorld)
{
m_childGuiHelper->render(0);
}
virtual void createPhysicsDebugDrawer( btDiscreteDynamicsWorld* rbWorld){}
virtual int registerTexture(const unsigned char* texels, int width, int height)
{
m_texels = texels;
m_textureWidth = width;
m_textureHeight = height;
m_cs->lock();
m_cs->setSharedParam(1,eRobotSimGUIHelperRegisterTexture);
m_cs->unlock();
while (m_cs->getSharedParam(1)!=eRobotSimGUIHelperIdle)
{
}
return m_textureId;
}
virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices,int primitiveType, int textureId)
{
m_vertices = vertices;
m_numvertices = numvertices;
m_indices = indices;
m_numIndices = numIndices;
m_primitiveType = primitiveType;
m_textureId = textureId;
m_cs->lock();
m_cs->setSharedParam(1,eRobotSimGUIHelperRegisterGraphicsShape);
m_cs->unlock();
while (m_cs->getSharedParam(1)!=eRobotSimGUIHelperIdle)
{
}
return m_shapeIndex;
}
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling)
{
m_shapeIndex = shapeIndex;
m_position = position;
m_quaternion = quaternion;
m_color = color;
m_scaling = scaling;
m_cs->lock();
m_cs->setSharedParam(1,eRobotSimGUIHelperRegisterGraphicsInstance);
m_cs->unlock();
while (m_cs->getSharedParam(1)!=eRobotSimGUIHelperIdle)
{
}
return m_instanceId;
}
virtual void removeAllGraphicsInstances()
{
m_cs->lock();
m_cs->setSharedParam(1,eRobotSimGUIHelperRemoveAllGraphicsInstances);
m_cs->unlock();
while (m_cs->getSharedParam(1)!=eRobotSimGUIHelperIdle)
{
}
}
virtual Common2dCanvasInterface* get2dCanvasInterface()
{
return 0;
}
virtual CommonParameterInterface* getParameterInterface()
{
return 0;
}
virtual CommonRenderInterface* getRenderInterface()
{
return 0;
}
virtual CommonGraphicsApp* getAppInterface()
{
return m_childGuiHelper->getAppInterface();
}
virtual void setUpAxis(int axis)
{
m_childGuiHelper->setUpAxis(axis);
}
virtual void resetCamera(float camDist, float pitch, float yaw, float camPosX,float camPosY, float camPosZ)
{
}
virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16], unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels, float* depthBuffer, int depthBufferSizeInPixels, int startPixelIndex, int destinationWidth, int destinationHeight, int* numPixelsCopied)
{
if (numPixelsCopied)
*numPixelsCopied = 0;
}
virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld)
{
}
virtual void drawText3D( const char* txt, float posX, float posZY, float posZ, float size)
{
}
};
struct b3RobotSimAPI_InternalData
{
//GUIHelperInterface* m_guiHelper;
PhysicsServerSharedMemory m_physicsServer;
b3PhysicsClientHandle m_physicsClient;
b3ThreadSupportInterface* m_threadSupport;
RobotSimArgs m_args[MAX_ROBOT_NUM_THREADS];
MultiThreadedOpenGLGuiHelper* m_multiThreadedHelper;
bool m_connected;
b3RobotSimAPI_InternalData()
:m_multiThreadedHelper(0),
m_physicsClient(0),
m_connected(false)
{
}
};
b3RobotSimAPI::b3RobotSimAPI()
{
m_data = new b3RobotSimAPI_InternalData;
}
void b3RobotSimAPI::stepSimulation()
{
b3SharedMemoryStatusHandle statusHandle;
int statusType;
b3Assert(b3CanSubmitCommand(m_data->m_physicsClient));
if (b3CanSubmitCommand(m_data->m_physicsClient))
{
statusHandle = b3SubmitClientCommandAndWaitStatus(m_data->m_physicsClient, b3InitStepSimulationCommand(m_data->m_physicsClient));
statusType = b3GetStatusType(statusHandle);
b3Assert(statusType==CMD_STEP_FORWARD_SIMULATION_COMPLETED);
}
}
void b3RobotSimAPI::setGravity(const b3Vector3& gravityAcceleration)
{
b3SharedMemoryCommandHandle command = b3InitPhysicsParamCommand(m_data->m_physicsClient);
b3SharedMemoryStatusHandle statusHandle;
b3PhysicsParamSetGravity(command, gravityAcceleration[0],gravityAcceleration[1],gravityAcceleration[2]);
statusHandle = b3SubmitClientCommandAndWaitStatus(m_data->m_physicsClient, command);
b3Assert(b3GetStatusType(statusHandle)==CMD_CLIENT_COMMAND_COMPLETED);
}
b3RobotSimAPI::~b3RobotSimAPI()
{
delete m_data;
}
void b3RobotSimAPI::processMultiThreadedGraphicsRequests()
{
switch (m_data->m_multiThreadedHelper->getCriticalSection()->getSharedParam(1))
{
case eRobotSimGUIHelperCreateCollisionShapeGraphicsObject:
{
m_data->m_multiThreadedHelper->m_childGuiHelper->createCollisionShapeGraphicsObject(m_data->m_multiThreadedHelper->m_colShape);
m_data->m_multiThreadedHelper->getCriticalSection()->lock();
m_data->m_multiThreadedHelper->getCriticalSection()->setSharedParam(1,eRobotSimGUIHelperIdle);
m_data->m_multiThreadedHelper->getCriticalSection()->unlock();
break;
}
case eRobotSimGUIHelperCreateCollisionObjectGraphicsObject:
{
m_data->m_multiThreadedHelper->m_childGuiHelper->createCollisionObjectGraphicsObject(m_data->m_multiThreadedHelper->m_obj,
m_data->m_multiThreadedHelper->m_color2);
m_data->m_multiThreadedHelper->getCriticalSection()->lock();
m_data->m_multiThreadedHelper->getCriticalSection()->setSharedParam(1,eRobotSimGUIHelperIdle);
m_data->m_multiThreadedHelper->getCriticalSection()->unlock();
break;
}
case eRobotSimGUIHelperRegisterTexture:
{
m_data->m_multiThreadedHelper->m_textureId = m_data->m_multiThreadedHelper->m_childGuiHelper->registerTexture(m_data->m_multiThreadedHelper->m_texels,
m_data->m_multiThreadedHelper->m_textureWidth,m_data->m_multiThreadedHelper->m_textureHeight);
m_data->m_multiThreadedHelper->getCriticalSection()->lock();
m_data->m_multiThreadedHelper->getCriticalSection()->setSharedParam(1,eRobotSimGUIHelperIdle);
m_data->m_multiThreadedHelper->getCriticalSection()->unlock();
break;
}
case eRobotSimGUIHelperRegisterGraphicsShape:
{
m_data->m_multiThreadedHelper->m_shapeIndex = m_data->m_multiThreadedHelper->m_childGuiHelper->registerGraphicsShape(
m_data->m_multiThreadedHelper->m_vertices,
m_data->m_multiThreadedHelper->m_numvertices,
m_data->m_multiThreadedHelper->m_indices,
m_data->m_multiThreadedHelper->m_numIndices,
m_data->m_multiThreadedHelper->m_primitiveType,
m_data->m_multiThreadedHelper->m_textureId);
m_data->m_multiThreadedHelper->getCriticalSection()->lock();
m_data->m_multiThreadedHelper->getCriticalSection()->setSharedParam(1,eRobotSimGUIHelperIdle);
m_data->m_multiThreadedHelper->getCriticalSection()->unlock();
break;
}
case eRobotSimGUIHelperRegisterGraphicsInstance:
{
m_data->m_multiThreadedHelper->m_instanceId = m_data->m_multiThreadedHelper->m_childGuiHelper->registerGraphicsInstance(
m_data->m_multiThreadedHelper->m_shapeIndex,
m_data->m_multiThreadedHelper->m_position,
m_data->m_multiThreadedHelper->m_quaternion,
m_data->m_multiThreadedHelper->m_color,
m_data->m_multiThreadedHelper->m_scaling);
m_data->m_multiThreadedHelper->getCriticalSection()->lock();
m_data->m_multiThreadedHelper->getCriticalSection()->setSharedParam(1,eRobotSimGUIHelperIdle);
m_data->m_multiThreadedHelper->getCriticalSection()->unlock();
break;
}
case eRobotSimGUIHelperRemoveAllGraphicsInstances:
{
m_data->m_multiThreadedHelper->m_childGuiHelper->removeAllGraphicsInstances();
int numRenderInstances = m_data->m_multiThreadedHelper->m_childGuiHelper->getRenderInterface()->getTotalNumInstances();
b3Assert(numRenderInstances==0);
m_data->m_multiThreadedHelper->getCriticalSection()->lock();
m_data->m_multiThreadedHelper->getCriticalSection()->setSharedParam(1,eRobotSimGUIHelperIdle);
m_data->m_multiThreadedHelper->getCriticalSection()->unlock();
break;
}
case eRobotSimGUIHelperIdle:
default:
{
}
}
#if 0
if (m_options == PHYSICS_SERVER_USE_RTC_CLOCK)
{
btClock rtc;
btScalar endTime = rtc.getTimeMilliseconds() + deltaTime*btScalar(800);
while (rtc.getTimeMilliseconds()<endTime)
{
m_physicsServer.processClientCommands();
}
} else
{
//for (int i=0;i<10;i++)
m_physicsServer.processClientCommands();
}
#endif
}
b3SharedMemoryStatusHandle b3RobotSimAPI::submitClientCommandAndWaitStatusMultiThreaded(b3PhysicsClientHandle physClient, b3SharedMemoryCommandHandle commandHandle)
{
int timeout = 1024*1024*1024;
b3SharedMemoryStatusHandle statusHandle=0;
b3SubmitClientCommand(physClient,commandHandle);
while ((statusHandle==0) && (timeout-- > 0))
{
statusHandle =b3ProcessServerStatus(physClient);
processMultiThreadedGraphicsRequests();
}
return (b3SharedMemoryStatusHandle) statusHandle;
}
int b3RobotSimAPI::getNumJoints(int bodyUniqueId) const
{
return b3GetNumJoints(m_data->m_physicsClient,bodyUniqueId);
}
bool b3RobotSimAPI::getJointInfo(int bodyUniqueId, int jointIndex, b3JointInfo* jointInfo)
{
return (b3GetJointInfo(m_data->m_physicsClient,bodyUniqueId, jointIndex,jointInfo)!=0);
}
void b3RobotSimAPI::setJointMotorControl(int bodyUniqueId, int jointIndex, const b3JointMotorArgs& args)
{
b3SharedMemoryStatusHandle statusHandle;
switch (args.m_controlMode)
{
case CONTROL_MODE_VELOCITY:
{
b3SharedMemoryCommandHandle command = b3JointControlCommandInit2( m_data->m_physicsClient, bodyUniqueId, CONTROL_MODE_VELOCITY);
b3JointInfo jointInfo;
b3GetJointInfo(m_data->m_physicsClient, bodyUniqueId, jointIndex, &jointInfo);
int uIndex = jointInfo.m_uIndex;
b3JointControlSetKd(command,uIndex,args.m_kd);
b3JointControlSetDesiredVelocity(command,uIndex,args.m_targetVelocity);
b3JointControlSetMaximumForce(command,uIndex,args.m_maxTorqueValue);
statusHandle = b3SubmitClientCommandAndWaitStatus(m_data->m_physicsClient, command);
break;
}
case CONTROL_MODE_POSITION_VELOCITY_PD:
{
b3SharedMemoryCommandHandle command = b3JointControlCommandInit2( m_data->m_physicsClient, bodyUniqueId, CONTROL_MODE_POSITION_VELOCITY_PD);
b3JointInfo jointInfo;
b3GetJointInfo(m_data->m_physicsClient, bodyUniqueId, jointIndex, &jointInfo);
int uIndex = jointInfo.m_uIndex;
int qIndex = jointInfo.m_qIndex;
b3JointControlSetDesiredPosition(command,qIndex,args.m_targetPosition);
b3JointControlSetKp(command,uIndex,args.m_kp);
b3JointControlSetDesiredVelocity(command,uIndex,args.m_targetVelocity);
b3JointControlSetKd(command,uIndex,args.m_kd);
b3JointControlSetMaximumForce(command,uIndex,args.m_maxTorqueValue);
statusHandle = b3SubmitClientCommandAndWaitStatus(m_data->m_physicsClient, command);
break;
}
case CONTROL_MODE_TORQUE:
{
b3SharedMemoryCommandHandle command = b3JointControlCommandInit2( m_data->m_physicsClient, bodyUniqueId, CONTROL_MODE_TORQUE);
b3JointInfo jointInfo;
b3GetJointInfo(m_data->m_physicsClient, bodyUniqueId, jointIndex, &jointInfo);
int uIndex = jointInfo.m_uIndex;
b3JointControlSetDesiredForceTorque(command,uIndex,args.m_maxTorqueValue);
statusHandle = b3SubmitClientCommandAndWaitStatus(m_data->m_physicsClient, command);
break;
}
default:
{
b3Error("Unknown control command in b3RobotSimAPI::setJointMotorControl");
}
}
}
bool b3RobotSimAPI::loadFile(const struct b3RobotSimLoadFileArgs& args, b3RobotSimLoadFileResults& results)
{
bool statusOk = false;
int robotUniqueId = -1;
b3Assert(m_data->m_connected);
switch (args.m_fileType)
{
case B3_URDF_FILE:
{
b3SharedMemoryStatusHandle statusHandle;
int statusType;
b3SharedMemoryCommandHandle command = b3LoadUrdfCommandInit(m_data->m_physicsClient, args.m_fileName.c_str());
//setting the initial position, orientation and other arguments are optional
b3LoadUrdfCommandSetStartPosition(command, args.m_startPosition[0],
args.m_startPosition[1],
args.m_startPosition[2]);
b3LoadUrdfCommandSetStartOrientation(command,args.m_startOrientation[0]
,args.m_startOrientation[1]
,args.m_startOrientation[2]
,args.m_startOrientation[3]);
if (args.m_forceOverrideFixedBase)
{
b3LoadUrdfCommandSetUseFixedBase(command,true);
}
statusHandle = submitClientCommandAndWaitStatusMultiThreaded(m_data->m_physicsClient, command);
statusType = b3GetStatusType(statusHandle);
b3Assert(statusType==CMD_URDF_LOADING_COMPLETED);
robotUniqueId = b3GetStatusBodyIndex(statusHandle);
results.m_uniqueObjectIds.push_back(robotUniqueId);
statusOk = true;
break;
}
case B3_SDF_FILE:
{
b3SharedMemoryStatusHandle statusHandle;
int statusType;
b3SharedMemoryCommandHandle command = b3LoadSdfCommandInit(m_data->m_physicsClient, args.m_fileName.c_str());
statusHandle = submitClientCommandAndWaitStatusMultiThreaded(m_data->m_physicsClient, command);
statusType = b3GetStatusType(statusHandle);
b3Assert(statusType == CMD_SDF_LOADING_COMPLETED);
if (statusType == CMD_SDF_LOADING_COMPLETED)
{
int numBodies = b3GetStatusBodyIndices(statusHandle, 0,0);
if (numBodies)
{
results.m_uniqueObjectIds.resize(numBodies);
int numBodies = b3GetStatusBodyIndices(statusHandle, &results.m_uniqueObjectIds[0],results.m_uniqueObjectIds.size());
}
statusOk = true;
}
break;
}
default:
{
b3Warning("Unknown file type in b3RobotSimAPI::loadFile");
}
}
return statusOk;
}
bool b3RobotSimAPI::connect(GUIHelperInterface* guiHelper)
{
m_data->m_multiThreadedHelper = new MultiThreadedOpenGLGuiHelper(guiHelper->getAppInterface(),guiHelper);
MultiThreadedOpenGLGuiHelper* guiHelperWrapper = new MultiThreadedOpenGLGuiHelper(guiHelper->getAppInterface(),guiHelper);
m_data->m_threadSupport = createRobotSimThreadSupport(MAX_ROBOT_NUM_THREADS);
for (int i=0;i<m_data->m_threadSupport->getNumTasks();i++)
{
RobotSimThreadLocalStorage* storage = (RobotSimThreadLocalStorage*) m_data->m_threadSupport->getThreadLocalMemory(i);
b3Assert(storage);
storage->threadId = i;
//storage->m_sharedMem = data->m_sharedMem;
}
for (int w=0;w<MAX_ROBOT_NUM_THREADS;w++)
{
m_data->m_args[w].m_cs = m_data->m_threadSupport->createCriticalSection();
m_data->m_args[w].m_cs->setSharedParam(0,eRobotSimIsUnInitialized);
int numMoving = 0;
m_data->m_args[w].m_positions.resize(numMoving);
m_data->m_args[w].m_physicsServerPtr = &m_data->m_physicsServer;
int index = 0;
m_data->m_threadSupport->runTask(B3_THREAD_SCHEDULE_TASK, (void*) &m_data->m_args[w], w);
while (m_data->m_args[w].m_cs->getSharedParam(0)==eRobotSimIsUnInitialized)
{
}
}
m_data->m_args[0].m_cs->setSharedParam(1,eRobotSimGUIHelperIdle);
m_data->m_multiThreadedHelper->setCriticalSection(m_data->m_args[0].m_cs);
m_data->m_connected = m_data->m_physicsServer.connectSharedMemory( m_data->m_multiThreadedHelper);
b3Assert(m_data->m_connected);
m_data->m_physicsClient = b3ConnectSharedMemory(SHARED_MEMORY_KEY);
int canSubmit = b3CanSubmitCommand(m_data->m_physicsClient);
b3Assert(canSubmit);
return m_data->m_connected && canSubmit;
}
void b3RobotSimAPI::disconnect()
{
for (int i=0;i<MAX_ROBOT_NUM_THREADS;i++)
{
m_data->m_args[i].m_cs->lock();
m_data->m_args[i].m_cs->setSharedParam(0,eRequestTerminateRobotSim);
m_data->m_args[i].m_cs->unlock();
}
int numActiveThreads = MAX_ROBOT_NUM_THREADS;
while (numActiveThreads)
{
int arg0,arg1;
if (m_data->m_threadSupport->isTaskCompleted(&arg0,&arg1,0))
{
numActiveThreads--;
printf("numActiveThreads = %d\n",numActiveThreads);
} else
{
}
};
printf("stopping threads\n");
delete m_data->m_threadSupport;
m_data->m_threadSupport = 0;
b3DisconnectSharedMemory(m_data->m_physicsClient);
m_data->m_physicsServer.disconnectSharedMemory(true);
m_data->m_connected = false;
}
void b3RobotSimAPI::renderScene()
{
if (m_data->m_multiThreadedHelper->m_childGuiHelper->getRenderInterface())
{
m_data->m_multiThreadedHelper->m_childGuiHelper->getRenderInterface()->writeTransforms();
}
m_data->m_physicsServer.renderScene();
}

View File

@@ -0,0 +1,99 @@
#ifndef B3_ROBOT_SIM_API_H
#define B3_ROBOT_SIM_API_H
///todo: remove those includes from this header
#include "../SharedMemory/PhysicsClientC_API.h"
#include "../SharedMemory/SharedMemoryPublic.h"
#include "Bullet3Common/b3Vector3.h"
#include "Bullet3Common/b3Quaternion.h"
#include "Bullet3Common/b3AlignedObjectArray.h"
#include <string>
enum b3RigidSimFileType
{
B3_URDF_FILE=1,
B3_SDF_FILE,
B3_AUTO_DETECT_FILE//todo based on extension
};
struct b3RobotSimLoadFileArgs
{
std::string m_fileName;
b3Vector3 m_startPosition;
b3Quaternion m_startOrientation;
bool m_forceOverrideFixedBase;
int m_fileType;
b3RobotSimLoadFileArgs(const std::string& fileName)
:m_fileName(fileName),
m_startPosition(b3MakeVector3(0,0,0)),
m_startOrientation(b3Quaternion(0,0,0,1)),
m_forceOverrideFixedBase(false),
m_fileType(B3_URDF_FILE)
{
}
};
struct b3RobotSimLoadFileResults
{
b3AlignedObjectArray<int> m_uniqueObjectIds;
b3RobotSimLoadFileResults()
{
}
};
struct b3JointMotorArgs
{
int m_controlMode;
double m_targetPosition;
double m_kp;
double m_targetVelocity;
double m_kd;
double m_maxTorqueValue;
b3JointMotorArgs(int controlMode)
:m_controlMode(controlMode),
m_targetPosition(0),
m_kp(0.1),
m_targetVelocity(0),
m_kd(0.9),
m_maxTorqueValue(1000)
{
}
};
class b3RobotSimAPI
{
struct b3RobotSimAPI_InternalData* m_data;
void processMultiThreadedGraphicsRequests();
b3SharedMemoryStatusHandle submitClientCommandAndWaitStatusMultiThreaded(b3PhysicsClientHandle physClient, b3SharedMemoryCommandHandle commandHandle);
public:
b3RobotSimAPI();
virtual ~b3RobotSimAPI();
bool connect(struct GUIHelperInterface* guiHelper);
void disconnect();
bool loadFile(const struct b3RobotSimLoadFileArgs& args, b3RobotSimLoadFileResults& results);
int getNumJoints(int bodyUniqueId) const;
bool getJointInfo(int bodyUniqueId, int jointIndex, b3JointInfo* jointInfo);
void setJointMotorControl(int bodyUniqueId, int jointIndex, const struct b3JointMotorArgs& args);
void stepSimulation();
void setGravity(const b3Vector3& gravityAcceleration);
void renderScene();
};
#endif //B3_ROBOT_SIM_API_H

View File

@@ -234,9 +234,8 @@ void RollingFrictionDemo::initPhysics()
{
btSerializer* s = new btDefaultSerializer;
m_dynamicsWorld->serialize(s);
b3ResourcePath p;
char resourcePath[1024];
if (p.findResourcePath("slope.bullet",resourcePath,1024))
if (b3ResourcePath::findResourcePath("slope.bullet",resourcePath,1024))
{
FILE* f = fopen(resourcePath,"wb");
fwrite(s->getBufferPointer(),s->getCurrentBufferSize(),1,f);

View File

@@ -26,7 +26,7 @@ public:
virtual int getNumJoints(int bodyIndex) const = 0;
virtual void getJointInfo(int bodyIndex, int jointIndex, struct b3JointInfo& info) const = 0;
virtual bool getJointInfo(int bodyIndex, int jointIndex, struct b3JointInfo& info) const = 0;
virtual void setSharedMemoryKey(int key) = 0;

View File

@@ -1,10 +1,34 @@
#include "PhysicsClientC_API.h"
#include "PhysicsClientSharedMemory.h"
#include "Bullet3Common/b3Scalar.h"
#include "Bullet3Common/b3Vector3.h"
#include <string.h>
#include "SharedMemoryCommands.h"
b3SharedMemoryCommandHandle b3LoadSdfCommandInit(b3PhysicsClientHandle physClient, const char* sdfFileName)
{
PhysicsClient* cl = (PhysicsClient* ) physClient;
b3Assert(cl);
b3Assert(cl->canSubmitCommand());
struct SharedMemoryCommand* command = cl->getAvailableSharedMemoryCommand();
b3Assert(command);
command->m_type = CMD_LOAD_SDF;
int len = strlen(sdfFileName);
if (len<MAX_SDF_FILENAME_LENGTH)
{
strcpy(command->m_sdfArguments.m_sdfFileName,sdfFileName);
} else
{
command->m_sdfArguments.m_sdfFileName[0] = 0;
}
command->m_updateFlags = SDF_ARGS_FILE_NAME;
return (b3SharedMemoryCommandHandle) command;
}
b3SharedMemoryCommandHandle b3LoadUrdfCommandInit(b3PhysicsClientHandle physClient, const char* urdfFileName)
{
@@ -91,6 +115,15 @@ int b3PhysicsParamSetGravity(b3SharedMemoryCommandHandle commandHandle, doub
return 0;
}
int b3PhysicsParamSetRealTimeSimulation(b3SharedMemoryCommandHandle commandHandle, int enableRealTimeSimulation)
{
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*) commandHandle;
b3Assert(command->m_type == CMD_SEND_PHYSICS_SIMULATION_PARAMETERS);
command->m_physSimParamArgs.m_allowRealTimeSimulation = enableRealTimeSimulation;
command->m_updateFlags |= SIM_PARAM_UPDATE_REAL_TIME_SIMULATION;
return 0;
}
int b3PhysicsParamSetTimeStep(b3SharedMemoryCommandHandle commandHandle, double timeStep)
{
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*) commandHandle;
@@ -127,7 +160,12 @@ b3SharedMemoryCommandHandle b3InitResetSimulationCommand(b3PhysicsClientHand
}
b3SharedMemoryCommandHandle b3JointControlCommandInit( b3PhysicsClientHandle physClient, int controlMode)
b3SharedMemoryCommandHandle b3JointControlCommandInit(b3PhysicsClientHandle physClient, int controlMode)
{
return b3JointControlCommandInit2(physClient,0,controlMode);
}
b3SharedMemoryCommandHandle b3JointControlCommandInit2( b3PhysicsClientHandle physClient, int bodyUniqueId, int controlMode)
{
PhysicsClient* cl = (PhysicsClient* ) physClient;
b3Assert(cl);
@@ -136,8 +174,12 @@ b3SharedMemoryCommandHandle b3JointControlCommandInit( b3PhysicsClientHandle phy
b3Assert(command);
command->m_type = CMD_SEND_DESIRED_STATE;
command->m_sendDesiredStateCommandArgument.m_controlMode = controlMode;
command->m_sendDesiredStateCommandArgument.m_bodyUniqueId = 0;
command->m_sendDesiredStateCommandArgument.m_bodyUniqueId = bodyUniqueId;
command->m_updateFlags = 0;
for (int i=0;i<MAX_DEGREE_OF_FREEDOM;i++)
{
command->m_sendDesiredStateCommandArgument.m_hasDesiredStateFlags[i] = 0;
}
return (b3SharedMemoryCommandHandle) command;
}
@@ -146,6 +188,9 @@ int b3JointControlSetDesiredPosition(b3SharedMemoryCommandHandle commandHandle,
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*) commandHandle;
b3Assert(command);
command->m_sendDesiredStateCommandArgument.m_desiredStateQ[qIndex] = value;
command->m_updateFlags |= SIM_DESIRED_STATE_HAS_Q;
command->m_sendDesiredStateCommandArgument.m_hasDesiredStateFlags[qIndex] |= SIM_DESIRED_STATE_HAS_Q;
return 0;
}
@@ -154,6 +199,9 @@ int b3JointControlSetKp(b3SharedMemoryCommandHandle commandHandle, int dofIndex,
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*) commandHandle;
b3Assert(command);
command->m_sendDesiredStateCommandArgument.m_Kp[dofIndex] = value;
command->m_updateFlags |= SIM_DESIRED_STATE_HAS_KP;
command->m_sendDesiredStateCommandArgument.m_hasDesiredStateFlags[dofIndex] |= SIM_DESIRED_STATE_HAS_KP;
return 0;
}
@@ -162,6 +210,9 @@ int b3JointControlSetKd(b3SharedMemoryCommandHandle commandHandle, int dofIndex,
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*) commandHandle;
b3Assert(command);
command->m_sendDesiredStateCommandArgument.m_Kd[dofIndex] = value;
command->m_updateFlags |= SIM_DESIRED_STATE_HAS_KD;
command->m_sendDesiredStateCommandArgument.m_hasDesiredStateFlags[dofIndex] |= SIM_DESIRED_STATE_HAS_KD;
return 0;
}
@@ -170,6 +221,9 @@ int b3JointControlSetDesiredVelocity(b3SharedMemoryCommandHandle commandHandle,
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*) commandHandle;
b3Assert(command);
command->m_sendDesiredStateCommandArgument.m_desiredStateQdot[dofIndex] = value;
command->m_updateFlags |= SIM_DESIRED_STATE_HAS_QDOT;
command->m_sendDesiredStateCommandArgument.m_hasDesiredStateFlags[dofIndex] |= SIM_DESIRED_STATE_HAS_QDOT;
return 0;
}
@@ -179,6 +233,9 @@ int b3JointControlSetMaximumForce(b3SharedMemoryCommandHandle commandHandle, int
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*) commandHandle;
b3Assert(command);
command->m_sendDesiredStateCommandArgument.m_desiredStateForceTorque[dofIndex] = value;
command->m_updateFlags |= SIM_DESIRED_STATE_HAS_MAX_FORCE;
command->m_sendDesiredStateCommandArgument.m_hasDesiredStateFlags[dofIndex] |= SIM_DESIRED_STATE_HAS_MAX_FORCE;
return 0;
}
@@ -187,6 +244,9 @@ int b3JointControlSetDesiredForceTorque(b3SharedMemoryCommandHandle commandHandl
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*) commandHandle;
b3Assert(command);
command->m_sendDesiredStateCommandArgument.m_desiredStateForceTorque[dofIndex] = value;
command->m_updateFlags |= SIM_DESIRED_STATE_HAS_MAX_FORCE;
command->m_sendDesiredStateCommandArgument.m_hasDesiredStateFlags[dofIndex] |= SIM_DESIRED_STATE_HAS_MAX_FORCE;
return 0;
}
@@ -335,6 +395,7 @@ int b3CreateBoxCommandSetStartOrientation(b3SharedMemoryCommandHandle commandHan
b3SharedMemoryCommandHandle b3CreatePoseCommandInit(b3PhysicsClientHandle physClient, int bodyIndex)
{
PhysicsClient* cl = (PhysicsClient* ) physClient;
b3Assert(cl);
b3Assert(cl->canSubmitCommand());
@@ -343,6 +404,11 @@ b3SharedMemoryCommandHandle b3CreatePoseCommandInit(b3PhysicsClientHandle physCl
command->m_type = CMD_INIT_POSE;
command->m_updateFlags =0;
command->m_initPoseArgs.m_bodyUniqueId = bodyIndex;
//a bit slow, initialing the full range to zero...
for (int i=0;i<MAX_DEGREE_OF_FREEDOM;i++)
{
command->m_initPoseArgs.m_hasInitialStateQ[i] = 0;
}
return (b3SharedMemoryCommandHandle) command;
}
@@ -355,6 +421,11 @@ int b3CreatePoseCommandSetBasePosition(b3SharedMemoryCommandHandle commandHandle
command->m_initPoseArgs.m_initialStateQ[0] = startPosX;
command->m_initPoseArgs.m_initialStateQ[1] = startPosY;
command->m_initPoseArgs.m_initialStateQ[2] = startPosZ;
command->m_initPoseArgs.m_hasInitialStateQ[0] = 1;
command->m_initPoseArgs.m_hasInitialStateQ[1] = 1;
command->m_initPoseArgs.m_hasInitialStateQ[2] = 1;
return 0;
}
@@ -368,6 +439,12 @@ int b3CreatePoseCommandSetBaseOrientation(b3SharedMemoryCommandHandle commandHan
command->m_initPoseArgs.m_initialStateQ[4] = startOrnY;
command->m_initPoseArgs.m_initialStateQ[5] = startOrnZ;
command->m_initPoseArgs.m_initialStateQ[6] = startOrnW;
command->m_initPoseArgs.m_hasInitialStateQ[3] = 1;
command->m_initPoseArgs.m_hasInitialStateQ[4] = 1;
command->m_initPoseArgs.m_hasInitialStateQ[5] = 1;
command->m_initPoseArgs.m_hasInitialStateQ[6] = 1;
return 0;
}
@@ -380,6 +457,7 @@ int b3CreatePoseCommandSetJointPositions(b3SharedMemoryCommandHandle commandHand
for (int i=0;i<numJointPositions;i++)
{
command->m_initPoseArgs.m_initialStateQ[i+7] = jointPositions[i];
command->m_initPoseArgs.m_hasInitialStateQ[i+7] = 1;
}
return 0;
}
@@ -396,6 +474,7 @@ int b3CreatePoseCommandSetJointPosition(b3PhysicsClientHandle physClient, b3Shar
if ((info.m_flags & JOINT_HAS_MOTORIZED_POWER) && info.m_qIndex >=0)
{
command->m_initPoseArgs.m_initialStateQ[info.m_qIndex] = jointPosition;
command->m_initPoseArgs.m_hasInitialStateQ[info.m_qIndex] = 1;
}
return 0;
}
@@ -403,7 +482,7 @@ int b3CreatePoseCommandSetJointPosition(b3PhysicsClientHandle physClient, b3Shar
b3SharedMemoryCommandHandle b3CreateSensorCommandInit(b3PhysicsClientHandle physClient)
b3SharedMemoryCommandHandle b3CreateSensorCommandInit(b3PhysicsClientHandle physClient, int bodyUniqueId)
{
PhysicsClient* cl = (PhysicsClient* ) physClient;
b3Assert(cl);
@@ -414,7 +493,7 @@ b3SharedMemoryCommandHandle b3CreateSensorCommandInit(b3PhysicsClientHandle phys
command->m_type = CMD_CREATE_SENSOR;
command->m_updateFlags = 0;
command->m_createSensorArguments.m_numJointSensorChanges = 0;
command->m_createSensorArguments.m_bodyUniqueId = 0;
command->m_createSensorArguments.m_bodyUniqueId = bodyUniqueId;
return (b3SharedMemoryCommandHandle) command;
}
@@ -489,6 +568,33 @@ int b3GetStatusType(b3SharedMemoryStatusHandle statusHandle)
return CMD_INVALID_STATUS;
}
int b3GetStatusBodyIndices(b3SharedMemoryStatusHandle statusHandle, int* bodyIndicesOut, int bodyIndicesCapacity)
{
int numBodies = 0;
const SharedMemoryStatus* status = (const SharedMemoryStatus* ) statusHandle;
b3Assert(status);
if (status)
{
switch (status->m_type)
{
case CMD_SDF_LOADING_COMPLETED:
{
int i,maxBodies;
numBodies = status->m_sdfLoadedArgs.m_numBodies;
maxBodies = btMin(bodyIndicesCapacity, numBodies);
for (i=0;i<maxBodies;i++)
{
bodyIndicesOut[i] = status->m_sdfLoadedArgs.m_bodyUniqueIds[i];
}
break;
}
}
}
return numBodies;
}
int b3GetStatusBodyIndex(b3SharedMemoryStatusHandle statusHandle)
{
const SharedMemoryStatus* status = (const SharedMemoryStatus* ) statusHandle;
@@ -528,6 +634,10 @@ int b3GetStatusActualState(b3SharedMemoryStatusHandle statusHandle,
const double* jointReactionForces[]) {
const SharedMemoryStatus* status = (const SharedMemoryStatus* ) statusHandle;
const SendActualStateArgs &args = status->m_sendActualStateArgs;
btAssert(status->m_type == CMD_ACTUAL_STATE_UPDATE_COMPLETED);
if (status->m_type != CMD_ACTUAL_STATE_UPDATE_COMPLETED)
return false;
if (bodyUniqueId) {
*bodyUniqueId = args.m_bodyUniqueId;
}
@@ -592,10 +702,10 @@ int b3GetNumJoints(b3PhysicsClientHandle physClient, int bodyId)
}
void b3GetJointInfo(b3PhysicsClientHandle physClient, int bodyIndex, int linkIndex, struct b3JointInfo* info)
int b3GetJointInfo(b3PhysicsClientHandle physClient, int bodyIndex, int jointIndex, struct b3JointInfo* info)
{
PhysicsClient* cl = (PhysicsClient* ) physClient;
cl->getJointInfo(bodyIndex, linkIndex,*info);
return cl->getJointInfo(bodyIndex, jointIndex, *info);
}
b3SharedMemoryCommandHandle b3PickBody(b3PhysicsClientHandle physClient, double rayFromWorldX,
@@ -691,6 +801,14 @@ b3SharedMemoryCommandHandle b3InitRequestCameraImage(b3PhysicsClientHandle physC
return (b3SharedMemoryCommandHandle) command;
}
void b3RequestCameraImageSelectRenderer(b3SharedMemoryCommandHandle commandHandle, int renderer)
{
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*) commandHandle;
b3Assert(command);
b3Assert(command->m_type == CMD_REQUEST_CAMERA_IMAGE_DATA);
b3Assert(renderer>(1<<15));
command->m_updateFlags |= renderer;
}
void b3RequestCameraImageSetCameraMatrices(b3SharedMemoryCommandHandle commandHandle, float viewMatrix[16], float projectionMatrix[16])
{
@@ -705,6 +823,131 @@ void b3RequestCameraImageSetCameraMatrices(b3SharedMemoryCommandHandle commandHa
command->m_updateFlags |= REQUEST_PIXEL_ARGS_HAS_CAMERA_MATRICES;
}
void b3RequestCameraImageSetViewMatrix(b3SharedMemoryCommandHandle commandHandle, const float cameraPosition[3], const float cameraTargetPosition[3], const float cameraUp[3])
{
b3Vector3 eye = b3MakeVector3(cameraPosition[0], cameraPosition[1], cameraPosition[2]);
b3Vector3 center = b3MakeVector3(cameraTargetPosition[0], cameraTargetPosition[1], cameraTargetPosition[2]);
b3Vector3 up = b3MakeVector3(cameraUp[0], cameraUp[1], cameraUp[2]);
b3Vector3 f = (center - eye).normalized();
b3Vector3 u = up.normalized();
b3Vector3 s = (f.cross(u)).normalized();
u = s.cross(f);
float viewMatrix[16];
viewMatrix[0*4+0] = s.x;
viewMatrix[1*4+0] = s.y;
viewMatrix[2*4+0] = s.z;
viewMatrix[0*4+1] = u.x;
viewMatrix[1*4+1] = u.y;
viewMatrix[2*4+1] = u.z;
viewMatrix[0*4+2] =-f.x;
viewMatrix[1*4+2] =-f.y;
viewMatrix[2*4+2] =-f.z;
viewMatrix[0*4+3] = 0.f;
viewMatrix[1*4+3] = 0.f;
viewMatrix[2*4+3] = 0.f;
viewMatrix[3*4+0] = -s.dot(eye);
viewMatrix[3*4+1] = -u.dot(eye);
viewMatrix[3*4+2] = f.dot(eye);
viewMatrix[3*4+3] = 1.f;
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*) commandHandle;
b3Assert(command);
b3Assert(command->m_type == CMD_REQUEST_CAMERA_IMAGE_DATA);
for (int i=0;i<16;i++)
{
command->m_requestPixelDataArguments.m_viewMatrix[i] = viewMatrix[i];
}
command->m_updateFlags |= REQUEST_PIXEL_ARGS_HAS_CAMERA_MATRICES;
}
void b3RequestCameraImageSetProjectionMatrix(b3SharedMemoryCommandHandle commandHandle, float left, float right, float bottom, float top, float nearVal, float farVal)
{
float frustum[16];
frustum[0*4+0] = (float(2) * nearVal) / (right - left);
frustum[0*4+1] = float(0);
frustum[0*4+2] = float(0);
frustum[0*4+3] = float(0);
frustum[1*4+0] = float(0);
frustum[1*4+1] = (float(2) * nearVal) / (top - bottom);
frustum[1*4+2] = float(0);
frustum[1*4+3] = float(0);
frustum[2*4+0] = (right + left) / (right - left);
frustum[2*4+1] = (top + bottom) / (top - bottom);
frustum[2*4+2] = -(farVal + nearVal) / (farVal - nearVal);
frustum[2*4+3] = float(-1);
frustum[3*4+0] = float(0);
frustum[3*4+1] = float(0);
frustum[3*4+2] = -(float(2) * farVal * nearVal) / (farVal - nearVal);
frustum[3*4+3] = float(0);
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*) commandHandle;
b3Assert(command);
b3Assert(command->m_type == CMD_REQUEST_CAMERA_IMAGE_DATA);
for (int i=0;i<16;i++)
{
command->m_requestPixelDataArguments.m_projectionMatrix[i] = frustum[i];
}
command->m_updateFlags |= REQUEST_PIXEL_ARGS_HAS_CAMERA_MATRICES;
}
void b3RequestCameraImageSetFOVProjectionMatrix(b3SharedMemoryCommandHandle commandHandle, float fov, float aspect, float nearVal, float farVal)
{
float yScale = 1.0 / tan((3.141592538 / 180.0) * fov / 2);
float xScale = yScale / aspect;
float frustum[16];
frustum[0*4+0] = xScale;
frustum[0*4+1] = float(0);
frustum[0*4+2] = float(0);
frustum[0*4+3] = float(0);
frustum[1*4+0] = float(0);
frustum[1*4+1] = yScale;
frustum[1*4+2] = float(0);
frustum[1*4+3] = float(0);
frustum[2*4+0] = 0;
frustum[2*4+1] = 0;
frustum[2*4+2] = (nearVal + farVal) / (nearVal - farVal);
frustum[2*4+3] = float(-1);
frustum[3*4+0] = float(0);
frustum[3*4+1] = float(0);
frustum[3*4+2] = (float(2) * farVal * nearVal) / (nearVal - farVal);
frustum[3*4+3] = float(0);
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*) commandHandle;
b3Assert(command);
b3Assert(command->m_type == CMD_REQUEST_CAMERA_IMAGE_DATA);
for (int i=0;i<16;i++)
{
command->m_requestPixelDataArguments.m_projectionMatrix[i] = frustum[i];
}
command->m_updateFlags |= REQUEST_PIXEL_ARGS_HAS_CAMERA_MATRICES;
}
void b3RequestCameraImageSetPixelResolution(b3SharedMemoryCommandHandle commandHandle, int width, int height )
{
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*) commandHandle;
b3Assert(command);
b3Assert(command->m_type == CMD_REQUEST_CAMERA_IMAGE_DATA);
command->m_requestPixelDataArguments.m_pixelWidth = width;
command->m_requestPixelDataArguments.m_pixelHeight = height;
command->m_updateFlags |= REQUEST_PIXEL_ARGS_SET_PIXEL_WIDTH_HEIGHT;
}
void b3GetCameraImageData(b3PhysicsClientHandle physClient, struct b3CameraImageData* imageData)
{
PhysicsClient* cl = (PhysicsClient* ) physClient;
@@ -714,3 +957,50 @@ void b3GetCameraImageData(b3PhysicsClientHandle physClient, struct b3CameraImage
}
}
b3SharedMemoryCommandHandle b3ApplyExternalForceCommandInit(b3PhysicsClientHandle physClient)
{
PhysicsClient* cl = (PhysicsClient* ) physClient;
b3Assert(cl);
b3Assert(cl->canSubmitCommand());
struct SharedMemoryCommand* command = cl->getAvailableSharedMemoryCommand();
b3Assert(command);
command->m_type = CMD_APPLY_EXTERNAL_FORCE;
command->m_updateFlags = 0;
command->m_externalForceArguments.m_numForcesAndTorques = 0;
return (b3SharedMemoryCommandHandle) command;
}
void b3ApplyExternalForce(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, int linkId, const double force[3], const double position[3], int flag)
{
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*) commandHandle;
b3Assert(command);
b3Assert(command->m_type == CMD_APPLY_EXTERNAL_FORCE);
int index = command->m_externalForceArguments.m_numForcesAndTorques;
command->m_externalForceArguments.m_bodyUniqueIds[index] = bodyUniqueId;
command->m_externalForceArguments.m_linkIds[index] = linkId;
command->m_externalForceArguments.m_forceFlags[index] = EF_FORCE+flag;
for (int i = 0; i < 3; ++i) {
command->m_externalForceArguments.m_forcesAndTorques[index+i] = force[i];
command->m_externalForceArguments.m_positions[index+i] = position[i];
}
command->m_externalForceArguments.m_numForcesAndTorques++;
}
void b3ApplyExternalTorque(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, int linkId, const double torque[3], int flag)
{
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*) commandHandle;
b3Assert(command);
b3Assert(command->m_type == CMD_APPLY_EXTERNAL_FORCE);
int index = command->m_externalForceArguments.m_numForcesAndTorques;
command->m_externalForceArguments.m_bodyUniqueIds[index] = bodyUniqueId;
command->m_externalForceArguments.m_linkIds[index] = linkId;
command->m_externalForceArguments.m_forceFlags[index] = EF_TORQUE+flag;
for (int i = 0; i < 3; ++i) {
command->m_externalForceArguments.m_forcesAndTorques[index+i] = torque[i];
}
command->m_externalForceArguments.m_numForcesAndTorques++;
}

View File

@@ -40,6 +40,8 @@ b3SharedMemoryStatusHandle b3ProcessServerStatus(b3PhysicsClientHandle physClien
/// Get the physics server return status type. See EnumSharedMemoryServerStatus in SharedMemoryPublic.h for error codes.
int b3GetStatusType(b3SharedMemoryStatusHandle statusHandle);
int b3GetStatusBodyIndices(b3SharedMemoryStatusHandle statusHandle, int* bodyIndicesOut, int bodyIndicesCapacity);
int b3GetStatusBodyIndex(b3SharedMemoryStatusHandle statusHandle);
int b3GetStatusActualState(b3SharedMemoryStatusHandle statusHandle,
@@ -54,8 +56,8 @@ int b3GetStatusActualState(b3SharedMemoryStatusHandle statusHandle,
///give a unique body index (after loading the body) return the number of joints.
int b3GetNumJoints(b3PhysicsClientHandle physClient, int bodyIndex);
///given a body and link index, return the joint information. See b3JointInfo in SharedMemoryPublic.h
void b3GetJointInfo(b3PhysicsClientHandle physClient, int bodyIndex, int linkIndex, struct b3JointInfo* info);
///given a body and joint index, return the joint information. See b3JointInfo in SharedMemoryPublic.h
int b3GetJointInfo(b3PhysicsClientHandle physClient, int bodyIndex, int jointIndex, struct b3JointInfo* info);
///Request debug lines for debug visualization. The flags in debugMode are the same as used in Bullet
///See btIDebugDraw::DebugDrawModes in Bullet/src/LinearMath/btIDebugDraw.h
@@ -68,12 +70,18 @@ void b3GetDebugLines(b3PhysicsClientHandle physClient, struct b3DebugLines* l
///request an image from a simulated camera, using a software renderer.
b3SharedMemoryCommandHandle b3InitRequestCameraImage(b3PhysicsClientHandle physClient);
void b3RequestCameraImageSetCameraMatrices(b3SharedMemoryCommandHandle command, float viewMatrix[16], float projectionMatrix[16]);
void b3RequestCameraImageSetViewMatrix(b3SharedMemoryCommandHandle command, const float cameraPosition[3], const float cameraTargetPosition[3], const float cameraUp[3]);
void b3RequestCameraImageSetProjectionMatrix(b3SharedMemoryCommandHandle command, float left, float right, float bottom, float top, float nearVal, float farVal);
void b3RequestCameraImageSetFOVProjectionMatrix(b3SharedMemoryCommandHandle command, float fov, float aspect, float nearVal, float farVal);
void b3RequestCameraImageSetPixelResolution(b3SharedMemoryCommandHandle command, int width, int height );
void b3RequestCameraImageSelectRenderer(b3SharedMemoryCommandHandle commandHandle, int renderer);
void b3GetCameraImageData(b3PhysicsClientHandle physClient, struct b3CameraImageData* imageData);
b3SharedMemoryCommandHandle b3InitPhysicsParamCommand(b3PhysicsClientHandle physClient);
int b3PhysicsParamSetGravity(b3SharedMemoryCommandHandle commandHandle, double gravx,double gravy, double gravz);
int b3PhysicsParamSetTimeStep(b3SharedMemoryCommandHandle commandHandle, double timeStep);
int b3PhysicsParamSetRealTimeSimulation(b3SharedMemoryCommandHandle commandHandle, int enableRealTimeSimulation);
b3SharedMemoryCommandHandle b3InitStepSimulationCommand(b3PhysicsClientHandle physClient);
@@ -88,14 +96,22 @@ int b3LoadUrdfCommandSetStartOrientation(b3SharedMemoryCommandHandle commandHand
int b3LoadUrdfCommandSetUseMultiBody(b3SharedMemoryCommandHandle commandHandle, int useMultiBody);
int b3LoadUrdfCommandSetUseFixedBase(b3SharedMemoryCommandHandle commandHandle, int useFixedBase);
///Set joint control variables such as desired position/angle, desired velocity,
///applied joint forces, dependent on the control mode (CONTROL_MODE_VELOCITY or CONTROL_MODE_TORQUE)
b3SharedMemoryCommandHandle b3LoadSdfCommandInit(b3PhysicsClientHandle physClient, const char* sdfFileName);
///The b3JointControlCommandInit method is obsolete, use b3JointControlCommandInit2 instead
b3SharedMemoryCommandHandle b3JointControlCommandInit(b3PhysicsClientHandle physClient, int controlMode);
///Set joint motor control variables such as desired position/angle, desired velocity,
///applied joint forces, dependent on the control mode (CONTROL_MODE_VELOCITY or CONTROL_MODE_TORQUE)
b3SharedMemoryCommandHandle b3JointControlCommandInit2(b3PhysicsClientHandle physClient, int bodyUniqueId, int controlMode);
///Only use when controlMode is CONTROL_MODE_POSITION_VELOCITY_PD
int b3JointControlSetDesiredPosition(b3SharedMemoryCommandHandle commandHandle, int qIndex, double value);
int b3JointControlSetKp(b3SharedMemoryCommandHandle commandHandle, int dofIndex, double value);
int b3JointControlSetKd(b3SharedMemoryCommandHandle commandHandle, int dofIndex, double value);
//Only use when controlMode is CONTROL_MODE_VELOCITY
///Only use when controlMode is CONTROL_MODE_VELOCITY
int b3JointControlSetDesiredVelocity(b3SharedMemoryCommandHandle commandHandle, int dofIndex, double value); /* find a better name for dof/q/u indices, point to b3JointInfo */
int b3JointControlSetMaximumForce(b3SharedMemoryCommandHandle commandHandle, int dofIndex, double value);
///Only use if when controlMode is CONTROL_MODE_TORQUE,
@@ -127,7 +143,7 @@ int b3CreatePoseCommandSetJointPosition(b3PhysicsClientHandle physClient, b3Shar
///We are currently not reading the sensor information from the URDF file, and programmatically assign sensors.
///This is rather inconsistent, to mix programmatical creation with loading from file.
b3SharedMemoryCommandHandle b3CreateSensorCommandInit(b3PhysicsClientHandle physClient);
b3SharedMemoryCommandHandle b3CreateSensorCommandInit(b3PhysicsClientHandle physClient, int bodyUniqueId);
int b3CreateSensorEnable6DofJointForceTorqueSensor(b3SharedMemoryCommandHandle commandHandle, int jointIndex, int enable);
///b3CreateSensorEnableIMUForLink is not implemented yet.
///For now, if the IMU is located in the root link, use the root world transform to mimic an IMU.
@@ -146,6 +162,11 @@ b3SharedMemoryCommandHandle b3MovePickedBody(b3PhysicsClientHandle physClient, d
double rayToWorldZ);
b3SharedMemoryCommandHandle b3RemovePickingConstraint(b3PhysicsClientHandle physClient);
/// Apply external force at the body (or link) center of mass, in world space/Cartesian coordinates.
b3SharedMemoryCommandHandle b3ApplyExternalForceCommandInit(b3PhysicsClientHandle physClient);
void b3ApplyExternalForce(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, int linkId, const double force[3], const double position[3], int flags);
void b3ApplyExternalTorque(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, int linkId, const double torque[3], int flags);
#ifdef __cplusplus
}
#endif

View File

@@ -21,8 +21,8 @@ struct MyMotorInfo2
int m_qIndex;
};
int camVisualizerWidth = 640;//1024/3;
int camVisualizerHeight = 480;//768/3;
int camVisualizerWidth = 320;//1024/3;
int camVisualizerHeight = 240;//768/3;
#define MAX_NUM_MOTORS 128
@@ -37,6 +37,9 @@ protected:
bool m_wantsTermination;
btAlignedObjectArray<int> m_userCommandRequests;
btAlignedObjectArray<int> m_bodyUniqueIds;
int m_sharedMemoryKey;
int m_selectedBody;
int m_prevSelectedBody;
@@ -66,7 +69,8 @@ protected:
{
if (m_guiHelper && m_guiHelper->getParameterInterface())
{
int bodyIndex = comboIndex;
int itemIndex = int(atoi(name));
int bodyIndex = m_bodyUniqueIds[itemIndex];
if (m_selectedBody != bodyIndex)
{
m_selectedBody = bodyIndex;
@@ -77,10 +81,10 @@ protected:
virtual void resetCamera()
{
float dist = 5;
float pitch = 50;
float yaw = 35;
float targetPos[3]={0,0,0};//-3,2.8,-2.5};
float dist = 4;
float pitch = 193;
float yaw = 25;
float targetPos[3]={0,0,0.5};//-3,2.8,-2.5};
m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
}
@@ -154,20 +158,23 @@ protected:
void prepareControlCommand(b3SharedMemoryCommandHandle commandHandle)
{
for (int i=0;i<m_numMotors;i++)
{
// btScalar targetVel = m_motorTargetVelocities[i].m_velTarget;
// int uIndex = m_motorTargetVelocities[i].m_uIndex;
// b3JointControlSetDesiredVelocity(commandHandle, uIndex,targetVel);
btScalar targetPos = m_motorTargetPositions[i].m_posTarget;
int qIndex = m_motorTargetPositions[i].m_qIndex;
int uIndex = m_motorTargetPositions[i].m_uIndex;
b3JointControlSetDesiredPosition(commandHandle, qIndex, targetPos);
b3JointControlSetKp(commandHandle, uIndex, 0.1);
b3JointControlSetKd(commandHandle, uIndex, 0.0);
static int serial=0;
serial++;
// b3Printf("# motors = %d, cmd[%d] qIndex = %d, uIndex = %d, targetPos = %f", m_numMotors, serial, qIndex,uIndex,targetPos);
b3JointControlSetMaximumForce(commandHandle,uIndex,1000);
b3JointControlSetDesiredPosition(commandHandle, qIndex, targetPos);
b3JointControlSetDesiredVelocity(commandHandle,uIndex,0);
b3JointControlSetKp(commandHandle, qIndex, 0.2);
b3JointControlSetKd(commandHandle, uIndex, 1.);
b3JointControlSetMaximumForce(commandHandle,uIndex,5000);
}
}
virtual void physicsDebugDraw(int debugFlags)
@@ -191,7 +198,7 @@ protected:
void MyComboBoxCallback (int combobox, const char* item, void* userPointer)
{
b3Printf("Item selected %s", item);
//b3Printf("Item selected %s", item);
PhysicsClientExample* cl = (PhysicsClientExample*) userPointer;
b3Assert(cl);
@@ -227,18 +234,22 @@ void PhysicsClientExample::prepareAndSubmitCommand(int commandId)
{
case CMD_LOAD_URDF:
{
b3SharedMemoryCommandHandle commandHandle = b3LoadUrdfCommandInit(m_physicsClientHandle, "kuka_iiwa/model.urdf");
//setting the initial position, orientation and other arguments are optional
double startPosX = 0;
static double startPosY = 0;
static double startPosY = 1;
double startPosZ = 0;
b3LoadUrdfCommandSetStartPosition(commandHandle, startPosX,startPosY,startPosZ);
startPosY += 2.f;
// ret = b3LoadUrdfCommandSetUseFixedBase(commandHandle, 1);
b3SubmitClientCommand(m_physicsClientHandle, commandHandle);
break;
}
case CMD_LOAD_SDF:
{
b3SharedMemoryCommandHandle commandHandle = b3LoadSdfCommandInit(m_physicsClientHandle, "kuka_iiwa/model.sdf");
b3SubmitClientCommand(m_physicsClientHandle, commandHandle);
break;
}
case CMD_REQUEST_CAMERA_IMAGE_DATA:
@@ -246,13 +257,16 @@ void PhysicsClientExample::prepareAndSubmitCommand(int commandId)
///request an image from a simulated camera, using a software renderer.
b3SharedMemoryCommandHandle commandHandle = b3InitRequestCameraImage(m_physicsClientHandle);
//b3RequestCameraImageSelectRenderer(commandHandle,ER_BULLET_HARDWARE_OPENGL);
float viewMatrix[16];
float projectionMatrix[16];
this->m_guiHelper->getRenderInterface()->getActiveCamera()->getCameraProjectionMatrix(projectionMatrix);
this->m_guiHelper->getRenderInterface()->getActiveCamera()->getCameraViewMatrix(viewMatrix);
m_guiHelper->getRenderInterface()->getActiveCamera()->getCameraProjectionMatrix(projectionMatrix);
m_guiHelper->getRenderInterface()->getActiveCamera()->getCameraViewMatrix(viewMatrix);
b3RequestCameraImageSetCameraMatrices(commandHandle, viewMatrix,projectionMatrix);
b3SubmitClientCommand(m_physicsClientHandle, commandHandle);
b3RequestCameraImageSetPixelResolution(commandHandle, camVisualizerWidth,camVisualizerHeight);
b3SubmitClientCommand(m_physicsClientHandle, commandHandle);
break;
}
case CMD_CREATE_BOX_COLLISION_SHAPE:
@@ -363,11 +377,18 @@ void PhysicsClientExample::prepareAndSubmitCommand(int commandId)
}
case CMD_SEND_DESIRED_STATE:
{
// b3SharedMemoryCommandHandle command = b3JointControlCommandInit( m_physicsClientHandle, CONTROL_MODE_VELOCITY);
b3SharedMemoryCommandHandle command = b3JointControlCommandInit( m_physicsClientHandle, CONTROL_MODE_POSITION_VELOCITY_PD);
if (m_selectedBody>=0)
{
// b3SharedMemoryCommandHandle command = b3JointControlCommandInit( m_physicsClientHandle, m_selectedBody, CONTROL_MODE_VELOCITY);
b3SharedMemoryCommandHandle command = b3JointControlCommandInit2( m_physicsClientHandle, m_selectedBody, CONTROL_MODE_POSITION_VELOCITY_PD);
// b3Printf("prepare control command for body %d", m_selectedBody);
prepareControlCommand(command);
b3SubmitClientCommand(m_physicsClientHandle, command);
break;
}
break;
}
case CMD_RESET_SIMULATION:
{
@@ -430,6 +451,11 @@ PhysicsClientExample::~PhysicsClientExample()
bool deInitializeSharedMemory = true;
m_physicsServer.disconnectSharedMemory(deInitializeSharedMemory);
}
if (m_canvas && (m_canvasIndex>=0))
{
m_canvas->destroyCanvas(m_canvasIndex);
}
b3Printf("~PhysicsClientExample\n");
}
@@ -450,6 +476,7 @@ void PhysicsClientExample::createButtons()
m_guiHelper->getParameterInterface()->removeAllParameters();
createButton("Load URDF",CMD_LOAD_URDF, isTrigger);
createButton("Load SDF",CMD_LOAD_SDF, isTrigger);
createButton("Get Camera Image",CMD_REQUEST_CAMERA_IMAGE_DATA,isTrigger);
createButton("Step Sim",CMD_STEP_FORWARD_SIMULATION, isTrigger);
createButton("Send Bullet Stream",CMD_SEND_BULLET_DATA_STREAM, isTrigger);
@@ -459,14 +486,41 @@ void PhysicsClientExample::createButtons()
}
createButton("Send Desired State",CMD_SEND_DESIRED_STATE, isTrigger);
createButton("Create Box Collider",CMD_CREATE_BOX_COLLISION_SHAPE,isTrigger);
createButton("Create Cylinder Body",CMD_CREATE_RIGID_BODY,isTrigger);
createButton("Create Cylinder Body",CMD_CREATE_RIGID_BODY,isTrigger);
createButton("Reset Simulation",CMD_RESET_SIMULATION,isTrigger);
createButton("Initialize Pose",CMD_INIT_POSE, isTrigger);
createButton("Initialize Pose",CMD_INIT_POSE, isTrigger);
createButton("Set gravity", CMD_SEND_PHYSICS_SIMULATION_PARAMETERS, isTrigger);
if (m_bodyUniqueIds.size())
{
if (m_selectedBody<0)
m_selectedBody = 0;
ComboBoxParams comboParams;
comboParams.m_comboboxId = 0;
comboParams.m_numItems = m_bodyUniqueIds.size();
comboParams.m_startItem = m_selectedBody;
comboParams.m_callback = MyComboBoxCallback;
comboParams.m_userPointer = this;
//todo: get the real object name
const char** blarray = new const char*[m_bodyUniqueIds.size()];
for (int i=0;i<m_bodyUniqueIds.size();i++)
{
char* bla = new char[16];
sprintf(bla,"%d", i);
blarray[i] = bla;
comboParams.m_items=blarray;//{&bla};
}
m_guiHelper->getParameterInterface()->registerComboBox(comboParams);
}
if (m_physicsClientHandle && m_selectedBody>=0)
{
m_numMotors = 0;
int numJoints = b3GetNumJoints(m_physicsClientHandle,m_selectedBody);
for (int i=0;i<numJoints;i++)
{
@@ -527,7 +581,6 @@ void PhysicsClientExample::initPhysics()
m_selectedBody = -1;
m_prevSelectedBody = -1;
if (m_options == eCLIENTEXAMPLE_SERVER)
{
m_canvas = m_guiHelper->get2dCanvasInterface();
if (m_canvas)
@@ -557,13 +610,22 @@ void PhysicsClientExample::initPhysics()
}
m_isOptionalServerConnected = m_physicsServer.connectSharedMemory( m_guiHelper);
}
m_physicsClientHandle = b3ConnectSharedMemory(m_sharedMemoryKey);
//m_physicsClientHandle = b3ConnectPhysicsLoopback(SHARED_MEMORY_KEY);
//m_physicsClientHandle = b3ConnectPhysicsDirect();
if (m_options == eCLIENTEXAMPLE_SERVER)
{
m_isOptionalServerConnected = m_physicsServer.connectSharedMemory( m_guiHelper);
}
if (m_options == eCLIENTEXAMPLE_DIRECT)
{
m_physicsClientHandle = b3ConnectPhysicsDirect();
} else
{
m_physicsClientHandle = b3ConnectSharedMemory(m_sharedMemoryKey);
//m_physicsClientHandle = b3ConnectPhysicsLoopback(SHARED_MEMORY_KEY);
}
if (!b3CanSubmitCommand(m_physicsClientHandle))
{
b3Warning("Cannot connect to physics client");
@@ -603,48 +665,77 @@ void PhysicsClientExample::stepSimulation(float deltaTime)
}
if (statusType ==CMD_CAMERA_IMAGE_COMPLETED)
{
static int counter=0;
char msg[1024];
sprintf(msg,"Camera image %d OK\n",counter++);
// static int counter=0;
// char msg[1024];
// sprintf(msg,"Camera image %d OK\n",counter++);
b3CameraImageData imageData;
b3GetCameraImageData(m_physicsClientHandle,&imageData);
if (m_canvas && m_canvasIndex >=0)
{
for (int i=0;i<imageData.m_pixelWidth;i++)
for (int i=0;i<camVisualizerWidth;i++)
{
for (int j=0;j<imageData.m_pixelHeight;j++)
for (int j=0;j<camVisualizerHeight;j++)
{
int xIndex = int(float(i)*(float(camVisualizerWidth)/float(imageData.m_pixelWidth)));
int yIndex = int(float(j)*(float(camVisualizerHeight)/float(imageData.m_pixelHeight)));
int xIndex = int(float(i)*(float(imageData.m_pixelWidth)/float(camVisualizerWidth)));
int yIndex = int(float(j)*(float(imageData.m_pixelHeight)/float(camVisualizerHeight)));
btClamp(yIndex,0,imageData.m_pixelHeight);
btClamp(xIndex,0,imageData.m_pixelWidth);
int bytesPerPixel = 4;
int bytesPerPixel = 4; //RGBA
int pixelIndex = (i+j*imageData.m_pixelWidth)*bytesPerPixel;
m_canvas->setPixel(m_canvasIndex,xIndex,camVisualizerHeight-1-yIndex,
int pixelIndex = (xIndex+yIndex*imageData.m_pixelWidth)*bytesPerPixel;
m_canvas->setPixel(m_canvasIndex,i,j,
imageData.m_rgbColorData[pixelIndex],
imageData.m_rgbColorData[pixelIndex+1],
imageData.m_rgbColorData[pixelIndex+2],
255);
// imageData.m_rgbColorData[pixelIndex+3]);
255); //alpha set to 255
}
}
m_canvas->refreshImageData(m_canvasIndex);
}
b3Printf(msg);
// b3Printf(msg);
}
if (statusType == CMD_CAMERA_IMAGE_FAILED)
{
b3Printf("Camera image FAILED\n");
b3Warning("Camera image FAILED\n");
}
if (statusType == CMD_URDF_LOADING_COMPLETED)
if (statusType == CMD_SDF_LOADING_COMPLETED)
{
int bodyIndex = b3GetStatusBodyIndex(status);
if (bodyIndex>=0)
int bodyIndicesOut[1024];
int bodyCapacity = 1024;
int numBodies = b3GetStatusBodyIndices(status, bodyIndicesOut, bodyCapacity);
if (numBodies > bodyCapacity)
{
b3Warning("loadSDF number of bodies (%d) exceeds the internal body capacity (%d)",numBodies, bodyCapacity);
} else
{
for (int i=0;i<numBodies;i++)
{
int bodyUniqueId = bodyIndicesOut[i];
m_bodyUniqueIds.push_back(bodyUniqueId);
int numJoints = b3GetNumJoints(m_physicsClientHandle,bodyUniqueId);
if (numJoints>0)
{
m_selectedBody = bodyUniqueId;
}
/* int numJoints = b3GetNumJoints(m_physicsClientHandle,bodyUniqueId);
b3Printf("numJoints = %d", numJoints);
for (int i=0;i<numJoints;i++)
{
b3JointInfo info;
b3GetJointInfo(m_physicsClientHandle,bodyUniqueId,i,&info);
b3Printf("Joint %s at q-index %d and u-index %d\n",info.m_jointName,info.m_qIndex,info.m_uIndex);
}
*/
}
}
//int numJoints = b3GetNumJoints(m_physicsClientHandle,bodyIndex);
//int bodyIndex = b3GetStatusBodyIndex(status);
/*if (bodyIndex>=0)
{
int numJoints = b3GetNumJoints(m_physicsClientHandle,bodyIndex);
@@ -653,7 +744,6 @@ void PhysicsClientExample::stepSimulation(float deltaTime)
b3JointInfo info;
b3GetJointInfo(m_physicsClientHandle,bodyIndex,i,&info);
b3Printf("Joint %s at q-index %d and u-index %d\n",info.m_jointName,info.m_qIndex,info.m_uIndex);
}
ComboBoxParams comboParams;
comboParams.m_comboboxId = bodyIndex;
@@ -667,12 +757,29 @@ void PhysicsClientExample::stepSimulation(float deltaTime)
comboParams.m_items=blarray;//{&bla};
m_guiHelper->getParameterInterface()->registerComboBox(comboParams);
}
*/
}
if (statusType == CMD_URDF_LOADING_COMPLETED)
{
int bodyIndex = b3GetStatusBodyIndex(status);
if (bodyIndex>=0)
{
m_bodyUniqueIds.push_back(bodyIndex);
m_selectedBody = bodyIndex;
int numJoints = b3GetNumJoints(m_physicsClientHandle,bodyIndex);
for (int i=0;i<numJoints;i++)
{
b3JointInfo info;
b3GetJointInfo(m_physicsClientHandle,bodyIndex,i,&info);
b3Printf("Joint %s at q-index %d and u-index %d\n",info.m_jointName,info.m_qIndex,info.m_uIndex);
}
}
}
}
}
if (b3CanSubmitCommand(m_physicsClientHandle))
@@ -695,6 +802,7 @@ void PhysicsClientExample::stepSimulation(float deltaTime)
{
m_selectedBody = -1;
m_numMotors=0;
m_bodyUniqueIds.clear();
createButtons();
b3SharedMemoryCommandHandle commandHandle = b3InitResetSimulationCommand(m_physicsClientHandle);
if (m_options == eCLIENTEXAMPLE_SERVER)
@@ -707,8 +815,8 @@ void PhysicsClientExample::stepSimulation(float deltaTime)
bool hasStatus = (status != 0);
if (hasStatus)
{
int statusType = b3GetStatusType(status);
b3Printf("Status after reset: %d",statusType);
//int statusType = b3GetStatusType(status);
//b3Printf("Status after reset: %d",statusType);
}
}
} else
@@ -725,13 +833,12 @@ void PhysicsClientExample::stepSimulation(float deltaTime)
if (m_numMotors)
{
enqueueCommand(CMD_SEND_DESIRED_STATE);
enqueueCommand(CMD_STEP_FORWARD_SIMULATION);
if (m_options != eCLIENTEXAMPLE_SERVER)
{
enqueueCommand(CMD_REQUEST_DEBUG_LINES);
}
//enqueueCommand(CMD_REQUEST_ACTUAL_STATE);
}
enqueueCommand(CMD_STEP_FORWARD_SIMULATION);
if (m_options != eCLIENTEXAMPLE_SERVER)
{
//enqueueCommand(CMD_REQUEST_DEBUG_LINES);
}
}
}
@@ -750,3 +857,4 @@ class CommonExampleInterface* PhysicsClientCreateFunc(struct CommonExampleOpt
}
return example;
}

View File

@@ -4,7 +4,7 @@
enum ClientExampleOptions
{
eCLIENTEXAMPLE_LOOPBACK=1,
eCLIENTEAXMPLE_DIRECT=2,
eCLIENTEXAMPLE_DIRECT=2,
eCLIENTEXAMPLE_SERVER=3,
};

View File

@@ -37,10 +37,13 @@ struct PhysicsClientSharedMemoryInternalData {
btAlignedObjectArray<unsigned char> m_cachedCameraPixelsRGBA;
btAlignedObjectArray<float> m_cachedCameraDepthBuffer;
btAlignedObjectArray<int> m_bodyIdsRequestInfo;
SharedMemoryStatus m_tempBackupServerStatus;
SharedMemoryStatus m_lastServerStatus;
int m_counter;
bool m_serverLoadUrdfOK;
bool m_isConnected;
bool m_waitingForServer;
bool m_hasLastServerStatus;
@@ -54,7 +57,6 @@ struct PhysicsClientSharedMemoryInternalData {
m_counter(0),
m_cachedCameraPixelsWidth(0),
m_cachedCameraPixelsHeight(0),
m_serverLoadUrdfOK(false),
m_isConnected(false),
m_waitingForServer(false),
m_hasLastServerStatus(false),
@@ -83,15 +85,16 @@ int PhysicsClientSharedMemory::getNumJoints(int bodyIndex) const
}
void PhysicsClientSharedMemory::getJointInfo(int bodyIndex, int jointIndex, b3JointInfo& info) const
bool PhysicsClientSharedMemory::getJointInfo(int bodyIndex, int jointIndex, b3JointInfo& info) const
{
BodyJointInfoCache** bodyJointsPtr = m_data->m_bodyJointMap[bodyIndex];
if (bodyJointsPtr && *bodyJointsPtr)
{
BodyJointInfoCache* bodyJoints = *bodyJointsPtr;
info = bodyJoints->m_jointInfo[jointIndex];
return true;
}
return false;
}
PhysicsClientSharedMemory::PhysicsClientSharedMemory()
@@ -168,6 +171,48 @@ bool PhysicsClientSharedMemory::connect() {
return true;
}
///todo(erwincoumans) refactor this: merge with PhysicsDirect::processBodyJointInfo
void PhysicsClientSharedMemory::processBodyJointInfo(int bodyUniqueId, const SharedMemoryStatus& serverCmd)
{
bParse::btBulletFile bf(
&this->m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor[0],
serverCmd.m_dataStreamArguments.m_streamChunkLength);
bf.setFileDNAisMemoryDNA();
bf.parse(false);
BodyJointInfoCache* bodyJoints = new BodyJointInfoCache;
m_data->m_bodyJointMap.insert(bodyUniqueId,bodyJoints);
for (int i = 0; i < bf.m_multiBodies.size(); i++)
{
int flag = bf.getFlags();
if ((flag & bParse::FD_DOUBLE_PRECISION) != 0)
{
Bullet::btMultiBodyDoubleData* mb =
(Bullet::btMultiBodyDoubleData*)bf.m_multiBodies[i];
addJointInfoFromMultiBodyData(mb,bodyJoints, m_data->m_verboseOutput);
} else
{
Bullet::btMultiBodyFloatData* mb =
(Bullet::btMultiBodyFloatData*)bf.m_multiBodies[i];
addJointInfoFromMultiBodyData(mb,bodyJoints, m_data->m_verboseOutput);
}
}
if (bf.ok()) {
if (m_data->m_verboseOutput)
{
b3Printf("Received robot description ok!\n");
}
} else
{
b3Warning("Robot description not received");
}
}
const SharedMemoryStatus* PhysicsClientSharedMemory::processServerStatus() {
SharedMemoryStatus* stat = 0;
@@ -204,8 +249,16 @@ const SharedMemoryStatus* PhysicsClientSharedMemory::processServerStatus() {
}
break;
}
case CMD_SDF_LOADING_COMPLETED: {
if (m_data->m_verboseOutput) {
b3Printf("Server loading the SDF OK\n");
}
break;
}
case CMD_URDF_LOADING_COMPLETED: {
m_data->m_serverLoadUrdfOK = true;
if (m_data->m_verboseOutput) {
b3Printf("Server loading the URDF OK\n");
}
@@ -265,7 +318,25 @@ const SharedMemoryStatus* PhysicsClientSharedMemory::processServerStatus() {
if (m_data->m_verboseOutput) {
b3Printf("Server failed loading the URDF...\n");
}
m_data->m_serverLoadUrdfOK = false;
break;
}
case CMD_BODY_INFO_COMPLETED:
{
if (m_data->m_verboseOutput) {
b3Printf("Received body info\n");
}
int bodyUniqueId = serverCmd.m_dataStreamArguments.m_bodyUniqueId;
processBodyJointInfo(bodyUniqueId, serverCmd);
break;
}
case CMD_SDF_LOADING_FAILED: {
if (m_data->m_verboseOutput) {
b3Printf("Server failed loading the SDF...\n");
}
break;
}
@@ -448,8 +519,15 @@ const SharedMemoryStatus* PhysicsClientSharedMemory::processServerStatus() {
unsigned char* rgbaPixelsReceived =
(unsigned char*)&m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor[0];
printf("pixel = %d\n", rgbaPixelsReceived[0]);
// printf("pixel = %d\n", rgbaPixelsReceived[0]);
float* depthBuffer = (float*)&(m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor[serverCmd.m_sendPixelDataArguments.m_numPixelsCopied*4]);
for (int i=0;i<serverCmd.m_sendPixelDataArguments.m_numPixelsCopied;i++)
{
m_data->m_cachedCameraDepthBuffer[i + serverCmd.m_sendPixelDataArguments.m_startingPixelIndex] = depthBuffer[i];
}
for (int i=0;i<serverCmd.m_sendPixelDataArguments.m_numPixelsCopied*numBytesPerPixel;i++)
{
m_data->m_cachedCameraPixelsRGBA[i + serverCmd.m_sendPixelDataArguments.m_startingPixelIndex*numBytesPerPixel]
@@ -461,7 +539,7 @@ const SharedMemoryStatus* PhysicsClientSharedMemory::processServerStatus() {
case CMD_CAMERA_IMAGE_FAILED:
{
b3Printf("Camera image FAILED\n");
b3Warning("Camera image FAILED\n");
break;
}
@@ -483,6 +561,50 @@ const SharedMemoryStatus* PhysicsClientSharedMemory::processServerStatus() {
m_data->m_waitingForServer = true;
}
if (serverCmd.m_type == CMD_SDF_LOADING_COMPLETED)
{
int numBodies = serverCmd.m_sdfLoadedArgs.m_numBodies;
if (numBodies>0)
{
m_data->m_tempBackupServerStatus = m_data->m_lastServerStatus;
for (int i=0;i<numBodies;i++)
{
m_data->m_bodyIdsRequestInfo.push_back(serverCmd.m_sdfLoadedArgs.m_bodyUniqueIds[i]);
}
int bodyId = m_data->m_bodyIdsRequestInfo[m_data->m_bodyIdsRequestInfo.size()-1];
m_data->m_bodyIdsRequestInfo.pop_back();
SharedMemoryCommand& command = m_data->m_testBlock1->m_clientCommands[0];
//now transfer the information of the individual objects etc.
command.m_type = CMD_REQUEST_BODY_INFO;
command.m_sdfRequestInfoArgs.m_bodyUniqueId = bodyId;
submitClientCommand(command);
return 0;
}
}
if (serverCmd.m_type == CMD_BODY_INFO_COMPLETED)
{
//are there any bodies left to be processed?
if (m_data->m_bodyIdsRequestInfo.size())
{
int bodyId = m_data->m_bodyIdsRequestInfo[m_data->m_bodyIdsRequestInfo.size()-1];
m_data->m_bodyIdsRequestInfo.pop_back();
SharedMemoryCommand& command = m_data->m_testBlock1->m_clientCommands[0];
//now transfer the information of the individual objects etc.
command.m_type = CMD_REQUEST_BODY_INFO;
command.m_sdfRequestInfoArgs.m_bodyUniqueId = bodyId;
submitClientCommand(command);
return 0;
} else
{
m_data->m_lastServerStatus = m_data->m_tempBackupServerStatus;
}
}
if (serverCmd.m_type == CMD_CAMERA_IMAGE_COMPLETED)
{
SharedMemoryCommand& command = m_data->m_testBlock1->m_clientCommands[0];
@@ -537,6 +659,8 @@ bool PhysicsClientSharedMemory::canSubmitCommand() const {
}
struct SharedMemoryCommand* PhysicsClientSharedMemory::getAvailableSharedMemoryCommand() {
static int sequence = 0;
m_data->m_testBlock1->m_clientCommands[0].m_sequenceNumber = sequence++;
return &m_data->m_testBlock1->m_clientCommands[0];
}

View File

@@ -11,7 +11,9 @@ class PhysicsClientSharedMemory : public PhysicsClient {
protected:
virtual void setSharedMemoryInterface(class SharedMemoryInterface* sharedMem);
void processBodyJointInfo(int bodyUniqueId, const struct SharedMemoryStatus& serverCmd);
public:
PhysicsClientSharedMemory();
virtual ~PhysicsClientSharedMemory();
@@ -34,7 +36,7 @@ public:
virtual int getNumJoints(int bodyIndex) const;
virtual void getJointInfo(int bodyIndex, int jointIndex, struct b3JointInfo& info) const;
virtual bool getJointInfo(int bodyIndex, int jointIndex, struct b3JointInfo& info) const;
virtual void setSharedMemoryKey(int key);

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