Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Benjamin Ellenberger
2016-06-04 11:36:43 +02:00
87 changed files with 10795 additions and 873 deletions

View File

@@ -12,6 +12,7 @@
#include "../Importers/ImportURDFDemo/MyMultiBodyCreator.h"
#include "../Importers/ImportURDFDemo/URDF2Bullet.h"
/// Create a btMultiBody model from URDF.
/// This is adapted from Bullet URDF loader example
class MyBtMultiBodyFromURDF {
@@ -44,7 +45,8 @@ public:
void init() {
this->createEmptyDynamicsWorld();
m_dynamicsWorld->setGravity(m_gravity);
BulletURDFImporter urdf_importer(&m_nogfx);
BulletURDFImporter urdf_importer(&m_nogfx, 0);
URDFImporterInterface &u2b(urdf_importer);
bool loadOk = u2b.loadURDF(m_filename.c_str(), m_base_fixed);

View File

@@ -105,6 +105,17 @@
description = "Do not build bullet3 libs"
}
newoption
{
trigger = "double",
description = "Double precision version of Bullet"
}
if _OPTIONS["double"] then
defines {"BT_USE_DOUBLE_PRECISION"}
end
configurations {"Release", "Debug"}
configuration "Release"
flags { "Optimize", "EnableSSE2","StaticRuntime", "NoMinimalRebuild", "FloatFast"}
@@ -194,6 +205,7 @@
include "../examples/HelloWorld"
include "../examples/BasicDemo"
include "../examples/InverseDynamics"
include "../examples/ExtendedTutorials"
include "../examples/SharedMemory"
include "../examples/MultiThreading"

View File

@@ -51,18 +51,18 @@ eval '$mypremake --file=stringifyKernel.lua --kernelfile="../src/Bullet3OpenCL/
eval '$mypremake --file=stringifyKernel.lua --kernelfile="../src/Bullet3OpenCL/Raycast/kernels/rayCastKernels.cl" --headerfile="../src/Bullet3OpenCL/Raycast/kernels/rayCastKernels.h" --stringname="rayCastKernelCL" stringify'
eval '$mypremake --file=stringifyKernel.lua --kernelfile="../btgui/OpenGLWindow/Shaders/instancingVS.glsl" --headerfile="../btgui/OpenGLWindow/Shaders/instancingVS.h" --stringname="instancingVertexShader" stringify'
eval '$mypremake --file=stringifyKernel.lua --kernelfile="../btgui/OpenGLWindow/Shaders/instancingPS.glsl" --headerfile="../btgui/OpenGLWindow/Shaders/instancingPS.h" --stringname="instancingFragmentShader" stringify'
eval '$mypremake --file=stringifyKernel.lua --kernelfile="../btgui/OpenGLWindow/Shaders/pointSpriteVS.glsl" --headerfile="../btgui/OpenGLWindow/Shaders/pointSpriteVS.h" --stringname="pointSpriteVertexShader" stringify'
eval '$mypremake --file=stringifyKernel.lua --kernelfile="../btgui/OpenGLWindow/Shaders/pointSpritePS.glsl" --headerfile="../btgui/OpenGLWindow/Shaders/pointSpritePS.h" --stringname="pointSpriteFragmentShader" stringify'
eval '$mypremake --file=stringifyKernel.lua --kernelfile="../examples/OpenGLWindow/Shaders/instancingVS.glsl" --headerfile="../examples/OpenGLWindow/Shaders/instancingVS.h" --stringname="instancingVertexShader" stringify'
eval '$mypremake --file=stringifyKernel.lua --kernelfile="../examples/OpenGLWindow/Shaders/instancingPS.glsl" --headerfile="../examples/OpenGLWindow/Shaders/instancingPS.h" --stringname="instancingFragmentShader" stringify'
eval '$mypremake --file=stringifyKernel.lua --kernelfile="../examples/OpenGLWindow/Shaders/pointSpriteVS.glsl" --headerfile="../examples/OpenGLWindow/Shaders/pointSpriteVS.h" --stringname="pointSpriteVertexShader" stringify'
eval '$mypremake --file=stringifyKernel.lua --kernelfile="../examples/OpenGLWindow/Shaders/pointSpritePS.glsl" --headerfile="../examples/OpenGLWindow/Shaders/pointSpritePS.h" --stringname="pointSpriteFragmentShader" stringify'
eval '$mypremake --file=stringifyKernel.lua --kernelfile="../btgui/OpenGLWindow/Shaders/createShadowMapInstancingPS.glsl" --headerfile="../btgui/OpenGLWindow/Shaders/createShadowMapInstancingPS.h" --stringname="createShadowMapInstancingFragmentShader" stringify'
eval '$mypremake --file=stringifyKernel.lua --kernelfile="../btgui/OpenGLWindow/Shaders/createShadowMapInstancingVS.glsl" --headerfile="../btgui/OpenGLWindow/Shaders/createShadowMapInstancingVS.h" --stringname="createShadowMapInstancingVertexShader" stringify'
eval '$mypremake --file=stringifyKernel.lua --kernelfile="../examples/OpenGLWindow/Shaders/createShadowMapInstancingPS.glsl" --headerfile="../examples/OpenGLWindow/Shaders/createShadowMapInstancingPS.h" --stringname="createShadowMapInstancingFragmentShader" stringify'
eval '$mypremake --file=stringifyKernel.lua --kernelfile="../examples/OpenGLWindow/Shaders/createShadowMapInstancingVS.glsl" --headerfile="../examples/OpenGLWindow/Shaders/createShadowMapInstancingVS.h" --stringname="createShadowMapInstancingVertexShader" stringify'
eval '$mypremake --file=stringifyKernel.lua --kernelfile="../btgui/OpenGLWindow/Shaders/useShadowMapInstancingPS.glsl" --headerfile="../btgui/OpenGLWindow/Shaders/useShadowMapInstancingPS.h" --stringname="useShadowMapInstancingFragmentShader" stringify'
eval '$mypremake --file=stringifyKernel.lua --kernelfile="../btgui/OpenGLWindow/Shaders/useShadowMapInstancingVS.glsl" --headerfile="../btgui/OpenGLWindow/Shaders/useShadowMapInstancingVS.h" --stringname="useShadowMapInstancingVertexShader" stringify'
eval '$mypremake --file=stringifyKernel.lua --kernelfile="../Demos3/GpuDemos/broadphase/pairsKernel.cl" --headerfile="../Demos3/GpuDemos/broadphase/pairsKernel.h" --stringname="pairsKernelsCL" stringify'
eval '$mypremake --file=stringifyKernel.lua --kernelfile="../examples/OpenGLWindow/Shaders/useShadowMapInstancingPS.glsl" --headerfile="../examples/OpenGLWindow/Shaders/useShadowMapInstancingPS.h" --stringname="useShadowMapInstancingFragmentShader" stringify'
eval '$mypremake --file=stringifyKernel.lua --kernelfile="../examples/OpenGLWindow/Shaders/useShadowMapInstancingVS.glsl" --headerfile="../examples/OpenGLWindow/Shaders/useShadowMapInstancingVS.h" --stringname="useShadowMapInstancingVertexShader" stringify'
eval '$mypremake --file=stringifyKernel.lua --kernelfile="../examples/OpenCL/broadphase/pairsKernel.cl" --headerfile="../examples/OpenCL/broadphase/pairsKernel.h" --stringname="pairsKernelsCL" stringify'

View File

@@ -1,4 +0,0 @@
cd `dirname $0`
./premake4_osx xcode4

7
build_and_run_cmake.sh Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/sh
rm CMakeCache.txt
mkdir build_cmake
cd build_cmake
cmake ..
make -j12
examples/ExampleBrowser/App_ExampleBrowser

7
build_and_run_premake.sh Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/sh
cd build3
./premake4_linux64 gmake
./premake4_osx gmake
cd gmake
make -j12
../../bin/App_BulletExampleBrowser_gmake_x64_release

View File

@@ -1,6 +1,7 @@
rem premake4 --with-pe vs2010
rem premake4 --bullet2demos vs2010
cd build3
premake4 --targetdir="../bin" vs2010
rem premake4 --targetdir="../server2bin" vs2010
rem cd vs2010
@@ -13,6 +14,6 @@ rem cd vs2010
rem rename 0_Bullet3Solution.sln 0_client.sln
rem cd ..
rem rename vs2010 vs2010_client
start vs2010/0_Bullet3Solution.sln
pause
pause

BIN
data/checker_grid.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
data/checker_huge.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -9,6 +9,6 @@ newmtl cube
Kd 0.5880 0.5880 0.5880
Ks 0.0000 0.0000 0.0000
Ke 0.0000 0.0000 0.0000
map_Ka cube.png
map_Kd cube.png
map_Ka cube.tga
map_Kd floor_diffuse.tga

View File

@@ -47,6 +47,10 @@
<material name="Orange">
<color rgba="1.0 0.423529411765 0.0392156862745 1.0"/>
</material>
<material name="Blue">
<color rgba="0.5 0.7 1.0 1.0"/>
</material>
<!--Import the lbr iiwa macro -->
<!--Import Transmissions -->
<!--Include Utilities -->
@@ -97,7 +101,7 @@
<geometry>
<mesh filename="meshes/link_1.stl"/>
</geometry>
<material name="Orange"/>
<material name="Blue"/>
</visual>
<collision>
<origin rpy="0 0 0" xyz="0 0 0"/>
@@ -126,7 +130,7 @@
<geometry>
<mesh filename="meshes/link_2.stl"/>
</geometry>
<material name="Orange"/>
<material name="Blue"/>
</visual>
<collision>
<origin rpy="0 0 0" xyz="0 0 0"/>
@@ -184,7 +188,7 @@
<geometry>
<mesh filename="meshes/link_4.stl"/>
</geometry>
<material name="Orange"/>
<material name="Blue"/>
</visual>
<collision>
<origin rpy="0 0 0" xyz="0 0 0"/>
@@ -213,7 +217,7 @@
<geometry>
<mesh filename="meshes/link_5.stl"/>
</geometry>
<material name="Orange"/>
<material name="Blue"/>
</visual>
<collision>
<origin rpy="0 0 0" xyz="0 0 0"/>

11
data/textured_sphere.mtl Normal file
View File

@@ -0,0 +1,11 @@
# Blender MTL File: 'None'
# Material Count: 1
newmtl None
Ns 0
Ka 0.000000 0.000000 0.000000
Kd 0.8 0.8 0.8
Ks 0.8 0.8 0.8
d 1
illum 2
map_Kd checker_grid.jpg

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
# Blender MTL File: 'None'
# Material Count: 1
newmtl None
Ns 0
Ka 0.000000 0.000000 0.000000
Kd 0.8 0.8 0.8
Ks 0.8 0.8 0.8
d 1
illum 2
map_Kd checker_huge.gif

File diff suppressed because it is too large Load Diff

View File

@@ -101,3 +101,35 @@ if os.is("MacOSX") then
links{"Cocoa.framework"}
end
project "App_BasicExampleTinyRenderer"
if _OPTIONS["ios"] then
kind "WindowedApp"
else
kind "ConsoleApp"
end
defines {"B3_USE_STANDALONE_EXAMPLE"}
includedirs {"../../src"}
links {
"BulletDynamics","BulletCollision", "LinearMath", "Bullet3Common"
}
language "C++"
files {
"BasicExample.cpp",
"*.h",
"../StandaloneMain/main_tinyrenderer_single_example.cpp",
"../ExampleBrowser/CollisionShape2TriangleMesh.cpp",
"../OpenGLWindow/SimpleCamera.cpp",
"../TinyRenderer/geometry.cpp",
"../TinyRenderer/model.cpp",
"../TinyRenderer/tgaimage.cpp",
"../TinyRenderer/our_gl.cpp",
"../TinyRenderer/TinyRenderer.cpp",
"../Utils/b3ResourcePath.cpp"
}

View File

@@ -6,6 +6,8 @@ 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 getCameraTargetPosition(float pos[3]) const = 0;
virtual void getCameraPosition(float pos[3]) const = 0;

View File

@@ -45,6 +45,8 @@ 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 autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld) =0;
virtual void drawText3D( const char* txt, float posX, float posZY, float posZ, float size)=0;
@@ -103,6 +105,16 @@ struct DummyGUIHelper : public GUIHelperInterface
{
}
virtual void copyCameraImageData(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;
}
virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld)
{
}

View File

@@ -15,10 +15,10 @@ struct DrawGridData
int upAxis;
float gridColor[4];
DrawGridData()
DrawGridData(int upAxis=1)
:gridSize(10),
upOffset(0.001f),
upAxis(1)
upAxis(upAxis)
{
gridColor[0] = 0.6f;
gridColor[1] = 0.6f;
@@ -76,6 +76,9 @@ struct CommonGraphicsApp
virtual void dumpNextFrameToPng(const char* pngFilename){}
virtual void dumpFramesToVideo(const char* mp4Filename){}
virtual void getScreenPixels(unsigned char* rgbaBuffer, int bufferSizeInBytes){};
virtual void getBackgroundColor(float* red, float* green, float* blue) const
{
if (red)
@@ -119,6 +122,7 @@ struct CommonGraphicsApp
virtual void swapBuffer() = 0;
virtual void drawText( const char* txt, int posX, int posY) = 0;
virtual void drawText3D( const char* txt, float posX, float posZY, float posZ, float size)=0;
virtual void drawTexturedRect(float x0, float y0, float x1, float y1, float color[4], float u0,float v0, float u1, float v1, int useRGBA)=0;
virtual int registerCubeShape(float halfExtentsX,float halfExtentsY, float halfExtentsZ, int textureIndex = -1, float textureScaling = 1)=0;
virtual int registerGraphicsUnitSphereShape(EnumSphereLevelOfDetail lod, int textureId=-1) = 0;

View File

@@ -40,12 +40,14 @@ struct ButtonParams
const char* m_name;
int m_buttonId;
void* m_userPointer;
bool m_isTrigger;
ButtonParamChangedCallback m_callback;
ButtonParams(const char* name, int buttonId, bool isTrigger)
:m_name(name),
m_buttonId(buttonId),
m_userPointer(0),
m_isTrigger(isTrigger),
m_callback(0)
{
}

View File

@@ -124,6 +124,8 @@ SET(BulletExampleBrowser_SRCS
../TinyRenderer/tgaimage.cpp
../TinyRenderer/our_gl.cpp
../TinyRenderer/TinyRenderer.cpp
../SharedMemory/TinyRendererVisualShapeConverter.cpp
../SharedMemory/TinyRendererVisualShapeConverter.h
../RenderingExamples/TinyRendererSetup.cpp
../SharedMemory/PhysicsServer.cpp
../SharedMemory/PhysicsClientSharedMemory.cpp

View File

@@ -63,7 +63,7 @@
#include "../ExtendedTutorials/SimpleCloth.h"
#include "../ExtendedTutorials/Chain.h"
#include "../ExtendedTutorials/Bridge.h"
#include "../ExtendedTutorials/RigidBodyFromObj.h"
#include "../ExtendedTutorials/RigidBodyFromObj.h"
struct ExampleEntry
{
@@ -88,38 +88,38 @@ struct ExampleEntry
static ExampleEntry gDefaultExamples[]=
{
ExampleEntry(0,"API"),
ExampleEntry(1,"Basic Example","Create some rigid bodies using box collision shapes. This is a good example to familiarize with the basic initialization of Bullet. The Basic Example can also be compiled without graphical user interface, as a console application. Press W for wireframe, A to show AABBs, I to suspend/restart physics simulation. Press D to toggle auto-deactivation of the simulation. ", BasicExampleCreateFunc),
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.",
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.",
AllConstraintCreateFunc),
ExampleEntry(1,"Motorized Hinge","Use of a btHingeConstraint. You can adjust the first slider to change the target velocity, and the second slider to adjust the maximum impulse applied to reach the target velocity. Note that the hinge angle can reach beyond -360 and 360 degrees.", ConstraintCreateFunc),
ExampleEntry(1,"TestHingeTorque", "Apply a torque in the hinge axis. This example uses a btHingeConstraint and btRigidBody. The setup is similar to the multi body example TestJointTorque.",
TestHingeTorqueCreateFunc),
// ExampleEntry(0,"What's new in 2.83"),
ExampleEntry(1,"6DofSpring2","Show the use of the btGeneric6DofSpring2Constraint. This is a replacement of the btGeneric6DofSpringConstraint, it has various improvements. This includes improved spring implementation and better control over the restitution (bounce) when the constraint hits its limits.",
ExampleEntry(1,"6DofSpring2","Show the use of the btGeneric6DofSpring2Constraint. This is a replacement of the btGeneric6DofSpringConstraint, it has various improvements. This includes improved spring implementation and better control over the restitution (bounce) when the constraint hits its limits.",
Dof6Spring2CreateFunc),
ExampleEntry(1,"Motor Demo", "Dynamic control the target velocity of a motor of a btHingeConstraint. This demo makes use of the 'internal tick callback'. You can press W for wireframe, C and L to visualize constraint frame and limits.", MotorControlCreateFunc),
ExampleEntry(1,"Gyroscopic", "Show the Dzhanibekov effect using various settings of the gyroscopic term. You can select the gyroscopic term computation using btRigidBody::setFlags, with arguments BT_ENABLE_GYROSCOPIC_FORCE_EXPLICIT (using explicit integration, which adds energy and can lead to explosions), BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_WORLD, BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY. If you don't set any of these flags, there is no gyroscopic term used.", GyroscopicCreateFunc),
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,"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),
@@ -128,7 +128,7 @@ static ExampleEntry gDefaultExamples[]=
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,"Tutorial"),
ExampleEntry(1,"Constant Velocity","Free moving rigid body, without external or constraint forces", TutorialCreateFunc,TUT_VELOCITY),
ExampleEntry(1,"Gravity Acceleration","Motion of a free falling rigid body under constant gravitational acceleration", TutorialCreateFunc,TUT_ACCELERATION),
@@ -139,13 +139,13 @@ static ExampleEntry gDefaultExamples[]=
ExampleEntry(0,"Collision"),
ExampleEntry(1, "Spheres & Plane C-API (Bullet2)", "Collision C-API using Bullet 2.x backend", CollisionTutorialBullet2CreateFunc,TUT_SPHERE_PLANE_BULLET2),
//ExampleEntry(1, "Spheres & Plane C-API (Bullet3)", "Collision C-API using Bullet 3.x backend", CollisionTutorialBullet2CreateFunc,TUT_SPHERE_PLANE_RTB3),
#ifdef INCLUDE_CLOTH_DEMOS
ExampleEntry(0,"Soft Body"),
ExampleEntry(1,"Cloth","Simulate a patch of cloth.", SoftDemoCreateFunc,0),
ExampleEntry(1,"Pressure","Simulate 3d soft body using a pressure constraint.",SoftDemoCreateFunc,1),
ExampleEntry(1,"Volume","Simulate 3d soft body using a volume constraint.",SoftDemoCreateFunc,2),
ExampleEntry(1,"Ropes","Simulate ropes", SoftDemoCreateFunc,3),
@@ -153,7 +153,7 @@ static ExampleEntry gDefaultExamples[]=
ExampleEntry(1,"Cloth Attach","A rigid body attached to a cloth.", SoftDemoCreateFunc,5),
ExampleEntry(1,"Sticks","Show simulation of ropes fixed to the ground.", SoftDemoCreateFunc,6),
ExampleEntry(1,"Capsule Collision","Collision detection between a capsule shape and cloth.", SoftDemoCreateFunc,7),
ExampleEntry(1,"Collide","Soft body collision", SoftDemoCreateFunc,8),
ExampleEntry(1,"Collide 2","Soft body collision",SoftDemoCreateFunc,9),
ExampleEntry(1,"Collide 3","Soft body collision",SoftDemoCreateFunc,10),
@@ -179,7 +179,7 @@ static ExampleEntry gDefaultExamples[]=
ExampleEntry(1,"Cluster Stack Mixed","Stacking of soft bodies and rigid bodies.",SoftDemoCreateFunc,29),
ExampleEntry(1,"Tetra Cube","Simulate a volumetric soft body cube defined by tetrahedra.", SoftDemoCreateFunc,30),
ExampleEntry(1,"Tetra Bunny","Simulate a volumetric soft body Stanford bunny defined by tetrahedra.", SoftDemoCreateFunc,31),
#endif //INCLUDE_CLOTH_DEMOS
///we disable the benchmarks in debug mode, they are way too slow and benchmarking in debug mode is not recommended
@@ -196,7 +196,7 @@ static ExampleEntry gDefaultExamples[]=
#endif
ExampleEntry(0,"Importers"),
ExampleEntry(1,"Import .bullet", "Load a binary .bullet file. The serialization mechanism can deal with versioning, differences in endianess, 32 and 64bit, double/single precision. It is easy to save a .bullet file, see the examples/Importers/ImportBullet/SerializeDemo.cpp for a code example how to export a .bullet file.", SerializeBulletCreateFunc),
@@ -206,50 +206,56 @@ static ExampleEntry gDefaultExamples[]=
ExampleEntry(1,"Obj2RigidBody Optimize", "Load a triangle mesh from Wavefront .obj, remove the vertices that are not on the convex hull", ET_RigidBodyFromObjCreateFunc,OptimizeConvexObj),
ExampleEntry(1,"Quake BSP", "Import a Quake .bsp file", ImportBspCreateFunc, 0),
ExampleEntry(1,"COLLADA dae", "Import the geometric mesh data from a COLLADA file. This is used as part of the URDF importer. This loader can also be used to import collision geometry in general. ",
ExampleEntry(1,"COLLADA dae", "Import the geometric mesh data from a COLLADA file. This is used as part of the URDF importer. This loader can also be used to import collision geometry in general. ",
ImportColladaCreateFunc, 0),
ExampleEntry(1,"STL", "Import the geometric mesh data from a STL file. This is used as part of the URDF importer. This loader can also be used to import collision geometry in general. ",ImportSTLCreateFunc, 0),
ExampleEntry(1,"URDF (RigidBody)", "Import a URDF file, and create rigid bodies (btRigidBody) connected by constraints.", ImportURDFCreateFunc, 0),
ExampleEntry(1,"URDF (MultiBody)", "Import a URDF file and create a single multibody (btMultiBody) with tree hierarchy of links (mobilizers).",
ExampleEntry(1,"URDF (MultiBody)", "Import a URDF file and create a single multibody (btMultiBody) with tree hierarchy of links (mobilizers).",
ImportURDFCreateFunc, 1),
ExampleEntry(1,"SDF (MultiBody)", "Import an SDF file, create multiple multibodies etc", ImportSDFCreateFunc),
ExampleEntry(0,"Vehicles"),
ExampleEntry(1,"Hinge2 Vehicle", "A rigid body chassis with 4 rigid body wheels attached by a btHinge2Constraint",Hinge2VehicleCreateFunc),
ExampleEntry(1,"ForkLift","Simulate a fork lift vehicle with a working fork lift that can be moved using the cursor keys. The wheels collision is simplified using ray tests."
"There are currently some issues with the wheel rendering, the wheels rotate when picking up the object."
"The demo implementation allows to choose various MLCP constraint solvers.",
"The demo implementation allows to choose various MLCP constraint solvers.",
ForkLiftCreateFunc),
ExampleEntry(0,"Raycast"),
ExampleEntry(1,"Raytest", "Cast rays using the btCollisionWorld::rayTest method. The example shows how to receive the hit position and normal along the ray against the first object. Also it shows how to receive all the hits along a ray.", RaytestCreateFunc),
ExampleEntry(1,"Raytracer","Implement an extremely simple ray tracer using the ray trace functionality in btCollisionWorld.",
ExampleEntry(1,"Raytracer","Implement an extremely simple ray tracer using the ray trace functionality in btCollisionWorld.",
RayTracerCreateFunc),
ExampleEntry(0,"Experiments"),
ExampleEntry(1,"Robot Control", "Create a physics client and server to create and control robots.",
PhysicsClientCreateFunc, eCLIENTEXAMPLE_SERVER),
ExampleEntry(1,"Physics Server", "Create a physics server that communicates with a physics client over shared memory",
PhysicsServerCreateFunc),
ExampleEntry(1,"Physics Server (RTC)", "Create a physics server that communicates with a physics client over shared memory. At each update, the Physics Server will continue calling 'stepSimulation' based on the real-time clock (RTC).",
PhysicsServerCreateFunc,PHYSICS_SERVER_USE_RTC_CLOCK),
ExampleEntry(1,"Physics Server (Logging)", "Create a physics server that communicates with a physics client over shared memory. It will log all commands to a file.",
PhysicsServerCreateFunc,PHYSICS_SERVER_ENABLE_COMMAND_LOGGING),
ExampleEntry(1,"Physics Server (Replay Log)", "Create a physics server that replay a command log from disk.",
PhysicsServerCreateFunc,PHYSICS_SERVER_REPLAY_FROM_COMMAND_LOG),
ExampleEntry(1, "Physics Client", "Create a physics client that can communicate with a physics server over shared memory", PhysicsClientCreateFunc),
#ifdef ENABLE_LUA
ExampleEntry(1,"Lua Script", "Create the dynamics world, collision shapes and rigid bodies using Lua scripting",
LuaDemoCreateFunc),
#endif
ExampleEntry(1,"MultiThreading (submitJob)", "Simple example of executing jobs across multiple threads.",
MultiThreadingExampleCreateFunc,SINGLE_SIM_THREAD),
ExampleEntry(1,"Voronoi Fracture", "Automatically create a compound rigid body using voronoi tesselation. Individual parts are modeled as rigid bodies using a btConvexHullShape.",
VoronoiFractureCreateFunc),
ExampleEntry(1,"Fracture demo", "Create a basic custom implementation to model fracturing objects, based on a btCompoundShape. It explicitly propagates the collision impulses and breaks the rigid body into multiple rigid bodies. Press F to toggle fracture and glue mode.", FractureDemoCreateFunc),
ExampleEntry(1,"Planar 2D","Show the use of 2D collision shapes and rigid body simulation. The collision shape is wrapped into a btConvex2dShape. The rigid bodies are restricted in a plane using the 'setAngularFactor' and 'setLinearFactor' API call.",Planar2DCreateFunc),
@@ -259,7 +265,7 @@ static ExampleEntry gDefaultExamples[]=
ExampleEntry(1,"CoordinateSystemDemo","Show the axis and positive rotation direction around the axis.", CoordinateSystemCreateFunc),
ExampleEntry(1,"Time Series", "Render some value(s) in a 2D graph window, shifting to the left", TimeSeriesCreateFunc),
ExampleEntry(1,"TinyRenderer", "Very small software renderer.", TinyRendererCreateFunc),
//Extended Tutorials Added by Mobeen
ExampleEntry(0,"Extended Tutorials"),
ExampleEntry(1,"Simple Box", "Simplest possible demo creating a single box rigid body that falls under gravity", ET_SimpleBoxCreateFunc),
@@ -268,9 +274,6 @@ static ExampleEntry gDefaultExamples[]=
ExampleEntry(1,"Simple Cloth", "Creating a simple piece of cloth", ET_SimpleClothCreateFunc),
ExampleEntry(1,"Simple Chain", "Creating 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", "Creating 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","Drop some boxes on an inclined plane",ET_InclinedPlaneCreateFunc),
ExampleEntry(1,"Multi Pendulum","Create a multi pendulum",ET_MultiPendulumCreateFunc),
ExampleEntry(1,"Newtonian Pendulum","Create a newtonian pendulum",ET_NewtonianPendulumCreateFunc),
//todo: create a category/tutorial about advanced topics, such as optimizations, using different collision detection algorithm, different constraint solvers etc.
//ExampleEntry(0,"Advanced"),
@@ -330,8 +333,8 @@ void ExampleEntriesAll::initExampleEntries()
{
m_data->m_allExamples.push_back(gAdditionalRegisteredExamples[i]);
}
int numDefaultEntries = sizeof(gDefaultExamples)/sizeof(ExampleEntry);
for (int i=0;i<numDefaultEntries;i++)

View File

@@ -141,7 +141,8 @@ void GwenParameterInterface::registerButtonParameter(ButtonParams& params)
MyButtonEventHandler* handler = new MyButtonEventHandler(params.m_callback,params.m_buttonId,params.m_userPointer);
button->SetText(params.m_name);
button->onPress.Add( handler, &MyButtonEventHandler::onButtonPress );
button->SetIsToggle(params.m_isTrigger);
m_paramInternalData->m_buttons.push_back(button);
m_paramInternalData->m_buttonEventHandlers.push_back(handler);
@@ -190,8 +191,8 @@ void GwenParameterInterface::registerComboBox(ComboBoxParams& params)
combobox->onSelection.Add(handler,&MyComboBoxHander2::onSelect);
int ypos = m_gwenInternalData->m_curYposition;
m_gwenInternalData->m_curYposition+=22;
combobox->SetPos(10, ypos );
combobox->SetWidth( 100 );
combobox->SetPos(5, ypos );
combobox->SetWidth( 220 );
//box->SetPos(120,130);
for (int i=0;i<params.m_numItems;i++)
{
@@ -200,6 +201,7 @@ void GwenParameterInterface::registerComboBox(ComboBoxParams& params)
combobox->OnItemSelected(item);
}
}

View File

@@ -76,17 +76,17 @@ public:
virtual ~ExampleEntriesPhysicsServer();
static void registerExampleEntry(int menuLevel, const char* name,const char* description, CommonExampleInterface::CreateFunc* createFunc, int option=0);
virtual void initExampleEntries();
virtual void initOpenCLExampleEntries();
virtual int getNumRegisteredExamples();
virtual CommonExampleInterface::CreateFunc* getExampleCreateFunc(int index);
virtual const char* getExampleName(int index);
virtual const char* getExampleDescription(int index);
virtual int getExampleOption(int index);
@@ -120,11 +120,14 @@ struct ExampleEntriesInternalData2
static ExampleEntryPhysicsServer gDefaultExamplesPhysicsServer[]=
{
ExampleEntryPhysicsServer(0,"Robotics Control"),
ExampleEntryPhysicsServer(1,"Physics Server", "Create a physics server that communicates with a physics client over shared memory",
PhysicsServerCreateFunc),
ExampleEntryPhysicsServer(1,"Physics Server (RTC)", "Create a physics server that communicates with a physics client over shared memory. At each update, the Physics Server will continue calling 'stepSimulation' based on the real-time clock (RTC).",
PhysicsServerCreateFunc,PHYSICS_SERVER_USE_RTC_CLOCK),
ExampleEntryPhysicsServer(1,"Physics Server (Logging)", "Create a physics server that communicates with a physics client over shared memory. It will log all commands to a file.",
PhysicsServerCreateFunc,PHYSICS_SERVER_ENABLE_COMMAND_LOGGING),
ExampleEntryPhysicsServer(1,"Physics Server (Replay Log)", "Create a physics server that replay a command log from disk.",
@@ -152,7 +155,7 @@ void ExampleEntriesPhysicsServer::initExampleEntries()
{
m_data->m_allExamples.clear();
int numDefaultEntries = sizeof(gDefaultExamplesPhysicsServer)/sizeof(ExampleEntryPhysicsServer);
for (int i=0;i<numDefaultEntries;i++)
@@ -231,8 +234,8 @@ void ExampleBrowserThreadFunc(void* userPtr,void* lsMemory)
int workLeft = true;
b3CommandLineArgs args2(args->m_argc,args->m_argv);
b3Clock clock;
ExampleEntriesPhysicsServer examples;
examples.initExampleEntries();
@@ -243,12 +246,12 @@ void ExampleBrowserThreadFunc(void* userPtr,void* lsMemory)
clock.reset();
if (init)
{
args->m_cs->lock();
args->m_cs->setSharedParam(0,eExampleBrowserIsInitialized);
args->m_cs->unlock();
do
do
{
float deltaTimeInSeconds = clock.getTimeMicroseconds()/1000000.f;
clock.reset();
@@ -405,7 +408,7 @@ void btUpdateInProcessExampleBrowserMainThread(btInProcessExampleBrowserMainThre
}
void btShutDownExampleBrowserMainThread(btInProcessExampleBrowserMainThreadInternalData* data)
{
data->m_exampleBrowser->setSharedMemoryInterface(0);
delete data->m_exampleBrowser;
delete data;

View File

@@ -143,6 +143,9 @@ struct OpenGLGuiHelperInternalData
struct CommonGraphicsApp* m_glApp;
class MyDebugDrawer* m_debugDraw;
GL_ShapeDrawer* m_gl2ShapeDrawer;
btAlignedObjectArray<unsigned char> m_rgbaPixelBuffer;
btAlignedObjectArray<float> m_depthBuffer;
};
@@ -238,8 +241,6 @@ void OpenGLGuiHelper::createCollisionShapeGraphicsObject(btCollisionShape* colli
{
gfxVertices[i].uv[j] = 0.5;//we don't have UV info...
}
}
}
@@ -325,6 +326,51 @@ 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)
{
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();
if (widthPtr)
*widthPtr = w;
if (heightPtr)
*heightPtr = h;
if (numPixelsCopied)
*numPixelsCopied = 0;
int numTotalPixels = w*h;
int numRemainingPixels = numTotalPixels - startPixelIndex;
int numBytesPerPixel = 4;//RGBA
int numRequestedPixels = btMin(rgbaBufferSizeInPixels,numRemainingPixels);
if (numRequestedPixels)
{
if (startPixelIndex==0)
{
//quick test: render the scene
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];
}
}
if (numPixelsCopied)
*numPixelsCopied = numRequestedPixels;
}
}
struct MyConvertPointerSizeT

View File

@@ -44,6 +44,8 @@ struct OpenGLGuiHelper : public GUIHelperInterface
virtual void setUpAxis(int axis);
virtual void resetCamera(float camDist, float pitch, float yaw, float camPosX,float camPosY, float camPosZ);
virtual void copyCameraImageData(unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels, float* depthBuffer, int depthBufferSizeInPixels, int startPixelIndex, int* width, int* height, int* numPixelsCopied);
virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld) ;

View File

@@ -76,6 +76,8 @@ project "App_BulletExampleBrowser"
"../SharedMemory/PhysicsLoopBackC_API.h",
"../SharedMemory/PhysicsServerCommandProcessor.cpp",
"../SharedMemory/PhysicsServerCommandProcessor.h",
"../SharedMemory/TinyRendererVisualShapeConverter.cpp",
"../SharedMemory/TinyRendererVisualShapeConverter.h",
"../MultiThreading/MultiThreadingExample.cpp",
"../MultiThreading/b3PosixThreadSupport.cpp",
"../MultiThreading/b3Win32ThreadSupport.cpp",

View File

@@ -42,7 +42,7 @@ struct RigidBodyFromObjExample : public CommonRigidBodyBase
virtual void renderScene();
void resetCamera()
{
float dist = 41;
float dist = 11;
float pitch = 52;
float yaw = 35;
float targetPos[3]={0,0.46,0};
@@ -87,8 +87,11 @@ void RigidBodyFromObjExample::initPhysics()
const GLInstanceVertex& v = glmesh->m_vertices->at(0);
btConvexHullShape* shape = new btConvexHullShape((const btScalar*)(&(v.xyzw[0])), glmesh->m_numvertices, sizeof(GLInstanceVertex));
float scaling[4] = {0.1,0.1,0.1,1};
shape->setLocalScaling(btVector3(0.1,0.1,0.1));
btVector3 localScaling(scaling[0],scaling[1],scaling[2]);
shape->setLocalScaling(localScaling);
if (m_options & OptimizeConvexObj)
{
@@ -114,25 +117,27 @@ void RigidBodyFromObjExample::initPhysics()
if (isDynamic)
shape->calculateLocalInertia(mass,localInertia);
btVector3 position(0,20,0);
float color[4] = {1,1,1,1};
float orn[4] = {0,0,0,1};
float pos[4] = {0,3,0,0};
btVector3 position(pos[0],pos[1],pos[2]);
startTransform.setOrigin(position);
btRigidBody* body = createRigidBody(mass,startTransform,shape);
btVector3 color(1,1,1);
btVector3 scaling(0.1,0.1,0.1);
btRigidBody* body = createRigidBody(mass,startTransform,shape);
bool useConvexHullForRendering = ((m_options & ObjUseConvexHullForRendering)!=0);
if (!useConvexHullForRendering)
{
int shapeId = m_guiHelper->getRenderInterface()->registerShape(&glmesh->m_vertices->at(0).xyzw[0],
glmesh->m_numvertices,
&glmesh->m_indices->at(0),
glmesh->m_numIndices,
B3_GL_TRIANGLES,-1);
shape->setUserIndex(shapeId);
int renderInstance = m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId,position,startTransform.getRotation(),color,scaling);
body->setUserIndex(renderInstance);
int shapeId = m_guiHelper->registerGraphicsShape(&glmesh->m_vertices->at(0).xyzw[0],
glmesh->m_numvertices,
&glmesh->m_indices->at(0),
glmesh->m_numIndices);
shape->setUserIndex(shapeId);
int renderInstance = m_guiHelper->registerGraphicsInstance(shapeId,pos,orn,color,scaling);
body->setUserIndex(renderInstance);
}
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
@@ -155,5 +160,5 @@ CommonExampleInterface* ET_RigidBodyFromObjCreateFunc(CommonExampleOptions& o
return new RigidBodyFromObjExample(options.m_guiHelper,options.m_option);
}
B3_STANDALONE_EXAMPLE(ET_RigidBodyFromObjCreateFunc)

View File

@@ -0,0 +1,218 @@
project "App_RigidBodyFromObjExample"
if _OPTIONS["ios"] then
kind "WindowedApp"
else
kind "ConsoleApp"
end
defines {"B3_USE_STANDALONE_EXAMPLE"}
includedirs {"../../src"}
links {
"BulletInverseDynamicsUtils", "BulletInverseDynamics","Bullet3Common","BulletDynamics","BulletCollision", "LinearMath"
}
language "C++"
files {
"RigidBodyFromObj.cpp",
"**.h",
"../StandaloneMain/main_console_single_example.cpp",
"../Utils/b3ResourcePath.cpp",
"../Utils/b3ResourcePath.h",
"../RenderingExamples/TimeSeriesCanvas.cpp",
"../RenderingExamples/TimeSeriesFontData.cpp",
"../MultiBody/InvertedPendulumPDControl.cpp",
"../ThirdPartyLibs/tinyxml/tinystr.cpp",
"../ThirdPartyLibs/tinyxml/tinyxml.cpp",
"../ThirdPartyLibs/tinyxml/tinyxmlerror.cpp",
"../ThirdPartyLibs/tinyxml/tinyxmlparser.cpp",
"../ThirdPartyLibs/Wavefront/tiny_obj_loader.cpp",
"../ThirdPartyLibs/Wavefront/tiny_obj_loader.h",
"../Importers/ImportColladaDemo/LoadMeshFromCollada.cpp",
"../Importers/ImportObjDemo/LoadMeshFromObj.cpp",
"../Importers/ImportObjDemo/Wavefront2GLInstanceGraphicsShape.cpp",
"../Importers/ImportURDFDemo/BulletUrdfImporter.cpp",
"../Importers/ImportURDFDemo/MyMultiBodyCreator.cpp",
"../Importers/ImportURDFDemo/URDF2Bullet.cpp",
"../Importers/ImportURDFDemo/UrdfParser.cpp",
"../Importers/ImportURDFDemo/urdfStringSplit.cpp",
}
project "App_RigidBodyFromObjExampleGui"
if _OPTIONS["ios"] then
kind "WindowedApp"
else
kind "ConsoleApp"
end
defines {"B3_USE_STANDALONE_EXAMPLE"}
includedirs {"../../src"}
links {
"BulletInverseDynamicsUtils", "BulletInverseDynamics","BulletDynamics","BulletCollision", "LinearMath", "OpenGL_Window","Bullet3Common"
}
initOpenGL()
initGlew()
language "C++"
files {
"RigidBodyFromObj.cpp",
"*.h",
"../StandaloneMain/main_opengl_single_example.cpp",
"../ExampleBrowser/OpenGLGuiHelper.cpp",
"../ExampleBrowser/GL_ShapeDrawer.cpp",
"../ExampleBrowser/CollisionShape2TriangleMesh.cpp",
"../Utils/b3ResourcePath.cpp",
"../Utils/b3ResourcePath.h",
"../RenderingExamples/TimeSeriesCanvas.cpp",
"../RenderingExamples/TimeSeriesFontData.cpp",
"../MultiBody/InvertedPendulumPDControl.cpp",
"../ThirdPartyLibs/tinyxml/tinystr.cpp",
"../ThirdPartyLibs/tinyxml/tinyxml.cpp",
"../ThirdPartyLibs/tinyxml/tinyxmlerror.cpp",
"../ThirdPartyLibs/tinyxml/tinyxmlparser.cpp",
"../ThirdPartyLibs/Wavefront/tiny_obj_loader.cpp",
"../ThirdPartyLibs/Wavefront/tiny_obj_loader.h",
"../Importers/ImportColladaDemo/LoadMeshFromCollada.cpp",
"../Importers/ImportObjDemo/LoadMeshFromObj.cpp",
"../Importers/ImportObjDemo/Wavefront2GLInstanceGraphicsShape.cpp",
"../Importers/ImportURDFDemo/BulletUrdfImporter.cpp",
"../Importers/ImportURDFDemo/MyMultiBodyCreator.cpp",
"../Importers/ImportURDFDemo/URDF2Bullet.cpp",
"../Importers/ImportURDFDemo/UrdfParser.cpp",
"../Importers/ImportURDFDemo/urdfStringSplit.cpp",
}
if os.is("Linux") then initX11() end
if os.is("MacOSX") then
links{"Cocoa.framework"}
end
project "App_RigidBodyFromObjExampleGuiWithSoftwareRenderer"
if _OPTIONS["ios"] then
kind "WindowedApp"
else
kind "ConsoleApp"
end
defines {"B3_USE_STANDALONE_EXAMPLE"}
includedirs {"../../src"}
links {
"BulletInverseDynamicsUtils", "BulletInverseDynamics","BulletDynamics","BulletCollision", "LinearMath", "OpenGL_Window","Bullet3Common"
}
initOpenGL()
initGlew()
language "C++"
files {
"RigidBodyFromObj.cpp",
"*.h",
"../StandaloneMain/main_sw_tinyrenderer_single_example.cpp",
"../ExampleBrowser/OpenGLGuiHelper.cpp",
"../ExampleBrowser/GL_ShapeDrawer.cpp",
"../ExampleBrowser/CollisionShape2TriangleMesh.cpp",
"../TinyRenderer/geometry.cpp",
"../TinyRenderer/model.cpp",
"../TinyRenderer/tgaimage.cpp",
"../TinyRenderer/our_gl.cpp",
"../TinyRenderer/TinyRenderer.cpp",
"../Utils/b3ResourcePath.cpp",
"../Utils/b3ResourcePath.cpp",
"../Utils/b3ResourcePath.h",
"../RenderingExamples/TimeSeriesCanvas.cpp",
"../RenderingExamples/TimeSeriesFontData.cpp",
"../MultiBody/InvertedPendulumPDControl.cpp",
"../ThirdPartyLibs/tinyxml/tinystr.cpp",
"../ThirdPartyLibs/tinyxml/tinyxml.cpp",
"../ThirdPartyLibs/tinyxml/tinyxmlerror.cpp",
"../ThirdPartyLibs/tinyxml/tinyxmlparser.cpp",
"../ThirdPartyLibs/Wavefront/tiny_obj_loader.cpp",
"../ThirdPartyLibs/Wavefront/tiny_obj_loader.h",
"../Importers/ImportColladaDemo/LoadMeshFromCollada.cpp",
"../Importers/ImportObjDemo/LoadMeshFromObj.cpp",
"../Importers/ImportObjDemo/Wavefront2GLInstanceGraphicsShape.cpp",
"../Importers/ImportURDFDemo/BulletUrdfImporter.cpp",
"../Importers/ImportURDFDemo/MyMultiBodyCreator.cpp",
"../Importers/ImportURDFDemo/URDF2Bullet.cpp",
"../Importers/ImportURDFDemo/UrdfParser.cpp",
"../Importers/ImportURDFDemo/urdfStringSplit.cpp",
}
if os.is("Linux") then initX11() end
if os.is("MacOSX") then
links{"Cocoa.framework"}
end
project "App_RigidBodyFromObjExampleTinyRenderer"
if _OPTIONS["ios"] then
kind "WindowedApp"
else
kind "ConsoleApp"
end
defines {"B3_USE_STANDALONE_EXAMPLE"}
includedirs {"../../src"}
links {
"BulletInverseDynamicsUtils", "BulletInverseDynamics","BulletDynamics","BulletCollision", "LinearMath", "Bullet3Common"
}
language "C++"
files {
"RigidBodyFromObj.cpp",
"*.h",
"../StandaloneMain/main_tinyrenderer_single_example.cpp",
"../OpenGLWindow/SimpleCamera.cpp",
"../ExampleBrowser/CollisionShape2TriangleMesh.cpp",
"../TinyRenderer/geometry.cpp",
"../TinyRenderer/model.cpp",
"../TinyRenderer/tgaimage.cpp",
"../TinyRenderer/our_gl.cpp",
"../TinyRenderer/TinyRenderer.cpp",
"../Utils/b3ResourcePath.cpp",
"../Utils/b3ResourcePath.cpp",
"../Utils/b3ResourcePath.h",
"../RenderingExamples/TimeSeriesCanvas.cpp",
"../RenderingExamples/TimeSeriesFontData.cpp",
"../MultiBody/InvertedPendulumPDControl.cpp",
"../ThirdPartyLibs/tinyxml/tinystr.cpp",
"../ThirdPartyLibs/tinyxml/tinyxml.cpp",
"../ThirdPartyLibs/tinyxml/tinyxmlerror.cpp",
"../ThirdPartyLibs/tinyxml/tinyxmlparser.cpp",
"../ThirdPartyLibs/Wavefront/tiny_obj_loader.cpp",
"../ThirdPartyLibs/Wavefront/tiny_obj_loader.h",
"../Importers/ImportColladaDemo/LoadMeshFromCollada.cpp",
"../Importers/ImportObjDemo/LoadMeshFromObj.cpp",
"../Importers/ImportObjDemo/Wavefront2GLInstanceGraphicsShape.cpp",
"../Importers/ImportURDFDemo/BulletUrdfImporter.cpp",
"../Importers/ImportURDFDemo/MyMultiBodyCreator.cpp",
"../Importers/ImportURDFDemo/URDF2Bullet.cpp",
"../Importers/ImportURDFDemo/UrdfParser.cpp",
"../Importers/ImportURDFDemo/urdfStringSplit.cpp",
}

View File

@@ -12,32 +12,28 @@
#include "stb_image/stb_image.h"
int b3ImportMeshUtility::loadAndRegisterMeshFromFile(const std::string& fileName, CommonRenderInterface* renderer)
bool b3ImportMeshUtility::loadAndRegisterMeshFromFileInternal(const std::string& fileName, b3ImportMeshData& meshData)
{
int shapeId = -1;
char relativeFileName[1024];
meshData.m_gfxShape = 0;
meshData.m_textureImage = 0;
meshData.m_textureHeight = 0;
meshData.m_textureWidth = 0;
char relativeFileName[1024];
if (b3ResourcePath::findResourcePath(fileName.c_str(), relativeFileName, 1024))
{
char pathPrefix[1024];
b3FileUtils::extractPath(relativeFileName, pathPrefix, 1024);
btVector3 shift(0,0,0);
// int index=10;
{
btVector3 shift(0,0,0);
std::vector<tinyobj::shape_t> shapes;
std::string err = tinyobj::LoadObj(shapes, relativeFileName, pathPrefix);
GLInstanceGraphicsShape* gfxShape = btgCreateGraphicsShapeFromWavefrontObj(shapes);
int textureIndex = -1;
//try to load some texture
for (int i=0;i<shapes.size();i++)
@@ -48,7 +44,7 @@ int b3ImportMeshUtility::loadAndRegisterMeshFromFile(const std::string& fileName
int width,height,n;
const char* filename = shape.material.diffuse_texname.c_str();
const unsigned char* image=0;
unsigned char* image=0;
const char* prefix[]={ pathPrefix,"./","./data/","../data/","../../data/","../../../data/","../../../../data/"};
int numprefix = sizeof(prefix)/sizeof(const char*);
@@ -61,37 +57,59 @@ int b3ImportMeshUtility::loadAndRegisterMeshFromFile(const std::string& fileName
if (b3ResourcePath::findResourcePath(relativeFileName, relativeFileName2, 1024))
{
image = stbi_load(relativeFileName, &width, &height, &n, 3);
meshData.m_textureImage = image;
if (image)
{
meshData.m_textureWidth = width;
meshData.m_textureHeight = height;
} else
{
meshData.m_textureWidth = 0;
meshData.m_textureHeight = 0;
}
} else
{
b3Warning("not found %s\n",relativeFileName);
}
}
if (image)
{
textureIndex = renderer->registerTexture(image,width,height);
if (textureIndex>=0)
{
break;
}
}
}
}
shapeId = renderer->registerShape(&gfxShape->m_vertices->at(0).xyzw[0], gfxShape->m_numvertices, &gfxShape->m_indices->at(0), gfxShape->m_numIndices,B3_GL_TRIANGLES,textureIndex);
meshData.m_gfxShape = gfxShape;
return true;
}
}
else
{
b3Warning("Cannot find %s\n", fileName.c_str());
}
return shapeId;
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

@@ -1,13 +1,24 @@
#ifndef B3_IMPORT_MESH_UTILITY_H
#define B3_IMPORT_MESH_UTILIY_H
#define B3_IMPORT_MESH_UTILITY_H
#include <string>
struct b3ImportMeshData
{
struct GLInstanceGraphicsShape* m_gfxShape;
unsigned char* m_textureImage;//in 3 component 8-bit RGB data
int m_textureWidth;
int m_textureHeight;
};
class b3ImportMeshUtility
{
public:
static int loadAndRegisterMeshFromFile(const std::string& fileName, class CommonRenderInterface* renderer);
static bool loadAndRegisterMeshFromFileInternal(const std::string& fileName, b3ImportMeshData& meshData);
};

View File

@@ -203,7 +203,8 @@ void ImportSDFSetup::initPhysics()
m_dynamicsWorld->setGravity(gravity);
BulletURDFImporter u2b(m_guiHelper);
BulletURDFImporter u2b(m_guiHelper, 0);
bool loadOk = u2b.loadSDF(m_fileName);

View File

@@ -39,6 +39,8 @@ struct BulletURDFInternalData
char m_pathPrefix[1024];
btHashMap<btHashInt,btVector4> m_linkColors;
btAlignedObjectArray<btCollisionShape*> m_allocatedCollisionShapes;
LinkVisualShapesConverter* m_customVisualShapesConverter;
};
@@ -57,13 +59,13 @@ enum MyFileType
BulletURDFImporter::BulletURDFImporter(struct GUIHelperInterface* helper)
BulletURDFImporter::BulletURDFImporter(struct GUIHelperInterface* helper, LinkVisualShapesConverter* customConverter)
{
m_data = new BulletURDFInternalData;
m_data->m_guiHelper = helper;
m_data->m_pathPrefix[0]=0;
m_data->m_customVisualShapesConverter = customConverter;
}
@@ -98,7 +100,6 @@ struct BulletErrorLogger : public ErrorLogger
bool BulletURDFImporter::loadURDF(const char* fileName, bool forceFixedBase)
{
m_data->m_linkColors.clear();
//int argc=0;
@@ -153,9 +154,6 @@ void BulletURDFImporter::activateModel(int modelIndex)
bool BulletURDFImporter::loadSDF(const char* fileName, bool forceFixedBase)
{
m_data->m_linkColors.clear();
//int argc=0;
char relativeFileName[1024];
@@ -234,16 +232,6 @@ void BulletURDFImporter::getLinkChildIndices(int linkIndex, btAlignedObjectArray
}
}
bool BulletURDFImporter::getLinkColor(int linkIndex, btVector4& colorRGBA) const
{
btVector4* rgbaPtr = m_data->m_linkColors[linkIndex];
if (rgbaPtr)
{
colorRGBA = *rgbaPtr;
return true;
}
return false;
}
std::string BulletURDFImporter::getLinkName(int linkIndex) const
{
@@ -339,327 +327,6 @@ bool BulletURDFImporter::getRootTransformInWorld(btTransform& rootTransformInWor
return true;
}
void convertURDFToVisualShape(const UrdfVisual* visual, const char* urdfPathPrefix, const btTransform& visualTransform, btAlignedObjectArray<GLInstanceVertex>& verticesOut, btAlignedObjectArray<int>& indicesOut)
{
GLInstanceGraphicsShape* glmesh = 0;
btConvexShape* convexColShape = 0;
switch (visual->m_geometry.m_type)
{
case URDF_GEOM_CYLINDER:
{
btAlignedObjectArray<btVector3> vertices;
//int numVerts = sizeof(barrel_vertices)/(9*sizeof(float));
int numSteps = 32;
for (int i = 0; i<numSteps; i++)
{
btScalar cylRadius = visual->m_geometry.m_cylinderRadius;
btScalar cylLength = visual->m_geometry.m_cylinderLength;
btVector3 vert(cylRadius*btSin(SIMD_2_PI*(float(i) / numSteps)), cylRadius*btCos(SIMD_2_PI*(float(i) / numSteps)), cylLength / 2.);
vertices.push_back(vert);
vert[2] = -cylLength / 2.;
vertices.push_back(vert);
}
btConvexHullShape* cylZShape = new btConvexHullShape(&vertices[0].x(), vertices.size(), sizeof(btVector3));
cylZShape->setMargin(0.001);
convexColShape = cylZShape;
break;
}
case URDF_GEOM_BOX:
{
btVector3 extents = visual->m_geometry.m_boxSize;
btBoxShape* boxShape = new btBoxShape(extents*0.5f);
//btConvexShape* boxShape = new btConeShapeX(extents[2]*0.5,extents[0]*0.5);
convexColShape = boxShape;
convexColShape->setMargin(0.001);
break;
}
case URDF_GEOM_SPHERE:
{
btScalar radius = visual->m_geometry.m_sphereRadius;
btSphereShape* sphereShape = new btSphereShape(radius);
convexColShape = sphereShape;
convexColShape->setMargin(0.001);
break;
break;
}
case URDF_GEOM_MESH:
{
if (visual->m_name.length())
{
//b3Printf("visual->name=%s\n", visual->m_name.c_str());
}
if (1)//visual->m_geometry)
{
if (visual->m_geometry.m_meshFileName.length())
{
const char* filename = visual->m_geometry.m_meshFileName.c_str();
//b3Printf("mesh->filename=%s\n", filename);
char fullPath[1024];
int fileType = 0;
char tmpPathPrefix[1024];
std::string xml_string;
int maxPathLen = 1024;
b3FileUtils::extractPath(filename,tmpPathPrefix,maxPathLen);
char visualPathPrefix[1024];
sprintf(visualPathPrefix,"%s%s",urdfPathPrefix,tmpPathPrefix);
sprintf(fullPath, "%s%s", urdfPathPrefix, filename);
b3FileUtils::toLower(fullPath);
if (strstr(fullPath, ".dae"))
{
fileType = FILE_COLLADA;
}
if (strstr(fullPath, ".stl"))
{
fileType = FILE_STL;
}
if (strstr(fullPath,".obj"))
{
fileType = FILE_OBJ;
}
sprintf(fullPath, "%s%s", urdfPathPrefix, filename);
FILE* f = fopen(fullPath, "rb");
if (f)
{
fclose(f);
switch (fileType)
{
case FILE_OBJ:
{
glmesh = LoadMeshFromObj(fullPath,visualPathPrefix);
break;
}
case FILE_STL:
{
glmesh = LoadMeshFromSTL(fullPath);
break;
}
case FILE_COLLADA:
{
btAlignedObjectArray<GLInstanceGraphicsShape> visualShapes;
btAlignedObjectArray<ColladaGraphicsInstance> visualShapeInstances;
btTransform upAxisTrans; upAxisTrans.setIdentity();
float unitMeterScaling = 1;
int upAxis = 2;
LoadMeshFromCollada(fullPath,
visualShapes,
visualShapeInstances,
upAxisTrans,
unitMeterScaling,
upAxis);
glmesh = new GLInstanceGraphicsShape;
// int index = 0;
glmesh->m_indices = new b3AlignedObjectArray<int>();
glmesh->m_vertices = new b3AlignedObjectArray<GLInstanceVertex>();
for (int i = 0; i<visualShapeInstances.size(); i++)
{
ColladaGraphicsInstance* instance = &visualShapeInstances[i];
GLInstanceGraphicsShape* gfxShape = &visualShapes[instance->m_shapeIndex];
b3AlignedObjectArray<GLInstanceVertex> verts;
verts.resize(gfxShape->m_vertices->size());
int baseIndex = glmesh->m_vertices->size();
for (int i = 0; i<gfxShape->m_vertices->size(); i++)
{
verts[i].normal[0] = gfxShape->m_vertices->at(i).normal[0];
verts[i].normal[1] = gfxShape->m_vertices->at(i).normal[1];
verts[i].normal[2] = gfxShape->m_vertices->at(i).normal[2];
verts[i].uv[0] = gfxShape->m_vertices->at(i).uv[0];
verts[i].uv[1] = gfxShape->m_vertices->at(i).uv[1];
verts[i].xyzw[0] = gfxShape->m_vertices->at(i).xyzw[0];
verts[i].xyzw[1] = gfxShape->m_vertices->at(i).xyzw[1];
verts[i].xyzw[2] = gfxShape->m_vertices->at(i).xyzw[2];
verts[i].xyzw[3] = gfxShape->m_vertices->at(i).xyzw[3];
}
int curNumIndices = glmesh->m_indices->size();
int additionalIndices = gfxShape->m_indices->size();
glmesh->m_indices->resize(curNumIndices + additionalIndices);
for (int k = 0; k<additionalIndices; k++)
{
glmesh->m_indices->at(curNumIndices + k) = gfxShape->m_indices->at(k) + baseIndex;
}
//compensate upAxisTrans and unitMeterScaling here
btMatrix4x4 upAxisMat;
upAxisMat.setIdentity();
// upAxisMat.setPureRotation(upAxisTrans.getRotation());
btMatrix4x4 unitMeterScalingMat;
unitMeterScalingMat.setPureScaling(btVector3(unitMeterScaling, unitMeterScaling, unitMeterScaling));
btMatrix4x4 worldMat = unitMeterScalingMat*upAxisMat*instance->m_worldTransform;
//btMatrix4x4 worldMat = instance->m_worldTransform;
int curNumVertices = glmesh->m_vertices->size();
int additionalVertices = verts.size();
glmesh->m_vertices->reserve(curNumVertices + additionalVertices);
for (int v = 0; v<verts.size(); v++)
{
btVector3 pos(verts[v].xyzw[0], verts[v].xyzw[1], verts[v].xyzw[2]);
pos = worldMat*pos;
verts[v].xyzw[0] = float(pos[0]);
verts[v].xyzw[1] = float(pos[1]);
verts[v].xyzw[2] = float(pos[2]);
glmesh->m_vertices->push_back(verts[v]);
}
}
glmesh->m_numIndices = glmesh->m_indices->size();
glmesh->m_numvertices = glmesh->m_vertices->size();
//glmesh = LoadMeshFromCollada(fullPath);
break;
}
default:
{
b3Warning("Error: unsupported file type for Visual mesh: %s\n", fullPath);
btAssert(0);
}
}
if (glmesh && glmesh->m_vertices && (glmesh->m_numvertices>0))
{
//apply the geometry scaling
for (int i=0;i<glmesh->m_vertices->size();i++)
{
glmesh->m_vertices->at(i).xyzw[0] *= visual->m_geometry.m_meshScale[0];
glmesh->m_vertices->at(i).xyzw[1] *= visual->m_geometry.m_meshScale[1];
glmesh->m_vertices->at(i).xyzw[2] *= visual->m_geometry.m_meshScale[2];
}
}
else
{
b3Warning("issue extracting mesh from COLLADA/STL file %s\n", fullPath);
}
}
else
{
b3Warning("mesh geometry not found %s\n", fullPath);
}
}
}
break;
}
default:
{
b3Warning("Error: unknown visual geometry type\n");
}
}
//if we have a convex, tesselate into localVertices/localIndices
if ((glmesh==0) && convexColShape)
{
btShapeHull* hull = new btShapeHull(convexColShape);
hull->buildHull(0.0);
{
// int strideInBytes = 9*sizeof(float);
int numVertices = hull->numVertices();
int numIndices = hull->numIndices();
glmesh = new GLInstanceGraphicsShape;
// int index = 0;
glmesh->m_indices = new b3AlignedObjectArray<int>();
glmesh->m_vertices = new b3AlignedObjectArray<GLInstanceVertex>();
for (int i = 0; i < numVertices; i++)
{
GLInstanceVertex vtx;
btVector3 pos = hull->getVertexPointer()[i];
vtx.xyzw[0] = pos.x();
vtx.xyzw[1] = pos.y();
vtx.xyzw[2] = pos.z();
vtx.xyzw[3] = 1.f;
pos.normalize();
vtx.normal[0] = pos.x();
vtx.normal[1] = pos.y();
vtx.normal[2] = pos.z();
vtx.uv[0] = 0.5f;
vtx.uv[1] = 0.5f;
glmesh->m_vertices->push_back(vtx);
}
btAlignedObjectArray<int> indices;
for (int i = 0; i < numIndices; i++)
{
glmesh->m_indices->push_back(hull->getIndexPointer()[i]);
}
glmesh->m_numvertices = glmesh->m_vertices->size();
glmesh->m_numIndices = glmesh->m_indices->size();
}
delete hull;
delete convexColShape;
convexColShape = 0;
}
if (glmesh && glmesh->m_numIndices>0 && glmesh->m_numvertices >0)
{
int baseIndex = verticesOut.size();
for (int i = 0; i < glmesh->m_indices->size(); i++)
{
indicesOut.push_back(glmesh->m_indices->at(i) + baseIndex);
}
for (int i = 0; i < glmesh->m_vertices->size(); i++)
{
GLInstanceVertex& v = glmesh->m_vertices->at(i);
btVector3 vert(v.xyzw[0],v.xyzw[1],v.xyzw[2]);
btVector3 vt = visualTransform*vert;
v.xyzw[0] = vt[0];
v.xyzw[1] = vt[1];
v.xyzw[2] = vt[2];
btVector3 triNormal(v.normal[0],v.normal[1],v.normal[2]);
triNormal = visualTransform.getBasis()*triNormal;
v.normal[0] = triNormal[0];
v.normal[1] = triNormal[1];
v.normal[2] = triNormal[2];
verticesOut.push_back(v);
}
}
delete glmesh;
}
btCollisionShape* convertURDFToCollisionShape(const UrdfCollision* collision, const char* urdfPathPrefix)
@@ -911,39 +578,343 @@ btCollisionShape* convertURDFToCollisionShape(const UrdfCollision* collision, co
}
int BulletURDFImporter::convertLinkVisualShapes(int linkIndex, const char* pathPrefix, const btTransform& inertialFrame) const
static void convertURDFToVisualShapeInternal(const UrdfVisual* visual, const char* urdfPathPrefix, const btTransform& visualTransform, btAlignedObjectArray<GLInstanceVertex>& verticesOut, btAlignedObjectArray<int>& indicesOut)
{
GLInstanceGraphicsShape* glmesh = 0;
btConvexShape* convexColShape = 0;
switch (visual->m_geometry.m_type)
{
case URDF_GEOM_CYLINDER:
{
btAlignedObjectArray<btVector3> vertices;
//int numVerts = sizeof(barrel_vertices)/(9*sizeof(float));
int numSteps = 32;
for (int i = 0; i<numSteps; i++)
{
btScalar cylRadius = visual->m_geometry.m_cylinderRadius;
btScalar cylLength = visual->m_geometry.m_cylinderLength;
btVector3 vert(cylRadius*btSin(SIMD_2_PI*(float(i) / numSteps)), cylRadius*btCos(SIMD_2_PI*(float(i) / numSteps)), cylLength / 2.);
vertices.push_back(vert);
vert[2] = -cylLength / 2.;
vertices.push_back(vert);
}
btConvexHullShape* cylZShape = new btConvexHullShape(&vertices[0].x(), vertices.size(), sizeof(btVector3));
cylZShape->setMargin(0.001);
convexColShape = cylZShape;
break;
}
case URDF_GEOM_BOX:
{
btVector3 extents = visual->m_geometry.m_boxSize;
btBoxShape* boxShape = new btBoxShape(extents*0.5f);
//btConvexShape* boxShape = new btConeShapeX(extents[2]*0.5,extents[0]*0.5);
convexColShape = boxShape;
convexColShape->setMargin(0.001);
break;
}
case URDF_GEOM_SPHERE:
{
btScalar radius = visual->m_geometry.m_sphereRadius;
btSphereShape* sphereShape = new btSphereShape(radius);
convexColShape = sphereShape;
convexColShape->setMargin(0.001);
break;
break;
}
case URDF_GEOM_MESH:
{
if (visual->m_name.length())
{
//b3Printf("visual->name=%s\n", visual->m_name.c_str());
}
if (1)//visual->m_geometry)
{
if (visual->m_geometry.m_meshFileName.length())
{
const char* filename = visual->m_geometry.m_meshFileName.c_str();
//b3Printf("mesh->filename=%s\n", filename);
char fullPath[1024];
int fileType = 0;
char tmpPathPrefix[1024];
std::string xml_string;
int maxPathLen = 1024;
b3FileUtils::extractPath(filename,tmpPathPrefix,maxPathLen);
char visualPathPrefix[1024];
sprintf(visualPathPrefix,"%s%s",urdfPathPrefix,tmpPathPrefix);
sprintf(fullPath, "%s%s", urdfPathPrefix, filename);
b3FileUtils::toLower(fullPath);
if (strstr(fullPath, ".dae"))
{
fileType = FILE_COLLADA;
}
if (strstr(fullPath, ".stl"))
{
fileType = FILE_STL;
}
if (strstr(fullPath,".obj"))
{
fileType = FILE_OBJ;
}
sprintf(fullPath, "%s%s", urdfPathPrefix, filename);
FILE* f = fopen(fullPath, "rb");
if (f)
{
fclose(f);
switch (fileType)
{
case FILE_OBJ:
{
glmesh = LoadMeshFromObj(fullPath,visualPathPrefix);
break;
}
case FILE_STL:
{
glmesh = LoadMeshFromSTL(fullPath);
break;
}
case FILE_COLLADA:
{
btAlignedObjectArray<GLInstanceGraphicsShape> visualShapes;
btAlignedObjectArray<ColladaGraphicsInstance> visualShapeInstances;
btTransform upAxisTrans; upAxisTrans.setIdentity();
float unitMeterScaling = 1;
int upAxis = 2;
LoadMeshFromCollada(fullPath,
visualShapes,
visualShapeInstances,
upAxisTrans,
unitMeterScaling,
upAxis);
glmesh = new GLInstanceGraphicsShape;
// int index = 0;
glmesh->m_indices = new b3AlignedObjectArray<int>();
glmesh->m_vertices = new b3AlignedObjectArray<GLInstanceVertex>();
for (int i = 0; i<visualShapeInstances.size(); i++)
{
ColladaGraphicsInstance* instance = &visualShapeInstances[i];
GLInstanceGraphicsShape* gfxShape = &visualShapes[instance->m_shapeIndex];
b3AlignedObjectArray<GLInstanceVertex> verts;
verts.resize(gfxShape->m_vertices->size());
int baseIndex = glmesh->m_vertices->size();
for (int i = 0; i<gfxShape->m_vertices->size(); i++)
{
verts[i].normal[0] = gfxShape->m_vertices->at(i).normal[0];
verts[i].normal[1] = gfxShape->m_vertices->at(i).normal[1];
verts[i].normal[2] = gfxShape->m_vertices->at(i).normal[2];
verts[i].uv[0] = gfxShape->m_vertices->at(i).uv[0];
verts[i].uv[1] = gfxShape->m_vertices->at(i).uv[1];
verts[i].xyzw[0] = gfxShape->m_vertices->at(i).xyzw[0];
verts[i].xyzw[1] = gfxShape->m_vertices->at(i).xyzw[1];
verts[i].xyzw[2] = gfxShape->m_vertices->at(i).xyzw[2];
verts[i].xyzw[3] = gfxShape->m_vertices->at(i).xyzw[3];
}
int curNumIndices = glmesh->m_indices->size();
int additionalIndices = gfxShape->m_indices->size();
glmesh->m_indices->resize(curNumIndices + additionalIndices);
for (int k = 0; k<additionalIndices; k++)
{
glmesh->m_indices->at(curNumIndices + k) = gfxShape->m_indices->at(k) + baseIndex;
}
//compensate upAxisTrans and unitMeterScaling here
btMatrix4x4 upAxisMat;
upAxisMat.setIdentity();
// upAxisMat.setPureRotation(upAxisTrans.getRotation());
btMatrix4x4 unitMeterScalingMat;
unitMeterScalingMat.setPureScaling(btVector3(unitMeterScaling, unitMeterScaling, unitMeterScaling));
btMatrix4x4 worldMat = unitMeterScalingMat*upAxisMat*instance->m_worldTransform;
//btMatrix4x4 worldMat = instance->m_worldTransform;
int curNumVertices = glmesh->m_vertices->size();
int additionalVertices = verts.size();
glmesh->m_vertices->reserve(curNumVertices + additionalVertices);
for (int v = 0; v<verts.size(); v++)
{
btVector3 pos(verts[v].xyzw[0], verts[v].xyzw[1], verts[v].xyzw[2]);
pos = worldMat*pos;
verts[v].xyzw[0] = float(pos[0]);
verts[v].xyzw[1] = float(pos[1]);
verts[v].xyzw[2] = float(pos[2]);
glmesh->m_vertices->push_back(verts[v]);
}
}
glmesh->m_numIndices = glmesh->m_indices->size();
glmesh->m_numvertices = glmesh->m_vertices->size();
//glmesh = LoadMeshFromCollada(fullPath);
break;
}
default:
{
b3Warning("Error: unsupported file type for Visual mesh: %s\n", fullPath);
btAssert(0);
}
}
if (glmesh && glmesh->m_vertices && (glmesh->m_numvertices>0))
{
//apply the geometry scaling
for (int i=0;i<glmesh->m_vertices->size();i++)
{
glmesh->m_vertices->at(i).xyzw[0] *= visual->m_geometry.m_meshScale[0];
glmesh->m_vertices->at(i).xyzw[1] *= visual->m_geometry.m_meshScale[1];
glmesh->m_vertices->at(i).xyzw[2] *= visual->m_geometry.m_meshScale[2];
}
}
else
{
b3Warning("issue extracting mesh from COLLADA/STL file %s\n", fullPath);
}
}
else
{
b3Warning("mesh geometry not found %s\n", fullPath);
}
}
}
break;
}
default:
{
b3Warning("Error: unknown visual geometry type\n");
}
}
//if we have a convex, tesselate into localVertices/localIndices
if ((glmesh==0) && convexColShape)
{
btShapeHull* hull = new btShapeHull(convexColShape);
hull->buildHull(0.0);
{
// int strideInBytes = 9*sizeof(float);
int numVertices = hull->numVertices();
int numIndices = hull->numIndices();
glmesh = new GLInstanceGraphicsShape;
// int index = 0;
glmesh->m_indices = new b3AlignedObjectArray<int>();
glmesh->m_vertices = new b3AlignedObjectArray<GLInstanceVertex>();
for (int i = 0; i < numVertices; i++)
{
GLInstanceVertex vtx;
btVector3 pos = hull->getVertexPointer()[i];
vtx.xyzw[0] = pos.x();
vtx.xyzw[1] = pos.y();
vtx.xyzw[2] = pos.z();
vtx.xyzw[3] = 1.f;
pos.normalize();
vtx.normal[0] = pos.x();
vtx.normal[1] = pos.y();
vtx.normal[2] = pos.z();
vtx.uv[0] = 0.5f;
vtx.uv[1] = 0.5f;
glmesh->m_vertices->push_back(vtx);
}
btAlignedObjectArray<int> indices;
for (int i = 0; i < numIndices; i++)
{
glmesh->m_indices->push_back(hull->getIndexPointer()[i]);
}
glmesh->m_numvertices = glmesh->m_vertices->size();
glmesh->m_numIndices = glmesh->m_indices->size();
}
delete hull;
delete convexColShape;
convexColShape = 0;
}
if (glmesh && glmesh->m_numIndices>0 && glmesh->m_numvertices >0)
{
int baseIndex = verticesOut.size();
for (int i = 0; i < glmesh->m_indices->size(); i++)
{
indicesOut.push_back(glmesh->m_indices->at(i) + baseIndex);
}
for (int i = 0; i < glmesh->m_vertices->size(); i++)
{
GLInstanceVertex& v = glmesh->m_vertices->at(i);
btVector3 vert(v.xyzw[0],v.xyzw[1],v.xyzw[2]);
btVector3 vt = visualTransform*vert;
v.xyzw[0] = vt[0];
v.xyzw[1] = vt[1];
v.xyzw[2] = vt[2];
btVector3 triNormal(v.normal[0],v.normal[1],v.normal[2]);
triNormal = visualTransform.getBasis()*triNormal;
v.normal[0] = triNormal[0];
v.normal[1] = triNormal[1];
v.normal[2] = triNormal[2];
verticesOut.push_back(v);
}
}
delete glmesh;
}
int BulletURDFImporter::convertLinkVisualShapes(int linkIndex, const char* pathPrefix, const btTransform& localInertiaFrame) const
{
btAlignedObjectArray<GLInstanceVertex> vertices;
btAlignedObjectArray<int> indices;
btTransform startTrans; startTrans.setIdentity();
int graphicsIndex = -1;
#if USE_ROS_URDF_PARSER
for (int v = 0; v < (int)m_data->m_links[linkIndex]->visual_array.size(); v++)
{
const Visual* vis = m_data->m_links[linkIndex]->visual_array[v].get();
btVector3 childPos(vis->origin.position.x, vis->origin.position.y, vis->origin.position.z);
btQuaternion childOrn(vis->origin.rotation.x, vis->origin.rotation.y, vis->origin.rotation.z, vis->origin.rotation.w);
btTransform childTrans;
childTrans.setOrigin(childPos);
childTrans.setRotation(childOrn);
convertURDFToVisualShape(vis, pathPrefix, inertialFrame.inverse()*childTrans, vertices, indices);
}
#else
const UrdfModel& model = m_data->m_urdfParser.getModel();
btAlignedObjectArray<GLInstanceVertex> vertices;
btAlignedObjectArray<int> indices;
btTransform startTrans; startTrans.setIdentity();
const UrdfModel& model = m_data->m_urdfParser.getModel();
UrdfLink* const* linkPtr = model.m_links.getAtIndex(linkIndex);
if (linkPtr)
{
const UrdfLink* link = *linkPtr;
for (int v = 0; v < link->m_visualArray.size();v++)
{
const UrdfVisual& vis = link->m_visualArray[v];
btTransform childTrans = vis.m_linkLocalFrame;
btTransform childTrans = vis.m_linkLocalFrame;
btHashString matName(vis.m_materialName.c_str());
UrdfMaterial *const * matPtr = model.m_materials[matName];
if (matPtr)
@@ -952,19 +923,40 @@ 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);
}
convertURDFToVisualShape(&vis, pathPrefix, inertialFrame.inverse()*childTrans, vertices, indices);
convertURDFToVisualShapeInternal(&vis, pathPrefix, localInertiaFrame.inverse()*childTrans, vertices, indices);
}
}
#endif
if (vertices.size() && indices.size())
{
graphicsIndex = m_data->m_guiHelper->registerGraphicsShape(&vertices[0].xyzw[0], vertices.size(), &indices[0], indices.size());
}
return graphicsIndex;
if (vertices.size() && indices.size())
{
graphicsIndex = m_data->m_guiHelper->registerGraphicsShape(&vertices[0].xyzw[0], vertices.size(), &indices[0], indices.size());
}
return graphicsIndex;
}
bool BulletURDFImporter::getLinkColor(int linkIndex, btVector4& colorRGBA) const
{
const btVector4* rgbaPtr = m_data->m_linkColors[linkIndex];
if (rgbaPtr)
{
colorRGBA = *rgbaPtr;
return true;
}
return false;
}
void BulletURDFImporter::convertLinkVisualShapes2(int linkIndex, const char* pathPrefix, const btTransform& localInertiaFrame, class btCollisionObject* colObj) const
{
if (m_data->m_customVisualShapesConverter)
{
const UrdfModel& model = m_data->m_urdfParser.getModel();
m_data->m_customVisualShapesConverter->convertVisualShapes(linkIndex,pathPrefix,localInertiaFrame, model, colObj);
}
}
int BulletURDFImporter::getNumAllocatedCollisionShapes() const
@@ -985,25 +977,6 @@ btCollisionShape* BulletURDFImporter::getAllocatedCollisionShape(int index)
m_data->m_allocatedCollisionShapes.push_back(compoundShape);
compoundShape->setMargin(0.001);
#if USE_ROS_URDF_PARSER
for (int v=0;v<(int)m_data->m_links[linkIndex]->collision_array.size();v++)
{
const Collision* col = m_data->m_links[linkIndex]->collision_array[v].get();
btCollisionShape* childShape = convertURDFToCollisionShape(col ,pathPrefix);
if (childShape)
{
btVector3 childPos(col->origin.position.x, col->origin.position.y, col->origin.position.z);
btQuaternion childOrn(col->origin.rotation.x, col->origin.rotation.y, col->origin.rotation.z, col->origin.rotation.w);
btTransform childTrans;
childTrans.setOrigin(childPos);
childTrans.setRotation(childOrn);
compoundShape->addChildShape(localInertiaFrame.inverse()*childTrans,childShape);
}
}
#else
UrdfLink* const* linkPtr = m_data->m_urdfParser.getModel().m_links.getAtIndex(linkIndex);
btAssert(linkPtr);
if (linkPtr)
@@ -1025,8 +998,6 @@ btCollisionShape* BulletURDFImporter::getAllocatedCollisionShape(int index)
}
}
}
#endif
return compoundShape;
}

View File

@@ -3,6 +3,8 @@
#include "URDFImporterInterface.h"
#include "LinkVisualShapesConverter.h"
///BulletURDFImporter can deal with URDF and (soon) SDF files
class BulletURDFImporter : public URDFImporterInterface
@@ -13,7 +15,7 @@ class BulletURDFImporter : public URDFImporterInterface
public:
BulletURDFImporter(struct GUIHelperInterface* guiHelper);
BulletURDFImporter(struct GUIHelperInterface* guiHelper, LinkVisualShapesConverter* customConverter);
virtual ~BulletURDFImporter();
@@ -35,7 +37,7 @@ public:
virtual std::string getLinkName(int linkIndex) const;
virtual bool getLinkColor(int linkIndex, btVector4& colorRGBA) const;
virtual std::string getJointName(int linkIndex) const;
virtual void getMassAndInertia(int linkIndex, btScalar& mass,btVector3& localInertiaDiagonal, btTransform& inertialFrame) const;
@@ -44,7 +46,9 @@ public:
virtual bool getRootTransformInWorld(btTransform& rootTransformInWorld) const;
virtual int convertLinkVisualShapes(int linkIndex, const char* pathPrefix, const btTransform& localInertiaFrame) const;
virtual int convertLinkVisualShapes(int linkIndex, const char* pathPrefix, const btTransform& inertialFrame) const;
virtual void convertLinkVisualShapes2(int linkIndex, const char* pathPrefix, const btTransform& inertialFrame, class btCollisionObject* colObj) const;
///todo(erwincoumans) refactor this convertLinkCollisionShapes/memory allocation
@@ -53,6 +57,7 @@ public:
virtual int getNumAllocatedCollisionShapes() const;
virtual class btCollisionShape* getAllocatedCollisionShape(int index);
};

View File

@@ -11,6 +11,7 @@
#include "../CommonInterfaces/CommonParameterInterface.h"
#include "../../Utils/b3ResourcePath.h"
#include "BulletUrdfImporter.h"
@@ -199,18 +200,9 @@ void ImportUrdfSetup::initPhysics()
m_dynamicsWorld->setGravity(gravity);
BulletURDFImporter u2b(m_guiHelper, 0);
//now print the tree using the new interface
URDFImporterInterface* bla=0;
static bool newURDF = true;
if (newURDF)
{
b3Printf("using new URDF\n");
bla = new BulletURDFImporter(m_guiHelper);
}
URDFImporterInterface& u2b = *bla;
bool loadOk = u2b.loadURDF(m_fileName);
#ifdef TEST_MULTIBODY_SERIALIZATION

View File

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

View File

@@ -209,9 +209,14 @@ void ConvertURDF2BulletInternal(const URDFImporterInterface& u2b, MultiBodyCreat
linkTransformInWorldSpace =parentTransformInWorldSpace*parent2joint;
}
int graphicsIndex = u2b.convertLinkVisualShapes(urdfLinkIndex,pathPrefix,localInertialFrame);
btCompoundShape* compoundShape = u2b.convertLinkCollisionShapes(urdfLinkIndex,pathPrefix,localInertialFrame);
int graphicsIndex = u2b.convertLinkVisualShapes(urdfLinkIndex,pathPrefix,localInertialFrame);
if (compoundShape)
{
@@ -243,6 +248,8 @@ void ConvertURDF2BulletInternal(const URDFImporterInterface& u2b, MultiBodyCreat
creation.createRigidBodyGraphicsInstance(urdfLinkIndex, body, color, graphicsIndex);
cache.registerRigidBody(urdfLinkIndex, body, inertialFrameInWorldSpace, mass, localInertiaDiagonal, compoundShape, localInertialFrame);
//untested: u2b.convertLinkVisualShapes2(urdfLinkIndex,pathPrefix,localInertialFrame,body);
} else
{
if (cache.m_bulletMultiBody==0)
@@ -382,6 +389,8 @@ void ConvertURDF2BulletInternal(const URDFImporterInterface& u2b, MultiBodyCreat
btVector4 color = selectColor2();//(0.0,0.0,0.5);
u2b.getLinkColor(urdfLinkIndex,color);
creation.createCollisionObjectGraphicsInstance(urdfLinkIndex,col,color);
u2b.convertLinkVisualShapes2(urdfLinkIndex,pathPrefix,localInertialFrame,col);
btScalar friction = 0.5f;
@@ -395,6 +404,9 @@ void ConvertURDF2BulletInternal(const URDFImporterInterface& u2b, MultiBodyCreat
cache.m_bulletMultiBody->setBaseCollider(col);
}
}
} else
{
//u2b.convertLinkVisualShapes2(urdfLinkIndex,pathPrefix,localInertialFrame,compoundShape);
}
}

View File

@@ -42,9 +42,11 @@ public:
virtual bool getRootTransformInWorld(btTransform& rootTransformInWorld) const =0;
///quick hack: need to rethink the API/dependencies of this
virtual int convertLinkVisualShapes(int linkIndex, const char* pathPrefix, const btTransform& inertialFrame) const = 0;
virtual int convertLinkVisualShapes(int linkIndex, const char* pathPrefix, const btTransform& inertialFrame) const { return -1;}
virtual void convertLinkVisualShapes2(int linkIndex, const char* pathPrefix, const btTransform& inertialFrame, class btCollisionObject* colObj) const { }
virtual class btCompoundShape* convertLinkCollisionShapes(int linkIndex, const char* pathPrefix, const btTransform& localInertiaFrame) const = 0;
virtual class btCompoundShape* convertLinkCollisionShapes(int linkIndex, const char* pathPrefix, const btTransform& localInertiaFrame) const = 0;
};
#endif //URDF_IMPORTER_INTERFACE_H

View File

@@ -186,6 +186,7 @@ public:
{
return m_sdfModels.size();
}
return 0;
}
void activateModel(int modelIndex);

View File

@@ -23,6 +23,7 @@ subject to the following restrictions:
#include "../Importers/ImportURDFDemo/BulletUrdfImporter.h"
#include "../Importers/ImportURDFDemo/URDF2Bullet.h"
#include "../Importers/ImportURDFDemo/MyMultiBodyCreator.h"
#include "../CommonInterfaces/CommonMultiBodyBase.h"
#include "btBulletDynamicsCommon.h"
@@ -85,10 +86,10 @@ public:
virtual void resetCamera()
{
float dist = 3.5;
float pitch = -136;
float yaw = 28;
float targetPos[3]={0.47,0,-0.64};
float dist = 1.5;
float pitch = -80;
float yaw = 10;
float targetPos[3]={0,0,0};
m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
}
};
@@ -150,10 +151,12 @@ void InverseDynamicsExample::initPhysics()
switch (m_option)
{
case 0:
case BT_ID_LOAD_URDF:
{
BulletURDFImporter u2b(m_guiHelper);
BulletURDFImporter u2b(m_guiHelper,0);
bool loadOk = u2b.loadURDF("kuka_lwr/kuka.urdf");
if (loadOk)
{
@@ -235,7 +238,7 @@ void InverseDynamicsExample::initPhysics()
}
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
@@ -343,4 +346,4 @@ CommonExampleInterface* InverseDynamicsExampleCreateFunc(CommonExampleOptions
B3_STANDALONE_EXAMPLE(InverseDynamicsExampleCreateFunc)
B3_STANDALONE_EXAMPLE(InverseDynamicsExampleCreateFunc)

View File

@@ -18,8 +18,8 @@ subject to the following restrictions:
enum btInverseDynamicsExampleOptions
{
BT_ID_LOAD_URDF=1,
BT_ID_PROGRAMMATICALLY=2
BT_ID_LOAD_URDF=0,
BT_ID_PROGRAMMATICALLY=1
};
class CommonExampleInterface* InverseDynamicsExampleCreateFunc(struct CommonExampleOptions& options);

View File

@@ -162,3 +162,55 @@ if os.is("MacOSX") then
links{"Cocoa.framework"}
end
project "App_InverseDynamicsExampleTinyRenderer"
if _OPTIONS["ios"] then
kind "WindowedApp"
else
kind "ConsoleApp"
end
defines {"B3_USE_STANDALONE_EXAMPLE"}
includedirs {"../../src"}
links {
"BulletInverseDynamicsUtils", "BulletInverseDynamics","BulletDynamics","BulletCollision", "LinearMath", "Bullet3Common"
}
language "C++"
files {
"InverseDynamicsExample.cpp",
"*.h",
"../StandaloneMain/main_tinyrenderer_single_example.cpp",
"../OpenGLWindow/SimpleCamera.cpp",
"../ExampleBrowser/CollisionShape2TriangleMesh.cpp",
"../TinyRenderer/geometry.cpp",
"../TinyRenderer/model.cpp",
"../TinyRenderer/tgaimage.cpp",
"../TinyRenderer/our_gl.cpp",
"../TinyRenderer/TinyRenderer.cpp",
"../Utils/b3ResourcePath.cpp",
"../Utils/b3ResourcePath.cpp",
"../Utils/b3ResourcePath.h",
"../RenderingExamples/TimeSeriesCanvas.cpp",
"../RenderingExamples/TimeSeriesFontData.cpp",
"../MultiBody/InvertedPendulumPDControl.cpp",
"../ThirdPartyLibs/tinyxml/tinystr.cpp",
"../ThirdPartyLibs/tinyxml/tinyxml.cpp",
"../ThirdPartyLibs/tinyxml/tinyxmlerror.cpp",
"../ThirdPartyLibs/tinyxml/tinyxmlparser.cpp",
"../ThirdPartyLibs/Wavefront/tiny_obj_loader.cpp",
"../ThirdPartyLibs/Wavefront/tiny_obj_loader.h",
"../Importers/ImportColladaDemo/LoadMeshFromCollada.cpp",
"../Importers/ImportObjDemo/LoadMeshFromObj.cpp",
"../Importers/ImportObjDemo/Wavefront2GLInstanceGraphicsShape.cpp",
"../Importers/ImportURDFDemo/BulletUrdfImporter.cpp",
"../Importers/ImportURDFDemo/MyMultiBodyCreator.cpp",
"../Importers/ImportURDFDemo/URDF2Bullet.cpp",
"../Importers/ImportURDFDemo/UrdfParser.cpp",
"../Importers/ImportURDFDemo/urdfStringSplit.cpp",
}

View File

@@ -19,7 +19,7 @@ subject to the following restrictions:
bool useShadowMap=true;//false;//true;
int shadowMapWidth=8192;
int shadowMapHeight=8192;
float shadowMapWorldSize=10;
float shadowMapWorldSize=50;
#define MAX_POINTS_IN_BATCH 1024
#define MAX_LINES_IN_BATCH 1024

View File

@@ -16,7 +16,8 @@ struct SimpleCameraInternalData
m_pitch(0),
m_aspect(1),
m_frustumZNear(0.01),
m_frustumZFar(1000)
m_frustumZFar(1000),
m_enableVR(false)
{
}
b3Vector3 m_cameraTargetPosition;
@@ -32,6 +33,11 @@ struct SimpleCameraInternalData
float m_aspect;
float m_frustumZNear;
float m_frustumZFar;
bool m_enableVR;
float m_viewMatrixVR[16];
float m_projectionMatrixVR[16];
};
@@ -46,7 +52,15 @@ SimpleCamera::~SimpleCamera()
delete m_data;
}
void SimpleCamera::setVRCamera(const float viewMat[16], const float projectionMatrix[16])
{
m_data->m_enableVR = true;
for (int i=0;i<16;i++)
{
m_data->m_viewMatrixVR[i] = viewMat[i];
m_data->m_projectionMatrixVR[i] = projectionMatrix[i];
}
}
static void b3CreateFrustum(
@@ -171,7 +185,7 @@ void SimpleCamera::update()
break;
default:
{
b3Assert(0);
//b3Assert(0);
return;
}
};
@@ -209,11 +223,29 @@ void SimpleCamera::update()
void SimpleCamera::getCameraProjectionMatrix(float projectionMatrix[16]) const
{
b3CreateFrustum(-m_data->m_aspect * m_data->m_frustumZNear, m_data->m_aspect * m_data->m_frustumZNear, -m_data->m_frustumZNear,m_data->m_frustumZNear, m_data->m_frustumZNear, m_data->m_frustumZFar,projectionMatrix);
if (m_data->m_enableVR)
{
for (int i=0;i<16;i++)
{
projectionMatrix[i] = m_data->m_projectionMatrixVR[i];
}
} else
{
b3CreateFrustum(-m_data->m_aspect * m_data->m_frustumZNear, m_data->m_aspect * m_data->m_frustumZNear, -m_data->m_frustumZNear,m_data->m_frustumZNear, m_data->m_frustumZNear, m_data->m_frustumZFar,projectionMatrix);
}
}
void SimpleCamera::getCameraViewMatrix(float viewMatrix[16]) const
{
b3CreateLookAt(m_data->m_cameraPosition,m_data->m_cameraTargetPosition,m_data->m_cameraUp,viewMatrix);
if (m_data->m_enableVR)
{
for (int i=0;i<16;i++)
{
viewMatrix[i] = m_data->m_viewMatrixVR[i];
}
} else
{
b3CreateLookAt(m_data->m_cameraPosition,m_data->m_cameraTargetPosition,m_data->m_cameraUp,viewMatrix);
}
}
void SimpleCamera::getCameraTargetPosition(double pos[3]) const

View File

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

View File

@@ -18,6 +18,7 @@ public:
virtual void swapBuffer();
virtual void drawText( const char* txt, int posX, int posY);
virtual void drawTexturedRect(float x0, float y0, float x1, float y1, float color[4], float u0,float v0, float u1, float v1, int useRGBA){};
virtual void setBackgroundColor(float red, float green, float blue);
virtual int registerCubeShape(float halfExtentsX,float halfExtentsY, float halfExtentsZ, int textureIndex = -1, float textureScaling = 1)
{

View File

@@ -425,6 +425,18 @@ void SimpleOpenGL3App::drawText( const char* txt, int posXi, int posYi)
glDisable(GL_BLEND);
}
void SimpleOpenGL3App::drawTexturedRect(float x0, float y0, float x1, float y1, float color[4], float u0,float v0, float u1, float v1, int useRGBA)
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
m_primRenderer->drawTexturedRect(x0,y0,x1,y1,color,u0,v0,u1,v1,useRGBA);
glDisable(GL_BLEND);
}
struct GfxVertex
{
float x,y,z,w;
@@ -645,6 +657,20 @@ SimpleOpenGL3App::~SimpleOpenGL3App()
delete m_data ;
}
void SimpleOpenGL3App::getScreenPixels(unsigned char* rgbaBuffer, int bufferSizeInBytes)
{
int width = (int)m_window->getRetinaScale()*m_instancingRenderer->getScreenWidth();
int height = (int)m_window->getRetinaScale()*m_instancingRenderer->getScreenHeight();
if ((width*height*4) == bufferSizeInBytes)
{
glReadPixels(0,0,width, height, GL_RGBA, GL_UNSIGNED_BYTE, rgbaBuffer);
int glstat = glGetError();
b3Assert(glstat==GL_NO_ERROR);
}
}
//#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
static void writeTextureToFile(int textureWidth, int textureHeight, const char* fileName, FILE* ffmpegVideo)

View File

@@ -24,6 +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 drawGrid(DrawGridData data=DrawGridData());
virtual void setUpAxis(int axis);
@@ -32,6 +33,7 @@ struct SimpleOpenGL3App : public CommonGraphicsApp
virtual void swapBuffer();
virtual void drawText( const char* txt, int posX, int posY);
virtual void drawText3D( const char* txt, float posX, float posZY, float posZ, float size);
virtual void drawTexturedRect(float x0, float y0, float x1, float y1, float color[4], float u0,float v0, float u1, float v1, int useRGBA);
struct sth_stash* getFontStash();

View File

@@ -718,15 +718,6 @@ void Win32Window::runMainLoop()
void Win32Window::startRendering()
{
pumpMessage();
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); //clear buffers
//glCullFace(GL_BACK);
//glFrontFace(GL_CCW);
// glEnable(GL_DEPTH_TEST);
}

View File

@@ -6,25 +6,91 @@
#include "Bullet3Common/b3AlignedObjectArray.h"
#include "../CommonInterfaces/CommonRenderInterface.h"
#include "../TinyRenderer/TinyRenderer.h"
#include "../CommonInterfaces/Common2dCanvasInterface.h"
//#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
//#include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h"
//#include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h"
#include "../CommonInterfaces/CommonExampleInterface.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "btBulletCollisionCommon.h"
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
#include "../ExampleBrowser/CollisionShape2TriangleMesh.h"
#include "../Importers/ImportMeshUtility/b3ImportMeshUtility.h"
#include "../OpenGLWindow/GLInstanceGraphicsShape.h"
#include "../CommonInterfaces/CommonParameterInterface.h"
struct TinyRendererSetupInternalData
{
TGAImage m_rgbColorBuffer;
b3AlignedObjectArray<float> m_depthBuffer;
int m_width;
int m_height;
btAlignedObjectArray<btConvexShape*> m_shapePtr;
btAlignedObjectArray<btTransform> m_transforms;
btAlignedObjectArray<TinyRenderObjectData*> m_renderObjects;
btVoronoiSimplexSolver m_simplexSolver;
btScalar m_pitch;
btScalar m_roll;
btScalar m_yaw;
int m_textureHandle;
int m_animateRenderer;
TinyRendererSetupInternalData(int width, int height)
:m_roll(0),
m_pitch(0),
m_yaw(0),
m_width(width),
m_height(height),
m_rgbColorBuffer(width,height,TGAImage::RGB),
m_textureHandle(0),
m_animateRenderer(0)
{
m_depthBuffer.resize(m_width*m_height);
}
void updateTransforms()
{
int numObjects = m_shapePtr.size();
m_transforms.resize(numObjects);
for (int i=0;i<numObjects;i++)
{
m_transforms[i].setIdentity();
//btVector3 pos(0.f,-(2.5* numObjects * 0.5)+i*2.5f, 0.f);
btVector3 pos(0.f,+i*2.5f, 0.f);
m_transforms[i].setIdentity();
m_transforms[i].setOrigin( pos );
btQuaternion orn;
if (i < 2)
{
orn.setEuler(m_yaw,m_pitch,m_roll);
m_transforms[i].setRotation(orn);
}
}
if (m_animateRenderer)
{
m_pitch += 0.005f;
m_yaw += 0.01f;
}
}
};
struct TinyRendererSetup : public CommonExampleInterface
{
struct GUIHelperInterface* m_guiHelper;
struct CommonGraphicsApp* m_app;
struct TinyRendererSetupInternalData* m_internalData;
bool m_useSoftware;
TinyRendererSetup(struct CommonGraphicsApp* app);
TinyRendererSetup(struct GUIHelperInterface* guiHelper);
virtual ~TinyRendererSetup();
@@ -48,204 +114,261 @@ struct TinyRendererSetup : public CommonExampleInterface
virtual void renderScene()
{
}
void animateRenderer(int animateRendererIndex)
{
m_internalData->m_animateRenderer = animateRendererIndex;
}
void selectRenderer(int rendererIndex)
{
m_useSoftware = (rendererIndex==0);
}
void resetCamera()
{
float dist = 11;
float pitch = 52;
float yaw = 35;
float targetPos[3]={0,0.46,0};
m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
}
};
struct TinyRendererSetupInternalData
TinyRendererSetup::TinyRendererSetup(struct GUIHelperInterface* gui)
{
int m_canvasIndex;
struct Common2dCanvasInterface* m_canvas;
TGAImage m_rgbColorBuffer;
b3AlignedObjectArray<float> m_depthBuffer;
int m_width;
int m_height;
btAlignedObjectArray<btConvexShape*> m_shapePtr;
btAlignedObjectArray<btTransform> m_transforms;
btAlignedObjectArray<TinyRenderObjectData*> m_renderObjects;
btVoronoiSimplexSolver m_simplexSolver;
btScalar m_pitch;
btScalar m_roll;
btScalar m_yaw;
m_useSoftware = false;
m_guiHelper = gui;
m_app = gui->getAppInterface();
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";
TinyRendererSetupInternalData(int width, int height)
:m_canvasIndex(-1),
m_canvas(0),
m_roll(0),
m_pitch(0),
m_yaw(0),
m_width(width),
m_height(height),
m_rgbColorBuffer(width,height,TGAImage::RGB)
{
btConeShape* cone = new btConeShape(1,1);
btSphereShape* sphere = new btSphereShape(1);
btBoxShape* box = new btBoxShape (btVector3(1,1,1));
m_shapePtr.push_back(cone);
m_shapePtr.push_back(sphere);
m_shapePtr.push_back(box);
m_depthBuffer.resize(m_width*m_height);
for (int i=0;i<m_shapePtr.size();i++)
{
TinyRenderObjectData* ob = new TinyRenderObjectData(m_width,m_height,m_rgbColorBuffer,m_depthBuffer);
btAlignedObjectArray<btVector3> vertexPositions;
btAlignedObjectArray<btVector3> vertexNormals;
btAlignedObjectArray<int> indicesOut;
btTransform ident;
ident.setIdentity();
CollisionShape2TriangleMesh(m_shapePtr[i],ident,vertexPositions,vertexNormals,indicesOut);
m_renderObjects.push_back(ob);
ob->registerMesh2(vertexPositions,vertexNormals,indicesOut);
}
//ob->registerMeshShape(
updateTransforms();
}
void updateTransforms()
{
int numObjects = m_shapePtr.size();
m_transforms.resize(numObjects);
for (int i=0;i<numObjects;i++)
{
m_transforms[i].setIdentity();
btVector3 pos(0.f,-(2.5* numObjects * 0.5)+i*2.5f, 0.f);
m_transforms[i].setIdentity();
m_transforms[i].setOrigin( pos );
btQuaternion orn;
if (i < 2)
int shapeId = -1;
b3ImportMeshData meshData;
if (b3ImportMeshUtility::loadAndRegisterMeshFromFileInternal(fileName, meshData))
{
orn.setEuler(m_yaw,m_pitch,m_roll);
m_transforms[i].setRotation(orn);
int textureIndex = -1;
if (meshData.m_textureImage)
{
textureIndex = m_guiHelper->getRenderInterface()->registerTexture(meshData.m_textureImage,meshData.m_textureWidth,meshData.m_textureHeight);
}
shapeId = m_guiHelper->getRenderInterface()->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);
float position[4]={0,0,0,1};
float orn[4]={0,0,0,1};
float color[4]={1,1,1,1};
float scaling[4]={1,1,1,1};
m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId,position,orn,color,scaling);
m_guiHelper->getRenderInterface()->writeTransforms();
m_internalData->m_shapePtr.push_back(0);
TinyRenderObjectData* ob = new TinyRenderObjectData(m_internalData->m_width,m_internalData->m_height,
m_internalData->m_rgbColorBuffer,
m_internalData->m_depthBuffer);
//ob->loadModel("cube.obj");
const int* indices = &meshData.m_gfxShape->m_indices->at(0);
ob->registerMeshShape(&meshData.m_gfxShape->m_vertices->at(0).xyzw[0],
meshData.m_gfxShape->m_numvertices,
indices,
meshData.m_gfxShape->m_numIndices,color, meshData.m_textureImage,meshData.m_textureWidth,meshData.m_textureHeight);
m_internalData->m_renderObjects.push_back(ob);
delete meshData.m_gfxShape;
delete meshData.m_textureImage;
}
}
m_pitch += 0.005f;
m_yaw += 0.01f;
}
};
TinyRendererSetup::TinyRendererSetup(struct CommonGraphicsApp* app)
{
m_app = app;
m_internalData = new TinyRendererSetupInternalData(128,128);
}
TinyRendererSetup::~TinyRendererSetup()
{
m_app->m_renderer->enableBlend(false);
delete m_internalData;
}
const char* itemsanimate[] = {"Fixed", "Rotate"};
void TinyRendererComboCallbackAnimate(int combobox, const char* item, void* userPointer)
{
TinyRendererSetup* cl = (TinyRendererSetup*) userPointer;
b3Assert(cl);
int index=-1;
int numItems = sizeof(itemsanimate)/sizeof(char*);
for (int i=0;i<numItems;i++)
{
if (!strcmp(item,itemsanimate[i]))
{
index = i;
}
}
cl->animateRenderer(index);
}
const char* items[] = {"Software", "OpenGL"};
void TinyRendererComboCallback(int combobox, const char* item, void* userPointer)
{
TinyRendererSetup* cl = (TinyRendererSetup*) userPointer;
b3Assert(cl);
int index=-1;
int numItems = sizeof(items)/sizeof(char*);
for (int i=0;i<numItems;i++)
{
if (!strcmp(item,items[i]))
{
index = i;
}
}
cl->selectRenderer(index);
}
void TinyRendererSetup::initPhysics()
{
//request a visual bitma/texture we can render to
m_app->setUpAxis(2);
m_internalData->m_canvas = m_app->m_2dCanvasInterface;
CommonRenderInterface* render = m_app->m_renderer;
m_internalData->m_textureHandle = render->registerTexture(m_internalData->m_rgbColorBuffer.buffer(),m_internalData->m_width,m_internalData->m_height);
{
ComboBoxParams comboParams;
comboParams.m_userPointer = this;
comboParams.m_numItems=sizeof(items)/sizeof(char*);
comboParams.m_startItem = 1;
comboParams.m_items=items;
comboParams.m_callback =TinyRendererComboCallback;
m_guiHelper->getParameterInterface()->registerComboBox( comboParams);
}
if (m_internalData->m_canvas)
{
m_internalData->m_canvasIndex = m_internalData->m_canvas->createCanvas("tinyrenderer",m_internalData->m_width,m_internalData->m_height);
for (int i=0;i<m_internalData->m_width;i++)
{
for (int j=0;j<m_internalData->m_height;j++)
{
unsigned char red=255;
unsigned char green=255;
unsigned char blue=255;
unsigned char alpha=255;
m_internalData->m_canvas->setPixel(m_internalData->m_canvasIndex,i,j,red,green,blue,alpha);
}
}
m_internalData->m_canvas->refreshImageData(m_internalData->m_canvasIndex);
//int bitmapId = gfxBridge.createRenderBitmap(width,height);
}
{
ComboBoxParams comboParams;
comboParams.m_userPointer = this;
comboParams.m_numItems=sizeof(itemsanimate)/sizeof(char*);
comboParams.m_startItem = 0;
comboParams.m_items=itemsanimate;
comboParams.m_callback =TinyRendererComboCallbackAnimate;
m_guiHelper->getParameterInterface()->registerComboBox( comboParams);
}
}
void TinyRendererSetup::exitPhysics()
{
if (m_internalData->m_canvas && m_internalData->m_canvasIndex>=0)
{
m_internalData->m_canvas->destroyCanvas(m_internalData->m_canvasIndex);
}
}
void TinyRendererSetup::stepSimulation(float deltaTime)
{
m_internalData->updateTransforms();
TGAColor clearColor;
clearColor.bgra[0] = 255;
clearColor.bgra[1] = 255;
clearColor.bgra[2] = 255;
clearColor.bgra[3] = 255;
for(int y=0;y<m_internalData->m_height;++y)
{
for(int x=0;x<m_internalData->m_width;++x)
{
m_internalData->m_rgbColorBuffer.set(x,y,clearColor);
m_internalData->m_depthBuffer[x+y*m_internalData->m_width] = -1e30f;
}
}
m_internalData->updateTransforms();
if (!m_useSoftware)
{
for (int i=0;i<m_internalData->m_transforms.size();i++)
{
m_guiHelper->getRenderInterface()->writeSingleInstanceTransformToCPU(m_internalData->m_transforms[i].getOrigin(),m_internalData->m_transforms[i].getRotation(),i);
}
m_guiHelper->getRenderInterface()->writeTransforms();
m_guiHelper->getRenderInterface()->renderScene();
} else
{
TGAColor clearColor;
clearColor.bgra[0] = 200;
clearColor.bgra[1] = 200;
clearColor.bgra[2] = 200;
clearColor.bgra[3] = 255;
for(int y=0;y<m_internalData->m_height;++y)
{
for(int x=0;x<m_internalData->m_width;++x)
{
m_internalData->m_rgbColorBuffer.set(x,y,clearColor);
m_internalData->m_depthBuffer[x+y*m_internalData->m_width] = -1e30f;
}
}
ATTRIBUTE_ALIGNED16(btScalar modelMat2[16]);
ATTRIBUTE_ALIGNED16(float viewMat[16]);
CommonRenderInterface* render = this->m_app->m_renderer;
render->getActiveCamera()->getCameraViewMatrix(viewMat);
ATTRIBUTE_ALIGNED16(btScalar modelMat2[16]);
ATTRIBUTE_ALIGNED16(float viewMat[16]);
ATTRIBUTE_ALIGNED16(float projMat[16]);
CommonRenderInterface* render = this->m_app->m_renderer;
render->getActiveCamera()->getCameraViewMatrix(viewMat);
render->getActiveCamera()->getCameraProjectionMatrix(projMat);
for (int o=0;o<this->m_internalData->m_renderObjects.size();o++)
{
const btTransform& tr = m_internalData->m_transforms[o];
tr.getOpenGLMatrix(modelMat2);
for (int i=0;i<4;i++)
{
for (int j=0;j<4;j++)
{
m_internalData->m_renderObjects[o]->m_modelMatrix[i][j] = float(modelMat2[i+4*j]);
m_internalData->m_renderObjects[o]->m_viewMatrix[i][j] = viewMat[i+4*j];
}
}
TinyRenderer::renderObject(*m_internalData->m_renderObjects[o]);
}
for(int y=0;y<m_internalData->m_height;++y)
{
for(int x=0;x<m_internalData->m_width;++x)
{
const TGAColor& color = m_internalData->m_rgbColorBuffer.get(x,y);
m_internalData->m_canvas->setPixel(m_internalData->m_canvasIndex,x,(m_internalData->m_height-1-y),
color.bgra[2],color.bgra[1],color.bgra[0],255);
}
}
//m_internalData->m_canvas->setPixel(m_internalData->m_canvasIndex,x,y,255,0,0,255);
m_internalData->m_canvas->refreshImageData(m_internalData->m_canvasIndex);
for (int o=0;o<this->m_internalData->m_renderObjects.size();o++)
{
const btTransform& tr = m_internalData->m_transforms[o];
tr.getOpenGLMatrix(modelMat2);
for (int i=0;i<4;i++)
{
for (int j=0;j<4;j++)
{
m_internalData->m_renderObjects[o]->m_modelMatrix[i][j] = float(modelMat2[i+4*j]);
m_internalData->m_renderObjects[o]->m_viewMatrix[i][j] = viewMat[i+4*j];
m_internalData->m_renderObjects[o]->m_projectionMatrix[i][j] = projMat[i+4*j];
btVector3 lightDirWorld;
switch (m_app->getUpAxis())
{
case 1:
lightDirWorld = btVector3(-50.f,100,30);
break;
case 2:
lightDirWorld = btVector3(-50.f,30,100);
break;
default:{}
};
m_internalData->m_renderObjects[o]->m_lightDirWorld = lightDirWorld.normalized();
}
}
TinyRenderer::renderObject(*m_internalData->m_renderObjects[o]);
}
//m_app->drawText("hello",500,500);
render->activateTexture(m_internalData->m_textureHandle);
render->updateTexture(m_internalData->m_textureHandle,m_internalData->m_rgbColorBuffer.buffer());
float color[4] = {1,1,1,1};
m_app->drawTexturedRect(0,0,m_app->m_window->getWidth(), m_app->m_window->getHeight(),color,0,0,1,1,true);
}
}
@@ -275,5 +398,5 @@ void TinyRendererSetup::syncPhysicsToGraphics(GraphicsPhysicsBridge& gfxBridge)
CommonExampleInterface* TinyRendererCreateFunc(struct CommonExampleOptions& options)
{
return new TinyRendererSetup(options.m_guiHelper->getAppInterface());
return new TinyRendererSetup(options.m_guiHelper);
}

View File

@@ -37,6 +37,9 @@ public:
virtual const float* getDebugLinesFrom() const = 0;
virtual const float* getDebugLinesTo() const = 0;
virtual const float* getDebugLinesColor() const = 0;
virtual void getCachedCameraImage(struct b3CameraImageData* cameraData)=0;
};
#endif // BT_PHYSICS_CLIENT_API_H

View File

@@ -676,3 +676,41 @@ void b3GetDebugLines(b3PhysicsClientHandle physClient, struct b3DebugLines* l
}
}
///request an image from a simulated camera, using a software renderer.
b3SharedMemoryCommandHandle b3InitRequestCameraImage(b3PhysicsClientHandle physClient)
{
PhysicsClient* cl = (PhysicsClient* ) physClient;
b3Assert(cl);
b3Assert(cl->canSubmitCommand());
struct SharedMemoryCommand* command = cl->getAvailableSharedMemoryCommand();
b3Assert(command);
command->m_type =CMD_REQUEST_CAMERA_IMAGE_DATA;
command->m_requestPixelDataArguments.m_startPixelIndex = 0;
command->m_updateFlags = 0;//REQUEST_PIXEL_ARGS_USE_HARDWARE_OPENGL;
return (b3SharedMemoryCommandHandle) command;
}
void b3RequestCameraImageSetCameraMatrices(b3SharedMemoryCommandHandle commandHandle, float viewMatrix[16], float projectionMatrix[16])
{
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] = projectionMatrix[i];
command->m_requestPixelDataArguments.m_viewMatrix[i] = viewMatrix[i];
}
command->m_updateFlags |= REQUEST_PIXEL_ARGS_HAS_CAMERA_MATRICES;
}
void b3GetCameraImageData(b3PhysicsClientHandle physClient, struct b3CameraImageData* imageData)
{
PhysicsClient* cl = (PhysicsClient* ) physClient;
if (cl)
{
cl->getCachedCameraImage(imageData);
}
}

View File

@@ -64,7 +64,12 @@ b3SharedMemoryCommandHandle b3InitRequestDebugLinesCommand(b3PhysicsClientHandle
///Get the pointers to the debug line information, after b3InitRequestDebugLinesCommand returns
///status CMD_DEBUG_LINES_COMPLETED
void b3GetDebugLines(b3PhysicsClientHandle physClient, struct b3DebugLines* lines);
///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 b3GetCameraImageData(b3PhysicsClientHandle physClient, struct b3CameraImageData* imageData);
b3SharedMemoryCommandHandle b3InitPhysicsParamCommand(b3PhysicsClientHandle physClient);
int b3PhysicsParamSetGravity(b3SharedMemoryCommandHandle commandHandle, double gravx,double gravy, double gravz);

View File

@@ -2,7 +2,7 @@
#include "PhysicsClientExample.h"
#include "../CommonInterfaces/CommonMultiBodyBase.h"
#include "../CommonInterfaces/Common2dCanvasInterface.h"
#include "SharedMemoryCommon.h"
#include "../CommonInterfaces/CommonParameterInterface.h"
#include "PhysicsClientC_API.h"
@@ -11,7 +11,7 @@
#include "PhysicsLoopBackC_API.h"
#include "PhysicsDirectC_API.h"
#include "PhysicsClientC_API.h"
#include "PhysicsServerSharedMemory.h"
struct MyMotorInfo2
{
btScalar m_velTarget;
@@ -21,6 +21,9 @@ struct MyMotorInfo2
int m_qIndex;
};
int camVisualizerWidth = 640;//1024/3;
int camVisualizerHeight = 480;//768/3;
#define MAX_NUM_MOTORS 128
@@ -28,25 +31,34 @@ class PhysicsClientExample : public SharedMemoryCommon
{
protected:
b3PhysicsClientHandle m_physicsClientHandle;
//this m_physicsServer is only used when option eCLIENTEXAMPLE_SERVER is enabled
PhysicsServerSharedMemory m_physicsServer;
bool m_wantsTermination;
btAlignedObjectArray<int> m_userCommandRequests;
int m_sharedMemoryKey;
int m_selectedBody;
int m_prevSelectedBody;
struct Common2dCanvasInterface* m_canvas;
int m_canvasIndex;
void createButton(const char* name, int id, bool isTrigger );
void createButtons();
public:
//@todo, add accessor methods
// MyMotorInfo2 m_motorTargetVelocities[MAX_NUM_MOTORS];
MyMotorInfo2 m_motorTargetPositions[MAX_NUM_MOTORS];
int m_numMotors;
int m_options;
bool m_isOptionalServerConnected;
PhysicsClientExample(GUIHelperInterface* helper);
public:
PhysicsClientExample(GUIHelperInterface* helper, int options);
virtual ~PhysicsClientExample();
virtual void initPhysics();
@@ -93,6 +105,11 @@ public:
virtual void exitPhysics(){};
virtual void renderScene()
{
if (m_options == eCLIENTEXAMPLE_SERVER)
{
m_physicsServer.renderScene();
}
b3DebugLines debugLines;
b3GetDebugLines(m_physicsClientHandle,&debugLines);
int numLines = debugLines.m_numDebugLines;
@@ -153,7 +170,13 @@ public:
b3JointControlSetMaximumForce(commandHandle,uIndex,1000);
}
}
virtual void physicsDebugDraw(int debugFlags){}
virtual void physicsDebugDraw(int debugFlags)
{
if (m_options==eCLIENTEXAMPLE_SERVER)
{
m_physicsServer.physicsDebugDraw(debugFlags);
}
}
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;}
@@ -218,6 +241,20 @@ void PhysicsClientExample::prepareAndSubmitCommand(int commandId)
break;
}
case CMD_REQUEST_CAMERA_IMAGE_DATA:
{
///request an image from a simulated camera, using a software renderer.
b3SharedMemoryCommandHandle commandHandle = b3InitRequestCameraImage(m_physicsClientHandle);
float viewMatrix[16];
float projectionMatrix[16];
this->m_guiHelper->getRenderInterface()->getActiveCamera()->getCameraProjectionMatrix(projectionMatrix);
this->m_guiHelper->getRenderInterface()->getActiveCamera()->getCameraViewMatrix(viewMatrix);
b3RequestCameraImageSetCameraMatrices(commandHandle, viewMatrix,projectionMatrix);
b3SubmitClientCommand(m_physicsClientHandle, commandHandle);
break;
}
case CMD_CREATE_BOX_COLLISION_SHAPE:
{
b3SharedMemoryCommandHandle commandHandle = b3CreateBoxShapeCommandInit(m_physicsClientHandle);
@@ -352,7 +389,7 @@ void PhysicsClientExample::prepareAndSubmitCommand(int commandId)
case CMD_SEND_PHYSICS_SIMULATION_PARAMETERS: {
b3SharedMemoryCommandHandle commandHandle = b3InitPhysicsParamCommand(m_physicsClientHandle);
b3PhysicsParamSetGravity(commandHandle, 0.0, 0.0, -9.8);
b3SubmitClientCommandAndWaitStatus(m_physicsClientHandle, commandHandle);
b3SubmitClientCommand(m_physicsClientHandle, commandHandle);
break;
}
default:
@@ -365,14 +402,17 @@ void PhysicsClientExample::prepareAndSubmitCommand(int commandId)
PhysicsClientExample::PhysicsClientExample(GUIHelperInterface* helper)
PhysicsClientExample::PhysicsClientExample(GUIHelperInterface* helper, int options)
:SharedMemoryCommon(helper),
m_physicsClientHandle(0),
m_wantsTermination(false),
m_sharedMemoryKey(SHARED_MEMORY_KEY),
m_selectedBody(-1),
m_prevSelectedBody(-1),
m_numMotors(0)
m_numMotors(0),
m_options(options),
m_isOptionalServerConnected(false),
m_canvas(0)
{
b3Printf("Started PhysicsClientExample\n");
}
@@ -384,6 +424,12 @@ PhysicsClientExample::~PhysicsClientExample()
b3ProcessServerStatus(m_physicsClientHandle);
b3DisconnectSharedMemory(m_physicsClientHandle);
}
if (m_options == eCLIENTEXAMPLE_SERVER)
{
bool deInitializeSharedMemory = true;
m_physicsServer.disconnectSharedMemory(deInitializeSharedMemory);
}
b3Printf("~PhysicsClientExample\n");
}
@@ -404,9 +450,13 @@ void PhysicsClientExample::createButtons()
m_guiHelper->getParameterInterface()->removeAllParameters();
createButton("Load URDF",CMD_LOAD_URDF, 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);
createButton("Get State",CMD_REQUEST_ACTUAL_STATE, isTrigger);
if (m_options!=eCLIENTEXAMPLE_SERVER)
{
createButton("Get State",CMD_REQUEST_ACTUAL_STATE, isTrigger);
}
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);
@@ -477,6 +527,39 @@ void PhysicsClientExample::initPhysics()
m_selectedBody = -1;
m_prevSelectedBody = -1;
if (m_options == eCLIENTEXAMPLE_SERVER)
{
m_canvas = m_guiHelper->get2dCanvasInterface();
if (m_canvas)
{
m_canvasIndex = m_canvas->createCanvas("Synthetic Camera",camVisualizerWidth, camVisualizerHeight);
for (int i=0;i<camVisualizerWidth;i++)
{
for (int j=0;j<camVisualizerHeight;j++)
{
unsigned char red=255;
unsigned char green=255;
unsigned char blue=255;
unsigned char alpha=255;
if (i==j)
{
red = 0;
green=0;
blue=0;
}
m_canvas->setPixel(m_canvasIndex,i,j,red,green,blue,alpha);
}
}
m_canvas->refreshImageData(m_canvasIndex);
}
m_isOptionalServerConnected = m_physicsServer.connectSharedMemory( m_guiHelper);
}
m_physicsClientHandle = b3ConnectSharedMemory(m_sharedMemoryKey);
//m_physicsClientHandle = b3ConnectPhysicsLoopback(SHARED_MEMORY_KEY);
//m_physicsClientHandle = b3ConnectPhysicsDirect();
@@ -491,6 +574,15 @@ void PhysicsClientExample::initPhysics()
void PhysicsClientExample::stepSimulation(float deltaTime)
{
if (m_options == eCLIENTEXAMPLE_SERVER)
{
for (int i=0;i<100;i++)
{
m_physicsServer.processClientCommands();
}
}
if (m_prevSelectedBody != m_selectedBody)
{
createButtons();
@@ -509,6 +601,46 @@ void PhysicsClientExample::stepSimulation(float deltaTime)
{
//b3Printf("bla\n");
}
if (statusType ==CMD_CAMERA_IMAGE_COMPLETED)
{
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 j=0;j<imageData.m_pixelHeight;j++)
{
int xIndex = int(float(i)*(float(camVisualizerWidth)/float(imageData.m_pixelWidth)));
int yIndex = int(float(j)*(float(camVisualizerHeight)/float(imageData.m_pixelHeight)));
btClamp(yIndex,0,imageData.m_pixelHeight);
btClamp(xIndex,0,imageData.m_pixelWidth);
int bytesPerPixel = 4;
int pixelIndex = (i+j*imageData.m_pixelWidth)*bytesPerPixel;
m_canvas->setPixel(m_canvasIndex,xIndex,camVisualizerHeight-1-yIndex,
imageData.m_rgbColorData[pixelIndex],
imageData.m_rgbColorData[pixelIndex+1],
imageData.m_rgbColorData[pixelIndex+2],
255);
// imageData.m_rgbColorData[pixelIndex+3]);
}
}
m_canvas->refreshImageData(m_canvasIndex);
}
b3Printf(msg);
}
if (statusType == CMD_CAMERA_IMAGE_FAILED)
{
b3Printf("Camera image FAILED\n");
}
if (statusType == CMD_URDF_LOADING_COMPLETED)
{
int bodyIndex = b3GetStatusBodyIndex(status);
@@ -564,10 +696,29 @@ void PhysicsClientExample::stepSimulation(float deltaTime)
m_selectedBody = -1;
m_numMotors=0;
createButtons();
}
prepareAndSubmitCommand(commandId);
b3SharedMemoryCommandHandle commandHandle = b3InitResetSimulationCommand(m_physicsClientHandle);
if (m_options == eCLIENTEXAMPLE_SERVER)
{
b3SubmitClientCommand(m_physicsClientHandle, commandHandle);
while (!b3CanSubmitCommand(m_physicsClientHandle))
{
m_physicsServer.processClientCommands();
b3SharedMemoryStatusHandle status = b3ProcessServerStatus(m_physicsClientHandle);
bool hasStatus = (status != 0);
if (hasStatus)
{
int statusType = b3GetStatusType(status);
b3Printf("Status after reset: %d",statusType);
}
}
} else
{
prepareAndSubmitCommand(commandId);
}
} else
{
prepareAndSubmitCommand(commandId);
}
} else
{
@@ -575,7 +726,10 @@ void PhysicsClientExample::stepSimulation(float deltaTime)
{
enqueueCommand(CMD_SEND_DESIRED_STATE);
enqueueCommand(CMD_STEP_FORWARD_SIMULATION);
enqueueCommand(CMD_REQUEST_DEBUG_LINES);
if (m_options != eCLIENTEXAMPLE_SERVER)
{
enqueueCommand(CMD_REQUEST_DEBUG_LINES);
}
//enqueueCommand(CMD_REQUEST_ACTUAL_STATE);
}
}
@@ -589,7 +743,7 @@ extern int gSharedMemoryKey;
class CommonExampleInterface* PhysicsClientCreateFunc(struct CommonExampleOptions& options)
{
PhysicsClientExample* example = new PhysicsClientExample(options.m_guiHelper);
PhysicsClientExample* example = new PhysicsClientExample(options.m_guiHelper, options.m_option);
if (gSharedMemoryKey>=0)
{
example->setSharedMemoryKey(gSharedMemoryKey);

View File

@@ -1,6 +1,13 @@
#ifndef PHYSICS_CLIENT_EXAMPLE_H
#define PHYSICS_CLIENT_EXAMPLE_H
enum ClientExampleOptions
{
eCLIENTEXAMPLE_LOOPBACK=1,
eCLIENTEAXMPLE_DIRECT=2,
eCLIENTEXAMPLE_SERVER=3,
};
class CommonExampleInterface* PhysicsClientCreateFunc(struct CommonExampleOptions& options);
#endif//PHYSICS_CLIENT_EXAMPLE_H

View File

@@ -32,6 +32,11 @@ struct PhysicsClientSharedMemoryInternalData {
btAlignedObjectArray<TmpFloat3> m_debugLinesTo;
btAlignedObjectArray<TmpFloat3> m_debugLinesColor;
int m_cachedCameraPixelsWidth;
int m_cachedCameraPixelsHeight;
btAlignedObjectArray<unsigned char> m_cachedCameraPixelsRGBA;
btAlignedObjectArray<float> m_cachedCameraDepthBuffer;
SharedMemoryStatus m_lastServerStatus;
int m_counter;
@@ -46,8 +51,10 @@ struct PhysicsClientSharedMemoryInternalData {
: m_sharedMemory(0),
m_ownsSharedMemory(false),
m_testBlock1(0),
m_counter(0),
m_serverLoadUrdfOK(false),
m_counter(0),
m_cachedCameraPixelsWidth(0),
m_cachedCameraPixelsHeight(0),
m_serverLoadUrdfOK(false),
m_isConnected(false),
m_waitingForServer(false),
m_hasLastServerStatus(false),
@@ -416,6 +423,47 @@ const SharedMemoryStatus* PhysicsClientSharedMemory::processServerStatus() {
break;
}
case CMD_CAMERA_IMAGE_COMPLETED:
{
if (m_data->m_verboseOutput)
{
b3Printf("Camera image OK\n");
}
int numBytesPerPixel = 4;//RGBA
int numTotalPixels = serverCmd.m_sendPixelDataArguments.m_startingPixelIndex+
serverCmd.m_sendPixelDataArguments.m_numPixelsCopied+
serverCmd.m_sendPixelDataArguments.m_numRemainingPixels;
m_data->m_cachedCameraPixelsWidth = 0;
m_data->m_cachedCameraPixelsHeight = 0;
int numPixels = serverCmd.m_sendPixelDataArguments.m_imageWidth*serverCmd.m_sendPixelDataArguments.m_imageHeight;
m_data->m_cachedCameraPixelsRGBA.reserve(numPixels*numBytesPerPixel);
m_data->m_cachedCameraDepthBuffer.resize(numTotalPixels);
m_data->m_cachedCameraPixelsRGBA.resize(numTotalPixels*numBytesPerPixel);
unsigned char* rgbaPixelsReceived =
(unsigned char*)&m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor[0];
printf("pixel = %d\n", rgbaPixelsReceived[0]);
for (int i=0;i<serverCmd.m_sendPixelDataArguments.m_numPixelsCopied*numBytesPerPixel;i++)
{
m_data->m_cachedCameraPixelsRGBA[i + serverCmd.m_sendPixelDataArguments.m_startingPixelIndex*numBytesPerPixel]
= rgbaPixelsReceived[i];
}
break;
}
case CMD_CAMERA_IMAGE_FAILED:
{
b3Printf("Camera image FAILED\n");
break;
}
default: {
b3Error("Unknown server status\n");
@@ -433,6 +481,30 @@ const SharedMemoryStatus* PhysicsClientSharedMemory::processServerStatus() {
m_data->m_waitingForServer = false;
} else {
m_data->m_waitingForServer = true;
}
if (serverCmd.m_type == CMD_CAMERA_IMAGE_COMPLETED)
{
SharedMemoryCommand& command = m_data->m_testBlock1->m_clientCommands[0];
if (serverCmd.m_sendPixelDataArguments.m_numRemainingPixels > 0)
{
// continue requesting remaining pixels
command.m_type = CMD_REQUEST_CAMERA_IMAGE_DATA;
command.m_requestPixelDataArguments.m_startPixelIndex =
serverCmd.m_sendPixelDataArguments.m_startingPixelIndex +
serverCmd.m_sendPixelDataArguments.m_numPixelsCopied;
submitClientCommand(command);
return 0;
} else
{
m_data->m_cachedCameraPixelsWidth = serverCmd.m_sendPixelDataArguments.m_imageWidth;
m_data->m_cachedCameraPixelsHeight = serverCmd.m_sendPixelDataArguments.m_imageHeight;
}
}
if ((serverCmd.m_type == CMD_DEBUG_LINES_COMPLETED) &&
@@ -496,6 +568,14 @@ void PhysicsClientSharedMemory::uploadBulletFileToSharedMemory(const char* data,
}
}
void PhysicsClientSharedMemory::getCachedCameraImage(struct b3CameraImageData* cameraData)
{
cameraData->m_pixelWidth = m_data->m_cachedCameraPixelsWidth;
cameraData->m_pixelHeight = m_data->m_cachedCameraPixelsHeight;
cameraData->m_depthValues = m_data->m_cachedCameraDepthBuffer.size() ? &m_data->m_cachedCameraDepthBuffer[0] : 0;
cameraData->m_rgbColorData = m_data->m_cachedCameraPixelsRGBA.size() ? &m_data->m_cachedCameraPixelsRGBA[0] : 0;
}
const float* PhysicsClientSharedMemory::getDebugLinesFrom() const {
if (m_data->m_debugLinesFrom.size()) {
return &m_data->m_debugLinesFrom[0].m_x;

View File

@@ -45,6 +45,7 @@ public:
virtual const float* getDebugLinesFrom() const;
virtual const float* getDebugLinesTo() const;
virtual const float* getDebugLinesColor() const;
virtual void getCachedCameraImage(struct b3CameraImageData* cameraData);
};
#endif // BT_PHYSICS_CLIENT_API_H

View File

@@ -328,3 +328,14 @@ const float* PhysicsDirect::getDebugLinesColor() const
}
return 0;
}
void PhysicsDirect::getCachedCameraImage(b3CameraImageData* cameraData)
{
if (cameraData)
{
cameraData->m_pixelHeight = 0;
cameraData->m_pixelWidth = 0;
cameraData->m_depthValues = 0;
cameraData->m_rgbColorData = 0;
}
}

View File

@@ -57,6 +57,8 @@ public:
virtual const float* getDebugLinesTo() const;
virtual const float* getDebugLinesColor() const;
virtual void getCachedCameraImage(b3CameraImageData* cameraData);
};
#endif //PHYSICS_DIRECT_H

View File

@@ -113,3 +113,8 @@ const float* PhysicsLoopBack::getDebugLinesColor() const
{
return m_data->m_physicsClient->getDebugLinesColor();
}
void PhysicsLoopBack::getCachedCameraImage(struct b3CameraImageData* cameraData)
{
return m_data->m_physicsClient->getCachedCameraImage(cameraData);
}

View File

@@ -52,6 +52,7 @@ public:
virtual const float* getDebugLinesFrom() const;
virtual const float* getDebugLinesTo() const;
virtual const float* getDebugLinesColor() const;
virtual void getCachedCameraImage(struct b3CameraImageData* cameraData);
};

View File

@@ -4,6 +4,7 @@
#include "../Importers/ImportURDFDemo/BulletUrdfImporter.h"
#include "../Importers/ImportURDFDemo/MyMultiBodyCreator.h"
#include "../Importers/ImportURDFDemo/URDF2Bullet.h"
#include "TinyRendererVisualShapeConverter.h"
#include "BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h"
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
#include "BulletDynamics/Featherstone/btMultiBodyPoint2Point.h"
@@ -287,7 +288,6 @@ struct PhysicsServerCommandProcessorInternalData
///handle management
btAlignedObjectArray<InternalBodyHandle> m_bodyHandles;
int m_numUsedHandles; // number of active handles
int m_firstFreeHandle; // free handles list
InternalBodyHandle* getHandle(int handle)
{
@@ -410,6 +410,7 @@ struct PhysicsServerCommandProcessorInternalData
btVector3 m_hitPos;
btScalar m_oldPickingDist;
bool m_prevCanSleep;
TinyRendererVisualShapeConverter m_visualConverter;
PhysicsServerCommandProcessorInternalData()
:
@@ -691,7 +692,9 @@ bool PhysicsServerCommandProcessor::loadUrdf(const char* fileName, const btVecto
return false;
}
BulletURDFImporter u2b(m_data->m_guiHelper);
BulletURDFImporter u2b(m_data->m_guiHelper, &m_data->m_visualConverter);
bool loadOk = u2b.loadURDF(fileName, useFixedBase);
@@ -962,6 +965,79 @@ bool PhysicsServerCommandProcessor::processCommand(const struct SharedMemoryComm
break;
}
case CMD_REQUEST_CAMERA_IMAGE_DATA:
{
int startPixelIndex = clientCmd.m_requestPixelDataArguments.m_startPixelIndex;
int width, height;
int numPixelsCopied = 0;
if ((clientCmd.m_updateFlags & REQUEST_PIXEL_ARGS_USE_HARDWARE_OPENGL)!=0)
{
m_data->m_guiHelper->copyCameraImageData(0,0,0,0,0,&width,&height,0);
}
else
{
m_data->m_visualConverter.getWidthAndHeight(width,height);
}
int numTotalPixels = width*height;
int numRemainingPixels = numTotalPixels - startPixelIndex;
if (numRemainingPixels>0)
{
int maxNumPixels = bufferSizeInBytes/8-1;
unsigned char* pixelRGBA = (unsigned char*)bufferServerToClient;
int numRequestedPixels = btMin(maxNumPixels,numRemainingPixels);
float* depthBuffer = (float*)(bufferServerToClient+numRequestedPixels*4);
if ((clientCmd.m_updateFlags & REQUEST_PIXEL_ARGS_USE_HARDWARE_OPENGL)!=0)
{
m_data->m_guiHelper->copyCameraImageData(pixelRGBA,numRequestedPixels,depthBuffer,numRequestedPixels,startPixelIndex,&width,&height,&numPixelsCopied);
} else
{
if (clientCmd.m_requestPixelDataArguments.m_startPixelIndex==0)
{
printf("-------------------------------\nRendering\n");
if ((clientCmd.m_updateFlags & REQUEST_PIXEL_ARGS_HAS_CAMERA_MATRICES)!=0)
{
m_data->m_visualConverter.render(
clientCmd.m_requestPixelDataArguments.m_viewMatrix,
clientCmd.m_requestPixelDataArguments.m_projectionMatrix);
} else
{
m_data->m_visualConverter.render();
}
}
m_data->m_visualConverter.copyCameraImageData(pixelRGBA,numRequestedPixels,depthBuffer,numRequestedPixels,startPixelIndex,&width,&height,&numPixelsCopied);
}
//each pixel takes 4 RGBA values and 1 float = 8 bytes
} else
{
}
serverStatusOut.m_type = CMD_CAMERA_IMAGE_COMPLETED;
serverStatusOut.m_sendPixelDataArguments.m_numPixelsCopied = numPixelsCopied;
serverStatusOut.m_sendPixelDataArguments.m_numRemainingPixels = numRemainingPixels - numPixelsCopied;
serverStatusOut.m_sendPixelDataArguments.m_startingPixelIndex = startPixelIndex;
serverStatusOut.m_sendPixelDataArguments.m_imageWidth = width;
serverStatusOut.m_sendPixelDataArguments.m_imageHeight= height;
hasStatus = true;
break;
}
case CMD_LOAD_URDF:
{
@@ -1545,6 +1621,10 @@ bool PhysicsServerCommandProcessor::processCommand(const struct SharedMemoryComm
{
m_data->m_guiHelper->getRenderInterface()->removeAllInstances();
}
if (m_data)
{
m_data->m_visualConverter.resetAll();
}
deleteDynamicsWorld();
createEmptyDynamicsWorld();
m_data->exitHandles();

View File

@@ -19,17 +19,18 @@ class PhysicsServerExample : public SharedMemoryCommon
bool m_isConnected;
btClock m_clock;
bool m_replay;
int m_options;
public:
PhysicsServerExample(GUIHelperInterface* helper, SharedMemoryInterface* sharedMem=0);
PhysicsServerExample(GUIHelperInterface* helper, SharedMemoryInterface* sharedMem=0, int options=0);
virtual ~PhysicsServerExample();
virtual void initPhysics();
virtual void stepSimulation(float deltaTime);
void enableCommandLogging()
{
m_physicsServer.enableCommandLogging(true,"BulletPhysicsCommandLog.bin");
@@ -40,9 +41,9 @@ public:
m_replay = true;
m_physicsServer.replayFromLogFile("BulletPhysicsCommandLog.bin");
}
virtual void resetCamera()
{
float dist = 5;
@@ -51,23 +52,23 @@ public:
float targetPos[3]={0,0,0};//-3,2.8,-2.5};
m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
}
virtual bool wantsTermination();
virtual bool isConnected();
virtual void renderScene();
virtual void exitPhysics(){}
virtual void physicsDebugDraw(int debugFlags);
btVector3 getRayTo(int x,int y);
virtual bool mouseMoveCallback(float x,float y)
{
if (m_replay)
return false;
CommonRenderInterface* renderer = m_guiHelper->getRenderInterface();
if (!renderer)
{
btAssert(0);
@@ -87,16 +88,16 @@ public:
return false;
CommonRenderInterface* renderer = m_guiHelper->getRenderInterface();
if (!renderer)
{
btAssert(0);
return false;
}
CommonWindowInterface* window = m_guiHelper->getAppInterface()->m_window;
if (state==1)
{
if(button==0 && (!window->isModifierKeyPressed(B3G_ALT) && !window->isModifierKeyPressed(B3G_CONTROL) ))
@@ -133,12 +134,13 @@ public:
};
PhysicsServerExample::PhysicsServerExample(GUIHelperInterface* helper, SharedMemoryInterface* sharedMem)
PhysicsServerExample::PhysicsServerExample(GUIHelperInterface* helper, SharedMemoryInterface* sharedMem, int options)
:SharedMemoryCommon(helper),
m_physicsServer(sharedMem),
m_wantsShutdown(false),
m_isConnected(false),
m_replay(false)
m_replay(false),
m_options(options)
{
b3Printf("Started PhysicsServer\n");
}
@@ -164,18 +166,18 @@ void PhysicsServerExample::initPhysics()
m_guiHelper->setUpAxis(upAxis);
#if 0
createEmptyDynamicsWorld();
//todo: create a special debug drawer that will cache the lines, so we can send the debug info over the wire
btVector3 grav(0,0,0);
grav[upAxis] = 0;//-9.8;
this->m_dynamicsWorld->setGravity(grav);
#endif
m_isConnected = m_physicsServer.connectSharedMemory( m_guiHelper);
}
@@ -188,11 +190,7 @@ bool PhysicsServerExample::wantsTermination()
void PhysicsServerExample::stepSimulation(float deltaTime)
{
if (m_replay)
{
for (int i=0;i<100;i++)
m_physicsServer.processClientCommands();
} else
if (m_options == PHYSICS_SERVER_USE_RTC_CLOCK)
{
btClock rtc;
btScalar endTime = rtc.getTimeMilliseconds() + deltaTime*btScalar(800);
@@ -201,6 +199,10 @@ void PhysicsServerExample::stepSimulation(float deltaTime)
{
m_physicsServer.processClientCommands();
}
} else
{
for (int i=0;i<10;i++)
m_physicsServer.processClientCommands();
}
}
@@ -222,7 +224,7 @@ void PhysicsServerExample::physicsDebugDraw(int debugDrawFlags)
btVector3 PhysicsServerExample::getRayTo(int x,int y)
{
CommonRenderInterface* renderer = m_guiHelper->getRenderInterface();
if (!renderer)
{
btAssert(0);
@@ -288,7 +290,7 @@ extern int gSharedMemoryKey;
class CommonExampleInterface* PhysicsServerCreateFunc(struct CommonExampleOptions& options)
{
PhysicsServerExample* example = new PhysicsServerExample(options.m_guiHelper, options.m_sharedMem);
PhysicsServerExample* example = new PhysicsServerExample(options.m_guiHelper, options.m_sharedMem, options.m_option);
if (gSharedMemoryKey>=0)
{
example->setSharedMemoryKey(gSharedMemoryKey);
@@ -302,5 +304,5 @@ class CommonExampleInterface* PhysicsServerCreateFunc(struct CommonExampleOpt
example->replayFromLogFile();
}
return example;
}

View File

@@ -5,6 +5,7 @@ enum PhysicsServerOptions
{
PHYSICS_SERVER_ENABLE_COMMAND_LOGGING=1,
PHYSICS_SERVER_REPLAY_FROM_COMMAND_LOG=2,
PHYSICS_SERVER_USE_RTC_CLOCK = 4,
};
class CommonExampleInterface* PhysicsServerCreateFunc(struct CommonExampleOptions& options);

View File

@@ -113,6 +113,21 @@ struct RequestDebugLinesArgs
int m_startingLineIndex;
};
struct RequestPixelDataArgs
{
float m_viewMatrix[16];
float m_projectionMatrix[16];
int m_startPixelIndex;
};
enum EnumRequestPixelDataUpdateFlags
{
REQUEST_PIXEL_ARGS_HAS_CAMERA_MATRICES=1,
REQUEST_PIXEL_ARGS_USE_HARDWARE_OPENGL=2,
};
struct SendDebugLinesArgs
{
int m_startingLineIndex;
@@ -120,6 +135,16 @@ struct SendDebugLinesArgs
int m_numRemainingDebugLines;
};
struct SendPixelDataArgs
{
int m_imageWidth;
int m_imageHeight;
int m_startingPixelIndex;
int m_numPixelsCopied;
int m_numRemainingPixels;
};
struct PickBodyArgs
{
double m_rayFromWorld[3];
@@ -270,6 +295,7 @@ struct SharedMemoryCommand
struct CreateSensorArgs m_createSensorArguments;
struct CreateBoxShapeArgs m_createBoxShapeArguments;
struct RequestDebugLinesArgs m_requestDebugLinesArguments;
struct RequestPixelDataArgs m_requestPixelDataArguments;
struct PickBodyArgs m_pickBodyArguments;
};
};
@@ -291,6 +317,7 @@ struct SharedMemoryStatus
struct BulletDataStreamArgs m_dataStreamArguments;
struct SendActualStateArgs m_sendActualStateArgs;
struct SendDebugLinesArgs m_sendDebugLinesArgs;
struct SendPixelDataArgs m_sendPixelDataArguments;
struct RigidBodyCreateArgs m_rigidBodyCreateArgs;
};
};

View File

@@ -23,6 +23,7 @@ enum EnumSharedMemoryClientCommand
CMD_PICK_BODY,
CMD_MOVE_PICKED_BODY,
CMD_REMOVE_PICKING_CONSTRAINT_BODY,
CMD_REQUEST_CAMERA_IMAGE_DATA,
CMD_MAX_CLIENT_COMMANDS
};
@@ -48,7 +49,9 @@ enum EnumSharedMemoryServerStatus
CMD_DEBUG_LINES_OVERFLOW_FAILED,
CMD_DESIRED_STATE_RECEIVED_COMPLETED,
CMD_STEP_FORWARD_SIMULATION_COMPLETED,
CMD_RESET_SIMULATION_COMPLETED,
CMD_RESET_SIMULATION_COMPLETED,
CMD_CAMERA_IMAGE_COMPLETED,
CMD_CAMERA_IMAGE_FAILED,
CMD_INVALID_STATUS,
CMD_MAX_SERVER_COMMANDS
};
@@ -105,6 +108,14 @@ struct b3DebugLines
const float* m_linesColor;//float red,green,blue times 'm_numDebugLines'.
};
struct b3CameraImageData
{
int m_pixelWidth;
int m_pixelHeight;
const unsigned char* m_rgbColorData;//3*m_pixelWidth*m_pixelHeight bytes
const float* m_depthValues;//m_pixelWidth*m_pixelHeight floats
};
///b3LinkState provides extra information such as the Cartesian world coordinates
///center of mass (COM) of the link, relative to the world reference frame.
///Orientation is a quaternion x,y,z,w
@@ -127,4 +138,5 @@ enum {
CONTROL_MODE_POSITION_VELOCITY_PD,
};
#endif//SHARED_MEMORY_PUBLIC_H

View File

@@ -0,0 +1,637 @@
/* Copyright (C) 2016 Google
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 "TinyRendererVisualShapeConverter.h"
#include "../Importers/ImportURDFDemo/URDFImporterInterface.h"
#include "btBulletCollisionCommon.h"
#include "../Importers/ImportObjDemo/LoadMeshFromObj.h"
#include "../Importers/ImportSTLDemo/LoadMeshFromSTL.h"
#include "../Importers/ImportColladaDemo/LoadMeshFromCollada.h"
#include "BulletCollision/CollisionShapes/btShapeHull.h"//to create a tesselation of a generic btConvexShape
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
#include "Bullet3Common/b3FileUtils.h"
#include <string>
#include "../Utils/b3ResourcePath.h"
#include "../TinyRenderer/TinyRenderer.h"
#include "../OpenGLWindow/SimpleCamera.h"
#include <iostream>
#include <fstream>
#include "../Importers/ImportURDFDemo/UrdfParser.h"
enum MyFileType
{
MY_FILE_STL=1,
MY_FILE_COLLADA=2,
MY_FILE_OBJ=3,
};
struct TinyRendererObjectArray
{
btAlignedObjectArray< TinyRenderObjectData*> m_renderObjects;
};
#define START_WIDTH 640
#define START_HEIGHT 480
struct TinyRendererVisualShapeConverterInternalData
{
btHashMap<btHashPtr,TinyRendererObjectArray*> m_swRenderInstances;
int m_upAxis;
int m_swWidth;
int m_swHeight;
TGAImage m_rgbColorBuffer;
b3AlignedObjectArray<float> m_depthBuffer;
SimpleCamera m_camera;
TinyRendererVisualShapeConverterInternalData()
:m_upAxis(2),
m_swWidth(START_WIDTH),
m_swHeight(START_HEIGHT),
m_rgbColorBuffer(START_WIDTH,START_HEIGHT,TGAImage::RGB)
{
m_depthBuffer.resize(m_swWidth*m_swHeight);
}
};
TinyRendererVisualShapeConverter::TinyRendererVisualShapeConverter()
{
m_data = new TinyRendererVisualShapeConverterInternalData();
float dist = 1.5;
float pitch = -80;
float yaw = 10;
float targetPos[3]={0,0,0};
m_data->m_camera.setCameraUpAxis(m_data->m_upAxis);
resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
}
TinyRendererVisualShapeConverter::~TinyRendererVisualShapeConverter()
{
delete m_data;
}
void convertURDFToVisualShape(const UrdfVisual* visual, const char* urdfPathPrefix, const btTransform& visualTransform, btAlignedObjectArray<GLInstanceVertex>& verticesOut, btAlignedObjectArray<int>& indicesOut)
{
GLInstanceGraphicsShape* glmesh = 0;
btConvexShape* convexColShape = 0;
switch (visual->m_geometry.m_type)
{
case URDF_GEOM_CYLINDER:
{
btAlignedObjectArray<btVector3> vertices;
//int numVerts = sizeof(barrel_vertices)/(9*sizeof(float));
int numSteps = 32;
for (int i = 0; i<numSteps; i++)
{
btScalar cylRadius = visual->m_geometry.m_cylinderRadius;
btScalar cylLength = visual->m_geometry.m_cylinderLength;
btVector3 vert(cylRadius*btSin(SIMD_2_PI*(float(i) / numSteps)), cylRadius*btCos(SIMD_2_PI*(float(i) / numSteps)), cylLength / 2.);
vertices.push_back(vert);
vert[2] = -cylLength / 2.;
vertices.push_back(vert);
}
btConvexHullShape* cylZShape = new btConvexHullShape(&vertices[0].x(), vertices.size(), sizeof(btVector3));
cylZShape->setMargin(0.001);
convexColShape = cylZShape;
break;
}
case URDF_GEOM_BOX:
{
btVector3 extents = visual->m_geometry.m_boxSize;
btBoxShape* boxShape = new btBoxShape(extents*0.5f);
//btConvexShape* boxShape = new btConeShapeX(extents[2]*0.5,extents[0]*0.5);
convexColShape = boxShape;
convexColShape->setMargin(0.001);
break;
}
case URDF_GEOM_SPHERE:
{
btScalar radius = visual->m_geometry.m_sphereRadius;
btSphereShape* sphereShape = new btSphereShape(radius);
convexColShape = sphereShape;
convexColShape->setMargin(0.001);
break;
break;
}
case URDF_GEOM_MESH:
{
if (visual->m_name.length())
{
//b3Printf("visual->name=%s\n", visual->m_name.c_str());
}
if (1)//visual->m_geometry)
{
if (visual->m_geometry.m_meshFileName.length())
{
const char* filename = visual->m_geometry.m_meshFileName.c_str();
//b3Printf("mesh->filename=%s\n", filename);
char fullPath[1024];
int fileType = 0;
char tmpPathPrefix[1024];
std::string xml_string;
int maxPathLen = 1024;
b3FileUtils::extractPath(filename,tmpPathPrefix,maxPathLen);
char visualPathPrefix[1024];
sprintf(visualPathPrefix,"%s%s",urdfPathPrefix,tmpPathPrefix);
sprintf(fullPath, "%s%s", urdfPathPrefix, filename);
b3FileUtils::toLower(fullPath);
if (strstr(fullPath, ".dae"))
{
fileType = MY_FILE_COLLADA;
}
if (strstr(fullPath, ".stl"))
{
fileType = MY_FILE_STL;
}
if (strstr(fullPath,".obj"))
{
fileType = MY_FILE_OBJ;
}
sprintf(fullPath, "%s%s", urdfPathPrefix, filename);
FILE* f = fopen(fullPath, "rb");
if (f)
{
fclose(f);
switch (fileType)
{
case MY_FILE_OBJ:
{
glmesh = LoadMeshFromObj(fullPath,visualPathPrefix);
break;
}
case MY_FILE_STL:
{
glmesh = LoadMeshFromSTL(fullPath);
break;
}
case MY_FILE_COLLADA:
{
btAlignedObjectArray<GLInstanceGraphicsShape> visualShapes;
btAlignedObjectArray<ColladaGraphicsInstance> visualShapeInstances;
btTransform upAxisTrans; upAxisTrans.setIdentity();
float unitMeterScaling = 1;
int upAxis = 2;
LoadMeshFromCollada(fullPath,
visualShapes,
visualShapeInstances,
upAxisTrans,
unitMeterScaling,
upAxis);
glmesh = new GLInstanceGraphicsShape;
// int index = 0;
glmesh->m_indices = new b3AlignedObjectArray<int>();
glmesh->m_vertices = new b3AlignedObjectArray<GLInstanceVertex>();
for (int i = 0; i<visualShapeInstances.size(); i++)
{
ColladaGraphicsInstance* instance = &visualShapeInstances[i];
GLInstanceGraphicsShape* gfxShape = &visualShapes[instance->m_shapeIndex];
b3AlignedObjectArray<GLInstanceVertex> verts;
verts.resize(gfxShape->m_vertices->size());
int baseIndex = glmesh->m_vertices->size();
for (int i = 0; i<gfxShape->m_vertices->size(); i++)
{
verts[i].normal[0] = gfxShape->m_vertices->at(i).normal[0];
verts[i].normal[1] = gfxShape->m_vertices->at(i).normal[1];
verts[i].normal[2] = gfxShape->m_vertices->at(i).normal[2];
verts[i].uv[0] = gfxShape->m_vertices->at(i).uv[0];
verts[i].uv[1] = gfxShape->m_vertices->at(i).uv[1];
verts[i].xyzw[0] = gfxShape->m_vertices->at(i).xyzw[0];
verts[i].xyzw[1] = gfxShape->m_vertices->at(i).xyzw[1];
verts[i].xyzw[2] = gfxShape->m_vertices->at(i).xyzw[2];
verts[i].xyzw[3] = gfxShape->m_vertices->at(i).xyzw[3];
}
int curNumIndices = glmesh->m_indices->size();
int additionalIndices = gfxShape->m_indices->size();
glmesh->m_indices->resize(curNumIndices + additionalIndices);
for (int k = 0; k<additionalIndices; k++)
{
glmesh->m_indices->at(curNumIndices + k) = gfxShape->m_indices->at(k) + baseIndex;
}
//compensate upAxisTrans and unitMeterScaling here
btMatrix4x4 upAxisMat;
upAxisMat.setIdentity();
// upAxisMat.setPureRotation(upAxisTrans.getRotation());
btMatrix4x4 unitMeterScalingMat;
unitMeterScalingMat.setPureScaling(btVector3(unitMeterScaling, unitMeterScaling, unitMeterScaling));
btMatrix4x4 worldMat = unitMeterScalingMat*upAxisMat*instance->m_worldTransform;
//btMatrix4x4 worldMat = instance->m_worldTransform;
int curNumVertices = glmesh->m_vertices->size();
int additionalVertices = verts.size();
glmesh->m_vertices->reserve(curNumVertices + additionalVertices);
for (int v = 0; v<verts.size(); v++)
{
btVector3 pos(verts[v].xyzw[0], verts[v].xyzw[1], verts[v].xyzw[2]);
pos = worldMat*pos;
verts[v].xyzw[0] = float(pos[0]);
verts[v].xyzw[1] = float(pos[1]);
verts[v].xyzw[2] = float(pos[2]);
glmesh->m_vertices->push_back(verts[v]);
}
}
glmesh->m_numIndices = glmesh->m_indices->size();
glmesh->m_numvertices = glmesh->m_vertices->size();
//glmesh = LoadMeshFromCollada(fullPath);
break;
}
default:
{
b3Warning("Error: unsupported file type for Visual mesh: %s\n", fullPath);
btAssert(0);
}
}
if (glmesh && glmesh->m_vertices && (glmesh->m_numvertices>0))
{
//apply the geometry scaling
for (int i=0;i<glmesh->m_vertices->size();i++)
{
glmesh->m_vertices->at(i).xyzw[0] *= visual->m_geometry.m_meshScale[0];
glmesh->m_vertices->at(i).xyzw[1] *= visual->m_geometry.m_meshScale[1];
glmesh->m_vertices->at(i).xyzw[2] *= visual->m_geometry.m_meshScale[2];
}
}
else
{
b3Warning("issue extracting mesh from COLLADA/STL file %s\n", fullPath);
}
}
else
{
b3Warning("mesh geometry not found %s\n", fullPath);
}
}
}
break;
}
default:
{
b3Warning("Error: unknown visual geometry type\n");
}
}
//if we have a convex, tesselate into localVertices/localIndices
if ((glmesh==0) && convexColShape)
{
btShapeHull* hull = new btShapeHull(convexColShape);
hull->buildHull(0.0);
{
// int strideInBytes = 9*sizeof(float);
int numVertices = hull->numVertices();
int numIndices = hull->numIndices();
glmesh = new GLInstanceGraphicsShape;
// int index = 0;
glmesh->m_indices = new b3AlignedObjectArray<int>();
glmesh->m_vertices = new b3AlignedObjectArray<GLInstanceVertex>();
for (int i = 0; i < numVertices; i++)
{
GLInstanceVertex vtx;
btVector3 pos = hull->getVertexPointer()[i];
vtx.xyzw[0] = pos.x();
vtx.xyzw[1] = pos.y();
vtx.xyzw[2] = pos.z();
vtx.xyzw[3] = 1.f;
pos.normalize();
vtx.normal[0] = pos.x();
vtx.normal[1] = pos.y();
vtx.normal[2] = pos.z();
vtx.uv[0] = 0.5f;
vtx.uv[1] = 0.5f;
glmesh->m_vertices->push_back(vtx);
}
btAlignedObjectArray<int> indices;
for (int i = 0; i < numIndices; i++)
{
glmesh->m_indices->push_back(hull->getIndexPointer()[i]);
}
glmesh->m_numvertices = glmesh->m_vertices->size();
glmesh->m_numIndices = glmesh->m_indices->size();
}
delete hull;
delete convexColShape;
convexColShape = 0;
}
if (glmesh && glmesh->m_numIndices>0 && glmesh->m_numvertices >0)
{
int baseIndex = verticesOut.size();
for (int i = 0; i < glmesh->m_indices->size(); i++)
{
indicesOut.push_back(glmesh->m_indices->at(i) + baseIndex);
}
for (int i = 0; i < glmesh->m_vertices->size(); i++)
{
GLInstanceVertex& v = glmesh->m_vertices->at(i);
btVector3 vert(v.xyzw[0],v.xyzw[1],v.xyzw[2]);
btVector3 vt = visualTransform*vert;
v.xyzw[0] = vt[0];
v.xyzw[1] = vt[1];
v.xyzw[2] = vt[2];
btVector3 triNormal(v.normal[0],v.normal[1],v.normal[2]);
triNormal = visualTransform.getBasis()*triNormal;
v.normal[0] = triNormal[0];
v.normal[1] = triNormal[1];
v.normal[2] = triNormal[2];
verticesOut.push_back(v);
}
}
delete glmesh;
}
void TinyRendererVisualShapeConverter::convertVisualShapes(int linkIndex, const char* pathPrefix, const btTransform& localInertiaFrame, const UrdfModel& model, class btCollisionObject* colObj)
{
btAlignedObjectArray<GLInstanceVertex> vertices;
btAlignedObjectArray<int> indices;
btTransform startTrans; startTrans.setIdentity();
int graphicsIndex = -1;
UrdfLink* const* linkPtr = model.m_links.getAtIndex(linkIndex);
if (linkPtr)
{
const UrdfLink* link = *linkPtr;
for (int v = 0; v < link->m_visualArray.size();v++)
{
const UrdfVisual& vis = link->m_visualArray[v];
btTransform childTrans = vis.m_linkLocalFrame;
btHashString matName(vis.m_materialName.c_str());
UrdfMaterial *const * matPtr = model.m_materials[matName];
float rgbaColor[4] = {1,1,1,1};
if (matPtr)
{
UrdfMaterial *const mat = *matPtr;
for (int i=0;i<4;i++)
rgbaColor[i] = mat->m_rgbaColor[i];
//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);
}
TinyRendererObjectArray** visualsPtr = m_data->m_swRenderInstances[colObj];
if (visualsPtr==0)
{
m_data->m_swRenderInstances.insert(colObj,new TinyRendererObjectArray);
}
visualsPtr = m_data->m_swRenderInstances[colObj];
btAssert(visualsPtr);
TinyRendererObjectArray* visuals = *visualsPtr;
convertURDFToVisualShape(&vis, pathPrefix, localInertiaFrame.inverse()*childTrans, vertices, indices);
if (vertices.size() && indices.size())
{
TinyRenderObjectData* tinyObj = new TinyRenderObjectData(m_data->m_swWidth,m_data->m_swHeight,m_data->m_rgbColorBuffer,m_data->m_depthBuffer);
tinyObj->registerMeshShape(&vertices[0].xyzw[0],vertices.size(),&indices[0],indices.size(),rgbaColor);
visuals->m_renderObjects.push_back(tinyObj);
}
}
}
}
void TinyRendererVisualShapeConverter::setUpAxis(int axis)
{
m_data->m_upAxis = axis;
m_data->m_camera.setCameraUpAxis(axis);
m_data->m_camera.update();
}
void TinyRendererVisualShapeConverter::resetCamera(float camDist, float pitch, float yaw, float camPosX,float camPosY, float camPosZ)
{
m_data->m_camera.setCameraDistance(camDist);
m_data->m_camera.setCameraPitch(pitch);
m_data->m_camera.setCameraYaw(yaw);
m_data->m_camera.setCameraTargetPosition(camPosX,camPosY,camPosZ);
m_data->m_camera.setAspectRatio((float)m_data->m_swWidth/(float)m_data->m_swHeight);
m_data->m_camera.update();
}
void TinyRendererVisualShapeConverter::clearBuffers(TGAColor& clearColor)
{
for(int y=0;y<m_data->m_swHeight;++y)
{
for(int x=0;x<m_data->m_swWidth;++x)
{
m_data->m_rgbColorBuffer.set(x,y,clearColor);
m_data->m_depthBuffer[x+y*m_data->m_swWidth] = -1e30f;
}
}
}
void TinyRendererVisualShapeConverter::render()
{
ATTRIBUTE_ALIGNED16(float viewMat[16]);
ATTRIBUTE_ALIGNED16(float projMat[16]);
m_data->m_camera.getCameraProjectionMatrix(projMat);
m_data->m_camera.getCameraViewMatrix(viewMat);
render(viewMat,projMat);
}
void TinyRendererVisualShapeConverter::render(const float viewMat[16], const float projMat[16])
{
//clear the color buffer
TGAColor clearColor;
clearColor.bgra[0] = 255;
clearColor.bgra[1] = 255;
clearColor.bgra[2] = 255;
clearColor.bgra[3] = 255;
clearBuffers(clearColor);
ATTRIBUTE_ALIGNED16(btScalar modelMat[16]);
btVector3 lightDirWorld(-5,200,-40);
switch (m_data->m_upAxis)
{
case 1:
lightDirWorld = btVector3(-50.f,100,30);
break;
case 2:
lightDirWorld = btVector3(-50.f,30,100);
break;
default:{}
};
lightDirWorld.normalize();
printf("num m_swRenderInstances = %d\n", m_data->m_swRenderInstances.size());
for (int i=0;i<m_data->m_swRenderInstances.size();i++)
{
TinyRendererObjectArray** visualArrayPtr = m_data->m_swRenderInstances.getAtIndex(i);
if (0==visualArrayPtr)
continue;//can this ever happen?
TinyRendererObjectArray* visualArray = *visualArrayPtr;
btHashPtr colObjHash = m_data->m_swRenderInstances.getKeyAtIndex(i);
const btCollisionObject* colObj = (btCollisionObject*) colObjHash.getPointer();
for (int v=0;v<visualArray->m_renderObjects.size();v++)
{
TinyRenderObjectData* renderObj = visualArray->m_renderObjects[v];
//sync the object transform
const btTransform& tr = colObj->getWorldTransform();
tr.getOpenGLMatrix(modelMat);
for (int i=0;i<4;i++)
{
for (int j=0;j<4;j++)
{
renderObj->m_projectionMatrix[i][j] = projMat[i+4*j];
renderObj->m_modelMatrix[i][j] = modelMat[i+4*j];
renderObj->m_viewMatrix[i][j] = viewMat[i+4*j];
renderObj->m_localScaling = colObj->getCollisionShape()->getLocalScaling();
renderObj->m_lightDirWorld = lightDirWorld;
}
}
TinyRenderer::renderObject(*renderObj);
}
}
//printf("write tga \n");
m_data->m_rgbColorBuffer.write_tga_file("camera.tga");
}
void TinyRendererVisualShapeConverter::getWidthAndHeight(int& width, int& height)
{
width = m_data->m_swWidth;
height = m_data->m_swHeight;
}
void TinyRendererVisualShapeConverter::copyCameraImageData(unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels, float* depthBuffer, int depthBufferSizeInPixels, int startPixelIndex, int* widthPtr, int* heightPtr, int* numPixelsCopied)
{
int w = m_data->m_rgbColorBuffer.get_width();
int h = m_data->m_rgbColorBuffer.get_height();
if (numPixelsCopied)
*numPixelsCopied = 0;
if (widthPtr)
*widthPtr = w;
if (heightPtr)
*heightPtr = h;
int numTotalPixels = w*h;
int numRemainingPixels = numTotalPixels - startPixelIndex;
int numBytesPerPixel = 4;//RGBA
int numRequestedPixels = btMin(rgbaBufferSizeInPixels,numRemainingPixels);
if (numRequestedPixels)
{
for (int i=0;i<numRequestedPixels;i++)
{
if (pixelsRGBA)
{
pixelsRGBA[i*numBytesPerPixel] = m_data->m_rgbColorBuffer.buffer()[(i+startPixelIndex)*3+0];
pixelsRGBA[i*numBytesPerPixel+1] = m_data->m_rgbColorBuffer.buffer()[(i+startPixelIndex)*3+1];
pixelsRGBA[i*numBytesPerPixel+2] = m_data->m_rgbColorBuffer.buffer()[(i+startPixelIndex)*3+2];
pixelsRGBA[i*numBytesPerPixel+3] = 255;
}
}
if (numPixelsCopied)
*numPixelsCopied = numRequestedPixels;
}
}
void TinyRendererVisualShapeConverter::resetAll()
{
//todo: free memory
m_data->m_swRenderInstances.clear();
}

View File

@@ -0,0 +1,38 @@
#ifndef TINY_RENDERER_VISUAL_SHAPE_CONVERTER_H
#define TINY_RENDERER_VISUAL_SHAPE_CONVERTER_H
#include "../Importers/ImportURDFDemo/LinkVisualShapesConverter.h"
struct TinyRendererVisualShapeConverter : public LinkVisualShapesConverter
{
struct TinyRendererVisualShapeConverterInternalData* m_data;
TinyRendererVisualShapeConverter();
virtual ~TinyRendererVisualShapeConverter();
virtual void convertVisualShapes(int linkIndex, const char* pathPrefix, const btTransform& localInertiaFrame, const UrdfModel& model, class btCollisionObject* colShape);
void setUpAxis(int axis);
void resetCamera(float camDist, float pitch, float yaw, float camPosX,float camPosY, float camPosZ);
void clearBuffers(struct TGAColor& clearColor);
void resetAll();
void getWidthAndHeight(int& width, int& height);
void copyCameraImageData(unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels, float* depthBuffer, int depthBufferSizeInPixels, int startPixelIndex, int* widthPtr, int* heightPtr, int* numPixelsCopied);
void render();
void render(const float viewMat[16], const float projMat[16]);
};
#endif //TINY_RENDERER_VISUAL_SHAPE_CONVERTER_H

View File

@@ -40,6 +40,15 @@ files {
"PhysicsLoopBackC_API.h",
"PhysicsServerCommandProcessor.cpp",
"PhysicsServerCommandProcessor.h",
"TinyRendererVisualShapeConverter.cpp",
"TinyRendererVisualShapeConverter.h",
"../TinyRenderer/geometry.cpp",
"../TinyRenderer/model.cpp",
"../TinyRenderer/tgaimage.cpp",
"../TinyRenderer/our_gl.cpp",
"../TinyRenderer/TinyRenderer.cpp",
"../OpenGLWindow/SimpleCamera.cpp",
"../OpenGLWindow/SimpleCamera.h",
"../Importers/ImportURDFDemo/ConvertRigidBodies2MultiBody.h",
"../Importers/ImportURDFDemo/MultiBodyCreationInterface.h",
"../Importers/ImportURDFDemo/MyMultiBodyCreator.cpp",
@@ -47,8 +56,6 @@ files {
"../Importers/ImportURDFDemo/BulletUrdfImporter.cpp",
"../Importers/ImportURDFDemo/BulletUrdfImporter.h",
"../Importers/ImportURDFDemo/UrdfParser.cpp",
"../Importers/ImportURDFDemo/BulletUrdfImporter.cpp",
"../Importers/ImportURDFDemo/BulletUrdfImporter.h",
"../Importers/ImportURDFDemo/urdfStringSplit.cpp",
"../Importers/ImportURDFDemo/UrdfParser.cpp",
"../Importers/ImportURDFDemo/UrdfParser.h",

View File

@@ -148,12 +148,29 @@ public:
clearBuffers(clearColor);
ATTRIBUTE_ALIGNED16(float modelMat[16]);
ATTRIBUTE_ALIGNED16(btScalar modelMat[16]);
ATTRIBUTE_ALIGNED16(float viewMat[16]);
ATTRIBUTE_ALIGNED16(float projMat[16]);
CommonRenderInterface* render = getRenderInterface();
render->getActiveCamera()->getCameraProjectionMatrix(projMat);
render->getActiveCamera()->getCameraViewMatrix(viewMat);
btVector3 lightDirWorld(-5,200,-40);
switch (1)//app->getUpAxis())
{
case 1:
lightDirWorld = btVector3(-50.f,100,30);
break;
case 2:
lightDirWorld = btVector3(-50.f,30,100);
break;
default:{}
};
lightDirWorld.normalize();
for (int i=0;i<rbWorld->getNumCollisionObjects();i++)
{
@@ -173,21 +190,25 @@ public:
if (sptr)
{
renderObj = *sptr;
}
}
//sync the object transform
const btTransform& tr = colObj->getWorldTransform();
tr.getOpenGLMatrix(modelMat);
//sync the object transform
const btTransform& tr = colObj->getWorldTransform();
tr.getOpenGLMatrix(modelMat);
for (int i=0;i<4;i++)
{
for (int j=0;j<4;j++)
{
renderObj->m_modelMatrix[i][j] = modelMat[i+4*j];
renderObj->m_viewMatrix[i][j] = viewMat[i+4*j];
for (int i=0;i<4;i++)
{
for (int j=0;j<4;j++)
{
renderObj->m_projectionMatrix[i][j] = projMat[i+4*j];
renderObj->m_modelMatrix[i][j] = modelMat[i+4*j];
renderObj->m_viewMatrix[i][j] = viewMat[i+4*j];
renderObj->m_localScaling = colObj->getCollisionShape()->getLocalScaling();
renderObj->m_lightDirWorld = lightDirWorld;
}
}
TinyRenderer::renderObject(*renderObj);
}
}
TinyRenderer::renderObject(*renderObj);
}
}
@@ -210,10 +231,12 @@ public:
static int counter=0;
counter++;
if (counter>10)
if ((counter&7)==0)
{
counter=0;
getFrameBuffer().write_tga_file("/Users/erwincoumans/develop/bullet3/framebuf.tga",true);
char filename[1024];
sprintf(filename,"framebuf%d.tga",counter);
getFrameBuffer().write_tga_file(filename,true);
}
float color[4] = {1,1,1,1};
m_primRenderer->drawTexturedRect(0,0,m_swWidth, m_swHeight,color,0,0,1,1,true);

View File

@@ -0,0 +1,376 @@
/*
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 "../CommonInterfaces/CommonExampleInterface.h"
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
#include "../ExampleBrowser/CollisionShape2TriangleMesh.h"
#include "../OpenGLWindow/GLInstanceGraphicsShape.h"
#include "LinearMath/btTransform.h"
#include "LinearMath/btHashMap.h"
#include "../TinyRenderer/TinyRenderer.h"
#include "../OpenGLWindow/SimpleCamera.h"
static btVector4 sMyColors[4] =
{
btVector4(0.3,0.3,1,1),
btVector4(0.6,0.6,1,1),
btVector4(0,1,0,1),
btVector4(0,1,1,1),
//btVector4(1,1,0,1),
};
struct TinyRendererGUIHelper : public GUIHelperInterface
{
int m_upAxis;
btHashMap<btHashInt,TinyRenderObjectData*> m_swRenderObjects;
btHashMap<btHashInt,int> m_swInstances;
int m_swWidth;
int m_swHeight;
TGAImage m_rgbColorBuffer;
b3AlignedObjectArray<float> m_depthBuffer;
SimpleCamera m_camera;
int m_colObjUniqueIndex;
TinyRendererGUIHelper( int swWidth, int swHeight)
: m_upAxis(1),
m_swWidth(swWidth),
m_swHeight(swHeight),
m_rgbColorBuffer(swWidth,swHeight,TGAImage::RGB),
m_colObjUniqueIndex(0)
{
m_depthBuffer.resize(swWidth*swHeight);
}
void clearBuffers(TGAColor& clearColor)
{
for(int y=0;y<m_swHeight;++y)
{
for(int x=0;x<m_swWidth;++x)
{
m_rgbColorBuffer.set(x,y,clearColor);
m_depthBuffer[x+y*m_swWidth] = -1e30f;
}
}
}
const TGAImage& getFrameBuffer() const
{
return m_rgbColorBuffer;
}
virtual ~TinyRendererGUIHelper()
{
for (int i=0;i<m_swRenderObjects.size();i++)
{
TinyRenderObjectData** d = m_swRenderObjects[i];
if (d && *d)
{
delete *d;
}
}
}
virtual void createRigidBodyGraphicsObject(btRigidBody* body,const btVector3& color){}
virtual void createCollisionObjectGraphicsObject(btCollisionObject* obj,const btVector3& color)
{
if (obj->getUserIndex()<0)
{
int colIndex = m_colObjUniqueIndex++;
obj->setUserIndex(colIndex);
int shapeIndex = obj->getCollisionShape()->getUserIndex();
if (colIndex>=0 && shapeIndex>=0)
{
m_swInstances.insert(colIndex,shapeIndex);
}
}
}
virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape)
{
//already has a graphics object?
if (collisionShape->getUserIndex()>=0)
return;
btAlignedObjectArray<GLInstanceVertex> gfxVertices;
btAlignedObjectArray<int> indices;
btTransform startTrans;startTrans.setIdentity();
{
btAlignedObjectArray<btVector3> vertexPositions;
btAlignedObjectArray<btVector3> vertexNormals;
CollisionShape2TriangleMesh(collisionShape,startTrans,vertexPositions,vertexNormals,indices);
gfxVertices.resize(vertexPositions.size());
for (int i=0;i<vertexPositions.size();i++)
{
for (int j=0;j<4;j++)
{
gfxVertices[i].xyzw[j] = vertexPositions[i][j];
}
for (int j=0;j<3;j++)
{
gfxVertices[i].normal[j] = vertexNormals[i][j];
}
for (int j=0;j<2;j++)
{
gfxVertices[i].uv[j] = 0.5;//we don't have UV info...
}
}
}
if (gfxVertices.size() && indices.size())
{
int shapeId = registerGraphicsShape(&gfxVertices[0].xyzw[0],gfxVertices.size(),&indices[0],indices.size());
collisionShape->setUserIndex(shapeId);
}
}
virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld){}
virtual void render(const btDiscreteDynamicsWorld* rbWorld)
{
//clear the color buffer
TGAColor clearColor;
clearColor.bgra[0] = 255;
clearColor.bgra[1] = 255;
clearColor.bgra[2] = 255;
clearColor.bgra[3] = 255;
clearBuffers(clearColor);
ATTRIBUTE_ALIGNED16(btScalar modelMat[16]);
ATTRIBUTE_ALIGNED16(float viewMat[16]);
ATTRIBUTE_ALIGNED16(float projMat[16]);
m_camera.getCameraProjectionMatrix(projMat);
m_camera.getCameraViewMatrix(viewMat);
btVector3 lightDirWorld(-5,200,-40);
switch (m_upAxis)
{
case 1:
lightDirWorld = btVector3(-50.f,100,30);
break;
case 2:
lightDirWorld = btVector3(-50.f,30,100);
break;
default:{}
};
lightDirWorld.normalize();
for (int i=0;i<rbWorld->getNumCollisionObjects();i++)
{
btCollisionObject* colObj = rbWorld->getCollisionObjectArray()[i];
int colObjIndex = colObj->getUserIndex();
int shapeIndex = colObj->getCollisionShape()->getUserIndex();
if (colObjIndex>=0 && shapeIndex>=0)
{
TinyRenderObjectData* renderObj = 0;
int* cptr = m_swInstances[colObjIndex];
if (cptr)
{
int c = *cptr;
TinyRenderObjectData** sptr = m_swRenderObjects[c];
if (sptr)
{
renderObj = *sptr;
//sync the object transform
const btTransform& tr = colObj->getWorldTransform();
tr.getOpenGLMatrix(modelMat);
for (int i=0;i<4;i++)
{
for (int j=0;j<4;j++)
{
renderObj->m_projectionMatrix[i][j] = projMat[i+4*j];
renderObj->m_modelMatrix[i][j] = modelMat[i+4*j];
renderObj->m_viewMatrix[i][j] = viewMat[i+4*j];
renderObj->m_localScaling = colObj->getCollisionShape()->getLocalScaling();
renderObj->m_lightDirWorld = lightDirWorld;
}
}
TinyRenderer::renderObject(*renderObj);
}
}
}
}
static int counter=0;
counter++;
if ((counter&7)==0)
{
char filename[1024];
sprintf(filename,"framebuf%d.tga",counter);
m_rgbColorBuffer.flip_vertically();
getFrameBuffer().write_tga_file(filename,true);
}
float color[4] = {1,1,1,1};
}
virtual void createPhysicsDebugDrawer( btDiscreteDynamicsWorld* rbWorld){}
virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices)
{
int shapeIndex = m_swRenderObjects.size();
TinyRenderObjectData* swObj = new TinyRenderObjectData(m_swWidth,m_swHeight,m_rgbColorBuffer,m_depthBuffer);
swObj->registerMeshShape(vertices,numvertices,indices,numIndices);
//swObj->createCube(1,1,1);//MeshShape(vertices,numvertices,indices,numIndices);
m_swRenderObjects.insert(shapeIndex,swObj);
return shapeIndex;
}
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling)
{
int colIndex = m_colObjUniqueIndex++;
if (colIndex>=0 && shapeIndex>=0)
{
TinyRenderObjectData** dPtr = m_swRenderObjects[shapeIndex];
if (dPtr && *dPtr)
{
TinyRenderObjectData* d= *dPtr;
d->m_localScaling.setValue(scaling[0],scaling[1],scaling[2]);
m_swInstances.insert(colIndex,shapeIndex);
}
}
return colIndex;
}
virtual Common2dCanvasInterface* get2dCanvasInterface()
{
return 0;
}
virtual CommonParameterInterface* getParameterInterface()
{
return 0;
}
virtual CommonRenderInterface* getRenderInterface()
{
return 0;
}
virtual CommonGraphicsApp* getAppInterface()
{
return 0;
}
virtual void setUpAxis(int axis)
{
m_upAxis = axis;
m_camera.setCameraUpAxis(axis);
m_camera.update();
}
virtual void resetCamera(float camDist, float pitch, float yaw, float camPosX,float camPosY, float camPosZ)
{
m_camera.setCameraDistance(camDist);
m_camera.setCameraPitch(pitch);
m_camera.setCameraYaw(yaw);
m_camera.setCameraTargetPosition(camPosX,camPosY,camPosZ);
m_camera.setAspectRatio((float)m_swWidth/(float)m_swHeight);
m_camera.update();
}
virtual void copyCameraImageData(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;
}
virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld)
{
for (int i=0;i<rbWorld->getNumCollisionObjects();i++)
{
btCollisionObject* colObj = rbWorld->getCollisionObjectArray()[i];
//btRigidBody* body = btRigidBody::upcast(colObj);
//does this also work for btMultiBody/btMultiBodyLinkCollider?
createCollisionShapeGraphicsObject(colObj->getCollisionShape());
int colorIndex = colObj->getBroadphaseHandle()->getUid() & 3;
btVector3 color= sMyColors[colorIndex];
createCollisionObjectGraphicsObject(colObj,color);
}
}
virtual void drawText3D( const char* txt, float posX, float posZY, float posZ, float size)
{
}
};
int main(int argc, char* argv[])
{
TinyRendererGUIHelper noGfx(640,480);
CommonExampleOptions options(&noGfx);
CommonExampleInterface* example = StandaloneExampleCreateFunc(options);
example->initPhysics();
example->resetCamera();
for (int i=0;i<1000;i++)
{
printf("Simulating step %d\n",i);
example->stepSimulation(1.f/60.f);
example->renderScene();
}
example->exitPhysics();
delete example;
return 0;
}

View File

@@ -12,28 +12,36 @@
#include "../OpenGLWindow/ShapeData.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "LinearMath/btVector3.h"
Vec3f light_dir_world(1,1,1);
struct Shader : public IShader {
Model* m_model;
Vec3f m_light_dir_local;
Matrix& m_modelView;
Matrix& m_modelMat;
Matrix m_invModelMat;
Matrix& m_modelView1;
Matrix& m_projectionMatrix;
Vec3f m_localScaling;
Vec4f m_colorRGBA;
mat<2,3,float> varying_uv; // triangle uv coordinates, written by the vertex shader, read by the fragment shader
mat<4,3,float> varying_tri; // triangle coordinates (clip coordinates), written by VS, read by FS
mat<3,3,float> varying_nrm; // normal per vertex to be interpolated by FS
mat<3,3,float> ndc_tri; // triangle in normalized device coordinates
//mat<3,3,float> ndc_tri; // triangle in normalized device coordinates
Shader(Model* model, Vec3f light_dir_local, Matrix& modelView, Matrix& projectionMatrix)
Shader(Model* model, Vec3f light_dir_local, Matrix& modelView, Matrix& projectionMatrix, Matrix& modelMat, Vec3f localScaling, const Vec4f& colorRGBA)
:m_model(model),
m_light_dir_local(light_dir_local),
m_modelView(modelView),
m_projectionMatrix(projectionMatrix)
m_modelView1(modelView),
m_projectionMatrix(projectionMatrix),
m_modelMat(modelMat),
m_localScaling(localScaling),
m_colorRGBA(colorRGBA)
{
m_invModelMat = m_modelMat.invert_transpose();
}
virtual Vec4f vertex(int iface, int nthvert) {
@@ -42,10 +50,19 @@ struct Shader : public IShader {
//printf("uv = %f,%f\n", uv.x,uv.y);
varying_uv.set_col(nthvert, uv);
varying_nrm.set_col(nthvert, proj<3>((m_projectionMatrix*m_modelView).invert_transpose()*embed<4>(m_model->normal(iface, nthvert), 0.f)));
Vec4f gl_Vertex = m_projectionMatrix*m_modelView*embed<4>(m_model->vert(iface, nthvert));
//varying_nrm.set_col(nthvert, proj<3>((m_projectionMatrix*m_modelView).invert_transpose()*embed<4>(m_model->normal(iface, nthvert), 0.f)));
varying_nrm.set_col(nthvert, proj<3>(m_invModelMat*embed<4>(m_model->normal(iface, nthvert), 0.f)));
//m_localNormal = m_model->normal(iface, nthvert);
//varying_nrm.set_col(nthvert, m_model->normal(iface, nthvert));
Vec3f unScaledVert = m_model->vert(iface, nthvert);
Vec3f scaledVert=Vec3f(unScaledVert[0]*m_localScaling[0],unScaledVert[1]*m_localScaling[1],unScaledVert[2]*m_localScaling[2]);
Vec4f gl_Vertex = m_projectionMatrix*m_modelView1*embed<4>(scaledVert);
varying_tri.set_col(nthvert, gl_Vertex);
ndc_tri.set_col(nthvert, proj<3>(gl_Vertex/gl_Vertex[3]));
//ndc_tri.set_col(nthvert, proj<3>(gl_Vertex/gl_Vertex[3]));
return gl_Vertex;
}
@@ -53,26 +70,17 @@ struct Shader : public IShader {
Vec3f bn = (varying_nrm*bar).normalize();
Vec2f uv = varying_uv*bar;
mat<3,3,float> A;
A[0] = ndc_tri.col(1) - ndc_tri.col(0);
A[1] = ndc_tri.col(2) - ndc_tri.col(0);
A[2] = bn;
mat<3,3,float> AI = A.invert();
Vec3f i = AI * Vec3f(varying_uv[0][1] - varying_uv[0][0], varying_uv[0][2] - varying_uv[0][0], 0);
Vec3f j = AI * Vec3f(varying_uv[1][1] - varying_uv[1][0], varying_uv[1][2] - varying_uv[1][0], 0);
mat<3,3,float> B;
B.set_col(0, i.normalize());
B.set_col(1, j.normalize());
B.set_col(2, bn);
Vec3f n = (B*m_model->normal(uv)).normalize();
float diff = b3Min(b3Max(0.f, n*m_light_dir_local+0.3f),1.f);
//float diff = 1;//full-bright
float ambient = 0.7;
//float diff = ambient+b3Min(b3Max(0.f, bn*light_dir_world),(1-ambient));
float diff = ambient+b3Min(b3Max(0.f, bn*m_light_dir_local),(1-ambient));
//float diff = b3Max(0.f, n*m_light_dir_local);
color = m_model->diffuse(uv)*diff;
//colors are store in BGRA?
color = TGAColor(color[0]*m_colorRGBA[2],
color[1]*m_colorRGBA[1],
color[2]*m_colorRGBA[0],
color[3]*m_colorRGBA[3]);
return false;
}
@@ -90,11 +98,14 @@ m_userIndex(-1)
{
Vec3f eye(1,1,3);
Vec3f center(0,0,0);
Vec3f up(0,1,0);
Vec3f up(0,0,1);
m_lightDirWorld.setValue(0,0,0);
m_localScaling.setValue(1,1,1);
m_modelMatrix = Matrix::identity();
m_viewMatrix = lookat(eye, center, up);
m_viewportMatrix = viewport(width/8, height/8, width*3/4, height*3/4);
//m_viewportMatrix = viewport(width/8, height/8, width*3/4, height*3/4);
//m_viewportMatrix = viewport(width/8, height/8, width*3/4, height*3/4);
m_viewportMatrix = viewport(0,0,width,height);
m_projectionMatrix = projection(-1.f/(eye-center).norm());
}
@@ -113,15 +124,24 @@ void TinyRenderObjectData::loadModel(const char* fileName)
}
void TinyRenderObjectData::registerMeshShape(const float* vertices, int numVertices,const int* indices, int numIndices)
void TinyRenderObjectData::registerMeshShape(const float* vertices, int numVertices,const int* indices, int numIndices, const float rgbaColor[4],
unsigned char* textureImage, int textureWidth, int textureHeight)
{
if (0==m_model)
{
m_model = new Model();
char relativeFileName[1024];
if (b3ResourcePath::findResourcePath("floor_diffuse.tga", relativeFileName, 1024))
m_model->setColorRGBA(rgbaColor);
if (textureImage)
{
m_model->loadDiffuseTexture(relativeFileName);
m_model->setDiffuseTextureFromData(textureImage,textureWidth,textureHeight);
} else
{
/*char relativeFileName[1024];
if (b3ResourcePath::findResourcePath("floor_diffuse.tga", relativeFileName, 1024))
{
m_model->loadDiffuseTexture(relativeFileName);
}
*/
}
for (int i=0;i<numVertices;i++)
@@ -219,21 +239,35 @@ TinyRenderObjectData::~TinyRenderObjectData()
void TinyRenderer::renderObject(TinyRenderObjectData& renderData)
{
Vec3f light_dir_local = Vec3f(renderData.m_lightDirWorld[0],renderData.m_lightDirWorld[1],renderData.m_lightDirWorld[2]);
Model* model = renderData.m_model;
if (0==model)
return;
//renderData.m_viewMatrix = lookat(eye, center, up);
int width = renderData.m_width;
int height = renderData.m_height;
//renderData.m_viewportMatrix = viewport(width/8, height/8, width*3/4, height*3/4);
renderData.m_viewportMatrix = viewport(0,0,renderData.m_width,renderData.m_height);
//renderData.m_projectionMatrix = projection(-1.f/(eye-center).norm());
b3AlignedObjectArray<float>& zbuffer = renderData.m_depthBuffer;
TGAImage& frame = renderData.m_rgbColorBuffer;
Vec3f light_dir_local = proj<3>((renderData.m_projectionMatrix*renderData.m_viewMatrix*renderData.m_modelMatrix*embed<4>(light_dir_world, 0.f))).normalize();
{
Matrix modelViewMatrix = renderData.m_viewMatrix*renderData.m_modelMatrix;
Shader shader(model, light_dir_local, modelViewMatrix, renderData.m_projectionMatrix);
for (int i=0; i<model->nfaces(); i++) {
Vec3f localScaling(renderData.m_localScaling[0],renderData.m_localScaling[1],renderData.m_localScaling[2]);
Shader shader(model, light_dir_local, modelViewMatrix, renderData.m_projectionMatrix,renderData.m_modelMatrix, localScaling, model->getColorRGBA());
printf("Render %d triangles.\n",model->nfaces());
for (int i=0; i<model->nfaces(); i++)
{
for (int j=0; j<3; j++) {
shader.vertex(i, j);
}

View File

@@ -16,7 +16,9 @@ struct TinyRenderObjectData
Matrix m_viewMatrix;
Matrix m_projectionMatrix;
Matrix m_viewportMatrix;
btVector3 m_localScaling;
btVector3 m_lightDirWorld;
//Model (vertices, indices, textures, shader)
Matrix m_modelMatrix;
class Model* m_model;
@@ -33,7 +35,8 @@ struct TinyRenderObjectData
void loadModel(const char* fileName);
void createCube(float HalfExtentsX,float HalfExtentsY,float HalfExtentsZ);
void registerMeshShape(const float* vertices, int numVertices,const int* indices, int numIndices);
void registerMeshShape(const float* vertices, int numVertices,const int* indices, int numIndices, const float rgbaColor[4],
unsigned char* textureImage=0, int textureWidth=0, int textureHeight=0);
void registerMesh2(btAlignedObjectArray<btVector3>& vertices, btAlignedObjectArray<btVector3>& normals,btAlignedObjectArray<int>& indices);

View File

@@ -49,6 +49,28 @@ Model::Model():verts_(), faces_(), norms_(), uv_(), diffusemap_(), normalmap_(),
{
}
void Model::setDiffuseTextureFromData(unsigned char* textureImage,int textureWidth,int textureHeight)
{
diffusemap_ = TGAImage(textureWidth, textureHeight, TGAImage::RGB);
for (int i=0;i<textureWidth;i++)
{
for (int j=0;j<textureHeight;j++)
{
TGAColor color;
color.bgra[0] = textureImage[(i+j*textureWidth)*3+0];
color.bgra[1] = textureImage[(i+j*textureWidth)*3+1];
color.bgra[2] = textureImage[(i+j*textureWidth)*3+2];
color.bgra[3] = 255;
color.bytespp = 3;
diffusemap_.set(i,j,color);
}
}
diffusemap_.flip_vertically();
}
void Model::loadDiffuseTexture(const char* relativeFileName)
{
diffusemap_.read_tga_file(relativeFileName);
@@ -108,8 +130,12 @@ void Model::load_texture(std::string filename, const char *suffix, TGAImage &img
}
TGAColor Model::diffuse(Vec2f uvf) {
Vec2i uv(uvf[0]*diffusemap_.get_width(), uvf[1]*diffusemap_.get_height());
return diffusemap_.get(uv[0], uv[1]);
if (diffusemap_.get_width() && diffusemap_.get_height())
{
Vec2i uv(uvf[0]*diffusemap_.get_width(), uvf[1]*diffusemap_.get_height());
return diffusemap_.get(uv[0], uv[1]);
}
return TGAColor(255,255,255,255);
}
Vec3f Model::normal(Vec2f uvf) {

View File

@@ -14,11 +14,24 @@ private:
TGAImage diffusemap_;
TGAImage normalmap_;
TGAImage specularmap_;
Vec4f m_colorRGBA;
void load_texture(std::string filename, const char *suffix, TGAImage &img);
public:
Model(const char *filename);
Model();
void setColorRGBA(const float rgba[4])
{
for (int i=0;i<4;i++)
m_colorRGBA[i] = rgba[i];
}
const Vec4f& getColorRGBA() const
{
return m_colorRGBA;
}
void loadDiffuseTexture(const char* relativeFileName);
void setDiffuseTextureFromData(unsigned char* textureImage,int textureWidth,int textureHeight);
void addVertex(float x,float y,float z, float normalX, float normalY, float normalZ, float u, float v);
void addTriangle(int vertexposIndex0, int normalIndex0, int uvIndex0,
int vertexposIndex1, int normalIndex1, int uvIndex1,

View File

@@ -60,8 +60,8 @@ Vec3f barycentric(Vec2f A, Vec2f B, Vec2f C, Vec2f P) {
}
void triangle(mat<4,3,float> &clipc, IShader &shader, TGAImage &image, float *zbuffer, const Matrix& viewPortMatrix) {
mat<3,4,float> pts = (viewPortMatrix*clipc).transpose(); // transposed to ease access to each of the points
mat<3,4,float> pts = (viewPortMatrix*clipc).transpose(); // transposed to ease access to each of the points
//we don't clip triangles that cross the near plane, just discard them instead of showing artifacts
if (pts[0][3]<0 || pts[1][3] <0 || pts[2][3] <0)
@@ -93,8 +93,10 @@ void triangle(mat<4,3,float> &clipc, IShader &shader, TGAImage &image, float *zb
Vec3f bc_clip = Vec3f(bc_screen.x/pts[0][3], bc_screen.y/pts[1][3], bc_screen.z/pts[2][3]);
bc_clip = bc_clip/(bc_clip.x+bc_clip.y+bc_clip.z);
float frag_depth = clipc[2]*bc_clip;
if (bc_screen.x<0 || bc_screen.y<0 || bc_screen.z<0 || zbuffer[P.x+P.y*image.get_width()]>frag_depth) continue;
float frag_depth = -1*(clipc[2]*bc_clip);
if (bc_screen.x<0 || bc_screen.y<0 || bc_screen.z<0 ||
zbuffer[P.x+P.y*image.get_width()]>frag_depth)
continue;
bool discard = shader.fragment(bc_clip, color);
if (!discard) {
zbuffer[P.x+P.y*image.get_width()] = frag_depth;

View File

@@ -8,7 +8,51 @@ INCLUDE_DIRECTORIES(
SET(pybullet_SRCS
pybullet.c
../../examples/ExampleBrowser/ExampleEntries.cpp
../../examples/ExampleBrowser/InProcessExampleBrowser.cpp
../../examples/SharedMemory/InProcessMemory.cpp
../../examples/SharedMemory/PhysicsClient.cpp
../../examples/SharedMemory/PhysicsClient.h
../../examples/SharedMemory/PhysicsServer.cpp
../../examples/SharedMemory/PhysicsServer.h
../../examples/SharedMemory/PhysicsServerExample.cpp
../../examples/SharedMemory/SharedMemoryInProcessPhysicsC_API.cpp
../../examples/SharedMemory/PhysicsServerSharedMemory.cpp
../../examples/SharedMemory/PhysicsServerSharedMemory.h
../../examples/SharedMemory/PhysicsDirect.cpp
../../examples/SharedMemory/PhysicsDirect.h
../../examples/SharedMemory/PhysicsDirectC_API.cpp
../../examples/SharedMemory/PhysicsDirectC_API.h
../../examples/SharedMemory/PhysicsServerCommandProcessor.cpp
../../examples/SharedMemory/PhysicsServerCommandProcessor.h
../../examples/SharedMemory/PhysicsClientSharedMemory.cpp
../../examples/SharedMemory/PhysicsClientSharedMemory.h
../../examples/SharedMemory/PhysicsClientC_API.cpp
../../examples/SharedMemory/PhysicsClientC_API.h
../../examples/SharedMemory/Win32SharedMemory.cpp
../../examples/SharedMemory/Win32SharedMemory.h
../../examples/SharedMemory/PosixSharedMemory.cpp
../../examples/SharedMemory/PosixSharedMemory.h
../../examples/Utils/b3ResourcePath.cpp
../../examples/Utils/b3ResourcePath.h
../../examples/ThirdPartyLibs/tinyxml/tinystr.cpp
../../examples/ThirdPartyLibs/tinyxml/tinyxml.cpp
../../examples/ThirdPartyLibs/tinyxml/tinyxmlerror.cpp
../../examples/ThirdPartyLibs/tinyxml/tinyxmlparser.cpp
../../examples/ThirdPartyLibs/Wavefront/tiny_obj_loader.cpp
../../examples/ThirdPartyLibs/Wavefront/tiny_obj_loader.h
../../examples/Importers/ImportColladaDemo/LoadMeshFromCollada.cpp
../../examples/Importers/ImportObjDemo/LoadMeshFromObj.cpp
../../examples/Importers/ImportObjDemo/Wavefront2GLInstanceGraphicsShape.cpp
../../examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp
../../examples/Importers/ImportURDFDemo/MyMultiBodyCreator.cpp
../../examples/Importers/ImportURDFDemo/URDF2Bullet.cpp
../../examples/Importers/ImportURDFDemo/UrdfParser.cpp
../../examples/Importers/ImportURDFDemo/urdfStringSplit.cpp
../../examples/Importers/ImportURDFDemo/DefaultVisualShapeConverter.cpp
../../examples/MultiThreading/b3PosixThreadSupport.cpp
../../examples/MultiThreading/b3Win32ThreadSupport.cpp
../../examples/MultiThreading/b3ThreadSupportInterface.cpp
)
IF(WIN32)
@@ -23,7 +67,7 @@ ADD_LIBRARY(pybullet SHARED ${pybullet_SRCS})
SET_TARGET_PROPERTIES(pybullet PROPERTIES VERSION ${BULLET_VERSION})
SET_TARGET_PROPERTIES(pybullet PROPERTIES SOVERSION ${BULLET_VERSION})
TARGET_LINK_LIBRARIES(pybullet BulletExampleBrowserLib BulletSoftBody BulletDynamics BulletCollision BulletInverseDynamicsUtils BulletInverseDynamics LinearMath OpenGLWindow gwen Bullet3Common ${PYTHON_LIBRARIES})
TARGET_LINK_LIBRARIES(pybullet BulletExampleBrowserLib BulletFileLoader BulletWorldImporter BulletSoftBody BulletDynamics BulletCollision BulletInverseDynamicsUtils BulletInverseDynamics LinearMath OpenGLWindow gwen Bullet3Common ${PYTHON_LIBRARIES})

View File

@@ -1,7 +1,6 @@
#include "../SharedMemory/SharedMemoryInProcessPhysicsC_API.h"
#include "../SharedMemory/PhysicsClientC_API.h"
#include "../SharedMemory/PhysicsDirectC_API.h"
#include "../SharedMemory/SharedMemoryInProcessPhysicsC_API.h"
#ifdef __APPLE__
@@ -127,14 +126,14 @@ pybullet_loadURDF(PyObject* self, PyObject* args)
int size= PySequence_Size(args);
int bodyIndex = -1;
const char* urdfFileName=0;
const char* urdfFileName="";
float startPosX =0;
float startPosY =0;
float startPosZ = 1;
float startOrnX = 0;
float startOrnY = 0;
float startOrnZ = 0;
float startOwnW = 1;
float startOrnW = 1;
printf("size=%d\n", size);
if (0==sm)
{
@@ -152,12 +151,13 @@ pybullet_loadURDF(PyObject* self, PyObject* args)
&startPosX,&startPosY,&startPosZ))
return NULL;
}
if (size==7)
if (size==8)
{
if (!PyArg_ParseTuple(args, "sfffffff", &urdfFileName,
&startPosX,startPosY,&startPosZ,
&startOrnX,&startOrnY,&startOrnZ, &startOwnW))
&startPosX,&startPosY,&startPosZ,
&startOrnX,&startOrnY,&startOrnZ, &startOrnW))
return NULL;
}
{
@@ -224,25 +224,114 @@ pybullet_setGravity(PyObject* self, PyObject* args)
//ASSERT_EQ(b3GetStatusType(statusHandle), CMD_CLIENT_COMMAND_COMPLETED);
}
if (1)
{
PyObject *pylist;
PyObject *item;
int i;
int num=3;
pylist = PyTuple_New(num);
for (i = 0; i < num; i++)
{
item = PyFloat_FromDouble(i);
PyTuple_SetItem(pylist, i, item);
}
return pylist;
}
Py_INCREF(Py_None);
return Py_None;
}
static void pybullet_internalGetBasePositionAndOrientation(int bodyIndex, double basePosition[3],double baseOrientation[3])
{
basePosition[0] = 0.;
basePosition[1] = 0.;
basePosition[2] = 0.;
baseOrientation[0] = 0.;
baseOrientation[1] = 0.;
baseOrientation[2] = 0.;
baseOrientation[3] = 1.;
{
{
b3SharedMemoryCommandHandle cmd_handle =
b3RequestActualStateCommandInit(sm, bodyIndex);
b3SharedMemoryStatusHandle status_handle =
b3SubmitClientCommandAndWaitStatus(sm, cmd_handle);
const int status_type = b3GetStatusType(status_handle);
const double* actualStateQ;
b3GetStatusActualState(status_handle, 0/* body_unique_id */,
0/* num_degree_of_freedom_q */,
0/* num_degree_of_freedom_u */, 0 /*root_local_inertial_frame*/,
&actualStateQ , 0 /* actual_state_q_dot */,
0 /* joint_reaction_forces */);
//now, position x,y,z = actualStateQ[0],actualStateQ[1],actualStateQ[2]
//and orientation x,y,z,w = actualStateQ[3],actualStateQ[4],actualStateQ[5],actualStateQ[6]
basePosition[0] = actualStateQ[0];
basePosition[1] = actualStateQ[1];
basePosition[2] = actualStateQ[2];
baseOrientation[0] = actualStateQ[3];
baseOrientation[1] = actualStateQ[4];
baseOrientation[2] = actualStateQ[5];
baseOrientation[3] = actualStateQ[6];
}
}
}
static PyObject *
pybullet_getBasePositionAndOrientation(PyObject* self, PyObject* args)
{
if (0==sm)
{
PyErr_SetString(SpamError, "Not connected to physics server.");
return NULL;
}
int bodyIndex = -1;
if (!PyArg_ParseTuple(args, "i", &bodyIndex ))
{
PyErr_SetString(SpamError, "Expected a body index (integer).");
return NULL;
}
double basePosition[3];
double baseOrientation[4];
pybullet_internalGetBasePositionAndOrientation(bodyIndex,basePosition,baseOrientation);
PyObject *pylistPos;
{
PyObject *item;
int i;
int num=3;
pylistPos = PyTuple_New(num);
for (i = 0; i < num; i++)
{
item = PyFloat_FromDouble(basePosition[i]);
PyTuple_SetItem(pylistPos, i, item);
}
}
PyObject *pylistOrientation;
{
PyObject *item;
int i;
int num=4;
pylistOrientation = PyTuple_New(num);
for (i = 0; i < num; i++)
{
item = PyFloat_FromDouble(baseOrientation[i]);
PyTuple_SetItem(pylistOrientation, i, item);
}
}
{
PyObject *pylist;
pylist = PyTuple_New(2);
PyTuple_SetItem(pylist,0,pylistPos);
PyTuple_SetItem(pylist,1,pylistOrientation);
return pylist;
}
}
static PyObject *
pybullet_getNumJoints(PyObject* self, PyObject* args)
{
@@ -290,6 +379,9 @@ static PyMethodDef SpamMethods[] = {
{"setGravity", pybullet_setGravity, METH_VARARGS,
"Set the gravity acceleration (x,y,z)."},
{"getBasePositionAndOrientation", pybullet_getBasePositionAndOrientation, METH_VARARGS,
"Get the world position and orientation of the base of the object. (x,y,z) position vector and (x,y,z,w) quaternion orientation."},
{"getNumsetGravity", pybullet_setGravity, METH_VARARGS,
"Set the gravity acceleration (x,y,z)."},
{
@@ -329,10 +421,16 @@ initpybullet(void)
SpamMethods, "Python bindings for Bullet");
#endif
#if PY_MAJOR_VERSION >= 3
if (m == NULL)
return m;
#else
if (m == NULL)
return;
#endif
PyModule_AddIntConstant (m, "SHARED_MEMORY", eCONNECT_SHARED_MEMORY); // user read
PyModule_AddIntConstant (m, "SHARED_MEMORY", eCONNECT_SHARED_MEMORY); // user read
PyModule_AddIntConstant (m, "DIRECT", eCONNECT_DIRECT); // user read
PyModule_AddIntConstant (m, "GUI", eCONNECT_GUI); // user read

View File

@@ -2,7 +2,7 @@ import pybullet
import time
#choose connection method: GUI, DIRECT, SHARED_MEMORY
pybullet.connect(pybullet.SHARED_MEMORY)
pybullet.connect(pybullet.GUI)
#load URDF, given a relative or absolute file+path
obj = pybullet.loadURDF("r2d2.urdf")
@@ -24,6 +24,8 @@ pybullet.setGravity(0,0,-9.8)
t_end = time.time() + 5
while time.time() < t_end:
pybullet.stepSimulation()
posAndOrn = pybullet.getBasePositionAndOrientation(obj)
print (posAndOrn)
print ("finished")
#remove all objects

View File

@@ -363,17 +363,33 @@ static const char* updateAabbsKernelCL= \
" int m_compoundBvhIndex;\n"
" };\n"
" int m_shapeType;\n"
" int m_shapeIndex;\n"
" union\n"
" {\n"
" int m_shapeIndex;\n"
" float m_height;\n"
" };\n"
"};\n"
"typedef struct b3GpuChildShape b3GpuChildShape_t;\n"
"struct b3GpuChildShape\n"
"{\n"
" b3Float4 m_childPosition;\n"
" b3Quat m_childOrientation;\n"
" int m_shapeIndex;\n"
" int m_unused0;\n"
" int m_unused1;\n"
" int m_unused2;\n"
" union\n"
" {\n"
" int m_shapeIndex;//used for SHAPE_COMPOUND_OF_CONVEX_HULLS\n"
" int m_capsuleAxis;\n"
" };\n"
" union \n"
" {\n"
" float m_radius;//used for childshape of SHAPE_COMPOUND_OF_SPHERES or SHAPE_COMPOUND_OF_CAPSULES\n"
" int m_numChildShapes;//used for compound shape\n"
" };\n"
" union \n"
" {\n"
" float m_height;//used for childshape of SHAPE_COMPOUND_OF_CAPSULES\n"
" int m_collidableShapeIndex;\n"
" };\n"
" int m_shapeType;\n"
"};\n"
"struct b3CompoundOverlappingPair\n"
"{\n"

View File

@@ -25,6 +25,8 @@ TODO:
#ifndef BT_SLIDER_CONSTRAINT_H
#define BT_SLIDER_CONSTRAINT_H
#include "LinearMath/btScalar.h"//for BT_USE_DOUBLE_PRECISION
#ifdef BT_USE_DOUBLE_PRECISION
#define btSliderConstraintData2 btSliderConstraintDoubleData
#define btSliderConstraintDataName "btSliderConstraintDoubleData"

View File

@@ -395,6 +395,19 @@ protected:
return &m_valueArray[index];
}
Key getKeyAtIndex(int index)
{
btAssert(index < m_keyArray.size());
return m_keyArray[index];
}
const Key getKeyAtIndex(int index) const
{
btAssert(index < m_keyArray.size());
return m_keyArray[index];
}
Value* operator[](const Key& key) {
return find(key);
}

View File

@@ -17,6 +17,7 @@ subject to the following restrictions:
#ifndef BT_SCALAR_H
#define BT_SCALAR_H
#ifdef BT_MANAGED_CODE
//Aligned data types not supported in managed code
#pragma unmanaged
@@ -104,7 +105,7 @@ inline int btGetVersion()
#ifdef BT_DEBUG
#ifdef _MSC_VER
#include <stdio.h>
#define btAssert(x) { if(!(x)){printf("Assert "__FILE__ ":%u ("#x")\n", __LINE__);__debugbreak(); }}
#define btAssert(x) { if(!(x)){printf("Assert "__FILE__ ":%u (%s)\n", __LINE__, #x);__debugbreak(); }}
#else//_MSC_VER
#include <assert.h>
#define btAssert assert

View File

@@ -73,9 +73,6 @@
"../../examples/Importers/ImportURDFDemo/MyMultiBodyCreator.h",
"../../examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp",
"../../examples/Importers/ImportURDFDemo/BulletUrdfImporter.h",
"../../examples/Importers/ImportURDFDemo/UrdfParser.cpp",
"../../examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp",
"../../examples/Importers/ImportURDFDemo/BulletUrdfImporter.h",
"../../examples/Importers/ImportURDFDemo/urdfStringSplit.cpp",
"../../examples/Importers/ImportURDFDemo/UrdfParser.cpp",
"../../examples/Importers/ImportURDFDemo/UrdfParser.h",

View File

@@ -48,6 +48,15 @@ ENDIF()
../../examples/SharedMemory/PosixSharedMemory.h
../../examples/Utils/b3ResourcePath.cpp
../../examples/Utils/b3ResourcePath.h
../../examples/SharedMemory/TinyRendererVisualShapeConverter.cpp
../../examples/SharedMemory/TinyRendererVisualShapeConverter.h
../../examples/OpenGLWindow/SimpleCamera.cpp
../../examples/OpenGLWindow/SimpleCamera.h
../../examples/TinyRenderer/geometry.cpp
../../examples/TinyRenderer/model.cpp
../../examples/TinyRenderer/tgaimage.cpp
../../examples/TinyRenderer/our_gl.cpp
../../examples/TinyRenderer/TinyRenderer.cpp
../../examples/ThirdPartyLibs/tinyxml/tinystr.cpp
../../examples/ThirdPartyLibs/tinyxml/tinyxml.cpp
../../examples/ThirdPartyLibs/tinyxml/tinyxmlerror.cpp
@@ -62,6 +71,8 @@ ENDIF()
../../examples/Importers/ImportURDFDemo/URDF2Bullet.cpp
../../examples/Importers/ImportURDFDemo/UrdfParser.cpp
../../examples/Importers/ImportURDFDemo/urdfStringSplit.cpp
)
ADD_TEST(Test_PhysicsClientServer_PASS Test_PhysicsClientServer)

View File

@@ -66,6 +66,15 @@ project ("Test_PhysicsServerLoopBack")
"../../examples/SharedMemory/Win32SharedMemory.h",
"../../examples/SharedMemory/PosixSharedMemory.cpp",
"../../examples/SharedMemory/PosixSharedMemory.h",
"../../examples/SharedMemory/TinyRendererVisualShapeConverter.cpp",
"../../examples/SharedMemory/TinyRendererVisualShapeConverter.h",
"../../examples/OpenGLWindow/SimpleCamera.cpp",
"../../examples/OpenGLWindow/SimpleCamera.h",
"../../examples/TinyRenderer/geometry.cpp",
"../../examples/TinyRenderer/model.cpp",
"../../examples/TinyRenderer/tgaimage.cpp",
"../../examples/TinyRenderer/our_gl.cpp",
"../../examples/TinyRenderer/TinyRenderer.cpp",
"../../examples/Utils/b3ResourcePath.cpp",
"../../examples/Utils/b3ResourcePath.h",
"../../examples/ThirdPartyLibs/tinyxml/tinystr.cpp",
@@ -123,6 +132,15 @@ project ("Test_PhysicsServerLoopBack")
"../../examples/SharedMemory/Win32SharedMemory.h",
"../../examples/SharedMemory/PosixSharedMemory.cpp",
"../../examples/SharedMemory/PosixSharedMemory.h",
"../../examples/SharedMemory/TinyRendererVisualShapeConverter.cpp",
"../../examples/SharedMemory/TinyRendererVisualShapeConverter.h",
"../../examples/TinyRenderer/geometry.cpp",
"../../examples/TinyRenderer/model.cpp",
"../../examples/TinyRenderer/tgaimage.cpp",
"../../examples/TinyRenderer/our_gl.cpp",
"../../examples/TinyRenderer/TinyRenderer.cpp",
"../../examples/OpenGLWindow/SimpleCamera.cpp",
"../../examples/OpenGLWindow/SimpleCamera.h",
"../../examples/Utils/b3ResourcePath.cpp",
"../../examples/Utils/b3ResourcePath.h",
"../../examples/ThirdPartyLibs/tinyxml/tinystr.cpp",
@@ -212,6 +230,13 @@ project ("Test_PhysicsServerInProcessExampleBrowser")
"../../examples/SharedMemory/Win32SharedMemory.h",
"../../examples/SharedMemory/PosixSharedMemory.cpp",
"../../examples/SharedMemory/PosixSharedMemory.h",
"../../examples/SharedMemory/TinyRendererVisualShapeConverter.cpp",
"../../examples/SharedMemory/TinyRendererVisualShapeConverter.h",
"../../examples/TinyRenderer/geometry.cpp",
"../../examples/TinyRenderer/model.cpp",
"../../examples/TinyRenderer/tgaimage.cpp",
"../../examples/TinyRenderer/our_gl.cpp",
"../../examples/TinyRenderer/TinyRenderer.cpp",
"../../examples/Utils/b3ResourcePath.cpp",
"../../examples/Utils/b3ResourcePath.h",
"../../examples/ThirdPartyLibs/tinyxml/tinystr.cpp",

5
xcode.command Executable file
View File

@@ -0,0 +1,5 @@
cd `dirname $0`
cd build3
./premake4_osx xcode4
open xcode4/0_Bullet3Solution.xcworkspace