mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-13 07:34:45 +00:00
update bullet so it actually works
Moved the addSourceDirectory for physics/Bullet into the Engine/Source/CMakeLists.txt file that way it can actually appear where we expect it to in the solution explorer.
This commit is contained in:
parent
c7be48130a
commit
13fa178cf6
5986 changed files with 1811270 additions and 453803 deletions
|
|
@ -13,7 +13,6 @@ subject to the following restrictions:
|
|||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#include "BasicExample.h"
|
||||
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
|
|
@ -26,23 +25,22 @@ subject to the following restrictions:
|
|||
|
||||
#include "../CommonInterfaces/CommonRigidBodyBase.h"
|
||||
|
||||
|
||||
struct BasicExample : public CommonRigidBodyBase
|
||||
{
|
||||
BasicExample(struct GUIHelperInterface* helper)
|
||||
:CommonRigidBodyBase(helper)
|
||||
: CommonRigidBodyBase(helper)
|
||||
{
|
||||
}
|
||||
virtual ~BasicExample(){}
|
||||
virtual ~BasicExample() {}
|
||||
virtual void initPhysics();
|
||||
virtual void renderScene();
|
||||
void resetCamera()
|
||||
{
|
||||
float dist = 4;
|
||||
float pitch = 52;
|
||||
float yaw = 35;
|
||||
float targetPos[3]={0,0,0};
|
||||
m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
|
||||
float pitch = -35;
|
||||
float yaw = 52;
|
||||
float targetPos[3] = {0, 0, 0};
|
||||
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -55,33 +53,30 @@ void BasicExample::initPhysics()
|
|||
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
|
||||
|
||||
if (m_dynamicsWorld->getDebugDrawer())
|
||||
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints);
|
||||
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints);
|
||||
|
||||
///create a few basic rigid bodies
|
||||
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));
|
||||
|
||||
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.)));
|
||||
|
||||
//groundShape->initializePolyhedralFeatures();
|
||||
//btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50);
|
||||
|
||||
|
||||
m_collisionShapes.push_back(groundShape);
|
||||
|
||||
btTransform groundTransform;
|
||||
groundTransform.setIdentity();
|
||||
groundTransform.setOrigin(btVector3(0,-50,0));
|
||||
groundTransform.setOrigin(btVector3(0, -50, 0));
|
||||
|
||||
{
|
||||
btScalar mass(0.);
|
||||
createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1));
|
||||
createRigidBody(mass, groundTransform, groundShape, btVector4(0, 0, 1, 1));
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
//create a few dynamic rigidbodies
|
||||
// Re-using the same collision is better for memory usage and performance
|
||||
|
||||
btBoxShape* colShape = createBoxShape(btVector3(.1,.1,.1));
|
||||
|
||||
btBoxShape* colShape = createBoxShape(btVector3(.1, .1, .1));
|
||||
|
||||
//btCollisionShape* colShape = new btSphereShape(btScalar(1.));
|
||||
m_collisionShapes.push_back(colShape);
|
||||
|
|
@ -90,62 +85,43 @@ void BasicExample::initPhysics()
|
|||
btTransform startTransform;
|
||||
startTransform.setIdentity();
|
||||
|
||||
btScalar mass(1.f);
|
||||
btScalar mass(1.f);
|
||||
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
bool isDynamic = (mass != 0.f);
|
||||
|
||||
btVector3 localInertia(0,0,0);
|
||||
btVector3 localInertia(0, 0, 0);
|
||||
if (isDynamic)
|
||||
colShape->calculateLocalInertia(mass,localInertia);
|
||||
colShape->calculateLocalInertia(mass, localInertia);
|
||||
|
||||
|
||||
for (int k=0;k<ARRAY_SIZE_Y;k++)
|
||||
for (int k = 0; k < ARRAY_SIZE_Y; k++)
|
||||
{
|
||||
for (int i=0;i<ARRAY_SIZE_X;i++)
|
||||
for (int i = 0; i < ARRAY_SIZE_X; i++)
|
||||
{
|
||||
for(int j = 0;j<ARRAY_SIZE_Z;j++)
|
||||
for (int j = 0; j < ARRAY_SIZE_Z; j++)
|
||||
{
|
||||
startTransform.setOrigin(btVector3(
|
||||
btScalar(0.2*i),
|
||||
btScalar(2+.2*k),
|
||||
btScalar(0.2*j)));
|
||||
|
||||
|
||||
createRigidBody(mass,startTransform,colShape);
|
||||
|
||||
btScalar(0.2 * i),
|
||||
btScalar(2 + .2 * k),
|
||||
btScalar(0.2 * j)));
|
||||
|
||||
createRigidBody(mass, startTransform, colShape);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void BasicExample::renderScene()
|
||||
{
|
||||
CommonRigidBodyBase::renderScene();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
CommonExampleInterface* BasicExampleCreateFunc(CommonExampleOptions& options)
|
||||
CommonExampleInterface* BasicExampleCreateFunc(CommonExampleOptions& options)
|
||||
{
|
||||
return new BasicExample(options.m_guiHelper);
|
||||
|
||||
}
|
||||
|
||||
|
||||
B3_STANDALONE_EXAMPLE(BasicExampleCreateFunc)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ subject to the following restrictions:
|
|||
#ifndef BASIC_EXAMPLE_H
|
||||
#define BASIC_EXAMPLE_H
|
||||
|
||||
class CommonExampleInterface* BasicExampleCreateFunc(struct CommonExampleOptions& options);
|
||||
class CommonExampleInterface* BasicExampleCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
|
||||
#endif //BASIC_DEMO_PHYSICS_SETUP_H
|
||||
#endif //BASIC_DEMO_PHYSICS_SETUP_H
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ INCLUDE_DIRECTORIES(
|
|||
${BULLET_PHYSICS_SOURCE_DIR}/src
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/btgui
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/examples
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/Glew
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/glad
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ SET(AppBasicExampleGui_SRCS
|
|||
ADD_DEFINITIONS(-DB3_USE_STANDALONE_EXAMPLE)
|
||||
|
||||
LINK_LIBRARIES(
|
||||
BulletDynamics BulletCollision LinearMath OpenGLWindow Bullet3Common ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}
|
||||
BulletDynamics BulletCollision LinearMath OpenGLWindow Bullet3Common
|
||||
)
|
||||
|
||||
#some code to support OpenGL and Glew cross platform
|
||||
|
|
@ -69,11 +69,12 @@ IF (WIN32)
|
|||
${BULLET_PHYSICS_SOURCE_DIR}/btgui/OpenGLWindow/GlewWindows
|
||||
)
|
||||
ADD_DEFINITIONS(-DGLEW_STATIC)
|
||||
LINK_LIBRARIES( ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} )
|
||||
ELSE(WIN32)
|
||||
IF(APPLE)
|
||||
find_library(COCOA NAMES Cocoa)
|
||||
MESSAGE(${COCOA})
|
||||
link_libraries(${COCOA})
|
||||
link_libraries(${COCOA} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY})
|
||||
|
||||
ELSE(APPLE)
|
||||
INCLUDE_DIRECTORIES(
|
||||
|
|
@ -83,7 +84,8 @@ ELSE(WIN32)
|
|||
ADD_DEFINITIONS("-DGLEW_STATIC")
|
||||
ADD_DEFINITIONS("-DGLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS=1")
|
||||
|
||||
LINK_LIBRARIES( X11 pthread dl Xext)
|
||||
FIND_PACKAGE(Threads)
|
||||
LINK_LIBRARIES( ${CMAKE_THREAD_LIBS_INIT} ${DL} )
|
||||
ENDIF(APPLE)
|
||||
ENDIF(WIN32)
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ subject to the following restrictions:
|
|||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#include "BasicExample.h"
|
||||
|
||||
#include "../CommonInterfaces/CommonExampleInterface.h"
|
||||
|
|
@ -22,26 +21,21 @@ subject to the following restrictions:
|
|||
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
|
||||
#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
|
||||
|
||||
|
||||
#include "LinearMath/btTransform.h"
|
||||
#include "LinearMath/btHashMap.h"
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
DummyGUIHelper noGfx;
|
||||
|
||||
CommonExampleOptions options(&noGfx);
|
||||
CommonExampleInterface* example = BasicExampleCreateFunc(options);
|
||||
|
||||
CommonExampleInterface* example = BasicExampleCreateFunc(options);
|
||||
|
||||
example->initPhysics();
|
||||
example->stepSimulation(1.f/60.f);
|
||||
example->stepSimulation(1.f / 60.f);
|
||||
example->exitPhysics();
|
||||
|
||||
delete example;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ language "C++"
|
|||
files {
|
||||
"**.cpp",
|
||||
"**.h",
|
||||
"../CommonInterfaces/*",
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -49,6 +50,7 @@ files {
|
|||
"../ExampleBrowser/OpenGLGuiHelper.cpp",
|
||||
"../ExampleBrowser/GL_ShapeDrawer.cpp",
|
||||
"../ExampleBrowser/CollisionShape2TriangleMesh.cpp",
|
||||
"../CommonInterfaces/*",
|
||||
"../Utils/b3Clock.cpp",
|
||||
"../Utils/b3Clock.h",
|
||||
}
|
||||
|
|
@ -90,6 +92,7 @@ files {
|
|||
"../ExampleBrowser/OpenGLGuiHelper.cpp",
|
||||
"../ExampleBrowser/GL_ShapeDrawer.cpp",
|
||||
"../ExampleBrowser/CollisionShape2TriangleMesh.cpp",
|
||||
"../CommonInterfaces/*",
|
||||
"../TinyRenderer/geometry.cpp",
|
||||
"../TinyRenderer/model.cpp",
|
||||
"../TinyRenderer/tgaimage.cpp",
|
||||
|
|
@ -130,6 +133,7 @@ files {
|
|||
"*.h",
|
||||
"../StandaloneMain/main_tinyrenderer_single_example.cpp",
|
||||
"../ExampleBrowser/CollisionShape2TriangleMesh.cpp",
|
||||
"../CommonInterfaces/*",
|
||||
"../OpenGLWindow/SimpleCamera.cpp",
|
||||
"../TinyRenderer/geometry.cpp",
|
||||
"../TinyRenderer/model.cpp",
|
||||
|
|
@ -175,6 +179,7 @@ files {
|
|||
"BasicExample.cpp",
|
||||
"*.h",
|
||||
"../StandaloneMain/hellovr_opengl_main.cpp",
|
||||
"../CommonInterfaces/*",
|
||||
"../ExampleBrowser/OpenGLGuiHelper.cpp",
|
||||
"../ExampleBrowser/GL_ShapeDrawer.cpp",
|
||||
"../ExampleBrowser/CollisionShape2TriangleMesh.cpp",
|
||||
|
|
@ -182,12 +187,14 @@ files {
|
|||
"../ThirdPartyLibs/openvr/samples/shared/lodepng.h",
|
||||
"../ThirdPartyLibs/openvr/samples/shared/Matrices.cpp",
|
||||
"../ThirdPartyLibs/openvr/samples/shared/Matrices.h",
|
||||
"../ThirdPartyLibs/openvr/samples/shared/strtools.cpp",
|
||||
"../ThirdPartyLibs/openvr/samples/shared/pathtools.cpp",
|
||||
"../ThirdPartyLibs/openvr/samples/shared/pathtools.h",
|
||||
"../ThirdPartyLibs/openvr/samples/shared/Vectors.h",
|
||||
"../Utils/b3Clock.cpp",
|
||||
"../Utils/b3Clock.h",
|
||||
|
||||
"../Utils/ChromeTraceUtil.cpp",
|
||||
"../Utils/ChromeTraceUtil.h",
|
||||
}
|
||||
|
||||
if os.is("Windows") then
|
||||
|
|
@ -200,4 +207,4 @@ if os.is("MacOSX") then
|
|||
links{"Cocoa.framework"}
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
Copyright (c) 2003-2006 Erwin Coumans https://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.
|
||||
|
|
@ -15,9 +15,6 @@ subject to the following restrictions:
|
|||
#ifndef BENCHMARK_EXAMPLE_H
|
||||
#define BENCHMARK_EXAMPLE_H
|
||||
|
||||
class CommonExampleInterface* BenchmarkCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
|
||||
|
||||
#endif //BENCHMARK_EXAMPLE_H
|
||||
class CommonExampleInterface* BenchmarkCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
#endif //BENCHMARK_EXAMPLE_H
|
||||
|
|
|
|||
647
Engine/lib/bullet/examples/Benchmarks/HaltonData.h
Normal file
647
Engine/lib/bullet/examples/Benchmarks/HaltonData.h
Normal file
|
|
@ -0,0 +1,647 @@
|
|||
// Generated by ./Tools/mksrc.py
|
||||
|
||||
// h00
|
||||
const int h00_numv = 14;
|
||||
const float h00_volu = 0.105869;
|
||||
const float h00_pos[3] = { -0.801161,-0.825905,-0.503586 };
|
||||
const float h00_verts[ h00_numv * 3 ] = {
|
||||
-0.198839,-0.174095,-0.496414, -0.198839,-0.073069,-0.496414, 0.355754,-0.174095,0.317906, 0.266263,0.078525,-0.113353, -0.198839,0.418138,0.148658, -0.198839,0.151957,0.285583, -0.004749,-0.165186,-0.496414, -0.198839,0.342511,-0.068863, -0.198839,-0.174095,0.341490, 0.030157,-0.174095,0.397398, -0.005096,-0.174095,-0.496414, 0.428901,-0.174095,0.139324, -0.198839,0.419530,0.145078, -0.111897,0.386202,0.018538,
|
||||
};
|
||||
// h01
|
||||
const int h01_numv = 16;
|
||||
const float h01_volu = 0.123003;
|
||||
const float h01_pos[3] = { -0.669502,-0.555335,-0.800913 };
|
||||
const float h01_verts[ h01_numv * 3 ] = {
|
||||
0.137874,0.266251,0.316069, -0.136407,-0.435756,-0.199087, -0.330498,0.127352,-0.199087, 0.378917,-0.091301,0.019367, 0.437409,0.033623,-0.016334, 0.038469,0.311615,0.180723, -0.330498,-0.343638,-0.199087, 0.193689,-0.157234,0.188948, 0.276656,-0.200503,-0.199087, 0.399981,0.033623,-0.199087, -0.039317,0.311615,-0.199087, -0.330498,0.071941,0.228464, 0.134604,-0.192045,0.183974, -0.243556,0.115632,0.315865, 0.128360,0.261346,0.324519, -0.053858,0.233367,0.333678,
|
||||
};
|
||||
// h02
|
||||
const int h02_numv = 22;
|
||||
const float h02_volu = 0.069699;
|
||||
const float h02_pos[3] = { -0.226726,-0.554920,-0.490680 };
|
||||
const float h02_verts[ h02_numv * 3 ] = {
|
||||
0.092179,-0.226103,0.260087, -0.296734,0.272195,0.041665, -0.063859,-0.091716,-0.290866, 0.291800,-0.116083,-0.104671, -0.005367,0.033207,-0.326567, 0.057499,0.071569,-0.315604, -0.314416,0.260931,0.014286, 0.001987,-0.310858,0.106391, 0.200664,0.041526,0.249449, -0.249087,-0.157649,-0.121285, 0.164143,-0.213455,-0.116915, 0.086533,-0.112211,0.311781, 0.301609,-0.100599,-0.031006, -0.013037,0.041374,0.269240, 0.214238,-0.145305,0.159971, -0.177599,0.337949,0.022880, -0.304902,0.265836,0.005836, 0.151444,0.029502,0.298046, 0.226514,0.065723,0.196331, -0.078156,0.329100,-0.024159, 0.053890,0.084483,0.272741, -0.198047,0.327898,0.050872,
|
||||
};
|
||||
// h03
|
||||
const int h03_numv = 18;
|
||||
const float h03_volu = 0.069585;
|
||||
const float h03_pos[3] = { -0.013871,-0.718833,-0.869565 };
|
||||
const float h03_verts[ h03_numv * 3 ] = {
|
||||
-0.207492,-0.281167,-0.130435, 0.113468,0.049972,0.264160, -0.007999,0.353837,-0.130435, 0.078945,0.047830,0.274214, -0.003048,-0.281167,0.119131, -0.048711,-0.049541,0.261970, -0.155356,0.235482,0.063281, 0.163083,-0.281167,0.065052, -0.378975,-0.037005,-0.130435, -0.276714,0.072197,0.088019, 0.263172,-0.281167,-0.130435, 0.247851,0.256254,-0.130435, 0.308871,0.008019,-0.130435, 0.268707,0.210552,0.010520, 0.116203,0.335344,-0.130435, 0.263499,0.226082,-0.009852, -0.255650,0.197121,-0.130435, -0.218222,0.197121,0.052318,
|
||||
};
|
||||
// h04
|
||||
const int h04_numv = 18;
|
||||
const float h04_volu = 0.049776;
|
||||
const float h04_pos[3] = { 0.037853,-0.892026,-0.431971 };
|
||||
const float h04_verts[ h04_numv * 3 ] = {
|
||||
-0.100436,0.123651,-0.175624, 0.353999,-0.060233,0.083056, 0.061744,0.223165,-0.173434, -0.054772,-0.107974,-0.318463, 0.079577,0.232813,-0.134685, 0.365414,-0.107974,0.061633, 0.111359,-0.107974,-0.372542, -0.262592,0.026248,0.047682, -0.327682,-0.107974,0.107959, -0.050341,0.191801,0.101262, -0.248632,-0.107974,0.379486, -0.172400,0.111003,0.201378, 0.324182,-0.074827,0.146980, 0.312271,-0.107974,0.174077, -0.248842,-0.086035,0.364515, -0.264984,-0.107974,0.352871, 0.027221,0.221023,-0.163380, 0.037030,0.236507,-0.089715,
|
||||
};
|
||||
// h05
|
||||
const int h05_numv = 12;
|
||||
const float h05_volu = 0.060052;
|
||||
const float h05_pos[3] = { -0.361440,-0.882680,-0.728709 };
|
||||
const float h05_verts[ h05_numv * 3 ] = {
|
||||
-0.444817,-0.117320,-0.271291, 0.140076,-0.117320,-0.271291, 0.136701,0.016901,0.344420, -0.031407,0.126842,-0.271291, 0.070855,0.236044,-0.052837, -0.114373,0.170111,0.116744, 0.344521,-0.117320,-0.021725, 0.298857,0.114305,0.121114, -0.444469,-0.108411,-0.271291, 0.071611,-0.117320,0.404697, -0.173458,0.135300,0.111770, -0.010820,-0.117320,0.364447,
|
||||
};
|
||||
// h06
|
||||
const int h06_numv = 16;
|
||||
const float h06_volu = 0.067458;
|
||||
const float h06_pos[3] = { 0.885250,-0.616510,-0.689541 };
|
||||
const float h06_verts[ h06_numv * 3 ] = {
|
||||
-0.230633,-0.043361,0.025874, -0.001305,-0.383490,-0.079103, 0.114750,-0.383490,0.055891, 0.114750,0.141993,-0.310459, 0.042572,0.157183,0.322917, 0.114750,0.349093,0.009138, 0.114750,-0.209139,-0.310459, 0.114750,-0.383490,-0.220772, 0.114750,0.143660,0.326163, -0.023969,0.120047,-0.310459, -0.230634,0.218132,-0.108639, -0.072958,0.349093,0.054965, -0.138827,-0.119612,0.199579, 0.020027,-0.383490,0.025057, -0.041036,-0.038390,0.301047, 0.114750,-0.091790,0.305977,
|
||||
};
|
||||
// h07
|
||||
const int h07_numv = 18;
|
||||
const float h07_volu = 0.100040;
|
||||
const float h07_pos[3] = { 0.439796,-0.816642,-0.690430 };
|
||||
const float h07_verts[ h07_numv * 3 ] = {
|
||||
-0.290584,-0.183358,-0.114083, 0.444149,-0.183358,-0.078214, -0.340199,0.147781,0.085025, -0.036530,-0.183358,0.320092, -0.047944,-0.135617,0.341515, 0.306627,0.080520,0.200468, -0.322367,0.157429,0.123774, 0.465481,-0.183358,0.025945, 0.214820,0.156771,0.026763, -0.144796,0.105827,-0.309570, 0.159858,-0.183358,-0.309570, -0.190496,-0.183358,-0.309570, -0.155412,0.298926,0.091748, -0.184960,0.308361,-0.168615, -0.134267,0.332806,-0.106403, 0.196572,0.110989,0.274357, -0.157992,0.325768,-0.131745, -0.142419,0.333870,-0.095406,
|
||||
};
|
||||
// h08
|
||||
const int h08_numv = 22;
|
||||
const float h08_volu = 0.095115;
|
||||
const float h08_pos[3] = { 0.582909,-0.382310,-0.514785 };
|
||||
const float h08_verts[ h08_numv * 3 ] = {
|
||||
0.039696,0.333763,-0.114253, -0.040720,0.073975,-0.343437, -0.281418,0.194479,0.107755, 0.071707,-0.016068,-0.283395, 0.071707,-0.277561,-0.148882, 0.163514,-0.353812,0.024824, 0.072380,0.310495,-0.182078, 0.344912,-0.077018,0.148161, 0.229382,0.114893,-0.119790, 0.056106,0.251986,0.176207, 0.261304,-0.272590,0.126291, 0.053460,-0.323343,0.098712, -0.280479,0.198156,0.096008, -0.285532,-0.100462,-0.271051, 0.094134,-0.250952,0.200497, -0.277380,-0.101526,-0.282048, -0.010614,0.002589,0.315575, -0.026292,0.211375,0.249710, 0.146296,0.123570,0.286302, 0.056041,0.119791,0.321947, -0.290185,0.102104,0.127875, -0.298525,-0.135406,-0.083897,
|
||||
};
|
||||
// h09
|
||||
const int h09_numv = 16;
|
||||
const float h09_volu = 0.059582;
|
||||
const float h09_pos[3] = { 0.627742,-0.657906,-0.898694 };
|
||||
const float h09_verts[ h09_numv * 3 ] = {
|
||||
-0.028087,-0.342094,-0.101306, 0.372258,-0.342094,-0.101306, 0.233539,0.161443,-0.101306, 0.372258,-0.167743,-0.101306, 0.256203,-0.342094,0.130050, 0.372258,-0.342094,-0.011619, -0.322212,0.174071,0.101861, 0.026875,-0.001965,0.235027, -0.098160,0.388838,-0.101306, 0.026875,0.259528,0.100514, -0.332742,-0.052909,-0.101306, -0.085552,0.349571,0.040471, -0.393762,0.195327,-0.101306, -0.372906,0.149626,0.039648, -0.378114,0.165155,0.019276, -0.345937,0.167033,0.076519,
|
||||
};
|
||||
// h10
|
||||
const int h10_numv = 18;
|
||||
const float h10_volu = 0.082139;
|
||||
const float h10_pos[3] = { -0.348593,-0.203405,-0.827574 };
|
||||
const float h10_verts[ h10_numv * 3 ] = {
|
||||
0.351136,-0.038001,-0.172426, 0.318157,0.110282,-0.172426, -0.183035,-0.085679,0.342730, -0.360226,-0.040315,-0.172426, 0.190400,0.248876,-0.172426, 0.296736,0.161596,-0.025823, 0.116500,-0.318307,0.010327, -0.282440,-0.040315,0.207384, -0.155944,0.334915,-0.140051, -0.055732,-0.013566,0.359774, 0.296359,0.169251,-0.045236, -0.155944,0.347503,-0.172426, 0.079072,-0.318307,-0.172426, 0.043711,-0.022416,0.312735, 0.326723,-0.161591,-0.172426, 0.179366,-0.279946,0.021290, 0.100706,0.105108,0.263039, 0.042697,0.111008,0.290353,
|
||||
};
|
||||
// h11
|
||||
const int h11_numv = 18;
|
||||
const float h11_volu = 0.058443;
|
||||
const float h11_pos[3] = { -0.902277,0.042835,-0.283464 };
|
||||
const float h11_verts[ h11_numv * 3 ] = {
|
||||
0.065494,-0.341848,-0.057123, 0.194525,0.153131,-0.091230, -0.097723,-0.350111,0.163707, 0.194525,-0.144351,0.061796, 0.065493,0.122511,-0.295991, -0.097723,-0.183345,0.306682, -0.097723,0.152153,0.335446, -0.097723,-0.428001,-0.052654, 0.107269,-0.156775,0.196004, -0.097723,0.199975,-0.375687, 0.037223,0.358435,0.033582, -0.097723,0.406471,-0.057020, -0.067761,-0.416891,-0.051054, -0.040073,-0.340339,0.134552, 0.056142,-0.350169,-0.055126, 0.004412,-0.376327,-0.008857, 0.025793,-0.108438,0.290488, -0.096343,0.152412,0.335215,
|
||||
};
|
||||
// h12
|
||||
const int h12_numv = 22;
|
||||
const float h12_volu = 0.106128;
|
||||
const float h12_pos[3] = { -0.838340,-0.076123,-0.758521 };
|
||||
const float h12_verts[ h12_numv * 3 ] = {
|
||||
0.207307,-0.167597,0.138331, 0.129521,-0.167597,-0.241479, -0.161660,0.318933,0.099371, 0.312802,0.272050,-0.241479, -0.161660,-0.330252,0.400013, -0.074718,-0.363580,0.273473, 0.001556,0.241469,0.179066, -0.161660,-0.309043,0.422403, -0.161660,-0.407271,0.186072, -0.161660,-0.351860,-0.241479, -0.007794,-0.231211,0.419931, 0.001557,-0.222890,0.417934, 0.309084,0.269226,-0.210613, -0.161660,0.422173,-0.241479, 0.072963,0.309250,0.057032, -0.161660,0.392766,-0.014569, -0.131698,-0.297933,0.424004, -0.161660,-0.327468,0.404309, 0.114980,-0.245845,0.291286, 0.009169,-0.227496,0.411012, 0.333803,0.207633,-0.209104, 0.333803,0.220221,-0.241479,
|
||||
};
|
||||
// h13
|
||||
const int h13_numv = 22;
|
||||
const float h13_volu = 0.080573;
|
||||
const float h13_pos[3] = { -0.579196,0.019592,-0.524795 };
|
||||
const float h13_verts[ h13_numv * 3 ] = {
|
||||
-0.186181,0.213535,-0.176694, 0.154423,-0.034973,0.266436, 0.105286,0.335497,0.021835, 0.055737,-0.302317,0.075780, -0.128556,-0.121108,0.303127, 0.252786,0.058395,0.170378, -0.257588,0.145754,-0.054660, 0.097995,0.334920,0.024505, 0.093556,-0.038093,0.287537, 0.074659,0.111918,-0.442830, -0.051837,-0.263312,-0.095394, -0.257587,-0.318605,0.184208, 0.273300,-0.111989,-0.012426, 0.049940,0.173511,-0.444339, -0.026589,0.239892,0.129875, -0.128556,0.176374,0.150102, 0.038054,-0.313581,0.048402, 0.047568,-0.308676,0.039952, -0.249976,-0.323211,0.177286, -0.144164,-0.341560,0.057561, 0.174871,-0.236563,0.056995, 0.154423,-0.246614,0.084987,
|
||||
};
|
||||
// h14
|
||||
const int h14_numv = 24;
|
||||
const float h14_volu = 0.092625;
|
||||
const float h14_pos[3] = { 0.037294,-0.326434,-0.629340 };
|
||||
const float h14_verts[ h14_numv * 3 ] = {
|
||||
0.244511,-0.164440,-0.192835, -0.034752,0.085028,-0.370660, -0.037506,-0.162763,0.334991, -0.206521,-0.156917,-0.176944, 0.151340,0.267484,0.166363, 0.265137,0.142280,0.210563, 0.260084,-0.156338,-0.156496, -0.285181,0.228137,0.064806, 0.037588,-0.329085,0.107655, -0.342176,0.100614,0.114501, 0.027780,-0.344569,0.033990, -0.089151,0.284625,-0.224057, -0.059164,-0.038562,-0.370660, 0.065038,-0.057055,-0.370660, 0.036995,0.362842,0.085406, 0.062303,-0.342427,0.023935, 0.217542,-0.181847,-0.229705, 0.212334,-0.166317,-0.250077, 0.224212,0.171137,0.236256, 0.080136,-0.332779,0.062684, 0.146779,-0.002116,0.303773, 0.264198,0.138603,0.222310, 0.247091,-0.191282,0.030659, 0.255431,0.046228,0.242430,
|
||||
};
|
||||
// h15
|
||||
const int h15_numv = 16;
|
||||
const float h15_volu = 0.047330;
|
||||
const float h15_pos[3] = { 0.221274,0.213040,-0.893886 };
|
||||
const float h15_verts[ h15_numv * 3 ] = {
|
||||
-0.273508,-0.247194,0.021075, -0.214206,0.249387,-0.106114, -0.394680,0.092354,-0.106114, 0.468273,-0.026582,-0.106114, -0.379467,-0.167569,-0.106114, -0.251710,-0.306163,-0.106114, -0.130453,-0.090301,0.212222, 0.215618,0.100683,0.162583, 0.108399,0.111587,0.216806, 0.543500,0.089559,-0.106114, 0.556660,0.080198,-0.106114, 0.496376,0.018888,-0.040935, 0.000444,-0.021162,0.246756, 0.322381,0.024676,0.097420, 0.541635,0.087788,-0.096097, 0.556215,0.081512,-0.106114,
|
||||
};
|
||||
// h16
|
||||
const int h16_numv = 24;
|
||||
const float h16_volu = 0.105221;
|
||||
const float h16_pos[3] = { -0.230932,0.200668,-0.677519 };
|
||||
const float h16_verts[ h16_numv * 3 ] = {
|
||||
0.072738,-0.155197,-0.322481, 0.178698,-0.234822,-0.195293, -0.074965,-0.293065,0.140297, -0.273605,-0.069158,-0.290106, -0.242978,0.154421,0.174559, 0.321753,-0.077929,-0.004145, 0.331656,-0.130769,0.158361, -0.234281,0.105965,-0.322481, 0.057526,0.104725,-0.322481, -0.070916,0.357222,-0.022485, 0.179075,-0.242477,-0.175878, 0.305221,-0.164260,0.133584, 0.289986,0.017556,0.326217, -0.205442,0.224195,0.181431, -0.273605,-0.056571,-0.322481, -0.016955,-0.298965,0.112984, -0.012263,0.183238,-0.322481, -0.122870,0.351842,-0.002882, -0.294606,-0.004741,-0.322481, -0.298324,-0.007565,-0.291615, 0.354068,-0.072999,0.110530, 0.306083,0.044665,0.287425, 0.072223,0.006072,0.394149, -0.095479,-0.122681,0.323101,
|
||||
};
|
||||
// h17
|
||||
const int h17_numv = 26;
|
||||
const float h17_volu = 0.108916;
|
||||
const float h17_pos[3] = { 0.335926,-0.094685,-0.795267 };
|
||||
const float h17_verts[ h17_numv * 3 ] = {
|
||||
0.319363,0.022871,0.098404, -0.388160,0.060531,-0.077543, 0.353621,0.281144,-0.204733, 0.207729,0.332401,-0.001198, 0.193656,-0.174383,-0.204733, -0.101947,-0.367894,-0.204733, -0.366362,0.001562,-0.204733, -0.261637,0.131093,0.251333, 0.356211,0.239639,0.008049, -0.212790,0.222354,0.228279, -0.038549,-0.388087,0.009431, -0.033495,-0.089469,0.376490, -0.054122,-0.396189,-0.026907, 0.286680,0.046139,0.166229, 0.206263,-0.213650,-0.062955, -0.030396,-0.389151,-0.001566, -0.086298,-0.398066,-0.084150, -0.233594,-0.288804,-0.204733, -0.114208,0.286563,0.148137, -0.245105,0.217424,0.113603, 0.376946,0.258587,-0.036908, 0.381724,0.326613,-0.139554, -0.147292,0.035735,0.332290, -0.235202,0.164584,0.276109, -0.333383,-0.146721,-0.204733, -0.387783,0.052876,-0.058130,
|
||||
};
|
||||
// h18
|
||||
const int h18_numv = 18;
|
||||
const float h18_volu = 0.081077;
|
||||
const float h18_pos[3] = { 0.870716,-0.039183,-0.528244 };
|
||||
const float h18_verts[ h18_numv * 3 ] = {
|
||||
-0.102809,0.184137,0.110997, 0.129284,0.393063,-0.471756, 0.129284,0.325763,0.151471, 0.124364,0.395398,-0.471756, -0.058424,-0.228234,-0.106332, 0.057106,-0.420144,0.161620, -0.248110,-0.009363,-0.100794, -0.231701,-0.091141,0.189666, 0.129284,-0.228234,-0.152159, 0.129284,-0.433667,0.164866, 0.129284,-0.166980,0.404939, -0.141510,-0.219557,0.299761, 0.129284,0.397646,-0.471756, -0.215427,-0.032631,-0.168619, 0.102902,0.388713,-0.463077, 0.129284,0.404181,-0.453605, -0.178579,0.184137,-0.258974, -0.157844,0.203085,-0.303931,
|
||||
};
|
||||
// h19
|
||||
const int h19_numv = 16;
|
||||
const float h19_volu = 0.057269;
|
||||
const float h19_pos[3] = { 0.808301,-0.134672,-0.879100 };
|
||||
const float h19_verts[ h19_numv * 3 ] = {
|
||||
0.052980,-0.361791,-0.120900, 0.191699,-0.339845,-0.120900, -0.030366,0.427910,-0.120900, 0.191699,0.488552,-0.120900, -0.118754,0.321131,-0.120900, 0.191699,-0.132745,0.198697, 0.186779,0.490887,-0.120900, 0.003992,-0.132745,0.244524, -0.153012,0.062857,0.182237, -0.153685,-0.263706,0.080920, -0.278719,-0.134396,-0.120900, -0.266112,-0.173663,0.020877, -0.090651,0.366600,-0.055721, -0.095429,0.298574,0.046924, -0.012422,0.433588,-0.120900, 0.165316,0.484202,-0.112221,
|
||||
};
|
||||
// h20
|
||||
const int h20_numv = 30;
|
||||
const float h20_volu = 0.107509;
|
||||
const float h20_pos[3] = { 0.402458,0.140897,-0.404353 };
|
||||
const float h20_verts[ h20_numv * 3 ] = {
|
||||
-0.100408,0.282050,-0.142576, 0.065914,0.236686,0.319509, -0.125820,0.203801,0.337118, 0.365449,0.004057,-0.012894, 0.056400,0.231781,0.327959, 0.034434,0.172826,-0.326950, -0.072786,0.183730,-0.272727, -0.247229,0.030507,0.295489, 0.136546,-0.281738,0.161639, 0.289679,0.004057,-0.382865, 0.141197,0.096819,-0.392113, -0.100966,-0.328728,-0.002677, -0.140953,-0.296194,0.011269, -0.180740,0.050981,-0.242777, -0.253566,0.024492,0.286206, -0.033492,0.282050,0.184162, 0.236557,-0.271221,0.065774, 0.154159,-0.311832,0.139278, -0.301735,-0.070997,-0.114805, -0.213824,-0.199847,-0.058625, -0.310451,0.100424,0.233258, -0.241567,0.131963,0.326249, -0.062874,0.247232,-0.227963, -0.327109,0.098788,0.164544, -0.279322,-0.013228,-0.162635, -0.343405,0.077327,0.053051, -0.313038,0.127071,0.015013, -0.327307,0.104436,0.014259, -0.100027,-0.325051,-0.014425, 0.220147,-0.189444,-0.224685,
|
||||
};
|
||||
// h21
|
||||
const int h21_numv = 20;
|
||||
const float h21_volu = 0.107886;
|
||||
const float h21_pos[3] = { -0.701261,0.516623,-0.734170 };
|
||||
const float h21_verts[ h21_numv * 3 ] = {
|
||||
0.220060,-0.162111,0.233880, -0.071194,0.139979,-0.265830, 0.326350,0.086982,0.076961, 0.175723,-0.320696,-0.265830, -0.194481,0.286846,0.262411, 0.236048,-0.209990,-0.265830, -0.298739,0.200252,0.166960, 0.264887,-0.091760,0.238083, 0.347459,0.035887,0.053770, -0.298739,0.031984,-0.265830, -0.298739,-0.199980,-0.038920, -0.298739,-0.170573,-0.265830, -0.064116,-0.283496,0.032682, 0.172005,-0.323520,-0.234964, 0.067327,0.317485,0.021628, 0.227351,-0.161534,0.231210, 0.015724,0.286846,0.365050, -0.065674,0.367082,0.311546, 0.153155,0.171345,0.362933, 0.139764,0.180879,0.371107,
|
||||
};
|
||||
// h22
|
||||
const int h22_numv = 14;
|
||||
const float h22_volu = 0.065276;
|
||||
const float h22_pos[3] = { -0.383570,0.726249,-0.891974 };
|
||||
const float h22_verts[ h22_numv * 3 ] = {
|
||||
0.403835,0.273751,-0.108026, -0.250365,0.107859,0.179431, -0.224444,0.273751,-0.108026, 0.311631,-0.076337,-0.108026, -0.388885,-0.069647,-0.108026, 0.349740,0.107545,0.033083, 0.400677,0.273751,-0.064850, -0.189576,0.273751,0.079255, 0.008658,-0.122644,0.234765, -0.081643,-0.419616,-0.108026, 0.029768,-0.173739,0.211573, 0.125191,-0.098941,0.194122, 0.140375,-0.342343,-0.108026, 0.081722,-0.168359,0.191970,
|
||||
};
|
||||
// h23
|
||||
const int h23_numv = 16;
|
||||
const float h23_volu = 0.051599;
|
||||
const float h23_pos[3] = { -0.800668,0.450995,-0.472891 };
|
||||
const float h23_verts[ h23_numv * 3 ] = {
|
||||
0.035291,-0.217869,-0.228598, -0.199332,-0.134353,-0.300199, -0.199332,0.265879,-0.094319, -0.095074,0.352473,0.001132, -0.199332,-0.001690,0.132407, -0.199332,-0.208186,-0.186260, 0.189555,0.299490,0.167366, -0.199332,0.309177,-0.027504, -0.064385,-0.049725,0.223009, -0.036116,-0.285650,-0.106564, 0.116475,0.143410,0.211970, 0.319467,-0.096483,-0.027399, 0.092916,-0.255030,0.098198, 0.194883,-0.191512,0.077971, 0.239171,0.246507,0.109828, 0.115131,0.352473,0.103771,
|
||||
};
|
||||
// h24
|
||||
const int h24_numv = 12;
|
||||
const float h24_volu = 0.050770;
|
||||
const float h24_pos[3] = { -0.845297,0.862613,-0.757515 };
|
||||
const float h24_verts[ h24_numv * 3 ] = {
|
||||
0.078361,0.021092,0.334891, -0.154703,-0.145738,0.190305, -0.154703,0.137387,-0.242485, -0.154703,-0.314006,-0.242485, 0.072842,-0.206011,-0.242485, 0.237283,0.137387,-0.242485, -0.154703,-0.102441,0.257120, -0.050445,-0.059144,0.285756, 0.211362,-0.028505,0.044972, -0.154703,0.137387,0.380489, 0.272151,0.137387,-0.055204, 0.060041,0.137387,0.393596,
|
||||
};
|
||||
// h25
|
||||
const int h25_numv = 16;
|
||||
const float h25_volu = 0.064196;
|
||||
const float h25_pos[3] = { 0.265380,0.609017,-0.859766 };
|
||||
const float h25_verts[ h25_numv * 3 ] = {
|
||||
0.171512,-0.295294,0.128463, -0.112864,0.390983,-0.140234, -0.179972,0.258217,0.163631, -0.171482,0.390983,0.031499, -0.146465,0.312621,0.159756, 0.063572,-0.117444,0.267684, -0.245115,0.390983,-0.140234, -0.337319,0.040895,-0.140234, 0.499394,-0.306418,-0.140234, 0.112578,-0.021086,0.259138, 0.074204,-0.220888,0.227450, 0.064293,-0.284390,0.182686, -0.258312,-0.146590,-0.140234, 0.497529,-0.308188,-0.130217, -0.299210,0.224777,0.000875, -0.248273,0.390983,-0.097058,
|
||||
};
|
||||
// h26
|
||||
const int h26_numv = 24;
|
||||
const float h26_volu = 0.101687;
|
||||
const float h26_pos[3] = { -0.341007,0.877992,-0.537072 };
|
||||
const float h26_verts[ h26_numv * 3 ] = {
|
||||
0.358114,0.122008,-0.419752, -0.168425,-0.052359,0.397165, -0.220490,-0.180490,0.174009, 0.459922,0.043646,-0.162938, 0.324251,-0.109249,-0.070985, -0.202046,0.011183,0.424477, 0.252084,0.007514,0.202105, -0.286958,0.122008,0.388199, 0.307177,-0.044198,-0.321819, 0.426415,-0.010758,-0.159063, 0.082627,-0.250684,-0.160780, -0.033904,-0.274387,-0.120138, -0.232139,0.122008,-0.275647, -0.292928,-0.043884,-0.175471, -0.344531,-0.074523,0.167952, -0.207099,-0.190024,0.165835, -0.444249,0.122008,0.173153, -0.425929,0.005713,0.114448, 0.327136,0.122008,0.185091, -0.202046,0.122008,0.443480, 0.434905,0.122008,-0.291195, 0.483509,0.122008,-0.120325, -0.187210,-0.038985,0.408631, -0.270106,-0.127507,0.231547,
|
||||
};
|
||||
// h27
|
||||
const int h27_numv = 24;
|
||||
const float h27_volu = 0.100588;
|
||||
const float h27_pos[3] = { 0.167088,0.649940,-0.364014 };
|
||||
const float h27_verts[ h27_numv * 3 ] = {
|
||||
-0.183844,0.118803,-0.244043, -0.044353,-0.266136,0.405236, -0.256011,0.235567,0.029047, 0.161864,-0.158366,-0.228068, 0.300539,0.065664,-0.127155, -0.024586,0.350060,-0.293383, -0.048173,0.271698,-0.335996, -0.180959,0.350060,0.012033, -0.081680,0.217294,-0.332121, -0.044357,0.350060,0.088262, -0.006196,-0.377080,0.285910, 0.201878,-0.226993,0.143823, -0.003872,-0.277036,0.420726, 0.210870,-0.062009,-0.236614, -0.003871,0.350060,0.098146, 0.183618,0.350060,-0.130723, -0.165155,-0.254165,0.331667, -0.075081,-0.408619,0.192919, -0.091738,-0.410255,0.124205, 0.005721,-0.287236,0.414262, -0.077668,-0.381972,-0.025325, -0.102748,-0.401170,0.182332, 0.134962,-0.226993,-0.182915, 0.109551,-0.305242,0.296779,
|
||||
};
|
||||
// h28
|
||||
const int h28_numv = 18;
|
||||
const float h28_volu = 0.075441;
|
||||
const float h28_pos[3] = { 0.013616,0.472900,-0.719797 };
|
||||
const float h28_verts[ h28_numv * 3 ] = {
|
||||
-0.187022,-0.167506,-0.280203, 0.109520,-0.345231,0.152809, -0.085555,0.177012,-0.280203, -0.271995,0.154408,0.021945, -0.030372,0.295843,0.111740, 0.061535,-0.227567,0.329703, 0.075804,-0.204932,0.330457, 0.071792,0.394334,0.023662, 0.208102,-0.281022,0.072668, -0.047446,0.360894,-0.139094, 0.077205,-0.350161,0.038133, -0.006548,-0.010473,-0.280203, 0.288434,-0.049953,0.172868, 0.315336,0.018674,0.127715, 0.316057,-0.148273,0.042717, 0.325968,-0.084770,0.087482, -0.256811,-0.088994,-0.280203, -0.315464,0.084990,0.019794,
|
||||
};
|
||||
// h29
|
||||
const int h29_numv = 20;
|
||||
const float h29_volu = 0.090754;
|
||||
const float h29_pos[3] = { -0.195482,0.549508,-0.348926 };
|
||||
const float h29_verts[ h29_numv * 3 ] = {
|
||||
-0.062897,0.077801,-0.348926, 0.254536,-0.331284,-0.002375, -0.179429,0.054098,-0.308283, 0.178726,0.219235,-0.259131, -0.352624,0.138460,-0.022310, 0.259822,-0.300738,0.167244, 0.197415,-0.153733,0.316579, 0.065987,-0.327570,0.133724, 0.114982,-0.134660,0.333685, 0.270633,-0.304175,-0.041168, -0.106366,0.008382,-0.351078, 0.106560,0.335999,0.013959, -0.240892,-0.124645,-0.147161, -0.313950,0.276125,0.209019, -0.158320,0.003002,-0.331475, 0.036774,-0.342768,0.065557, 0.284902,-0.281540,-0.040413, 0.270832,-0.309823,0.109117, 0.013405,-0.084041,0.336165, 0.046528,-0.137097,0.329090,
|
||||
};
|
||||
// h30
|
||||
const int h30_numv = 26;
|
||||
const float h30_volu = 0.141813;
|
||||
const float h30_pos[3] = { 0.709749,0.432546,-0.520590 };
|
||||
const float h30_verts[ h30_numv * 3 ] = {
|
||||
0.086130,-0.133630,-0.479410, 0.290251,-0.067548,-0.461259, 0.290251,0.254276,-0.130163, -0.166094,-0.194830,-0.275875, -0.114073,0.017151,0.452790, 0.263868,-0.083016,-0.470730, -0.015645,0.141724,0.383369, -0.170984,0.316821,0.046789, -0.242122,0.283058,0.029421, 0.290251,0.110614,0.239339, -0.340783,-0.009598,0.300399, 0.290251,-0.018830,0.261535, 0.067740,-0.137994,-0.479410, -0.241377,-0.054963,0.435747, 0.058158,-0.287592,0.103343, 0.290251,-0.145966,0.143817, 0.068185,-0.139308,-0.479410, -0.017612,-0.287592,-0.266628, 0.053160,-0.131717,-0.469392, -0.272857,-0.118823,-0.210712, 0.007901,-0.200618,-0.414231, 0.003123,-0.268644,-0.311584, -0.331791,0.155385,-0.080037, -0.407699,-0.009598,-0.026339, -0.380797,0.059028,-0.071491, -0.370165,-0.044416,-0.111725,
|
||||
};
|
||||
// h31
|
||||
const int h31_numv = 20;
|
||||
const float h31_volu = 0.145607;
|
||||
const float h31_pos[3] = { 0.628702,0.773411,-0.793457 };
|
||||
const float h31_verts[ h31_numv * 3 ] = {
|
||||
-0.189575,0.226589,0.317223, 0.371298,-0.414948,-0.206543, -0.476185,0.226589,-0.206543, 0.371298,0.226589,-0.206543, -0.250744,-0.185480,0.192828, 0.148787,-0.478859,-0.206543, -0.509787,0.148227,0.093447, -0.534804,0.226589,-0.034811, -0.277996,0.226589,0.298719, -0.486200,0.226589,0.136059, 0.371298,-0.408413,-0.188392, 0.167177,-0.474495,-0.206543, 0.366378,-0.417196,-0.206543, 0.344915,-0.423881,-0.197864, 0.371298,-0.086589,0.142703, 0.371298,0.226589,0.089002, -0.161075,-0.057807,0.302287, -0.089936,-0.024044,0.319655, 0.134207,-0.472582,-0.196526, 0.136072,-0.470812,-0.206543,
|
||||
};
|
||||
// h32
|
||||
const int h32_numv = 22;
|
||||
const float h32_volu = 0.092552;
|
||||
const float h32_pos[3] = { -0.648077,-0.694629,-0.055690 };
|
||||
const float h32_verts[ h32_numv * 3 ] = {
|
||||
-0.351923,0.020682,-0.162313, -0.351923,0.291038,-0.298522, 0.116588,0.074450,0.304425, 0.180292,0.145010,-0.063690, -0.351923,0.286862,-0.299238, 0.082653,-0.305371,0.200452, 0.444715,-0.214767,0.086986, 0.440565,-0.305371,0.060643, 0.437298,-0.305371,0.003205, 0.441236,-0.180086,0.007980, 0.202670,-0.305371,-0.129990, -0.122926,-0.305371,-0.050498, -0.351923,0.343433,0.003710, 0.034975,0.067995,0.334312, -0.249787,0.361137,-0.236631, 0.059834,0.222599,0.089656, 0.420946,-0.305371,-0.023410, 0.437088,-0.283432,-0.011766, -0.351923,0.387353,-0.064067, -0.294272,0.397125,-0.093222, -0.351923,0.309463,-0.280428, -0.321961,0.320573,-0.278827,
|
||||
};
|
||||
// h33
|
||||
const int h33_numv = 18;
|
||||
const float h33_volu = 0.056945;
|
||||
const float h33_pos[3] = { -0.288352,-0.547292,0.050646 };
|
||||
const float h33_verts[ h33_numv * 3 ] = {
|
||||
0.084990,-0.362104,-0.019350, -0.079434,0.021164,0.334816, 0.019488,-0.072734,0.262363, 0.115516,0.076855,-0.268585, 0.213070,0.021874,-0.243280, 0.274323,0.089944,-0.132397, 0.019789,0.332949,0.053313, 0.257211,0.025988,-0.078610, 0.131191,0.288888,-0.060012, 0.118204,-0.320377,0.031687, 0.081511,-0.327423,-0.098356, -0.243137,-0.072887,0.198089, -0.179433,-0.002327,-0.170026, -0.299891,0.075262,-0.016680, -0.055817,0.322184,0.088384, -0.038680,0.277450,0.153234, 0.148159,-0.119839,-0.229545, 0.048588,0.033746,-0.272086,
|
||||
};
|
||||
// h34
|
||||
const int h34_numv = 24;
|
||||
const float h34_volu = 0.086482;
|
||||
const float h34_pos[3] = { -0.499709,-0.643458,-0.327986 };
|
||||
const float h34_verts[ h34_numv * 3 ] = {
|
||||
-0.500291,0.235691,-0.026942, -0.413349,0.203755,-0.157062, -0.223651,0.321490,-0.139249, 0.209880,-0.356542,0.003973, 0.365162,-0.137565,0.097393, 0.292868,-0.231257,0.280276, 0.359516,-0.023673,0.149087, -0.329463,0.339839,-0.019523, -0.041433,0.349469,-0.148408, 0.054302,-0.356542,0.142306, 0.272578,-0.356542,0.248886, 0.288720,-0.334603,0.260530, 0.023896,-0.069111,-0.283979, 0.274970,-0.222320,-0.056303, 0.127449,-0.356542,-0.036276, -0.035189,-0.103922,-0.288953, -0.023751,0.360733,-0.121029, -0.500291,0.237083,-0.030523, -0.346425,0.336124,-0.010604, 0.259945,0.129913,0.106546, -0.500291,0.239867,-0.026226, -0.470329,0.269402,-0.006532, -0.398155,0.309966,0.035665, 0.031924,0.093839,0.208606,
|
||||
};
|
||||
// h35
|
||||
const int h35_numv = 12;
|
||||
const float h35_volu = 0.072358;
|
||||
const float h35_pos[3] = { -0.852811,-0.781078,0.150064 };
|
||||
const float h35_verts[ h35_numv * 3 ] = {
|
||||
-0.147189,-0.218922,0.332047, 0.103613,-0.074924,0.288589, -0.147189,0.429882,-0.202044, -0.147189,-0.218922,-0.312160, 0.239709,0.154443,0.128558, 0.287386,-0.218922,-0.005301, -0.043492,-0.218922,0.344705, 0.074717,-0.218922,0.306226, -0.147189,0.402063,0.012610, 0.208223,0.167113,0.176854, -0.147189,0.107130,-0.368067, 0.081807,-0.218922,-0.256252,
|
||||
};
|
||||
// h36
|
||||
const int h36_numv = 18;
|
||||
const float h36_volu = 0.076715;
|
||||
const float h36_pos[3] = { 0.330903,-0.599381,-0.308448 };
|
||||
const float h36_verts[ h36_numv * 3 ] = {
|
||||
0.235744,-0.093981,0.208985, 0.157036,0.091360,0.296934, -0.213473,-0.059832,-0.258208, 0.131366,0.084254,0.304768, 0.060949,-0.352878,-0.040467, 0.031132,-0.367472,0.023458, -0.038178,0.319175,-0.078462, 0.346140,-0.033881,-0.005840, 0.305466,-0.106272,-0.107625, -0.256020,-0.056138,-0.213238, -0.331115,0.110184,0.014099, -0.356965,0.085987,0.067218, 0.185622,-0.147504,0.212044, 0.241393,0.219660,0.109239, -0.343391,-0.100844,-0.022261, -0.046519,0.081665,-0.290234, -0.272849,0.156195,0.144404, -0.146830,0.270831,-0.017119,
|
||||
};
|
||||
// h37
|
||||
const int h37_numv = 18;
|
||||
const float h37_volu = 0.098217;
|
||||
const float h37_pos[3] = { 0.055330,-0.588368,0.333127 };
|
||||
const float h37_verts[ h37_numv * 3 ] = {
|
||||
-0.107417,0.016721,0.347927, 0.283844,-0.036335,0.197820, 0.129290,0.324988,-0.064466, -0.012100,0.128834,-0.356552, 0.344968,0.171444,-0.038138, -0.270436,0.127441,0.395275, -0.130084,-0.375511,-0.154724, 0.001812,-0.380727,-0.087638, -0.247911,0.142505,0.383526, 0.360906,0.133475,0.137346, 0.062042,-0.352141,-0.072933, 0.261216,0.073240,-0.194499, 0.127844,0.325300,-0.059106, 0.361773,0.137946,0.130076, -0.225478,-0.279302,-0.250794, -0.324194,-0.031659,-0.020118, -0.297963,0.086614,0.328910, -0.086471,0.067064,-0.361091,
|
||||
};
|
||||
// h38
|
||||
const int h38_numv = 28;
|
||||
const float h38_volu = 0.093559;
|
||||
const float h38_pos[3] = { 0.133166,-0.773583,-0.050905 };
|
||||
const float h38_verts[ h38_numv * 3 ] = {
|
||||
-0.076024,-0.195512,0.296394, 0.264846,-0.226417,0.026836, 0.183380,0.258456,0.189533, -0.015793,-0.166926,0.311098, -0.267713,-0.007440,-0.179688, -0.159228,0.260189,-0.190326, -0.343945,-0.226417,-0.001580, -0.273359,0.106452,-0.127994, 0.216958,-0.226417,-0.206989, 0.383359,0.026697,-0.045499, 0.329103,0.258456,0.047225, -0.089936,0.314049,0.027481, -0.145654,0.073358,-0.279804, 0.228869,-0.193270,-0.234086, -0.131382,0.326289,-0.026485, -0.075112,0.330397,-0.113139, -0.208448,0.248166,-0.141729, -0.011151,-0.226417,0.296364, -0.211663,-0.226417,0.216210, -0.072038,-0.226417,0.288931, -0.336528,-0.135813,0.082201, -0.147195,0.316236,-0.030846, -0.340678,-0.226417,0.055858, -0.164307,0.252279,0.022941, -0.344155,-0.204478,-0.016551, -0.340007,-0.101132,0.003195, -0.207920,-0.190296,0.229308, -0.303314,-0.094086,0.133238,
|
||||
};
|
||||
// h39
|
||||
const int h39_numv = 32;
|
||||
const float h39_volu = 0.060173;
|
||||
const float h39_pos[3] = { -0.130993,-0.349156,0.297470 };
|
||||
const float h39_verts[ h39_numv * 3 ] = {
|
||||
0.132777,-0.098138,-0.374861, 0.174223,-0.110378,-0.320895, -0.236793,-0.176972,0.087992, 0.120090,0.163784,-0.274197, -0.036262,0.126682,-0.293283, -0.239846,-0.040235,0.342234, -0.196039,0.079314,-0.093590, -0.026168,0.090752,-0.306837, -0.084113,-0.111771,0.430932, -0.132771,0.138527,-0.197817, -0.061588,-0.096707,0.419183, -0.167047,-0.030107,0.457226, 0.314167,0.086089,-0.023449, 0.140527,0.255266,-0.004320, -0.137571,0.134813,-0.193511, 0.315613,0.085777,-0.028809, 0.116964,-0.108191,-0.379221, 0.099852,-0.172148,-0.325434, -0.176687,-0.026318,0.447418, -0.168971,-0.023213,0.453768, -0.137871,-0.270870,0.015539, -0.111640,-0.152598,0.364567, -0.122362,-0.092357,0.456223, -0.127730,-0.079472,0.460978, -0.243030,-0.080780,0.324741, -0.136583,-0.114124,0.420896, -0.241856,-0.054541,0.348612, -0.178625,-0.028253,0.445248, -0.171209,-0.024409,0.453290, -0.169333,-0.024798,0.455225, 0.224076,0.244621,-0.088171, 0.213513,0.251212,-0.061379,
|
||||
};
|
||||
// h40
|
||||
const int h40_numv = 24;
|
||||
const float h40_volu = 0.115424;
|
||||
const float h40_pos[3] = { 0.492476,-0.748212,0.263785 };
|
||||
const float h40_verts[ h40_numv * 3 ] = {
|
||||
-0.375103,-0.192297,-0.003592, 0.259307,0.208511,0.137583, 0.097667,-0.251788,0.295436, 0.264741,-0.251788,-0.112461, -0.092178,0.331289,0.031204, 0.024049,0.001327,-0.360189, 0.074171,0.054850,-0.363248, 0.312772,-0.115013,-0.159366, -0.175930,0.233085,-0.125157, -0.094464,-0.251788,-0.287854, -0.004537,0.240191,-0.275299, -0.030207,0.233085,-0.267465, -0.370461,-0.251788,-0.018326, 0.056736,-0.251788,0.315422, -0.153302,0.123509,0.267162, -0.068302,0.078845,0.319783, 0.171724,0.348803,0.156293, 0.053571,0.367605,-0.023060, -0.075373,0.297791,0.199418, 0.109457,0.331072,0.189737, -0.005042,0.303901,0.226077, 0.014996,0.282164,0.244247, -0.076239,0.293319,0.206688, -0.068649,0.297216,0.207331,
|
||||
};
|
||||
// h41
|
||||
const int h41_numv = 18;
|
||||
const float h41_volu = 0.076473;
|
||||
const float h41_pos[3] = { 0.741085,-0.876917,-0.246261 };
|
||||
const float h41_verts[ h41_numv * 3 ] = {
|
||||
0.005338,0.140795,-0.243701, -0.174437,0.183555,0.146798, 0.258916,-0.123083,-0.387389, 0.103129,0.222017,-0.142233, 0.164192,-0.123083,-0.418224, 0.016133,-0.123083,0.397585, 0.258916,0.168617,-0.137303, 0.258916,-0.123083,0.279039, -0.343073,-0.123083,0.222192, -0.064041,0.243655,-0.068027, -0.104715,0.171264,-0.169812, -0.390960,-0.123083,-0.011633, -0.224559,0.130032,0.149857, -0.379049,-0.089936,-0.038730, -0.349233,-0.075342,-0.102654, -0.337817,-0.123083,-0.124077, 0.258916,-0.009416,0.259549, 0.064164,0.013692,0.350680,
|
||||
};
|
||||
// h42
|
||||
const int h42_numv = 26;
|
||||
const float h42_volu = 0.137951;
|
||||
const float h42_pos[3] = { 0.814994,-0.482932,0.027418 };
|
||||
const float h42_verts[ h42_numv * 3 ] = {
|
||||
-0.063211,-0.056769,0.373950, 0.185005,0.097851,0.415613, -0.248347,-0.210430,-0.126881, 0.112828,0.023604,-0.394042, -0.108847,0.115253,0.400661, -0.327055,-0.025089,-0.038931, -0.085789,0.224192,-0.255901, 0.185005,-0.403401,-0.014130, 0.185005,-0.225368,-0.410982, -0.009747,-0.380293,0.077002, -0.175394,0.222730,-0.208732, 0.002670,0.221670,0.389944, -0.150794,0.083523,0.392660, 0.160182,0.229752,0.436714, 0.133897,0.345057,0.231744, -0.006362,0.255606,0.329122, 0.185005,0.234054,0.438967, 0.185005,0.352490,0.238788, 0.029219,-0.171968,-0.415912, -0.137952,-0.150330,-0.341706, 0.185005,0.276769,-0.150723, 0.185005,0.010082,-0.390796, -0.176045,0.220413,-0.220256, -0.242698,0.103211,-0.226628, -0.268948,0.102325,0.213307, -0.248100,0.136462,0.190657,
|
||||
};
|
||||
// h43
|
||||
const int h43_numv = 26;
|
||||
const float h43_volu = 0.091347;
|
||||
const float h43_pos[3] = { -0.439313,0.395062,-0.161996 };
|
||||
const float h43_verts[ h43_numv * 3 ] = {
|
||||
-0.171800,0.355423,-0.143529, -0.041887,-0.040549,-0.338294, -0.088904,0.443945,0.033555, -0.050746,0.256028,0.267789, -0.120718,0.085236,0.331241, 0.112903,-0.317075,-0.192421, -0.024680,-0.380539,0.081401, 0.014540,-0.410443,-0.096363, -0.166472,-0.135578,-0.232924, -0.179653,0.199344,0.219565, 0.056744,-0.387608,-0.004660, -0.088904,0.425462,0.081094, -0.046327,-0.413563,-0.075262, -0.024725,0.299814,0.247575, -0.150602,0.151087,0.286944, -0.050613,-0.134365,0.334664, -0.244880,0.199344,-0.098926, -0.122184,0.302440,-0.201067, -0.108793,0.292906,-0.209241, -0.034597,-0.039973,-0.340964, 0.309817,-0.173124,-0.053206, -0.070119,0.430571,0.022089, 0.002939,0.029802,-0.334091, 0.280604,-0.188322,-0.121373, 0.290359,0.017349,0.142160, 0.257236,0.070405,0.149235,
|
||||
};
|
||||
// h44
|
||||
const int h44_numv = 26;
|
||||
const float h44_volu = 0.104111;
|
||||
const float h44_pos[3] = { -0.656166,-0.300748,0.215302 };
|
||||
const float h44_verts[ h44_numv * 3 ] = {
|
||||
-0.220317,0.235145,-0.208278, 0.078796,0.351295,-0.102059, 0.283317,-0.102949,0.430780, 0.285327,-0.088643,0.424402, 0.201177,0.226255,-0.138992, 0.124677,-0.319431,0.033433, 0.117727,0.304230,-0.184196, 0.043064,-0.325887,0.063320, -0.138842,0.186808,-0.302762, 0.311997,0.075640,-0.076273, 0.067923,-0.171282,-0.181336, -0.343834,-0.050448,-0.267282, -0.343834,-0.078267,-0.052628, -0.343834,0.035932,0.053112, 0.088073,0.239020,0.159535, 0.282143,-0.129188,0.406909, -0.286183,0.003244,-0.364214, -0.343834,0.054532,0.043544, 0.011578,-0.313217,0.111616, 0.329134,0.030906,-0.011422, 0.089881,-0.140507,0.355648, 0.092412,-0.225203,0.279944, 0.288380,-0.225380,0.170160, 0.101854,0.336248,-0.130909, -0.343834,-0.006528,-0.335059, -0.343834,0.160238,-0.192084,
|
||||
};
|
||||
// h45
|
||||
const int h45_numv = 22;
|
||||
const float h45_volu = 0.073607;
|
||||
const float h45_pos[3] = { -0.692003,0.228592,-0.074767 };
|
||||
const float h45_verts[ h45_numv * 3 ] = {
|
||||
0.206363,-0.247093,-0.162491, 0.114633,-0.178045,0.188010, 0.007810,0.365814,-0.186155, -0.306616,-0.033345,0.126518, -0.055718,0.198405,0.254002, 0.153565,-0.225110,0.105873, -0.184480,-0.294195,0.081791, 0.073037,0.365814,0.132336, 0.155930,-0.080562,0.225951, -0.173050,0.172678,-0.175116, -0.103005,-0.342532,-0.012694, -0.015749,-0.330108,-0.146901, 0.086218,0.030892,-0.320153, -0.015750,-0.032626,-0.299926, 0.228010,-0.214069,-0.005829, 0.104078,0.176805,0.286842, 0.137691,-0.193092,0.159160, 0.102087,0.317557,0.199715, -0.062260,0.197254,0.252076, 0.131971,0.251706,0.244012, 0.186972,0.021095,0.262581, 0.202077,0.032105,0.247435,
|
||||
};
|
||||
// h46
|
||||
const int h46_numv = 24;
|
||||
const float h46_volu = 0.077166;
|
||||
const float h46_pos[3] = { -0.506861,-0.263372,-0.148064 };
|
||||
const float h46_verts[ h46_numv * 3 ] = {
|
||||
-0.435488,-0.034132,-0.000849, 0.039076,-0.286247,0.028683, -0.031577,0.266854,0.179170, 0.042868,0.277895,0.067468, 0.334025,-0.207064,-0.069876, -0.200891,0.161856,-0.073604, -0.329922,-0.035641,-0.192524, -0.391003,-0.070120,-0.144257, 0.124292,0.270826,-0.018593, -0.288147,0.149432,0.060603, 0.051872,0.188879,0.224374, -0.081382,-0.208658,0.182030, 0.243097,0.052743,0.247717, 0.267097,-0.250173,-0.073376, 0.162691,0.038264,0.287094, 0.339607,0.040898,0.152251, 0.238297,0.049029,0.252023, 0.349700,0.004968,0.138697, 0.021220,0.244871,-0.089194, -0.322311,-0.040247,-0.199445, -0.016599,-0.019353,-0.300951, 0.082088,0.247991,-0.110295, -0.339273,-0.043963,-0.190526, 0.082087,0.036350,-0.291745,
|
||||
};
|
||||
// h47
|
||||
const int h47_numv = 36;
|
||||
const float h47_volu = 0.096745;
|
||||
const float h47_pos[3] = { -0.132135,0.108975,0.072319 };
|
||||
const float h47_verts[ h47_numv * 3 ] = {
|
||||
0.298509,0.263511,-0.009995, -0.406303,-0.105494,-0.041213, 0.295351,0.263929,-0.015607, -0.362255,0.123840,0.142831, -0.016819,0.303436,-0.092155, 0.214655,-0.206919,0.163772, 0.119596,0.038081,0.333996, -0.357791,0.151721,0.100349, 0.141669,-0.202865,0.220831, -0.322854,-0.183468,0.003991, -0.422177,-0.073475,0.012073, 0.248529,0.277838,-0.020262, -0.331858,-0.094452,-0.152914, -0.250434,-0.101521,-0.238975, -0.131628,-0.319604,0.027334, 0.281027,0.056414,-0.190466, 0.134068,0.286800,-0.104666, 0.293847,0.266235,0.003176, -0.403938,0.039055,0.078865, -0.372896,0.140712,0.115495, -0.035119,-0.331449,-0.068132, 0.121232,-0.294347,-0.049046, 0.051634,0.305873,-0.087560, 0.254870,0.274829,-0.031097, 0.196475,0.139795,-0.254001, 0.002640,0.112963,-0.287521, 0.198447,0.073853,0.288417, 0.224142,0.132346,-0.243414, 0.225218,-0.213510,0.136980, 0.298178,-0.027388,0.023425, 0.292448,0.199019,0.106734, 0.304944,0.253729,-0.022071, 0.308556,0.186869,0.065231, 0.305066,0.254217,-0.020526, 0.293027,0.163885,-0.150423, 0.287364,0.062429,-0.181183,
|
||||
};
|
||||
// h48
|
||||
const int h48_numv = 24;
|
||||
const float h48_volu = 0.097516;
|
||||
const float h48_pos[3] = { 0.292729,-0.243911,-0.041409 };
|
||||
const float h48_verts[ h48_numv * 3 ] = {
|
||||
-0.303632,0.058539,0.064682, -0.108656,-0.084639,-0.284158, 0.263889,0.072976,-0.223666, 0.274166,-0.102559,0.259484, 0.253318,-0.136696,0.282134, 0.346872,-0.016291,-0.139905, -0.290945,-0.203383,-0.035982, 0.008763,0.056080,-0.365621, 0.246275,0.103070,-0.201305, 0.107569,-0.173012,0.336398, -0.249499,-0.215623,0.017984, -0.234675,-0.199275,-0.122635, 0.023817,-0.271216,0.180037, 0.169540,-0.271216,0.037729, -0.126686,0.325499,0.137154, 0.195210,-0.264110,0.029895, 0.346221,-0.018608,-0.151429, 0.279567,-0.135810,-0.157801, -0.143837,0.409300,-0.076739, -0.137500,0.415315,-0.067456, -0.031223,0.088614,-0.351675, -0.000004,-0.036295,-0.345501, -0.199646,0.139376,0.250708, -0.108109,-0.019468,0.310070,
|
||||
};
|
||||
// h49
|
||||
const int h49_numv = 30;
|
||||
const float h49_volu = 0.103417;
|
||||
const float h49_pos[3] = { -0.082648,-0.117151,-0.277803 };
|
||||
const float h49_verts[ h49_numv * 3 ] = {
|
||||
0.344154,-0.038146,-0.115281, -0.165239,0.018854,-0.286732, -0.342125,0.101770,0.019444, -0.222234,-0.108669,-0.237036, -0.321677,-0.099820,-0.189997, 0.084432,-0.330143,0.200412, -0.076061,0.323891,-0.005566, -0.299921,0.124605,0.111147, -0.223248,0.024754,-0.259418, 0.141702,0.335375,-0.073499, 0.231540,0.282540,0.159656, 0.156937,0.153559,-0.266131, -0.243762,0.195138,-0.076614, -0.084607,-0.105324,0.281990, 0.266721,-0.211399,-0.047765, 0.071745,-0.068221,0.301076, -0.090188,-0.353285,0.059864, -0.342125,-0.109871,-0.162005, -0.074513,-0.141253,0.268436, 0.140702,-0.326035,0.113759, 0.082436,-0.372046,-0.016546, 0.056586,-0.396243,0.036572, 0.007365,-0.408266,0.085169, 0.068619,-0.340196,0.196052, 0.183372,0.187050,-0.241355, 0.271282,0.058201,-0.185174, 0.174655,0.358472,0.106708, -0.046848,0.339089,0.062601, 0.146988,0.365921,0.096121, 0.157998,0.356836,0.037994,
|
||||
};
|
||||
// h50
|
||||
const int h50_numv = 20;
|
||||
const float h50_volu = 0.069183;
|
||||
const float h50_pos[3] = { -0.304007,-0.060848,0.383791 };
|
||||
const float h50_verts[ h50_numv * 3 ] = {
|
||||
0.035443,-0.153495,-0.279832, 0.291468,0.207904,0.022524, -0.264086,-0.000880,-0.008953, -0.190383,0.293663,-0.168640, 0.004043,-0.311521,0.367447, -0.001962,-0.311376,0.364440, -0.150982,-0.013645,-0.307481, -0.250305,0.096348,-0.299398, 0.040243,-0.149781,-0.284138, -0.040162,-0.164260,-0.244761, -0.228192,0.064423,0.060664, 0.001805,-0.312717,0.366969, -0.232066,0.208878,-0.232607, -0.273363,0.111395,-0.270548, 0.313541,-0.033043,-0.090641, -0.003673,-0.314626,0.361097, -0.023025,-0.208994,-0.179911, -0.066832,-0.328543,0.255913, -0.170020,0.271491,-0.017447, 0.190786,0.198102,0.196479,
|
||||
};
|
||||
// h51
|
||||
const int h51_numv = 20;
|
||||
const float h51_volu = 0.097496;
|
||||
const float h51_pos[3] = { 0.796238,0.092236,-0.101631 };
|
||||
const float h51_verts[ h51_numv * 3 ] = {
|
||||
-0.221011,0.347408,0.061823, -0.319697,0.291705,0.052616, 0.203762,-0.222678,0.367837, -0.200562,0.357460,0.033830, 0.203762,0.194344,-0.275142, -0.239620,-0.263171,-0.163444, 0.152653,-0.230111,0.360793, 0.203762,0.321480,-0.157424, -0.337380,0.280442,0.025237, -0.327866,0.285347,0.016786, -0.028332,0.052718,-0.315616, 0.203762,-0.298399,-0.021674, -0.257234,-0.233077,-0.141083, -0.157288,-0.354755,-0.091207, 0.203762,0.006585,0.328526, -0.156637,-0.352438,-0.079683, 0.030926,0.103995,0.283692, -0.036002,0.060886,0.280191, -0.157223,-0.222560,-0.236947, -0.067033,-0.350976,-0.126852,
|
||||
};
|
||||
// h52
|
||||
const int h52_numv = 16;
|
||||
const float h52_volu = 0.084293;
|
||||
const float h52_pos[3] = { 0.513157,0.018456,0.067444 };
|
||||
const float h52_verts[ h52_numv * 3 ] = {
|
||||
-0.347114,0.063132,0.028301, -0.352265,0.254404,-0.145548, 0.247079,0.134666,0.111116, -0.336736,0.277388,0.070106, 0.126444,-0.278658,-0.248758, -0.340226,0.344736,-0.015651, 0.295476,-0.245782,0.289096, -0.054299,0.354222,-0.143838, 0.053738,-0.364926,0.150631, -0.036616,0.365485,-0.116459, 0.025847,-0.159297,-0.310158, -0.357928,0.152948,-0.176308, 0.019058,0.098592,0.213176, 0.435734,-0.156331,0.191718, -0.340348,0.344248,-0.017196, -0.236518,0.326242,-0.134679,
|
||||
};
|
||||
// h53
|
||||
const int h53_numv = 16;
|
||||
const float h53_volu = 0.086476;
|
||||
const float h53_pos[3] = { -0.781555,0.807509,0.197497 };
|
||||
const float h53_verts[ h53_numv * 3 ] = {
|
||||
0.291496,-0.156419,-0.091704, -0.218445,0.192491,0.461269, -0.218445,0.192491,-0.255541, -0.218445,-0.397567,0.047987, 0.027292,-0.381663,-0.020188, -0.218445,-0.373860,0.169935, 0.033835,-0.380512,-0.018262, 0.352556,0.192491,0.043056, 0.162589,-0.213103,-0.139928, 0.191640,-0.261360,-0.072549, 0.238502,0.192491,-0.291089, 0.253338,0.013015,-0.278399, 0.326334,-0.087525,-0.081781, 0.317517,-0.112633,-0.111918, 0.238502,0.081667,-0.310092, 0.153590,0.192491,-0.346370,
|
||||
};
|
||||
// h54
|
||||
const int h54_numv = 20;
|
||||
const float h54_volu = 0.089003;
|
||||
const float h54_pos[3] = { -0.845912,0.679404,-0.140778 };
|
||||
const float h54_verts[ h54_numv * 3 ] = {
|
||||
0.317695,0.141120,0.059877, 0.091649,-0.253558,0.318087, -0.154088,0.080768,-0.359617, -0.152707,-0.484157,0.192529, -0.154088,0.320596,0.082735, 0.078976,0.204301,-0.281846, -0.154088,-0.269462,0.386262, -0.154088,0.320596,-0.236248, -0.154088,-0.484416,0.192760, 0.226946,-0.084997,0.198347, 0.060656,0.320596,-0.223141, 0.161719,-0.084997,-0.120143, 0.217947,0.320596,-0.008094, -0.049829,0.124065,-0.330981, -0.154088,-0.230098,-0.199706, -0.019141,-0.278134,-0.109104, 0.160374,0.124065,-0.228342, 0.234799,0.071081,-0.164747, 0.302859,0.209772,0.028184, 0.317695,0.159603,0.012337,
|
||||
};
|
||||
// h55
|
||||
const int h55_numv = 16;
|
||||
const float h55_volu = 0.055290;
|
||||
const float h55_pos[3] = { 0.087136,0.788999,0.139771 };
|
||||
const float h55_verts[ h55_numv * 3 ] = {
|
||||
0.076080,-0.416095,-0.083059, -0.323951,0.211001,0.286715, 0.205112,0.211001,-0.185127, 0.076081,0.211001,-0.405639, -0.148237,0.211001,0.332473, 0.101171,-0.226374,0.192117, -0.006832,-0.085411,0.277812, 0.205111,-0.223849,0.038561, -0.274823,0.078877,0.258729, 0.035595,0.211001,-0.415523, 0.074576,-0.413789,-0.064275, 0.079238,-0.416513,-0.077447, 0.107256,-0.249478,0.168347, 0.117855,-0.236273,0.172768, 0.029258,-0.402186,-0.087713, 0.035598,-0.405195,-0.098549,
|
||||
};
|
||||
// h56
|
||||
const int h56_numv = 20;
|
||||
const float h56_volu = 0.096963;
|
||||
const float h56_pos[3] = { -0.186579,0.800379,0.005269 };
|
||||
const float h56_verts[ h56_numv * 3 ] = {
|
||||
0.004502,-0.334912,-0.018030, 0.302973,-0.413566,0.046788, 0.309310,0.199621,-0.281021, -0.242420,0.199621,0.235284, -0.121421,0.199621,0.412527, 0.172708,0.199621,-0.357250, -0.050236,0.199621,0.421217, -0.341638,0.020145,-0.086171, -0.356474,0.199621,-0.098861, 0.097656,0.085128,-0.340236, -0.001108,0.067497,0.393231, -0.356474,0.088797,-0.117864, -0.277459,-0.105503,0.080310, 0.309314,-0.416575,0.035953, 0.106078,-0.385531,-0.020510, 0.188512,-0.404604,-0.037617, -0.268642,-0.080395,0.110447, -0.118494,0.123210,0.393231, -0.341638,0.038628,-0.133710, -0.322853,0.025254,-0.145176,
|
||||
};
|
||||
// h57
|
||||
const int h57_numv = 16;
|
||||
const float h57_volu = 0.081294;
|
||||
const float h57_pos[3] = { 0.851151,0.533342,0.098902 };
|
||||
const float h57_verts[ h57_numv * 3 ] = {
|
||||
-0.184097,0.265595,0.004922, 0.148849,0.009818,-0.380153, 0.148849,-0.049459,0.325702, -0.275924,-0.093697,-0.138710, 0.148849,-0.119626,-0.357957, -0.275924,0.137573,0.059567, -0.112901,0.343928,0.059438, -0.249462,0.157589,0.121951, 0.148849,-0.434521,0.127992, 0.148849,0.447452,0.070089, 0.148849,-0.343521,0.212252, -0.023987,-0.337111,0.083159, -0.018406,-0.089149,0.305285, -0.008312,-0.125079,0.291731, -0.255475,-0.083645,-0.166703, -0.157047,0.040928,-0.236124,
|
||||
};
|
||||
// h58
|
||||
const int h58_numv = 20;
|
||||
const float h58_volu = 0.077812;
|
||||
const float h58_pos[3] = { 0.374418,0.849026,0.291935 };
|
||||
const float h58_verts[ h58_numv * 3 ] = {
|
||||
-0.082171,-0.283876,-0.113603, 0.200809,-0.178111,-0.133466, -0.082170,0.150974,-0.337291, 0.089508,-0.034332,0.259248, 0.146093,0.150974,0.326019, 0.410849,0.150974,-0.104898, -0.435519,0.150974,0.180309, -0.294114,-0.145438,0.125648, 0.292636,-0.050089,-0.188111, 0.183309,0.150974,-0.304884, 0.227271,-0.158095,-0.071082, 0.363832,0.028244,-0.133595, -0.169427,-0.296300,0.020604, 0.087144,-0.178878,0.139171, 0.071270,-0.146859,0.192458, -0.429747,0.150974,0.185433, -0.186111,-0.286401,0.039952, 0.048213,-0.131812,0.221308, -0.268420,-0.171352,0.132706, -0.212551,-0.233071,0.128708,
|
||||
};
|
||||
// h59
|
||||
const int h59_numv = 12;
|
||||
const float h59_volu = 0.098632;
|
||||
const float h59_pos[3] = { 0.795288,0.838821,-0.270144 };
|
||||
const float h59_verts[ h59_numv * 3 ] = {
|
||||
-0.010021,0.161179,0.457181, -0.356162,0.161179,-0.206090, 0.204712,-0.152000,-0.380610, 0.204712,0.161179,-0.434310, -0.057037,0.038449,0.428484, -0.237561,0.161179,0.257195, -0.256523,-0.089455,-0.203657, -0.128234,-0.039885,0.373968, 0.204712,-0.295661,-0.011106, -0.101183,-0.264551,0.132922, 0.204712,0.141973,0.439135, 0.204712,0.161179,0.444075,
|
||||
};
|
||||
// h60
|
||||
const int h60_numv = 22;
|
||||
const float h60_volu = 0.091310;
|
||||
const float h60_pos[3] = { 0.415485,0.715407,-0.130668 };
|
||||
const float h60_verts[ h60_numv * 3 ] = {
|
||||
-0.064779,0.284593,-0.364069, 0.142242,0.284593,0.117719, -0.242554,-0.352215,0.182461, 0.061056,-0.331466,0.081653, 0.180191,-0.265711,0.062868, 0.251569,0.083531,0.234492, -0.123237,0.284593,0.085312, -0.123238,-0.150257,0.309000, 0.159742,-0.044491,0.289138, 0.278619,-0.141137,-0.006553, -0.252268,0.284593,-0.135200, 0.123280,0.033960,-0.343133, 0.052142,0.000197,-0.360501, 0.023641,0.284593,-0.345566, 0.159742,-0.275763,0.090860, -0.138846,-0.370709,0.063434, -0.249111,-0.342921,0.192992, -0.046519,-0.292460,-0.089523, -0.252269,-0.342503,0.187380, -0.242676,-0.352703,0.180916, 0.052887,-0.337824,0.045824, 0.043373,-0.342729,0.054274,
|
||||
};
|
||||
// h61
|
||||
const int h61_numv = 24;
|
||||
const float h61_volu = 0.075853;
|
||||
const float h61_pos[3] = { 0.499694,0.403970,0.252554 };
|
||||
const float h61_verts[ h61_numv * 3 ] = {
|
||||
0.101994,0.286961,-0.031701, -0.294704,0.148756,0.059985, -0.023153,-0.020028,-0.301569, 0.156136,0.037589,0.286475, -0.323273,-0.108125,-0.115004, 0.032521,-0.286922,0.028066, -0.038132,0.266178,0.178552, 0.260541,-0.250848,-0.073994, 0.327470,-0.207739,-0.070493, 0.075532,0.266945,-0.094084, 0.075532,0.035675,-0.292362, 0.343145,0.004293,0.138079, 0.231743,0.048354,0.251404, 0.045317,0.188205,0.223756, -0.087937,-0.209333,0.181412, -0.330859,-0.089605,0.055955, 0.333052,0.040223,0.151633, 0.236542,0.052068,0.247099, -0.339382,-0.095975,-0.073501, -0.326763,-0.040778,-0.200761, -0.207448,0.161180,-0.074222, -0.333320,-0.031483,-0.190230, -0.305302,0.135551,0.055565, -0.337982,-0.028760,-0.177059,
|
||||
};
|
||||
// h62
|
||||
const int h62_numv = 18;
|
||||
const float h62_volu = 0.089635;
|
||||
const float h62_pos[3] = { -0.412607,-0.798932,0.393221 };
|
||||
const float h62_verts[ h62_numv * 3 ] = {
|
||||
0.143743,0.178906,-0.080212, -0.336591,-0.057070,0.045432, -0.365487,-0.201068,0.063069, -0.043446,-0.201068,0.325146, -0.118881,0.178753,-0.144486, -0.152818,-0.201068,-0.248459, 0.205095,-0.201068,-0.388268, 0.337853,-0.164947,-0.214818, 0.038585,0.368996,0.228990, 0.242459,-0.068737,-0.310888, -0.200495,0.172297,-0.114599, -0.231981,0.184967,-0.066303, 0.334110,-0.201068,-0.227916, 0.209245,-0.110463,-0.361925, 0.145031,0.335652,0.325145, 0.169974,0.297178,0.268816, -0.151147,0.272981,0.102025, 0.044821,0.272804,-0.007759,
|
||||
};
|
||||
// h63
|
||||
const int h63_numv = 20;
|
||||
const float h63_volu = 0.065070;
|
||||
const float h63_pos[3] = { -0.683722,-0.408459,0.881106 };
|
||||
const float h63_verts[ h63_numv * 3 ] = {
|
||||
0.408763,0.050375,-0.050997, 0.001643,0.372246,0.104787, -0.316278,-0.373443,0.118894, -0.000569,0.379463,0.118894, -0.316278,-0.303582,-0.012874, 0.413107,-0.090210,0.118894, 0.072977,-0.026465,-0.250457, -0.316278,0.104758,0.118894, -0.133134,0.036421,-0.232486, -0.316278,-0.061367,-0.137470, 0.406500,0.014459,-0.083368, 0.416439,0.055265,0.118894, 0.411396,0.069115,-0.001513, 0.370009,0.144956,0.118894, 0.377753,0.036235,-0.132875, 0.381520,0.034894,-0.130346, 0.374104,0.031050,-0.138388, 0.376042,0.032985,-0.136218, 0.383396,0.034505,-0.128411, 0.385682,0.029196,-0.126410,
|
||||
};
|
||||
// h64
|
||||
const int h64_numv = 14;
|
||||
const float h64_volu = 0.063334;
|
||||
const float h64_pos[3] = { -0.862240,-0.589074,0.504780 };
|
||||
const float h64_verts[ h64_numv * 3 ] = {
|
||||
-0.034062,-0.410926,-0.010011, 0.045384,0.217035,0.143840, 0.295955,0.147819,0.066170, 0.251495,0.154150,0.125869, -0.137760,-0.410926,0.116573, -0.137760,0.324258,-0.236366, -0.137760,0.210059,-0.342106, -0.137760,-0.122967,0.363452, -0.137760,-0.410926,-0.022669, 0.298486,0.063123,-0.009534, -0.137760,0.298525,-0.037806, 0.113042,-0.266928,-0.066127, -0.137760,0.119248,0.238856, 0.217652,-0.024891,-0.177862,
|
||||
};
|
||||
// h65
|
||||
const int h65_numv = 22;
|
||||
const float h65_volu = 0.115639;
|
||||
const float h65_pos[3] = { -0.632833,-0.759826,0.781144 };
|
||||
const float h65_verts[ h65_numv * 3 ] = {
|
||||
-0.367167,-0.022076,0.218856, 0.176779,-0.240174,-0.062777, -0.145261,-0.240174,-0.324854, -0.367167,-0.240174,-0.159791, -0.367167,-0.240174,0.218856, 0.229214,-0.240174,0.218856, -0.367167,0.047785,0.087088, 0.379478,0.318313,-0.027451, 0.258810,0.329890,-0.158933, 0.022088,0.324902,-0.150495, -0.263470,-0.240174,-0.286375, -0.116365,-0.096176,-0.342491, 0.384007,0.200623,0.218856, 0.365257,0.296546,-0.062778, 0.323215,0.382417,-0.038426, 0.362218,0.261157,0.218856, 0.374110,0.331198,-0.022696, 0.069079,0.233875,-0.285898, 0.066548,0.318571,-0.210194, 0.259984,0.356129,-0.135062, 0.334793,0.380563,-0.026448, 0.355611,0.365826,0.016594,
|
||||
};
|
||||
// h66
|
||||
const int h66_numv = 12;
|
||||
const float h66_volu = 0.090843;
|
||||
const float h66_pos[3] = { 0.194452,-0.846656,0.702344 };
|
||||
const float h66_verts[ h66_numv * 3 ] = {
|
||||
0.144722,0.221953,-0.171396, 0.354760,-0.153344,-0.123136, 0.229722,0.177289,-0.118776, -0.077080,-0.093853,-0.442151, -0.263367,-0.153344,0.297656, 0.293204,-0.153344,0.297656, -0.291202,0.163722,0.297656, 0.229722,0.015381,0.297656, -0.072437,-0.153344,-0.456885, -0.246539,0.275009,-0.021290, -0.133324,-0.153344,-0.464317, -0.137311,-0.122439,-0.456854,
|
||||
};
|
||||
// h67
|
||||
const int h67_numv = 14;
|
||||
const float h67_volu = 0.073139;
|
||||
const float h67_pos[3] = { -0.182450,-0.819619,0.699488 };
|
||||
const float h67_verts[ h67_numv * 3 ] = {
|
||||
0.085699,0.136685,0.300512, -0.221169,-0.180381,0.300512, -0.273604,-0.180381,0.018878, 0.130363,0.247972,-0.018435, -0.085126,0.356339,0.018877, 0.113535,-0.180381,0.300512, -0.066376,0.260416,0.300512, -0.060183,0.317865,-0.037452, 0.103953,-0.180381,-0.534183, 0.107696,-0.144260,-0.521085, 0.239592,-0.149476,-0.453999, 0.243578,-0.180381,-0.461462, -0.070905,0.378106,0.054205, -0.032656,0.358692,0.028913,
|
||||
};
|
||||
// h68
|
||||
const int h68_numv = 24;
|
||||
const float h68_volu = 0.110178;
|
||||
const float h68_pos[3] = { 0.194790,-0.476753,0.823942 };
|
||||
const float h68_verts[ h68_numv * 3 ] = {
|
||||
-0.387371,0.030890,-0.107289, 0.221446,0.021860,-0.353469, -0.465405,-0.021917,0.176058, -0.291540,-0.206181,0.176058, 0.076464,0.334736,-0.007133, 0.229384,-0.354523,0.176058, 0.292644,0.032441,-0.334080, -0.452945,0.146290,0.025179, 0.246219,0.093034,-0.297244, 0.229037,0.025757,-0.352826, 0.107091,0.321655,0.176058, 0.390186,-0.018723,0.176058, 0.312682,0.010704,-0.315910, 0.229384,-0.192615,-0.240374, 0.144384,-0.147950,-0.292995, -0.246877,-0.094895,-0.142888, -0.409896,0.015825,-0.095540, -0.443616,-0.082450,0.176058, -0.462073,0.123559,0.176058, -0.472012,0.082753,-0.026204, -0.453513,0.048124,-0.065494, -0.448145,0.035240,-0.070249, -0.469749,0.118668,0.006167, -0.467116,0.137408,0.055651,
|
||||
};
|
||||
// h69
|
||||
const int h69_numv = 18;
|
||||
const float h69_volu = 0.150904;
|
||||
const float h69_pos[3] = { 0.751581,-0.668854,0.749549 };
|
||||
const float h69_verts[ h69_numv * 3 ] = {
|
||||
0.248419,0.357221,0.250451, -0.263925,-0.331146,0.250451, 0.248419,0.283773,-0.306518, 0.248419,-0.331146,0.009798, 0.000203,0.129153,-0.348181, 0.248419,-0.331146,0.250451, -0.202369,-0.331146,-0.170342, -0.161439,-0.331146,-0.190328, 0.248419,0.424683,-0.270088, -0.087381,0.269445,-0.329471, -0.149648,0.251714,-0.296027, -0.327407,-0.162422,0.250451, -0.166605,0.173379,0.250451, -0.045433,0.301175,-0.321470, -0.327407,-0.000512,-0.165981, -0.244109,0.202806,-0.241517, 0.223596,0.415674,-0.285417, 0.248419,0.419976,-0.283164,
|
||||
};
|
||||
// h70
|
||||
const int h70_numv = 8;
|
||||
const float h70_volu = 0.052841;
|
||||
const float h70_pos[3] = { 0.870032,-0.820199,0.384721 };
|
||||
const float h70_verts[ h70_numv * 3 ] = {
|
||||
0.129968,-0.179801,0.374626, 0.129968,-0.179801,-0.351943, -0.279890,-0.179801,0.174500, 0.129968,0.435118,0.058310, -0.112815,-0.179801,-0.233397, -0.118249,0.280498,0.016648, 0.129968,-0.066134,-0.371433, -0.064784,-0.043027,-0.280302,
|
||||
};
|
||||
// h71
|
||||
const int h71_numv = 16;
|
||||
const float h71_volu = 0.078575;
|
||||
const float h71_pos[3] = { -0.715618,-0.146967,0.614144 };
|
||||
const float h71_verts[ h71_numv * 3 ] = {
|
||||
-0.284382,-0.099249,-0.355298, 0.407938,-0.228507,0.130744, -0.284382,-0.117849,-0.345730, 0.406000,-0.230442,0.128574, 0.033539,0.110754,0.371749, 0.104873,-0.287957,0.016505, -0.197952,0.422046,0.249299, -0.284382,0.237452,0.048837, -0.101238,-0.225072,0.034476, -0.284382,-0.143582,-0.147170, 0.149333,-0.294288,-0.043194, 0.409649,-0.225257,0.134087, 0.147525,0.085239,-0.239307, 0.183419,0.150542,-0.169689, 0.342769,-0.256730,0.031938, 0.344779,-0.242424,0.025560,
|
||||
};
|
||||
// h72
|
||||
const int h72_numv = 24;
|
||||
const float h72_volu = 0.135103;
|
||||
const float h72_pos[3] = { -0.469590,0.119774,0.755853 };
|
||||
const float h72_verts[ h72_numv * 3 ] = {
|
||||
-0.212489,-0.155987,0.230040, -0.214701,-0.148769,0.244147, -0.443980,0.155306,0.107590, 0.375305,0.040715,-0.139275, -0.004437,0.090870,-0.389509, 0.311360,0.156806,0.046426, -0.480672,0.247962,0.244147, -0.005314,0.363706,-0.137567, 0.163621,-0.491997,-0.007622, 0.213688,0.055724,0.244147, -0.495580,0.247143,0.161130, -0.499540,0.269230,0.219387, 0.144703,0.290282,-0.088352, 0.355676,0.140088,-0.062598, -0.062609,-0.116199,-0.311398, -0.088334,0.254773,-0.303291, 0.356369,0.017480,-0.175583, 0.155877,-0.383277,0.244147, 0.169264,-0.493727,-0.003158, 0.197264,-0.459118,0.123740, 0.194631,-0.477857,0.074256, 0.211435,-0.450236,0.093267, 0.167388,-0.493339,-0.005093, 0.169626,-0.492143,-0.004615,
|
||||
};
|
||||
// h73
|
||||
const int h73_numv = 16;
|
||||
const float h73_volu = 0.036032;
|
||||
const float h73_pos[3] = { -0.912743,-0.085439,0.831075 };
|
||||
const float h73_verts[ h73_numv * 3 ] = {
|
||||
0.095887,-0.286600,-0.182455, -0.087257,0.175924,-0.168094, -0.087257,-0.205110,-0.364101, 0.230664,0.049226,0.154818, -0.037519,0.453174,0.168925, 0.228452,0.056443,0.168925, -0.087257,0.484247,0.168925, -0.000826,0.360518,0.032367, -0.087257,-0.218262,0.168925, -0.087257,-0.384387,-0.087440, -0.087257,0.485343,0.150329, -0.064760,0.476158,0.168925, -0.052427,0.452355,0.085908, -0.087257,0.457669,0.073457, -0.056387,0.474442,0.144165, -0.056885,0.474757,0.144652,
|
||||
};
|
||||
// h74
|
||||
const int h74_numv = 22;
|
||||
const float h74_volu = 0.115647;
|
||||
const float h74_pos[3] = { -0.806688,0.162223,0.365754 };
|
||||
const float h74_verts[ h74_numv * 3 ] = {
|
||||
-0.106882,0.112856,0.497689, -0.158482,0.204693,0.551229, 0.218764,0.243174,-0.153679, 0.270615,-0.014193,-0.214570, -0.193312,-0.071737,0.297227, 0.312298,0.070592,-0.150604, -0.069795,-0.227826,-0.358730, 0.248765,0.212323,0.086808, -0.193312,-0.408439,-0.106908, -0.193312,0.210007,0.538778, 0.301657,0.087464,-0.177940, -0.191931,0.033024,-0.314003, -0.193312,0.271426,0.001678, 0.058968,0.264774,-0.186519, -0.193312,0.247719,-0.120270, 0.052425,0.263623,-0.188445, 0.332661,0.048420,0.000590, 0.274489,-0.158648,0.078702, 0.238595,-0.223951,0.009084, 0.229318,-0.111676,-0.252511, -0.193312,-0.302733,-0.342536, -0.193312,0.032765,-0.313772,
|
||||
};
|
||||
// h75
|
||||
const int h75_numv = 18;
|
||||
const float h75_volu = 0.089620;
|
||||
const float h75_pos[3] = { 0.052817,0.072055,0.868740 };
|
||||
const float h75_verts[ h75_numv * 3 ] = {
|
||||
0.433734,0.123433,0.131260, 0.005775,0.176863,-0.278988, 0.218437,-0.214071,-0.051932, -0.366530,-0.335558,0.131260, -0.308719,0.103443,0.131260, -0.147102,0.088434,-0.252162, -0.310972,-0.402518,-0.019619, -0.003079,0.231496,-0.237914, 0.112171,0.347564,-0.006639, 0.302595,-0.019353,-0.141822, 0.235603,0.353295,0.131260, 0.077918,0.377107,0.131260, 0.249063,-0.227153,0.131260, -0.166731,0.187806,-0.175486, -0.093909,0.310921,0.131260, -0.211047,0.204525,-0.066461, -0.325143,-0.411399,0.010853, -0.320100,-0.425249,0.131260,
|
||||
};
|
||||
// h76
|
||||
const int h76_numv = 24;
|
||||
const float h76_volu = 0.095138;
|
||||
const float h76_pos[3] = { 0.088788,-0.142804,0.576459 };
|
||||
const float h76_verts[ h76_numv * 3 ] = {
|
||||
0.352221,-0.240915,-0.049761, -0.386828,-0.236459,0.178237, 0.182466,0.000788,0.240349, -0.006268,0.044860,-0.340368, 0.298110,0.182836,0.102163, -0.389114,-0.231150,0.176236, -0.030195,0.391722,0.013292, -0.363747,-0.215280,0.253650, -0.388752,-0.229565,0.174779, -0.101327,0.289860,-0.170144, 0.328315,-0.307617,-0.113256, -0.079254,0.048914,-0.283309, 0.094387,-0.120263,-0.302438, -0.281369,-0.303059,0.140194, 0.335039,-0.308192,-0.105343, 0.327448,-0.312089,-0.105986, 0.022142,0.379302,-0.133650, -0.346943,-0.187659,0.272661, -0.202009,0.280058,0.003811, -0.183073,0.303293,0.040119, 0.266624,0.195506,0.150459, -0.022476,0.325632,-0.215723, -0.347511,-0.285824,0.181989, -0.366010,-0.251196,0.221279,
|
||||
};
|
||||
// h77
|
||||
const int h77_numv = 26;
|
||||
const float h77_volu = 0.087804;
|
||||
const float h77_pos[3] = { 0.390778,-0.073451,0.362494 };
|
||||
const float h77_verts[ h77_numv * 3 ] = {
|
||||
-0.003880,0.113483,0.316128, 0.315369,-0.294228,0.065585, -0.206158,-0.189928,-0.093832, 0.020979,0.268088,0.071472, -0.324466,0.256279,-0.001758, -0.230465,0.381445,-0.183441, 0.426887,-0.187811,0.054869, 0.211155,-0.343689,0.091028, -0.224735,0.155039,-0.266749, 0.077733,0.119939,0.286241, 0.026325,-0.376970,0.100709, -0.297695,-0.031084,-0.153195, 0.009520,-0.343472,-0.067504, 0.155269,-0.307156,-0.121769, -0.207604,-0.189616,-0.088472, -0.308258,-0.024493,-0.126403, 0.050231,-0.310268,0.164204, 0.176117,-0.273019,-0.144419, 0.417855,-0.153875,-0.005953, 0.273422,-0.325958,0.057585, 0.096656,-0.370860,0.127368, 0.033049,-0.377545,0.108622, -0.214357,0.369295,-0.224944, 0.141437,0.190499,-0.081874, -0.279848,0.309949,0.080316, -0.221943,0.387815,-0.053985,
|
||||
};
|
||||
// h78
|
||||
const int h78_numv = 20;
|
||||
const float h78_volu = 0.126407;
|
||||
const float h78_pos[3] = { 0.652845,-0.171711,0.785711 };
|
||||
const float h78_verts[ h78_numv * 3 ] = {
|
||||
-0.350965,0.016612,0.214289, 0.347155,-0.072460,-0.306250, -0.381591,0.029695,0.031097, 0.347155,-0.139922,0.214289, 0.322332,-0.081469,-0.321579, -0.265947,0.211743,-0.107089, -0.020631,0.312250,-0.000249, 0.347155,0.151286,0.214289, 0.347155,-0.036860,-0.269624, -0.184333,0.218199,-0.136976, -0.297433,0.224413,-0.058793, -0.211836,-0.212008,-0.259013, -0.050911,-0.245429,-0.332189, -0.067869,-0.323764,0.214289, -0.166294,0.367199,0.214289, -0.026282,0.399418,0.214289, -0.145373,-0.294337,-0.277679, -0.165410,-0.272600,-0.295849, 0.053302,-0.195968,-0.357632, 0.164820,-0.089551,-0.368349,
|
||||
};
|
||||
// h79
|
||||
const int h79_numv = 20;
|
||||
const float h79_volu = 0.069132;
|
||||
const float h79_pos[3] = { 0.747670,0.086302,0.441993 };
|
||||
const float h79_verts[ h79_numv * 3 ] = {
|
||||
0.252330,0.012519,-0.215098, 0.012566,0.066820,-0.263433, 0.201221,-0.224177,-0.182831, 0.095169,0.321961,-0.051360, -0.091840,0.355257,0.097036, -0.215455,0.030746,-0.161373, -0.279159,-0.039814,0.206742, 0.060963,-0.313628,-0.085453, -0.115456,0.054238,0.343469, 0.252330,-0.294873,0.074094, -0.016233,0.366022,0.061965, -0.074702,0.310522,0.161887, 0.252330,0.103519,-0.130839, 0.252330,-0.216744,-0.175787, -0.335913,0.108335,-0.008027, 0.079494,0.109929,-0.259932, 0.069995,-0.347564,-0.024631, 0.252330,-0.330473,0.037468, 0.252330,-0.335180,0.024392, 0.227507,-0.339482,0.022139,
|
||||
};
|
||||
// h80
|
||||
const int h80_numv = 14;
|
||||
const float h80_volu = 0.076324;
|
||||
const float h80_pos[3] = { 0.872729,0.237609,0.718600 };
|
||||
const float h80_verts[ h80_numv * 3 ] = {
|
||||
0.127271,0.331095,-0.032200, 0.127271,-0.258034,0.281400, 0.127271,-0.446180,-0.202512, -0.199761,0.159215,-0.114719, -0.141292,0.214715,-0.214641, -0.136492,0.218429,-0.218946, -0.240515,-0.097070,0.066863, -0.246166,-0.009903,0.281400, -0.239577,0.050556,0.281400, 0.127271,0.263358,0.281400, 0.127271,0.246274,-0.293996, 0.127271,-0.047788,-0.407445, -0.039983,0.206584,-0.314412, -0.029889,0.170654,-0.327966,
|
||||
};
|
||||
// h81
|
||||
const int h81_numv = 10;
|
||||
const float h81_volu = 0.092471;
|
||||
const float h81_pos[3] = { -0.647649,0.823554,0.820209 };
|
||||
const float h81_verts[ h81_numv * 3 ] = {
|
||||
0.457657,0.176446,0.179791, -0.352351,-0.423650,0.161195, -0.352351,0.176446,-0.147497, -0.352351,-0.424746,0.179791, -0.352351,0.176446,0.179791, 0.395926,0.059255,0.179791, 0.203225,-0.169390,-0.173056, 0.338792,0.176446,-0.400601, -0.321979,-0.434236,0.155518, -0.329854,-0.432835,0.179791,
|
||||
};
|
||||
// h82
|
||||
const int h82_numv = 22;
|
||||
const float h82_volu = 0.133984;
|
||||
const float h82_pos[3] = { -0.704013,0.655334,0.510913 };
|
||||
const float h82_verts[ h82_numv * 3 ] = {
|
||||
-0.295987,0.344666,0.147853, 0.143982,-0.175036,-0.341668, -0.295987,-0.255430,0.470491, 0.398940,0.268255,-0.112413, -0.265615,-0.266016,0.464814, -0.043708,-0.228337,-0.331678, 0.395156,0.344666,-0.091306, 0.146090,-0.280788,-0.058352, 0.259589,-0.001170,0.136240, -0.295987,0.344666,0.161799, 0.268488,-0.087750,0.102566, -0.295987,-0.221685,-0.143481, -0.265117,-0.266331,0.464327, 0.229109,-0.171854,0.107373, -0.295987,-0.283104,0.393619, -0.261157,-0.288418,0.406070, 0.116089,-0.249937,-0.298838, 0.396013,0.344666,-0.093117, 0.248792,0.064649,-0.395197, 0.275014,0.344666,-0.270360, 0.114098,-0.109185,-0.385965, 0.213954,-0.004245,-0.405120,
|
||||
};
|
||||
// h83
|
||||
const int h83_numv = 12;
|
||||
const float h83_volu = 0.056796;
|
||||
const float h83_pos[3] = { -0.429347,0.488254,0.882979 };
|
||||
const float h83_verts[ h83_numv * 3 ] = {
|
||||
-0.006178,0.079330,-0.269501, -0.548156,-0.097535,0.117020, -0.015077,0.165910,-0.235826, -0.540281,-0.098936,0.092747, 0.104460,-0.078198,-0.215479, 0.388255,-0.105278,0.117020, 0.173445,-0.312756,0.117020, 0.177624,0.394555,0.117020, -0.045557,-0.004774,-0.264694, 0.271117,-0.211674,-0.080700, -0.539783,-0.099251,0.092261, -0.520915,-0.120519,0.117020,
|
||||
};
|
||||
// h84
|
||||
const int h84_numv = 22;
|
||||
const float h84_volu = 0.109330;
|
||||
const float h84_pos[3] = { -0.121674,0.670783,0.713170 };
|
||||
const float h84_verts[ h84_numv * 3 ] = {
|
||||
-0.313851,-0.103198,-0.099691, -0.010109,0.329217,0.286830, 0.252410,-0.221620,0.286830, -0.068318,0.329217,0.286830, 0.080582,-0.287807,0.286830, 0.201978,0.032805,-0.295587, -0.187183,0.329217,-0.293562, 0.227672,0.006891,-0.288529, -0.130049,0.212026,0.286830, -0.322750,-0.016619,-0.066017, -0.036556,-0.394202,0.089109, 0.171412,-0.367231,-0.082344, -0.203213,-0.260726,-0.045669, 0.007760,-0.410921,-0.019916, 0.265234,-0.083360,-0.251274, 0.286662,-0.251163,0.148930, -0.115141,0.329217,-0.286684, -0.066013,0.197094,-0.314670, -0.183399,0.252807,-0.314670, -0.186326,0.329217,-0.295374, 0.060573,0.329217,-0.240926, 0.066345,0.329217,-0.235802,
|
||||
};
|
||||
// h85
|
||||
const int h85_numv = 36;
|
||||
const float h85_volu = 0.148789;
|
||||
const float h85_pos[3] = { -0.198763,0.456116,0.345386 };
|
||||
const float h85_verts[ h85_numv * 3 ] = {
|
||||
0.248501,-0.152565,0.285440, 0.011075,0.411760,0.053114, 0.304761,0.221558,0.079254, 0.360475,-0.080906,-0.269891, -0.389161,-0.050719,-0.133311, 0.279067,0.247472,0.072197, 0.342323,0.131307,0.116509, -0.236762,0.111468,0.268093, 0.084849,-0.196255,0.347868, 0.186224,-0.309060,0.060929, -0.295627,-0.223301,-0.130236, 0.016686,0.009351,-0.358147, 0.315157,-0.069303,-0.293328, -0.106311,0.467473,0.053114, 0.257356,-0.207198,0.244366, 0.367598,-0.141752,-0.036878, 0.104478,-0.295627,0.271192, -0.126124,-0.046060,0.322115, -0.256458,0.263868,-0.229670, 0.085542,-0.318862,0.234884, -0.291296,0.194974,-0.239593, -0.265275,0.238760,-0.259807, -0.361268,0.024182,-0.176141, -0.291163,-0.195420,-0.172718, -0.276141,0.027364,0.272900, -0.306268,-0.206429,-0.157572, -0.275264,-0.245473,0.020958, -0.359160,-0.081570,0.107176, 0.360630,0.159839,0.075257, 0.387070,0.106509,-0.013499, 0.393155,0.083405,-0.037268, 0.359076,-0.148122,-0.166333, 0.309693,-0.219618,0.097423, 0.265075,-0.273288,0.015350, 0.118262,-0.041268,-0.360627, 0.049809,-0.043705,-0.365222,
|
||||
};
|
||||
// h86
|
||||
const int h86_numv = 14;
|
||||
const float h86_volu = 0.108919;
|
||||
const float h86_pos[3] = { 0.238541,0.789776,0.775739 };
|
||||
const float h86_verts[ h86_numv * 3 ] = {
|
||||
-0.094981,-0.202353,-0.313843, -0.370325,0.210224,0.224261, -0.076674,-0.173821,-0.355096, 0.281969,0.210224,-0.157785, 0.225385,0.024918,-0.224556, 0.374020,0.210224,0.224261, 0.316487,0.210224,-0.084750, -0.107806,-0.340614,0.224261, 0.201351,-0.281476,0.224261, 0.184090,-0.072562,-0.262496, -0.073553,-0.370157,0.086361, 0.049879,-0.364426,0.224261, -0.132543,-0.112102,-0.351098, -0.293871,0.210224,-0.298371,
|
||||
};
|
||||
// h87
|
||||
const int h87_numv = 16;
|
||||
const float h87_volu = 0.089360;
|
||||
const float h87_pos[3] = { 0.798384,0.791714,0.481127 };
|
||||
const float h87_verts[ h87_numv * 3 ] = {
|
||||
-0.277873,0.208286,0.136827, -0.253373,-0.199539,-0.004817, 0.201616,0.208286,-0.307196, 0.201616,0.189080,-0.312136, 0.201616,-0.223010,0.205272, 0.201616,0.208286,0.427133, 0.201616,-0.307831,-0.056523, -0.352696,-0.089547,0.003266, -0.060134,0.085556,-0.322787, -0.013117,0.208286,-0.294090, -0.336822,-0.121565,-0.050021, -0.196695,-0.100782,-0.260274, -0.062147,-0.335676,0.018525, 0.034362,-0.347521,-0.076940, -0.334458,0.022980,0.070056, -0.243356,0.208286,0.209862,
|
||||
};
|
||||
// h88
|
||||
const int h88_numv = 26;
|
||||
const float h88_volu = 0.102785;
|
||||
const float h88_pos[3] = { 0.372790,0.365732,0.656967 };
|
||||
const float h88_verts[ h88_numv * 3 ] = {
|
||||
-0.084370,0.059618,0.343033, 0.095722,-0.319244,-0.008232, 0.172221,0.226443,-0.180656, 0.300178,0.031092,-0.053086, 0.259424,-0.225193,0.128495, 0.253773,-0.138025,0.343033, -0.207802,0.053887,0.205134, 0.072899,0.336435,-0.172573, -0.203955,-0.051368,-0.348458, 0.260362,-0.077566,0.343033, 0.038967,-0.171095,-0.223000, 0.088772,0.304416,-0.225861, 0.113761,-0.170244,0.343033, 0.067103,0.142568,0.343033, -0.229230,0.221691,-0.195070, -0.323052,-0.062181,-0.026140, 0.014109,-0.325700,0.021656, -0.261860,-0.129234,-0.214158, -0.017378,-0.313030,0.069951, -0.314197,-0.116814,-0.067215, 0.049841,0.351482,-0.143724, -0.178398,0.173789,-0.348849, -0.210923,0.250223,-0.236324, 0.283040,0.075827,-0.117937, -0.184483,0.196893,-0.325078, -0.167799,0.186994,-0.344427,
|
||||
};
|
||||
// h89
|
||||
const int h89_numv = 16;
|
||||
const float h89_volu = 0.098811;
|
||||
const float h89_pos[3] = { 0.713605,0.673779,0.814484 };
|
||||
const float h89_verts[ h89_numv * 3 ] = {
|
||||
-0.273713,-0.165479,0.185516, -0.080453,-0.385613,0.185516, 0.286395,-0.172812,0.185516, 0.286395,0.326221,0.093776, -0.101044,0.326221,0.185516, 0.286395,0.326221,0.185516, 0.017832,-0.221455,-0.310526, 0.286395,-0.105074,-0.128085, -0.040637,-0.276955,-0.210604, -0.057774,-0.232220,-0.275455, -0.158577,0.326221,-0.123495, -0.267917,0.028388,-0.330091, -0.290974,0.043435,-0.301241, -0.249679,0.140915,-0.263301, -0.168594,-0.081604,-0.338174, 0.022632,-0.217741,-0.314831,
|
||||
};
|
||||
|
||||
//Aggregate of all cells.
|
||||
const int halton_numc = 90;
|
||||
const int halton_numv[ halton_numc ] = {
|
||||
h00_numv,h01_numv,h02_numv,h03_numv,h04_numv,h05_numv,h06_numv,h07_numv,h08_numv,h09_numv,h10_numv,h11_numv,h12_numv,h13_numv,h14_numv,h15_numv,h16_numv,h17_numv,h18_numv,h19_numv,h20_numv,h21_numv,h22_numv,h23_numv,h24_numv,h25_numv,h26_numv,h27_numv,h28_numv,h29_numv,h30_numv,h31_numv,h32_numv,h33_numv,h34_numv,h35_numv,h36_numv,h37_numv,h38_numv,h39_numv,h40_numv,h41_numv,h42_numv,h43_numv,h44_numv,h45_numv,h46_numv,h47_numv,h48_numv,h49_numv,h50_numv,h51_numv,h52_numv,h53_numv,h54_numv,h55_numv,h56_numv,h57_numv,h58_numv,h59_numv,h60_numv,h61_numv,h62_numv,h63_numv,h64_numv,h65_numv,h66_numv,h67_numv,h68_numv,h69_numv,h70_numv,h71_numv,h72_numv,h73_numv,h74_numv,h75_numv,h76_numv,h77_numv,h78_numv,h79_numv,h80_numv,h81_numv,h82_numv,h83_numv,h84_numv,h85_numv,h86_numv,h87_numv,h88_numv,h89_numv,
|
||||
};
|
||||
const float halton_volu[ halton_numc ] = {
|
||||
h00_volu,h01_volu,h02_volu,h03_volu,h04_volu,h05_volu,h06_volu,h07_volu,h08_volu,h09_volu,h10_volu,h11_volu,h12_volu,h13_volu,h14_volu,h15_volu,h16_volu,h17_volu,h18_volu,h19_volu,h20_volu,h21_volu,h22_volu,h23_volu,h24_volu,h25_volu,h26_volu,h27_volu,h28_volu,h29_volu,h30_volu,h31_volu,h32_volu,h33_volu,h34_volu,h35_volu,h36_volu,h37_volu,h38_volu,h39_volu,h40_volu,h41_volu,h42_volu,h43_volu,h44_volu,h45_volu,h46_volu,h47_volu,h48_volu,h49_volu,h50_volu,h51_volu,h52_volu,h53_volu,h54_volu,h55_volu,h56_volu,h57_volu,h58_volu,h59_volu,h60_volu,h61_volu,h62_volu,h63_volu,h64_volu,h65_volu,h66_volu,h67_volu,h68_volu,h69_volu,h70_volu,h71_volu,h72_volu,h73_volu,h74_volu,h75_volu,h76_volu,h77_volu,h78_volu,h79_volu,h80_volu,h81_volu,h82_volu,h83_volu,h84_volu,h85_volu,h86_volu,h87_volu,h88_volu,h89_volu,
|
||||
};
|
||||
const float* halton_pos[ halton_numc ] = {
|
||||
h00_pos,h01_pos,h02_pos,h03_pos,h04_pos,h05_pos,h06_pos,h07_pos,h08_pos,h09_pos,h10_pos,h11_pos,h12_pos,h13_pos,h14_pos,h15_pos,h16_pos,h17_pos,h18_pos,h19_pos,h20_pos,h21_pos,h22_pos,h23_pos,h24_pos,h25_pos,h26_pos,h27_pos,h28_pos,h29_pos,h30_pos,h31_pos,h32_pos,h33_pos,h34_pos,h35_pos,h36_pos,h37_pos,h38_pos,h39_pos,h40_pos,h41_pos,h42_pos,h43_pos,h44_pos,h45_pos,h46_pos,h47_pos,h48_pos,h49_pos,h50_pos,h51_pos,h52_pos,h53_pos,h54_pos,h55_pos,h56_pos,h57_pos,h58_pos,h59_pos,h60_pos,h61_pos,h62_pos,h63_pos,h64_pos,h65_pos,h66_pos,h67_pos,h68_pos,h69_pos,h70_pos,h71_pos,h72_pos,h73_pos,h74_pos,h75_pos,h76_pos,h77_pos,h78_pos,h79_pos,h80_pos,h81_pos,h82_pos,h83_pos,h84_pos,h85_pos,h86_pos,h87_pos,h88_pos,h89_pos,
|
||||
};
|
||||
const float* halton_verts[ halton_numc ] = {
|
||||
h00_verts,h01_verts,h02_verts,h03_verts,h04_verts,h05_verts,h06_verts,h07_verts,h08_verts,h09_verts,h10_verts,h11_verts,h12_verts,h13_verts,h14_verts,h15_verts,h16_verts,h17_verts,h18_verts,h19_verts,h20_verts,h21_verts,h22_verts,h23_verts,h24_verts,h25_verts,h26_verts,h27_verts,h28_verts,h29_verts,h30_verts,h31_verts,h32_verts,h33_verts,h34_verts,h35_verts,h36_verts,h37_verts,h38_verts,h39_verts,h40_verts,h41_verts,h42_verts,h43_verts,h44_verts,h45_verts,h46_verts,h47_verts,h48_verts,h49_verts,h50_verts,h51_verts,h52_verts,h53_verts,h54_verts,h55_verts,h56_verts,h57_verts,h58_verts,h59_verts,h60_verts,h61_verts,h62_verts,h63_verts,h64_verts,h65_verts,h66_verts,h67_verts,h68_verts,h69_verts,h70_verts,h71_verts,h72_verts,h73_verts,h74_verts,h75_verts,h76_verts,h77_verts,h78_verts,h79_verts,h80_verts,h81_verts,h82_verts,h83_verts,h84_verts,h85_verts,h86_verts,h87_verts,h88_verts,h89_verts,
|
||||
};
|
||||
|
|
@ -2,48 +2,133 @@
|
|||
#define TaruIdxCount 132
|
||||
|
||||
static float TaruVtx[] = {
|
||||
1.08664f,-1.99237f,0.0f,
|
||||
0.768369f,-1.99237f,-0.768369f,
|
||||
1.28852f,1.34412e-007f,-1.28852f,
|
||||
1.82224f,1.90735e-007f,0.0f,
|
||||
0.0f,-1.99237f,-1.08664f,
|
||||
0.0f,0.0f,-1.82224f,
|
||||
0.0f,-1.99237f,-1.08664f,
|
||||
-0.768369f,-1.99237f,-0.768369f,
|
||||
-1.28852f,1.34412e-007f,-1.28852f,
|
||||
0.0f,0.0f,-1.82224f,
|
||||
-1.08664f,-1.99237f,1.82086e-007f,
|
||||
-1.82224f,1.90735e-007f,1.59305e-007f,
|
||||
-0.768369f,-1.99237f,0.76837f,
|
||||
-1.28852f,2.47058e-007f,1.28852f,
|
||||
1.42495e-007f,-1.99237f,1.08664f,
|
||||
2.38958e-007f,2.70388e-007f,1.82224f,
|
||||
0.768369f,-1.99237f,0.768369f,
|
||||
1.28852f,2.47058e-007f,1.28852f,
|
||||
0.768369f,1.99237f,-0.768369f,
|
||||
1.08664f,1.99237f,0.0f,
|
||||
0.0f,1.99237f,-1.08664f,
|
||||
-0.768369f,1.99237f,-0.768369f,
|
||||
0.0f,1.99237f,-1.08664f,
|
||||
-1.08664f,1.99237f,0.0f,
|
||||
-0.768369f,1.99237f,0.768369f,
|
||||
1.42495e-007f,1.99237f,1.08664f,
|
||||
0.768369f,1.99237f,0.768369f,
|
||||
1.42495e-007f,-1.99237f,1.08664f,
|
||||
-0.768369f,-1.99237f,0.76837f,
|
||||
-1.08664f,-1.99237f,1.82086e-007f,
|
||||
-0.768369f,-1.99237f,-0.768369f,
|
||||
0.0f,-1.99237f,-1.08664f,
|
||||
0.768369f,-1.99237f,-0.768369f,
|
||||
1.08664f,-1.99237f,0.0f,
|
||||
0.768369f,-1.99237f,0.768369f,
|
||||
0.768369f,1.99237f,-0.768369f,
|
||||
0.0f,1.99237f,-1.08664f,
|
||||
-0.768369f,1.99237f,-0.768369f,
|
||||
-1.08664f,1.99237f,0.0f,
|
||||
-0.768369f,1.99237f,0.768369f,
|
||||
1.42495e-007f,1.99237f,1.08664f,
|
||||
0.768369f,1.99237f,0.768369f,
|
||||
1.08664f,1.99237f,0.0f,
|
||||
1.08664f,
|
||||
-1.99237f,
|
||||
0.0f,
|
||||
0.768369f,
|
||||
-1.99237f,
|
||||
-0.768369f,
|
||||
1.28852f,
|
||||
1.34412e-007f,
|
||||
-1.28852f,
|
||||
1.82224f,
|
||||
1.90735e-007f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
-1.99237f,
|
||||
-1.08664f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
-1.82224f,
|
||||
0.0f,
|
||||
-1.99237f,
|
||||
-1.08664f,
|
||||
-0.768369f,
|
||||
-1.99237f,
|
||||
-0.768369f,
|
||||
-1.28852f,
|
||||
1.34412e-007f,
|
||||
-1.28852f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
-1.82224f,
|
||||
-1.08664f,
|
||||
-1.99237f,
|
||||
1.82086e-007f,
|
||||
-1.82224f,
|
||||
1.90735e-007f,
|
||||
1.59305e-007f,
|
||||
-0.768369f,
|
||||
-1.99237f,
|
||||
0.76837f,
|
||||
-1.28852f,
|
||||
2.47058e-007f,
|
||||
1.28852f,
|
||||
1.42495e-007f,
|
||||
-1.99237f,
|
||||
1.08664f,
|
||||
2.38958e-007f,
|
||||
2.70388e-007f,
|
||||
1.82224f,
|
||||
0.768369f,
|
||||
-1.99237f,
|
||||
0.768369f,
|
||||
1.28852f,
|
||||
2.47058e-007f,
|
||||
1.28852f,
|
||||
0.768369f,
|
||||
1.99237f,
|
||||
-0.768369f,
|
||||
1.08664f,
|
||||
1.99237f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
1.99237f,
|
||||
-1.08664f,
|
||||
-0.768369f,
|
||||
1.99237f,
|
||||
-0.768369f,
|
||||
0.0f,
|
||||
1.99237f,
|
||||
-1.08664f,
|
||||
-1.08664f,
|
||||
1.99237f,
|
||||
0.0f,
|
||||
-0.768369f,
|
||||
1.99237f,
|
||||
0.768369f,
|
||||
1.42495e-007f,
|
||||
1.99237f,
|
||||
1.08664f,
|
||||
0.768369f,
|
||||
1.99237f,
|
||||
0.768369f,
|
||||
1.42495e-007f,
|
||||
-1.99237f,
|
||||
1.08664f,
|
||||
-0.768369f,
|
||||
-1.99237f,
|
||||
0.76837f,
|
||||
-1.08664f,
|
||||
-1.99237f,
|
||||
1.82086e-007f,
|
||||
-0.768369f,
|
||||
-1.99237f,
|
||||
-0.768369f,
|
||||
0.0f,
|
||||
-1.99237f,
|
||||
-1.08664f,
|
||||
0.768369f,
|
||||
-1.99237f,
|
||||
-0.768369f,
|
||||
1.08664f,
|
||||
-1.99237f,
|
||||
0.0f,
|
||||
0.768369f,
|
||||
-1.99237f,
|
||||
0.768369f,
|
||||
0.768369f,
|
||||
1.99237f,
|
||||
-0.768369f,
|
||||
0.0f,
|
||||
1.99237f,
|
||||
-1.08664f,
|
||||
-0.768369f,
|
||||
1.99237f,
|
||||
-0.768369f,
|
||||
-1.08664f,
|
||||
1.99237f,
|
||||
0.0f,
|
||||
-0.768369f,
|
||||
1.99237f,
|
||||
0.768369f,
|
||||
1.42495e-007f,
|
||||
1.99237f,
|
||||
1.08664f,
|
||||
0.768369f,
|
||||
1.99237f,
|
||||
0.768369f,
|
||||
1.08664f,
|
||||
1.99237f,
|
||||
0.0f,
|
||||
};
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
119
Engine/lib/bullet/examples/BulletRobotics/BoxStack.cpp
Normal file
119
Engine/lib/bullet/examples/BulletRobotics/BoxStack.cpp
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
|
||||
#include "BoxStack.h"
|
||||
|
||||
#include "../CommonInterfaces/CommonGraphicsAppInterface.h"
|
||||
#include "Bullet3Common/b3AlignedObjectArray.h"
|
||||
#include "../CommonInterfaces/CommonRenderInterface.h"
|
||||
#include "../CommonInterfaces/CommonExampleInterface.h"
|
||||
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
|
||||
#include "../SharedMemory/PhysicsServerSharedMemory.h"
|
||||
#include "../SharedMemory/PhysicsClientC_API.h"
|
||||
#include "../CommonInterfaces/CommonParameterInterface.h"
|
||||
#include "../SharedMemory/SharedMemoryPublic.h"
|
||||
#include <string>
|
||||
|
||||
#include "../RobotSimulator/b3RobotSimulatorClientAPI.h"
|
||||
#include "../Utils/b3Clock.h"
|
||||
|
||||
class BoxStackExample : public CommonExampleInterface
|
||||
{
|
||||
CommonGraphicsApp* m_app;
|
||||
GUIHelperInterface* m_guiHelper;
|
||||
b3RobotSimulatorClientAPI m_robotSim;
|
||||
int m_options;
|
||||
|
||||
public:
|
||||
BoxStackExample(GUIHelperInterface* helper, int options)
|
||||
: m_app(helper->getAppInterface()),
|
||||
m_guiHelper(helper),
|
||||
m_options(options)
|
||||
{
|
||||
m_app->setUpAxis(2);
|
||||
}
|
||||
|
||||
virtual ~BoxStackExample()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void physicsDebugDraw(int debugDrawMode)
|
||||
{
|
||||
m_robotSim.debugDraw(debugDrawMode);
|
||||
}
|
||||
virtual void initPhysics()
|
||||
{
|
||||
int mode = eCONNECT_EXISTING_EXAMPLE_BROWSER;
|
||||
m_robotSim.setGuiHelper(m_guiHelper);
|
||||
bool connected = m_robotSim.connect(mode);
|
||||
|
||||
b3Printf("robotSim connected = %d", connected);
|
||||
|
||||
m_robotSim.configureDebugVisualizer(COV_ENABLE_RGB_BUFFER_PREVIEW, 0);
|
||||
m_robotSim.configureDebugVisualizer(COV_ENABLE_DEPTH_BUFFER_PREVIEW, 0);
|
||||
m_robotSim.configureDebugVisualizer(COV_ENABLE_SEGMENTATION_MARK_PREVIEW, 0);
|
||||
|
||||
b3RobotSimulatorLoadUrdfFileArgs args;
|
||||
b3RobotSimulatorChangeDynamicsArgs dynamicsArgs;
|
||||
int massRatio = 4;
|
||||
int mass = 1;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
args.m_startPosition.setValue(0, 0, i * .06);
|
||||
int boxIdx = m_robotSim.loadURDF("cube_small.urdf", args);
|
||||
dynamicsArgs.m_mass = mass;
|
||||
m_robotSim.changeDynamics(boxIdx, -1, dynamicsArgs);
|
||||
mass *= massRatio;
|
||||
}
|
||||
|
||||
m_robotSim.loadURDF("plane.urdf");
|
||||
m_robotSim.setGravity(btVector3(0, 0, -10));
|
||||
}
|
||||
|
||||
virtual void exitPhysics()
|
||||
{
|
||||
m_robotSim.disconnect();
|
||||
}
|
||||
virtual void stepSimulation(float deltaTime)
|
||||
{
|
||||
m_robotSim.stepSimulation();
|
||||
}
|
||||
virtual void renderScene()
|
||||
{
|
||||
m_robotSim.renderScene();
|
||||
}
|
||||
|
||||
virtual bool mouseMoveCallback(float x, float y)
|
||||
{
|
||||
return m_robotSim.mouseMoveCallback(x, y);
|
||||
}
|
||||
virtual bool mouseButtonCallback(int button, int state, float x, float y)
|
||||
{
|
||||
return m_robotSim.mouseButtonCallback(button, state, x, y);
|
||||
}
|
||||
virtual bool keyboardCallback(int key, int state)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void resetCamera()
|
||||
{
|
||||
float dist = 1.5;
|
||||
float pitch = -10;
|
||||
float yaw = 18;
|
||||
float targetPos[3] = {-0.2, 0.8, 0.3};
|
||||
|
||||
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
|
||||
|
||||
if (m_app->m_renderer && m_app->m_renderer->getActiveCamera())
|
||||
{
|
||||
m_app->m_renderer->getActiveCamera()->setCameraDistance(dist);
|
||||
m_app->m_renderer->getActiveCamera()->setCameraPitch(pitch);
|
||||
m_app->m_renderer->getActiveCamera()->setCameraYaw(yaw);
|
||||
m_app->m_renderer->getActiveCamera()->setCameraTargetPosition(targetPos[0], targetPos[1], targetPos[2]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class CommonExampleInterface* BoxStackExampleCreateFunc(struct CommonExampleOptions& options)
|
||||
{
|
||||
return new BoxStackExample(options.m_guiHelper, options.m_option);
|
||||
}
|
||||
21
Engine/lib/bullet/examples/BulletRobotics/BoxStack.h
Normal file
21
Engine/lib/bullet/examples/BulletRobotics/BoxStack.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2016 Google Inc. http://bulletphysics.org
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BOX_STACK_EXAMPLE_H
|
||||
#define BOX_STACK_EXAMPLE_H
|
||||
|
||||
class CommonExampleInterface* BoxStackExampleCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
#endif //BOX_STACK_EXAMPLE_H
|
||||
172
Engine/lib/bullet/examples/BulletRobotics/FixJointBoxes.cpp
Normal file
172
Engine/lib/bullet/examples/BulletRobotics/FixJointBoxes.cpp
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
#include "FixJointBoxes.h"
|
||||
|
||||
#include "../CommonInterfaces/CommonGraphicsAppInterface.h"
|
||||
#include "Bullet3Common/b3AlignedObjectArray.h"
|
||||
#include "../CommonInterfaces/CommonRenderInterface.h"
|
||||
#include "../CommonInterfaces/CommonExampleInterface.h"
|
||||
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
|
||||
#include "../SharedMemory/PhysicsServerSharedMemory.h"
|
||||
#include "../SharedMemory/PhysicsClientC_API.h"
|
||||
#include "../SharedMemory/SharedMemoryPublic.h"
|
||||
#include "../CommonInterfaces/CommonParameterInterface.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "../RobotSimulator/b3RobotSimulatorClientAPI.h"
|
||||
|
||||
static btScalar numSolverIterations = 1000;
|
||||
static btScalar solverId = 0;
|
||||
|
||||
class FixJointBoxes : public CommonExampleInterface
|
||||
{
|
||||
GUIHelperInterface* m_guiHelper;
|
||||
b3RobotSimulatorClientAPI m_robotSim;
|
||||
int m_options;
|
||||
b3RobotSimulatorSetPhysicsEngineParameters physicsArgs;
|
||||
int solver;
|
||||
|
||||
const size_t numCubes;
|
||||
std::vector<int> cubeIds;
|
||||
|
||||
public:
|
||||
FixJointBoxes(GUIHelperInterface* helper, int options)
|
||||
: m_guiHelper(helper),
|
||||
m_options(options),
|
||||
numCubes(30),
|
||||
cubeIds(numCubes, 0),
|
||||
solver(solverId)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~FixJointBoxes()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void physicsDebugDraw(int debugDrawMode)
|
||||
{
|
||||
m_robotSim.debugDraw(debugDrawMode);
|
||||
}
|
||||
virtual void initPhysics()
|
||||
{
|
||||
int mode = eCONNECT_EXISTING_EXAMPLE_BROWSER;
|
||||
m_robotSim.setGuiHelper(m_guiHelper);
|
||||
bool connected = m_robotSim.connect(mode);
|
||||
|
||||
b3Printf("robotSim connected = %d", connected);
|
||||
|
||||
m_robotSim.configureDebugVisualizer(COV_ENABLE_RGB_BUFFER_PREVIEW, 0);
|
||||
m_robotSim.configureDebugVisualizer(COV_ENABLE_DEPTH_BUFFER_PREVIEW, 0);
|
||||
m_robotSim.configureDebugVisualizer(COV_ENABLE_SEGMENTATION_MARK_PREVIEW, 0);
|
||||
|
||||
{
|
||||
b3RobotSimulatorLoadUrdfFileArgs args;
|
||||
b3RobotSimulatorChangeDynamicsArgs dynamicsArgs;
|
||||
|
||||
for (int i = 0; i < numCubes; i++)
|
||||
{
|
||||
args.m_forceOverrideFixedBase = (i == 0);
|
||||
args.m_startPosition.setValue(0, i * 0.05, 1);
|
||||
cubeIds[i] = m_robotSim.loadURDF("cube_small.urdf", args);
|
||||
|
||||
b3RobotJointInfo jointInfo;
|
||||
|
||||
jointInfo.m_parentFrame[1] = -0.025;
|
||||
jointInfo.m_childFrame[1] = 0.025;
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
m_robotSim.createConstraint(cubeIds[i], -1, cubeIds[i - 1], -1, &jointInfo);
|
||||
m_robotSim.setCollisionFilterGroupMask(cubeIds[i], -1, 0, 0);
|
||||
}
|
||||
|
||||
m_robotSim.loadURDF("plane.urdf");
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
SliderParams slider("Direct solver", &solverId);
|
||||
slider.m_minVal = 0;
|
||||
slider.m_maxVal = 1;
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
}
|
||||
{
|
||||
SliderParams slider("numSolverIterations", &numSolverIterations);
|
||||
slider.m_minVal = 50;
|
||||
slider.m_maxVal = 1e4;
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
}
|
||||
|
||||
physicsArgs.m_defaultGlobalCFM = 1e-6;
|
||||
m_robotSim.setPhysicsEngineParameter(physicsArgs);
|
||||
|
||||
m_robotSim.setGravity(btVector3(0, 0, -10));
|
||||
m_robotSim.setNumSolverIterations((int)numSolverIterations);
|
||||
}
|
||||
|
||||
virtual void exitPhysics()
|
||||
{
|
||||
m_robotSim.disconnect();
|
||||
}
|
||||
|
||||
void resetCubePosition()
|
||||
{
|
||||
for (int i = 0; i < numCubes; i++)
|
||||
{
|
||||
btVector3 pos(0, i * (btScalar)0.05, 1);
|
||||
btQuaternion quar(0, 0, 0, 1);
|
||||
m_robotSim.resetBasePositionAndOrientation(cubeIds[i], pos, quar);
|
||||
}
|
||||
}
|
||||
virtual void stepSimulation(float deltaTime)
|
||||
{
|
||||
int newSolver = (int)(solverId + 0.5);
|
||||
if (newSolver != solver)
|
||||
{
|
||||
printf("Switching solver, new %d, old %d\n", newSolver, solver);
|
||||
solver = newSolver;
|
||||
resetCubePosition();
|
||||
if (solver)
|
||||
{
|
||||
physicsArgs.m_constraintSolverType = eConstraintSolverLCP_DANTZIG;
|
||||
}
|
||||
else
|
||||
{
|
||||
physicsArgs.m_constraintSolverType = eConstraintSolverLCP_SI;
|
||||
}
|
||||
|
||||
m_robotSim.setPhysicsEngineParameter(physicsArgs);
|
||||
}
|
||||
m_robotSim.setNumSolverIterations((int)numSolverIterations);
|
||||
m_robotSim.stepSimulation();
|
||||
}
|
||||
virtual void renderScene()
|
||||
{
|
||||
m_robotSim.renderScene();
|
||||
}
|
||||
|
||||
virtual bool mouseMoveCallback(float x, float y)
|
||||
{
|
||||
return m_robotSim.mouseMoveCallback(x, y);
|
||||
}
|
||||
virtual bool mouseButtonCallback(int button, int state, float x, float y)
|
||||
{
|
||||
return m_robotSim.mouseButtonCallback(button, state, x, y);
|
||||
}
|
||||
virtual bool keyboardCallback(int key, int state)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void resetCamera()
|
||||
{
|
||||
float dist = 1;
|
||||
float pitch = -20;
|
||||
float yaw = -30;
|
||||
float targetPos[3] = {0, 0.2, 0.5};
|
||||
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
|
||||
}
|
||||
};
|
||||
|
||||
class CommonExampleInterface* FixJointBoxesCreateFunc(struct CommonExampleOptions& options)
|
||||
{
|
||||
return new FixJointBoxes(options.m_guiHelper, options.m_option);
|
||||
}
|
||||
21
Engine/lib/bullet/examples/BulletRobotics/FixJointBoxes.h
Normal file
21
Engine/lib/bullet/examples/BulletRobotics/FixJointBoxes.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2016 Google Inc. http://bulletphysics.org
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef FIX_JOINT_BOXES_H
|
||||
#define FIX_JOINT_BOXES_H
|
||||
|
||||
class CommonExampleInterface* FixJointBoxesCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
#endif //FIX_JOINT_BOXES_H
|
||||
109
Engine/lib/bullet/examples/BulletRobotics/JointLimit.cpp
Normal file
109
Engine/lib/bullet/examples/BulletRobotics/JointLimit.cpp
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
|
||||
#include "JointLimit.h"
|
||||
|
||||
#include "../CommonInterfaces/CommonGraphicsAppInterface.h"
|
||||
#include "Bullet3Common/b3AlignedObjectArray.h"
|
||||
#include "../CommonInterfaces/CommonRenderInterface.h"
|
||||
#include "../CommonInterfaces/CommonExampleInterface.h"
|
||||
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
|
||||
#include "../SharedMemory/PhysicsServerSharedMemory.h"
|
||||
#include "../SharedMemory/PhysicsClientC_API.h"
|
||||
#include "../SharedMemory/SharedMemoryPublic.h"
|
||||
#include "../CommonInterfaces/CommonParameterInterface.h"
|
||||
#include <string>
|
||||
|
||||
#include "../RobotSimulator/b3RobotSimulatorClientAPI.h"
|
||||
#include "../Utils/b3Clock.h"
|
||||
|
||||
class JointLimit : public CommonExampleInterface
|
||||
{
|
||||
GUIHelperInterface* m_guiHelper;
|
||||
b3RobotSimulatorClientAPI m_robotSim;
|
||||
int m_options;
|
||||
|
||||
public:
|
||||
JointLimit(GUIHelperInterface* helper, int options)
|
||||
: m_guiHelper(helper),
|
||||
m_options(options)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~JointLimit()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void physicsDebugDraw(int debugDrawMode)
|
||||
{
|
||||
m_robotSim.debugDraw(debugDrawMode);
|
||||
}
|
||||
virtual void initPhysics()
|
||||
{
|
||||
int mode = eCONNECT_EXISTING_EXAMPLE_BROWSER;
|
||||
m_robotSim.setGuiHelper(m_guiHelper);
|
||||
bool connected = m_robotSim.connect(mode);
|
||||
|
||||
b3Printf("robotSim connected = %d", connected);
|
||||
|
||||
m_robotSim.configureDebugVisualizer(COV_ENABLE_RGB_BUFFER_PREVIEW, 0);
|
||||
m_robotSim.configureDebugVisualizer(COV_ENABLE_DEPTH_BUFFER_PREVIEW, 0);
|
||||
m_robotSim.configureDebugVisualizer(COV_ENABLE_SEGMENTATION_MARK_PREVIEW, 0);
|
||||
|
||||
b3RobotSimulatorSetPhysicsEngineParameters physicsArgs;
|
||||
physicsArgs.m_constraintSolverType = eConstraintSolverLCP_DANTZIG;
|
||||
|
||||
physicsArgs.m_defaultGlobalCFM = 1e-6;
|
||||
|
||||
m_robotSim.setNumSolverIterations(10);
|
||||
|
||||
b3RobotSimulatorLoadUrdfFileArgs loadArgs;
|
||||
int humanoid = m_robotSim.loadURDF("test_joints_MB.urdf", loadArgs);
|
||||
|
||||
b3RobotSimulatorChangeDynamicsArgs dynamicsArgs;
|
||||
dynamicsArgs.m_linearDamping = 0;
|
||||
dynamicsArgs.m_angularDamping = 0;
|
||||
m_robotSim.changeDynamics(humanoid, -1, dynamicsArgs);
|
||||
|
||||
m_robotSim.setGravity(btVector3(0, 0, -10));
|
||||
}
|
||||
|
||||
virtual void exitPhysics()
|
||||
{
|
||||
m_robotSim.disconnect();
|
||||
}
|
||||
virtual void stepSimulation(float deltaTime)
|
||||
{
|
||||
m_robotSim.stepSimulation();
|
||||
}
|
||||
virtual void renderScene()
|
||||
{
|
||||
m_robotSim.renderScene();
|
||||
}
|
||||
|
||||
virtual bool mouseMoveCallback(float x, float y)
|
||||
{
|
||||
return m_robotSim.mouseMoveCallback(x, y);
|
||||
}
|
||||
virtual bool mouseButtonCallback(int button, int state, float x, float y)
|
||||
{
|
||||
return m_robotSim.mouseButtonCallback(button, state, x, y);
|
||||
}
|
||||
virtual bool keyboardCallback(int key, int state)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void resetCamera()
|
||||
{
|
||||
float dist = 3;
|
||||
float pitch = -10;
|
||||
float yaw = 18;
|
||||
float targetPos[3] = {0.6, 0.8, 0.3};
|
||||
|
||||
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
|
||||
}
|
||||
};
|
||||
|
||||
class CommonExampleInterface* JointLimitCreateFunc(struct CommonExampleOptions& options)
|
||||
{
|
||||
return new JointLimit(options.m_guiHelper, options.m_option);
|
||||
}
|
||||
21
Engine/lib/bullet/examples/BulletRobotics/JointLimit.h
Normal file
21
Engine/lib/bullet/examples/BulletRobotics/JointLimit.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2016 Google Inc. http://bulletphysics.org
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef JOINT_LIMIT_EXAMPLE_H
|
||||
#define JOINT_LIMIT_EXAMPLE_H
|
||||
|
||||
class CommonExampleInterface* JointLimitCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
#endif //JOINT_LIMIT_EXAMPLE_H
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
SUBDIRS( HelloWorld BasicDemo )
|
||||
SUBDIRS( HelloWorld BasicDemo)
|
||||
IF(BUILD_BULLET3)
|
||||
SUBDIRS( ExampleBrowser ThirdPartyLibs/Gwen ThirdPartyLibs/BussIK OpenGLWindow )
|
||||
SUBDIRS( ExampleBrowser RobotSimulator SharedMemory ThirdPartyLibs/Gwen ThirdPartyLibs/BussIK ThirdPartyLibs/clsocket OpenGLWindow TwoJoint )
|
||||
ENDIF()
|
||||
|
||||
IF(BUILD_PYBULLET)
|
||||
SUBDIRS(pybullet)
|
||||
ENDIF(BUILD_PYBULLET)
|
||||
|
|
|
|||
|
|
@ -3,17 +3,17 @@
|
|||
#include "Internal/Bullet2CollisionSdk.h"
|
||||
#include "Internal/RealTimeBullet3CollisionSdk.h"
|
||||
|
||||
/* Collision World */
|
||||
|
||||
/* Collision World */
|
||||
|
||||
plCollisionWorldHandle plCreateCollisionWorld(plCollisionSdkHandle collisionSdkHandle, int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity)
|
||||
{
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
|
||||
return sdk->createCollisionWorld( maxNumObjsCapacity, maxNumShapesCapacity, maxNumPairsCapacity);
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
|
||||
return sdk->createCollisionWorld(maxNumObjsCapacity, maxNumShapesCapacity, maxNumPairsCapacity);
|
||||
}
|
||||
|
||||
void plDeleteCollisionWorld(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle)
|
||||
void plDeleteCollisionWorld(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle)
|
||||
{
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
|
||||
if (sdk && worldHandle)
|
||||
{
|
||||
sdk->deleteCollisionWorld(worldHandle);
|
||||
|
|
@ -26,7 +26,7 @@ plCollisionSdkHandle plCreateBullet2CollisionSdk()
|
|||
return Bullet2CollisionSdk::createBullet2SdkHandle();
|
||||
#else
|
||||
return 0;
|
||||
#endif //DISABLE_BULLET2_COLLISION_SDK
|
||||
#endif //DISABLE_BULLET2_COLLISION_SDK
|
||||
}
|
||||
|
||||
plCollisionSdkHandle plCreateRealTimeBullet3CollisionSdk()
|
||||
|
|
@ -40,91 +40,89 @@ plCollisionSdkHandle plCreateRealTimeBullet3CollisionSdk()
|
|||
|
||||
void plDeleteCollisionSdk(plCollisionSdkHandle collisionSdkHandle)
|
||||
{
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
|
||||
delete sdk;
|
||||
}
|
||||
|
||||
plCollisionShapeHandle plCreateSphereShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plReal radius)
|
||||
{
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
|
||||
return sdk->createSphereShape(worldHandle,radius);
|
||||
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
|
||||
return sdk->createSphereShape(worldHandle, radius);
|
||||
}
|
||||
|
||||
plCollisionShapeHandle plCreatePlaneShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle,
|
||||
plReal planeNormalX,
|
||||
plReal planeNormalY,
|
||||
plReal planeNormalZ,
|
||||
plReal planeConstant)
|
||||
plCollisionShapeHandle plCreatePlaneShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle,
|
||||
plReal planeNormalX,
|
||||
plReal planeNormalY,
|
||||
plReal planeNormalZ,
|
||||
plReal planeConstant)
|
||||
{
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
|
||||
return sdk->createPlaneShape(worldHandle,planeNormalX,planeNormalY,planeNormalZ,planeConstant);
|
||||
}
|
||||
|
||||
plCollisionShapeHandle plCreateCapsuleShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plReal radius, plReal height, int capsuleAxis)
|
||||
{
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
|
||||
return sdk->createCapsuleShape(worldHandle,radius,height,capsuleAxis);
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
|
||||
return sdk->createPlaneShape(worldHandle, planeNormalX, planeNormalY, planeNormalZ, planeConstant);
|
||||
}
|
||||
|
||||
plCollisionShapeHandle plCreateCompoundShape(plCollisionSdkHandle collisionSdkHandle,plCollisionWorldHandle worldHandle)
|
||||
plCollisionShapeHandle plCreateCapsuleShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plReal radius, plReal height, int capsuleAxis)
|
||||
{
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
|
||||
return sdk->createCapsuleShape(worldHandle, radius, height, capsuleAxis);
|
||||
}
|
||||
|
||||
plCollisionShapeHandle plCreateCompoundShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle)
|
||||
{
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
|
||||
return sdk->createCompoundShape(worldHandle);
|
||||
}
|
||||
void plAddChildShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShape,plCollisionShapeHandle childShape, plVector3 childPos,plQuaternion childOrn)
|
||||
void plAddChildShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape, plVector3 childPos, plQuaternion childOrn)
|
||||
{
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
|
||||
sdk->addChildShape(worldHandle,compoundShape,childShape,childPos,childOrn);
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
|
||||
sdk->addChildShape(worldHandle, compoundShape, childShape, childPos, childOrn);
|
||||
}
|
||||
|
||||
void plDeleteShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionShapeHandle shapeHandle)
|
||||
{
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
|
||||
sdk->deleteShape(worldHandle,shapeHandle);
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
|
||||
sdk->deleteShape(worldHandle, shapeHandle);
|
||||
}
|
||||
|
||||
plCollisionObjectHandle plCreateCollisionObject( plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, void* userData, int userIndex, plCollisionShapeHandle cshape ,plVector3 childPos,plQuaternion childOrn)
|
||||
plCollisionObjectHandle plCreateCollisionObject(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, void* userData, int userIndex, plCollisionShapeHandle cshape, plVector3 childPos, plQuaternion childOrn)
|
||||
{
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
|
||||
return sdk->createCollisionObject(worldHandle, userData, userIndex, cshape, childPos, childOrn);
|
||||
|
||||
}
|
||||
|
||||
void plDeleteCollisionObject(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle body)
|
||||
{
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
|
||||
sdk->deleteCollisionObject(body);
|
||||
}
|
||||
|
||||
void plSetCollisionObjectTransform( plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle objHandle, plVector3 position,plQuaternion orientation)
|
||||
void plSetCollisionObjectTransform(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle objHandle, plVector3 position, plQuaternion orientation)
|
||||
{
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
|
||||
sdk->setCollisionObjectTransform(worldHandle,objHandle,position,orientation);
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
|
||||
sdk->setCollisionObjectTransform(worldHandle, objHandle, position, orientation);
|
||||
}
|
||||
|
||||
void plAddCollisionObject(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle world, plCollisionObjectHandle object)
|
||||
{
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
|
||||
sdk->addCollisionObject(world,object);
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
|
||||
sdk->addCollisionObject(world, object);
|
||||
}
|
||||
void plRemoveCollisionObject(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle world, plCollisionObjectHandle object)
|
||||
{
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
|
||||
sdk->removeCollisionObject(world,object);
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
|
||||
sdk->removeCollisionObject(world, object);
|
||||
}
|
||||
|
||||
/* Collision Queries */
|
||||
int plCollide(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle colA, plCollisionObjectHandle colB,
|
||||
lwContactPoint* pointsOut, int pointCapacity)
|
||||
lwContactPoint* pointsOut, int pointCapacity)
|
||||
{
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
|
||||
return sdk->collide(worldHandle, colA,colB,pointsOut,pointCapacity);
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
|
||||
return sdk->collide(worldHandle, colA, colB, pointsOut, pointCapacity);
|
||||
}
|
||||
|
||||
void plWorldCollide(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle world,
|
||||
plNearCallback filter, void* userData)
|
||||
plNearCallback filter, void* userData)
|
||||
{
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle;
|
||||
sdk->collideWorld(world,filter,userData);
|
||||
CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle;
|
||||
sdk->collideWorld(world, filter, userData);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,111 +1,104 @@
|
|||
#ifndef LW_COLLISION_C_API_H
|
||||
#define LW_COLLISION_C_API_H
|
||||
|
||||
|
||||
#define PL_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
|
||||
|
||||
#define PL_DECLARE_HANDLE(name) \
|
||||
typedef struct name##__ \
|
||||
{ \
|
||||
int unused; \
|
||||
} * name
|
||||
|
||||
#ifdef BT_USE_DOUBLE_PRECISION
|
||||
typedef double plReal;
|
||||
typedef double plReal;
|
||||
#else
|
||||
typedef float plReal;
|
||||
typedef float plReal;
|
||||
#endif
|
||||
|
||||
typedef plReal plVector3[3];
|
||||
typedef plReal plQuaternion[4];
|
||||
typedef plReal plVector3[3];
|
||||
typedef plReal plQuaternion[4];
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/** Particular collision SDK (C-API) */
|
||||
PL_DECLARE_HANDLE(plCollisionSdkHandle);
|
||||
|
||||
|
||||
/** Collision world, belonging to some collision SDK (C-API)*/
|
||||
PL_DECLARE_HANDLE(plCollisionWorldHandle);
|
||||
|
||||
|
||||
/** Collision object that can be part of a collision World (C-API)*/
|
||||
PL_DECLARE_HANDLE(plCollisionObjectHandle);
|
||||
|
||||
|
||||
/** Collision Shape/Geometry, property of a collision object (C-API)*/
|
||||
PL_DECLARE_HANDLE(plCollisionShapeHandle);
|
||||
|
||||
/* Collision SDK */
|
||||
|
||||
|
||||
extern plCollisionSdkHandle plCreateBullet2CollisionSdk();
|
||||
|
||||
#ifndef DISABLE_REAL_TIME_BULLET3_COLLISION_SDK
|
||||
extern plCollisionSdkHandle plCreateRealTimeBullet3CollisionSdk();
|
||||
#endif //DISABLE_REAL_TIME_BULLET3_COLLISION_SDK
|
||||
#endif //DISABLE_REAL_TIME_BULLET3_COLLISION_SDK
|
||||
|
||||
// extern plCollisionSdkHandle plCreateCustomCollisionSdk();
|
||||
|
||||
// extern plCollisionSdkHandle plCreateCustomCollisionSdk();
|
||||
|
||||
extern void plDeleteCollisionSdk(plCollisionSdkHandle collisionSdkHandle);
|
||||
|
||||
//extern int plGetSdkWorldCreationIntParameter();
|
||||
//extern int plSetSdkWorldCreationIntParameter(int newValue);
|
||||
|
||||
/* Collision World */
|
||||
|
||||
extern plCollisionWorldHandle plCreateCollisionWorld(plCollisionSdkHandle collisionSdkHandle, int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity);
|
||||
extern void plDeleteCollisionWorld(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle world);
|
||||
|
||||
|
||||
extern void plAddCollisionObject(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle world, plCollisionObjectHandle object);
|
||||
extern void plRemoveCollisionObject(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle world, plCollisionObjectHandle object);
|
||||
|
||||
|
||||
|
||||
extern plCollisionWorldHandle plCreateCollisionWorld(plCollisionSdkHandle collisionSdkHandle, int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity);
|
||||
extern void plDeleteCollisionWorld(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle world);
|
||||
|
||||
extern void plAddCollisionObject(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle world, plCollisionObjectHandle object);
|
||||
extern void plRemoveCollisionObject(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle world, plCollisionObjectHandle object);
|
||||
|
||||
/* Collision Object */
|
||||
|
||||
extern plCollisionObjectHandle plCreateCollisionObject( plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle cshape , plVector3 startPosition,plQuaternion startOrientation);
|
||||
extern void plDeleteCollisionObject(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle body);
|
||||
extern void plSetCollisionObjectTransform( plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle objHandle, plVector3 startPosition,plQuaternion startOrientation);
|
||||
|
||||
|
||||
extern plCollisionObjectHandle plCreateCollisionObject(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle cshape, plVector3 startPosition, plQuaternion startOrientation);
|
||||
extern void plDeleteCollisionObject(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle body);
|
||||
extern void plSetCollisionObjectTransform(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle objHandle, plVector3 startPosition, plQuaternion startOrientation);
|
||||
|
||||
/* Collision Shape definition */
|
||||
|
||||
extern plCollisionShapeHandle plCreateSphereShape(plCollisionSdkHandle sdk, plCollisionWorldHandle worldHandle, plReal radius);
|
||||
extern plCollisionShapeHandle plCreateCapsuleShape(plCollisionSdkHandle sdk, plCollisionWorldHandle worldHandle, plReal radius, plReal height, int capsuleAxis);
|
||||
extern plCollisionShapeHandle plCreatePlaneShape(plCollisionSdkHandle sdk, plCollisionWorldHandle worldHandle,
|
||||
plReal planeNormalX,
|
||||
plReal planeNormalY,
|
||||
plReal planeNormalZ,
|
||||
plReal planeConstant);
|
||||
extern plCollisionShapeHandle plCreateCompoundShape(plCollisionSdkHandle sdk,plCollisionWorldHandle worldHandle);
|
||||
extern void plAddChildShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShape,plCollisionShapeHandle childShape, plVector3 childPos,plQuaternion childOrn);
|
||||
|
||||
extern void plDeleteShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionShapeHandle shape);
|
||||
|
||||
|
||||
|
||||
|
||||
extern plCollisionShapeHandle plCreateSphereShape(plCollisionSdkHandle sdk, plCollisionWorldHandle worldHandle, plReal radius);
|
||||
extern plCollisionShapeHandle plCreateCapsuleShape(plCollisionSdkHandle sdk, plCollisionWorldHandle worldHandle, plReal radius, plReal height, int capsuleAxis);
|
||||
extern plCollisionShapeHandle plCreatePlaneShape(plCollisionSdkHandle sdk, plCollisionWorldHandle worldHandle,
|
||||
plReal planeNormalX,
|
||||
plReal planeNormalY,
|
||||
plReal planeNormalZ,
|
||||
plReal planeConstant);
|
||||
extern plCollisionShapeHandle plCreateCompoundShape(plCollisionSdkHandle sdk, plCollisionWorldHandle worldHandle);
|
||||
extern void plAddChildShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape, plVector3 childPos, plQuaternion childOrn);
|
||||
|
||||
extern void plDeleteShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionShapeHandle shape);
|
||||
|
||||
/* Contact Results */
|
||||
|
||||
|
||||
struct lwContactPoint
|
||||
{
|
||||
plVector3 m_ptOnAWorld;
|
||||
plVector3 m_ptOnBWorld;
|
||||
plVector3 m_normalOnB;
|
||||
plReal m_distance;
|
||||
plReal m_distance;
|
||||
};
|
||||
|
||||
|
||||
/* Collision Filtering */
|
||||
typedef void(*plNearCallback)(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, void* userData,
|
||||
plCollisionObjectHandle objA, plCollisionObjectHandle objB);
|
||||
|
||||
|
||||
typedef void (*plNearCallback)(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, void* userData,
|
||||
plCollisionObjectHandle objA, plCollisionObjectHandle objB);
|
||||
|
||||
/* Collision Queries */
|
||||
extern int plCollide(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle colA, plCollisionObjectHandle colB,
|
||||
lwContactPoint* pointsOut, int pointCapacity);
|
||||
|
||||
|
||||
extern void plWorldCollide(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle world,
|
||||
plNearCallback filter, void* userData);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif //LW_COLLISION_C_API_H
|
||||
|
||||
#endif //LW_COLLISION_C_API_H
|
||||
|
|
|
|||
|
|
@ -27,125 +27,121 @@ const int sNumSpheres = 10;
|
|||
|
||||
lwContactPoint pointsOut[sPointCapacity];
|
||||
int numNearCallbacks = 0;
|
||||
static btVector4 sColors[4] =
|
||||
{
|
||||
btVector4(1,0.7,0.7,1),
|
||||
btVector4(1,1,0.7,1),
|
||||
btVector4(0.7,1,0.7,1),
|
||||
btVector4(0.7,1,1,1),
|
||||
static btVector4 sColors[4] =
|
||||
{
|
||||
btVector4(1, 0.7, 0.7, 1),
|
||||
btVector4(1, 1, 0.7, 1),
|
||||
btVector4(0.7, 1, 0.7, 1),
|
||||
btVector4(0.7, 1, 1, 1),
|
||||
};
|
||||
|
||||
void myNearCallback(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, void* userData, plCollisionObjectHandle objA, plCollisionObjectHandle objB)
|
||||
{
|
||||
numNearCallbacks++;
|
||||
int remainingCapacity = sPointCapacity-gTotalPoints;
|
||||
btAssert(remainingCapacity>0);
|
||||
int remainingCapacity = sPointCapacity - gTotalPoints;
|
||||
btAssert(remainingCapacity > 0);
|
||||
|
||||
if (remainingCapacity>0)
|
||||
if (remainingCapacity > 0)
|
||||
{
|
||||
lwContactPoint* pointPtr = &pointsOut[gTotalPoints];
|
||||
int numNewPoints = plCollide(sdkHandle, worldHandle, objA,objB,pointPtr,remainingCapacity);
|
||||
int numNewPoints = plCollide(sdkHandle, worldHandle, objA, objB, pointPtr, remainingCapacity);
|
||||
btAssert(numNewPoints <= remainingCapacity);
|
||||
gTotalPoints+=numNewPoints;
|
||||
gTotalPoints += numNewPoints;
|
||||
}
|
||||
}
|
||||
|
||||
class CollisionTutorialBullet2 : public CommonExampleInterface
|
||||
{
|
||||
CommonGraphicsApp* m_app;
|
||||
CommonGraphicsApp* m_app;
|
||||
GUIHelperInterface* m_guiHelper;
|
||||
int m_tutorialIndex;
|
||||
|
||||
TimeSeriesCanvas* m_timeSeriesCanvas0;
|
||||
|
||||
int m_tutorialIndex;
|
||||
|
||||
TimeSeriesCanvas* m_timeSeriesCanvas0;
|
||||
|
||||
plCollisionSdkHandle m_collisionSdkHandle;
|
||||
plCollisionWorldHandle m_collisionWorldHandle;
|
||||
|
||||
int m_stage;
|
||||
int m_counter;
|
||||
|
||||
|
||||
// int m_stage;
|
||||
// int m_counter;
|
||||
|
||||
public:
|
||||
|
||||
CollisionTutorialBullet2(GUIHelperInterface* guiHelper, int tutorialIndex)
|
||||
:m_app(guiHelper->getAppInterface()),
|
||||
m_guiHelper(guiHelper),
|
||||
m_tutorialIndex(tutorialIndex),
|
||||
m_collisionSdkHandle(0),
|
||||
m_collisionWorldHandle(0),
|
||||
m_stage(0),
|
||||
m_counter(0),
|
||||
m_timeSeriesCanvas0(0)
|
||||
{
|
||||
|
||||
CollisionTutorialBullet2(GUIHelperInterface* guiHelper, int tutorialIndex)
|
||||
: m_app(guiHelper->getAppInterface()),
|
||||
m_guiHelper(guiHelper),
|
||||
m_tutorialIndex(tutorialIndex),
|
||||
m_timeSeriesCanvas0(0),
|
||||
m_collisionSdkHandle(0),
|
||||
m_collisionWorldHandle(0)
|
||||
// m_stage(0),
|
||||
// m_counter(0)
|
||||
{
|
||||
gTotalPoints = 0;
|
||||
m_app->setUpAxis(1);
|
||||
m_app->m_renderer->enableBlend(true);
|
||||
|
||||
|
||||
switch (m_tutorialIndex)
|
||||
{
|
||||
case TUT_SPHERE_PLANE_RTB3:
|
||||
case TUT_SPHERE_PLANE_BULLET2:
|
||||
{
|
||||
|
||||
if (m_tutorialIndex==TUT_SPHERE_PLANE_BULLET2)
|
||||
if (m_tutorialIndex == TUT_SPHERE_PLANE_BULLET2)
|
||||
{
|
||||
m_collisionSdkHandle = plCreateBullet2CollisionSdk();
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef DISABLE_REAL_TIME_BULLET3_COLLISION_SDK
|
||||
m_collisionSdkHandle = plCreateRealTimeBullet3CollisionSdk();
|
||||
#endif //DISABLE_REAL_TIME_BULLET3_COLLISION_SDK
|
||||
#endif //DISABLE_REAL_TIME_BULLET3_COLLISION_SDK
|
||||
}
|
||||
if (m_collisionSdkHandle)
|
||||
{
|
||||
int maxNumObjsCapacity=1024;
|
||||
int maxNumShapesCapacity=1024;
|
||||
int maxNumPairsCapacity=16384;
|
||||
int maxNumObjsCapacity = 1024;
|
||||
int maxNumShapesCapacity = 1024;
|
||||
int maxNumPairsCapacity = 16384;
|
||||
btAlignedObjectArray<plCollisionObjectHandle> colliders;
|
||||
m_collisionWorldHandle = plCreateCollisionWorld(m_collisionSdkHandle,maxNumObjsCapacity,maxNumShapesCapacity,maxNumPairsCapacity);
|
||||
m_collisionWorldHandle = plCreateCollisionWorld(m_collisionSdkHandle, maxNumObjsCapacity, maxNumShapesCapacity, maxNumPairsCapacity);
|
||||
//create objects, do query etc
|
||||
{
|
||||
float radius = 1.f;
|
||||
|
||||
void* userPointer = 0;
|
||||
{
|
||||
for (int j=0;j<sNumCompounds;j++)
|
||||
for (int j = 0; j < sNumCompounds; j++)
|
||||
{
|
||||
plCollisionShapeHandle compoundShape = plCreateCompoundShape(m_collisionSdkHandle,m_collisionWorldHandle);
|
||||
plCollisionShapeHandle compoundShape = plCreateCompoundShape(m_collisionSdkHandle, m_collisionWorldHandle);
|
||||
|
||||
for (int i=0;i<sNumSpheres;i++)
|
||||
for (int i = 0; i < sNumSpheres; i++)
|
||||
{
|
||||
btVector3 childPos(i*1.5,0,0);
|
||||
btQuaternion childOrn(0,0,0,1);
|
||||
|
||||
btVector3 scaling(radius,radius,radius);
|
||||
|
||||
plCollisionShapeHandle childShape = plCreateSphereShape(m_collisionSdkHandle, m_collisionWorldHandle,radius);
|
||||
plAddChildShape(m_collisionSdkHandle,m_collisionWorldHandle,compoundShape, childShape,childPos,childOrn);
|
||||
|
||||
|
||||
btVector3 childPos(i * 1.5, 0, 0);
|
||||
btQuaternion childOrn(0, 0, 0, 1);
|
||||
|
||||
btVector3 scaling(radius, radius, radius);
|
||||
|
||||
plCollisionShapeHandle childShape = plCreateSphereShape(m_collisionSdkHandle, m_collisionWorldHandle, radius);
|
||||
plAddChildShape(m_collisionSdkHandle, m_collisionWorldHandle, compoundShape, childShape, childPos, childOrn);
|
||||
|
||||
//m_guiHelper->createCollisionObjectGraphicsObject(colObj,color);
|
||||
|
||||
}
|
||||
if (m_tutorialIndex==TUT_SPHERE_PLANE_BULLET2)
|
||||
if (m_tutorialIndex == TUT_SPHERE_PLANE_BULLET2)
|
||||
{
|
||||
btCollisionShape* colShape = (btCollisionShape*) compoundShape;
|
||||
btCollisionShape* colShape = (btCollisionShape*)compoundShape;
|
||||
m_guiHelper->createCollisionShapeGraphicsObject(colShape);
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
btVector3 pos(j*sNumSpheres*1.5,-2.4,0);
|
||||
btQuaternion orn(0,0,0,1);
|
||||
plCollisionObjectHandle colObjHandle = plCreateCollisionObject(m_collisionSdkHandle,m_collisionWorldHandle,userPointer, -1,compoundShape,pos,orn);
|
||||
if (m_tutorialIndex==TUT_SPHERE_PLANE_BULLET2)
|
||||
btVector3 pos(j * sNumSpheres * 1.5, -2.4, 0);
|
||||
btQuaternion orn(0, 0, 0, 1);
|
||||
plCollisionObjectHandle colObjHandle = plCreateCollisionObject(m_collisionSdkHandle, m_collisionWorldHandle, userPointer, -1, compoundShape, pos, orn);
|
||||
if (m_tutorialIndex == TUT_SPHERE_PLANE_BULLET2)
|
||||
{
|
||||
btCollisionObject* colObj = (btCollisionObject*) colObjHandle;
|
||||
btVector4 color=sColors[j&3];
|
||||
m_guiHelper->createCollisionObjectGraphicsObject(colObj,color);
|
||||
btCollisionObject* colObj = (btCollisionObject*)colObjHandle;
|
||||
btVector4 color = sColors[j & 3];
|
||||
m_guiHelper->createCollisionObjectGraphicsObject(colObj, color);
|
||||
colliders.push_back(colObjHandle);
|
||||
plAddCollisionObject(m_collisionSdkHandle, m_collisionWorldHandle,colObjHandle);
|
||||
plAddCollisionObject(m_collisionSdkHandle, m_collisionWorldHandle, colObjHandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -153,27 +149,26 @@ public:
|
|||
}
|
||||
|
||||
{
|
||||
plCollisionShapeHandle colShape = plCreatePlaneShape(m_collisionSdkHandle, m_collisionWorldHandle,0,1,0,-3.5);
|
||||
btVector3 pos(0,0,0);
|
||||
btQuaternion orn(0,0,0,1);
|
||||
plCollisionShapeHandle colShape = plCreatePlaneShape(m_collisionSdkHandle, m_collisionWorldHandle, 0, 1, 0, -3.5);
|
||||
btVector3 pos(0, 0, 0);
|
||||
btQuaternion orn(0, 0, 0, 1);
|
||||
void* userPointer = 0;
|
||||
plCollisionObjectHandle colObj = plCreateCollisionObject(m_collisionSdkHandle,m_collisionWorldHandle,userPointer, 0,colShape,pos,orn);
|
||||
plCollisionObjectHandle colObj = plCreateCollisionObject(m_collisionSdkHandle, m_collisionWorldHandle, userPointer, 0, colShape, pos, orn);
|
||||
colliders.push_back(colObj);
|
||||
plAddCollisionObject(m_collisionSdkHandle, m_collisionWorldHandle,colObj);
|
||||
plAddCollisionObject(m_collisionSdkHandle, m_collisionWorldHandle, colObj);
|
||||
}
|
||||
|
||||
int numContacts = plCollide(m_collisionSdkHandle,m_collisionWorldHandle,colliders[0],colliders[1],pointsOut,sPointCapacity);
|
||||
printf("numContacts = %d\n", numContacts);
|
||||
void* myUserPtr = 0;
|
||||
|
||||
plWorldCollide(m_collisionSdkHandle,m_collisionWorldHandle,myNearCallback, myUserPtr);
|
||||
printf("total points=%d\n",gTotalPoints);
|
||||
|
||||
//plRemoveCollisionObject(m_collisionSdkHandle,m_collisionWorldHandle,colObj);
|
||||
int numContacts = plCollide(m_collisionSdkHandle, m_collisionWorldHandle, colliders[0], colliders[1], pointsOut, sPointCapacity);
|
||||
printf("numContacts = %d\n", numContacts);
|
||||
void* myUserPtr = 0;
|
||||
|
||||
plWorldCollide(m_collisionSdkHandle, m_collisionWorldHandle, myNearCallback, myUserPtr);
|
||||
printf("total points=%d\n", gTotalPoints);
|
||||
|
||||
//plRemoveCollisionObject(m_collisionSdkHandle,m_collisionWorldHandle,colObj);
|
||||
//plDeleteCollisionObject(m_collisionSdkHandle,colObj);
|
||||
//plDeleteShape(m_collisionSdkHandle,colShape);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
m_timeSeriesCanvas0 = new TimeSeriesCanvas(m_app->m_2dCanvasInterface,512,256,"Constant Velocity");
|
||||
|
|
@ -185,101 +180,86 @@ public:
|
|||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
default:
|
||||
{
|
||||
|
||||
m_timeSeriesCanvas0 = new TimeSeriesCanvas(m_app->m_2dCanvasInterface,512,256,"Unknown");
|
||||
m_timeSeriesCanvas0 ->setupTimeSeries(1,60, 0);
|
||||
|
||||
m_timeSeriesCanvas0 = new TimeSeriesCanvas(m_app->m_2dCanvasInterface, 512, 256, "Unknown");
|
||||
m_timeSeriesCanvas0->setupTimeSeries(1, 60, 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
{
|
||||
|
||||
int boxId = m_app->registerCubeShape(100,0.01,100);
|
||||
b3Vector3 pos = b3MakeVector3(0,-3.5,0);
|
||||
b3Quaternion orn(0,0,0,1);
|
||||
b3Vector4 color = b3MakeVector4(1,1,1,1);
|
||||
b3Vector3 scaling = b3MakeVector3(1,1,1);
|
||||
m_app->m_renderer->registerGraphicsInstance(boxId,pos,orn,color,scaling);
|
||||
int boxId = m_app->registerCubeShape(100, 0.01, 100);
|
||||
b3Vector3 pos = b3MakeVector3(0, -3.5, 0);
|
||||
b3Quaternion orn(0, 0, 0, 1);
|
||||
b3Vector4 color = b3MakeVector4(1, 1, 1, 1);
|
||||
b3Vector3 scaling = b3MakeVector3(1, 1, 1);
|
||||
m_app->m_renderer->registerGraphicsInstance(boxId, pos, orn, color, scaling);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
int textureIndex = -1;
|
||||
|
||||
|
||||
if (1)
|
||||
{
|
||||
int width,height,n;
|
||||
|
||||
int width, height, n;
|
||||
|
||||
const char* filename = "data/cube.png";
|
||||
const unsigned char* image=0;
|
||||
|
||||
const char* prefix[]={"./","../","../../","../../../","../../../../"};
|
||||
int numprefix = sizeof(prefix)/sizeof(const char*);
|
||||
|
||||
for (int i=0;!image && i<numprefix;i++)
|
||||
const unsigned char* image = 0;
|
||||
|
||||
const char* prefix[] = {"./", "../", "../../", "../../../", "../../../../"};
|
||||
int numprefix = sizeof(prefix) / sizeof(const char*);
|
||||
|
||||
for (int i = 0; !image && i < numprefix; i++)
|
||||
{
|
||||
char relativeFileName[1024];
|
||||
sprintf(relativeFileName,"%s%s",prefix[i],filename);
|
||||
sprintf(relativeFileName, "%s%s", prefix[i], filename);
|
||||
image = stbi_load(relativeFileName, &width, &height, &n, 3);
|
||||
}
|
||||
|
||||
|
||||
b3Assert(image);
|
||||
if (image)
|
||||
{
|
||||
textureIndex = m_app->m_renderer->registerTexture(image,width,height);
|
||||
textureIndex = m_app->m_renderer->registerTexture(image, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
m_app->m_renderer->writeTransforms();
|
||||
}
|
||||
virtual ~CollisionTutorialBullet2()
|
||||
{
|
||||
}
|
||||
virtual ~CollisionTutorialBullet2()
|
||||
{
|
||||
delete m_timeSeriesCanvas0;
|
||||
|
||||
plDeleteCollisionWorld(m_collisionSdkHandle,m_collisionWorldHandle);
|
||||
plDeleteCollisionWorld(m_collisionSdkHandle, m_collisionWorldHandle);
|
||||
|
||||
plDeleteCollisionSdk(m_collisionSdkHandle);
|
||||
|
||||
m_timeSeriesCanvas0 = 0;
|
||||
}
|
||||
|
||||
m_app->m_renderer->enableBlend(false);
|
||||
}
|
||||
|
||||
|
||||
virtual void initPhysics()
|
||||
{
|
||||
}
|
||||
virtual void exitPhysics()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
virtual void stepSimulation(float deltaTime)
|
||||
{
|
||||
virtual void initPhysics()
|
||||
{
|
||||
}
|
||||
virtual void exitPhysics()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void stepSimulation(float deltaTime)
|
||||
{
|
||||
#ifndef BT_NO_PROFILE
|
||||
CProfileManager::Reset();
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
void* myUserPtr = 0;
|
||||
|
||||
|
||||
gTotalPoints = 0;
|
||||
numNearCallbacks = 0;
|
||||
{
|
||||
BT_PROFILE("plWorldCollide");
|
||||
if (m_collisionSdkHandle && m_collisionWorldHandle)
|
||||
{
|
||||
plWorldCollide(m_collisionSdkHandle,m_collisionWorldHandle,myNearCallback, myUserPtr);
|
||||
plWorldCollide(m_collisionSdkHandle, m_collisionWorldHandle, myNearCallback, myUserPtr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -305,87 +285,76 @@ public:
|
|||
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
if (m_timeSeriesCanvas0)
|
||||
m_timeSeriesCanvas0->nextTick();
|
||||
|
||||
|
||||
|
||||
|
||||
// m_app->m_renderer->writeSingleInstanceTransformToCPU(m_bodies[i]->m_worldPose.m_position, m_bodies[i]->m_worldPose.m_orientation, m_bodies[i]->m_graphicsIndex);
|
||||
|
||||
|
||||
m_app->m_renderer->writeTransforms();
|
||||
|
||||
m_app->m_renderer->writeTransforms();
|
||||
#ifndef BT_NO_PROFILE
|
||||
CProfileManager::Increment_Frame_Counter();
|
||||
CProfileManager::Increment_Frame_Counter();
|
||||
#endif
|
||||
}
|
||||
virtual void renderScene()
|
||||
{
|
||||
}
|
||||
virtual void renderScene()
|
||||
{
|
||||
if (m_app && m_app->m_renderer)
|
||||
{
|
||||
m_app->m_renderer->renderScene();
|
||||
|
||||
m_app->m_renderer->clearZBuffer();
|
||||
|
||||
m_app->drawText3D("X",1,0,0,1);
|
||||
m_app->drawText3D("Y",0,1,0,1);
|
||||
m_app->drawText3D("Z",0,0,1,1);
|
||||
m_app->drawText3D("X", 1, 0, 0, 1);
|
||||
m_app->drawText3D("Y", 0, 1, 0, 1);
|
||||
m_app->drawText3D("Z", 0, 0, 1, 1);
|
||||
|
||||
|
||||
for (int i=0;i<gTotalPoints;i++)
|
||||
for (int i = 0; i < gTotalPoints; i++)
|
||||
{
|
||||
const lwContactPoint& contact = pointsOut[i];
|
||||
btVector3 color(1,1,0);
|
||||
btScalar lineWidth=3;
|
||||
if (contact.m_distance<0)
|
||||
btVector3 color(1, 1, 0);
|
||||
btScalar lineWidth = 3;
|
||||
if (contact.m_distance < 0)
|
||||
{
|
||||
color.setValue(1,0,0);
|
||||
color.setValue(1, 0, 0);
|
||||
}
|
||||
m_app->m_renderer->drawLine(contact.m_ptOnAWorld,contact.m_ptOnBWorld,color,lineWidth);
|
||||
m_app->m_renderer->drawLine(contact.m_ptOnAWorld, contact.m_ptOnBWorld, color, lineWidth);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
virtual void physicsDebugDraw(int debugDrawFlags)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
virtual bool mouseMoveCallback(float x,float y)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool mouseButtonCallback(int button, int state, float x, float y)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool keyboardCallback(int key, int state)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void physicsDebugDraw(int debugDrawFlags)
|
||||
{
|
||||
}
|
||||
virtual bool mouseMoveCallback(float x, float y)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool mouseButtonCallback(int button, int state, float x, float y)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool keyboardCallback(int key, int state)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void resetCamera()
|
||||
{
|
||||
float dist = 10.5;
|
||||
float pitch = 136;
|
||||
float yaw = 32;
|
||||
float targetPos[3]={0,0,0};
|
||||
if (m_app->m_renderer && m_app->m_renderer->getActiveCamera())
|
||||
float pitch = -32;
|
||||
float yaw = 136;
|
||||
float targetPos[3] = {0, 0, 0};
|
||||
if (m_app->m_renderer && m_app->m_renderer->getActiveCamera())
|
||||
{
|
||||
m_app->m_renderer->getActiveCamera()->setCameraDistance(dist);
|
||||
m_app->m_renderer->getActiveCamera()->setCameraPitch(pitch);
|
||||
m_app->m_renderer->getActiveCamera()->setCameraYaw(yaw);
|
||||
m_app->m_renderer->getActiveCamera()->setCameraTargetPosition(targetPos[0],targetPos[1],targetPos[2]);
|
||||
m_app->m_renderer->getActiveCamera()->setCameraTargetPosition(targetPos[0], targetPos[1], targetPos[2]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class CommonExampleInterface* CollisionTutorialBullet2CreateFunc(struct CommonExampleOptions& options)
|
||||
class CommonExampleInterface* CollisionTutorialBullet2CreateFunc(struct CommonExampleOptions& options)
|
||||
{
|
||||
return new CollisionTutorialBullet2(options.m_guiHelper, options.m_option);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
#ifndef COLLISION_TUTORIAL_H
|
||||
#define COLLISION_TUTORIAL_H
|
||||
#define COLLISION_TUTORIAL_H
|
||||
|
||||
enum EnumCollisionTutorialTypes
|
||||
{
|
||||
TUT_SPHERE_PLANE_BULLET2=0,
|
||||
TUT_SPHERE_PLANE_RTB3,
|
||||
TUT_SPHERE_PLANE_BULLET2 = 0,
|
||||
TUT_SPHERE_PLANE_RTB3,
|
||||
};
|
||||
|
||||
class CommonExampleInterface* CollisionTutorialBullet2CreateFunc(struct CommonExampleOptions& options);
|
||||
class CommonExampleInterface* CollisionTutorialBullet2CreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
#endif //COLLISION_TUTORIAL_H
|
||||
#endif //COLLISION_TUTORIAL_H
|
||||
|
|
|
|||
|
|
@ -6,103 +6,102 @@ struct Bullet2CollisionSdkInternalData
|
|||
btCollisionConfiguration* m_collisionConfig;
|
||||
btCollisionDispatcher* m_dispatcher;
|
||||
btBroadphaseInterface* m_aabbBroadphase;
|
||||
|
||||
btCollisionWorld* m_collisionWorld;
|
||||
|
||||
|
||||
Bullet2CollisionSdkInternalData()
|
||||
:m_aabbBroadphase(0),
|
||||
m_dispatcher(0),
|
||||
m_collisionWorld(0)
|
||||
: m_collisionConfig(0),
|
||||
m_dispatcher(0),
|
||||
m_aabbBroadphase(0),
|
||||
m_collisionWorld(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Bullet2CollisionSdk::Bullet2CollisionSdk()
|
||||
{
|
||||
m_internalData = new Bullet2CollisionSdkInternalData;
|
||||
}
|
||||
|
||||
|
||||
Bullet2CollisionSdk::~Bullet2CollisionSdk()
|
||||
{
|
||||
delete m_internalData;
|
||||
m_internalData = 0;
|
||||
}
|
||||
|
||||
|
||||
plCollisionWorldHandle Bullet2CollisionSdk::createCollisionWorld(int /*maxNumObjsCapacity*/, int /*maxNumShapesCapacity*/, int /*maxNumPairsCapacity*/)
|
||||
{
|
||||
m_internalData->m_collisionConfig = new btDefaultCollisionConfiguration;
|
||||
|
||||
|
||||
m_internalData->m_dispatcher = new btCollisionDispatcher(m_internalData->m_collisionConfig);
|
||||
m_internalData->m_aabbBroadphase = new btDbvtBroadphase();
|
||||
m_internalData->m_collisionWorld = new btCollisionWorld(m_internalData->m_dispatcher,
|
||||
m_internalData->m_aabbBroadphase,
|
||||
m_internalData->m_collisionConfig);
|
||||
return (plCollisionWorldHandle) m_internalData->m_collisionWorld;
|
||||
return (plCollisionWorldHandle)m_internalData->m_collisionWorld;
|
||||
}
|
||||
|
||||
|
||||
void Bullet2CollisionSdk::deleteCollisionWorld(plCollisionWorldHandle worldHandle)
|
||||
{
|
||||
btCollisionWorld* world = (btCollisionWorld*) worldHandle;
|
||||
btCollisionWorld* world = (btCollisionWorld*)worldHandle;
|
||||
btAssert(m_internalData->m_collisionWorld == world);
|
||||
|
||||
|
||||
if (m_internalData->m_collisionWorld == world)
|
||||
{
|
||||
delete m_internalData->m_collisionWorld;
|
||||
m_internalData->m_collisionWorld=0;
|
||||
m_internalData->m_collisionWorld = 0;
|
||||
delete m_internalData->m_aabbBroadphase;
|
||||
m_internalData->m_aabbBroadphase=0;
|
||||
m_internalData->m_aabbBroadphase = 0;
|
||||
delete m_internalData->m_dispatcher;
|
||||
m_internalData->m_dispatcher=0;
|
||||
m_internalData->m_dispatcher = 0;
|
||||
delete m_internalData->m_collisionConfig;
|
||||
m_internalData->m_collisionConfig=0;
|
||||
}
|
||||
m_internalData->m_collisionConfig = 0;
|
||||
}
|
||||
}
|
||||
|
||||
plCollisionShapeHandle Bullet2CollisionSdk::createSphereShape(plCollisionWorldHandle /*worldHandle*/, plReal radius)
|
||||
{
|
||||
btSphereShape* sphereShape = new btSphereShape(radius);
|
||||
return (plCollisionShapeHandle) sphereShape;
|
||||
return (plCollisionShapeHandle)sphereShape;
|
||||
}
|
||||
|
||||
plCollisionShapeHandle Bullet2CollisionSdk::createPlaneShape(plCollisionWorldHandle worldHandle,
|
||||
plReal planeNormalX,
|
||||
plReal planeNormalY,
|
||||
plReal planeNormalZ,
|
||||
plReal planeConstant)
|
||||
plCollisionShapeHandle Bullet2CollisionSdk::createPlaneShape(plCollisionWorldHandle worldHandle,
|
||||
plReal planeNormalX,
|
||||
plReal planeNormalY,
|
||||
plReal planeNormalZ,
|
||||
plReal planeConstant)
|
||||
{
|
||||
btStaticPlaneShape* planeShape = new btStaticPlaneShape(btVector3(planeNormalX,planeNormalY,planeNormalZ),planeConstant);
|
||||
return (plCollisionShapeHandle) planeShape;
|
||||
btStaticPlaneShape* planeShape = new btStaticPlaneShape(btVector3(planeNormalX, planeNormalY, planeNormalZ), planeConstant);
|
||||
return (plCollisionShapeHandle)planeShape;
|
||||
}
|
||||
|
||||
plCollisionShapeHandle Bullet2CollisionSdk::createCapsuleShape(plCollisionWorldHandle worldHandle,
|
||||
plReal radius,
|
||||
plReal height,
|
||||
int capsuleAxis)
|
||||
plCollisionShapeHandle Bullet2CollisionSdk::createCapsuleShape(plCollisionWorldHandle worldHandle,
|
||||
plReal radius,
|
||||
plReal height,
|
||||
int capsuleAxis)
|
||||
{
|
||||
btCapsuleShape* capsule = 0;
|
||||
|
||||
switch (capsuleAxis)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
capsule = new btCapsuleShapeX(radius,height);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
capsule = new btCapsuleShape(radius,height);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
capsule = new btCapsuleShapeZ(radius,height);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
btAssert(0);
|
||||
}
|
||||
case 0:
|
||||
{
|
||||
capsule = new btCapsuleShapeX(radius, height);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
capsule = new btCapsuleShape(radius, height);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
capsule = new btCapsuleShapeZ(radius, height);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
btAssert(0);
|
||||
}
|
||||
}
|
||||
return (plCollisionShapeHandle)capsule;
|
||||
}
|
||||
|
|
@ -111,28 +110,27 @@ plCollisionShapeHandle Bullet2CollisionSdk::createCompoundShape(plCollisionWorld
|
|||
{
|
||||
return (plCollisionShapeHandle) new btCompoundShape();
|
||||
}
|
||||
void Bullet2CollisionSdk::addChildShape(plCollisionWorldHandle worldHandle,plCollisionShapeHandle compoundShapeHandle, plCollisionShapeHandle childShapeHandle,plVector3 childPos,plQuaternion childOrn)
|
||||
void Bullet2CollisionSdk::addChildShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShapeHandle, plCollisionShapeHandle childShapeHandle, plVector3 childPos, plQuaternion childOrn)
|
||||
{
|
||||
btCompoundShape* compound = (btCompoundShape*) compoundShapeHandle;
|
||||
btCollisionShape* childShape = (btCollisionShape*) childShapeHandle;
|
||||
btCompoundShape* compound = (btCompoundShape*)compoundShapeHandle;
|
||||
btCollisionShape* childShape = (btCollisionShape*)childShapeHandle;
|
||||
btTransform localTrans;
|
||||
localTrans.setOrigin(btVector3(childPos[0],childPos[1],childPos[2]));
|
||||
localTrans.setRotation(btQuaternion(childOrn[0],childOrn[1],childOrn[2],childOrn[3]));
|
||||
compound->addChildShape(localTrans,childShape);
|
||||
|
||||
localTrans.setOrigin(btVector3(childPos[0], childPos[1], childPos[2]));
|
||||
localTrans.setRotation(btQuaternion(childOrn[0], childOrn[1], childOrn[2], childOrn[3]));
|
||||
compound->addChildShape(localTrans, childShape);
|
||||
}
|
||||
|
||||
void Bullet2CollisionSdk::deleteShape(plCollisionWorldHandle /*worldHandle*/, plCollisionShapeHandle shapeHandle)
|
||||
{
|
||||
btCollisionShape* shape = (btCollisionShape*) shapeHandle;
|
||||
btCollisionShape* shape = (btCollisionShape*)shapeHandle;
|
||||
delete shape;
|
||||
}
|
||||
|
||||
void Bullet2CollisionSdk::addCollisionObject(plCollisionWorldHandle worldHandle, plCollisionObjectHandle objectHandle)
|
||||
{
|
||||
btCollisionWorld* world = (btCollisionWorld*) worldHandle;
|
||||
btCollisionObject* colObj = (btCollisionObject*) objectHandle;
|
||||
btAssert(world && colObj);
|
||||
btCollisionWorld* world = (btCollisionWorld*)worldHandle;
|
||||
btCollisionObject* colObj = (btCollisionObject*)objectHandle;
|
||||
btAssert(world && colObj);
|
||||
if (world == m_internalData->m_collisionWorld && colObj)
|
||||
{
|
||||
world->addCollisionObject(colObj);
|
||||
|
|
@ -140,101 +138,98 @@ void Bullet2CollisionSdk::addCollisionObject(plCollisionWorldHandle worldHandle,
|
|||
}
|
||||
void Bullet2CollisionSdk::removeCollisionObject(plCollisionWorldHandle worldHandle, plCollisionObjectHandle objectHandle)
|
||||
{
|
||||
btCollisionWorld* world = (btCollisionWorld*) worldHandle;
|
||||
btCollisionObject* colObj = (btCollisionObject*) objectHandle;
|
||||
btAssert(world && colObj);
|
||||
btCollisionWorld* world = (btCollisionWorld*)worldHandle;
|
||||
btCollisionObject* colObj = (btCollisionObject*)objectHandle;
|
||||
btAssert(world && colObj);
|
||||
if (world == m_internalData->m_collisionWorld && colObj)
|
||||
{
|
||||
world->removeCollisionObject(colObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
plCollisionObjectHandle Bullet2CollisionSdk::createCollisionObject( plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle shapeHandle ,
|
||||
plVector3 startPosition,plQuaternion startOrientation )
|
||||
plCollisionObjectHandle Bullet2CollisionSdk::createCollisionObject(plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle shapeHandle,
|
||||
plVector3 startPosition, plQuaternion startOrientation)
|
||||
|
||||
{
|
||||
btCollisionShape* colShape = (btCollisionShape*) shapeHandle;
|
||||
btCollisionShape* colShape = (btCollisionShape*)shapeHandle;
|
||||
btAssert(colShape);
|
||||
if (colShape)
|
||||
{
|
||||
btCollisionObject* colObj= new btCollisionObject;
|
||||
btCollisionObject* colObj = new btCollisionObject;
|
||||
colObj->setUserIndex(userIndex);
|
||||
colObj->setUserPointer(userPointer);
|
||||
colObj->setCollisionShape(colShape);
|
||||
btTransform tr;
|
||||
tr.setOrigin(btVector3(startPosition[0],startPosition[1],startPosition[2]));
|
||||
tr.setRotation(btQuaternion(startOrientation[0],startOrientation[1],startOrientation[2],startOrientation[3]));
|
||||
btTransform tr;
|
||||
tr.setOrigin(btVector3(startPosition[0], startPosition[1], startPosition[2]));
|
||||
tr.setRotation(btQuaternion(startOrientation[0], startOrientation[1], startOrientation[2], startOrientation[3]));
|
||||
colObj->setWorldTransform(tr);
|
||||
return (plCollisionObjectHandle) colObj;
|
||||
return (plCollisionObjectHandle)colObj;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Bullet2CollisionSdk::deleteCollisionObject(plCollisionObjectHandle bodyHandle)
|
||||
{
|
||||
btCollisionObject* colObj = (btCollisionObject*) bodyHandle;
|
||||
btCollisionObject* colObj = (btCollisionObject*)bodyHandle;
|
||||
delete colObj;
|
||||
}
|
||||
void Bullet2CollisionSdk::setCollisionObjectTransform(plCollisionWorldHandle /*worldHandle*/, plCollisionObjectHandle bodyHandle,
|
||||
plVector3 position,plQuaternion orientation )
|
||||
plVector3 position, plQuaternion orientation)
|
||||
{
|
||||
btCollisionObject* colObj = (btCollisionObject*) bodyHandle;
|
||||
btTransform tr;
|
||||
tr.setOrigin(btVector3(position[0],position[1],position[2]));
|
||||
tr.setRotation(btQuaternion(orientation[0],orientation[1],orientation[2],orientation[3]));
|
||||
btCollisionObject* colObj = (btCollisionObject*)bodyHandle;
|
||||
btTransform tr;
|
||||
tr.setOrigin(btVector3(position[0], position[1], position[2]));
|
||||
tr.setRotation(btQuaternion(orientation[0], orientation[1], orientation[2], orientation[3]));
|
||||
colObj->setWorldTransform(tr);
|
||||
}
|
||||
|
||||
|
||||
struct Bullet2ContactResultCallback : public btCollisionWorld::ContactResultCallback
|
||||
struct Bullet2ContactResultCallback : public btCollisionWorld::ContactResultCallback
|
||||
{
|
||||
int m_numContacts;
|
||||
lwContactPoint* m_pointsOut;
|
||||
int m_pointCapacity;
|
||||
|
||||
Bullet2ContactResultCallback(lwContactPoint* pointsOut, int pointCapacity) :
|
||||
m_numContacts(0),
|
||||
m_pointsOut(pointsOut),
|
||||
m_pointCapacity(pointCapacity)
|
||||
{
|
||||
}
|
||||
virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1)
|
||||
{
|
||||
if (m_numContacts<m_pointCapacity)
|
||||
{
|
||||
lwContactPoint& ptOut = m_pointsOut[m_numContacts];
|
||||
ptOut.m_distance = cp.m_distance1;
|
||||
ptOut.m_normalOnB[0] = cp.m_normalWorldOnB.getX();
|
||||
ptOut.m_normalOnB[1] = cp.m_normalWorldOnB.getY();
|
||||
ptOut.m_normalOnB[2] = cp.m_normalWorldOnB.getZ();
|
||||
ptOut.m_ptOnAWorld[0] = cp.m_positionWorldOnA[0];
|
||||
ptOut.m_ptOnAWorld[1] = cp.m_positionWorldOnA[1];
|
||||
ptOut.m_ptOnAWorld[2] = cp.m_positionWorldOnA[2];
|
||||
ptOut.m_ptOnBWorld[0] = cp.m_positionWorldOnB[0];
|
||||
ptOut.m_ptOnBWorld[1] = cp.m_positionWorldOnB[1];
|
||||
ptOut.m_ptOnBWorld[2] = cp.m_positionWorldOnB[2];
|
||||
m_numContacts++;
|
||||
}
|
||||
|
||||
return 1.f;
|
||||
}
|
||||
int m_numContacts;
|
||||
lwContactPoint* m_pointsOut;
|
||||
int m_pointCapacity;
|
||||
|
||||
Bullet2ContactResultCallback(lwContactPoint* pointsOut, int pointCapacity) : m_numContacts(0),
|
||||
m_pointsOut(pointsOut),
|
||||
m_pointCapacity(pointCapacity)
|
||||
{
|
||||
}
|
||||
virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper* colObj1Wrap, int partId1, int index1)
|
||||
{
|
||||
if (m_numContacts < m_pointCapacity)
|
||||
{
|
||||
lwContactPoint& ptOut = m_pointsOut[m_numContacts];
|
||||
ptOut.m_distance = cp.m_distance1;
|
||||
ptOut.m_normalOnB[0] = cp.m_normalWorldOnB.getX();
|
||||
ptOut.m_normalOnB[1] = cp.m_normalWorldOnB.getY();
|
||||
ptOut.m_normalOnB[2] = cp.m_normalWorldOnB.getZ();
|
||||
ptOut.m_ptOnAWorld[0] = cp.m_positionWorldOnA[0];
|
||||
ptOut.m_ptOnAWorld[1] = cp.m_positionWorldOnA[1];
|
||||
ptOut.m_ptOnAWorld[2] = cp.m_positionWorldOnA[2];
|
||||
ptOut.m_ptOnBWorld[0] = cp.m_positionWorldOnB[0];
|
||||
ptOut.m_ptOnBWorld[1] = cp.m_positionWorldOnB[1];
|
||||
ptOut.m_ptOnBWorld[2] = cp.m_positionWorldOnB[2];
|
||||
m_numContacts++;
|
||||
}
|
||||
|
||||
return 1.f;
|
||||
}
|
||||
};
|
||||
|
||||
int Bullet2CollisionSdk::collide(plCollisionWorldHandle worldHandle,plCollisionObjectHandle colA, plCollisionObjectHandle colB,
|
||||
lwContactPoint* pointsOut, int pointCapacity)
|
||||
int Bullet2CollisionSdk::collide(plCollisionWorldHandle worldHandle, plCollisionObjectHandle colA, plCollisionObjectHandle colB,
|
||||
lwContactPoint* pointsOut, int pointCapacity)
|
||||
{
|
||||
|
||||
btCollisionWorld* world = (btCollisionWorld*) worldHandle;
|
||||
btCollisionObject* colObjA = (btCollisionObject*) colA;
|
||||
btCollisionObject* colObjB = (btCollisionObject*) colB;
|
||||
btAssert(world && colObjA && colObjB);
|
||||
if (world == m_internalData->m_collisionWorld && colObjA && colObjB)
|
||||
{
|
||||
Bullet2ContactResultCallback cb(pointsOut,pointCapacity);
|
||||
world->contactPairTest(colObjA,colObjB,cb);
|
||||
return cb.m_numContacts;
|
||||
}
|
||||
return 0;
|
||||
btCollisionWorld* world = (btCollisionWorld*)worldHandle;
|
||||
btCollisionObject* colObjA = (btCollisionObject*)colA;
|
||||
btCollisionObject* colObjB = (btCollisionObject*)colB;
|
||||
btAssert(world && colObjA && colObjB);
|
||||
if (world == m_internalData->m_collisionWorld && colObjA && colObjB)
|
||||
{
|
||||
Bullet2ContactResultCallback cb(pointsOut, pointCapacity);
|
||||
world->contactPairTest(colObjA, colObjB, cb);
|
||||
return cb.m_numContacts;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static plNearCallback gTmpFilter;
|
||||
|
|
@ -246,30 +241,30 @@ static void* gUserData = 0;
|
|||
|
||||
void Bullet2NearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo)
|
||||
{
|
||||
btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
|
||||
btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;
|
||||
plCollisionObjectHandle obA =(plCollisionObjectHandle) colObj0;
|
||||
plCollisionObjectHandle obB =(plCollisionObjectHandle) colObj1;
|
||||
if(gTmpFilter)
|
||||
{
|
||||
gTmpFilter(gCollisionSdk,gCollisionWorldHandle, gUserData,obA,obB);
|
||||
gNearCallbackCount++;
|
||||
}
|
||||
btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
|
||||
btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;
|
||||
plCollisionObjectHandle obA = (plCollisionObjectHandle)colObj0;
|
||||
plCollisionObjectHandle obB = (plCollisionObjectHandle)colObj1;
|
||||
if (gTmpFilter)
|
||||
{
|
||||
gTmpFilter(gCollisionSdk, gCollisionWorldHandle, gUserData, obA, obB);
|
||||
gNearCallbackCount++;
|
||||
}
|
||||
}
|
||||
|
||||
void Bullet2CollisionSdk::collideWorld( plCollisionWorldHandle worldHandle,
|
||||
plNearCallback filter, void* userData)
|
||||
void Bullet2CollisionSdk::collideWorld(plCollisionWorldHandle worldHandle,
|
||||
plNearCallback filter, void* userData)
|
||||
{
|
||||
btCollisionWorld* world = (btCollisionWorld*) worldHandle;
|
||||
//chain the near-callback
|
||||
gTmpFilter = filter;
|
||||
gNearCallbackCount = 0;
|
||||
gUserData = userData;
|
||||
gCollisionSdk = (plCollisionSdkHandle)this;
|
||||
gCollisionWorldHandle = worldHandle;
|
||||
m_internalData->m_dispatcher->setNearCallback(Bullet2NearCallback);
|
||||
world->performDiscreteCollisionDetection();
|
||||
gTmpFilter = 0;
|
||||
btCollisionWorld* world = (btCollisionWorld*)worldHandle;
|
||||
//chain the near-callback
|
||||
gTmpFilter = filter;
|
||||
gNearCallbackCount = 0;
|
||||
gUserData = userData;
|
||||
gCollisionSdk = (plCollisionSdkHandle)this;
|
||||
gCollisionWorldHandle = worldHandle;
|
||||
m_internalData->m_dispatcher->setNearCallback(Bullet2NearCallback);
|
||||
world->performDiscreteCollisionDetection();
|
||||
gTmpFilter = 0;
|
||||
}
|
||||
|
||||
plCollisionSdkHandle Bullet2CollisionSdk::createBullet2SdkHandle()
|
||||
|
|
|
|||
|
|
@ -6,51 +6,50 @@
|
|||
class Bullet2CollisionSdk : public CollisionSdkInterface
|
||||
{
|
||||
struct Bullet2CollisionSdkInternalData* m_internalData;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
Bullet2CollisionSdk();
|
||||
|
||||
|
||||
virtual ~Bullet2CollisionSdk();
|
||||
|
||||
|
||||
virtual plCollisionWorldHandle createCollisionWorld(int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity);
|
||||
|
||||
|
||||
virtual void deleteCollisionWorld(plCollisionWorldHandle worldHandle);
|
||||
|
||||
virtual plCollisionShapeHandle createSphereShape(plCollisionWorldHandle worldHandle, plReal radius);
|
||||
|
||||
virtual plCollisionShapeHandle createPlaneShape(plCollisionWorldHandle worldHandle,
|
||||
plReal planeNormalX,
|
||||
plReal planeNormalY,
|
||||
plReal planeNormalZ,
|
||||
|
||||
virtual plCollisionShapeHandle createPlaneShape(plCollisionWorldHandle worldHandle,
|
||||
plReal planeNormalX,
|
||||
plReal planeNormalY,
|
||||
plReal planeNormalZ,
|
||||
plReal planeConstant);
|
||||
|
||||
virtual plCollisionShapeHandle createCapsuleShape(plCollisionWorldHandle worldHandle,
|
||||
plReal radius,
|
||||
plReal height,
|
||||
int capsuleAxis);
|
||||
virtual plCollisionShapeHandle createCapsuleShape(plCollisionWorldHandle worldHandle,
|
||||
plReal radius,
|
||||
plReal height,
|
||||
int capsuleAxis);
|
||||
|
||||
virtual plCollisionShapeHandle createCompoundShape(plCollisionWorldHandle worldHandle);
|
||||
virtual void addChildShape(plCollisionWorldHandle worldHandle,plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape,plVector3 childPos,plQuaternion childOrn);
|
||||
virtual void addChildShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape, plVector3 childPos, plQuaternion childOrn);
|
||||
|
||||
virtual void deleteShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle shape);
|
||||
|
||||
|
||||
virtual void addCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object);
|
||||
virtual void removeCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object);
|
||||
|
||||
virtual plCollisionObjectHandle createCollisionObject( plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle cshape ,
|
||||
plVector3 startPosition,plQuaternion startOrientation );
|
||||
virtual void deleteCollisionObject(plCollisionObjectHandle body);
|
||||
virtual void removeCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object);
|
||||
|
||||
virtual plCollisionObjectHandle createCollisionObject(plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle cshape,
|
||||
plVector3 startPosition, plQuaternion startOrientation);
|
||||
virtual void deleteCollisionObject(plCollisionObjectHandle body);
|
||||
virtual void setCollisionObjectTransform(plCollisionWorldHandle world, plCollisionObjectHandle body,
|
||||
plVector3 position,plQuaternion orientation );
|
||||
|
||||
virtual int collide(plCollisionWorldHandle world,plCollisionObjectHandle colA, plCollisionObjectHandle colB,
|
||||
lwContactPoint* pointsOut, int pointCapacity);
|
||||
|
||||
virtual void collideWorld( plCollisionWorldHandle world,
|
||||
plNearCallback filter, void* userData);
|
||||
plVector3 position, plQuaternion orientation);
|
||||
|
||||
virtual int collide(plCollisionWorldHandle world, plCollisionObjectHandle colA, plCollisionObjectHandle colB,
|
||||
lwContactPoint* pointsOut, int pointCapacity);
|
||||
|
||||
virtual void collideWorld(plCollisionWorldHandle world,
|
||||
plNearCallback filter, void* userData);
|
||||
|
||||
static plCollisionSdkHandle createBullet2SdkHandle();
|
||||
};
|
||||
|
||||
#endif //BULLET2_COLLISION_SDK_H
|
||||
#endif //BULLET2_COLLISION_SDK_H
|
||||
|
|
|
|||
|
|
@ -6,50 +6,46 @@
|
|||
class CollisionSdkInterface
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~CollisionSdkInterface()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual plCollisionWorldHandle createCollisionWorld(int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity) = 0;
|
||||
|
||||
|
||||
virtual void deleteCollisionWorld(plCollisionWorldHandle worldHandle) = 0;
|
||||
|
||||
|
||||
virtual plCollisionShapeHandle createSphereShape(plCollisionWorldHandle worldHandle, plReal radius) = 0;
|
||||
|
||||
virtual plCollisionShapeHandle createPlaneShape(plCollisionWorldHandle worldHandle,
|
||||
plReal planeNormalX,
|
||||
plReal planeNormalY,
|
||||
plReal planeNormalZ,
|
||||
virtual plCollisionShapeHandle createPlaneShape(plCollisionWorldHandle worldHandle,
|
||||
plReal planeNormalX,
|
||||
plReal planeNormalY,
|
||||
plReal planeNormalZ,
|
||||
plReal planeConstant) = 0;
|
||||
|
||||
virtual plCollisionShapeHandle createCapsuleShape(plCollisionWorldHandle worldHandle,
|
||||
plReal radius,
|
||||
plReal height,
|
||||
int capsuleAxis) = 0;
|
||||
|
||||
virtual plCollisionShapeHandle createCapsuleShape(plCollisionWorldHandle worldHandle,
|
||||
plReal radius,
|
||||
plReal height,
|
||||
int capsuleAxis) = 0;
|
||||
|
||||
virtual plCollisionShapeHandle createCompoundShape(plCollisionWorldHandle worldHandle) = 0;
|
||||
virtual void addChildShape(plCollisionWorldHandle worldHandle,plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape,plVector3 childPos,plQuaternion childOrn)=0;
|
||||
virtual void addChildShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape, plVector3 childPos, plQuaternion childOrn) = 0;
|
||||
|
||||
virtual void deleteShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle shape) = 0;
|
||||
|
||||
virtual void addCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object)=0;
|
||||
virtual void removeCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object)=0;
|
||||
|
||||
virtual plCollisionObjectHandle createCollisionObject( plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle cshape ,
|
||||
plVector3 startPosition,plQuaternion startOrientation )=0;
|
||||
virtual void deleteCollisionObject(plCollisionObjectHandle body)=0;
|
||||
virtual void setCollisionObjectTransform(plCollisionWorldHandle world, plCollisionObjectHandle body,
|
||||
plVector3 position,plQuaternion orientation )=0;
|
||||
|
||||
virtual int collide(plCollisionWorldHandle world,plCollisionObjectHandle colA, plCollisionObjectHandle colB,
|
||||
lwContactPoint* pointsOut, int pointCapacity)=0;
|
||||
|
||||
virtual void collideWorld( plCollisionWorldHandle world,
|
||||
plNearCallback filter, void* userData)=0;
|
||||
|
||||
|
||||
virtual void addCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object) = 0;
|
||||
virtual void removeCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object) = 0;
|
||||
|
||||
virtual plCollisionObjectHandle createCollisionObject(plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle cshape,
|
||||
plVector3 startPosition, plQuaternion startOrientation) = 0;
|
||||
virtual void deleteCollisionObject(plCollisionObjectHandle body) = 0;
|
||||
virtual void setCollisionObjectTransform(plCollisionWorldHandle world, plCollisionObjectHandle body,
|
||||
plVector3 position, plQuaternion orientation) = 0;
|
||||
|
||||
virtual int collide(plCollisionWorldHandle world, plCollisionObjectHandle colA, plCollisionObjectHandle colB,
|
||||
lwContactPoint* pointsOut, int pointCapacity) = 0;
|
||||
|
||||
virtual void collideWorld(plCollisionWorldHandle world,
|
||||
plNearCallback filter, void* userData) = 0;
|
||||
};
|
||||
|
||||
#endif //COLLISION_SDK_INTERFACE_H
|
||||
|
||||
#endif //COLLISION_SDK_INTERFACE_H
|
||||
|
|
|
|||
|
|
@ -8,30 +8,27 @@
|
|||
//convert the opaque pointer to int
|
||||
struct RTB3_ColliderOpaque2Int
|
||||
{
|
||||
union
|
||||
{
|
||||
plCollisionObjectHandle m_ptrValue;
|
||||
int m_intValue;
|
||||
};
|
||||
union {
|
||||
plCollisionObjectHandle m_ptrValue;
|
||||
int m_intValue;
|
||||
};
|
||||
};
|
||||
struct RTB3_ShapeOpaque2Int
|
||||
{
|
||||
union
|
||||
{
|
||||
plCollisionShapeHandle m_ptrValue;
|
||||
int m_intValue;
|
||||
};
|
||||
union {
|
||||
plCollisionShapeHandle m_ptrValue;
|
||||
int m_intValue;
|
||||
};
|
||||
};
|
||||
|
||||
enum RTB3ShapeTypes
|
||||
{
|
||||
RTB3_SHAPE_SPHERE=0,
|
||||
RTB3_SHAPE_SPHERE = 0,
|
||||
RTB3_SHAPE_PLANE,
|
||||
RTB3_SHAPE_CAPSULE,
|
||||
MAX_NUM_SINGLE_SHAPE_TYPES,
|
||||
RTB3_SHAPE_COMPOUND_INTERNAL,
|
||||
|
||||
|
||||
};
|
||||
|
||||
//we start at 1, so that the 0 index is 'invalid' just like a nullptr
|
||||
|
|
@ -47,20 +44,24 @@ struct RTB3CollisionWorld
|
|||
b3AlignedObjectArray<b3Transform> m_collidableTransforms;
|
||||
|
||||
b3AlignedObjectArray<b3Collidable> m_collidables;
|
||||
|
||||
|
||||
b3AlignedObjectArray<b3GpuChildShape> m_childShapes;
|
||||
b3AlignedObjectArray<b3Aabb> m_localSpaceAabbs;
|
||||
b3AlignedObjectArray<b3Aabb> m_worldSpaceAabbs;
|
||||
b3AlignedObjectArray<b3Aabb> m_localSpaceAabbs;
|
||||
b3AlignedObjectArray<b3Aabb> m_worldSpaceAabbs;
|
||||
b3AlignedObjectArray<b3GpuFace> m_planeFaces;
|
||||
b3AlignedObjectArray<b3CompoundOverlappingPair> m_compoundOverlappingPairs;
|
||||
int m_nextFreeShapeIndex;
|
||||
|
||||
union {
|
||||
int m_nextFreeShapeIndex;
|
||||
void* m_nextFreeShapePtr;
|
||||
};
|
||||
int m_nextFreeCollidableIndex;
|
||||
int m_nextFreePlaneFaceIndex;
|
||||
|
||||
RTB3CollisionWorld()
|
||||
:m_nextFreeCollidableIndex(START_COLLIDABLE_INDEX),
|
||||
m_nextFreeShapeIndex(START_SHAPE_INDEX),
|
||||
m_nextFreePlaneFaceIndex(0)//this value is never exposed to the user, so we can start from 0
|
||||
: m_nextFreeShapeIndex(START_SHAPE_INDEX),
|
||||
m_nextFreeCollidableIndex(START_COLLIDABLE_INDEX),
|
||||
m_nextFreePlaneFaceIndex(0) //this value is never exposed to the user, so we can start from 0
|
||||
{
|
||||
}
|
||||
};
|
||||
|
|
@ -72,42 +73,42 @@ struct RealTimeBullet3CollisionSdkInternalData
|
|||
|
||||
RealTimeBullet3CollisionSdk::RealTimeBullet3CollisionSdk()
|
||||
{
|
||||
// int szCol = sizeof(b3Collidable);
|
||||
// int szShap = sizeof(b3GpuChildShape);
|
||||
// int szComPair = sizeof(b3CompoundOverlappingPair);
|
||||
// int szCol = sizeof(b3Collidable);
|
||||
// int szShap = sizeof(b3GpuChildShape);
|
||||
// int szComPair = sizeof(b3CompoundOverlappingPair);
|
||||
m_internalData = new RealTimeBullet3CollisionSdkInternalData;
|
||||
}
|
||||
|
||||
|
||||
RealTimeBullet3CollisionSdk::~RealTimeBullet3CollisionSdk()
|
||||
{
|
||||
delete m_internalData;
|
||||
m_internalData=0;
|
||||
m_internalData = 0;
|
||||
}
|
||||
|
||||
|
||||
plCollisionWorldHandle RealTimeBullet3CollisionSdk::createCollisionWorld(int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity)
|
||||
{
|
||||
RTB3CollisionWorld* world = new RTB3CollisionWorld();
|
||||
world->m_collidables.resize(maxNumObjsCapacity+START_COLLIDABLE_INDEX);
|
||||
world->m_collidablePositions.resize(maxNumObjsCapacity+START_COLLIDABLE_INDEX);
|
||||
world->m_collidableOrientations.resize(maxNumObjsCapacity+START_COLLIDABLE_INDEX);
|
||||
world->m_collidableTransforms.resize(maxNumObjsCapacity+START_COLLIDABLE_INDEX);
|
||||
world->m_collidableUserPointers.resize(maxNumObjsCapacity+START_COLLIDABLE_INDEX);
|
||||
world->m_collidableUserIndices.resize(maxNumObjsCapacity+START_COLLIDABLE_INDEX);
|
||||
world->m_childShapes.resize(maxNumShapesCapacity+START_SHAPE_INDEX);
|
||||
world->m_collidables.resize(maxNumObjsCapacity + START_COLLIDABLE_INDEX);
|
||||
world->m_collidablePositions.resize(maxNumObjsCapacity + START_COLLIDABLE_INDEX);
|
||||
world->m_collidableOrientations.resize(maxNumObjsCapacity + START_COLLIDABLE_INDEX);
|
||||
world->m_collidableTransforms.resize(maxNumObjsCapacity + START_COLLIDABLE_INDEX);
|
||||
world->m_collidableUserPointers.resize(maxNumObjsCapacity + START_COLLIDABLE_INDEX);
|
||||
world->m_collidableUserIndices.resize(maxNumObjsCapacity + START_COLLIDABLE_INDEX);
|
||||
world->m_childShapes.resize(maxNumShapesCapacity + START_SHAPE_INDEX);
|
||||
world->m_planeFaces.resize(maxNumShapesCapacity);
|
||||
|
||||
|
||||
world->m_compoundOverlappingPairs.resize(maxNumPairsCapacity);
|
||||
|
||||
m_internalData->m_collisionWorlds.push_back(world);
|
||||
return (plCollisionWorldHandle) world;
|
||||
return (plCollisionWorldHandle)world;
|
||||
}
|
||||
|
||||
|
||||
void RealTimeBullet3CollisionSdk::deleteCollisionWorld(plCollisionWorldHandle worldHandle)
|
||||
{
|
||||
RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle;
|
||||
RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle;
|
||||
int loc = m_internalData->m_collisionWorlds.findLinearSearch(world);
|
||||
b3Assert(loc >=0 && loc<m_internalData->m_collisionWorlds.size());
|
||||
if (loc >=0 && loc<m_internalData->m_collisionWorlds.size())
|
||||
b3Assert(loc >= 0 && loc < m_internalData->m_collisionWorlds.size());
|
||||
if (loc >= 0 && loc < m_internalData->m_collisionWorlds.size())
|
||||
{
|
||||
m_internalData->m_collisionWorlds.remove(world);
|
||||
delete world;
|
||||
|
|
@ -116,84 +117,87 @@ void RealTimeBullet3CollisionSdk::deleteCollisionWorld(plCollisionWorldHandle wo
|
|||
|
||||
plCollisionShapeHandle RealTimeBullet3CollisionSdk::createSphereShape(plCollisionWorldHandle worldHandle, plReal radius)
|
||||
{
|
||||
RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle;
|
||||
b3Assert(world->m_nextFreeShapeIndex<world->m_childShapes.size());
|
||||
if (world->m_nextFreeShapeIndex<world->m_childShapes.size())
|
||||
RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle;
|
||||
b3Assert(world->m_nextFreeShapeIndex < world->m_childShapes.size());
|
||||
if (world->m_nextFreeShapeIndex < world->m_childShapes.size())
|
||||
{
|
||||
b3GpuChildShape& shape = world->m_childShapes[world->m_nextFreeShapeIndex];
|
||||
shape.m_childPosition.setZero();
|
||||
shape.m_childOrientation.setValue(0,0,0,1);
|
||||
shape.m_childOrientation.setValue(0, 0, 0, 1);
|
||||
shape.m_radius = radius;
|
||||
shape.m_shapeType = RTB3_SHAPE_SPHERE;
|
||||
return (plCollisionShapeHandle) world->m_nextFreeShapeIndex++;
|
||||
world->m_nextFreeShapeIndex++;
|
||||
return (plCollisionShapeHandle)world->m_nextFreeShapePtr;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
plCollisionShapeHandle RealTimeBullet3CollisionSdk::createPlaneShape(plCollisionWorldHandle worldHandle,
|
||||
plReal planeNormalX,
|
||||
plReal planeNormalY,
|
||||
plReal planeNormalZ,
|
||||
plReal planeConstant)
|
||||
|
||||
plCollisionShapeHandle RealTimeBullet3CollisionSdk::createPlaneShape(plCollisionWorldHandle worldHandle,
|
||||
plReal planeNormalX,
|
||||
plReal planeNormalY,
|
||||
plReal planeNormalZ,
|
||||
plReal planeConstant)
|
||||
{
|
||||
RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle;
|
||||
RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle;
|
||||
b3Assert(world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size());
|
||||
|
||||
if (world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size())
|
||||
{
|
||||
b3GpuChildShape& shape = world->m_childShapes[world->m_nextFreeShapeIndex];
|
||||
shape.m_childPosition.setZero();
|
||||
shape.m_childOrientation.setValue(0,0,0,1);
|
||||
world->m_planeFaces[world->m_nextFreePlaneFaceIndex].m_plane = b3MakeVector4(planeNormalX,planeNormalY,planeNormalZ,planeConstant);
|
||||
shape.m_childOrientation.setValue(0, 0, 0, 1);
|
||||
world->m_planeFaces[world->m_nextFreePlaneFaceIndex].m_plane = b3MakeVector4(planeNormalX, planeNormalY, planeNormalZ, planeConstant);
|
||||
shape.m_shapeIndex = world->m_nextFreePlaneFaceIndex++;
|
||||
shape.m_shapeType = RTB3_SHAPE_PLANE;
|
||||
return (plCollisionShapeHandle) world->m_nextFreeShapeIndex++;
|
||||
world->m_nextFreeShapeIndex++;
|
||||
return (plCollisionShapeHandle)world->m_nextFreeShapePtr;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
plCollisionShapeHandle RealTimeBullet3CollisionSdk::createCapsuleShape(plCollisionWorldHandle worldHandle,
|
||||
plReal radius,
|
||||
plReal height,
|
||||
int capsuleAxis)
|
||||
plCollisionShapeHandle RealTimeBullet3CollisionSdk::createCapsuleShape(plCollisionWorldHandle worldHandle,
|
||||
plReal radius,
|
||||
plReal height,
|
||||
int capsuleAxis)
|
||||
{
|
||||
RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle;
|
||||
RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle;
|
||||
b3Assert(world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size());
|
||||
|
||||
if (world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size())
|
||||
{
|
||||
b3GpuChildShape& shape = world->m_childShapes[world->m_nextFreeShapeIndex];
|
||||
shape.m_childPosition.setZero();
|
||||
shape.m_childOrientation.setValue(0,0,0,1);
|
||||
shape.m_childOrientation.setValue(0, 0, 0, 1);
|
||||
shape.m_radius = radius;
|
||||
shape.m_height = height;
|
||||
shape.m_shapeIndex = capsuleAxis;
|
||||
shape.m_shapeType = RTB3_SHAPE_CAPSULE;
|
||||
return (plCollisionShapeHandle) world->m_nextFreeShapeIndex++;
|
||||
world->m_nextFreeShapeIndex++;
|
||||
return (plCollisionShapeHandle)world->m_nextFreeShapePtr;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
plCollisionShapeHandle RealTimeBullet3CollisionSdk::createCompoundShape(plCollisionWorldHandle worldHandle)
|
||||
{
|
||||
RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle;
|
||||
RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle;
|
||||
b3Assert(world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size());
|
||||
|
||||
if (world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size())
|
||||
{
|
||||
b3GpuChildShape& shape = world->m_childShapes[world->m_nextFreeShapeIndex];
|
||||
shape.m_childPosition.setZero();
|
||||
shape.m_childOrientation.setValue(0,0,0,1);
|
||||
shape.m_childOrientation.setValue(0, 0, 0, 1);
|
||||
shape.m_numChildShapes = 0;
|
||||
shape.m_shapeType = RTB3_SHAPE_COMPOUND_INTERNAL;
|
||||
return (plCollisionShapeHandle) world->m_nextFreeShapeIndex++;
|
||||
world->m_nextFreeShapeIndex++;
|
||||
return (plCollisionShapeHandle)world->m_nextFreeShapePtr;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RealTimeBullet3CollisionSdk::addChildShape(plCollisionWorldHandle worldHandle,plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape,plVector3 childPos,plQuaternion childOrn)
|
||||
void RealTimeBullet3CollisionSdk::addChildShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape, plVector3 childPos, plQuaternion childOrn)
|
||||
{
|
||||
|
||||
}
|
||||
void RealTimeBullet3CollisionSdk::deleteShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle shape)
|
||||
{
|
||||
|
|
@ -202,7 +206,7 @@ void RealTimeBullet3CollisionSdk::deleteShape(plCollisionWorldHandle worldHandle
|
|||
//this would be solved by one more in-direction, at some performance penalty for certain operations
|
||||
//for now, we don't delete and eventually run out-of-shapes
|
||||
}
|
||||
|
||||
|
||||
void RealTimeBullet3CollisionSdk::addCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object)
|
||||
{
|
||||
///createCollisionObject already adds it to the world
|
||||
|
|
@ -212,46 +216,45 @@ void RealTimeBullet3CollisionSdk::removeCollisionObject(plCollisionWorldHandle w
|
|||
{
|
||||
///todo, see deleteShape
|
||||
}
|
||||
|
||||
plCollisionObjectHandle RealTimeBullet3CollisionSdk::createCollisionObject( plCollisionWorldHandle worldHandle, void* userPointer,
|
||||
int userIndex, plCollisionShapeHandle shapeHandle ,
|
||||
plVector3 startPosition,plQuaternion startOrientation )
|
||||
|
||||
plCollisionObjectHandle RealTimeBullet3CollisionSdk::createCollisionObject(plCollisionWorldHandle worldHandle, void* userPointer,
|
||||
int userIndex, plCollisionShapeHandle shapeHandle,
|
||||
plVector3 startPosition, plQuaternion startOrientation)
|
||||
{
|
||||
RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle;
|
||||
RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle;
|
||||
b3Assert(world->m_nextFreeCollidableIndex < world->m_collidables.size());
|
||||
if (world->m_nextFreeCollidableIndex < world->m_collidables.size())
|
||||
{
|
||||
b3Collidable& collidable = world->m_collidables[world->m_nextFreeCollidableIndex];
|
||||
world->m_collidablePositions[world->m_nextFreeCollidableIndex].setValue(startPosition[0],startPosition[1],startPosition[2]);
|
||||
world->m_collidableOrientations[world->m_nextFreeCollidableIndex].setValue(startOrientation[0],startOrientation[1],startOrientation[2],startOrientation[3]);
|
||||
world->m_collidablePositions[world->m_nextFreeCollidableIndex].setValue(startPosition[0], startPosition[1], startPosition[2]);
|
||||
world->m_collidableOrientations[world->m_nextFreeCollidableIndex].setValue(startOrientation[0], startOrientation[1], startOrientation[2], startOrientation[3]);
|
||||
world->m_collidableTransforms[world->m_nextFreeCollidableIndex].setOrigin(world->m_collidablePositions[world->m_nextFreeCollidableIndex]);
|
||||
world->m_collidableTransforms[world->m_nextFreeCollidableIndex].setRotation(world->m_collidableOrientations[world->m_nextFreeCollidableIndex]);
|
||||
world->m_collidableUserPointers[world->m_nextFreeCollidableIndex] = userPointer;
|
||||
world->m_collidableUserIndices[world->m_nextFreeCollidableIndex] = userIndex;
|
||||
RTB3_ShapeOpaque2Int caster;
|
||||
caster.m_ptrValue = shapeHandle;
|
||||
int shapeIndex = caster.m_intValue;
|
||||
collidable.m_shapeIndex = shapeIndex;
|
||||
RTB3_ShapeOpaque2Int caster;
|
||||
caster.m_ptrValue = shapeHandle;
|
||||
int shapeIndex = caster.m_intValue;
|
||||
collidable.m_shapeIndex = shapeIndex;
|
||||
b3GpuChildShape& shape = world->m_childShapes[shapeIndex];
|
||||
collidable.m_shapeType = shape.m_shapeType;
|
||||
collidable.m_numChildShapes = 1;
|
||||
|
||||
switch (collidable.m_shapeType)
|
||||
{
|
||||
case RTB3_SHAPE_SPHERE:
|
||||
case RTB3_SHAPE_SPHERE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case RTB3_SHAPE_PLANE:
|
||||
case RTB3_SHAPE_PLANE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case RTB3_SHAPE_COMPOUND_INTERNAL:
|
||||
case RTB3_SHAPE_COMPOUND_INTERNAL:
|
||||
{
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
default:
|
||||
{
|
||||
b3Assert(0);
|
||||
}
|
||||
|
|
@ -265,18 +268,19 @@ plCollisionObjectHandle RealTimeBullet3CollisionSdk::createCollisionObject( plC
|
|||
collidable.m_shapeIndex = shape.m_shapeIndex;
|
||||
break;
|
||||
*/
|
||||
return (plCollisionObjectHandle)world->m_nextFreeCollidableIndex++;
|
||||
world->m_nextFreeCollidableIndex++;
|
||||
return (plCollisionObjectHandle)world->m_nextFreeShapePtr;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void RealTimeBullet3CollisionSdk::deleteCollisionObject(plCollisionObjectHandle body)
|
||||
{
|
||||
///todo, see deleteShape
|
||||
}
|
||||
|
||||
|
||||
void RealTimeBullet3CollisionSdk::setCollisionObjectTransform(plCollisionWorldHandle world, plCollisionObjectHandle body,
|
||||
plVector3 position,plQuaternion orientation )
|
||||
plVector3 position, plQuaternion orientation)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -287,159 +291,154 @@ struct plContactCache
|
|||
int numAddedPoints;
|
||||
};
|
||||
|
||||
typedef void (*plDetectCollisionFunc)(RTB3CollisionWorld* world,int colA, int shapeIndexA, int colB, int shapeIndexB,
|
||||
plContactCache* contactCache);
|
||||
typedef void (*plDetectCollisionFunc)(RTB3CollisionWorld* world, int colA, int shapeIndexA, int colB, int shapeIndexB,
|
||||
plContactCache* contactCache);
|
||||
|
||||
void detectCollisionDummy(RTB3CollisionWorld* world,int colA, int shapeIndexA, int colB, int shapeIndexB,
|
||||
plContactCache* contactCache)
|
||||
void detectCollisionDummy(RTB3CollisionWorld* world, int colA, int shapeIndexA, int colB, int shapeIndexB,
|
||||
plContactCache* contactCache)
|
||||
{
|
||||
(void)world;
|
||||
(void)colA,(void)colB;
|
||||
(void)colA, (void)colB;
|
||||
(void)contactCache;
|
||||
}
|
||||
|
||||
void plVecCopy(float* dst,const b3Vector3& src)
|
||||
void plVecCopy(float* dst, const b3Vector3& src)
|
||||
{
|
||||
dst[0] = src.x;
|
||||
dst[1] = src.y;
|
||||
dst[2] = src.z;
|
||||
}
|
||||
void plVecCopy(double* dst,const b3Vector3& src)
|
||||
void plVecCopy(double* dst, const b3Vector3& src)
|
||||
{
|
||||
dst[0] = src.x;
|
||||
dst[1] = src.y;
|
||||
dst[2] = src.z;
|
||||
dst[0] = src.x;
|
||||
dst[1] = src.y;
|
||||
dst[2] = src.z;
|
||||
}
|
||||
|
||||
void ComputeClosestPointsPlaneSphere(const b3Vector3& planeNormalWorld, b3Scalar planeConstant, const b3Vector3& spherePosWorld,b3Scalar sphereRadius, plContactCache* contactCache)
|
||||
void ComputeClosestPointsPlaneSphere(const b3Vector3& planeNormalWorld, b3Scalar planeConstant, const b3Vector3& spherePosWorld, b3Scalar sphereRadius, plContactCache* contactCache)
|
||||
{
|
||||
if (contactCache->numAddedPoints < contactCache->pointCapacity)
|
||||
{
|
||||
lwContactPoint& pointOut = contactCache->pointsOut[contactCache->numAddedPoints];
|
||||
b3Scalar t = -(spherePosWorld.dot(-planeNormalWorld)+planeConstant);
|
||||
b3Vector3 intersectionPoint = spherePosWorld+t*-planeNormalWorld;
|
||||
b3Scalar distance = t-sphereRadius;
|
||||
if (distance<=0)
|
||||
b3Scalar t = -(spherePosWorld.dot(-planeNormalWorld) + planeConstant);
|
||||
b3Vector3 intersectionPoint = spherePosWorld + t * -planeNormalWorld;
|
||||
b3Scalar distance = t - sphereRadius;
|
||||
if (distance <= 0)
|
||||
{
|
||||
pointOut.m_distance = distance;
|
||||
plVecCopy(pointOut.m_ptOnBWorld,intersectionPoint);
|
||||
plVecCopy(pointOut.m_ptOnAWorld,spherePosWorld+sphereRadius*-planeNormalWorld);
|
||||
plVecCopy(pointOut.m_normalOnB,planeNormalWorld);
|
||||
plVecCopy(pointOut.m_ptOnBWorld, intersectionPoint);
|
||||
plVecCopy(pointOut.m_ptOnAWorld, spherePosWorld + sphereRadius * -planeNormalWorld);
|
||||
plVecCopy(pointOut.m_normalOnB, planeNormalWorld);
|
||||
contactCache->numAddedPoints++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ComputeClosestPointsSphereSphere(b3Scalar sphereARadius, const b3Vector3& sphereAPosWorld, b3Scalar sphereBRadius, const b3Vector3& sphereBPosWorld, plContactCache* contactCache) {
|
||||
|
||||
void ComputeClosestPointsSphereSphere(b3Scalar sphereARadius, const b3Vector3& sphereAPosWorld, b3Scalar sphereBRadius, const b3Vector3& sphereBPosWorld, plContactCache* contactCache)
|
||||
{
|
||||
if (contactCache->numAddedPoints < contactCache->pointCapacity)
|
||||
{
|
||||
lwContactPoint& pointOut = contactCache->pointsOut[contactCache->numAddedPoints];
|
||||
b3Vector3 diff = sphereAPosWorld-sphereBPosWorld;
|
||||
b3Vector3 diff = sphereAPosWorld - sphereBPosWorld;
|
||||
|
||||
b3Scalar len = diff.length();
|
||||
pointOut.m_distance = len - (sphereARadius+sphereBRadius);
|
||||
if (pointOut.m_distance<=0)
|
||||
pointOut.m_distance = len - (sphereARadius + sphereBRadius);
|
||||
if (pointOut.m_distance <= 0)
|
||||
{
|
||||
b3Vector3 normOnB = b3MakeVector3(1,0,0);
|
||||
if (len > B3_EPSILON) {
|
||||
b3Vector3 normOnB = b3MakeVector3(1, 0, 0);
|
||||
if (len > B3_EPSILON)
|
||||
{
|
||||
normOnB = diff / len;
|
||||
}
|
||||
|
||||
plVecCopy(pointOut.m_normalOnB,normOnB);
|
||||
b3Vector3 ptAWorld = sphereAPosWorld - sphereARadius*normOnB;
|
||||
plVecCopy(pointOut.m_ptOnAWorld,ptAWorld);
|
||||
plVecCopy(pointOut.m_ptOnBWorld,ptAWorld-normOnB*pointOut.m_distance);
|
||||
|
||||
|
||||
plVecCopy(pointOut.m_normalOnB, normOnB);
|
||||
b3Vector3 ptAWorld = sphereAPosWorld - sphereARadius * normOnB;
|
||||
plVecCopy(pointOut.m_ptOnAWorld, ptAWorld);
|
||||
plVecCopy(pointOut.m_ptOnBWorld, ptAWorld - normOnB * pointOut.m_distance);
|
||||
|
||||
contactCache->numAddedPoints++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE void detectCollisionSphereSphere(RTB3CollisionWorld* world,int colA, int shapeIndexA, int colB, int shapeIndexB,
|
||||
plContactCache* contactCache)
|
||||
B3_FORCE_INLINE void detectCollisionSphereSphere(RTB3CollisionWorld* world, int colA, int shapeIndexA, int colB, int shapeIndexB,
|
||||
plContactCache* contactCache)
|
||||
{
|
||||
|
||||
const b3Scalar radiusA = world->m_childShapes[shapeIndexA].m_radius;
|
||||
const b3Scalar radiusB = world->m_childShapes[shapeIndexB].m_radius;
|
||||
|
||||
|
||||
const b3Transform& trA = world->m_collidableTransforms[colA];
|
||||
const b3Vector3& sphereALocalPos = world->m_childShapes[shapeIndexA].m_childPosition;
|
||||
b3Vector3 spherePosAWorld = trA(sphereALocalPos);
|
||||
//b3Vector3 spherePosAWorld = b3QuatRotate( world->m_collidableOrientations[colA], sphereALocalPos ) + (world->m_collidablePositions[colA]);
|
||||
|
||||
|
||||
const b3Transform& trB = world->m_collidableTransforms[colB];
|
||||
const b3Vector3& sphereBLocalPos = world->m_childShapes[shapeIndexB].m_childPosition;
|
||||
b3Vector3 spherePosBWorld = trB(sphereBLocalPos);
|
||||
//b3Vector3 spherePosBWorld = b3QuatRotate( world->m_collidableOrientations[colB], sphereBLocalPos ) + (world->m_collidablePositions[colB]);
|
||||
|
||||
ComputeClosestPointsSphereSphere(radiusA,spherePosAWorld,radiusB,spherePosBWorld,contactCache);
|
||||
ComputeClosestPointsSphereSphere(radiusA, spherePosAWorld, radiusB, spherePosBWorld, contactCache);
|
||||
}
|
||||
|
||||
void detectCollisionSpherePlane(RTB3CollisionWorld* world,int colA, int shapeIndexA, int colB, int shapeIndexB,
|
||||
plContactCache* contactCache)
|
||||
void detectCollisionSpherePlane(RTB3CollisionWorld* world, int colA, int shapeIndexA, int colB, int shapeIndexB,
|
||||
plContactCache* contactCache)
|
||||
{
|
||||
const b3Transform& trA = world->m_collidableTransforms[colA];
|
||||
const b3Vector3& sphereALocalPos = world->m_childShapes[shapeIndexA].m_childPosition;
|
||||
b3Vector3 spherePosAWorld = trA(sphereALocalPos);
|
||||
|
||||
|
||||
int planeFaceIndex = world->m_childShapes[shapeIndexB].m_shapeIndex;
|
||||
b3Vector3 planeNormal = world->m_planeFaces[planeFaceIndex].m_plane;
|
||||
b3Scalar planeConstant = planeNormal[3];
|
||||
planeNormal[3] = 0.f;
|
||||
|
||||
ComputeClosestPointsPlaneSphere(planeNormal, planeConstant, spherePosAWorld,world->m_childShapes[shapeIndexA].m_radius, contactCache);
|
||||
|
||||
ComputeClosestPointsPlaneSphere(planeNormal, planeConstant, spherePosAWorld, world->m_childShapes[shapeIndexA].m_radius, contactCache);
|
||||
}
|
||||
|
||||
void detectCollisionPlaneSphere(RTB3CollisionWorld* world,int colA, int shapeIndexA, int colB, int shapeIndexB,
|
||||
plContactCache* contactCache)
|
||||
void detectCollisionPlaneSphere(RTB3CollisionWorld* world, int colA, int shapeIndexA, int colB, int shapeIndexB,
|
||||
plContactCache* contactCache)
|
||||
{
|
||||
(void)world;
|
||||
(void)colA,(void)shapeIndexA,(void)colB,(void)shapeIndexB;
|
||||
(void)colA, (void)shapeIndexA, (void)colB, (void)shapeIndexB;
|
||||
(void)contactCache;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef RTB3_SHAPE_CAPSULE
|
||||
plDetectCollisionFunc funcTbl_detectCollision[MAX_NUM_SINGLE_SHAPE_TYPES,][MAX_NUM_SINGLE_SHAPE_TYPES,] = {
|
||||
{detectCollisionSphereSphere ,detectCollisionSpherePlane ,detectCollisionSphereCapsule},
|
||||
{detectCollisionPlaneSphere ,detectCollisionDummy ,detectCollisionPlaneCapsule},
|
||||
{detectCollisionCapsuleSphere ,detectCollisionCapsulePlane ,detectCollisionCapsuleCapsule},
|
||||
plDetectCollisionFunc funcTbl_detectCollision[MAX_NUM_SINGLE_SHAPE_TYPES, ][MAX_NUM_SINGLE_SHAPE_TYPES, ] = {
|
||||
{detectCollisionSphereSphere, detectCollisionSpherePlane, detectCollisionSphereCapsule},
|
||||
{detectCollisionPlaneSphere, detectCollisionDummy, detectCollisionPlaneCapsule},
|
||||
{detectCollisionCapsuleSphere, detectCollisionCapsulePlane, detectCollisionCapsuleCapsule},
|
||||
};
|
||||
#else
|
||||
plDetectCollisionFunc funcTbl_detectCollision[MAX_NUM_SINGLE_SHAPE_TYPES][MAX_NUM_SINGLE_SHAPE_TYPES] = {
|
||||
{detectCollisionSphereSphere ,detectCollisionSpherePlane},
|
||||
{detectCollisionPlaneSphere ,detectCollisionDummy },
|
||||
{detectCollisionSphereSphere, detectCollisionSpherePlane},
|
||||
{detectCollisionPlaneSphere, detectCollisionDummy},
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
int RealTimeBullet3CollisionSdk::collide(plCollisionWorldHandle worldHandle,plCollisionObjectHandle colAHandle, plCollisionObjectHandle colBHandle,
|
||||
lwContactPoint* pointsOutOrg, int pointCapacity)
|
||||
int RealTimeBullet3CollisionSdk::collide(plCollisionWorldHandle worldHandle, plCollisionObjectHandle colAHandle, plCollisionObjectHandle colBHandle,
|
||||
lwContactPoint* pointsOutOrg, int pointCapacity)
|
||||
{
|
||||
|
||||
RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle;
|
||||
RTB3_ColliderOpaque2Int caster;
|
||||
caster.m_ptrValue =colAHandle;
|
||||
int colAIndex = caster.m_intValue;
|
||||
caster.m_ptrValue = colBHandle;
|
||||
int colBIndex = caster.m_intValue;
|
||||
const b3Collidable& colA = world->m_collidables[colAIndex];
|
||||
RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle;
|
||||
RTB3_ColliderOpaque2Int caster;
|
||||
caster.m_ptrValue = colAHandle;
|
||||
int colAIndex = caster.m_intValue;
|
||||
caster.m_ptrValue = colBHandle;
|
||||
int colBIndex = caster.m_intValue;
|
||||
const b3Collidable& colA = world->m_collidables[colAIndex];
|
||||
const b3Collidable& colB = world->m_collidables[colBIndex];
|
||||
|
||||
plContactCache contactCache;
|
||||
contactCache.pointCapacity = pointCapacity;
|
||||
contactCache.pointsOut = pointsOutOrg;
|
||||
contactCache.numAddedPoints = 0;
|
||||
|
||||
for (int i=0;i<colA.m_numChildShapes;i++)
|
||||
|
||||
for (int i = 0; i < colA.m_numChildShapes; i++)
|
||||
{
|
||||
for (int j=0;j<colB.m_numChildShapes;j++)
|
||||
for (int j = 0; j < colB.m_numChildShapes; j++)
|
||||
{
|
||||
if (contactCache.numAddedPoints<pointCapacity)
|
||||
if (contactCache.numAddedPoints < pointCapacity)
|
||||
{
|
||||
//funcTbl_detectCollision[world->m_childShapes[colA.m_shapeIndex+i].m_shapeType]
|
||||
// [world->m_childShapes[colB.m_shapeIndex+j].m_shapeType](world,colAIndex,colA.m_shapeIndex+i,colBIndex,colB.m_shapeIndex+j,&contactCache);
|
||||
|
|
@ -451,25 +450,24 @@ int RealTimeBullet3CollisionSdk::collide(plCollisionWorldHandle worldHandle,plCo
|
|||
return 0;
|
||||
}
|
||||
|
||||
void RealTimeBullet3CollisionSdk::collideWorld( plCollisionWorldHandle worldHandle,
|
||||
plNearCallback filter, void* userData)
|
||||
void RealTimeBullet3CollisionSdk::collideWorld(plCollisionWorldHandle worldHandle,
|
||||
plNearCallback filter, void* userData)
|
||||
{
|
||||
RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle;
|
||||
RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle;
|
||||
if (filter)
|
||||
{
|
||||
RTB3_ColliderOpaque2Int caster;
|
||||
plCollisionObjectHandle colA;
|
||||
plCollisionObjectHandle colB;
|
||||
for (int i=START_COLLIDABLE_INDEX;i<world->m_nextFreeCollidableIndex;i++)
|
||||
for (int i = START_COLLIDABLE_INDEX; i < world->m_nextFreeCollidableIndex; i++)
|
||||
{
|
||||
|
||||
for (int j=i+1;j<world->m_nextFreeCollidableIndex;j++)
|
||||
for (int j = i + 1; j < world->m_nextFreeCollidableIndex; j++)
|
||||
{
|
||||
caster.m_intValue = i;
|
||||
colA = caster.m_ptrValue;
|
||||
caster.m_intValue = j;
|
||||
colA = caster.m_ptrValue;
|
||||
caster.m_intValue = j;
|
||||
colB = caster.m_ptrValue;
|
||||
filter((plCollisionSdkHandle)this,worldHandle,userData,colA,colB);
|
||||
filter((plCollisionSdkHandle)this, worldHandle, userData, colA, colB);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,50 +6,48 @@
|
|||
class RealTimeBullet3CollisionSdk : public CollisionSdkInterface
|
||||
{
|
||||
struct RealTimeBullet3CollisionSdkInternalData* m_internalData;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
RealTimeBullet3CollisionSdk();
|
||||
|
||||
|
||||
virtual ~RealTimeBullet3CollisionSdk();
|
||||
|
||||
|
||||
virtual plCollisionWorldHandle createCollisionWorld(int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity);
|
||||
|
||||
|
||||
virtual void deleteCollisionWorld(plCollisionWorldHandle worldHandle);
|
||||
|
||||
virtual plCollisionShapeHandle createSphereShape(plCollisionWorldHandle worldHandle, plReal radius);
|
||||
virtual plCollisionShapeHandle createPlaneShape(plCollisionWorldHandle worldHandle,
|
||||
plReal planeNormalX,
|
||||
plReal planeNormalY,
|
||||
plReal planeNormalZ,
|
||||
virtual plCollisionShapeHandle createPlaneShape(plCollisionWorldHandle worldHandle,
|
||||
plReal planeNormalX,
|
||||
plReal planeNormalY,
|
||||
plReal planeNormalZ,
|
||||
plReal planeConstant);
|
||||
virtual plCollisionShapeHandle createCapsuleShape(plCollisionWorldHandle worldHandle,
|
||||
plReal radius,
|
||||
plReal height,
|
||||
int capsuleAxis);
|
||||
|
||||
virtual plCollisionShapeHandle createCapsuleShape(plCollisionWorldHandle worldHandle,
|
||||
plReal radius,
|
||||
plReal height,
|
||||
int capsuleAxis);
|
||||
|
||||
virtual plCollisionShapeHandle createCompoundShape(plCollisionWorldHandle worldHandle);
|
||||
virtual void addChildShape(plCollisionWorldHandle worldHandle,plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape,plVector3 childPos,plQuaternion childOrn);
|
||||
virtual void addChildShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape, plVector3 childPos, plQuaternion childOrn);
|
||||
|
||||
virtual void deleteShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle shape);
|
||||
|
||||
|
||||
virtual void addCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object);
|
||||
virtual void removeCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object);
|
||||
|
||||
virtual plCollisionObjectHandle createCollisionObject( plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle cshape ,
|
||||
plVector3 startPosition,plQuaternion startOrientation );
|
||||
virtual void deleteCollisionObject(plCollisionObjectHandle body);
|
||||
virtual void removeCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object);
|
||||
|
||||
virtual plCollisionObjectHandle createCollisionObject(plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle cshape,
|
||||
plVector3 startPosition, plQuaternion startOrientation);
|
||||
virtual void deleteCollisionObject(plCollisionObjectHandle body);
|
||||
virtual void setCollisionObjectTransform(plCollisionWorldHandle world, plCollisionObjectHandle body,
|
||||
plVector3 position,plQuaternion orientation );
|
||||
|
||||
virtual int collide(plCollisionWorldHandle world,plCollisionObjectHandle colA, plCollisionObjectHandle colB,
|
||||
lwContactPoint* pointsOut, int pointCapacity);
|
||||
|
||||
virtual void collideWorld( plCollisionWorldHandle world,
|
||||
plNearCallback filter, void* userData);
|
||||
plVector3 position, plQuaternion orientation);
|
||||
|
||||
virtual int collide(plCollisionWorldHandle world, plCollisionObjectHandle colA, plCollisionObjectHandle colB,
|
||||
lwContactPoint* pointsOut, int pointCapacity);
|
||||
|
||||
virtual void collideWorld(plCollisionWorldHandle world,
|
||||
plNearCallback filter, void* userData);
|
||||
|
||||
static plCollisionSdkHandle createRealTimeBullet3CollisionSdkHandle();
|
||||
};
|
||||
|
||||
|
||||
#endif //REAL_TIME_COLLISION_SDK_H
|
||||
#endif //REAL_TIME_COLLISION_SDK_H
|
||||
|
|
|
|||
|
|
@ -4,14 +4,12 @@
|
|||
struct Common2dCanvasInterface
|
||||
{
|
||||
virtual ~Common2dCanvasInterface() {}
|
||||
virtual int createCanvas(const char* canvasName, int width, int height)=0;
|
||||
virtual void destroyCanvas(int canvasId)=0;
|
||||
virtual void setPixel(int canvasId, int x, int y, unsigned char red, unsigned char green,unsigned char blue, unsigned char alpha)=0;
|
||||
virtual void getPixel(int canvasId, int x, int y, unsigned char& red, unsigned char& green,unsigned char& blue, unsigned char& alpha)=0;
|
||||
|
||||
virtual void refreshImageData(int canvasId)=0;
|
||||
virtual int createCanvas(const char* canvasName, int width, int height, int xPos, int yPos) = 0;
|
||||
virtual void destroyCanvas(int canvasId) = 0;
|
||||
virtual void setPixel(int canvasId, int x, int y, unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha) = 0;
|
||||
virtual void getPixel(int canvasId, int x, int y, unsigned char& red, unsigned char& green, unsigned char& blue, unsigned char& alpha) = 0;
|
||||
|
||||
virtual void refreshImageData(int canvasId) = 0;
|
||||
};
|
||||
|
||||
#endif //COMMON_2D_CANVAS_INTERFACE_H
|
||||
|
||||
#endif //COMMON_2D_CANVAS_INTERFACE_H
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
#ifndef COMMON_CALLBACKS_H
|
||||
#define COMMON_CALLBACKS_H
|
||||
|
||||
typedef void (*b3WheelCallback)(float deltax, float deltay);
|
||||
typedef void (*b3ResizeCallback)(float width, float height);
|
||||
typedef void (*b3MouseMoveCallback)(float x, float y);
|
||||
typedef void (*b3MouseButtonCallback)(int button, int state, float x, float y);
|
||||
typedef void (*b3KeyboardCallback)(int keycode, int state);
|
||||
typedef void (*b3RenderCallback)();
|
||||
|
||||
enum
|
||||
{
|
||||
B3G_ESCAPE = 27,
|
||||
B3G_SPACE = 32,
|
||||
B3G_F1 = 0xff00,
|
||||
B3G_F2,
|
||||
B3G_F3,
|
||||
B3G_F4,
|
||||
B3G_F5,
|
||||
B3G_F6,
|
||||
B3G_F7,
|
||||
B3G_F8,
|
||||
B3G_F9,
|
||||
B3G_F10,
|
||||
B3G_F11,
|
||||
B3G_F12,
|
||||
B3G_F13,
|
||||
B3G_F14,
|
||||
B3G_F15,
|
||||
B3G_LEFT_ARROW,
|
||||
B3G_RIGHT_ARROW,
|
||||
B3G_UP_ARROW,
|
||||
B3G_DOWN_ARROW,
|
||||
B3G_PAGE_UP,
|
||||
B3G_PAGE_DOWN,
|
||||
B3G_END,
|
||||
B3G_HOME,
|
||||
B3G_INSERT,
|
||||
B3G_DELETE,
|
||||
B3G_BACKSPACE,
|
||||
B3G_SHIFT,
|
||||
B3G_CONTROL,
|
||||
B3G_ALT,
|
||||
B3G_RETURN,
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -3,13 +3,14 @@
|
|||
|
||||
struct CommonCameraInterface
|
||||
{
|
||||
virtual void getCameraProjectionMatrix(float m[16])const = 0;
|
||||
virtual ~CommonCameraInterface() {}
|
||||
virtual void getCameraProjectionMatrix(float m[16]) const = 0;
|
||||
virtual void getCameraViewMatrix(float m[16]) const = 0;
|
||||
|
||||
virtual void setVRCamera(const float viewMat[16], const float projectionMatrix[16])=0;
|
||||
virtual void disableVRCamera()=0;
|
||||
virtual bool isVRCamera() const =0;
|
||||
virtual void setVRCameraOffsetTransform(const float offset[16])=0;
|
||||
|
||||
virtual void setVRCamera(const float viewMat[16], const float projectionMatrix[16]) = 0;
|
||||
virtual void disableVRCamera() = 0;
|
||||
virtual bool isVRCamera() const = 0;
|
||||
virtual void setVRCameraOffsetTransform(const float offset[16]) = 0;
|
||||
|
||||
virtual void getCameraTargetPosition(float pos[3]) const = 0;
|
||||
virtual void getCameraPosition(float pos[3]) const = 0;
|
||||
|
|
@ -17,25 +18,29 @@ struct CommonCameraInterface
|
|||
virtual void getCameraTargetPosition(double pos[3]) const = 0;
|
||||
virtual void getCameraPosition(double pos[3]) const = 0;
|
||||
|
||||
virtual void setCameraTargetPosition(float x,float y,float z) = 0;
|
||||
virtual void setCameraDistance(float dist) = 0;
|
||||
virtual float getCameraDistance() const = 0;
|
||||
virtual void setCameraTargetPosition(float x, float y, float z) = 0;
|
||||
virtual void setCameraDistance(float dist) = 0;
|
||||
virtual float getCameraDistance() const = 0;
|
||||
|
||||
virtual void setCameraUpVector(float x, float y, float z) = 0;
|
||||
virtual void getCameraUpVector(float up[3]) const = 0;
|
||||
virtual void getCameraForwardVector(float fwd[3]) const = 0;
|
||||
|
||||
virtual void setCameraUpVector(float x,float y, float z) = 0;
|
||||
virtual void getCameraUpVector(float up[3]) const = 0;
|
||||
///the setCameraUpAxis will call the 'setCameraUpVector' and 'setCameraForwardVector'
|
||||
virtual void setCameraUpAxis(int axis) = 0;
|
||||
virtual int getCameraUpAxis() const = 0;
|
||||
virtual void setCameraUpAxis(int axis) = 0;
|
||||
virtual int getCameraUpAxis() const = 0;
|
||||
|
||||
virtual void setCameraYaw(float yaw) = 0;
|
||||
virtual float getCameraYaw() const = 0;
|
||||
|
||||
virtual void setCameraPitch(float pitch) = 0;
|
||||
virtual float getCameraPitch() const = 0;
|
||||
virtual void setCameraYaw(float yaw) = 0;
|
||||
virtual float getCameraYaw() const = 0;
|
||||
|
||||
virtual void setAspectRatio(float ratio) = 0;
|
||||
virtual float getAspectRatio() const = 0;
|
||||
virtual void setCameraPitch(float pitch) = 0;
|
||||
virtual float getCameraPitch() const = 0;
|
||||
|
||||
virtual void setAspectRatio(float ratio) = 0;
|
||||
virtual float getAspectRatio() const = 0;
|
||||
|
||||
virtual float getCameraFrustumFar() const = 0;
|
||||
virtual float getCameraFrustumNear() const = 0;
|
||||
};
|
||||
|
||||
#endif //COMMON_CAMERA_INTERFACE_H
|
||||
|
||||
#endif //COMMON_CAMERA_INTERFACE_H
|
||||
|
|
|
|||
|
|
@ -0,0 +1,221 @@
|
|||
|
||||
#ifndef COMMON_DEFORMABLE_BODY_SETUP_H
|
||||
#define COMMON_DEFORMABLE_BODY_SETUP_H
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h"
|
||||
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
|
||||
#include "BulletDynamics/Featherstone/btMultiBodyPoint2Point.h"
|
||||
#include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h"
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "CommonExampleInterface.h"
|
||||
#include "CommonGUIHelperInterface.h"
|
||||
#include "CommonRenderInterface.h"
|
||||
#include "CommonGraphicsAppInterface.h"
|
||||
#include "CommonWindowInterface.h"
|
||||
#include "CommonCameraInterface.h"
|
||||
#include "CommonMultiBodyBase.h"
|
||||
#include "BulletSoftBody/btSoftBody.h"
|
||||
|
||||
struct CommonDeformableBodyBase : public CommonMultiBodyBase
|
||||
{
|
||||
btAlignedObjectArray<btDeformableLagrangianForce*> m_forces;
|
||||
btSoftBody* m_pickedSoftBody;
|
||||
btDeformableMousePickingForce* m_mouseForce;
|
||||
btScalar m_pickingForceElasticStiffness, m_pickingForceDampingStiffness, m_maxPickingForce;
|
||||
CommonDeformableBodyBase(GUIHelperInterface* helper)
|
||||
: CommonMultiBodyBase(helper),
|
||||
m_pickedSoftBody(0),
|
||||
m_mouseForce(0),
|
||||
m_pickingForceElasticStiffness(100),
|
||||
m_pickingForceDampingStiffness(0.0),
|
||||
m_maxPickingForce(0.3)
|
||||
{
|
||||
}
|
||||
|
||||
virtual btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld()
|
||||
{
|
||||
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
|
||||
}
|
||||
|
||||
virtual const btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld() const
|
||||
{
|
||||
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
|
||||
}
|
||||
|
||||
struct ClosestRayResultCallbackWithInfo : public btCollisionWorld::ClosestRayResultCallback
|
||||
{
|
||||
ClosestRayResultCallbackWithInfo(const btVector3& rayFromWorld, const btVector3& rayToWorld)
|
||||
: ClosestRayResultCallback(rayFromWorld, rayToWorld)
|
||||
{
|
||||
}
|
||||
int m_faceId;
|
||||
|
||||
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace)
|
||||
{
|
||||
//caller already does the filter on the m_closestHitFraction
|
||||
btAssert(rayResult.m_hitFraction <= m_closestHitFraction);
|
||||
|
||||
m_closestHitFraction = rayResult.m_hitFraction;
|
||||
m_collisionObject = rayResult.m_collisionObject;
|
||||
if (rayResult.m_localShapeInfo)
|
||||
{
|
||||
m_faceId = rayResult.m_localShapeInfo->m_triangleIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_faceId = -1;
|
||||
}
|
||||
if (normalInWorldSpace)
|
||||
{
|
||||
m_hitNormalWorld = rayResult.m_hitNormalLocal;
|
||||
}
|
||||
else
|
||||
{
|
||||
///need to transform normal into worldspace
|
||||
m_hitNormalWorld = m_collisionObject->getWorldTransform().getBasis() * rayResult.m_hitNormalLocal;
|
||||
}
|
||||
m_hitPointWorld.setInterpolate3(m_rayFromWorld, m_rayToWorld, rayResult.m_hitFraction);
|
||||
return rayResult.m_hitFraction;
|
||||
}
|
||||
};
|
||||
|
||||
virtual bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)
|
||||
{
|
||||
if (getDeformableDynamicsWorld() == 0)
|
||||
return false;
|
||||
ClosestRayResultCallbackWithInfo rayCallback(rayFromWorld, rayToWorld);
|
||||
getDeformableDynamicsWorld()->rayTest(rayFromWorld, rayToWorld, rayCallback);
|
||||
if (rayCallback.hasHit())
|
||||
{
|
||||
btVector3 pickPos = rayCallback.m_hitPointWorld;
|
||||
btRigidBody* body = (btRigidBody*)btRigidBody::upcast(rayCallback.m_collisionObject);
|
||||
btSoftBody* psb = (btSoftBody*)btSoftBody::upcast(rayCallback.m_collisionObject);
|
||||
m_oldPickingPos = rayToWorld;
|
||||
m_hitPos = pickPos;
|
||||
m_oldPickingDist = (pickPos - rayFromWorld).length();
|
||||
if (body)
|
||||
{
|
||||
if (!(body->isStaticObject() || body->isKinematicObject()))
|
||||
{
|
||||
m_pickedBody = body;
|
||||
m_pickedBody->setActivationState(DISABLE_DEACTIVATION);
|
||||
btVector3 localPivot = body->getCenterOfMassTransform().inverse() * pickPos;
|
||||
btPoint2PointConstraint* p2p = new btPoint2PointConstraint(*body, localPivot);
|
||||
m_dynamicsWorld->addConstraint(p2p, true);
|
||||
m_pickedConstraint = p2p;
|
||||
btScalar mousePickClamping = 30.f;
|
||||
p2p->m_setting.m_impulseClamp = mousePickClamping;
|
||||
//very weak constraint for picking
|
||||
p2p->m_setting.m_tau = 0.001f;
|
||||
}
|
||||
}
|
||||
else if (psb)
|
||||
{
|
||||
int face_id = rayCallback.m_faceId;
|
||||
if (face_id >= 0 && face_id < psb->m_faces.size())
|
||||
{
|
||||
m_pickedSoftBody = psb;
|
||||
psb->setActivationState(DISABLE_DEACTIVATION);
|
||||
const btSoftBody::Face& f = psb->m_faces[face_id];
|
||||
btDeformableMousePickingForce* mouse_force = new btDeformableMousePickingForce(m_pickingForceElasticStiffness, m_pickingForceDampingStiffness, f, m_hitPos, m_maxPickingForce);
|
||||
m_mouseForce = mouse_force;
|
||||
getDeformableDynamicsWorld()->addForce(psb, mouse_force);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
btMultiBodyLinkCollider* multiCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(rayCallback.m_collisionObject);
|
||||
if (multiCol && multiCol->m_multiBody)
|
||||
{
|
||||
m_prevCanSleep = multiCol->m_multiBody->getCanSleep();
|
||||
multiCol->m_multiBody->setCanSleep(false);
|
||||
|
||||
btVector3 pivotInA = multiCol->m_multiBody->worldPosToLocal(multiCol->m_link, pickPos);
|
||||
|
||||
btMultiBodyPoint2Point* p2p = new btMultiBodyPoint2Point(multiCol->m_multiBody, multiCol->m_link, 0, pivotInA, pickPos);
|
||||
//if you add too much energy to the system, causing high angular velocities, simulation 'explodes'
|
||||
//see also http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=4&t=949
|
||||
//so we try to avoid it by clamping the maximum impulse (force) that the mouse pick can apply
|
||||
//it is not satisfying, hopefully we find a better solution (higher order integrator, using joint friction using a zero-velocity target motor with limited force etc?)
|
||||
btScalar scaling = 1;
|
||||
p2p->setMaxAppliedImpulse(2 * scaling);
|
||||
btMultiBodyDynamicsWorld* world = (btMultiBodyDynamicsWorld*)m_dynamicsWorld;
|
||||
world->addMultiBodyConstraint(p2p);
|
||||
m_pickingMultiBodyPoint2Point = p2p;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool movePickedBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)
|
||||
{
|
||||
if (m_pickedBody && m_pickedConstraint)
|
||||
{
|
||||
btPoint2PointConstraint* pickCon = static_cast<btPoint2PointConstraint*>(m_pickedConstraint);
|
||||
if (pickCon)
|
||||
{
|
||||
//keep it at the same picking distance
|
||||
btVector3 newPivotB;
|
||||
btVector3 dir = rayToWorld - rayFromWorld;
|
||||
dir.normalize();
|
||||
dir *= m_oldPickingDist;
|
||||
newPivotB = rayFromWorld + dir;
|
||||
pickCon->setPivotB(newPivotB);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (m_pickingMultiBodyPoint2Point)
|
||||
{
|
||||
//keep it at the same picking distance
|
||||
btVector3 dir = rayToWorld - rayFromWorld;
|
||||
dir.normalize();
|
||||
dir *= m_oldPickingDist;
|
||||
btVector3 newPivotB = rayFromWorld + dir;
|
||||
m_pickingMultiBodyPoint2Point->setPivotInB(newPivotB);
|
||||
}
|
||||
if (m_pickedSoftBody && m_mouseForce)
|
||||
{
|
||||
btVector3 newPivot;
|
||||
btVector3 dir = rayToWorld - rayFromWorld;
|
||||
dir.normalize();
|
||||
dir *= m_oldPickingDist;
|
||||
newPivot = rayFromWorld + dir;
|
||||
m_mouseForce->setMousePos(newPivot);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void removePickingConstraint()
|
||||
{
|
||||
if (m_pickedConstraint)
|
||||
{
|
||||
m_dynamicsWorld->removeConstraint(m_pickedConstraint);
|
||||
|
||||
if (m_pickedBody)
|
||||
{
|
||||
m_pickedBody->forceActivationState(ACTIVE_TAG);
|
||||
m_pickedBody->activate(true);
|
||||
}
|
||||
delete m_pickedConstraint;
|
||||
m_pickedConstraint = 0;
|
||||
m_pickedBody = 0;
|
||||
}
|
||||
if (m_pickingMultiBodyPoint2Point)
|
||||
{
|
||||
m_pickingMultiBodyPoint2Point->getMultiBodyA()->setCanSleep(m_prevCanSleep);
|
||||
btMultiBodyDynamicsWorld* world = (btMultiBodyDynamicsWorld*)m_dynamicsWorld;
|
||||
world->removeMultiBodyConstraint(m_pickingMultiBodyPoint2Point);
|
||||
delete m_pickingMultiBodyPoint2Point;
|
||||
m_pickingMultiBodyPoint2Point = 0;
|
||||
}
|
||||
if (m_pickedSoftBody)
|
||||
{
|
||||
getDeformableDynamicsWorld()->removeForce(m_pickedSoftBody, m_mouseForce);
|
||||
delete m_mouseForce;
|
||||
m_mouseForce = 0;
|
||||
m_pickedSoftBody = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif //COMMON_MULTI_BODY_SETUP_H
|
||||
|
|
@ -3,91 +3,94 @@
|
|||
#ifndef COMMON_EXAMPLE_INTERFACE_H
|
||||
#define COMMON_EXAMPLE_INTERFACE_H
|
||||
|
||||
struct CommandProcessorCreationInterface
|
||||
{
|
||||
virtual ~CommandProcessorCreationInterface() {}
|
||||
virtual class CommandProcessorInterface* createCommandProcessor() = 0;
|
||||
virtual void deleteCommandProcessor(CommandProcessorInterface*) = 0;
|
||||
};
|
||||
|
||||
struct CommonExampleOptions
|
||||
{
|
||||
struct GUIHelperInterface* m_guiHelper;
|
||||
struct GUIHelperInterface* m_guiHelper;
|
||||
|
||||
//Those are optional, some examples will use them others don't. Each example should work with them being 0.
|
||||
int m_option;
|
||||
int m_option;
|
||||
const char* m_fileName;
|
||||
class SharedMemoryInterface* m_sharedMem;
|
||||
CommandProcessorCreationInterface* m_commandProcessorCreation;
|
||||
bool m_skipGraphicsUpdate;
|
||||
|
||||
|
||||
CommonExampleOptions(struct GUIHelperInterface* helper, int option=0)
|
||||
:m_guiHelper(helper),
|
||||
m_option(option),
|
||||
m_fileName(0),
|
||||
m_sharedMem(0)
|
||||
CommonExampleOptions(struct GUIHelperInterface* helper, int option = 0)
|
||||
: m_guiHelper(helper),
|
||||
m_option(option),
|
||||
m_fileName(0),
|
||||
m_sharedMem(0),
|
||||
m_commandProcessorCreation(0),
|
||||
m_skipGraphicsUpdate(false)
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class CommonExampleInterface
|
||||
{
|
||||
public:
|
||||
|
||||
typedef class CommonExampleInterface* (CreateFunc)(CommonExampleOptions& options);
|
||||
typedef class CommonExampleInterface*(CreateFunc)(CommonExampleOptions& options);
|
||||
|
||||
virtual ~CommonExampleInterface()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
virtual void initPhysics()=0;
|
||||
virtual void exitPhysics()=0;
|
||||
virtual void stepSimulation(float deltaTime)=0;
|
||||
virtual void renderScene()=0;
|
||||
virtual void physicsDebugDraw(int debugFlags)=0;//for now we reuse the flags in Bullet/src/LinearMath/btIDebugDraw.h
|
||||
virtual void initPhysics() = 0;
|
||||
virtual void exitPhysics() = 0;
|
||||
virtual void updateGraphics() {}
|
||||
virtual void stepSimulation(float deltaTime) = 0;
|
||||
virtual void renderScene() = 0;
|
||||
virtual void physicsDebugDraw(int debugFlags) = 0; //for now we reuse the flags in Bullet/src/LinearMath/btIDebugDraw.h
|
||||
//reset camera is only called when switching demo. this way you can restart (initPhysics) and watch in a specific location easier
|
||||
virtual void resetCamera(){};
|
||||
virtual bool mouseMoveCallback(float x,float y)=0;
|
||||
virtual bool mouseButtonCallback(int button, int state, float x, float y)=0;
|
||||
virtual bool keyboardCallback(int key, int state)=0;
|
||||
virtual void resetCamera(){};
|
||||
virtual bool mouseMoveCallback(float x, float y) = 0;
|
||||
virtual bool mouseButtonCallback(int button, int state, float x, float y) = 0;
|
||||
virtual bool keyboardCallback(int key, int state) = 0;
|
||||
|
||||
virtual void vrControllerMoveCallback(int controllerId, float pos[4], float orientation[4], float analogAxis) {}
|
||||
virtual void vrControllerButtonCallback(int controllerId, int button, int state, float pos[4], float orientation[4]){}
|
||||
virtual void vrControllerMoveCallback(int controllerId, float pos[4], float orientation[4], float analogAxis, float auxAnalogAxes[10]) {}
|
||||
virtual void vrControllerButtonCallback(int controllerId, int button, int state, float pos[4], float orientation[4]) {}
|
||||
virtual void vrHMDMoveCallback(int controllerId, float pos[4], float orientation[4]) {}
|
||||
virtual void vrGenericTrackerMoveCallback(int controllerId, float pos[4], float orientation[4]) {}
|
||||
|
||||
virtual void processCommandLineArgs(int argc, char* argv[]){};
|
||||
virtual void processCommandLineArgs(int argc, char* argv[]){};
|
||||
};
|
||||
|
||||
class ExampleEntries
|
||||
{
|
||||
|
||||
public:
|
||||
virtual ~ExampleEntries() {}
|
||||
|
||||
virtual ~ExampleEntries() {}
|
||||
virtual void initExampleEntries() = 0;
|
||||
|
||||
virtual void initOpenCLExampleEntries() = 0;
|
||||
|
||||
virtual void initExampleEntries()=0;
|
||||
virtual int getNumRegisteredExamples() = 0;
|
||||
|
||||
virtual void initOpenCLExampleEntries()=0;
|
||||
virtual CommonExampleInterface::CreateFunc* getExampleCreateFunc(int index) = 0;
|
||||
|
||||
virtual int getNumRegisteredExamples()=0;
|
||||
virtual const char* getExampleName(int index) = 0;
|
||||
|
||||
virtual CommonExampleInterface::CreateFunc* getExampleCreateFunc(int index)=0;
|
||||
|
||||
virtual const char* getExampleName(int index)=0;
|
||||
|
||||
virtual const char* getExampleDescription(int index)=0;
|
||||
|
||||
virtual int getExampleOption(int index)=0;
|
||||
virtual const char* getExampleDescription(int index) = 0;
|
||||
|
||||
virtual int getExampleOption(int index) = 0;
|
||||
};
|
||||
|
||||
|
||||
CommonExampleInterface* StandaloneExampleCreateFunc(CommonExampleOptions& options);
|
||||
|
||||
#ifdef B3_USE_STANDALONE_EXAMPLE
|
||||
#define B3_STANDALONE_EXAMPLE(ExampleFunc) CommonExampleInterface* StandaloneExampleCreateFunc(CommonExampleOptions& options)\
|
||||
{\
|
||||
return ExampleFunc(options);\
|
||||
#define B3_STANDALONE_EXAMPLE(ExampleFunc) \
|
||||
CommonExampleInterface* StandaloneExampleCreateFunc(CommonExampleOptions& options) \
|
||||
{ \
|
||||
return ExampleFunc(options); \
|
||||
}
|
||||
#else//B3_USE_STANDALONE_EXAMPLE
|
||||
#define B3_STANDALONE_EXAMPLE(ExampleFunc)
|
||||
#endif //B3_USE_STANDALONE_EXAMPLE
|
||||
#else //B3_USE_STANDALONE_EXAMPLE
|
||||
#define B3_STANDALONE_EXAMPLE(ExampleFunc)
|
||||
#endif //B3_USE_STANDALONE_EXAMPLE
|
||||
|
||||
|
||||
|
||||
#endif //COMMON_EXAMPLE_INTERFACE_H
|
||||
#endif //COMMON_EXAMPLE_INTERFACE_H
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef COMMON_FILE_IO_INTERFACE_H
|
||||
#define COMMON_FILE_IO_INTERFACE_H
|
||||
|
||||
struct CommonFileIOInterface
|
||||
{
|
||||
int m_fileIOType;
|
||||
const char* m_pathPrefix;
|
||||
|
||||
CommonFileIOInterface(int fileIOType, const char* pathPrefix)
|
||||
:m_fileIOType(fileIOType),
|
||||
m_pathPrefix(pathPrefix)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~CommonFileIOInterface()
|
||||
{
|
||||
}
|
||||
virtual int fileOpen(const char* fileName, const char* mode)=0;
|
||||
virtual int fileRead(int fileHandle, char* destBuffer, int numBytes)=0;
|
||||
virtual int fileWrite(int fileHandle,const char* sourceBuffer, int numBytes)=0;
|
||||
virtual void fileClose(int fileHandle)=0;
|
||||
virtual bool findResourcePath(const char* fileName, char* resourcePathOut, int resourcePathMaxNumBytes)=0;
|
||||
virtual char* readLine(int fileHandle, char* destBuffer, int numBytes)=0;
|
||||
virtual int getFileSize(int fileHandle)=0;
|
||||
virtual void enableFileCaching(bool enable) = 0;
|
||||
};
|
||||
|
||||
#endif //COMMON_FILE_IO_INTERFACE_H
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
#ifndef GUI_HELPER_INTERFACE_H
|
||||
#define GUI_HELPER_INTERFACE_H
|
||||
|
||||
|
||||
class btRigidBody;
|
||||
class btVector3;
|
||||
class btCollisionObject;
|
||||
|
|
@ -12,94 +10,159 @@ struct CommonParameterInterface;
|
|||
struct CommonRenderInterface;
|
||||
struct CommonGraphicsApp;
|
||||
|
||||
struct GUISyncPosition
|
||||
{
|
||||
int m_graphicsInstanceId;
|
||||
float m_pos[4];
|
||||
float m_orn[4];
|
||||
};
|
||||
|
||||
typedef void (*VisualizerFlagCallback)(int flag, bool enable);
|
||||
|
||||
///The Bullet 2 GraphicsPhysicsBridge let's the graphics engine create graphics representation and synchronize
|
||||
struct GUIHelperInterface
|
||||
{
|
||||
virtual ~GUIHelperInterface() {}
|
||||
|
||||
virtual void createRigidBodyGraphicsObject(btRigidBody* body,const btVector3& color) = 0;
|
||||
virtual void createRigidBodyGraphicsObject(btRigidBody* body, const btVector3& color) = 0;
|
||||
|
||||
virtual void createCollisionObjectGraphicsObject(btCollisionObject* obj,const btVector3& color) = 0;
|
||||
virtual void createCollisionObjectGraphicsObject(btCollisionObject* obj, const btVector3& color) = 0;
|
||||
|
||||
virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape)=0;
|
||||
virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape) = 0;
|
||||
|
||||
virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld)=0;
|
||||
|
||||
virtual void render(const btDiscreteDynamicsWorld* rbWorld)=0;
|
||||
|
||||
virtual void createPhysicsDebugDrawer( btDiscreteDynamicsWorld* rbWorld)=0;
|
||||
|
||||
virtual int registerTexture(const unsigned char* texels, int width, int height)=0;
|
||||
virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices,int primitiveType, int textureId) = 0;
|
||||
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) =0;
|
||||
virtual void removeAllGraphicsInstances()=0;
|
||||
virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld) = 0;
|
||||
virtual void syncPhysicsToGraphics2(const btDiscreteDynamicsWorld* rbWorld) {}
|
||||
virtual void syncPhysicsToGraphics2(const GUISyncPosition* positions, int numPositions) {}
|
||||
|
||||
virtual Common2dCanvasInterface* get2dCanvasInterface()=0;
|
||||
virtual void render(const btDiscreteDynamicsWorld* rbWorld) = 0;
|
||||
|
||||
virtual void createPhysicsDebugDrawer(btDiscreteDynamicsWorld* rbWorld) = 0;
|
||||
|
||||
virtual int registerTexture(const unsigned char* texels, int width, int height) = 0;
|
||||
virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices, int primitiveType, int textureId) = 0;
|
||||
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) = 0;
|
||||
virtual void removeAllGraphicsInstances() = 0;
|
||||
virtual void removeGraphicsInstance(int graphicsUid) {}
|
||||
virtual void changeInstanceFlags(int instanceUid, int flags) {}
|
||||
virtual void changeRGBAColor(int instanceUid, const double rgbaColor[4]) {}
|
||||
virtual void changeScaling(int instanceUid, const double scaling[3]) {}
|
||||
virtual void changeSpecularColor(int instanceUid, const double specularColor[3]) {}
|
||||
virtual void changeTexture(int textureUniqueId, const unsigned char* rgbTexels, int width, int height) {}
|
||||
virtual void updateShape(int shapeIndex, float* vertices, int numVertices) {}
|
||||
virtual int getShapeIndexFromInstance(int instanceUid) { return -1; }
|
||||
virtual void replaceTexture(int shapeIndex, int textureUid) {}
|
||||
virtual void removeTexture(int textureUid) {}
|
||||
virtual void setBackgroundColor(const double rgbBackground[3]) {}
|
||||
|
||||
virtual CommonParameterInterface* getParameterInterface()=0;
|
||||
|
||||
virtual CommonRenderInterface* getRenderInterface()=0;
|
||||
virtual Common2dCanvasInterface* get2dCanvasInterface() = 0;
|
||||
|
||||
virtual CommonGraphicsApp* getAppInterface()=0;
|
||||
virtual CommonParameterInterface* getParameterInterface() = 0;
|
||||
|
||||
virtual void setUpAxis(int axis)=0;
|
||||
virtual CommonRenderInterface* getRenderInterface() = 0;
|
||||
|
||||
virtual void resetCamera(float camDist, float pitch, float yaw, float camPosX,float camPosY, float camPosZ)=0;
|
||||
virtual const CommonRenderInterface* getRenderInterface() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual CommonGraphicsApp* getAppInterface() = 0;
|
||||
|
||||
virtual void setUpAxis(int axis) = 0;
|
||||
|
||||
virtual void resetCamera(float camDist, float yaw, float pitch, float camPosX, float camPosY, float camPosZ) = 0;
|
||||
|
||||
virtual bool getCameraInfo(int* width, int* height, float viewMatrix[16], float projectionMatrix[16], float camUp[3], float camForward[3], float hor[3], float vert[3], float* yaw, float* pitch, float* camDist, float camTarget[3]) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void setVisualizerFlag(int flag, int enable){};
|
||||
|
||||
virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
|
||||
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
|
||||
float* depthBuffer, int depthBufferSizeInPixels,
|
||||
int startPixelIndex, int destinationWidth, int destinationHeight, int* numPixelsCopied)
|
||||
{
|
||||
copyCameraImageData(viewMatrix, projectionMatrix, pixelsRGBA, rgbaBufferSizeInPixels,
|
||||
depthBuffer, depthBufferSizeInPixels,
|
||||
0, 0,
|
||||
startPixelIndex, destinationWidth,
|
||||
destinationHeight, numPixelsCopied);
|
||||
}
|
||||
|
||||
virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
|
||||
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
|
||||
float* depthBuffer, int depthBufferSizeInPixels,
|
||||
int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels,
|
||||
int startPixelIndex, int destinationWidth, int destinationHeight, int* numPixelsCopied) = 0;
|
||||
virtual void debugDisplayCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
|
||||
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
|
||||
float* depthBuffer, int depthBufferSizeInPixels,
|
||||
int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels,
|
||||
int startPixelIndex, int destinationWidth, int destinationHeight, int* numPixelsCopied) {}
|
||||
|
||||
virtual void setProjectiveTextureMatrices(const float viewMatrix[16], const float projectionMatrix[16]) {}
|
||||
virtual void setProjectiveTexture(bool useProjectiveTexture) {}
|
||||
|
||||
virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld) = 0;
|
||||
|
||||
virtual void drawText3D(const char* txt, float posX, float posY, float posZ, float size) {}
|
||||
virtual void drawText3D(const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag) {}
|
||||
|
||||
virtual int addUserDebugText3D(const char* txt, const double positionXYZ[3], const double orientation[4], const double textColorRGB[3], double size, double lifeTime, int trackingVisualShapeIndex, int optionFlags, int replaceItemUid) { return -1; }
|
||||
virtual int addUserDebugLine(const double debugLineFromXYZ[3], const double debugLineToXYZ[3], const double debugLineColorRGB[3], double lineWidth, double lifeTime, int trackingVisualShapeIndex, int replaceItemUid) { return -1; };
|
||||
virtual int addUserDebugPoints(const double debugPointPositionXYZ[], const double debugPointColorRGB[3], double pointSize, double lifeTime, int trackingVisualShapeIndex, int replaceItemUid, int debugPointNum) { return -1; };
|
||||
virtual int addUserDebugParameter(const char* txt, double rangeMin, double rangeMax, double startValue) { return -1; };
|
||||
virtual int readUserDebugParameter(int itemUniqueId, double* value) { return 0; }
|
||||
|
||||
virtual void removeUserDebugItem(int debugItemUniqueId){};
|
||||
virtual void removeAllUserDebugItems(){};
|
||||
virtual void removeAllUserParameters() {};
|
||||
|
||||
virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
|
||||
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
|
||||
float* depthBuffer, int depthBufferSizeInPixels,
|
||||
int startPixelIndex, int destinationWidth, int destinationHeight, int* numPixelsCopied)
|
||||
{
|
||||
copyCameraImageData(viewMatrix,projectionMatrix,pixelsRGBA,rgbaBufferSizeInPixels,
|
||||
depthBuffer,depthBufferSizeInPixels,
|
||||
0,0,
|
||||
startPixelIndex,destinationWidth,
|
||||
destinationHeight,numPixelsCopied);
|
||||
}
|
||||
|
||||
virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
|
||||
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
|
||||
float* depthBuffer, int depthBufferSizeInPixels,
|
||||
int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels,
|
||||
int startPixelIndex, int destinationWidth, int destinationHeight, int* numPixelsCopied)=0;
|
||||
|
||||
virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld) =0;
|
||||
|
||||
virtual void drawText3D( const char* txt, float posX, float posZY, float posZ, float size)=0;
|
||||
|
||||
virtual void setVisualizerFlagCallback(VisualizerFlagCallback callback) {}
|
||||
|
||||
//empty name stops dumping video
|
||||
virtual void dumpFramesToVideo(const char* mp4FileName){};
|
||||
virtual void drawDebugDrawerLines(){}
|
||||
virtual void clearLines(){}
|
||||
virtual bool isRemoteVisualizer() { return false; }
|
||||
};
|
||||
|
||||
|
||||
///the DummyGUIHelper does nothing, so we can test the examples without GUI/graphics (in 'console mode')
|
||||
struct DummyGUIHelper : public GUIHelperInterface
|
||||
{
|
||||
DummyGUIHelper() {}
|
||||
DummyGUIHelper()
|
||||
{
|
||||
|
||||
}
|
||||
virtual ~DummyGUIHelper() {}
|
||||
|
||||
virtual void createRigidBodyGraphicsObject(btRigidBody* body,const btVector3& color){}
|
||||
virtual void createRigidBodyGraphicsObject(btRigidBody* body, const btVector3& color) {}
|
||||
|
||||
virtual void createCollisionObjectGraphicsObject(btCollisionObject* obj,const btVector3& color) {}
|
||||
virtual void createCollisionObjectGraphicsObject(btCollisionObject* obj, const btVector3& color) {}
|
||||
|
||||
virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape){}
|
||||
virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape) {}
|
||||
|
||||
virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld){}
|
||||
virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld) {}
|
||||
|
||||
virtual void render(const btDiscreteDynamicsWorld* rbWorld) {}
|
||||
|
||||
virtual void createPhysicsDebugDrawer( btDiscreteDynamicsWorld* rbWorld){}
|
||||
virtual void createPhysicsDebugDrawer(btDiscreteDynamicsWorld* rbWorld) {}
|
||||
|
||||
virtual int registerTexture(const unsigned char* texels, int width, int height) { return -1; }
|
||||
virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices, int primitiveType, int textureId) { return -1; }
|
||||
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) { return -1; }
|
||||
virtual void removeAllGraphicsInstances() {}
|
||||
virtual void removeGraphicsInstance(int graphicsUid) {}
|
||||
virtual void changeRGBAColor(int instanceUid, const double rgbaColor[4]) {}
|
||||
virtual void changeScaling(int instanceUid, const double scaling[3]) {}
|
||||
|
||||
virtual int registerTexture(const unsigned char* texels, int width, int height){return -1;}
|
||||
virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices,int primitiveType, int textureId){return -1;}
|
||||
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) {return -1;}
|
||||
virtual void removeAllGraphicsInstances(){}
|
||||
|
||||
virtual Common2dCanvasInterface* get2dCanvasInterface()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
virtual CommonParameterInterface* getParameterInterface()
|
||||
{
|
||||
return 0;
|
||||
|
|
@ -109,40 +172,64 @@ struct DummyGUIHelper : public GUIHelperInterface
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
virtual CommonGraphicsApp* getAppInterface()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
virtual void setUpAxis(int axis)
|
||||
{
|
||||
}
|
||||
virtual void resetCamera(float camDist, float pitch, float yaw, float camPosX,float camPosY, float camPosZ)
|
||||
virtual void resetCamera(float camDist, float yaw, float pitch, float camPosX, float camPosY, float camPosZ)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
|
||||
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
|
||||
float* depthBuffer, int depthBufferSizeInPixels,
|
||||
int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels,
|
||||
int startPixelIndex, int width, int height, int* numPixelsCopied)
|
||||
|
||||
virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
|
||||
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
|
||||
float* depthBuffer, int depthBufferSizeInPixels,
|
||||
int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels,
|
||||
int startPixelIndex, int width, int height, int* numPixelsCopied)
|
||||
|
||||
{
|
||||
if (numPixelsCopied)
|
||||
*numPixelsCopied = 0;
|
||||
if (numPixelsCopied)
|
||||
*numPixelsCopied = 0;
|
||||
}
|
||||
|
||||
virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld)
|
||||
virtual void setProjectiveTextureMatrices(const float viewMatrix[16], const float projectionMatrix[16])
|
||||
{
|
||||
}
|
||||
|
||||
virtual void drawText3D( const char* txt, float posX, float posZY, float posZ, float size)
|
||||
|
||||
virtual void setProjectiveTexture(bool useProjectiveTexture)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void drawText3D(const char* txt, float posX, float posZY, float posZ, float size)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void drawText3D(const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag)
|
||||
{
|
||||
}
|
||||
|
||||
virtual int addUserDebugLine(const double debugLineFromXYZ[3], const double debugLineToXYZ[3], const double debugLineColorRGB[3], double lineWidth, double lifeTime, int trackingVisualShapeIndex, int replaceItemUid)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
virtual int addUserDebugPoints(const double debugPointPositionXYZ[3], const double debugPointColorRGB[3], double pointSize, double lifeTime, int trackingVisualShapeIndex, int replaceItemUid, int debugPointNum)
|
||||
{
|
||||
return -1;
|
||||
};
|
||||
virtual void removeUserDebugItem(int debugItemUniqueId)
|
||||
{
|
||||
}
|
||||
virtual void removeAllUserDebugItems()
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif //GUI_HELPER_INTERFACE_H
|
||||
|
||||
#endif //GUI_HELPER_INTERFACE_H
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
#ifndef COMMON_GRAPHICS_APP_H
|
||||
#define COMMON_GRAPHICS_APP_H
|
||||
|
||||
|
||||
|
||||
#include "Bullet3Common/b3Vector3.h"
|
||||
#include "CommonRenderInterface.h"
|
||||
#include "CommonWindowInterface.h"
|
||||
|
|
@ -10,26 +8,26 @@
|
|||
|
||||
struct DrawGridData
|
||||
{
|
||||
int gridSize;
|
||||
float upOffset;
|
||||
int upAxis;
|
||||
float gridColor[4];
|
||||
int gridSize;
|
||||
float upOffset;
|
||||
int upAxis;
|
||||
float gridColor[4];
|
||||
|
||||
DrawGridData(int upAxis=1)
|
||||
:gridSize(10),
|
||||
upOffset(0.001f),
|
||||
upAxis(upAxis)
|
||||
{
|
||||
gridColor[0] = 0.6f;
|
||||
gridColor[1] = 0.6f;
|
||||
gridColor[2] = 0.6f;
|
||||
gridColor[3] = 1.f;
|
||||
}
|
||||
DrawGridData(int upAx = 1)
|
||||
: gridSize(10),
|
||||
upOffset(0.001f),
|
||||
upAxis(upAx)
|
||||
{
|
||||
gridColor[0] = 0.6f;
|
||||
gridColor[1] = 0.6f;
|
||||
gridColor[2] = 0.6f;
|
||||
gridColor[3] = 1.f;
|
||||
}
|
||||
};
|
||||
|
||||
enum EnumSphereLevelOfDetail
|
||||
{
|
||||
SPHERE_LOD_POINT_SPRITE=0,
|
||||
SPHERE_LOD_POINT_SPRITE = 0,
|
||||
SPHERE_LOD_LOW,
|
||||
SPHERE_LOD_MEDIUM,
|
||||
SPHERE_LOD_HIGH,
|
||||
|
|
@ -37,23 +35,29 @@ enum EnumSphereLevelOfDetail
|
|||
};
|
||||
struct CommonGraphicsApp
|
||||
{
|
||||
class CommonWindowInterface* m_window;
|
||||
struct CommonRenderInterface* m_renderer;
|
||||
struct CommonParameterInterface* m_parameterInterface;
|
||||
struct Common2dCanvasInterface* m_2dCanvasInterface;
|
||||
enum drawText3DOption
|
||||
{
|
||||
eDrawText3D_OrtogonalFaceCamera = 1,
|
||||
eDrawText3D_TrueType = 2,
|
||||
eDrawText3D_TrackObject = 4,
|
||||
};
|
||||
class CommonWindowInterface* m_window;
|
||||
struct CommonRenderInterface* m_renderer;
|
||||
struct CommonParameterInterface* m_parameterInterface;
|
||||
struct Common2dCanvasInterface* m_2dCanvasInterface;
|
||||
|
||||
bool m_leftMouseButton;
|
||||
bool m_middleMouseButton;
|
||||
bool m_rightMouseButton;
|
||||
bool m_leftMouseButton;
|
||||
bool m_middleMouseButton;
|
||||
bool m_rightMouseButton;
|
||||
float m_wheelMultiplier;
|
||||
float m_mouseMoveMultiplier;
|
||||
float m_mouseXpos;
|
||||
float m_mouseYpos;
|
||||
bool m_mouseInitialized;
|
||||
float m_backgroundColorRGB[3];
|
||||
float m_mouseXpos;
|
||||
float m_mouseYpos;
|
||||
bool m_mouseInitialized;
|
||||
float m_backgroundColorRGB[3];
|
||||
|
||||
CommonGraphicsApp()
|
||||
:m_window(0),
|
||||
: m_window(0),
|
||||
m_renderer(0),
|
||||
m_parameterInterface(0),
|
||||
m_2dCanvasInterface(0),
|
||||
|
|
@ -74,11 +78,12 @@ struct CommonGraphicsApp
|
|||
{
|
||||
}
|
||||
|
||||
virtual void dumpNextFrameToPng(const char* pngFilename){}
|
||||
virtual void dumpFramesToVideo(const char* mp4Filename){}
|
||||
|
||||
virtual void getScreenPixels(unsigned char* rgbaBuffer, int bufferSizeInBytes, float* depthBuffer, int depthBufferSizeInBytes){}
|
||||
|
||||
virtual void dumpNextFrameToPng(const char* pngFilename) {}
|
||||
virtual void dumpFramesToVideo(const char* mp4Filename) {}
|
||||
|
||||
virtual void getScreenPixels(unsigned char* rgbaBuffer, int bufferSizeInBytes, float* depthBuffer, int depthBufferSizeInBytes) {}
|
||||
virtual void setViewport(int width, int height) {}
|
||||
|
||||
virtual void getBackgroundColor(float* red, float* green, float* blue) const
|
||||
{
|
||||
if (red)
|
||||
|
|
@ -88,6 +93,7 @@ struct CommonGraphicsApp
|
|||
if (blue)
|
||||
*blue = m_backgroundColorRGB[2];
|
||||
}
|
||||
virtual void setMp4Fps(int fps) {}
|
||||
virtual void setBackgroundColor(float red, float green, float blue)
|
||||
{
|
||||
m_backgroundColorRGB[0] = red;
|
||||
|
|
@ -107,177 +113,175 @@ struct CommonGraphicsApp
|
|||
{
|
||||
m_mouseMoveMultiplier = mult;
|
||||
}
|
||||
|
||||
|
||||
virtual float getMouseMoveMultiplier() const
|
||||
{
|
||||
return m_mouseMoveMultiplier;
|
||||
}
|
||||
|
||||
|
||||
|
||||
virtual void drawGrid(DrawGridData data=DrawGridData()) = 0;
|
||||
virtual void drawGrid(DrawGridData data = DrawGridData()) = 0;
|
||||
virtual void setUpAxis(int axis) = 0;
|
||||
virtual int getUpAxis() const = 0;
|
||||
|
||||
|
||||
virtual void swapBuffer() = 0;
|
||||
virtual void drawText( const char* txt, int posX, int posY) = 0;
|
||||
virtual void drawText3D( const char* txt, float posX, float posZY, float posZ, float size)=0;
|
||||
virtual void drawTexturedRect(float x0, float y0, float x1, float y1, float color[4], float u0,float v0, float u1, float v1, int useRGBA)=0;
|
||||
virtual int registerCubeShape(float halfExtentsX,float halfExtentsY, float halfExtentsZ, int textureIndex = -1, float textureScaling = 1)=0;
|
||||
virtual int registerGraphicsUnitSphereShape(EnumSphereLevelOfDetail lod, int textureId=-1) = 0;
|
||||
|
||||
|
||||
virtual void registerGrid(int xres, int yres, float color0[4], float color1[4])=0;
|
||||
|
||||
void defaultMouseButtonCallback( int button, int state, float x, float y)
|
||||
virtual void drawText(const char* txt, int posX, int posY)
|
||||
{
|
||||
if (button==0)
|
||||
m_leftMouseButton= (state==1);
|
||||
if (button==1)
|
||||
m_middleMouseButton= (state==1);
|
||||
float size = 1;
|
||||
float colorRGBA[4] = { 0, 0, 0, 1 };
|
||||
drawText(txt, posX, posY, size, colorRGBA);
|
||||
}
|
||||
|
||||
if (button==2)
|
||||
m_rightMouseButton= (state==1);
|
||||
virtual void drawText(const char* txt, int posX, int posY, float size)
|
||||
{
|
||||
float colorRGBA[4] = { 0, 0, 0, 1 };
|
||||
drawText(txt, posX, posY, size, colorRGBA);
|
||||
}
|
||||
virtual void drawText(const char* txt, int posX, int posY, float size, float colorRGBA[4]) = 0;
|
||||
virtual void drawText3D(const char* txt, float posX, float posY, float posZ, float size) = 0;
|
||||
virtual void drawText3D(const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag) = 0;
|
||||
virtual void drawTexturedRect(float x0, float y0, float x1, float y1, float color[4], float u0, float v0, float u1, float v1, int useRGBA) = 0;
|
||||
virtual int registerCubeShape(float halfExtentsX, float halfExtentsY, float halfExtentsZ, int textureIndex = -1, float textureScaling = 1) = 0;
|
||||
virtual int registerGraphicsUnitSphereShape(EnumSphereLevelOfDetail lod, int textureId = -1) = 0;
|
||||
|
||||
virtual void registerGrid(int xres, int yres, float color0[4], float color1[4]) = 0;
|
||||
|
||||
void defaultMouseButtonCallback(int button, int state, float x, float y)
|
||||
{
|
||||
if (button == 0)
|
||||
m_leftMouseButton = (state == 1);
|
||||
if (button == 1)
|
||||
m_middleMouseButton = (state == 1);
|
||||
|
||||
if (button == 2)
|
||||
m_rightMouseButton = (state == 1);
|
||||
|
||||
m_mouseXpos = x;
|
||||
m_mouseYpos = y;
|
||||
m_mouseInitialized = true;
|
||||
}
|
||||
void defaultMouseMoveCallback( float x, float y)
|
||||
void defaultMouseMoveCallback(float x, float y)
|
||||
{
|
||||
|
||||
if (m_window && m_renderer)
|
||||
{
|
||||
CommonCameraInterface* camera = m_renderer->getActiveCamera();
|
||||
|
||||
bool isAltPressed = m_window->isModifierKeyPressed(B3G_ALT);
|
||||
bool isControlPressed = m_window->isModifierKeyPressed(B3G_CONTROL);
|
||||
|
||||
|
||||
|
||||
if (isAltPressed || isControlPressed)
|
||||
{
|
||||
float xDelta = x-m_mouseXpos;
|
||||
float yDelta = y-m_mouseYpos;
|
||||
float xDelta = x - m_mouseXpos;
|
||||
float yDelta = y - m_mouseYpos;
|
||||
float cameraDistance = camera->getCameraDistance();
|
||||
float pitch = camera->getCameraPitch();
|
||||
float yaw = camera->getCameraYaw();
|
||||
|
||||
float targPos[3];
|
||||
float camPos[3];
|
||||
float camPos[3];
|
||||
|
||||
camera->getCameraTargetPosition(targPos);
|
||||
camera->getCameraPosition(camPos);
|
||||
|
||||
b3Vector3 cameraPosition = b3MakeVector3(b3Scalar(camPos[0]),
|
||||
b3Scalar(camPos[1]),
|
||||
b3Scalar(camPos[2]));
|
||||
|
||||
b3Vector3 cameraTargetPosition = b3MakeVector3( b3Scalar(targPos[0]),
|
||||
b3Scalar(targPos[1]),
|
||||
b3Scalar(targPos[2]));
|
||||
b3Vector3 cameraUp = b3MakeVector3(0,0,0);
|
||||
b3Vector3 cameraPosition = b3MakeVector3(b3Scalar(camPos[0]),
|
||||
b3Scalar(camPos[1]),
|
||||
b3Scalar(camPos[2]));
|
||||
|
||||
b3Vector3 cameraTargetPosition = b3MakeVector3(b3Scalar(targPos[0]),
|
||||
b3Scalar(targPos[1]),
|
||||
b3Scalar(targPos[2]));
|
||||
b3Vector3 cameraUp = b3MakeVector3(0, 0, 0);
|
||||
cameraUp[camera->getCameraUpAxis()] = 1.f;
|
||||
|
||||
|
||||
if (m_leftMouseButton)
|
||||
{
|
||||
// if (b3Fabs(xDelta)>b3Fabs(yDelta))
|
||||
// {
|
||||
pitch -= xDelta*m_mouseMoveMultiplier;
|
||||
// } else
|
||||
// {
|
||||
yaw += yDelta*m_mouseMoveMultiplier;
|
||||
// }
|
||||
// if (b3Fabs(xDelta)>b3Fabs(yDelta))
|
||||
// {
|
||||
pitch -= yDelta * m_mouseMoveMultiplier;
|
||||
// } else
|
||||
// {
|
||||
yaw -= xDelta * m_mouseMoveMultiplier;
|
||||
// }
|
||||
}
|
||||
|
||||
if (m_middleMouseButton)
|
||||
{
|
||||
cameraTargetPosition += cameraUp * yDelta*0.01;
|
||||
cameraTargetPosition += cameraUp * yDelta *m_mouseMoveMultiplier* 0.01;
|
||||
|
||||
|
||||
b3Vector3 fwd = cameraTargetPosition-cameraPosition;
|
||||
b3Vector3 fwd = cameraTargetPosition - cameraPosition;
|
||||
b3Vector3 side = cameraUp.cross(fwd);
|
||||
side.normalize();
|
||||
cameraTargetPosition += side * xDelta*0.01;
|
||||
|
||||
cameraTargetPosition += side * xDelta *m_mouseMoveMultiplier* 0.01;
|
||||
}
|
||||
if (m_rightMouseButton)
|
||||
{
|
||||
cameraDistance -= xDelta*0.01f;
|
||||
cameraDistance -= yDelta*0.01f;
|
||||
if (cameraDistance<1)
|
||||
cameraDistance=1;
|
||||
if (cameraDistance>1000)
|
||||
cameraDistance=1000;
|
||||
cameraDistance -= xDelta * m_mouseMoveMultiplier*0.01f;
|
||||
cameraDistance -= yDelta * m_mouseMoveMultiplier*0.01f;
|
||||
if (cameraDistance < 1)
|
||||
cameraDistance = 1;
|
||||
if (cameraDistance > 1000)
|
||||
cameraDistance = 1000;
|
||||
}
|
||||
camera->setCameraDistance(cameraDistance);
|
||||
camera->setCameraPitch(pitch);
|
||||
camera->setCameraYaw(yaw);
|
||||
camera->setCameraTargetPosition(cameraTargetPosition[0],cameraTargetPosition[1],cameraTargetPosition[2]);
|
||||
|
||||
}
|
||||
camera->setCameraTargetPosition(cameraTargetPosition[0], cameraTargetPosition[1], cameraTargetPosition[2]);
|
||||
}
|
||||
|
||||
} //m_window && m_renderer
|
||||
|
||||
}//m_window && m_renderer
|
||||
|
||||
m_mouseXpos = x;
|
||||
m_mouseYpos = y;
|
||||
m_mouseInitialized = true;
|
||||
}
|
||||
// void defaultKeyboardCallback(int key, int state)
|
||||
// {
|
||||
// }
|
||||
void defaultWheelCallback( float deltax, float deltay)
|
||||
// void defaultKeyboardCallback(int key, int state)
|
||||
// {
|
||||
// }
|
||||
void defaultWheelCallback(float deltax, float deltay)
|
||||
{
|
||||
|
||||
if (m_renderer)
|
||||
{
|
||||
b3Vector3 cameraTargetPosition, cameraPosition, cameraUp = b3MakeVector3(0,0,0);
|
||||
b3Vector3 cameraTargetPosition, cameraPosition, cameraUp = b3MakeVector3(0, 0, 0);
|
||||
cameraUp[getUpAxis()] = 1;
|
||||
CommonCameraInterface* camera = m_renderer->getActiveCamera();
|
||||
|
||||
|
||||
camera->getCameraPosition(cameraPosition);
|
||||
camera->getCameraTargetPosition(cameraTargetPosition);
|
||||
|
||||
|
||||
if (!m_leftMouseButton)
|
||||
{
|
||||
|
||||
float cameraDistance = camera->getCameraDistance();
|
||||
if (deltay<0 || cameraDistance>1)
|
||||
float cameraDistance = camera->getCameraDistance();
|
||||
if (deltay < 0 || cameraDistance > 1)
|
||||
{
|
||||
cameraDistance -= deltay*0.01f;
|
||||
if (cameraDistance<1)
|
||||
cameraDistance=1;
|
||||
cameraDistance -= deltay*m_wheelMultiplier;
|
||||
if (cameraDistance < 1)
|
||||
cameraDistance = 1;
|
||||
camera->setCameraDistance(cameraDistance);
|
||||
|
||||
} else
|
||||
{
|
||||
|
||||
b3Vector3 fwd = cameraTargetPosition-cameraPosition;
|
||||
fwd.normalize();
|
||||
cameraTargetPosition += fwd*deltay*m_wheelMultiplier;//todo: expose it in the GUI?
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (b3Fabs(deltax)>b3Fabs(deltay))
|
||||
else
|
||||
{
|
||||
b3Vector3 fwd = cameraTargetPosition-cameraPosition;
|
||||
b3Vector3 fwd = cameraTargetPosition - cameraPosition;
|
||||
fwd.normalize();
|
||||
cameraTargetPosition += fwd * deltay * m_wheelMultiplier; //todo: expose it in the GUI?
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (b3Fabs(deltax) > b3Fabs(deltay))
|
||||
{
|
||||
b3Vector3 fwd = cameraTargetPosition - cameraPosition;
|
||||
b3Vector3 side = cameraUp.cross(fwd);
|
||||
side.normalize();
|
||||
cameraTargetPosition += side * deltax*m_wheelMultiplier;
|
||||
|
||||
} else
|
||||
cameraTargetPosition += side * deltax * m_wheelMultiplier;
|
||||
}
|
||||
else
|
||||
{
|
||||
cameraTargetPosition -= cameraUp * deltay*m_wheelMultiplier;
|
||||
|
||||
cameraTargetPosition -= cameraUp * deltay * m_wheelMultiplier;
|
||||
}
|
||||
}
|
||||
|
||||
camera->setCameraTargetPosition(cameraTargetPosition[0],cameraTargetPosition[1],cameraTargetPosition[2]);
|
||||
camera->setCameraTargetPosition(cameraTargetPosition[0], cameraTargetPosition[1], cameraTargetPosition[2]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //COMMON_GRAPHICS_APP_H
|
||||
#endif //COMMON_GRAPHICS_APP_H
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
#ifndef COMMON_MULTI_BODY_SETUP_H
|
||||
#define COMMON_MULTI_BODY_SETUP_H
|
||||
|
||||
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
|
||||
#include "BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h"
|
||||
|
|
@ -18,20 +17,60 @@
|
|||
#include "CommonWindowInterface.h"
|
||||
#include "CommonCameraInterface.h"
|
||||
|
||||
enum MyFilterModes
|
||||
{
|
||||
FILTER_GROUPAMASKB_AND_GROUPBMASKA2 = 0,
|
||||
FILTER_GROUPAMASKB_OR_GROUPBMASKA2
|
||||
};
|
||||
|
||||
struct MyOverlapFilterCallback2 : public btOverlapFilterCallback
|
||||
{
|
||||
int m_filterMode;
|
||||
|
||||
MyOverlapFilterCallback2()
|
||||
: m_filterMode(FILTER_GROUPAMASKB_AND_GROUPBMASKA2)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~MyOverlapFilterCallback2()
|
||||
{
|
||||
}
|
||||
// return true when pairs need collision
|
||||
virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) const
|
||||
{
|
||||
if (m_filterMode == FILTER_GROUPAMASKB_AND_GROUPBMASKA2)
|
||||
{
|
||||
bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
|
||||
collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
|
||||
return collides;
|
||||
}
|
||||
|
||||
if (m_filterMode == FILTER_GROUPAMASKB_OR_GROUPBMASKA2)
|
||||
{
|
||||
bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
|
||||
collides = collides || (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
|
||||
return collides;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
struct CommonMultiBodyBase : public CommonExampleInterface
|
||||
{
|
||||
//keep the collision shapes, for deletion/cleanup
|
||||
btAlignedObjectArray<btCollisionShape*> m_collisionShapes;
|
||||
btBroadphaseInterface* m_broadphase;
|
||||
btCollisionDispatcher* m_dispatcher;
|
||||
btMultiBodyConstraintSolver* m_solver;
|
||||
//keep the collision shapes, for deletion/cleanup
|
||||
btAlignedObjectArray<btCollisionShape*> m_collisionShapes;
|
||||
MyOverlapFilterCallback2* m_filterCallback;
|
||||
btOverlappingPairCache* m_pairCache;
|
||||
btBroadphaseInterface* m_broadphase;
|
||||
btCollisionDispatcher* m_dispatcher;
|
||||
btMultiBodyConstraintSolver* m_solver;
|
||||
btDefaultCollisionConfiguration* m_collisionConfiguration;
|
||||
btMultiBodyDynamicsWorld* m_dynamicsWorld;
|
||||
|
||||
//data for picking objects
|
||||
class btRigidBody* m_pickedBody;
|
||||
class btRigidBody* m_pickedBody;
|
||||
class btTypedConstraint* m_pickedConstraint;
|
||||
class btMultiBodyPoint2Point* m_pickingMultiBodyPoint2Point;
|
||||
class btMultiBodyPoint2Point* m_pickingMultiBodyPoint2Point;
|
||||
|
||||
btVector3 m_oldPickingPos;
|
||||
btVector3 m_hitPos;
|
||||
|
|
@ -41,16 +80,18 @@ struct CommonMultiBodyBase : public CommonExampleInterface
|
|||
struct GUIHelperInterface* m_guiHelper;
|
||||
|
||||
CommonMultiBodyBase(GUIHelperInterface* helper)
|
||||
:m_broadphase(0),
|
||||
m_dispatcher(0),
|
||||
m_solver(0),
|
||||
m_collisionConfiguration(0),
|
||||
m_dynamicsWorld(0),
|
||||
m_pickedBody(0),
|
||||
m_pickedConstraint(0),
|
||||
m_pickingMultiBodyPoint2Point(0),
|
||||
m_prevCanSleep(false),
|
||||
m_guiHelper(helper)
|
||||
: m_filterCallback(0),
|
||||
m_pairCache(0),
|
||||
m_broadphase(0),
|
||||
m_dispatcher(0),
|
||||
m_solver(0),
|
||||
m_collisionConfiguration(0),
|
||||
m_dynamicsWorld(0),
|
||||
m_pickedBody(0),
|
||||
m_pickedConstraint(0),
|
||||
m_pickingMultiBodyPoint2Point(0),
|
||||
m_prevCanSleep(false),
|
||||
m_guiHelper(helper)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -59,11 +100,16 @@ struct CommonMultiBodyBase : public CommonExampleInterface
|
|||
///collision configuration contains default setup for memory, collision setup
|
||||
m_collisionConfiguration = new btDefaultCollisionConfiguration();
|
||||
//m_collisionConfiguration->setConvexConvexMultipointIterations();
|
||||
m_filterCallback = new MyOverlapFilterCallback2();
|
||||
|
||||
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
|
||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
||||
|
||||
m_broadphase = new btDbvtBroadphase();//btSimpleBroadphase();
|
||||
m_pairCache = new btHashedOverlappingPairCache();
|
||||
|
||||
m_pairCache->setOverlapFilterCallback(m_filterCallback);
|
||||
|
||||
m_broadphase = new btDbvtBroadphase(m_pairCache); //btSimpleBroadphase();
|
||||
|
||||
m_solver = new btMultiBodyConstraintSolver;
|
||||
|
||||
|
|
@ -72,7 +118,6 @@ struct CommonMultiBodyBase : public CommonExampleInterface
|
|||
m_dynamicsWorld->setGravity(btVector3(0, -10, 0));
|
||||
}
|
||||
|
||||
|
||||
virtual void stepSimulation(float deltaTime)
|
||||
{
|
||||
if (m_dynamicsWorld)
|
||||
|
|
@ -81,7 +126,6 @@ struct CommonMultiBodyBase : public CommonExampleInterface
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
virtual void exitPhysics()
|
||||
{
|
||||
removePickingConstraint();
|
||||
|
|
@ -91,13 +135,12 @@ struct CommonMultiBodyBase : public CommonExampleInterface
|
|||
|
||||
if (m_dynamicsWorld)
|
||||
{
|
||||
int i;
|
||||
for (i = m_dynamicsWorld->getNumConstraints() - 1; i >= 0; i--)
|
||||
{
|
||||
m_dynamicsWorld->removeConstraint(m_dynamicsWorld->getConstraint(i));
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = m_dynamicsWorld->getNumConstraints() - 1; i >= 0; i--)
|
||||
{
|
||||
m_dynamicsWorld->removeConstraint(m_dynamicsWorld->getConstraint(i));
|
||||
}
|
||||
|
||||
for (i = m_dynamicsWorld->getNumMultiBodyConstraints() - 1; i >= 0; i--)
|
||||
{
|
||||
btMultiBodyConstraint* mbc = m_dynamicsWorld->getMultiBodyConstraint(i);
|
||||
|
|
@ -124,7 +167,7 @@ struct CommonMultiBodyBase : public CommonExampleInterface
|
|||
}
|
||||
}
|
||||
//delete collision shapes
|
||||
for (int j = 0; j<m_collisionShapes.size(); j++)
|
||||
for (int j = 0; j < m_collisionShapes.size(); j++)
|
||||
{
|
||||
btCollisionShape* shape = m_collisionShapes[j];
|
||||
delete shape;
|
||||
|
|
@ -135,16 +178,22 @@ struct CommonMultiBodyBase : public CommonExampleInterface
|
|||
m_dynamicsWorld = 0;
|
||||
|
||||
delete m_solver;
|
||||
m_solver=0;
|
||||
m_solver = 0;
|
||||
|
||||
delete m_broadphase;
|
||||
m_broadphase=0;
|
||||
m_broadphase = 0;
|
||||
|
||||
delete m_dispatcher;
|
||||
m_dispatcher=0;
|
||||
m_dispatcher = 0;
|
||||
|
||||
delete m_pairCache;
|
||||
m_pairCache = 0;
|
||||
|
||||
delete m_filterCallback;
|
||||
m_filterCallback = 0;
|
||||
|
||||
delete m_collisionConfiguration;
|
||||
m_collisionConfiguration=0;
|
||||
m_collisionConfiguration = 0;
|
||||
}
|
||||
|
||||
virtual void syncPhysicsToGraphics()
|
||||
|
|
@ -157,63 +206,72 @@ struct CommonMultiBodyBase : public CommonExampleInterface
|
|||
|
||||
virtual void renderScene()
|
||||
{
|
||||
if (m_dynamicsWorld)
|
||||
{
|
||||
m_guiHelper->syncPhysicsToGraphics(m_dynamicsWorld);
|
||||
if (m_dynamicsWorld)
|
||||
{
|
||||
m_guiHelper->syncPhysicsToGraphics(m_dynamicsWorld);
|
||||
|
||||
m_guiHelper->render(m_dynamicsWorld);
|
||||
}
|
||||
|
||||
m_guiHelper->render(m_dynamicsWorld);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void physicsDebugDraw(int debugDrawFlags)
|
||||
{
|
||||
if (m_dynamicsWorld)
|
||||
{
|
||||
virtual void physicsDebugDraw(int debugDrawFlags)
|
||||
{
|
||||
if (m_dynamicsWorld)
|
||||
{
|
||||
if (m_dynamicsWorld->getDebugDrawer())
|
||||
{
|
||||
m_dynamicsWorld->getDebugDrawer()->setDebugMode(debugDrawFlags);
|
||||
}
|
||||
m_dynamicsWorld->debugDrawWorld();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
virtual bool keyboardCallback(int key, int state)
|
||||
{
|
||||
return false;//don't handle this key
|
||||
m_dynamicsWorld->debugDrawWorld();
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool keyboardCallback(int key, int state)
|
||||
{
|
||||
if ((key == B3G_F3) && state && m_dynamicsWorld)
|
||||
{
|
||||
btDefaultSerializer* serializer = new btDefaultSerializer();
|
||||
m_dynamicsWorld->serialize(serializer);
|
||||
|
||||
btVector3 getRayTo(int x,int y)
|
||||
FILE* file = fopen("testFile.bullet", "wb");
|
||||
fwrite(serializer->getBufferPointer(), serializer->getCurrentBufferSize(), 1, file);
|
||||
fclose(file);
|
||||
//b3Printf("btDefaultSerializer wrote testFile.bullet");
|
||||
delete serializer;
|
||||
return true;
|
||||
}
|
||||
return false; //don't handle this key
|
||||
}
|
||||
|
||||
btVector3 getRayTo(int x, int y)
|
||||
{
|
||||
CommonRenderInterface* renderer = m_guiHelper->getRenderInterface();
|
||||
|
||||
|
||||
if (!renderer)
|
||||
{
|
||||
btAssert(0);
|
||||
return btVector3(0,0,0);
|
||||
return btVector3(0, 0, 0);
|
||||
}
|
||||
|
||||
float top = 1.f;
|
||||
float bottom = -1.f;
|
||||
float nearPlane = 1.f;
|
||||
float tanFov = (top-bottom)*0.5f / nearPlane;
|
||||
float tanFov = (top - bottom) * 0.5f / nearPlane;
|
||||
float fov = btScalar(2.0) * btAtan(tanFov);
|
||||
|
||||
btVector3 camPos,camTarget;
|
||||
btVector3 camPos, camTarget;
|
||||
renderer->getActiveCamera()->getCameraPosition(camPos);
|
||||
renderer->getActiveCamera()->getCameraTargetPosition(camTarget);
|
||||
|
||||
btVector3 rayFrom = camPos;
|
||||
btVector3 rayForward = (camTarget-camPos);
|
||||
btVector3 rayFrom = camPos;
|
||||
btVector3 rayForward = (camTarget - camPos);
|
||||
rayForward.normalize();
|
||||
float farPlane = 10000.f;
|
||||
rayForward*= farPlane;
|
||||
rayForward *= farPlane;
|
||||
|
||||
btVector3 rightOffset;
|
||||
btVector3 cameraUp=btVector3(0,0,0);
|
||||
cameraUp[m_guiHelper->getAppInterface()->getUpAxis()]=1;
|
||||
btVector3 cameraUp = btVector3(0, 0, 0);
|
||||
cameraUp[m_guiHelper->getAppInterface()->getUpAxis()] = 1;
|
||||
|
||||
btVector3 vertical = cameraUp;
|
||||
|
||||
|
|
@ -223,25 +281,22 @@ struct CommonMultiBodyBase : public CommonExampleInterface
|
|||
vertical = hor.cross(rayForward);
|
||||
vertical.normalize();
|
||||
|
||||
float tanfov = tanf(0.5f*fov);
|
||||
|
||||
float tanfov = tanf(0.5f * fov);
|
||||
|
||||
hor *= 2.f * farPlane * tanfov;
|
||||
vertical *= 2.f * farPlane * tanfov;
|
||||
|
||||
btScalar aspect;
|
||||
float width = float(renderer->getScreenWidth());
|
||||
float height = float (renderer->getScreenHeight());
|
||||
float height = float(renderer->getScreenHeight());
|
||||
|
||||
aspect = width / height;
|
||||
|
||||
hor*=aspect;
|
||||
aspect = width / height;
|
||||
|
||||
hor *= aspect;
|
||||
|
||||
btVector3 rayToCenter = rayFrom + rayForward;
|
||||
btVector3 dHor = hor * 1.f/width;
|
||||
btVector3 dVert = vertical * 1.f/height;
|
||||
|
||||
btVector3 dHor = hor * 1.f / width;
|
||||
btVector3 dVert = vertical * 1.f / height;
|
||||
|
||||
btVector3 rayTo = rayToCenter - 0.5f * hor + 0.5f * vertical;
|
||||
rayTo += btScalar(x) * dHor;
|
||||
|
|
@ -249,10 +304,10 @@ struct CommonMultiBodyBase : public CommonExampleInterface
|
|||
return rayTo;
|
||||
}
|
||||
|
||||
virtual bool mouseMoveCallback(float x,float y)
|
||||
virtual bool mouseMoveCallback(float x, float y)
|
||||
{
|
||||
CommonRenderInterface* renderer = m_guiHelper->getRenderInterface();
|
||||
|
||||
|
||||
if (!renderer)
|
||||
{
|
||||
btAssert(0);
|
||||
|
|
@ -262,41 +317,39 @@ struct CommonMultiBodyBase : public CommonExampleInterface
|
|||
btVector3 rayTo = getRayTo(int(x), int(y));
|
||||
btVector3 rayFrom;
|
||||
renderer->getActiveCamera()->getCameraPosition(rayFrom);
|
||||
movePickedBody(rayFrom,rayTo);
|
||||
movePickedBody(rayFrom, rayTo);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool mouseButtonCallback(int button, int state, float x, float y)
|
||||
virtual bool mouseButtonCallback(int button, int state, float x, float y)
|
||||
{
|
||||
CommonRenderInterface* renderer = m_guiHelper->getRenderInterface();
|
||||
|
||||
|
||||
if (!renderer)
|
||||
{
|
||||
btAssert(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
CommonWindowInterface* window = m_guiHelper->getAppInterface()->m_window;
|
||||
|
||||
|
||||
if (state==1)
|
||||
if (state == 1)
|
||||
{
|
||||
if(button==0 && (!window->isModifierKeyPressed(B3G_ALT) && !window->isModifierKeyPressed(B3G_CONTROL) ))
|
||||
if (button == 0 && (!window->isModifierKeyPressed(B3G_ALT) && !window->isModifierKeyPressed(B3G_CONTROL)))
|
||||
{
|
||||
btVector3 camPos;
|
||||
renderer->getActiveCamera()->getCameraPosition(camPos);
|
||||
|
||||
btVector3 rayFrom = camPos;
|
||||
btVector3 rayTo = getRayTo(int(x),int(y));
|
||||
btVector3 rayTo = getRayTo(int(x), int(y));
|
||||
|
||||
pickBody(rayFrom, rayTo);
|
||||
|
||||
|
||||
}
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
if (button==0)
|
||||
if (button == 0)
|
||||
{
|
||||
removePickingConstraint();
|
||||
//remove p2p
|
||||
|
|
@ -307,10 +360,9 @@ struct CommonMultiBodyBase : public CommonExampleInterface
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
virtual bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)
|
||||
{
|
||||
if (m_dynamicsWorld==0)
|
||||
if (m_dynamicsWorld == 0)
|
||||
return false;
|
||||
|
||||
btCollisionWorld::ClosestRayResultCallback rayCallback(rayFromWorld, rayToWorld);
|
||||
|
|
@ -318,7 +370,6 @@ struct CommonMultiBodyBase : public CommonExampleInterface
|
|||
m_dynamicsWorld->rayTest(rayFromWorld, rayToWorld, rayCallback);
|
||||
if (rayCallback.hasHit())
|
||||
{
|
||||
|
||||
btVector3 pickPos = rayCallback.m_hitPointWorld;
|
||||
btRigidBody* body = (btRigidBody*)btRigidBody::upcast(rayCallback.m_collisionObject);
|
||||
if (body)
|
||||
|
|
@ -338,33 +389,31 @@ struct CommonMultiBodyBase : public CommonExampleInterface
|
|||
//very weak constraint for picking
|
||||
p2p->m_setting.m_tau = 0.001f;
|
||||
}
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
btMultiBodyLinkCollider* multiCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(rayCallback.m_collisionObject);
|
||||
if (multiCol && multiCol->m_multiBody)
|
||||
{
|
||||
|
||||
m_prevCanSleep = multiCol->m_multiBody->getCanSleep();
|
||||
multiCol->m_multiBody->setCanSleep(false);
|
||||
|
||||
btVector3 pivotInA = multiCol->m_multiBody->worldPosToLocal(multiCol->m_link, pickPos);
|
||||
|
||||
btMultiBodyPoint2Point* p2p = new btMultiBodyPoint2Point(multiCol->m_multiBody,multiCol->m_link,0,pivotInA,pickPos);
|
||||
btMultiBodyPoint2Point* p2p = new btMultiBodyPoint2Point(multiCol->m_multiBody, multiCol->m_link, 0, pivotInA, pickPos);
|
||||
//if you add too much energy to the system, causing high angular velocities, simulation 'explodes'
|
||||
//see also http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=4&t=949
|
||||
//so we try to avoid it by clamping the maximum impulse (force) that the mouse pick can apply
|
||||
//it is not satisfying, hopefully we find a better solution (higher order integrator, using joint friction using a zero-velocity target motor with limited force etc?)
|
||||
btScalar scaling=1;
|
||||
p2p->setMaxAppliedImpulse(2*scaling);
|
||||
|
||||
btMultiBodyDynamicsWorld* world = (btMultiBodyDynamicsWorld*) m_dynamicsWorld;
|
||||
btScalar scaling = 1;
|
||||
p2p->setMaxAppliedImpulse(2 * scaling);
|
||||
|
||||
btMultiBodyDynamicsWorld* world = (btMultiBodyDynamicsWorld*)m_dynamicsWorld;
|
||||
world->addMultiBodyConstraint(p2p);
|
||||
m_pickingMultiBodyPoint2Point =p2p;
|
||||
m_pickingMultiBodyPoint2Point = p2p;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// pickObject(pickPos, rayCallback.m_collisionObject);
|
||||
m_oldPickingPos = rayToWorld;
|
||||
m_hitPos = pickPos;
|
||||
|
|
@ -376,14 +425,14 @@ struct CommonMultiBodyBase : public CommonExampleInterface
|
|||
}
|
||||
virtual bool movePickedBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)
|
||||
{
|
||||
if (m_pickedBody && m_pickedConstraint)
|
||||
if (m_pickedBody && m_pickedConstraint)
|
||||
{
|
||||
btPoint2PointConstraint* pickCon = static_cast<btPoint2PointConstraint*>(m_pickedConstraint);
|
||||
if (pickCon)
|
||||
{
|
||||
//keep it at the same picking distance
|
||||
|
||||
btVector3 dir = rayToWorld-rayFromWorld;
|
||||
|
||||
btVector3 dir = rayToWorld - rayFromWorld;
|
||||
dir.normalize();
|
||||
dir *= m_oldPickingDist;
|
||||
|
||||
|
|
@ -391,28 +440,34 @@ struct CommonMultiBodyBase : public CommonExampleInterface
|
|||
pickCon->setPivotB(newPivotB);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (m_pickingMultiBodyPoint2Point)
|
||||
{
|
||||
//keep it at the same picking distance
|
||||
|
||||
|
||||
btVector3 dir = rayToWorld-rayFromWorld;
|
||||
btVector3 dir = rayToWorld - rayFromWorld;
|
||||
dir.normalize();
|
||||
dir *= m_oldPickingDist;
|
||||
|
||||
btVector3 newPivotB = rayFromWorld + dir;
|
||||
|
||||
|
||||
m_pickingMultiBodyPoint2Point->setPivotInB(newPivotB);
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void removePickingConstraint()
|
||||
{
|
||||
if (m_pickedConstraint)
|
||||
{
|
||||
m_dynamicsWorld->removeConstraint(m_pickedConstraint);
|
||||
|
||||
if (m_pickedBody)
|
||||
{
|
||||
m_pickedBody->forceActivationState(ACTIVE_TAG);
|
||||
m_pickedBody->activate(true);
|
||||
}
|
||||
delete m_pickedConstraint;
|
||||
m_pickedConstraint = 0;
|
||||
m_pickedBody = 0;
|
||||
|
|
@ -420,22 +475,20 @@ struct CommonMultiBodyBase : public CommonExampleInterface
|
|||
if (m_pickingMultiBodyPoint2Point)
|
||||
{
|
||||
m_pickingMultiBodyPoint2Point->getMultiBodyA()->setCanSleep(m_prevCanSleep);
|
||||
btMultiBodyDynamicsWorld* world = (btMultiBodyDynamicsWorld*) m_dynamicsWorld;
|
||||
btMultiBodyDynamicsWorld* world = (btMultiBodyDynamicsWorld*)m_dynamicsWorld;
|
||||
world->removeMultiBodyConstraint(m_pickingMultiBodyPoint2Point);
|
||||
delete m_pickingMultiBodyPoint2Point;
|
||||
m_pickingMultiBodyPoint2Point = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
btBoxShape* createBoxShape(const btVector3& halfExtents)
|
||||
{
|
||||
btBoxShape* box = new btBoxShape(halfExtents);
|
||||
return box;
|
||||
}
|
||||
|
||||
btRigidBody* createRigidBody(float mass, const btTransform& startTransform, btCollisionShape* shape, const btVector4& color = btVector4(1, 0, 0, 1))
|
||||
btRigidBody* createRigidBody(float mass, const btTransform& startTransform, btCollisionShape* shape, const btVector4& color = btVector4(1, 0, 0, 1))
|
||||
{
|
||||
btAssert((!shape || shape->getShapeType() != INVALID_SHAPE_PROXYTYPE));
|
||||
|
||||
|
|
@ -446,7 +499,7 @@ struct CommonMultiBodyBase : public CommonExampleInterface
|
|||
if (isDynamic)
|
||||
shape->calculateLocalInertia(mass, localInertia);
|
||||
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
|
||||
#define USE_MOTIONSTATE 1
|
||||
#ifdef USE_MOTIONSTATE
|
||||
|
|
@ -460,7 +513,7 @@ struct CommonMultiBodyBase : public CommonExampleInterface
|
|||
#else
|
||||
btRigidBody* body = new btRigidBody(mass, 0, shape, localInertia);
|
||||
body->setWorldTransform(startTransform);
|
||||
#endif//
|
||||
#endif //
|
||||
|
||||
body->setUserIndex(-1);
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
|
|
@ -468,5 +521,4 @@ struct CommonMultiBodyBase : public CommonExampleInterface
|
|||
}
|
||||
};
|
||||
|
||||
#endif //COMMON_MULTI_BODY_SETUP_H
|
||||
|
||||
#endif //COMMON_MULTI_BODY_SETUP_H
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
typedef void (*SliderParamChangedCallback) (float newVal);
|
||||
typedef void (*SliderParamChangedCallback)(float newVal, void* userPointer);
|
||||
#include "LinearMath/btScalar.h"
|
||||
|
||||
struct SliderParams
|
||||
|
|
@ -16,39 +16,42 @@ struct SliderParams
|
|||
btScalar* m_paramValuePointer;
|
||||
void* m_userPointer;
|
||||
bool m_clampToNotches;
|
||||
bool m_showValues;
|
||||
|
||||
bool m_clampToIntegers;
|
||||
bool m_showValues;
|
||||
|
||||
SliderParams(const char* name, btScalar* targetValuePointer)
|
||||
:m_name(name),
|
||||
m_minVal(-100),
|
||||
m_maxVal(100),
|
||||
m_callback(0),
|
||||
m_paramValuePointer(targetValuePointer),
|
||||
m_userPointer(0),
|
||||
m_clampToNotches(true),
|
||||
m_showValues(true)
|
||||
: m_name(name),
|
||||
m_minVal(-100),
|
||||
m_maxVal(100),
|
||||
m_callback(0),
|
||||
m_paramValuePointer(targetValuePointer),
|
||||
m_userPointer(0),
|
||||
m_clampToNotches(false),
|
||||
m_clampToIntegers(false),
|
||||
m_showValues(true)
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
typedef void (*ButtonParamChangedCallback) (int buttonId, bool buttonState, void* userPointer);
|
||||
typedef void (*ComboBoxCallback) (int combobox, const char* item, void* userPointer);
|
||||
typedef void (*ButtonParamChangedCallback)(int buttonId, bool buttonState, void* userPointer);
|
||||
typedef void (*ComboBoxCallback)(int combobox, const char* item, void* userPointer);
|
||||
|
||||
struct ButtonParams
|
||||
{
|
||||
const char* m_name;
|
||||
int m_buttonId;
|
||||
void* m_userPointer;
|
||||
bool m_isTrigger;
|
||||
bool m_isTrigger;
|
||||
bool m_initialState;
|
||||
|
||||
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)
|
||||
: m_name(name),
|
||||
m_buttonId(buttonId),
|
||||
m_userPointer(0),
|
||||
m_isTrigger(isTrigger),
|
||||
m_initialState(false),
|
||||
m_callback(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
|
@ -60,32 +63,29 @@ struct ComboBoxParams
|
|||
const char** m_items;
|
||||
int m_startItem;
|
||||
ComboBoxCallback m_callback;
|
||||
void* m_userPointer;
|
||||
void* m_userPointer;
|
||||
|
||||
ComboBoxParams()
|
||||
:m_comboboxId(-1),
|
||||
m_numItems(0),
|
||||
m_items(0),
|
||||
m_startItem(0),
|
||||
m_callback(0),
|
||||
m_userPointer(0)
|
||||
: m_comboboxId(-1),
|
||||
m_numItems(0),
|
||||
m_items(0),
|
||||
m_startItem(0),
|
||||
m_callback(0),
|
||||
m_userPointer(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct CommonParameterInterface
|
||||
{
|
||||
|
||||
virtual ~CommonParameterInterface() {}
|
||||
virtual void registerSliderFloatParameter(SliderParams& params)=0;
|
||||
virtual void registerButtonParameter(ButtonParams& params)=0;
|
||||
virtual void registerComboBox(ComboBoxParams& params)=0;
|
||||
|
||||
virtual void syncParameters()=0;
|
||||
virtual void removeAllParameters()=0;
|
||||
virtual void setSliderValue(int sliderIndex, double sliderValue)=0;
|
||||
virtual void registerSliderFloatParameter(SliderParams& params) = 0;
|
||||
virtual void registerButtonParameter(ButtonParams& params) = 0;
|
||||
virtual void registerComboBox(ComboBoxParams& params) = 0;
|
||||
|
||||
virtual void syncParameters() = 0;
|
||||
virtual void removeAllParameters() = 0;
|
||||
virtual void setSliderValue(int sliderIndex, double sliderValue) = 0;
|
||||
};
|
||||
|
||||
#endif //PARAM_INTERFACE_H
|
||||
|
||||
#endif //PARAM_INTERFACE_H
|
||||
|
|
|
|||
|
|
@ -9,93 +9,145 @@ enum
|
|||
B3_GL_POINTS
|
||||
};
|
||||
|
||||
enum
|
||||
enum
|
||||
{
|
||||
B3_DEFAULT_RENDERMODE=1,
|
||||
B3_INSTANCE_TRANSPARANCY = 1,
|
||||
B3_INSTANCE_TEXTURE = 2,
|
||||
B3_INSTANCE_DOUBLE_SIDED = 4,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
B3_DEFAULT_RENDERMODE = 1,
|
||||
//B3_WIREFRAME_RENDERMODE,
|
||||
B3_CREATE_SHADOWMAP_RENDERMODE,
|
||||
B3_USE_SHADOWMAP_RENDERMODE,
|
||||
B3_USE_SHADOWMAP_RENDERMODE_REFLECTION,
|
||||
B3_USE_SHADOWMAP_RENDERMODE_REFLECTION_PLANE,
|
||||
B3_USE_PROJECTIVE_TEXTURE_RENDERMODE,
|
||||
B3_SEGMENTATION_MASK_RENDERMODE,
|
||||
};
|
||||
|
||||
struct GfxVertexFormat0
|
||||
{
|
||||
float x, y, z, w;
|
||||
float unused0, unused1, unused2, unused3;
|
||||
float u, v;
|
||||
};
|
||||
|
||||
struct GfxVertexFormat1
|
||||
{
|
||||
float x, y, z, w;
|
||||
float nx, ny, nz;
|
||||
float u, v;
|
||||
};
|
||||
|
||||
struct CommonRenderInterface
|
||||
{
|
||||
virtual void init()=0;
|
||||
virtual void updateCamera(int upAxis)=0;
|
||||
virtual ~CommonRenderInterface() {}
|
||||
virtual void init() = 0;
|
||||
virtual void updateCamera(int upAxis) = 0;
|
||||
virtual void removeAllInstances() = 0;
|
||||
|
||||
virtual const CommonCameraInterface* getActiveCamera() const =0;
|
||||
virtual CommonCameraInterface* getActiveCamera()=0;
|
||||
virtual void setActiveCamera(CommonCameraInterface* cam)=0;
|
||||
|
||||
virtual void removeGraphicsInstance(int instanceUid) = 0;
|
||||
|
||||
virtual void renderScene()=0;
|
||||
virtual void renderSceneInternal(int renderMode=B3_DEFAULT_RENDERMODE){};
|
||||
virtual const CommonCameraInterface* getActiveCamera() const = 0;
|
||||
virtual CommonCameraInterface* getActiveCamera() = 0;
|
||||
virtual void setActiveCamera(CommonCameraInterface* cam) = 0;
|
||||
|
||||
virtual void setLightPosition(const float lightPos[3]) = 0;
|
||||
virtual void setLightPosition(const double lightPos[3]) = 0;
|
||||
virtual void setBackgroundColor(const double rgbBackground[3]) = 0;
|
||||
|
||||
virtual void setShadowMapResolution(int shadowMapResolution) = 0;
|
||||
virtual void setShadowMapIntensity(double shadowMapIntensity) = 0;
|
||||
|
||||
virtual void setShadowMapWorldSize(float worldSize) = 0;
|
||||
|
||||
virtual void setProjectiveTextureMatrices(const float viewMatrix[16], const float projectionMatrix[16]){};
|
||||
virtual void setProjectiveTexture(bool useProjectiveTexture){};
|
||||
|
||||
virtual void renderScene() = 0;
|
||||
virtual void renderSceneInternal(int renderMode = B3_DEFAULT_RENDERMODE){};
|
||||
virtual int getScreenWidth() = 0;
|
||||
virtual int getScreenHeight() = 0;
|
||||
|
||||
virtual void resize(int width, int height) = 0;
|
||||
virtual void resize(int width, int height) = 0;
|
||||
|
||||
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling)=0;
|
||||
virtual int registerGraphicsInstance(int shapeIndex, const double* position, const double* quaternion, const double* color, const double* scaling)=0;
|
||||
virtual void drawLines(const float* positions, const float color[4], int numPoints, int pointStrideInBytes, const unsigned int* indices, int numIndices, float pointDrawSize)=0;
|
||||
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) = 0;
|
||||
virtual int registerGraphicsInstance(int shapeIndex, const double* position, const double* quaternion, const double* color, const double* scaling) = 0;
|
||||
virtual void drawLines(const float* positions, const float color[4], int numPoints, int pointStrideInBytes, const unsigned int* indices, int numIndices, float pointDrawSize) = 0;
|
||||
virtual void drawLine(const float from[4], const float to[4], const float color[4], float lineWidth) = 0;
|
||||
virtual void drawLine(const double from[4], const double to[4], const double color[4], double lineWidth) = 0;
|
||||
virtual void drawPoint(const float* position, const float color[4], float pointDrawSize)=0;
|
||||
virtual void drawPoint(const double* position, const double color[4], double pointDrawSize)=0;
|
||||
virtual int registerShape(const float* vertices, int numvertices, const int* indices, int numIndices,int primitiveType=B3_GL_TRIANGLES, int textureIndex=-1)=0;
|
||||
virtual void updateShape(int shapeIndex, const float* vertices)=0;
|
||||
|
||||
virtual int registerTexture(const unsigned char* texels, int width, int height)=0;
|
||||
virtual void updateTexture(int textureIndex, const unsigned char* texels)=0;
|
||||
virtual void activateTexture(int textureIndex)=0;
|
||||
|
||||
virtual void writeSingleInstanceTransformToCPU(const float* position, const float* orientation, int srcIndex)=0;
|
||||
virtual void writeSingleInstanceTransformToCPU(const double* position, const double* orientation, int srcIndex)=0;
|
||||
virtual void writeSingleInstanceColorToCPU(float* color, int srcIndex)=0;
|
||||
virtual void writeSingleInstanceColorToCPU(double* color, int srcIndex)=0;
|
||||
virtual void writeSingleInstanceScaleToCPU(float* scale, int srcIndex)=0;
|
||||
virtual void writeSingleInstanceScaleToCPU(double* scale, int srcIndex)=0;
|
||||
|
||||
virtual int getTotalNumInstances() const = 0;
|
||||
|
||||
virtual void writeTransforms()=0;
|
||||
virtual void enableBlend(bool blend)=0;
|
||||
virtual void clearZBuffer()=0;
|
||||
virtual void drawPoint(const float* position, const float color[4], float pointDrawSize) = 0;
|
||||
virtual void drawPoint(const double* position, const double color[4], double pointDrawSize) = 0;
|
||||
virtual void drawPoints(const float* positions, const float* colors, int numPoints, int pointStrideInBytes, float pointDrawSize) = 0;
|
||||
virtual void drawTexturedTriangleMesh(float worldPosition[3], float worldOrientation[4], const float* vertices, int numvertices, const unsigned int* indices, int numIndices, float color[4], int textureIndex = -1, int vertexLayout = 0) = 0;
|
||||
|
||||
virtual int registerShape(const float* vertices, int numvertices, const int* indices, int numIndices, int primitiveType = B3_GL_TRIANGLES, int textureIndex = -1) = 0;
|
||||
virtual void updateShape(int shapeIndex, const float* vertices, int numVertices) = 0;
|
||||
|
||||
virtual int registerTexture(const unsigned char* texels, int width, int height, bool flipPixelsY = true) = 0;
|
||||
virtual void updateTexture(int textureIndex, const unsigned char* texels, bool flipPixelsY = true) = 0;
|
||||
virtual void activateTexture(int textureIndex) = 0;
|
||||
virtual void replaceTexture(int shapeIndex, int textureIndex){};
|
||||
virtual void removeTexture(int textureIndex) = 0;
|
||||
|
||||
virtual void setPlaneReflectionShapeIndex(int index) {}
|
||||
|
||||
virtual int getShapeIndexFromInstance(int srcIndex) { return -1; }
|
||||
|
||||
virtual bool readSingleInstanceTransformToCPU(float* position, float* orientation, int srcIndex) = 0;
|
||||
|
||||
virtual void writeSingleInstanceTransformToCPU(const float* position, const float* orientation, int srcIndex) = 0;
|
||||
virtual void writeSingleInstanceTransformToCPU(const double* position, const double* orientation, int srcIndex) = 0;
|
||||
virtual void writeSingleInstanceColorToCPU(const float* color, int srcIndex) = 0;
|
||||
virtual void writeSingleInstanceColorToCPU(const double* color, int srcIndex) = 0;
|
||||
virtual void writeSingleInstanceScaleToCPU(const float* scale, int srcIndex) = 0;
|
||||
virtual void writeSingleInstanceScaleToCPU(const double* scale, int srcIndex) = 0;
|
||||
virtual void writeSingleInstanceSpecularColorToCPU(const double* specular, int srcIndex) = 0;
|
||||
virtual void writeSingleInstanceSpecularColorToCPU(const float* specular, int srcIndex) = 0;
|
||||
virtual void writeSingleInstanceFlagsToCPU(int flags, int srcIndex) = 0;
|
||||
|
||||
virtual int getTotalNumInstances() const = 0;
|
||||
|
||||
virtual void writeTransforms() = 0;
|
||||
|
||||
virtual void clearZBuffer() = 0;
|
||||
|
||||
//This is internal access to OpenGL3+ features, mainly used for OpenCL-OpenGL interop
|
||||
//Only the GLInstancingRenderer supports it, just return 0 otherwise.
|
||||
virtual struct GLInstanceRendererInternalData* getInternalData()=0;
|
||||
virtual struct GLInstanceRendererInternalData* getInternalData() = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline int projectWorldCoordToScreen(T objx, T objy, T objz,
|
||||
const T modelMatrix[16],
|
||||
const T projMatrix[16],
|
||||
const int viewport[4],
|
||||
T *winx, T *winy, T *winz)
|
||||
const T modelMatrix[16],
|
||||
const T projMatrix[16],
|
||||
const int viewport[4],
|
||||
T* winx, T* winy, T* winz)
|
||||
{
|
||||
int i;
|
||||
T in2[4];
|
||||
T tmp[4];
|
||||
|
||||
in2[0]=objx;
|
||||
in2[1]=objy;
|
||||
in2[2]=objz;
|
||||
in2[3]=T(1.0);
|
||||
in2[0] = objx;
|
||||
in2[1] = objy;
|
||||
in2[2] = objz;
|
||||
in2[3] = T(1.0);
|
||||
|
||||
for (i=0; i<4; i++)
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
tmp[i] = in2[0] * modelMatrix[0*4+i] + in2[1] * modelMatrix[1*4+i] +
|
||||
in2[2] * modelMatrix[2*4+i] + in2[3] * modelMatrix[3*4+i];
|
||||
tmp[i] = in2[0] * modelMatrix[0 * 4 + i] + in2[1] * modelMatrix[1 * 4 + i] +
|
||||
in2[2] * modelMatrix[2 * 4 + i] + in2[3] * modelMatrix[3 * 4 + i];
|
||||
}
|
||||
|
||||
T out[4];
|
||||
for (i=0; i<4; i++)
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
out[i] = tmp[0] * projMatrix[0*4+i] + tmp[1] * projMatrix[1*4+i] + tmp[2] * projMatrix[2*4+i] + tmp[3] * projMatrix[3*4+i];
|
||||
out[i] = tmp[0] * projMatrix[0 * 4 + i] + tmp[1] * projMatrix[1 * 4 + i] + tmp[2] * projMatrix[2 * 4 + i] + tmp[3] * projMatrix[3 * 4 + i];
|
||||
}
|
||||
|
||||
if (out[3] == T(0.0))
|
||||
if (out[3] == T(0.0))
|
||||
return 0;
|
||||
out[0] /= out[3];
|
||||
out[1] /= out[3];
|
||||
|
|
@ -109,11 +161,10 @@ inline int projectWorldCoordToScreen(T objx, T objy, T objz,
|
|||
out[0] = out[0] * viewport[2] + viewport[0];
|
||||
out[1] = out[1] * viewport[3] + viewport[1];
|
||||
|
||||
*winx=out[0];
|
||||
*winy=out[1];
|
||||
*winz=out[2];
|
||||
*winx = out[0];
|
||||
*winy = out[1];
|
||||
*winz = out[2];
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif//COMMON_RENDER_INTERFACE_H
|
||||
|
||||
#endif //COMMON_RENDER_INTERFACE_H
|
||||
|
|
|
|||
|
|
@ -2,52 +2,50 @@
|
|||
#ifndef COMMON_RIGID_BODY_BASE_H
|
||||
#define COMMON_RIGID_BODY_BASE_H
|
||||
|
||||
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "CommonExampleInterface.h"
|
||||
#include "CommonGUIHelperInterface.h"
|
||||
#include "CommonRenderInterface.h"
|
||||
#include "CommonCameraInterface.h"
|
||||
|
||||
#include "CommonGraphicsAppInterface.h"
|
||||
#include "CommonWindowInterface.h"
|
||||
#include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h"
|
||||
|
||||
struct CommonRigidBodyBase : public CommonExampleInterface
|
||||
{
|
||||
//keep the collision shapes, for deletion/cleanup
|
||||
btAlignedObjectArray<btCollisionShape*> m_collisionShapes;
|
||||
btBroadphaseInterface* m_broadphase;
|
||||
btCollisionDispatcher* m_dispatcher;
|
||||
btConstraintSolver* m_solver;
|
||||
//keep the collision shapes, for deletion/cleanup
|
||||
btAlignedObjectArray<btCollisionShape*> m_collisionShapes;
|
||||
btBroadphaseInterface* m_broadphase;
|
||||
btCollisionDispatcher* m_dispatcher;
|
||||
btConstraintSolver* m_solver;
|
||||
btDefaultCollisionConfiguration* m_collisionConfiguration;
|
||||
btDiscreteDynamicsWorld* m_dynamicsWorld;
|
||||
|
||||
//data for picking objects
|
||||
class btRigidBody* m_pickedBody;
|
||||
class btRigidBody* m_pickedBody;
|
||||
class btTypedConstraint* m_pickedConstraint;
|
||||
int m_savedState;
|
||||
int m_savedState;
|
||||
btVector3 m_oldPickingPos;
|
||||
btVector3 m_hitPos;
|
||||
btScalar m_oldPickingDist;
|
||||
struct GUIHelperInterface* m_guiHelper;
|
||||
|
||||
CommonRigidBodyBase(struct GUIHelperInterface* helper)
|
||||
:m_broadphase(0),
|
||||
m_dispatcher(0),
|
||||
m_solver(0),
|
||||
m_collisionConfiguration(0),
|
||||
m_dynamicsWorld(0),
|
||||
m_pickedBody(0),
|
||||
m_pickedConstraint(0),
|
||||
m_guiHelper(helper)
|
||||
: m_broadphase(0),
|
||||
m_dispatcher(0),
|
||||
m_solver(0),
|
||||
m_collisionConfiguration(0),
|
||||
m_dynamicsWorld(0),
|
||||
m_pickedBody(0),
|
||||
m_pickedConstraint(0),
|
||||
m_guiHelper(helper)
|
||||
{
|
||||
}
|
||||
virtual ~CommonRigidBodyBase()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
btDiscreteDynamicsWorld* getDynamicsWorld()
|
||||
btDiscreteDynamicsWorld* getDynamicsWorld()
|
||||
{
|
||||
return m_dynamicsWorld;
|
||||
}
|
||||
|
|
@ -59,7 +57,7 @@ struct CommonRigidBodyBase : public CommonExampleInterface
|
|||
//m_collisionConfiguration->setConvexConvexMultipointIterations();
|
||||
|
||||
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
|
||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
||||
|
||||
m_broadphase = new btDbvtBroadphase();
|
||||
|
||||
|
|
@ -72,7 +70,6 @@ struct CommonRigidBodyBase : public CommonExampleInterface
|
|||
m_dynamicsWorld->setGravity(btVector3(0, -10, 0));
|
||||
}
|
||||
|
||||
|
||||
virtual void stepSimulation(float deltaTime)
|
||||
{
|
||||
if (m_dynamicsWorld)
|
||||
|
|
@ -96,15 +93,14 @@ struct CommonRigidBodyBase : public CommonExampleInterface
|
|||
//cleanup in the reverse order of creation/initialization
|
||||
|
||||
//remove the rigidbodies from the dynamics world and delete them
|
||||
|
||||
|
||||
if (m_dynamicsWorld)
|
||||
{
|
||||
|
||||
int i;
|
||||
for (i = m_dynamicsWorld->getNumConstraints() - 1; i >= 0; i--)
|
||||
{
|
||||
m_dynamicsWorld->removeConstraint(m_dynamicsWorld->getConstraint(i));
|
||||
}
|
||||
int i;
|
||||
for (i = m_dynamicsWorld->getNumConstraints() - 1; i >= 0; i--)
|
||||
{
|
||||
m_dynamicsWorld->removeConstraint(m_dynamicsWorld->getConstraint(i));
|
||||
}
|
||||
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
|
||||
{
|
||||
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
|
||||
|
|
@ -118,7 +114,7 @@ struct CommonRigidBodyBase : public CommonExampleInterface
|
|||
}
|
||||
}
|
||||
//delete collision shapes
|
||||
for (int j = 0; j<m_collisionShapes.size(); j++)
|
||||
for (int j = 0; j < m_collisionShapes.size(); j++)
|
||||
{
|
||||
btCollisionShape* shape = m_collisionShapes[j];
|
||||
delete shape;
|
||||
|
|
@ -126,84 +122,80 @@ struct CommonRigidBodyBase : public CommonExampleInterface
|
|||
m_collisionShapes.clear();
|
||||
|
||||
delete m_dynamicsWorld;
|
||||
m_dynamicsWorld=0;
|
||||
m_dynamicsWorld = 0;
|
||||
|
||||
delete m_solver;
|
||||
m_solver=0;
|
||||
m_solver = 0;
|
||||
|
||||
delete m_broadphase;
|
||||
m_broadphase=0;
|
||||
m_broadphase = 0;
|
||||
|
||||
delete m_dispatcher;
|
||||
m_dispatcher=0;
|
||||
m_dispatcher = 0;
|
||||
|
||||
delete m_collisionConfiguration;
|
||||
m_collisionConfiguration=0;
|
||||
m_collisionConfiguration = 0;
|
||||
}
|
||||
|
||||
|
||||
virtual void debugDraw(int debugDrawFlags)
|
||||
{
|
||||
if (m_dynamicsWorld)
|
||||
{
|
||||
virtual void debugDraw(int debugDrawFlags)
|
||||
{
|
||||
if (m_dynamicsWorld)
|
||||
{
|
||||
if (m_dynamicsWorld->getDebugDrawer())
|
||||
{
|
||||
m_dynamicsWorld->getDebugDrawer()->setDebugMode(debugDrawFlags);
|
||||
}
|
||||
m_dynamicsWorld->debugDrawWorld();
|
||||
}
|
||||
m_dynamicsWorld->debugDrawWorld();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
virtual bool keyboardCallback(int key, int state)
|
||||
virtual bool keyboardCallback(int key, int state)
|
||||
{
|
||||
if ((key==B3G_F3) && state && m_dynamicsWorld)
|
||||
if ((key == B3G_F3) && state && m_dynamicsWorld)
|
||||
{
|
||||
btDefaultSerializer* serializer = new btDefaultSerializer();
|
||||
btDefaultSerializer* serializer = new btDefaultSerializer();
|
||||
m_dynamicsWorld->serialize(serializer);
|
||||
|
||||
FILE* file = fopen("testFile.bullet","wb");
|
||||
fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1, file);
|
||||
FILE* file = fopen("testFile.bullet", "wb");
|
||||
fwrite(serializer->getBufferPointer(), serializer->getCurrentBufferSize(), 1, file);
|
||||
fclose(file);
|
||||
//b3Printf("btDefaultSerializer wrote testFile.bullet");
|
||||
delete serializer;
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;//don't handle this key
|
||||
return false; //don't handle this key
|
||||
}
|
||||
|
||||
|
||||
btVector3 getRayTo(int x,int y)
|
||||
btVector3 getRayTo(int x, int y)
|
||||
{
|
||||
CommonRenderInterface* renderer = m_guiHelper->getRenderInterface();
|
||||
|
||||
|
||||
if (!renderer)
|
||||
{
|
||||
btAssert(0);
|
||||
return btVector3(0,0,0);
|
||||
return btVector3(0, 0, 0);
|
||||
}
|
||||
|
||||
float top = 1.f;
|
||||
float bottom = -1.f;
|
||||
float nearPlane = 1.f;
|
||||
float tanFov = (top-bottom)*0.5f / nearPlane;
|
||||
float tanFov = (top - bottom) * 0.5f / nearPlane;
|
||||
float fov = btScalar(2.0) * btAtan(tanFov);
|
||||
|
||||
btVector3 camPos,camTarget;
|
||||
|
||||
btVector3 camPos, camTarget;
|
||||
|
||||
renderer->getActiveCamera()->getCameraPosition(camPos);
|
||||
renderer->getActiveCamera()->getCameraTargetPosition(camTarget);
|
||||
|
||||
btVector3 rayFrom = camPos;
|
||||
btVector3 rayForward = (camTarget-camPos);
|
||||
btVector3 rayFrom = camPos;
|
||||
btVector3 rayForward = (camTarget - camPos);
|
||||
rayForward.normalize();
|
||||
float farPlane = 10000.f;
|
||||
rayForward*= farPlane;
|
||||
rayForward *= farPlane;
|
||||
|
||||
btVector3 rightOffset;
|
||||
btVector3 cameraUp=btVector3(0,0,0);
|
||||
cameraUp[m_guiHelper->getAppInterface()->getUpAxis()]=1;
|
||||
btVector3 cameraUp = btVector3(0, 0, 0);
|
||||
cameraUp[m_guiHelper->getAppInterface()->getUpAxis()] = 1;
|
||||
|
||||
btVector3 vertical = cameraUp;
|
||||
|
||||
|
|
@ -213,25 +205,22 @@ struct CommonRigidBodyBase : public CommonExampleInterface
|
|||
vertical = hor.cross(rayForward);
|
||||
vertical.safeNormalize();
|
||||
|
||||
float tanfov = tanf(0.5f*fov);
|
||||
|
||||
float tanfov = tanf(0.5f * fov);
|
||||
|
||||
hor *= 2.f * farPlane * tanfov;
|
||||
vertical *= 2.f * farPlane * tanfov;
|
||||
|
||||
btScalar aspect;
|
||||
float width = float(renderer->getScreenWidth());
|
||||
float height = float (renderer->getScreenHeight());
|
||||
float height = float(renderer->getScreenHeight());
|
||||
|
||||
aspect = width / height;
|
||||
|
||||
hor*=aspect;
|
||||
aspect = width / height;
|
||||
|
||||
hor *= aspect;
|
||||
|
||||
btVector3 rayToCenter = rayFrom + rayForward;
|
||||
btVector3 dHor = hor * 1.f/width;
|
||||
btVector3 dVert = vertical * 1.f/height;
|
||||
|
||||
btVector3 dHor = hor * 1.f / width;
|
||||
btVector3 dVert = vertical * 1.f / height;
|
||||
|
||||
btVector3 rayTo = rayToCenter - 0.5f * hor + 0.5f * vertical;
|
||||
rayTo += btScalar(x) * dHor;
|
||||
|
|
@ -239,10 +228,10 @@ struct CommonRigidBodyBase : public CommonExampleInterface
|
|||
return rayTo;
|
||||
}
|
||||
|
||||
virtual bool mouseMoveCallback(float x,float y)
|
||||
virtual bool mouseMoveCallback(float x, float y)
|
||||
{
|
||||
CommonRenderInterface* renderer = m_guiHelper->getRenderInterface();
|
||||
|
||||
|
||||
if (!renderer)
|
||||
{
|
||||
btAssert(0);
|
||||
|
|
@ -252,21 +241,21 @@ struct CommonRigidBodyBase : public CommonExampleInterface
|
|||
btVector3 rayTo = getRayTo(int(x), int(y));
|
||||
btVector3 rayFrom;
|
||||
renderer->getActiveCamera()->getCameraPosition(rayFrom);
|
||||
movePickedBody(rayFrom,rayTo);
|
||||
movePickedBody(rayFrom, rayTo);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool mouseButtonCallback(int button, int state, float x, float y)
|
||||
virtual bool mouseButtonCallback(int button, int state, float x, float y)
|
||||
{
|
||||
CommonRenderInterface* renderer = m_guiHelper->getRenderInterface();
|
||||
|
||||
|
||||
if (!renderer)
|
||||
{
|
||||
btAssert(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
CommonWindowInterface* window = m_guiHelper->getAppInterface()->m_window;
|
||||
|
||||
#if 0
|
||||
|
|
@ -294,25 +283,23 @@ struct CommonRigidBodyBase : public CommonExampleInterface
|
|||
printf("NO CONTROL pressed\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if (state==1)
|
||||
|
||||
if (state == 1)
|
||||
{
|
||||
if(button==0 && (!window->isModifierKeyPressed(B3G_ALT) && !window->isModifierKeyPressed(B3G_CONTROL) ))
|
||||
if (button == 0 && (!window->isModifierKeyPressed(B3G_ALT) && !window->isModifierKeyPressed(B3G_CONTROL)))
|
||||
{
|
||||
btVector3 camPos;
|
||||
renderer->getActiveCamera()->getCameraPosition(camPos);
|
||||
|
||||
btVector3 rayFrom = camPos;
|
||||
btVector3 rayTo = getRayTo(int(x),int(y));
|
||||
btVector3 rayTo = getRayTo(int(x), int(y));
|
||||
|
||||
pickBody(rayFrom, rayTo);
|
||||
|
||||
|
||||
}
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
if (button==0)
|
||||
if (button == 0)
|
||||
{
|
||||
removePickingConstraint();
|
||||
//remove p2p
|
||||
|
|
@ -323,18 +310,17 @@ struct CommonRigidBodyBase : public CommonExampleInterface
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
virtual bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)
|
||||
{
|
||||
if (m_dynamicsWorld==0)
|
||||
if (m_dynamicsWorld == 0)
|
||||
return false;
|
||||
|
||||
btCollisionWorld::ClosestRayResultCallback rayCallback(rayFromWorld, rayToWorld);
|
||||
|
||||
rayCallback.m_flags |= btTriangleRaycastCallback::kF_UseGjkConvexCastRaytest;
|
||||
m_dynamicsWorld->rayTest(rayFromWorld, rayToWorld, rayCallback);
|
||||
if (rayCallback.hasHit())
|
||||
{
|
||||
|
||||
btVector3 pickPos = rayCallback.m_hitPointWorld;
|
||||
btRigidBody* body = (btRigidBody*)btRigidBody::upcast(rayCallback.m_collisionObject);
|
||||
if (body)
|
||||
|
|
@ -357,7 +343,6 @@ struct CommonRigidBodyBase : public CommonExampleInterface
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// pickObject(pickPos, rayCallback.m_collisionObject);
|
||||
m_oldPickingPos = rayToWorld;
|
||||
m_hitPos = pickPos;
|
||||
|
|
@ -369,7 +354,7 @@ struct CommonRigidBodyBase : public CommonExampleInterface
|
|||
}
|
||||
virtual bool movePickedBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)
|
||||
{
|
||||
if (m_pickedBody && m_pickedConstraint)
|
||||
if (m_pickedBody && m_pickedConstraint)
|
||||
{
|
||||
btPoint2PointConstraint* pickCon = static_cast<btPoint2PointConstraint*>(m_pickedConstraint);
|
||||
if (pickCon)
|
||||
|
|
@ -402,15 +387,24 @@ struct CommonRigidBodyBase : public CommonExampleInterface
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
btBoxShape* createBoxShape(const btVector3& halfExtents)
|
||||
{
|
||||
btBoxShape* box = new btBoxShape(halfExtents);
|
||||
return box;
|
||||
}
|
||||
|
||||
btRigidBody* createRigidBody(float mass, const btTransform& startTransform, btCollisionShape* shape, const btVector4& color = btVector4(1, 0, 0, 1))
|
||||
void deleteRigidBody(btRigidBody* body)
|
||||
{
|
||||
int graphicsUid = body->getUserIndex();
|
||||
m_guiHelper->removeGraphicsInstance(graphicsUid);
|
||||
|
||||
m_dynamicsWorld->removeRigidBody(body);
|
||||
btMotionState* ms = body->getMotionState();
|
||||
delete body;
|
||||
delete ms;
|
||||
}
|
||||
|
||||
btRigidBody* createRigidBody(float mass, const btTransform& startTransform, btCollisionShape* shape, const btVector4& color = btVector4(1, 0, 0, 1))
|
||||
{
|
||||
btAssert((!shape || shape->getShapeType() != INVALID_SHAPE_PROXYTYPE));
|
||||
|
||||
|
|
@ -421,7 +415,7 @@ struct CommonRigidBodyBase : public CommonExampleInterface
|
|||
if (isDynamic)
|
||||
shape->calculateLocalInertia(mass, localInertia);
|
||||
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
|
||||
#define USE_MOTIONSTATE 1
|
||||
#ifdef USE_MOTIONSTATE
|
||||
|
|
@ -435,28 +429,26 @@ struct CommonRigidBodyBase : public CommonExampleInterface
|
|||
#else
|
||||
btRigidBody* body = new btRigidBody(mass, 0, shape, localInertia);
|
||||
body->setWorldTransform(startTransform);
|
||||
#endif//
|
||||
#endif //
|
||||
|
||||
body->setUserIndex(-1);
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
return body;
|
||||
}
|
||||
|
||||
|
||||
|
||||
virtual void renderScene()
|
||||
{
|
||||
if (m_dynamicsWorld)
|
||||
{
|
||||
|
||||
m_guiHelper->syncPhysicsToGraphics(m_dynamicsWorld);
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
m_guiHelper->render(m_dynamicsWorld);
|
||||
{
|
||||
m_guiHelper->syncPhysicsToGraphics(m_dynamicsWorld);
|
||||
}
|
||||
|
||||
{
|
||||
m_guiHelper->render(m_dynamicsWorld);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif //COMMON_RIGID_BODY_SETUP_H
|
||||
|
||||
#endif //COMMON_RIGID_BODY_SETUP_H
|
||||
|
|
|
|||
|
|
@ -1,130 +1,88 @@
|
|||
#ifndef B3G_WINDOW_INTERFACE_H
|
||||
#define B3G_WINDOW_INTERFACE_H
|
||||
|
||||
|
||||
typedef void (*b3WheelCallback)(float deltax, float deltay);
|
||||
typedef void (*b3ResizeCallback)( float width, float height);
|
||||
typedef void (*b3MouseMoveCallback)( float x, float y);
|
||||
typedef void (*b3MouseButtonCallback)(int button, int state, float x, float y);
|
||||
typedef void (*b3KeyboardCallback)(int keycode, int state);
|
||||
typedef void (*b3RenderCallback) ();
|
||||
|
||||
enum {
|
||||
B3G_ESCAPE = 27,
|
||||
B3G_F1 = 0xff00,
|
||||
B3G_F2,
|
||||
B3G_F3,
|
||||
B3G_F4,
|
||||
B3G_F5,
|
||||
B3G_F6,
|
||||
B3G_F7,
|
||||
B3G_F8,
|
||||
B3G_F9,
|
||||
B3G_F10,
|
||||
B3G_F11,
|
||||
B3G_F12,
|
||||
B3G_F13,
|
||||
B3G_F14,
|
||||
B3G_F15,
|
||||
B3G_LEFT_ARROW,
|
||||
B3G_RIGHT_ARROW,
|
||||
B3G_UP_ARROW,
|
||||
B3G_DOWN_ARROW,
|
||||
B3G_PAGE_UP,
|
||||
B3G_PAGE_DOWN,
|
||||
B3G_END,
|
||||
B3G_HOME,
|
||||
B3G_INSERT,
|
||||
B3G_DELETE,
|
||||
B3G_BACKSPACE,
|
||||
B3G_SHIFT,
|
||||
B3G_CONTROL,
|
||||
B3G_ALT,
|
||||
B3G_RETURN
|
||||
};
|
||||
#include "CommonCallbacks.h"
|
||||
|
||||
struct b3gWindowConstructionInfo
|
||||
{
|
||||
int m_width;
|
||||
int m_height;
|
||||
bool m_fullscreen;
|
||||
int m_colorBitsPerPixel;
|
||||
void* m_windowHandle;
|
||||
const char* m_title;
|
||||
int m_openglVersion;
|
||||
|
||||
int m_width;
|
||||
int m_height;
|
||||
bool m_fullscreen;
|
||||
int m_colorBitsPerPixel;
|
||||
void* m_windowHandle;
|
||||
const char* m_title;
|
||||
int m_openglVersion;
|
||||
int m_renderDevice;
|
||||
|
||||
b3gWindowConstructionInfo(int width=1024, int height=768)
|
||||
:m_width(width),
|
||||
m_height(height),
|
||||
m_fullscreen(false),
|
||||
m_colorBitsPerPixel(32),
|
||||
m_windowHandle(0),
|
||||
m_title("title"),
|
||||
m_openglVersion(3)
|
||||
{
|
||||
}
|
||||
b3gWindowConstructionInfo(int width = 1024, int height = 768)
|
||||
: m_width(width),
|
||||
m_height(height),
|
||||
m_fullscreen(false),
|
||||
m_colorBitsPerPixel(32),
|
||||
m_windowHandle(0),
|
||||
m_title("title"),
|
||||
m_openglVersion(3),
|
||||
m_renderDevice(-1)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class CommonWindowInterface
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~CommonWindowInterface()
|
||||
{
|
||||
}
|
||||
public:
|
||||
virtual ~CommonWindowInterface()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void createDefaultWindow(int width, int height, const char* title)
|
||||
{
|
||||
b3gWindowConstructionInfo ci(width,height);
|
||||
ci.m_title = title;
|
||||
createWindow(ci);
|
||||
}
|
||||
virtual void createDefaultWindow(int width, int height, const char* title)
|
||||
{
|
||||
b3gWindowConstructionInfo ci(width, height);
|
||||
ci.m_title = title;
|
||||
createWindow(ci);
|
||||
}
|
||||
|
||||
virtual void createWindow(const b3gWindowConstructionInfo& ci)=0;
|
||||
|
||||
virtual void closeWindow()=0;
|
||||
virtual void createWindow(const b3gWindowConstructionInfo& ci) = 0;
|
||||
|
||||
virtual void runMainLoop()=0;
|
||||
virtual float getTimeInSeconds()=0;
|
||||
virtual void closeWindow() = 0;
|
||||
|
||||
virtual bool requestedExit() const = 0;
|
||||
virtual void setRequestExit() = 0;
|
||||
virtual void runMainLoop() = 0;
|
||||
virtual float getTimeInSeconds() = 0;
|
||||
|
||||
virtual void startRendering()=0;
|
||||
virtual bool requestedExit() const = 0;
|
||||
virtual void setRequestExit() = 0;
|
||||
|
||||
virtual void endRendering()=0;
|
||||
virtual void startRendering() = 0;
|
||||
|
||||
virtual bool isModifierKeyPressed(int key) = 0;
|
||||
|
||||
virtual void setMouseMoveCallback(b3MouseMoveCallback mouseCallback)=0;
|
||||
virtual b3MouseMoveCallback getMouseMoveCallback()=0;
|
||||
|
||||
virtual void setMouseButtonCallback(b3MouseButtonCallback mouseCallback)=0;
|
||||
virtual b3MouseButtonCallback getMouseButtonCallback()=0;
|
||||
virtual void endRendering() = 0;
|
||||
|
||||
virtual void setResizeCallback(b3ResizeCallback resizeCallback)=0;
|
||||
virtual b3ResizeCallback getResizeCallback()=0;
|
||||
|
||||
virtual void setWheelCallback(b3WheelCallback wheelCallback)=0;
|
||||
virtual b3WheelCallback getWheelCallback()=0;
|
||||
|
||||
virtual void setKeyboardCallback( b3KeyboardCallback keyboardCallback)=0;
|
||||
virtual b3KeyboardCallback getKeyboardCallback()=0;
|
||||
virtual bool isModifierKeyPressed(int key) = 0;
|
||||
|
||||
virtual void setRenderCallback( b3RenderCallback renderCallback) = 0;
|
||||
|
||||
virtual void setWindowTitle(const char* title)=0;
|
||||
virtual void setMouseMoveCallback(b3MouseMoveCallback mouseCallback) = 0;
|
||||
virtual b3MouseMoveCallback getMouseMoveCallback() = 0;
|
||||
|
||||
virtual float getRetinaScale() const =0;
|
||||
virtual void setAllowRetina(bool allow) =0;
|
||||
virtual void setMouseButtonCallback(b3MouseButtonCallback mouseCallback) = 0;
|
||||
virtual b3MouseButtonCallback getMouseButtonCallback() = 0;
|
||||
|
||||
virtual int getWidth() const = 0;
|
||||
virtual int getHeight() const = 0;
|
||||
virtual void setResizeCallback(b3ResizeCallback resizeCallback) = 0;
|
||||
virtual b3ResizeCallback getResizeCallback() = 0;
|
||||
|
||||
virtual int fileOpenDialog(char* fileName, int maxFileNameLength) = 0;
|
||||
|
||||
virtual void setWheelCallback(b3WheelCallback wheelCallback) = 0;
|
||||
virtual b3WheelCallback getWheelCallback() = 0;
|
||||
|
||||
virtual void setKeyboardCallback(b3KeyboardCallback keyboardCallback) = 0;
|
||||
virtual b3KeyboardCallback getKeyboardCallback() = 0;
|
||||
|
||||
virtual void setRenderCallback(b3RenderCallback renderCallback) = 0;
|
||||
|
||||
virtual void setWindowTitle(const char* title) = 0;
|
||||
|
||||
virtual float getRetinaScale() const = 0;
|
||||
virtual void setAllowRetina(bool allow) = 0;
|
||||
|
||||
virtual int getWidth() const = 0;
|
||||
virtual int getHeight() const = 0;
|
||||
|
||||
virtual int fileOpenDialog(char* fileName, int maxFileNameLength) = 0;
|
||||
};
|
||||
|
||||
#endif //B3G_WINDOW_INTERFACE_H
|
||||
#endif //B3G_WINDOW_INTERFACE_H
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
Copyright (c) 2003-2006 Erwin Coumans https://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.
|
||||
|
|
@ -15,8 +15,6 @@ subject to the following restrictions:
|
|||
#ifndef ALL_CONSTRAINT_DEMO_H
|
||||
#define ALL_CONSTRAINT_DEMO_H
|
||||
|
||||
class CommonExampleInterface* AllConstraintCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
|
||||
#endif //ALL_CONSTRAINT_DEMO_H
|
||||
class CommonExampleInterface* AllConstraintCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
#endif //ALL_CONSTRAINT_DEMO_H
|
||||
|
|
|
|||
|
|
@ -1,11 +1,8 @@
|
|||
#include "ConstraintPhysicsSetup.h"
|
||||
|
||||
|
||||
#include "../CommonInterfaces/CommonRigidBodyBase.h"
|
||||
#include "../CommonInterfaces/CommonParameterInterface.h"
|
||||
|
||||
|
||||
|
||||
struct ConstraintPhysicsSetup : public CommonRigidBodyBase
|
||||
{
|
||||
ConstraintPhysicsSetup(struct GUIHelperInterface* helper);
|
||||
|
|
@ -14,21 +11,18 @@ struct ConstraintPhysicsSetup : public CommonRigidBodyBase
|
|||
|
||||
virtual void stepSimulation(float deltaTime);
|
||||
|
||||
|
||||
virtual void resetCamera()
|
||||
{
|
||||
float dist = 7;
|
||||
float pitch = 721;
|
||||
float yaw = 44;
|
||||
float targetPos[3]={8,1,-11};
|
||||
m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
|
||||
float pitch = -44;
|
||||
float yaw = 721;
|
||||
float targetPos[3] = {8, 1, -11};
|
||||
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
ConstraintPhysicsSetup::ConstraintPhysicsSetup(struct GUIHelperInterface* helper)
|
||||
:CommonRigidBodyBase(helper)
|
||||
: CommonRigidBodyBase(helper)
|
||||
{
|
||||
}
|
||||
ConstraintPhysicsSetup::~ConstraintPhysicsSetup()
|
||||
|
|
@ -36,63 +30,56 @@ ConstraintPhysicsSetup::~ConstraintPhysicsSetup()
|
|||
}
|
||||
|
||||
static btScalar val;
|
||||
static btScalar targetVel=0;
|
||||
static btScalar maxImpulse=10000;
|
||||
static btHingeAccumulatedAngleConstraint* spDoorHinge=0;
|
||||
static btScalar actualHingeVelocity=0.f;
|
||||
static btScalar targetVel = 0;
|
||||
static btScalar maxImpulse = 10000;
|
||||
static btHingeAccumulatedAngleConstraint* spDoorHinge = 0;
|
||||
static btScalar actualHingeVelocity = 0.f;
|
||||
|
||||
static btVector3 btAxisA(0,1,0);
|
||||
static btVector3 btAxisA(0, 1, 0);
|
||||
|
||||
void ConstraintPhysicsSetup::stepSimulation(float deltaTime)
|
||||
{
|
||||
val=spDoorHinge->getAccumulatedHingeAngle()*SIMD_DEGS_PER_RAD;
|
||||
if (m_dynamicsWorld)
|
||||
val = spDoorHinge->getAccumulatedHingeAngle() * SIMD_DEGS_PER_RAD;
|
||||
if (m_dynamicsWorld)
|
||||
{
|
||||
spDoorHinge->enableAngularMotor(true,targetVel,maxImpulse);
|
||||
spDoorHinge->enableAngularMotor(true, targetVel, maxImpulse);
|
||||
|
||||
m_dynamicsWorld->stepSimulation(deltaTime,10,1./240.);
|
||||
m_dynamicsWorld->stepSimulation(deltaTime, 10, 1. / 240.);
|
||||
|
||||
btHingeConstraint* hinge = spDoorHinge;
|
||||
|
||||
btHingeConstraint* hinge = spDoorHinge;
|
||||
if (hinge)
|
||||
{
|
||||
const btRigidBody& bodyA = hinge->getRigidBodyA();
|
||||
const btRigidBody& bodyB = hinge->getRigidBodyB();
|
||||
|
||||
if (hinge)
|
||||
{
|
||||
btTransform trA = bodyA.getWorldTransform();
|
||||
btVector3 angVelA = bodyA.getAngularVelocity();
|
||||
btVector3 angVelB = bodyB.getAngularVelocity();
|
||||
|
||||
const btRigidBody& bodyA = hinge->getRigidBodyA();
|
||||
const btRigidBody& bodyB = hinge->getRigidBodyB();
|
||||
|
||||
|
||||
btTransform trA = bodyA.getWorldTransform();
|
||||
btVector3 angVelA = bodyA.getAngularVelocity();
|
||||
btVector3 angVelB = bodyB.getAngularVelocity();
|
||||
|
||||
{
|
||||
btVector3 ax1 = trA.getBasis()*hinge->getFrameOffsetA().getBasis().getColumn(2);
|
||||
btScalar vel = angVelA.dot(ax1);
|
||||
vel -= angVelB.dot(ax1);
|
||||
printf("hinge velocity (q) = %f\n", vel);
|
||||
actualHingeVelocity=vel;
|
||||
}
|
||||
btVector3 ortho0,ortho1;
|
||||
btPlaneSpace1(btAxisA,ortho0,ortho1);
|
||||
{
|
||||
|
||||
btScalar vel2 = angVelA.dot(ortho0);
|
||||
vel2 -= angVelB.dot(ortho0);
|
||||
printf("hinge orthogonal1 velocity (q) = %f\n", vel2);
|
||||
}
|
||||
{
|
||||
|
||||
btScalar vel0 = angVelA.dot(ortho1);
|
||||
vel0 -= angVelB.dot(ortho1);
|
||||
printf("hinge orthogonal0 velocity (q) = %f\n", vel0);
|
||||
}
|
||||
}
|
||||
{
|
||||
btVector3 ax1 = trA.getBasis() * hinge->getFrameOffsetA().getBasis().getColumn(2);
|
||||
btScalar vel = angVelA.dot(ax1);
|
||||
vel -= angVelB.dot(ax1);
|
||||
printf("hinge velocity (q) = %f\n", vel);
|
||||
actualHingeVelocity = vel;
|
||||
}
|
||||
btVector3 ortho0, ortho1;
|
||||
btPlaneSpace1(btAxisA, ortho0, ortho1);
|
||||
{
|
||||
btScalar vel2 = angVelA.dot(ortho0);
|
||||
vel2 -= angVelB.dot(ortho0);
|
||||
printf("hinge orthogonal1 velocity (q) = %f\n", vel2);
|
||||
}
|
||||
{
|
||||
btScalar vel0 = angVelA.dot(ortho1);
|
||||
vel0 -= angVelB.dot(ortho1);
|
||||
printf("hinge orthogonal0 velocity (q) = %f\n", vel0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ConstraintPhysicsSetup::initPhysics()
|
||||
{
|
||||
m_guiHelper->setUpAxis(1);
|
||||
|
|
@ -100,62 +87,59 @@ void ConstraintPhysicsSetup::initPhysics()
|
|||
createEmptyDynamicsWorld();
|
||||
|
||||
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
|
||||
int mode = btIDebugDraw::DBG_DrawWireframe
|
||||
+btIDebugDraw::DBG_DrawConstraints
|
||||
+btIDebugDraw::DBG_DrawConstraintLimits;
|
||||
int mode = btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawConstraints + btIDebugDraw::DBG_DrawConstraintLimits;
|
||||
m_dynamicsWorld->getDebugDrawer()->setDebugMode(mode);
|
||||
|
||||
{
|
||||
SliderParams slider("target vel", &targetVel);
|
||||
slider.m_minVal = -4;
|
||||
slider.m_maxVal = 4;
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
}
|
||||
|
||||
{
|
||||
SliderParams slider("target vel",&targetVel);
|
||||
slider.m_minVal=-4;
|
||||
slider.m_maxVal=4;
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
}
|
||||
{
|
||||
SliderParams slider("max impulse", &maxImpulse);
|
||||
slider.m_minVal = 0;
|
||||
slider.m_maxVal = 1000;
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
}
|
||||
|
||||
{
|
||||
SliderParams slider("max impulse",&maxImpulse);
|
||||
slider.m_minVal=0;
|
||||
slider.m_maxVal=1000;
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
}
|
||||
{
|
||||
SliderParams slider("actual vel", &actualHingeVelocity);
|
||||
slider.m_minVal = -4;
|
||||
slider.m_maxVal = 4;
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
}
|
||||
|
||||
{
|
||||
SliderParams slider("actual vel",&actualHingeVelocity);
|
||||
slider.m_minVal=-4;
|
||||
slider.m_maxVal=4;
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
}
|
||||
val = 1.f;
|
||||
{
|
||||
SliderParams slider("angle", &val);
|
||||
slider.m_minVal = -720;
|
||||
slider.m_maxVal = 720;
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
}
|
||||
|
||||
val=1.f;
|
||||
{
|
||||
SliderParams slider("angle",&val);
|
||||
slider.m_minVal=-720;
|
||||
slider.m_maxVal=720;
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
}
|
||||
|
||||
{ // create a door using hinge constraint attached to the world
|
||||
{ // create a door using hinge constraint attached to the world
|
||||
btCollisionShape* pDoorShape = new btBoxShape(btVector3(2.0f, 5.0f, 0.2f));
|
||||
m_collisionShapes.push_back(pDoorShape);
|
||||
btTransform doorTrans;
|
||||
doorTrans.setIdentity();
|
||||
doorTrans.setOrigin(btVector3(-5.0f, -2.0f, 0.0f));
|
||||
btRigidBody* pDoorBody = createRigidBody( 1.0, doorTrans, pDoorShape);
|
||||
btRigidBody* pDoorBody = createRigidBody(1.0, doorTrans, pDoorShape);
|
||||
pDoorBody->setActivationState(DISABLE_DEACTIVATION);
|
||||
const btVector3 btPivotA(10.f + 2.1f, -2.0f, 0.0f ); // right next to the door slightly outside
|
||||
const btVector3 btPivotA(10.f + 2.1f, -2.0f, 0.0f); // right next to the door slightly outside
|
||||
|
||||
spDoorHinge = new btHingeAccumulatedAngleConstraint( *pDoorBody, btPivotA, btAxisA );
|
||||
spDoorHinge = new btHingeAccumulatedAngleConstraint(*pDoorBody, btPivotA, btAxisA);
|
||||
|
||||
m_dynamicsWorld->addConstraint(spDoorHinge);
|
||||
m_dynamicsWorld->addConstraint(spDoorHinge);
|
||||
|
||||
spDoorHinge->setDbgDrawSize(btScalar(5.f));
|
||||
}
|
||||
|
||||
|
||||
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
|
||||
}
|
||||
|
||||
class CommonExampleInterface* ConstraintCreateFunc(CommonExampleOptions& options)
|
||||
class CommonExampleInterface* ConstraintCreateFunc(CommonExampleOptions& options)
|
||||
{
|
||||
return new ConstraintPhysicsSetup(options.m_guiHelper);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#ifndef CONSTAINT_PHYSICS_SETUP_H
|
||||
#define CONSTAINT_PHYSICS_SETUP_H
|
||||
|
||||
class CommonExampleInterface* ConstraintCreateFunc(struct CommonExampleOptions& options);
|
||||
class CommonExampleInterface* ConstraintCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
#endif //CONSTAINT_PHYSICS_SETUP_H
|
||||
#endif //CONSTAINT_PHYSICS_SETUP_H
|
||||
|
|
|
|||
|
|
@ -9,37 +9,32 @@
|
|||
|
||||
#include "BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h"
|
||||
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#ifndef M_PI_2
|
||||
#define M_PI_2 1.57079632679489661923
|
||||
#define M_PI_2 1.57079632679489661923
|
||||
#endif
|
||||
|
||||
#ifndef M_PI_4
|
||||
#define M_PI_4 0.785398163397448309616
|
||||
#define M_PI_4 0.785398163397448309616
|
||||
#endif
|
||||
|
||||
|
||||
extern float g_additionalBodyMass;
|
||||
|
||||
//comment this out to compare with original spring constraint
|
||||
#define USE_6DOF2
|
||||
#ifdef USE_6DOF2
|
||||
#define CONSTRAINT_TYPE btGeneric6DofSpring2Constraint
|
||||
#define EXTRAPARAMS
|
||||
#define CONSTRAINT_TYPE btGeneric6DofSpring2Constraint
|
||||
#define EXTRAPARAMS
|
||||
#else
|
||||
#define CONSTRAINT_TYPE btGeneric6DofSpringConstraint
|
||||
#define EXTRAPARAMS ,true
|
||||
#define CONSTRAINT_TYPE btGeneric6DofSpringConstraint
|
||||
#define EXTRAPARAMS , true
|
||||
#endif
|
||||
|
||||
#include "../CommonInterfaces/CommonRigidBodyBase.h"
|
||||
|
||||
|
||||
|
||||
|
||||
struct Dof6Spring2Setup : public CommonRigidBodyBase
|
||||
{
|
||||
struct Dof6Spring2SetupInternalData* m_data;
|
||||
|
|
@ -55,42 +50,39 @@ struct Dof6Spring2Setup : public CommonRigidBodyBase
|
|||
virtual void resetCamera()
|
||||
{
|
||||
float dist = 5;
|
||||
float pitch = 722;
|
||||
float yaw = 35;
|
||||
float targetPos[3]={4,2,-11};
|
||||
m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
|
||||
float pitch = -35;
|
||||
float yaw = 722;
|
||||
float targetPos[3] = {4, 2, -11};
|
||||
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct Dof6Spring2SetupInternalData
|
||||
{
|
||||
btRigidBody* m_TranslateSpringBody;
|
||||
btRigidBody* m_TranslateSpringBody2;
|
||||
btRigidBody* m_RotateSpringBody;
|
||||
btRigidBody* m_RotateSpringBody2;
|
||||
btRigidBody* m_BouncingTranslateBody;
|
||||
btRigidBody* m_MotorBody;
|
||||
btRigidBody* m_ServoMotorBody;
|
||||
btRigidBody* m_ChainLeftBody;
|
||||
btRigidBody* m_ChainRightBody;
|
||||
CONSTRAINT_TYPE* m_ServoMotorConstraint;
|
||||
CONSTRAINT_TYPE* m_ChainLeftConstraint;
|
||||
CONSTRAINT_TYPE* m_ChainRightConstraint;
|
||||
btRigidBody* m_TranslateSpringBody;
|
||||
btRigidBody* m_TranslateSpringBody2;
|
||||
btRigidBody* m_RotateSpringBody;
|
||||
btRigidBody* m_RotateSpringBody2;
|
||||
btRigidBody* m_BouncingTranslateBody;
|
||||
btRigidBody* m_MotorBody;
|
||||
btRigidBody* m_ServoMotorBody;
|
||||
btRigidBody* m_ChainLeftBody;
|
||||
btRigidBody* m_ChainRightBody;
|
||||
CONSTRAINT_TYPE* m_ServoMotorConstraint;
|
||||
CONSTRAINT_TYPE* m_ChainLeftConstraint;
|
||||
CONSTRAINT_TYPE* m_ChainRightConstraint;
|
||||
|
||||
|
||||
float mDt;
|
||||
|
||||
unsigned int frameID;
|
||||
Dof6Spring2SetupInternalData()
|
||||
: mDt(1./60.),frameID(0)
|
||||
: mDt(1. / 60.), frameID(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
Dof6Spring2Setup::Dof6Spring2Setup(struct GUIHelperInterface* helper)
|
||||
:CommonRigidBodyBase(helper)
|
||||
: CommonRigidBodyBase(helper)
|
||||
{
|
||||
m_data = new Dof6Spring2SetupInternalData;
|
||||
}
|
||||
|
|
@ -102,394 +94,397 @@ Dof6Spring2Setup::~Dof6Spring2Setup()
|
|||
void Dof6Spring2Setup::initPhysics()
|
||||
{
|
||||
// Setup the basic world
|
||||
|
||||
|
||||
m_guiHelper->setUpAxis(1);
|
||||
|
||||
m_collisionConfiguration = new btDefaultCollisionConfiguration();
|
||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
||||
btVector3 worldAabbMin(-10000,-10000,-10000);
|
||||
btVector3 worldAabbMax(10000,10000,10000);
|
||||
m_broadphase = new btAxisSweep3 (worldAabbMin, worldAabbMax);
|
||||
m_collisionConfiguration = new btDefaultCollisionConfiguration();
|
||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
||||
btVector3 worldAabbMin(-10000, -10000, -10000);
|
||||
btVector3 worldAabbMax(10000, 10000, 10000);
|
||||
m_broadphase = new btAxisSweep3(worldAabbMin, worldAabbMax);
|
||||
|
||||
/////// uncomment the corresponding line to test a solver.
|
||||
//m_solver = new btSequentialImpulseConstraintSolver;
|
||||
m_solver = new btNNCGConstraintSolver;
|
||||
//m_solver = new btMLCPSolver(new btSolveProjectedGaussSeidel());
|
||||
//m_solver = new btMLCPSolver(new btDantzigSolver());
|
||||
//m_solver = new btMLCPSolver(new btLemkeSolver());
|
||||
/////// uncomment the corresponding line to test a solver.
|
||||
//m_solver = new btSequentialImpulseConstraintSolver;
|
||||
m_solver = new btNNCGConstraintSolver;
|
||||
//m_solver = new btMLCPSolver(new btSolveProjectedGaussSeidel());
|
||||
//m_solver = new btMLCPSolver(new btDantzigSolver());
|
||||
//m_solver = new btMLCPSolver(new btLemkeSolver());
|
||||
|
||||
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
|
||||
m_dynamicsWorld->getDispatchInfo().m_useContinuous = true;
|
||||
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration);
|
||||
m_dynamicsWorld->getDispatchInfo().m_useContinuous = true;
|
||||
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
|
||||
|
||||
m_dynamicsWorld->setGravity(btVector3(0,0,0));
|
||||
|
||||
// Setup a big ground box
|
||||
{
|
||||
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.),btScalar(5.),btScalar(200.)));
|
||||
btTransform groundTransform;
|
||||
groundTransform.setIdentity();
|
||||
groundTransform.setOrigin(btVector3(0,-10,0));
|
||||
m_dynamicsWorld->setGravity(btVector3(0, 0, 0));
|
||||
|
||||
// Setup a big ground box
|
||||
{
|
||||
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.), btScalar(5.), btScalar(200.)));
|
||||
btTransform groundTransform;
|
||||
groundTransform.setIdentity();
|
||||
groundTransform.setOrigin(btVector3(0, -10, 0));
|
||||
#define CREATE_GROUND_COLLISION_OBJECT 1
|
||||
#ifdef CREATE_GROUND_COLLISION_OBJECT
|
||||
btCollisionObject* fixedGround = new btCollisionObject();
|
||||
fixedGround->setCollisionShape(groundShape);
|
||||
fixedGround->setWorldTransform(groundTransform);
|
||||
m_dynamicsWorld->addCollisionObject(fixedGround);
|
||||
btCollisionObject* fixedGround = new btCollisionObject();
|
||||
fixedGround->setCollisionShape(groundShape);
|
||||
fixedGround->setWorldTransform(groundTransform);
|
||||
m_dynamicsWorld->addCollisionObject(fixedGround);
|
||||
#else
|
||||
localCreateRigidBody(btScalar(0.),groundTransform,groundShape);
|
||||
#endif //CREATE_GROUND_COLLISION_OBJECT
|
||||
}
|
||||
localCreateRigidBody(btScalar(0.), groundTransform, groundShape);
|
||||
#endif //CREATE_GROUND_COLLISION_OBJECT
|
||||
}
|
||||
|
||||
m_dynamicsWorld->getSolverInfo().m_numIterations = 100;
|
||||
m_dynamicsWorld->getSolverInfo().m_numIterations = 100;
|
||||
|
||||
btCollisionShape* shape;
|
||||
btVector3 localInertia(0,0,0);
|
||||
btDefaultMotionState* motionState;
|
||||
btTransform bodyTransform;
|
||||
btScalar mass;
|
||||
btTransform localA;
|
||||
btTransform localB;
|
||||
CONSTRAINT_TYPE* constraint;
|
||||
btCollisionShape* shape;
|
||||
btVector3 localInertia(0, 0, 0);
|
||||
btDefaultMotionState* motionState;
|
||||
btTransform bodyTransform;
|
||||
btScalar mass;
|
||||
btTransform localA;
|
||||
btTransform localB;
|
||||
CONSTRAINT_TYPE* constraint;
|
||||
|
||||
//static body centered in the origo
|
||||
mass = 0.0;
|
||||
shape= new btBoxShape(btVector3(0.5,0.5,0.5));
|
||||
localInertia = btVector3(0,0,0);
|
||||
//static body centered in the origo
|
||||
mass = 0.0;
|
||||
shape = new btBoxShape(btVector3(0.5, 0.5, 0.5));
|
||||
localInertia = btVector3(0, 0, 0);
|
||||
bodyTransform.setIdentity();
|
||||
motionState = new btDefaultMotionState(bodyTransform);
|
||||
btRigidBody* staticBody = new btRigidBody(mass, motionState, shape, localInertia);
|
||||
|
||||
/////////// box with undamped translate spring attached to static body
|
||||
/////////// the box should oscillate left-to-right forever
|
||||
{
|
||||
mass = 1.0;
|
||||
shape = new btBoxShape(btVector3(0.5, 0.5, 0.5));
|
||||
shape->calculateLocalInertia(mass, localInertia);
|
||||
bodyTransform.setIdentity();
|
||||
bodyTransform.setOrigin(btVector3(-2, 0, -5));
|
||||
motionState = new btDefaultMotionState(bodyTransform);
|
||||
btRigidBody* staticBody = new btRigidBody(mass,motionState,shape,localInertia);
|
||||
|
||||
/////////// box with undamped translate spring attached to static body
|
||||
/////////// the box should oscillate left-to-right forever
|
||||
{
|
||||
mass = 1.0;
|
||||
shape= new btBoxShape(btVector3(0.5,0.5,0.5));
|
||||
shape->calculateLocalInertia(mass,localInertia);
|
||||
bodyTransform.setIdentity();
|
||||
bodyTransform.setOrigin(btVector3(-2,0,-5));
|
||||
motionState = new btDefaultMotionState(bodyTransform);
|
||||
m_data->m_TranslateSpringBody = new btRigidBody(mass,motionState,shape,localInertia);
|
||||
m_data->m_TranslateSpringBody->setActivationState(DISABLE_DEACTIVATION);
|
||||
m_dynamicsWorld->addRigidBody(m_data->m_TranslateSpringBody);
|
||||
localA.setIdentity();localA.getOrigin() = btVector3(0,0,-5);
|
||||
localB.setIdentity();
|
||||
constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_TranslateSpringBody, localA, localB EXTRAPARAMS);
|
||||
constraint->setLimit(0, 1,-1);
|
||||
constraint->setLimit(1, 0, 0);
|
||||
constraint->setLimit(2, 0, 0);
|
||||
constraint->setLimit(3, 0, 0);
|
||||
constraint->setLimit(4, 0, 0);
|
||||
constraint->setLimit(5, 0, 0);
|
||||
constraint->enableSpring(0, true);
|
||||
constraint->setStiffness(0, 100);
|
||||
#ifdef USE_6DOF2
|
||||
constraint->setDamping(0, 0);
|
||||
#else
|
||||
constraint->setDamping(0, 1);
|
||||
#endif
|
||||
constraint->setEquilibriumPoint(0, 0);
|
||||
constraint->setDbgDrawSize(btScalar(2.f));
|
||||
m_dynamicsWorld->addConstraint(constraint, true);
|
||||
}
|
||||
|
||||
/////////// box with rotate spring, attached to static body
|
||||
/////////// box should swing (rotate) left-to-right forever
|
||||
{
|
||||
mass = 1.0;
|
||||
shape= new btBoxShape(btVector3(0.5,0.5,0.5));
|
||||
shape->calculateLocalInertia(mass,localInertia);
|
||||
bodyTransform.setIdentity();
|
||||
bodyTransform.getBasis().setEulerZYX(0,0,M_PI_2);
|
||||
motionState = new btDefaultMotionState(bodyTransform);
|
||||
m_data->m_RotateSpringBody = new btRigidBody(mass,motionState,shape,localInertia);
|
||||
m_data->m_RotateSpringBody->setActivationState(DISABLE_DEACTIVATION);
|
||||
m_dynamicsWorld->addRigidBody(m_data->m_RotateSpringBody);
|
||||
localA.setIdentity();localA.getOrigin() = btVector3(0,0,0);
|
||||
localB.setIdentity();localB.setOrigin(btVector3(0,0.5,0));
|
||||
constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_RotateSpringBody, localA, localB EXTRAPARAMS);
|
||||
constraint->setLimit(0, 0, 0);
|
||||
constraint->setLimit(1, 0, 0);
|
||||
constraint->setLimit(2, 0, 0);
|
||||
constraint->setLimit(3, 0, 0);
|
||||
constraint->setLimit(4, 0, 0);
|
||||
constraint->setLimit(5, 1, -1);
|
||||
constraint->enableSpring(5, true);
|
||||
constraint->setStiffness(5, 100);
|
||||
#ifdef USE_6DOF2
|
||||
constraint->setDamping(5, 0);
|
||||
#else
|
||||
constraint->setDamping(5, 1);
|
||||
#endif
|
||||
constraint->setEquilibriumPoint(0, 0);
|
||||
constraint->setDbgDrawSize(btScalar(2.f));
|
||||
m_dynamicsWorld->addConstraint(constraint, true);
|
||||
}
|
||||
|
||||
/////////// box with bouncing constraint, translation is bounced at the positive x limit, but not at the negative limit
|
||||
/////////// bouncing can not be set independently at low and high limits, so two constraints will be created: one that defines the low (non bouncing) limit, and one that defines the high (bouncing) limit
|
||||
/////////// the box should move to the left (as an impulse will be applied to it periodically) until it reaches its limit, then bounce back
|
||||
{
|
||||
mass = 1.0;
|
||||
shape= new btBoxShape(btVector3(0.5,0.5,0.5));
|
||||
shape->calculateLocalInertia(mass,localInertia);
|
||||
bodyTransform.setIdentity();
|
||||
bodyTransform.setOrigin(btVector3(0,0,-3));
|
||||
motionState = new btDefaultMotionState(bodyTransform);
|
||||
m_data->m_BouncingTranslateBody = new btRigidBody(mass,motionState,shape,localInertia);
|
||||
m_data->m_BouncingTranslateBody->setActivationState(DISABLE_DEACTIVATION);
|
||||
m_data->m_BouncingTranslateBody->setDeactivationTime(btScalar(20000000));
|
||||
m_dynamicsWorld->addRigidBody(m_data->m_BouncingTranslateBody);
|
||||
localA.setIdentity();localA.getOrigin() = btVector3(0,0,0);
|
||||
localB.setIdentity();
|
||||
constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_BouncingTranslateBody, localA, localB EXTRAPARAMS);
|
||||
constraint->setLimit(0, -2, SIMD_INFINITY);
|
||||
constraint->setLimit(1, 0, 0);
|
||||
constraint->setLimit(2, -3, -3);
|
||||
constraint->setLimit(3, 0, 0);
|
||||
constraint->setLimit(4, 0, 0);
|
||||
constraint->setLimit(5, 0, 0);
|
||||
#ifdef USE_6DOF2
|
||||
constraint->setBounce(0,0);
|
||||
#else //bounce is named restitution in 6dofspring, but not implemented for translational limit motor, so the following line has no effect
|
||||
constraint->getTranslationalLimitMotor()->m_restitution = 0.0;
|
||||
#endif
|
||||
constraint->setParam(BT_CONSTRAINT_STOP_ERP,0.995,0);
|
||||
constraint->setParam(BT_CONSTRAINT_STOP_CFM,0.0,0);
|
||||
constraint->setDbgDrawSize(btScalar(2.f));
|
||||
m_dynamicsWorld->addConstraint(constraint, true);
|
||||
constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_BouncingTranslateBody, localA, localB EXTRAPARAMS);
|
||||
constraint->setLimit(0, -SIMD_INFINITY, 2);
|
||||
constraint->setLimit(1, 0, 0);
|
||||
constraint->setLimit(2, -3, -3);
|
||||
constraint->setLimit(3, 0, 0);
|
||||
constraint->setLimit(4, 0, 0);
|
||||
constraint->setLimit(5, 0, 0);
|
||||
#ifdef USE_6DOF2
|
||||
constraint->setBounce(0,1);
|
||||
#else //bounce is named restitution in 6dofspring, but not implemented for translational limit motor, so the following line has no effect
|
||||
constraint->getTranslationalLimitMotor()->m_restitution = 1.0;
|
||||
#endif
|
||||
constraint->setParam(BT_CONSTRAINT_STOP_ERP,0.995,0);
|
||||
constraint->setParam(BT_CONSTRAINT_STOP_CFM,0.0,0);
|
||||
constraint->setDbgDrawSize(btScalar(2.f));
|
||||
m_dynamicsWorld->addConstraint(constraint, true);
|
||||
}
|
||||
|
||||
/////////// box with rotational motor, attached to static body
|
||||
/////////// the box should rotate around the y axis
|
||||
{
|
||||
mass = 1.0;
|
||||
shape= new btBoxShape(btVector3(0.5,0.5,0.5));
|
||||
shape->calculateLocalInertia(mass,localInertia);
|
||||
bodyTransform.setIdentity();
|
||||
bodyTransform.setOrigin(btVector3(4,0,0));
|
||||
motionState = new btDefaultMotionState(bodyTransform);
|
||||
m_data->m_MotorBody = new btRigidBody(mass,motionState,shape,localInertia);
|
||||
m_data->m_MotorBody->setActivationState(DISABLE_DEACTIVATION);
|
||||
m_dynamicsWorld->addRigidBody(m_data->m_MotorBody);
|
||||
localA.setIdentity();localA.getOrigin() = btVector3(4,0,0);
|
||||
localB.setIdentity();
|
||||
constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_MotorBody, localA, localB EXTRAPARAMS);
|
||||
constraint->setLimit(0, 0, 0);
|
||||
constraint->setLimit(1, 0, 0);
|
||||
constraint->setLimit(2, 0, 0);
|
||||
constraint->setLimit(3, 0, 0);
|
||||
constraint->setLimit(4, 0, 0);
|
||||
constraint->setLimit(5, 1,-1);
|
||||
#ifdef USE_6DOF2
|
||||
constraint->enableMotor(5,true);
|
||||
constraint->setTargetVelocity(5,3.f);
|
||||
constraint->setMaxMotorForce(5,10.f);
|
||||
#else
|
||||
constraint->getRotationalLimitMotor(2)->m_enableMotor = true;
|
||||
constraint->getRotationalLimitMotor(2)->m_targetVelocity = 3.f;
|
||||
constraint->getRotationalLimitMotor(2)->m_maxMotorForce = 10;
|
||||
#endif
|
||||
constraint->setDbgDrawSize(btScalar(2.f));
|
||||
m_dynamicsWorld->addConstraint(constraint, true);
|
||||
}
|
||||
|
||||
/////////// box with rotational servo motor, attached to static body
|
||||
/////////// the box should rotate around the y axis until it reaches its target
|
||||
/////////// the target will be negated periodically
|
||||
{
|
||||
mass = 1.0;
|
||||
shape= new btBoxShape(btVector3(0.5,0.5,0.5));
|
||||
shape->calculateLocalInertia(mass,localInertia);
|
||||
bodyTransform.setIdentity();
|
||||
bodyTransform.setOrigin(btVector3(7,0,0));
|
||||
motionState = new btDefaultMotionState(bodyTransform);
|
||||
m_data->m_ServoMotorBody = new btRigidBody(mass,motionState,shape,localInertia);
|
||||
m_data->m_ServoMotorBody->setActivationState(DISABLE_DEACTIVATION);
|
||||
m_dynamicsWorld->addRigidBody(m_data->m_ServoMotorBody);
|
||||
localA.setIdentity();localA.getOrigin() = btVector3(7,0,0);
|
||||
localB.setIdentity();
|
||||
constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_ServoMotorBody, localA, localB EXTRAPARAMS);
|
||||
constraint->setLimit(0, 0, 0);
|
||||
constraint->setLimit(1, 0, 0);
|
||||
constraint->setLimit(2, 0, 0);
|
||||
constraint->setLimit(3, 0, 0);
|
||||
constraint->setLimit(4, 0, 0);
|
||||
constraint->setLimit(5, 1,-1);
|
||||
#ifdef USE_6DOF2
|
||||
constraint->enableMotor(5,true);
|
||||
constraint->setTargetVelocity(5,3.f);
|
||||
constraint->setMaxMotorForce(5,10.f);
|
||||
constraint->setServo(5,true);
|
||||
constraint->setServoTarget(5, M_PI_2);
|
||||
#else
|
||||
constraint->getRotationalLimitMotor(2)->m_enableMotor = true;
|
||||
constraint->getRotationalLimitMotor(2)->m_targetVelocity = 3.f;
|
||||
constraint->getRotationalLimitMotor(2)->m_maxMotorForce = 10;
|
||||
//servo motor is not implemented in 6dofspring constraint
|
||||
#endif
|
||||
constraint->setDbgDrawSize(btScalar(2.f));
|
||||
m_dynamicsWorld->addConstraint(constraint, true);
|
||||
m_data->m_ServoMotorConstraint = constraint;
|
||||
}
|
||||
|
||||
////////// chain of boxes linked together with fully limited rotational and translational constraints
|
||||
////////// the chain will be pulled to the left and to the right periodically. They should strictly stick together.
|
||||
{
|
||||
btScalar limitConstraintStrength = 0.6;
|
||||
int bodycount = 10;
|
||||
btRigidBody* prevBody = 0;
|
||||
for(int i = 0; i < bodycount; ++i)
|
||||
{
|
||||
mass = 1.0;
|
||||
shape= new btBoxShape(btVector3(0.5,0.5,0.5));
|
||||
shape->calculateLocalInertia(mass,localInertia);
|
||||
bodyTransform.setIdentity();
|
||||
bodyTransform.setOrigin(btVector3(- i,0,3));
|
||||
motionState = new btDefaultMotionState(bodyTransform);
|
||||
btRigidBody* body = new btRigidBody(mass,motionState,shape,localInertia);
|
||||
body->setActivationState(DISABLE_DEACTIVATION);
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
if(prevBody != 0)
|
||||
{
|
||||
localB.setIdentity();
|
||||
localB.setOrigin(btVector3(0.5,0,0));
|
||||
btTransform localA;
|
||||
localA.setIdentity();
|
||||
localA.setOrigin(btVector3(-0.5,0,0));
|
||||
CONSTRAINT_TYPE* constraint = new CONSTRAINT_TYPE(*prevBody, *body, localA, localB EXTRAPARAMS);
|
||||
constraint->setLimit(0, -0.01, 0.01);
|
||||
constraint->setLimit(1, 0, 0);
|
||||
constraint->setLimit(2, 0, 0);
|
||||
constraint->setLimit(3, 0, 0);
|
||||
constraint->setLimit(4, 0, 0);
|
||||
constraint->setLimit(5, 0, 0);
|
||||
for(int a = 0; a < 6; ++a)
|
||||
{
|
||||
constraint->setParam(BT_CONSTRAINT_STOP_ERP,0.9,a);
|
||||
constraint->setParam(BT_CONSTRAINT_STOP_CFM,0.0,a);
|
||||
}
|
||||
constraint->setDbgDrawSize(btScalar(1.f));
|
||||
m_dynamicsWorld->addConstraint(constraint, true);
|
||||
|
||||
if(i < bodycount - 1)
|
||||
{
|
||||
localA.setIdentity();localA.getOrigin() = btVector3(0,0,3);
|
||||
localB.setIdentity();
|
||||
CONSTRAINT_TYPE* constraintZY = new CONSTRAINT_TYPE(*staticBody, *body, localA, localB EXTRAPARAMS);
|
||||
constraintZY->setLimit(0, 1, -1);
|
||||
constraintZY->setDbgDrawSize(btScalar(1.f));
|
||||
m_dynamicsWorld->addConstraint(constraintZY, true);
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
localA.setIdentity();localA.getOrigin() = btVector3(bodycount,0,3);
|
||||
localB.setIdentity();
|
||||
localB.setOrigin(btVector3(0,0,0));
|
||||
m_data->m_ChainLeftBody = body;
|
||||
m_data->m_ChainLeftConstraint = new CONSTRAINT_TYPE(*staticBody, *body, localA, localB EXTRAPARAMS);
|
||||
m_data->m_ChainLeftConstraint->setLimit(3,0,0);
|
||||
m_data->m_ChainLeftConstraint->setLimit(4,0,0);
|
||||
m_data->m_ChainLeftConstraint->setLimit(5,0,0);
|
||||
for(int a = 0; a < 6; ++a)
|
||||
{
|
||||
m_data->m_ChainLeftConstraint->setParam(BT_CONSTRAINT_STOP_ERP,limitConstraintStrength,a);
|
||||
m_data->m_ChainLeftConstraint->setParam(BT_CONSTRAINT_STOP_CFM,0.0,a);
|
||||
}
|
||||
m_data->m_ChainLeftConstraint->setDbgDrawSize(btScalar(1.f));
|
||||
m_dynamicsWorld->addConstraint(m_data->m_ChainLeftConstraint, true);
|
||||
}
|
||||
prevBody = body;
|
||||
}
|
||||
m_data->m_ChainRightBody = prevBody;
|
||||
localA.setIdentity();localA.getOrigin() = btVector3(-bodycount,0,3);
|
||||
localB.setIdentity();
|
||||
localB.setOrigin(btVector3(0,0,0));
|
||||
m_data->m_ChainRightConstraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_ChainRightBody, localA, localB EXTRAPARAMS);
|
||||
m_data->m_ChainRightConstraint->setLimit(3,0,0);
|
||||
m_data->m_ChainRightConstraint->setLimit(4,0,0);
|
||||
m_data->m_ChainRightConstraint->setLimit(5,0,0);
|
||||
for(int a = 0; a < 6; ++a)
|
||||
{
|
||||
m_data->m_ChainRightConstraint->setParam(BT_CONSTRAINT_STOP_ERP,limitConstraintStrength,a);
|
||||
m_data->m_ChainRightConstraint->setParam(BT_CONSTRAINT_STOP_CFM,0.0,a);
|
||||
}
|
||||
}
|
||||
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
|
||||
}
|
||||
|
||||
|
||||
void Dof6Spring2Setup::animate()
|
||||
{
|
||||
|
||||
/////// servo motor: flip its target periodically
|
||||
m_data->m_TranslateSpringBody = new btRigidBody(mass, motionState, shape, localInertia);
|
||||
m_data->m_TranslateSpringBody->setActivationState(DISABLE_DEACTIVATION);
|
||||
m_dynamicsWorld->addRigidBody(m_data->m_TranslateSpringBody);
|
||||
localA.setIdentity();
|
||||
localA.getOrigin() = btVector3(0, 0, -5);
|
||||
localB.setIdentity();
|
||||
constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_TranslateSpringBody, localA, localB EXTRAPARAMS);
|
||||
constraint->setLimit(0, 1, -1);
|
||||
constraint->setLimit(1, 0, 0);
|
||||
constraint->setLimit(2, 0, 0);
|
||||
constraint->setLimit(3, 0, 0);
|
||||
constraint->setLimit(4, 0, 0);
|
||||
constraint->setLimit(5, 0, 0);
|
||||
constraint->enableSpring(0, true);
|
||||
constraint->setStiffness(0, 100);
|
||||
#ifdef USE_6DOF2
|
||||
static float servoNextFrame = -1;
|
||||
btScalar pos = m_data->m_ServoMotorConstraint->getRotationalLimitMotor(2)->m_currentPosition;
|
||||
btScalar target = m_data->m_ServoMotorConstraint->getRotationalLimitMotor(2)->m_servoTarget;
|
||||
if(servoNextFrame < 0)
|
||||
{
|
||||
m_data->m_ServoMotorConstraint->getRotationalLimitMotor(2)->m_servoTarget *= -1;
|
||||
servoNextFrame = 3.0;
|
||||
}
|
||||
servoNextFrame -= m_data->mDt;
|
||||
constraint->setDamping(0, 0);
|
||||
#else
|
||||
constraint->setDamping(0, 1);
|
||||
#endif
|
||||
constraint->setEquilibriumPoint(0, 0);
|
||||
constraint->setDbgDrawSize(btScalar(2.f));
|
||||
m_dynamicsWorld->addConstraint(constraint, true);
|
||||
}
|
||||
|
||||
/////// constraint chain: pull the chain left and right periodically
|
||||
static float chainNextFrame = -1;
|
||||
static bool left = true;
|
||||
if(chainNextFrame < 0)
|
||||
/////////// box with rotate spring, attached to static body
|
||||
/////////// box should swing (rotate) left-to-right forever
|
||||
{
|
||||
mass = 1.0;
|
||||
shape = new btBoxShape(btVector3(0.5, 0.5, 0.5));
|
||||
shape->calculateLocalInertia(mass, localInertia);
|
||||
bodyTransform.setIdentity();
|
||||
bodyTransform.getBasis().setEulerZYX(0, 0, M_PI_2);
|
||||
motionState = new btDefaultMotionState(bodyTransform);
|
||||
m_data->m_RotateSpringBody = new btRigidBody(mass, motionState, shape, localInertia);
|
||||
m_data->m_RotateSpringBody->setActivationState(DISABLE_DEACTIVATION);
|
||||
m_dynamicsWorld->addRigidBody(m_data->m_RotateSpringBody);
|
||||
localA.setIdentity();
|
||||
localA.getOrigin() = btVector3(0, 0, 0);
|
||||
localB.setIdentity();
|
||||
localB.setOrigin(btVector3(0, 0.5, 0));
|
||||
constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_RotateSpringBody, localA, localB EXTRAPARAMS);
|
||||
constraint->setLimit(0, 0, 0);
|
||||
constraint->setLimit(1, 0, 0);
|
||||
constraint->setLimit(2, 0, 0);
|
||||
constraint->setLimit(3, 0, 0);
|
||||
constraint->setLimit(4, 0, 0);
|
||||
constraint->setLimit(5, 1, -1);
|
||||
constraint->enableSpring(5, true);
|
||||
constraint->setStiffness(5, 100);
|
||||
#ifdef USE_6DOF2
|
||||
constraint->setDamping(5, 0);
|
||||
#else
|
||||
constraint->setDamping(5, 1);
|
||||
#endif
|
||||
constraint->setEquilibriumPoint(0, 0);
|
||||
constraint->setDbgDrawSize(btScalar(2.f));
|
||||
m_dynamicsWorld->addConstraint(constraint, true);
|
||||
}
|
||||
|
||||
/////////// box with bouncing constraint, translation is bounced at the positive x limit, but not at the negative limit
|
||||
/////////// bouncing can not be set independently at low and high limits, so two constraints will be created: one that defines the low (non bouncing) limit, and one that defines the high (bouncing) limit
|
||||
/////////// the box should move to the left (as an impulse will be applied to it periodically) until it reaches its limit, then bounce back
|
||||
{
|
||||
mass = 1.0;
|
||||
shape = new btBoxShape(btVector3(0.5, 0.5, 0.5));
|
||||
shape->calculateLocalInertia(mass, localInertia);
|
||||
bodyTransform.setIdentity();
|
||||
bodyTransform.setOrigin(btVector3(0, 0, -3));
|
||||
motionState = new btDefaultMotionState(bodyTransform);
|
||||
m_data->m_BouncingTranslateBody = new btRigidBody(mass, motionState, shape, localInertia);
|
||||
m_data->m_BouncingTranslateBody->setActivationState(DISABLE_DEACTIVATION);
|
||||
m_data->m_BouncingTranslateBody->setDeactivationTime(btScalar(20000000));
|
||||
m_dynamicsWorld->addRigidBody(m_data->m_BouncingTranslateBody);
|
||||
localA.setIdentity();
|
||||
localA.getOrigin() = btVector3(0, 0, 0);
|
||||
localB.setIdentity();
|
||||
constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_BouncingTranslateBody, localA, localB EXTRAPARAMS);
|
||||
constraint->setLimit(0, -2, SIMD_INFINITY);
|
||||
constraint->setLimit(1, 0, 0);
|
||||
constraint->setLimit(2, -3, -3);
|
||||
constraint->setLimit(3, 0, 0);
|
||||
constraint->setLimit(4, 0, 0);
|
||||
constraint->setLimit(5, 0, 0);
|
||||
#ifdef USE_6DOF2
|
||||
constraint->setBounce(0, 0);
|
||||
#else //bounce is named restitution in 6dofspring, but not implemented for translational limit motor, so the following line has no effect
|
||||
constraint->getTranslationalLimitMotor()->m_restitution = 0.0;
|
||||
#endif
|
||||
constraint->setParam(BT_CONSTRAINT_STOP_ERP, 0.995, 0);
|
||||
constraint->setParam(BT_CONSTRAINT_STOP_CFM, 0.0, 0);
|
||||
constraint->setDbgDrawSize(btScalar(2.f));
|
||||
m_dynamicsWorld->addConstraint(constraint, true);
|
||||
constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_BouncingTranslateBody, localA, localB EXTRAPARAMS);
|
||||
constraint->setLimit(0, -SIMD_INFINITY, 2);
|
||||
constraint->setLimit(1, 0, 0);
|
||||
constraint->setLimit(2, -3, -3);
|
||||
constraint->setLimit(3, 0, 0);
|
||||
constraint->setLimit(4, 0, 0);
|
||||
constraint->setLimit(5, 0, 0);
|
||||
#ifdef USE_6DOF2
|
||||
constraint->setBounce(0, 1);
|
||||
#else //bounce is named restitution in 6dofspring, but not implemented for translational limit motor, so the following line has no effect
|
||||
constraint->getTranslationalLimitMotor()->m_restitution = 1.0;
|
||||
#endif
|
||||
constraint->setParam(BT_CONSTRAINT_STOP_ERP, 0.995, 0);
|
||||
constraint->setParam(BT_CONSTRAINT_STOP_CFM, 0.0, 0);
|
||||
constraint->setDbgDrawSize(btScalar(2.f));
|
||||
m_dynamicsWorld->addConstraint(constraint, true);
|
||||
}
|
||||
|
||||
/////////// box with rotational motor, attached to static body
|
||||
/////////// the box should rotate around the y axis
|
||||
{
|
||||
mass = 1.0;
|
||||
shape = new btBoxShape(btVector3(0.5, 0.5, 0.5));
|
||||
shape->calculateLocalInertia(mass, localInertia);
|
||||
bodyTransform.setIdentity();
|
||||
bodyTransform.setOrigin(btVector3(4, 0, 0));
|
||||
motionState = new btDefaultMotionState(bodyTransform);
|
||||
m_data->m_MotorBody = new btRigidBody(mass, motionState, shape, localInertia);
|
||||
m_data->m_MotorBody->setActivationState(DISABLE_DEACTIVATION);
|
||||
m_dynamicsWorld->addRigidBody(m_data->m_MotorBody);
|
||||
localA.setIdentity();
|
||||
localA.getOrigin() = btVector3(4, 0, 0);
|
||||
localB.setIdentity();
|
||||
constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_MotorBody, localA, localB EXTRAPARAMS);
|
||||
constraint->setLimit(0, 0, 0);
|
||||
constraint->setLimit(1, 0, 0);
|
||||
constraint->setLimit(2, 0, 0);
|
||||
constraint->setLimit(3, 0, 0);
|
||||
constraint->setLimit(4, 0, 0);
|
||||
constraint->setLimit(5, 1, -1);
|
||||
#ifdef USE_6DOF2
|
||||
constraint->enableMotor(5, true);
|
||||
constraint->setTargetVelocity(5, 3.f);
|
||||
constraint->setMaxMotorForce(5, 600.f);
|
||||
#else
|
||||
constraint->getRotationalLimitMotor(2)->m_enableMotor = true;
|
||||
constraint->getRotationalLimitMotor(2)->m_targetVelocity = 3.f;
|
||||
constraint->getRotationalLimitMotor(2)->m_maxMotorForce = 600.f;
|
||||
#endif
|
||||
constraint->setDbgDrawSize(btScalar(2.f));
|
||||
m_dynamicsWorld->addConstraint(constraint, true);
|
||||
}
|
||||
|
||||
/////////// box with rotational servo motor, attached to static body
|
||||
/////////// the box should rotate around the y axis until it reaches its target
|
||||
/////////// the target will be negated periodically
|
||||
{
|
||||
mass = 1.0;
|
||||
shape = new btBoxShape(btVector3(0.5, 0.5, 0.5));
|
||||
shape->calculateLocalInertia(mass, localInertia);
|
||||
bodyTransform.setIdentity();
|
||||
bodyTransform.setOrigin(btVector3(7, 0, 0));
|
||||
motionState = new btDefaultMotionState(bodyTransform);
|
||||
m_data->m_ServoMotorBody = new btRigidBody(mass, motionState, shape, localInertia);
|
||||
m_data->m_ServoMotorBody->setActivationState(DISABLE_DEACTIVATION);
|
||||
m_dynamicsWorld->addRigidBody(m_data->m_ServoMotorBody);
|
||||
localA.setIdentity();
|
||||
localA.getOrigin() = btVector3(7, 0, 0);
|
||||
localB.setIdentity();
|
||||
constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_ServoMotorBody, localA, localB EXTRAPARAMS);
|
||||
constraint->setLimit(0, 0, 0);
|
||||
constraint->setLimit(1, 0, 0);
|
||||
constraint->setLimit(2, 0, 0);
|
||||
constraint->setLimit(3, 0, 0);
|
||||
constraint->setLimit(4, 0, 0);
|
||||
constraint->setLimit(5, 1, -1);
|
||||
#ifdef USE_6DOF2
|
||||
constraint->enableMotor(5, true);
|
||||
constraint->setTargetVelocity(5, 3.f);
|
||||
constraint->setMaxMotorForce(5, 600.f);
|
||||
constraint->setServo(5, true);
|
||||
constraint->setServoTarget(5, M_PI_2);
|
||||
#else
|
||||
constraint->getRotationalLimitMotor(2)->m_enableMotor = true;
|
||||
constraint->getRotationalLimitMotor(2)->m_targetVelocity = 3.f;
|
||||
constraint->getRotationalLimitMotor(2)->m_maxMotorForce = 600.f;
|
||||
//servo motor is not implemented in 6dofspring constraint
|
||||
#endif
|
||||
constraint->setDbgDrawSize(btScalar(2.f));
|
||||
m_dynamicsWorld->addConstraint(constraint, true);
|
||||
m_data->m_ServoMotorConstraint = constraint;
|
||||
}
|
||||
|
||||
////////// chain of boxes linked together with fully limited rotational and translational constraints
|
||||
////////// the chain will be pulled to the left and to the right periodically. They should strictly stick together.
|
||||
{
|
||||
btScalar limitConstraintStrength = 0.6;
|
||||
int bodycount = 10;
|
||||
btRigidBody* prevBody = 0;
|
||||
for (int i = 0; i < bodycount; ++i)
|
||||
{
|
||||
if(!left)
|
||||
mass = 1.0;
|
||||
shape = new btBoxShape(btVector3(0.5, 0.5, 0.5));
|
||||
shape->calculateLocalInertia(mass, localInertia);
|
||||
bodyTransform.setIdentity();
|
||||
bodyTransform.setOrigin(btVector3(-i, 0, 3));
|
||||
motionState = new btDefaultMotionState(bodyTransform);
|
||||
btRigidBody* body = new btRigidBody(mass, motionState, shape, localInertia);
|
||||
body->setActivationState(DISABLE_DEACTIVATION);
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
if (prevBody != 0)
|
||||
{
|
||||
m_data->m_ChainRightBody->setActivationState(ACTIVE_TAG);
|
||||
m_dynamicsWorld->removeConstraint(m_data->m_ChainRightConstraint);
|
||||
m_data->m_ChainLeftConstraint->setDbgDrawSize(btScalar(2.f));
|
||||
m_dynamicsWorld->addConstraint(m_data->m_ChainLeftConstraint, true);
|
||||
localB.setIdentity();
|
||||
localB.setOrigin(btVector3(0.5, 0, 0));
|
||||
btTransform localA;
|
||||
localA.setIdentity();
|
||||
localA.setOrigin(btVector3(-0.5, 0, 0));
|
||||
CONSTRAINT_TYPE* constraint = new CONSTRAINT_TYPE(*prevBody, *body, localA, localB EXTRAPARAMS);
|
||||
constraint->setLimit(0, -0.01, 0.01);
|
||||
constraint->setLimit(1, 0, 0);
|
||||
constraint->setLimit(2, 0, 0);
|
||||
constraint->setLimit(3, 0, 0);
|
||||
constraint->setLimit(4, 0, 0);
|
||||
constraint->setLimit(5, 0, 0);
|
||||
for (int a = 0; a < 6; ++a)
|
||||
{
|
||||
constraint->setParam(BT_CONSTRAINT_STOP_ERP, 0.9, a);
|
||||
constraint->setParam(BT_CONSTRAINT_STOP_CFM, 0.0, a);
|
||||
}
|
||||
constraint->setDbgDrawSize(btScalar(1.f));
|
||||
m_dynamicsWorld->addConstraint(constraint, true);
|
||||
|
||||
if (i < bodycount - 1)
|
||||
{
|
||||
localA.setIdentity();
|
||||
localA.getOrigin() = btVector3(0, 0, 3);
|
||||
localB.setIdentity();
|
||||
CONSTRAINT_TYPE* constraintZY = new CONSTRAINT_TYPE(*staticBody, *body, localA, localB EXTRAPARAMS);
|
||||
constraintZY->setLimit(0, 1, -1);
|
||||
constraintZY->setDbgDrawSize(btScalar(1.f));
|
||||
m_dynamicsWorld->addConstraint(constraintZY, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_data->m_ChainLeftBody->setActivationState(ACTIVE_TAG);
|
||||
m_dynamicsWorld->removeConstraint(m_data->m_ChainLeftConstraint);
|
||||
m_data->m_ChainRightConstraint->setDbgDrawSize(btScalar(2.f));
|
||||
m_dynamicsWorld->addConstraint(m_data->m_ChainRightConstraint, true);
|
||||
localA.setIdentity();
|
||||
localA.getOrigin() = btVector3(bodycount, 0, 3);
|
||||
localB.setIdentity();
|
||||
localB.setOrigin(btVector3(0, 0, 0));
|
||||
m_data->m_ChainLeftBody = body;
|
||||
m_data->m_ChainLeftConstraint = new CONSTRAINT_TYPE(*staticBody, *body, localA, localB EXTRAPARAMS);
|
||||
m_data->m_ChainLeftConstraint->setLimit(3, 0, 0);
|
||||
m_data->m_ChainLeftConstraint->setLimit(4, 0, 0);
|
||||
m_data->m_ChainLeftConstraint->setLimit(5, 0, 0);
|
||||
for (int a = 0; a < 6; ++a)
|
||||
{
|
||||
m_data->m_ChainLeftConstraint->setParam(BT_CONSTRAINT_STOP_ERP, limitConstraintStrength, a);
|
||||
m_data->m_ChainLeftConstraint->setParam(BT_CONSTRAINT_STOP_CFM, 0.0, a);
|
||||
}
|
||||
m_data->m_ChainLeftConstraint->setDbgDrawSize(btScalar(1.f));
|
||||
m_dynamicsWorld->addConstraint(m_data->m_ChainLeftConstraint, true);
|
||||
}
|
||||
chainNextFrame = 3.0;
|
||||
left = !left;
|
||||
prevBody = body;
|
||||
}
|
||||
chainNextFrame -= m_data->mDt;
|
||||
|
||||
/////// bouncing constraint: push the box periodically
|
||||
m_data->m_BouncingTranslateBody->setActivationState(ACTIVE_TAG);
|
||||
static float bounceNextFrame = -1;
|
||||
if(bounceNextFrame < 0)
|
||||
m_data->m_ChainRightBody = prevBody;
|
||||
localA.setIdentity();
|
||||
localA.getOrigin() = btVector3(-bodycount, 0, 3);
|
||||
localB.setIdentity();
|
||||
localB.setOrigin(btVector3(0, 0, 0));
|
||||
m_data->m_ChainRightConstraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_ChainRightBody, localA, localB EXTRAPARAMS);
|
||||
m_data->m_ChainRightConstraint->setLimit(3, 0, 0);
|
||||
m_data->m_ChainRightConstraint->setLimit(4, 0, 0);
|
||||
m_data->m_ChainRightConstraint->setLimit(5, 0, 0);
|
||||
for (int a = 0; a < 6; ++a)
|
||||
{
|
||||
m_data->m_BouncingTranslateBody->applyCentralImpulse(btVector3(10,0,0));
|
||||
bounceNextFrame = 3.0;
|
||||
m_data->m_ChainRightConstraint->setParam(BT_CONSTRAINT_STOP_ERP, limitConstraintStrength, a);
|
||||
m_data->m_ChainRightConstraint->setParam(BT_CONSTRAINT_STOP_CFM, 0.0, a);
|
||||
}
|
||||
bounceNextFrame -= m_data->mDt;
|
||||
|
||||
m_data->frameID++;
|
||||
}
|
||||
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
|
||||
}
|
||||
|
||||
void Dof6Spring2Setup::animate()
|
||||
{
|
||||
/////// servo motor: flip its target periodically
|
||||
#ifdef USE_6DOF2
|
||||
static float servoNextFrame = -1;
|
||||
if (servoNextFrame < 0)
|
||||
{
|
||||
m_data->m_ServoMotorConstraint->getRotationalLimitMotor(2)->m_servoTarget *= -1;
|
||||
servoNextFrame = 3.0;
|
||||
}
|
||||
servoNextFrame -= m_data->mDt;
|
||||
#endif
|
||||
|
||||
/////// constraint chain: pull the chain left and right periodically
|
||||
static float chainNextFrame = -1;
|
||||
static bool left = true;
|
||||
if (chainNextFrame < 0)
|
||||
{
|
||||
if (!left)
|
||||
{
|
||||
m_data->m_ChainRightBody->setActivationState(ACTIVE_TAG);
|
||||
m_dynamicsWorld->removeConstraint(m_data->m_ChainRightConstraint);
|
||||
m_data->m_ChainLeftConstraint->setDbgDrawSize(btScalar(2.f));
|
||||
m_dynamicsWorld->addConstraint(m_data->m_ChainLeftConstraint, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_data->m_ChainLeftBody->setActivationState(ACTIVE_TAG);
|
||||
m_dynamicsWorld->removeConstraint(m_data->m_ChainLeftConstraint);
|
||||
m_data->m_ChainRightConstraint->setDbgDrawSize(btScalar(2.f));
|
||||
m_dynamicsWorld->addConstraint(m_data->m_ChainRightConstraint, true);
|
||||
}
|
||||
chainNextFrame = 3.0;
|
||||
left = !left;
|
||||
}
|
||||
chainNextFrame -= m_data->mDt;
|
||||
|
||||
/////// bouncing constraint: push the box periodically
|
||||
m_data->m_BouncingTranslateBody->setActivationState(ACTIVE_TAG);
|
||||
static float bounceNextFrame = -1;
|
||||
if (bounceNextFrame < 0)
|
||||
{
|
||||
m_data->m_BouncingTranslateBody->applyCentralImpulse(btVector3(10, 0, 0));
|
||||
bounceNextFrame = 3.0;
|
||||
}
|
||||
bounceNextFrame -= m_data->mDt;
|
||||
|
||||
m_data->frameID++;
|
||||
}
|
||||
|
||||
void Dof6Spring2Setup::stepSimulation(float deltaTime)
|
||||
{
|
||||
|
|
@ -497,7 +492,7 @@ void Dof6Spring2Setup::stepSimulation(float deltaTime)
|
|||
m_dynamicsWorld->stepSimulation(deltaTime);
|
||||
}
|
||||
|
||||
class CommonExampleInterface* Dof6Spring2CreateFunc( CommonExampleOptions& options)
|
||||
class CommonExampleInterface* Dof6Spring2CreateFunc(CommonExampleOptions& options)
|
||||
{
|
||||
return new Dof6Spring2Setup(options.m_guiHelper);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#ifndef GENERIC_6DOF_SPRING2_CONSTRAINT_DEMO_H
|
||||
#define GENERIC_6DOF_SPRING2_CONSTRAINT_DEMO_H
|
||||
|
||||
class CommonExampleInterface* Dof6Spring2CreateFunc(struct CommonExampleOptions& options);
|
||||
class CommonExampleInterface* Dof6Spring2CreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
#endif //GENERIC_6DOF_SPRING2_CONSTRAINT_DEMO_H
|
||||
#endif //GENERIC_6DOF_SPRING2_CONSTRAINT_DEMO_H
|
||||
|
|
|
|||
|
|
@ -1,108 +1,96 @@
|
|||
#include "TestHingeTorque.h"
|
||||
|
||||
|
||||
#include "../CommonInterfaces/CommonRigidBodyBase.h"
|
||||
#include "../CommonInterfaces/CommonParameterInterface.h"
|
||||
|
||||
short collisionFilterGroup = short(btBroadphaseProxy::CharacterFilter);
|
||||
short collisionFilterMask = short(btBroadphaseProxy::AllFilter ^ (btBroadphaseProxy::CharacterFilter));
|
||||
int collisionFilterGroup = int(btBroadphaseProxy::CharacterFilter);
|
||||
int collisionFilterMask = int(btBroadphaseProxy::AllFilter ^ (btBroadphaseProxy::CharacterFilter));
|
||||
static btScalar radius(0.2);
|
||||
|
||||
struct TestHingeTorque : public CommonRigidBodyBase
|
||||
{
|
||||
bool m_once;
|
||||
btAlignedObjectArray<btJointFeedback*> m_jointFeedback;
|
||||
bool m_once;
|
||||
btAlignedObjectArray<btJointFeedback*> m_jointFeedback;
|
||||
|
||||
TestHingeTorque(struct GUIHelperInterface* helper);
|
||||
virtual ~ TestHingeTorque();
|
||||
virtual ~TestHingeTorque();
|
||||
virtual void initPhysics();
|
||||
|
||||
virtual void stepSimulation(float deltaTime);
|
||||
|
||||
|
||||
virtual void resetCamera()
|
||||
{
|
||||
|
||||
float dist = 5;
|
||||
float pitch = 270;
|
||||
float yaw = 21;
|
||||
float targetPos[3]={-1.34,3.4,-0.44};
|
||||
m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
|
||||
float dist = 5;
|
||||
float pitch = -21;
|
||||
float yaw = 270;
|
||||
float targetPos[3] = {-1.34, 3.4, -0.44};
|
||||
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
TestHingeTorque::TestHingeTorque(struct GUIHelperInterface* helper)
|
||||
:CommonRigidBodyBase(helper),
|
||||
m_once(true)
|
||||
: CommonRigidBodyBase(helper),
|
||||
m_once(true)
|
||||
{
|
||||
}
|
||||
TestHingeTorque::~ TestHingeTorque()
|
||||
TestHingeTorque::~TestHingeTorque()
|
||||
{
|
||||
for (int i=0;i<m_jointFeedback.size();i++)
|
||||
for (int i = 0; i < m_jointFeedback.size(); i++)
|
||||
{
|
||||
delete m_jointFeedback[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void TestHingeTorque::stepSimulation(float deltaTime)
|
||||
{
|
||||
if (0)//m_once)
|
||||
{
|
||||
m_once=false;
|
||||
btHingeConstraint* hinge = (btHingeConstraint*)m_dynamicsWorld->getConstraint(0);
|
||||
|
||||
btRigidBody& bodyA = hinge->getRigidBodyA();
|
||||
btTransform trA = bodyA.getWorldTransform();
|
||||
btVector3 hingeAxisInWorld = trA.getBasis()*hinge->getFrameOffsetA().getBasis().getColumn(2);
|
||||
hinge->getRigidBodyA().applyTorque(-hingeAxisInWorld*10);
|
||||
hinge->getRigidBodyB().applyTorque(hingeAxisInWorld*10);
|
||||
|
||||
}
|
||||
|
||||
m_dynamicsWorld->stepSimulation(1./240,0);
|
||||
|
||||
if (0) //m_once)
|
||||
{
|
||||
m_once = false;
|
||||
btHingeConstraint* hinge = (btHingeConstraint*)m_dynamicsWorld->getConstraint(0);
|
||||
|
||||
btRigidBody& bodyA = hinge->getRigidBodyA();
|
||||
btTransform trA = bodyA.getWorldTransform();
|
||||
btVector3 hingeAxisInWorld = trA.getBasis() * hinge->getFrameOffsetA().getBasis().getColumn(2);
|
||||
hinge->getRigidBodyA().applyTorque(-hingeAxisInWorld * 10);
|
||||
hinge->getRigidBodyB().applyTorque(hingeAxisInWorld * 10);
|
||||
}
|
||||
|
||||
m_dynamicsWorld->stepSimulation(1. / 240, 0);
|
||||
|
||||
static int count = 0;
|
||||
if ((count& 0x0f)==0)
|
||||
if ((count & 0x0f) == 0)
|
||||
{
|
||||
btRigidBody* base = btRigidBody::upcast(m_dynamicsWorld->getCollisionObjectArray()[0]);
|
||||
|
||||
b3Printf("base angvel = %f,%f,%f",base->getAngularVelocity()[0],
|
||||
|
||||
b3Printf("base angvel = %f,%f,%f", base->getAngularVelocity()[0],
|
||||
base->getAngularVelocity()[1],
|
||||
|
||||
|
||||
base->getAngularVelocity()[2]);
|
||||
|
||||
|
||||
btRigidBody* child = btRigidBody::upcast(m_dynamicsWorld->getCollisionObjectArray()[1]);
|
||||
|
||||
|
||||
b3Printf("child angvel = %f,%f,%f",child->getAngularVelocity()[0],
|
||||
|
||||
b3Printf("child angvel = %f,%f,%f", child->getAngularVelocity()[0],
|
||||
child->getAngularVelocity()[1],
|
||||
|
||||
child->getAngularVelocity()[2]);
|
||||
|
||||
for (int i=0;i<m_jointFeedback.size();i++)
|
||||
|
||||
for (int i = 0; i < m_jointFeedback.size(); i++)
|
||||
{
|
||||
b3Printf("Applied force at the COM/Inertial frame B[%d]:(%f,%f,%f), torque B:(%f,%f,%f)\n", i,
|
||||
|
||||
|
||||
m_jointFeedback[i]->m_appliedForceBodyB.x(),
|
||||
m_jointFeedback[i]->m_appliedForceBodyB.y(),
|
||||
m_jointFeedback[i]->m_appliedForceBodyB.z(),
|
||||
m_jointFeedback[i]->m_appliedTorqueBodyB.x(),
|
||||
m_jointFeedback[i]->m_appliedTorqueBodyB.y(),
|
||||
m_jointFeedback[i]->m_appliedTorqueBodyB.z());
|
||||
m_jointFeedback[i]->m_appliedForceBodyB.x(),
|
||||
m_jointFeedback[i]->m_appliedForceBodyB.y(),
|
||||
m_jointFeedback[i]->m_appliedForceBodyB.z(),
|
||||
m_jointFeedback[i]->m_appliedTorqueBodyB.x(),
|
||||
m_jointFeedback[i]->m_appliedTorqueBodyB.y(),
|
||||
m_jointFeedback[i]->m_appliedTorqueBodyB.z());
|
||||
}
|
||||
}
|
||||
count++;
|
||||
|
||||
//CommonRigidBodyBase::stepSimulation(deltaTime);
|
||||
//CommonRigidBodyBase::stepSimulation(deltaTime);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void TestHingeTorque::initPhysics()
|
||||
{
|
||||
int upAxis = 1;
|
||||
|
|
@ -110,94 +98,89 @@ void TestHingeTorque::initPhysics()
|
|||
|
||||
createEmptyDynamicsWorld();
|
||||
m_dynamicsWorld->getSolverInfo().m_splitImpulse = false;
|
||||
|
||||
m_dynamicsWorld->setGravity(btVector3(0,0,-10));
|
||||
|
||||
|
||||
m_dynamicsWorld->setGravity(btVector3(0, 0, -10));
|
||||
|
||||
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
|
||||
int mode = btIDebugDraw::DBG_DrawWireframe
|
||||
+btIDebugDraw::DBG_DrawConstraints
|
||||
+btIDebugDraw::DBG_DrawConstraintLimits;
|
||||
int mode = btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawConstraints + btIDebugDraw::DBG_DrawConstraintLimits;
|
||||
m_dynamicsWorld->getDebugDrawer()->setDebugMode(mode);
|
||||
|
||||
{ // create a door using hinge constraint attached to the world
|
||||
|
||||
{ // create a door using hinge constraint attached to the world
|
||||
|
||||
int numLinks = 2;
|
||||
bool spherical = false; //set it ot false -to use 1DoF hinges instead of 3DoF sphericals
|
||||
bool canSleep = false;
|
||||
bool selfCollide = false;
|
||||
btVector3 linkHalfExtents(0.05, 0.37, 0.1);
|
||||
btVector3 baseHalfExtents(0.05, 0.37, 0.1);
|
||||
int numLinks = 2;
|
||||
// bool selfCollide = false;
|
||||
btVector3 linkHalfExtents(0.05, 0.37, 0.1);
|
||||
btVector3 baseHalfExtents(0.05, 0.37, 0.1);
|
||||
|
||||
btBoxShape* baseBox = new btBoxShape(baseHalfExtents);
|
||||
btVector3 basePosition = btVector3(-0.4f, 3.f, 0.f);
|
||||
btTransform baseWorldTrans;
|
||||
baseWorldTrans.setIdentity();
|
||||
baseWorldTrans.setOrigin(basePosition);
|
||||
|
||||
//mbC->forceMultiDof(); //if !spherical, you can comment this line to check the 1DoF algorithm
|
||||
//init the base
|
||||
btVector3 baseInertiaDiag(0.f, 0.f, 0.f);
|
||||
float baseMass = 0.f;
|
||||
float linkMass = 1.f;
|
||||
|
||||
btRigidBody* base = createRigidBody(baseMass,baseWorldTrans,baseBox);
|
||||
m_dynamicsWorld->removeRigidBody(base);
|
||||
base->setDamping(0,0);
|
||||
m_dynamicsWorld->addRigidBody(base,collisionFilterGroup,collisionFilterMask);
|
||||
btBoxShape* linkBox1 = new btBoxShape(linkHalfExtents);
|
||||
btBoxShape* baseBox = new btBoxShape(baseHalfExtents);
|
||||
btVector3 basePosition = btVector3(-0.4f, 3.f, 0.f);
|
||||
btTransform baseWorldTrans;
|
||||
baseWorldTrans.setIdentity();
|
||||
baseWorldTrans.setOrigin(basePosition);
|
||||
|
||||
//mbC->forceMultiDof(); //if !spherical, you can comment this line to check the 1DoF algorithm
|
||||
//init the base
|
||||
btVector3 baseInertiaDiag(0.f, 0.f, 0.f);
|
||||
float baseMass = 0.f;
|
||||
float linkMass = 1.f;
|
||||
|
||||
btRigidBody* base = createRigidBody(baseMass, baseWorldTrans, baseBox);
|
||||
m_dynamicsWorld->removeRigidBody(base);
|
||||
base->setDamping(0, 0);
|
||||
m_dynamicsWorld->addRigidBody(base, collisionFilterGroup, collisionFilterMask);
|
||||
btBoxShape* linkBox1 = new btBoxShape(linkHalfExtents);
|
||||
btSphereShape* linkSphere = new btSphereShape(radius);
|
||||
|
||||
btRigidBody* prevBody = base;
|
||||
|
||||
for (int i=0;i<numLinks;i++)
|
||||
{
|
||||
btTransform linkTrans;
|
||||
linkTrans = baseWorldTrans;
|
||||
|
||||
linkTrans.setOrigin(basePosition-btVector3(0,linkHalfExtents[1]*2.f*(i+1),0));
|
||||
|
||||
|
||||
btRigidBody* prevBody = base;
|
||||
|
||||
for (int i = 0; i < numLinks; i++)
|
||||
{
|
||||
btTransform linkTrans;
|
||||
linkTrans = baseWorldTrans;
|
||||
|
||||
linkTrans.setOrigin(basePosition - btVector3(0, linkHalfExtents[1] * 2.f * (i + 1), 0));
|
||||
|
||||
btCollisionShape* colOb = 0;
|
||||
|
||||
if (i==0)
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
colOb = linkBox1;
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
colOb = linkSphere;
|
||||
}
|
||||
btRigidBody* linkBody = createRigidBody(linkMass,linkTrans,colOb);
|
||||
m_dynamicsWorld->removeRigidBody(linkBody);
|
||||
m_dynamicsWorld->addRigidBody(linkBody,collisionFilterGroup,collisionFilterMask);
|
||||
linkBody->setDamping(0,0);
|
||||
btRigidBody* linkBody = createRigidBody(linkMass, linkTrans, colOb);
|
||||
m_dynamicsWorld->removeRigidBody(linkBody);
|
||||
m_dynamicsWorld->addRigidBody(linkBody, collisionFilterGroup, collisionFilterMask);
|
||||
linkBody->setDamping(0, 0);
|
||||
btTypedConstraint* con = 0;
|
||||
|
||||
if (i==0)
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
//create a hinge constraint
|
||||
btVector3 pivotInA(0,-linkHalfExtents[1],0);
|
||||
btVector3 pivotInB(0,linkHalfExtents[1],0);
|
||||
btVector3 axisInA(1,0,0);
|
||||
btVector3 axisInB(1,0,0);
|
||||
btVector3 pivotInA(0, -linkHalfExtents[1], 0);
|
||||
btVector3 pivotInB(0, linkHalfExtents[1], 0);
|
||||
btVector3 axisInA(1, 0, 0);
|
||||
btVector3 axisInB(1, 0, 0);
|
||||
bool useReferenceA = true;
|
||||
btHingeConstraint* hinge = new btHingeConstraint(*prevBody,*linkBody,
|
||||
pivotInA,pivotInB,
|
||||
axisInA,axisInB,useReferenceA);
|
||||
btHingeConstraint* hinge = new btHingeConstraint(*prevBody, *linkBody,
|
||||
pivotInA, pivotInB,
|
||||
axisInA, axisInB, useReferenceA);
|
||||
con = hinge;
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
btTransform pivotInA(btQuaternion::getIdentity(),btVector3(0, -radius, 0)); //par body's COM to cur body's COM offset
|
||||
btTransform pivotInB(btQuaternion::getIdentity(),btVector3(0, radius, 0)); //cur body's COM to cur body's PIV offset
|
||||
btTransform pivotInA(btQuaternion::getIdentity(), btVector3(0, -radius, 0)); //par body's COM to cur body's COM offset
|
||||
btTransform pivotInB(btQuaternion::getIdentity(), btVector3(0, radius, 0)); //cur body's COM to cur body's PIV offset
|
||||
btGeneric6DofSpring2Constraint* fixed = new btGeneric6DofSpring2Constraint(*prevBody, *linkBody,
|
||||
pivotInA,pivotInB);
|
||||
fixed->setLinearLowerLimit(btVector3(0,0,0));
|
||||
fixed->setLinearUpperLimit(btVector3(0,0,0));
|
||||
fixed->setAngularLowerLimit(btVector3(0,0,0));
|
||||
fixed->setAngularUpperLimit(btVector3(0,0,0));
|
||||
|
||||
con = fixed;
|
||||
pivotInA, pivotInB);
|
||||
fixed->setLinearLowerLimit(btVector3(0, 0, 0));
|
||||
fixed->setLinearUpperLimit(btVector3(0, 0, 0));
|
||||
fixed->setAngularLowerLimit(btVector3(0, 0, 0));
|
||||
fixed->setAngularUpperLimit(btVector3(0, 0, 0));
|
||||
|
||||
con = fixed;
|
||||
}
|
||||
btAssert(con);
|
||||
if (con)
|
||||
|
|
@ -206,38 +189,36 @@ void TestHingeTorque::initPhysics()
|
|||
m_jointFeedback.push_back(fb);
|
||||
con->setJointFeedback(fb);
|
||||
|
||||
m_dynamicsWorld->addConstraint(con,true);
|
||||
m_dynamicsWorld->addConstraint(con, true);
|
||||
}
|
||||
prevBody = linkBody;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (1)
|
||||
{
|
||||
btVector3 groundHalfExtents(1,1,0.2);
|
||||
groundHalfExtents[upAxis]=1.f;
|
||||
btVector3 groundHalfExtents(1, 1, 0.2);
|
||||
groundHalfExtents[upAxis] = 1.f;
|
||||
btBoxShape* box = new btBoxShape(groundHalfExtents);
|
||||
box->initializePolyhedralFeatures();
|
||||
|
||||
btTransform start; start.setIdentity();
|
||||
|
||||
btTransform start;
|
||||
start.setIdentity();
|
||||
btVector3 groundOrigin(-0.4f, 3.f, 0.f);
|
||||
btVector3 basePosition = btVector3(-0.4f, 3.f, 0.f);
|
||||
btQuaternion groundOrn(btVector3(0,1,0),0.25*SIMD_PI);
|
||||
|
||||
groundOrigin[upAxis] -=.5;
|
||||
groundOrigin[2]-=0.6;
|
||||
// btVector3 basePosition = btVector3(-0.4f, 3.f, 0.f);
|
||||
btQuaternion groundOrn(btVector3(0, 1, 0), 0.25 * SIMD_PI);
|
||||
|
||||
groundOrigin[upAxis] -= .5;
|
||||
groundOrigin[2] -= 0.6;
|
||||
start.setOrigin(groundOrigin);
|
||||
// start.setRotation(groundOrn);
|
||||
btRigidBody* body = createRigidBody(0,start,box);
|
||||
// start.setRotation(groundOrn);
|
||||
btRigidBody* body = createRigidBody(0, start, box);
|
||||
body->setFriction(0);
|
||||
|
||||
}
|
||||
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
|
||||
}
|
||||
|
||||
class CommonExampleInterface* TestHingeTorqueCreateFunc(CommonExampleOptions& options)
|
||||
class CommonExampleInterface* TestHingeTorqueCreateFunc(CommonExampleOptions& options)
|
||||
{
|
||||
return new TestHingeTorque(options.m_guiHelper);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef TEST_HINGE_TORQUE_H
|
||||
#define TEST_HINGE_TORQUE_H
|
||||
|
||||
class CommonExampleInterface* TestHingeTorqueCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
#endif //TEST_HINGE_TORQUE_H
|
||||
class CommonExampleInterface* TestHingeTorqueCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
#endif //TEST_HINGE_TORQUE_H
|
||||
|
|
|
|||
251
Engine/lib/bullet/examples/DeformableDemo/ClothFriction.cpp
Normal file
251
Engine/lib/bullet/examples/DeformableDemo/ClothFriction.cpp
Normal file
|
|
@ -0,0 +1,251 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 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 "ClothFriction.h"
|
||||
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
|
||||
#include "BulletSoftBody/btSoftBody.h"
|
||||
#include "BulletSoftBody/btSoftBodyHelpers.h"
|
||||
#include "BulletSoftBody/btDeformableBodySolver.h"
|
||||
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
|
||||
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
|
||||
#include <stdio.h> //printf debugging
|
||||
|
||||
#include "../CommonInterfaces/CommonDeformableBodyBase.h"
|
||||
#include "../Utils/b3ResourcePath.h"
|
||||
|
||||
///The ClothFriction shows the use of deformable friction.
|
||||
class ClothFriction : public CommonDeformableBodyBase
|
||||
{
|
||||
btDeformableBodySolver* m_deformableBodySolver;
|
||||
public:
|
||||
ClothFriction(struct GUIHelperInterface* helper)
|
||||
: CommonDeformableBodyBase(helper),
|
||||
m_deformableBodySolver(0)
|
||||
{
|
||||
}
|
||||
virtual ~ClothFriction()
|
||||
{
|
||||
|
||||
}
|
||||
void initPhysics();
|
||||
|
||||
void exitPhysics();
|
||||
|
||||
void resetCamera()
|
||||
{
|
||||
float dist = 12;
|
||||
float pitch = -50;
|
||||
float yaw = 120;
|
||||
float targetPos[3] = {0, -3, 0};
|
||||
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
|
||||
}
|
||||
|
||||
void stepSimulation(float deltaTime)
|
||||
{
|
||||
float internalTimeStep = 1. / 240.f;
|
||||
m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep);
|
||||
}
|
||||
|
||||
virtual void renderScene()
|
||||
{
|
||||
CommonDeformableBodyBase::renderScene();
|
||||
btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
|
||||
|
||||
for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
|
||||
{
|
||||
btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i];
|
||||
{
|
||||
//btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer());
|
||||
btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), fDrawFlags::Faces);// deformableWorld->getDrawFlags());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
void ClothFriction::initPhysics()
|
||||
{
|
||||
m_guiHelper->setUpAxis(1);
|
||||
|
||||
///collision configuration contains default setup for memory, collision setup
|
||||
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
|
||||
|
||||
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
|
||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
||||
|
||||
m_broadphase = new btDbvtBroadphase();
|
||||
m_deformableBodySolver = new btDeformableBodySolver();
|
||||
|
||||
///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
|
||||
btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
|
||||
sol->setDeformableSolver(m_deformableBodySolver);
|
||||
m_solver = sol;
|
||||
|
||||
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, m_deformableBodySolver);
|
||||
btVector3 gravity = btVector3(0, -10, 0);
|
||||
m_dynamicsWorld->setGravity(gravity);
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.setDefaultVoxelsz(0.25);
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.Reset();
|
||||
|
||||
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
|
||||
|
||||
{
|
||||
///create a ground
|
||||
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150), btScalar(25.), btScalar(150)));
|
||||
|
||||
m_collisionShapes.push_back(groundShape);
|
||||
|
||||
btTransform groundTransform;
|
||||
groundTransform.setIdentity();
|
||||
groundTransform.setOrigin(btVector3(0, -32, 0));
|
||||
groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.1));
|
||||
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
|
||||
btScalar mass(0.);
|
||||
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
bool isDynamic = (mass != 0.f);
|
||||
|
||||
btVector3 localInertia(0, 0, 0);
|
||||
if (isDynamic)
|
||||
groundShape->calculateLocalInertia(mass, localInertia);
|
||||
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
|
||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
|
||||
btRigidBody* body = new btRigidBody(rbInfo);
|
||||
body->setFriction(3);
|
||||
|
||||
//add the ground to the dynamics world
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
}
|
||||
|
||||
// create a piece of cloth
|
||||
{
|
||||
btScalar s = 4;
|
||||
btScalar h = 0;
|
||||
|
||||
btSoftBody* psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, h, -s),
|
||||
btVector3(+s, h, -s),
|
||||
btVector3(-s, h, +s),
|
||||
btVector3(+s, h, +s),
|
||||
10,10,
|
||||
0, true);
|
||||
|
||||
psb->getCollisionShape()->setMargin(0.06);
|
||||
psb->generateBendingConstraints(2);
|
||||
psb->setTotalMass(1);
|
||||
psb->setSpringStiffness(100);
|
||||
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
|
||||
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
|
||||
psb->m_cfg.kDF = 3;
|
||||
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
|
||||
psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDF;
|
||||
psb->m_cfg.collisions |= btSoftBody::fCollision::VF_DD;
|
||||
getDeformableDynamicsWorld()->addSoftBody(psb);
|
||||
|
||||
btDeformableMassSpringForce* mass_spring = new btDeformableMassSpringForce(10,1, true);
|
||||
getDeformableDynamicsWorld()->addForce(psb, mass_spring);
|
||||
m_forces.push_back(mass_spring);
|
||||
|
||||
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
|
||||
getDeformableDynamicsWorld()->addForce(psb, gravity_force);
|
||||
m_forces.push_back(gravity_force);
|
||||
|
||||
|
||||
h = .5;
|
||||
s = 2;
|
||||
btSoftBody* psb2 = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, h, -s),
|
||||
btVector3(+s, h, -s),
|
||||
btVector3(-s, h, +s),
|
||||
btVector3(+s, h, +s),
|
||||
5,5,
|
||||
0, true);
|
||||
psb2->getCollisionShape()->setMargin(0.06);
|
||||
psb2->generateBendingConstraints(2);
|
||||
psb2->setTotalMass(1);
|
||||
psb2->setSpringStiffness(100);
|
||||
psb2->m_cfg.kKHR = 1; // collision hardness with kinematic objects
|
||||
psb2->m_cfg.kCHR = 1; // collision hardness with rigid body
|
||||
psb2->m_cfg.kDF = 1;
|
||||
psb2->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
|
||||
psb2->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDF;
|
||||
psb2->m_cfg.collisions |= btSoftBody::fCollision::VF_DD;
|
||||
psb->translate(btVector3(0,0,0));
|
||||
getDeformableDynamicsWorld()->addSoftBody(psb2);
|
||||
|
||||
btDeformableMassSpringForce* mass_spring2 = new btDeformableMassSpringForce(10,.1, true);
|
||||
getDeformableDynamicsWorld()->addForce(psb2, mass_spring2);
|
||||
m_forces.push_back(mass_spring2);
|
||||
|
||||
btDeformableGravityForce* gravity_force2 = new btDeformableGravityForce(gravity);
|
||||
getDeformableDynamicsWorld()->addForce(psb2, gravity_force2);
|
||||
m_forces.push_back(gravity_force2);
|
||||
}
|
||||
getDeformableDynamicsWorld()->setImplicit(false);
|
||||
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
|
||||
}
|
||||
|
||||
void ClothFriction::exitPhysics()
|
||||
{
|
||||
//cleanup in the reverse order of creation/initialization
|
||||
removePickingConstraint();
|
||||
//remove the rigidbodies from the dynamics world and delete them
|
||||
int i;
|
||||
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
|
||||
{
|
||||
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
|
||||
btRigidBody* body = btRigidBody::upcast(obj);
|
||||
if (body && body->getMotionState())
|
||||
{
|
||||
delete body->getMotionState();
|
||||
}
|
||||
m_dynamicsWorld->removeCollisionObject(obj);
|
||||
delete obj;
|
||||
}
|
||||
// delete forces
|
||||
for (int j = 0; j < m_forces.size(); j++)
|
||||
{
|
||||
btDeformableLagrangianForce* force = m_forces[j];
|
||||
delete force;
|
||||
}
|
||||
m_forces.clear();
|
||||
//delete collision shapes
|
||||
for (int j = 0; j < m_collisionShapes.size(); j++)
|
||||
{
|
||||
btCollisionShape* shape = m_collisionShapes[j];
|
||||
delete shape;
|
||||
}
|
||||
m_collisionShapes.clear();
|
||||
|
||||
delete m_dynamicsWorld;
|
||||
|
||||
delete m_solver;
|
||||
|
||||
delete m_deformableBodySolver;
|
||||
|
||||
delete m_broadphase;
|
||||
|
||||
delete m_dispatcher;
|
||||
|
||||
delete m_collisionConfiguration;
|
||||
}
|
||||
|
||||
class CommonExampleInterface* ClothFrictionCreateFunc(struct CommonExampleOptions& options)
|
||||
{
|
||||
return new ClothFriction(options.m_guiHelper);
|
||||
}
|
||||
|
||||
|
||||
19
Engine/lib/bullet/examples/DeformableDemo/ClothFriction.h
Normal file
19
Engine/lib/bullet/examples/DeformableDemo/ClothFriction.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 Google Inc. http://bulletphysics.org
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef CLOTH_FRICTION_H
|
||||
#define CLOTH_FRICTION_H
|
||||
|
||||
class CommonExampleInterface* ClothFrictionCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
#endif //CLOTH_FRICTION_H
|
||||
273
Engine/lib/bullet/examples/DeformableDemo/Collide.cpp
Normal file
273
Engine/lib/bullet/examples/DeformableDemo/Collide.cpp
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 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 "Collide.h"
|
||||
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
|
||||
#include "BulletSoftBody/btSoftBody.h"
|
||||
#include "BulletSoftBody/btSoftBodyHelpers.h"
|
||||
#include "BulletSoftBody/btDeformableBodySolver.h"
|
||||
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
|
||||
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
|
||||
#include "../CommonInterfaces/CommonParameterInterface.h"
|
||||
#include <stdio.h> //printf debugging
|
||||
|
||||
#include "../CommonInterfaces/CommonDeformableBodyBase.h"
|
||||
#include "../Utils/b3ResourcePath.h"
|
||||
|
||||
///The Collide shows the contact between volumetric deformable objects and rigid objects.
|
||||
static btScalar E = 50;
|
||||
static btScalar nu = 0.3;
|
||||
static btScalar damping_alpha = 0.1;
|
||||
static btScalar damping_beta = 0.01;
|
||||
static btScalar COLLIDING_VELOCITY = 15;
|
||||
|
||||
struct TetraCube
|
||||
{
|
||||
#include "../SoftDemo/cube.inl"
|
||||
};
|
||||
|
||||
class Collide : public CommonDeformableBodyBase
|
||||
{
|
||||
btDeformableLinearElasticityForce* m_linearElasticity;
|
||||
|
||||
public:
|
||||
Collide(struct GUIHelperInterface* helper)
|
||||
: CommonDeformableBodyBase(helper)
|
||||
{
|
||||
m_linearElasticity = 0;
|
||||
}
|
||||
virtual ~Collide()
|
||||
{
|
||||
}
|
||||
void initPhysics();
|
||||
|
||||
void exitPhysics();
|
||||
|
||||
void resetCamera()
|
||||
{
|
||||
float dist = 20;
|
||||
float pitch = 0;
|
||||
float yaw = 90;
|
||||
float targetPos[3] = {0, 3, 0};
|
||||
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
|
||||
}
|
||||
|
||||
void Ctor_RbUpStack()
|
||||
{
|
||||
float mass = 0.5;
|
||||
btCollisionShape* shape = new btBoxShape(btVector3(2, 2, 2));
|
||||
btTransform startTransform;
|
||||
startTransform.setIdentity();
|
||||
startTransform.setOrigin(btVector3(0,-2,0));
|
||||
btRigidBody* rb = createRigidBody(mass, startTransform, shape);
|
||||
rb->setLinearVelocity(btVector3(0,+COLLIDING_VELOCITY, 0));
|
||||
}
|
||||
|
||||
void stepSimulation(float deltaTime)
|
||||
{
|
||||
m_linearElasticity->setPoissonRatio(nu);
|
||||
m_linearElasticity->setYoungsModulus(E);
|
||||
m_linearElasticity->setDamping(damping_alpha, damping_beta);
|
||||
float internalTimeStep = 1. / 60.f;
|
||||
m_dynamicsWorld->stepSimulation(deltaTime, 1, internalTimeStep);
|
||||
}
|
||||
|
||||
virtual void renderScene()
|
||||
{
|
||||
CommonDeformableBodyBase::renderScene();
|
||||
btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
|
||||
|
||||
for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
|
||||
{
|
||||
btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i];
|
||||
{
|
||||
btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer());
|
||||
btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), deformableWorld->getDrawFlags());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void Collide::initPhysics()
|
||||
{
|
||||
m_guiHelper->setUpAxis(1);
|
||||
|
||||
///collision configuration contains default setup for memory, collision setup
|
||||
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
|
||||
|
||||
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
|
||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
||||
|
||||
m_broadphase = new btDbvtBroadphase();
|
||||
btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
|
||||
|
||||
btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
|
||||
sol->setDeformableSolver(deformableBodySolver);
|
||||
m_solver = sol;
|
||||
|
||||
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
|
||||
btVector3 gravity = btVector3(0, 0, 0);
|
||||
m_dynamicsWorld->setGravity(gravity);
|
||||
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
|
||||
|
||||
// create volumetric soft body
|
||||
{
|
||||
btSoftBody* psb = btSoftBodyHelpers::CreateFromTetGenData(getDeformableDynamicsWorld()->getWorldInfo(),
|
||||
TetraCube::getElements(),
|
||||
0,
|
||||
TetraCube::getNodes(),
|
||||
false, true, true);
|
||||
getDeformableDynamicsWorld()->addSoftBody(psb);
|
||||
psb->scale(btVector3(2, 2, 2));
|
||||
psb->translate(btVector3(0, 7, 0));
|
||||
psb->getCollisionShape()->setMargin(0.1);
|
||||
psb->setTotalMass(0.5);
|
||||
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
|
||||
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
|
||||
psb->m_cfg.kDF = 0;
|
||||
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
|
||||
psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDN;
|
||||
psb->m_sleepingThreshold = 0;
|
||||
btSoftBodyHelpers::generateBoundaryFaces(psb);
|
||||
|
||||
psb->setVelocity(btVector3(0, -COLLIDING_VELOCITY, 0));
|
||||
|
||||
btDeformableLinearElasticityForce* linearElasticity = new btDeformableLinearElasticityForce(100,100,0.01);
|
||||
m_linearElasticity = linearElasticity;
|
||||
getDeformableDynamicsWorld()->addForce(psb, linearElasticity);
|
||||
m_forces.push_back(linearElasticity);
|
||||
}
|
||||
getDeformableDynamicsWorld()->setImplicit(true);
|
||||
getDeformableDynamicsWorld()->setLineSearch(false);
|
||||
getDeformableDynamicsWorld()->setUseProjection(true);
|
||||
getDeformableDynamicsWorld()->getSolverInfo().m_deformable_erp = 0.3;
|
||||
getDeformableDynamicsWorld()->getSolverInfo().m_deformable_maxErrorReduction = btScalar(200);
|
||||
getDeformableDynamicsWorld()->getSolverInfo().m_leastSquaresResidualThreshold = 1e-3;
|
||||
getDeformableDynamicsWorld()->getSolverInfo().m_splitImpulse = true;
|
||||
getDeformableDynamicsWorld()->getSolverInfo().m_numIterations = 100;
|
||||
// add a few rigid bodies
|
||||
Ctor_RbUpStack();
|
||||
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
|
||||
|
||||
// {
|
||||
// SliderParams slider("Young's Modulus", &E);
|
||||
// slider.m_minVal = 0;
|
||||
// slider.m_maxVal = 2000;
|
||||
// if (m_guiHelper->getParameterInterface())
|
||||
// m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
// }
|
||||
// {
|
||||
// SliderParams slider("Poisson Ratio", &nu);
|
||||
// slider.m_minVal = 0.05;
|
||||
// slider.m_maxVal = 0.49;
|
||||
// if (m_guiHelper->getParameterInterface())
|
||||
// m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
// }
|
||||
// {
|
||||
// SliderParams slider("Mass Damping", &damping_alpha);
|
||||
// slider.m_minVal = 0.001;
|
||||
// slider.m_maxVal = 0.01;
|
||||
// if (m_guiHelper->getParameterInterface())
|
||||
// m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
// }
|
||||
// {
|
||||
// SliderParams slider("Stiffness Damping", &damping_beta);
|
||||
// slider.m_minVal = 0.001;
|
||||
// slider.m_maxVal = 0.01;
|
||||
// if (m_guiHelper->getParameterInterface())
|
||||
// m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
// }
|
||||
{
|
||||
SliderParams slider("Young's Modulus", &E);
|
||||
slider.m_minVal = 0;
|
||||
slider.m_maxVal = 2000;
|
||||
if (m_guiHelper->getParameterInterface())
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
}
|
||||
{
|
||||
SliderParams slider("Poisson Ratio", &nu);
|
||||
slider.m_minVal = 0.05;
|
||||
slider.m_maxVal = 0.49;
|
||||
if (m_guiHelper->getParameterInterface())
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
}
|
||||
{
|
||||
SliderParams slider("Mass Damping", &damping_alpha);
|
||||
slider.m_minVal = 0;
|
||||
slider.m_maxVal = 1;
|
||||
if (m_guiHelper->getParameterInterface())
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
}
|
||||
{
|
||||
SliderParams slider("Stiffness Damping", &damping_beta);
|
||||
slider.m_minVal = 0;
|
||||
slider.m_maxVal = 0.1;
|
||||
if (m_guiHelper->getParameterInterface())
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
}
|
||||
}
|
||||
|
||||
void Collide::exitPhysics()
|
||||
{
|
||||
//cleanup in the reverse order of creation/initialization
|
||||
removePickingConstraint();
|
||||
//remove the rigidbodies from the dynamics world and delete them
|
||||
int i;
|
||||
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
|
||||
{
|
||||
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
|
||||
btRigidBody* body = btRigidBody::upcast(obj);
|
||||
if (body && body->getMotionState())
|
||||
{
|
||||
delete body->getMotionState();
|
||||
}
|
||||
m_dynamicsWorld->removeCollisionObject(obj);
|
||||
delete obj;
|
||||
}
|
||||
// delete forces
|
||||
for (int j = 0; j < m_forces.size(); j++)
|
||||
{
|
||||
btDeformableLagrangianForce* force = m_forces[j];
|
||||
delete force;
|
||||
}
|
||||
m_forces.clear();
|
||||
|
||||
//delete collision shapes
|
||||
for (int j = 0; j < m_collisionShapes.size(); j++)
|
||||
{
|
||||
btCollisionShape* shape = m_collisionShapes[j];
|
||||
delete shape;
|
||||
}
|
||||
m_collisionShapes.clear();
|
||||
|
||||
delete m_dynamicsWorld;
|
||||
|
||||
delete m_solver;
|
||||
|
||||
delete m_broadphase;
|
||||
|
||||
delete m_dispatcher;
|
||||
|
||||
delete m_collisionConfiguration;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class CommonExampleInterface* CollideCreateFunc(struct CommonExampleOptions& options)
|
||||
{
|
||||
return new Collide(options.m_guiHelper);
|
||||
}
|
||||
|
||||
|
||||
19
Engine/lib/bullet/examples/DeformableDemo/Collide.h
Normal file
19
Engine/lib/bullet/examples/DeformableDemo/Collide.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 Google Inc. http://bulletphysics.org
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef _COLLIDE_H
|
||||
#define _COLLIDE_H
|
||||
|
||||
class CommonExampleInterface* CollideCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
#endif //_COLLIDE_H
|
||||
|
|
@ -0,0 +1,222 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 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 "DeformableClothAnchor.h"
|
||||
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
|
||||
#include "BulletSoftBody/btSoftBody.h"
|
||||
#include "BulletSoftBody/btSoftBodyHelpers.h"
|
||||
#include "BulletSoftBody/btDeformableBodySolver.h"
|
||||
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
|
||||
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
|
||||
#include <stdio.h> //printf debugging
|
||||
|
||||
#include "../CommonInterfaces/CommonDeformableBodyBase.h"
|
||||
#include "../Utils/b3ResourcePath.h"
|
||||
|
||||
///The DeformableClothAnchor shows contact between deformable objects and rigid objects.
|
||||
class DeformableClothAnchor : public CommonDeformableBodyBase
|
||||
{
|
||||
public:
|
||||
DeformableClothAnchor(struct GUIHelperInterface* helper)
|
||||
: CommonDeformableBodyBase(helper)
|
||||
{
|
||||
}
|
||||
virtual ~DeformableClothAnchor()
|
||||
{
|
||||
}
|
||||
void initPhysics();
|
||||
|
||||
void exitPhysics();
|
||||
|
||||
void resetCamera()
|
||||
{
|
||||
float dist = 20;
|
||||
float pitch = -45;
|
||||
float yaw = 100;
|
||||
float targetPos[3] = {0, -3, 0};
|
||||
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
|
||||
}
|
||||
|
||||
void stepSimulation(float deltaTime)
|
||||
{
|
||||
//use a smaller internal timestep, there are stability issues
|
||||
float internalTimeStep = 1. / 240.f;
|
||||
m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep);
|
||||
}
|
||||
|
||||
virtual void renderScene()
|
||||
{
|
||||
CommonDeformableBodyBase::renderScene();
|
||||
btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
|
||||
|
||||
for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
|
||||
{
|
||||
btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i];
|
||||
//if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe)))
|
||||
{
|
||||
//btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer());
|
||||
btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), fDrawFlags::Faces);// deformableWorld->getDrawFlags());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void DeformableClothAnchor::initPhysics()
|
||||
{
|
||||
m_guiHelper->setUpAxis(1);
|
||||
|
||||
///collision configuration contains default setup for memory, collision setup
|
||||
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
|
||||
|
||||
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
|
||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
||||
|
||||
m_broadphase = new btDbvtBroadphase();
|
||||
btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
|
||||
|
||||
///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
|
||||
btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
|
||||
sol->setDeformableSolver(deformableBodySolver);
|
||||
m_solver = sol;
|
||||
|
||||
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
|
||||
// deformableBodySolver->setWorld(getDeformableDynamicsWorld());
|
||||
// m_dynamicsWorld->getSolverInfo().m_singleAxisDeformableThreshold = 0.f;//faster but lower quality
|
||||
btVector3 gravity = btVector3(0, -10, 0);
|
||||
m_dynamicsWorld->setGravity(gravity);
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
|
||||
|
||||
// getDeformableDynamicsWorld()->before_solver_callbacks.push_back(dynamics);
|
||||
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
|
||||
|
||||
{
|
||||
///create a ground
|
||||
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(25.), btScalar(150.)));
|
||||
|
||||
m_collisionShapes.push_back(groundShape);
|
||||
|
||||
btTransform groundTransform;
|
||||
groundTransform.setIdentity();
|
||||
groundTransform.setOrigin(btVector3(0, -50, 0));
|
||||
groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.));
|
||||
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
|
||||
btScalar mass(0.);
|
||||
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
bool isDynamic = (mass != 0.f);
|
||||
|
||||
btVector3 localInertia(0, 0, 0);
|
||||
if (isDynamic)
|
||||
groundShape->calculateLocalInertia(mass, localInertia);
|
||||
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
|
||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
|
||||
btRigidBody* body = new btRigidBody(rbInfo);
|
||||
body->setFriction(1);
|
||||
|
||||
//add the ground to the dynamics world
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
}
|
||||
|
||||
// create a piece of cloth
|
||||
{
|
||||
const btScalar s = 4;
|
||||
const btScalar h = 6;
|
||||
const int r = 8;
|
||||
btSoftBody* psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, h, -s),
|
||||
btVector3(+s, h, -s),
|
||||
btVector3(-s, h, +s),
|
||||
btVector3(+s, h, +s), r, r, 4 + 8, true);
|
||||
psb->getCollisionShape()->setMargin(0.1);
|
||||
psb->generateBendingConstraints(2);
|
||||
psb->setTotalMass(1);
|
||||
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
|
||||
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
|
||||
psb->m_cfg.kDF = 2;
|
||||
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
|
||||
psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDF;
|
||||
getDeformableDynamicsWorld()->addSoftBody(psb);
|
||||
|
||||
btDeformableMassSpringForce* mass_spring = new btDeformableMassSpringForce(100,1, true);
|
||||
getDeformableDynamicsWorld()->addForce(psb, mass_spring);
|
||||
m_forces.push_back(mass_spring);
|
||||
|
||||
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
|
||||
getDeformableDynamicsWorld()->addForce(psb, gravity_force);
|
||||
m_forces.push_back(gravity_force);
|
||||
|
||||
btTransform startTransform;
|
||||
startTransform.setIdentity();
|
||||
startTransform.setOrigin(btVector3(0, h, -(s + 3.5)));
|
||||
btRigidBody* body = createRigidBody(1, startTransform, new btBoxShape(btVector3(s, 1, 3)));
|
||||
psb->appendDeformableAnchor(0, body);
|
||||
psb->appendDeformableAnchor(r - 1, body);
|
||||
}
|
||||
getDeformableDynamicsWorld()->setImplicit(false);
|
||||
getDeformableDynamicsWorld()->setLineSearch(false);
|
||||
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
|
||||
}
|
||||
|
||||
void DeformableClothAnchor::exitPhysics()
|
||||
{
|
||||
//cleanup in the reverse order of creation/initialization
|
||||
removePickingConstraint();
|
||||
//remove the rigidbodies from the dynamics world and delete them
|
||||
int i;
|
||||
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
|
||||
{
|
||||
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
|
||||
btRigidBody* body = btRigidBody::upcast(obj);
|
||||
if (body && body->getMotionState())
|
||||
{
|
||||
delete body->getMotionState();
|
||||
}
|
||||
m_dynamicsWorld->removeCollisionObject(obj);
|
||||
delete obj;
|
||||
}
|
||||
// delete forces
|
||||
for (int j = 0; j < m_forces.size(); j++)
|
||||
{
|
||||
btDeformableLagrangianForce* force = m_forces[j];
|
||||
delete force;
|
||||
}
|
||||
m_forces.clear();
|
||||
//delete collision shapes
|
||||
for (int j = 0; j < m_collisionShapes.size(); j++)
|
||||
{
|
||||
btCollisionShape* shape = m_collisionShapes[j];
|
||||
delete shape;
|
||||
}
|
||||
m_collisionShapes.clear();
|
||||
|
||||
delete m_dynamicsWorld;
|
||||
|
||||
delete m_solver;
|
||||
|
||||
delete m_broadphase;
|
||||
|
||||
delete m_dispatcher;
|
||||
|
||||
delete m_collisionConfiguration;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class CommonExampleInterface* DeformableClothAnchorCreateFunc(struct CommonExampleOptions& options)
|
||||
{
|
||||
return new DeformableClothAnchor(options.m_guiHelper);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 Google Inc. http://bulletphysics.org
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef DEFORMABLE_CLOTH_ANCHOR_H
|
||||
#define DEFORMABLE_CLOTH_ANCHOR_H
|
||||
|
||||
class CommonExampleInterface* DeformableClothAnchorCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
#endif //DEFORMABLE_CLOTH_ANCHOR_H
|
||||
257
Engine/lib/bullet/examples/DeformableDemo/DeformableContact.cpp
Normal file
257
Engine/lib/bullet/examples/DeformableDemo/DeformableContact.cpp
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 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 "DeformableContact.h"
|
||||
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
|
||||
#include "BulletSoftBody/btSoftBody.h"
|
||||
#include "BulletSoftBody/btSoftBodyHelpers.h"
|
||||
#include "BulletSoftBody/btDeformableBodySolver.h"
|
||||
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
|
||||
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
|
||||
#include <stdio.h> //printf debugging
|
||||
|
||||
#include "../CommonInterfaces/CommonDeformableBodyBase.h"
|
||||
#include "../Utils/b3ResourcePath.h"
|
||||
|
||||
///The DeformableContact shows the contact between deformable objects
|
||||
|
||||
class DeformableContact : public CommonDeformableBodyBase
|
||||
{
|
||||
public:
|
||||
DeformableContact(struct GUIHelperInterface* helper)
|
||||
: CommonDeformableBodyBase(helper)
|
||||
{
|
||||
}
|
||||
virtual ~DeformableContact()
|
||||
{
|
||||
}
|
||||
void initPhysics();
|
||||
|
||||
void exitPhysics();
|
||||
|
||||
void resetCamera()
|
||||
{
|
||||
float dist = 12;
|
||||
float pitch = -50;
|
||||
float yaw = 120;
|
||||
float targetPos[3] = {0, -3, 0};
|
||||
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
|
||||
}
|
||||
|
||||
void stepSimulation(float deltaTime)
|
||||
{
|
||||
float internalTimeStep = 1. / 240.f;
|
||||
m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep);
|
||||
}
|
||||
|
||||
virtual void renderScene()
|
||||
{
|
||||
CommonDeformableBodyBase::renderScene();
|
||||
|
||||
|
||||
btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
|
||||
|
||||
for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
|
||||
{
|
||||
btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i];
|
||||
{
|
||||
//btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer());
|
||||
btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), fDrawFlags::Faces);// StddeformableWorld->getDrawFlags());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
void DeformableContact::initPhysics()
|
||||
{
|
||||
m_guiHelper->setUpAxis(1);
|
||||
|
||||
///collision configuration contains default setup for memory, collision setup
|
||||
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
|
||||
|
||||
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
|
||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
||||
|
||||
m_broadphase = new btDbvtBroadphase();
|
||||
btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
|
||||
|
||||
///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
|
||||
btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
|
||||
sol->setDeformableSolver(deformableBodySolver);
|
||||
m_solver = sol;
|
||||
|
||||
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
|
||||
btVector3 gravity = btVector3(0, -10, 0);
|
||||
m_dynamicsWorld->setGravity(gravity);
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.setDefaultVoxelsz(0.25);
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.Reset();
|
||||
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
|
||||
|
||||
{
|
||||
///create a ground
|
||||
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150), btScalar(25.), btScalar(150)));
|
||||
|
||||
m_collisionShapes.push_back(groundShape);
|
||||
|
||||
btTransform groundTransform;
|
||||
groundTransform.setIdentity();
|
||||
groundTransform.setOrigin(btVector3(0, -32, 0));
|
||||
groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.));
|
||||
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
|
||||
btScalar mass(0.);
|
||||
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
bool isDynamic = (mass != 0.f);
|
||||
|
||||
btVector3 localInertia(0, 0, 0);
|
||||
if (isDynamic)
|
||||
groundShape->calculateLocalInertia(mass, localInertia);
|
||||
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
|
||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
|
||||
btRigidBody* body = new btRigidBody(rbInfo);
|
||||
body->setFriction(2);
|
||||
|
||||
//add the ground to the dynamics world
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
}
|
||||
|
||||
// create a piece of cloth
|
||||
{
|
||||
btScalar s = 4;
|
||||
btScalar h = 0;
|
||||
|
||||
btSoftBody* psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, h, -s),
|
||||
btVector3(+s, h, -s),
|
||||
btVector3(-s, h, +s),
|
||||
btVector3(+s, h, +s),
|
||||
20,20,
|
||||
1 + 2 + 4 + 8, true);
|
||||
|
||||
psb->getCollisionShape()->setMargin(0.05);
|
||||
psb->generateBendingConstraints(2);
|
||||
psb->setSpringStiffness(10);
|
||||
psb->setTotalMass(1);
|
||||
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
|
||||
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
|
||||
psb->m_cfg.kDF = 0;
|
||||
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
|
||||
psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDF;
|
||||
psb->m_cfg.collisions |= btSoftBody::fCollision::VF_DD;
|
||||
getDeformableDynamicsWorld()->addSoftBody(psb);
|
||||
|
||||
btDeformableMassSpringForce* mass_spring = new btDeformableMassSpringForce(10,1, true);
|
||||
getDeformableDynamicsWorld()->addForce(psb, mass_spring);
|
||||
m_forces.push_back(mass_spring);
|
||||
|
||||
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
|
||||
getDeformableDynamicsWorld()->addForce(psb, gravity_force);
|
||||
m_forces.push_back(gravity_force);
|
||||
|
||||
|
||||
h = 2;
|
||||
s = 2;
|
||||
btSoftBody* psb2 = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, h, -s),
|
||||
btVector3(+s, h, -s),
|
||||
btVector3(-s, h, +s),
|
||||
btVector3(+s, h, +s),
|
||||
10,10,
|
||||
0, true);
|
||||
psb2->getCollisionShape()->setMargin(0.05);
|
||||
psb2->generateBendingConstraints(2);
|
||||
psb2->setSpringStiffness(10);
|
||||
psb2->setTotalMass(1);
|
||||
psb2->m_cfg.kKHR = 1; // collision hardness with kinematic objects
|
||||
psb2->m_cfg.kCHR = 1; // collision hardness with rigid body
|
||||
psb2->m_cfg.kDF = 0.5;
|
||||
psb2->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
|
||||
psb2->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDF;
|
||||
psb2->m_cfg.collisions |= btSoftBody::fCollision::VF_DD;
|
||||
psb->translate(btVector3(3.5,0,0));
|
||||
getDeformableDynamicsWorld()->addSoftBody(psb2);
|
||||
|
||||
btDeformableMassSpringForce* mass_spring2 = new btDeformableMassSpringForce(10,1, true);
|
||||
getDeformableDynamicsWorld()->addForce(psb2, mass_spring2);
|
||||
m_forces.push_back(mass_spring2);
|
||||
|
||||
btDeformableGravityForce* gravity_force2 = new btDeformableGravityForce(gravity);
|
||||
getDeformableDynamicsWorld()->addForce(psb2, gravity_force2);
|
||||
m_forces.push_back(gravity_force2);
|
||||
}
|
||||
getDeformableDynamicsWorld()->setImplicit(false);
|
||||
getDeformableDynamicsWorld()->setLineSearch(false);
|
||||
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
|
||||
int numInstances = m_guiHelper->getRenderInterface()->getTotalNumInstances();
|
||||
double rgbaColors[3][4] = { { 1, 0, 0, 1 } , { 0, 1, 0, 1 } ,{ 0, 0, 1, 1 } };
|
||||
|
||||
for (int i = 0; i < numInstances; i++)
|
||||
{
|
||||
m_guiHelper->changeInstanceFlags(i, B3_INSTANCE_DOUBLE_SIDED);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void DeformableContact::exitPhysics()
|
||||
{
|
||||
//cleanup in the reverse order of creation/initialization
|
||||
removePickingConstraint();
|
||||
//remove the rigidbodies from the dynamics world and delete them
|
||||
int i;
|
||||
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
|
||||
{
|
||||
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
|
||||
btRigidBody* body = btRigidBody::upcast(obj);
|
||||
if (body && body->getMotionState())
|
||||
{
|
||||
delete body->getMotionState();
|
||||
}
|
||||
m_dynamicsWorld->removeCollisionObject(obj);
|
||||
delete obj;
|
||||
}
|
||||
// delete forces
|
||||
for (int j = 0; j < m_forces.size(); j++)
|
||||
{
|
||||
btDeformableLagrangianForce* force = m_forces[j];
|
||||
delete force;
|
||||
}
|
||||
m_forces.clear();
|
||||
//delete collision shapes
|
||||
for (int j = 0; j < m_collisionShapes.size(); j++)
|
||||
{
|
||||
btCollisionShape* shape = m_collisionShapes[j];
|
||||
delete shape;
|
||||
}
|
||||
m_collisionShapes.clear();
|
||||
|
||||
delete m_dynamicsWorld;
|
||||
|
||||
delete m_solver;
|
||||
|
||||
delete m_broadphase;
|
||||
|
||||
delete m_dispatcher;
|
||||
|
||||
delete m_collisionConfiguration;
|
||||
}
|
||||
|
||||
class CommonExampleInterface* DeformableContactCreateFunc(struct CommonExampleOptions& options)
|
||||
{
|
||||
return new DeformableContact(options.m_guiHelper);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 Google Inc. http://bulletphysics.org
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef DEFORMABLE_CONTACT_H
|
||||
#define DEFORMABLE_CONTACT_H
|
||||
|
||||
class CommonExampleInterface* DeformableContactCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
#endif //_DEFORMABLE_CONTACT_H
|
||||
|
|
@ -0,0 +1,393 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 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 "DeformableMultibody.h"
|
||||
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
|
||||
#include "BulletSoftBody/btSoftBody.h"
|
||||
#include "BulletSoftBody/btSoftBodyHelpers.h"
|
||||
#include "BulletSoftBody/btDeformableBodySolver.h"
|
||||
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
|
||||
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
|
||||
#include <stdio.h> //printf debugging
|
||||
|
||||
#include "../CommonInterfaces/CommonRigidBodyBase.h"
|
||||
#include "../Utils/b3ResourcePath.h"
|
||||
#include "../SoftDemo/BunnyMesh.h"
|
||||
#include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h"
|
||||
#include "BulletDynamics/Featherstone/btMultiBodyJointFeedback.h"
|
||||
|
||||
#include "../CommonInterfaces/CommonDeformableBodyBase.h"
|
||||
#include "../Utils/b3ResourcePath.h"
|
||||
///The DeformableMultibody demo deformable bodies self-collision
|
||||
static bool g_floatingBase = true;
|
||||
static float friction = 1.;
|
||||
class DeformableMultibody : public CommonDeformableBodyBase
|
||||
{
|
||||
public:
|
||||
DeformableMultibody(struct GUIHelperInterface* helper)
|
||||
:CommonDeformableBodyBase(helper)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~DeformableMultibody()
|
||||
{
|
||||
}
|
||||
|
||||
void initPhysics();
|
||||
|
||||
void exitPhysics();
|
||||
|
||||
void resetCamera()
|
||||
{
|
||||
float dist = 30;
|
||||
float pitch = -30;
|
||||
float yaw = 100;
|
||||
float targetPos[3] = {0, -10, 0};
|
||||
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
|
||||
}
|
||||
|
||||
virtual void stepSimulation(float deltaTime);
|
||||
|
||||
btMultiBody* createFeatherstoneMultiBody_testMultiDof(class btMultiBodyDynamicsWorld* world, int numLinks, const btVector3& basePosition, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents, bool spherical = false, bool floating = false);
|
||||
|
||||
void addColliders_testMultiDof(btMultiBody* pMultiBody, btMultiBodyDynamicsWorld* pWorld, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents);
|
||||
|
||||
virtual void renderScene()
|
||||
{
|
||||
CommonDeformableBodyBase::renderScene();
|
||||
btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
|
||||
|
||||
for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
|
||||
{
|
||||
btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i];
|
||||
{
|
||||
btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer());
|
||||
btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), fDrawFlags::Faces);// deformableWorld->getDrawFlags());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void DeformableMultibody::initPhysics()
|
||||
{
|
||||
m_guiHelper->setUpAxis(1);
|
||||
|
||||
///collision configuration contains default setup for memory, collision setup
|
||||
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
|
||||
|
||||
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
|
||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
||||
|
||||
m_broadphase = new btDbvtBroadphase();
|
||||
btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
|
||||
btDeformableMultiBodyConstraintSolver* sol;
|
||||
sol = new btDeformableMultiBodyConstraintSolver;
|
||||
sol->setDeformableSolver(deformableBodySolver);
|
||||
m_solver = sol;
|
||||
|
||||
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
|
||||
btVector3 gravity = btVector3(0, -10, 0);
|
||||
m_dynamicsWorld->setGravity(gravity);
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.setDefaultVoxelsz(0.25);
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.Reset();
|
||||
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
|
||||
|
||||
{
|
||||
///create a ground
|
||||
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(25.), btScalar(150.)));
|
||||
|
||||
m_collisionShapes.push_back(groundShape);
|
||||
|
||||
btTransform groundTransform;
|
||||
groundTransform.setIdentity();
|
||||
groundTransform.setOrigin(btVector3(0, -40, 0));
|
||||
groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.));
|
||||
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
|
||||
btScalar mass(0.);
|
||||
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
bool isDynamic = (mass != 0.f);
|
||||
|
||||
btVector3 localInertia(0, 0, 0);
|
||||
if (isDynamic)
|
||||
groundShape->calculateLocalInertia(mass, localInertia);
|
||||
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
|
||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
|
||||
btRigidBody* body = new btRigidBody(rbInfo);
|
||||
body->setFriction(0.5);
|
||||
|
||||
//add the ground to the dynamics world
|
||||
m_dynamicsWorld->addRigidBody(body,1,1+2);
|
||||
}
|
||||
|
||||
{
|
||||
bool damping = true;
|
||||
bool gyro = false;
|
||||
int numLinks = 4;
|
||||
bool spherical = false; //set it ot false -to use 1DoF hinges instead of 3DoF sphericals
|
||||
bool canSleep = false;
|
||||
bool selfCollide = true;
|
||||
btVector3 linkHalfExtents(.4, 1, .4);
|
||||
btVector3 baseHalfExtents(.4, 1, .4);
|
||||
|
||||
btMultiBody* mbC = createFeatherstoneMultiBody_testMultiDof(m_dynamicsWorld, numLinks, btVector3(0.f, 10.f,0.f), linkHalfExtents, baseHalfExtents, spherical, g_floatingBase);
|
||||
|
||||
mbC->setCanSleep(canSleep);
|
||||
mbC->setHasSelfCollision(selfCollide);
|
||||
mbC->setUseGyroTerm(gyro);
|
||||
//
|
||||
if (!damping)
|
||||
{
|
||||
mbC->setLinearDamping(0.0f);
|
||||
mbC->setAngularDamping(0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
mbC->setLinearDamping(0.04f);
|
||||
mbC->setAngularDamping(0.04f);
|
||||
}
|
||||
|
||||
if (numLinks > 0)
|
||||
{
|
||||
btScalar q0 = 0.f * SIMD_PI / 180.f;
|
||||
if (!spherical)
|
||||
{
|
||||
mbC->setJointPosMultiDof(0, &q0);
|
||||
}
|
||||
else
|
||||
{
|
||||
btQuaternion quat0(btVector3(1, 1, 0).normalized(), q0);
|
||||
quat0.normalize();
|
||||
mbC->setJointPosMultiDof(0, quat0);
|
||||
}
|
||||
}
|
||||
///
|
||||
addColliders_testMultiDof(mbC, m_dynamicsWorld, baseHalfExtents, linkHalfExtents);
|
||||
}
|
||||
|
||||
// create a patch of cloth
|
||||
{
|
||||
btScalar h = 0;
|
||||
const btScalar s = 4;
|
||||
btSoftBody* psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, h, -s),
|
||||
btVector3(+s, h, -s),
|
||||
btVector3(-s, h, +s),
|
||||
btVector3(+s, h, +s),
|
||||
20,20,
|
||||
// 3,3,
|
||||
1 + 2 + 4 + 8, true);
|
||||
|
||||
psb->getCollisionShape()->setMargin(0.025);
|
||||
psb->generateBendingConstraints(2);
|
||||
psb->setTotalMass(1);
|
||||
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
|
||||
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
|
||||
psb->m_cfg.kDF = 2;
|
||||
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
|
||||
psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDF;
|
||||
psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_MDF;
|
||||
psb->setCollisionFlags(0);
|
||||
getDeformableDynamicsWorld()->addSoftBody(psb);
|
||||
|
||||
btDeformableMassSpringForce* mass_spring = new btDeformableMassSpringForce(30, 1, true);
|
||||
getDeformableDynamicsWorld()->addForce(psb, mass_spring);
|
||||
m_forces.push_back(mass_spring);
|
||||
|
||||
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
|
||||
getDeformableDynamicsWorld()->addForce(psb, gravity_force);
|
||||
m_forces.push_back(gravity_force);
|
||||
}
|
||||
getDeformableDynamicsWorld()->setImplicit(false);
|
||||
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
|
||||
}
|
||||
|
||||
void DeformableMultibody::exitPhysics()
|
||||
{
|
||||
//cleanup in the reverse order of creation/initialization
|
||||
removePickingConstraint();
|
||||
//remove the rigidbodies from the dynamics world and delete them
|
||||
int i;
|
||||
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
|
||||
{
|
||||
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
|
||||
btRigidBody* body = btRigidBody::upcast(obj);
|
||||
if (body && body->getMotionState())
|
||||
{
|
||||
delete body->getMotionState();
|
||||
}
|
||||
m_dynamicsWorld->removeCollisionObject(obj);
|
||||
delete obj;
|
||||
}
|
||||
// delete forces
|
||||
for (int j = 0; j < m_forces.size(); j++)
|
||||
{
|
||||
btDeformableLagrangianForce* force = m_forces[j];
|
||||
delete force;
|
||||
}
|
||||
m_forces.clear();
|
||||
//delete collision shapes
|
||||
for (int j = 0; j < m_collisionShapes.size(); j++)
|
||||
{
|
||||
btCollisionShape* shape = m_collisionShapes[j];
|
||||
delete shape;
|
||||
}
|
||||
m_collisionShapes.clear();
|
||||
|
||||
delete m_dynamicsWorld;
|
||||
|
||||
delete m_solver;
|
||||
|
||||
delete m_broadphase;
|
||||
|
||||
delete m_dispatcher;
|
||||
|
||||
delete m_collisionConfiguration;
|
||||
}
|
||||
|
||||
void DeformableMultibody::stepSimulation(float deltaTime)
|
||||
{
|
||||
// getDeformableDynamicsWorld()->getMultiBodyDynamicsWorld()->stepSimulation(deltaTime);
|
||||
m_dynamicsWorld->stepSimulation(deltaTime, 5, 1./250.);
|
||||
}
|
||||
|
||||
|
||||
btMultiBody* DeformableMultibody::createFeatherstoneMultiBody_testMultiDof(btMultiBodyDynamicsWorld* pWorld, int numLinks, const btVector3& basePosition, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents, bool spherical, bool floating)
|
||||
{
|
||||
//init the base
|
||||
btVector3 baseInertiaDiag(0.f, 0.f, 0.f);
|
||||
float baseMass = .1f;
|
||||
|
||||
if (baseMass)
|
||||
{
|
||||
btCollisionShape* pTempBox = new btBoxShape(btVector3(baseHalfExtents[0], baseHalfExtents[1], baseHalfExtents[2]));
|
||||
pTempBox->calculateLocalInertia(baseMass, baseInertiaDiag);
|
||||
delete pTempBox;
|
||||
}
|
||||
|
||||
bool canSleep = false;
|
||||
|
||||
btMultiBody* pMultiBody = new btMultiBody(numLinks, baseMass, baseInertiaDiag, !floating, canSleep);
|
||||
|
||||
btQuaternion baseOriQuat(0.f, 0.f, 0.f, 1.f);
|
||||
pMultiBody->setBasePos(basePosition);
|
||||
pMultiBody->setWorldToBaseRot(baseOriQuat);
|
||||
btVector3 vel(0, 0, 0);
|
||||
// pMultiBody->setBaseVel(vel);
|
||||
|
||||
//init the links
|
||||
btVector3 hingeJointAxis(1, 0, 0);
|
||||
float linkMass = .1f;
|
||||
btVector3 linkInertiaDiag(0.f, 0.f, 0.f);
|
||||
|
||||
btCollisionShape* pTempBox = new btBoxShape(btVector3(linkHalfExtents[0], linkHalfExtents[1], linkHalfExtents[2]));
|
||||
pTempBox->calculateLocalInertia(linkMass, linkInertiaDiag);
|
||||
delete pTempBox;
|
||||
|
||||
//y-axis assumed up
|
||||
btVector3 parentComToCurrentCom(0, -linkHalfExtents[1] * 2.f, 0); //par body's COM to cur body's COM offset
|
||||
btVector3 currentPivotToCurrentCom(0, -linkHalfExtents[1], 0); //cur body's COM to cur body's PIV offset
|
||||
btVector3 parentComToCurrentPivot = parentComToCurrentCom - currentPivotToCurrentCom; //par body's COM to cur body's PIV offset
|
||||
|
||||
//////
|
||||
btScalar q0 = 0.f * SIMD_PI / 180.f;
|
||||
btQuaternion quat0(btVector3(0, 1, 0).normalized(), q0);
|
||||
quat0.normalize();
|
||||
/////
|
||||
|
||||
for (int i = 0; i < numLinks; ++i)
|
||||
{
|
||||
if (!spherical)
|
||||
pMultiBody->setupRevolute(i, linkMass, linkInertiaDiag, i - 1, btQuaternion(0.f, 0.f, 0.f, 1.f), hingeJointAxis, parentComToCurrentPivot, currentPivotToCurrentCom, true);
|
||||
else
|
||||
//pMultiBody->setupPlanar(i, linkMass, linkInertiaDiag, i - 1, btQuaternion(0.f, 0.f, 0.f, 1.f)/*quat0*/, btVector3(1, 0, 0), parentComToCurrentPivot*2, false);
|
||||
pMultiBody->setupSpherical(i, linkMass, linkInertiaDiag, i - 1, btQuaternion(0.f, 0.f, 0.f, 1.f), parentComToCurrentPivot, currentPivotToCurrentCom, true);
|
||||
}
|
||||
|
||||
pMultiBody->finalizeMultiDof();
|
||||
|
||||
///
|
||||
pWorld->addMultiBody(pMultiBody);
|
||||
///
|
||||
return pMultiBody;
|
||||
}
|
||||
|
||||
void DeformableMultibody::addColliders_testMultiDof(btMultiBody* pMultiBody, btMultiBodyDynamicsWorld* pWorld, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents)
|
||||
{
|
||||
btAlignedObjectArray<btQuaternion> world_to_local;
|
||||
world_to_local.resize(pMultiBody->getNumLinks() + 1);
|
||||
|
||||
btAlignedObjectArray<btVector3> local_origin;
|
||||
local_origin.resize(pMultiBody->getNumLinks() + 1);
|
||||
world_to_local[0] = pMultiBody->getWorldToBaseRot();
|
||||
local_origin[0] = pMultiBody->getBasePos();
|
||||
|
||||
{
|
||||
|
||||
btScalar quat[4] = {-world_to_local[0].x(), -world_to_local[0].y(), -world_to_local[0].z(), world_to_local[0].w()};
|
||||
|
||||
btCollisionShape* box = new btBoxShape(baseHalfExtents);
|
||||
box->setMargin(0.01);
|
||||
btMultiBodyLinkCollider* col = new btMultiBodyLinkCollider(pMultiBody, -1);
|
||||
col->setCollisionShape(box);
|
||||
|
||||
btTransform tr;
|
||||
tr.setIdentity();
|
||||
tr.setOrigin(local_origin[0]);
|
||||
tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3]));
|
||||
col->setWorldTransform(tr);
|
||||
|
||||
pWorld->addCollisionObject(col, 2, 1 + 2);
|
||||
|
||||
col->setFriction(friction);
|
||||
pMultiBody->setBaseCollider(col);
|
||||
}
|
||||
|
||||
for (int i = 0; i < pMultiBody->getNumLinks(); ++i)
|
||||
{
|
||||
const int parent = pMultiBody->getParent(i);
|
||||
world_to_local[i + 1] = pMultiBody->getParentToLocalRot(i) * world_to_local[parent + 1];
|
||||
local_origin[i + 1] = local_origin[parent + 1] + (quatRotate(world_to_local[i + 1].inverse(), pMultiBody->getRVector(i)));
|
||||
}
|
||||
|
||||
for (int i = 0; i < pMultiBody->getNumLinks(); ++i)
|
||||
{
|
||||
btVector3 posr = local_origin[i + 1];
|
||||
|
||||
btScalar quat[4] = {-world_to_local[i + 1].x(), -world_to_local[i + 1].y(), -world_to_local[i + 1].z(), world_to_local[i + 1].w()};
|
||||
|
||||
btCollisionShape* box = new btBoxShape(linkHalfExtents);
|
||||
btMultiBodyLinkCollider* col = new btMultiBodyLinkCollider(pMultiBody, i);
|
||||
|
||||
col->setCollisionShape(box);
|
||||
btTransform tr;
|
||||
tr.setIdentity();
|
||||
tr.setOrigin(posr);
|
||||
tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3]));
|
||||
col->setWorldTransform(tr);
|
||||
col->setFriction(friction);
|
||||
pWorld->addCollisionObject(col, 2, 1 + 2);
|
||||
|
||||
pMultiBody->getLink(i).m_collider = col;
|
||||
}
|
||||
}
|
||||
class CommonExampleInterface* DeformableMultibodyCreateFunc(struct CommonExampleOptions& options)
|
||||
{
|
||||
return new DeformableMultibody(options.m_guiHelper);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 Google Inc. http://bulletphysics.org
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef _DEFORMABLE_MULTIBODY_H
|
||||
#define _DEFORMABLE_MULTIBODY_H
|
||||
|
||||
class CommonExampleInterface* DeformableMultibodyCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
#endif //_DEFORMABLE_MULTIBODY_H
|
||||
334
Engine/lib/bullet/examples/DeformableDemo/DeformableRigid.cpp
Normal file
334
Engine/lib/bullet/examples/DeformableDemo/DeformableRigid.cpp
Normal file
|
|
@ -0,0 +1,334 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 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 "DeformableRigid.h"
|
||||
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
|
||||
#include "BulletSoftBody/btSoftBody.h"
|
||||
#include "BulletSoftBody/btSoftBodyHelpers.h"
|
||||
#include "BulletSoftBody/btDeformableBodySolver.h"
|
||||
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
|
||||
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
|
||||
#include <stdio.h> //printf debugging
|
||||
|
||||
#include "../CommonInterfaces/CommonDeformableBodyBase.h"
|
||||
#include "../Utils/b3ResourcePath.h"
|
||||
|
||||
///The DeformableRigid shows contact between deformable objects and rigid objects.
|
||||
class DeformableRigid : public CommonDeformableBodyBase
|
||||
{
|
||||
public:
|
||||
DeformableRigid(struct GUIHelperInterface* helper)
|
||||
:CommonDeformableBodyBase(helper)
|
||||
{
|
||||
}
|
||||
virtual ~DeformableRigid()
|
||||
{
|
||||
}
|
||||
void initPhysics();
|
||||
|
||||
void exitPhysics();
|
||||
|
||||
void resetCamera()
|
||||
{
|
||||
float dist = 20;
|
||||
float pitch = -45;
|
||||
float yaw = 100;
|
||||
float targetPos[3] = {0, -3, 0};
|
||||
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
|
||||
}
|
||||
|
||||
void stepSimulation(float deltaTime)
|
||||
{
|
||||
//use a smaller internal timestep, there are stability issues
|
||||
float internalTimeStep = 1. / 240.f;
|
||||
m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep);
|
||||
|
||||
//
|
||||
// btCollisionShape* boxShape = new btBoxShape(btVector3(1, 1, 1));
|
||||
// boxShape->setMargin(1e-3);
|
||||
// if (0)
|
||||
// {
|
||||
// btVector3 p(0.99,1.01,0.99);
|
||||
// for (int i = 0; i < 40; ++i)
|
||||
// {
|
||||
// p[1] -= 0.001;
|
||||
// btScalar margin(.000001);
|
||||
// btTransform trans;
|
||||
// trans.setIdentity();
|
||||
// btGjkEpaSolver2::sResults results;
|
||||
// const btConvexShape* csh = static_cast<const btConvexShape*>(boxShape);
|
||||
// btScalar d = btGjkEpaSolver2::SignedDistance(p, margin, csh, trans, results);
|
||||
// printf("d = %f\n", d);
|
||||
// printf("----\n");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// btVector3 p(.991,1.01,.99);
|
||||
// for (int i = 0; i < 40; ++i)
|
||||
// {
|
||||
// p[1] -= 0.001;
|
||||
// btScalar margin(.006);
|
||||
// btTransform trans;
|
||||
// trans.setIdentity();
|
||||
// btScalar dst;
|
||||
// btGjkEpaSolver2::sResults results;
|
||||
// btTransform point_transform;
|
||||
// point_transform.setIdentity();
|
||||
// point_transform.setOrigin(p);
|
||||
// btSphereShape sphere(margin);
|
||||
// btVector3 guess(0,0,0);
|
||||
// const btConvexShape* csh = static_cast<const btConvexShape*>(boxShape);
|
||||
// btGjkEpaSolver2::SignedDistance(&sphere, point_transform, csh, trans, guess, results);
|
||||
// dst = results.distance-csh->getMargin();
|
||||
// dst -= margin;
|
||||
// printf("d = %f\n", dst);
|
||||
// printf("----\n");
|
||||
// }
|
||||
}
|
||||
|
||||
void Ctor_RbUpStack(int count)
|
||||
{
|
||||
float mass = .2;
|
||||
|
||||
btCompoundShape* cylinderCompound = new btCompoundShape;
|
||||
btCollisionShape* cylinderShape = new btCylinderShapeX(btVector3(2, .5, .5));
|
||||
btCollisionShape* boxShape = new btBoxShape(btVector3(2, .5, .5));
|
||||
btTransform localTransform;
|
||||
localTransform.setIdentity();
|
||||
cylinderCompound->addChildShape(localTransform, boxShape);
|
||||
btQuaternion orn(SIMD_HALF_PI, 0, 0);
|
||||
localTransform.setRotation(orn);
|
||||
// localTransform.setOrigin(btVector3(1,1,1));
|
||||
cylinderCompound->addChildShape(localTransform, cylinderShape);
|
||||
|
||||
btCollisionShape* shape[] = {
|
||||
new btBoxShape(btVector3(1, 1, 1)),
|
||||
new btSphereShape(0.75),
|
||||
cylinderCompound
|
||||
};
|
||||
// static const int nshapes = sizeof(shape) / sizeof(shape[0]);
|
||||
// for (int i = 0; i < count; ++i)
|
||||
// {
|
||||
// btTransform startTransform;
|
||||
// startTransform.setIdentity();
|
||||
// startTransform.setOrigin(btVector3(0, 2+ 2 * i, 0));
|
||||
// startTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.));
|
||||
// createRigidBody(mass, startTransform, shape[i % nshapes]);
|
||||
// }
|
||||
btTransform startTransform;
|
||||
startTransform.setIdentity();
|
||||
startTransform.setOrigin(btVector3(1, 1.5, 1));
|
||||
createRigidBody(mass, startTransform, shape[0]);
|
||||
startTransform.setOrigin(btVector3(1, 1.5, -1));
|
||||
createRigidBody(mass, startTransform, shape[0]);
|
||||
startTransform.setOrigin(btVector3(-1, 1.5, 1));
|
||||
createRigidBody(mass, startTransform, shape[0]);
|
||||
startTransform.setOrigin(btVector3(-1, 1.5, -1));
|
||||
createRigidBody(mass, startTransform, shape[0]);
|
||||
startTransform.setOrigin(btVector3(0, 3.5, 0));
|
||||
createRigidBody(mass, startTransform, shape[0]);
|
||||
}
|
||||
|
||||
virtual const btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld() const
|
||||
{
|
||||
///just make it a btSoftRigidDynamicsWorld please
|
||||
///or we will add type checking
|
||||
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
|
||||
}
|
||||
|
||||
virtual btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld()
|
||||
{
|
||||
///just make it a btSoftRigidDynamicsWorld please
|
||||
///or we will add type checking
|
||||
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
|
||||
}
|
||||
|
||||
virtual void renderScene()
|
||||
{
|
||||
CommonDeformableBodyBase::renderScene();
|
||||
btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
|
||||
|
||||
for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
|
||||
{
|
||||
btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i];
|
||||
//if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe)))
|
||||
{
|
||||
btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer());
|
||||
btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), fDrawFlags::Faces);// deformableWorld->getDrawFlags());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void DeformableRigid::initPhysics()
|
||||
{
|
||||
m_guiHelper->setUpAxis(1);
|
||||
|
||||
///collision configuration contains default setup for memory, collision setup
|
||||
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
|
||||
|
||||
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
|
||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
||||
|
||||
m_broadphase = new btDbvtBroadphase();
|
||||
btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
|
||||
|
||||
///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
|
||||
btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
|
||||
sol->setDeformableSolver(deformableBodySolver);
|
||||
m_solver = sol;
|
||||
|
||||
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
|
||||
// deformableBodySolver->setWorld(getDeformableDynamicsWorld());
|
||||
// m_dynamicsWorld->getSolverInfo().m_singleAxisDeformableThreshold = 0.f;//faster but lower quality
|
||||
btVector3 gravity = btVector3(0, -10, 0);
|
||||
m_dynamicsWorld->setGravity(gravity);
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.setDefaultVoxelsz(0.25);
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.Reset();
|
||||
|
||||
// getDeformableDynamicsWorld()->before_solver_callbacks.push_back(dynamics);
|
||||
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
|
||||
|
||||
{
|
||||
///create a ground
|
||||
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(25.), btScalar(150.)));
|
||||
|
||||
m_collisionShapes.push_back(groundShape);
|
||||
|
||||
btTransform groundTransform;
|
||||
groundTransform.setIdentity();
|
||||
groundTransform.setOrigin(btVector3(0, -42, 0));
|
||||
groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.));
|
||||
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
|
||||
btScalar mass(0.);
|
||||
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
bool isDynamic = (mass != 0.f);
|
||||
|
||||
btVector3 localInertia(0, 0, 0);
|
||||
if (isDynamic)
|
||||
groundShape->calculateLocalInertia(mass, localInertia);
|
||||
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
|
||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
|
||||
btRigidBody* body = new btRigidBody(rbInfo);
|
||||
body->setFriction(1);
|
||||
|
||||
//add the ground to the dynamics world
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
}
|
||||
|
||||
// create a piece of cloth
|
||||
if(1)
|
||||
{
|
||||
bool onGround = false;
|
||||
const btScalar s = 4;
|
||||
const btScalar h = 0;
|
||||
|
||||
btSoftBody* psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, h, -s),
|
||||
btVector3(+s, h, -s),
|
||||
btVector3(-s, h, +s),
|
||||
btVector3(+s, h, +s),
|
||||
// 3,3,
|
||||
20,20,
|
||||
1 + 2 + 4 + 8, true);
|
||||
// 0, true);
|
||||
|
||||
if (onGround)
|
||||
psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, 0, -s),
|
||||
btVector3(+s, 0, -s),
|
||||
btVector3(-s, 0, +s),
|
||||
btVector3(+s, 0, +s),
|
||||
// 20,20,
|
||||
2,2,
|
||||
0, true);
|
||||
|
||||
psb->getCollisionShape()->setMargin(0.05);
|
||||
psb->generateBendingConstraints(2);
|
||||
psb->setTotalMass(1);
|
||||
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
|
||||
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
|
||||
psb->m_cfg.kDF = 2;
|
||||
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
|
||||
psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDF;
|
||||
getDeformableDynamicsWorld()->addSoftBody(psb);
|
||||
|
||||
btDeformableMassSpringForce* mass_spring = new btDeformableMassSpringForce(15,0.5, true);
|
||||
getDeformableDynamicsWorld()->addForce(psb, mass_spring);
|
||||
m_forces.push_back(mass_spring);
|
||||
|
||||
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
|
||||
getDeformableDynamicsWorld()->addForce(psb, gravity_force);
|
||||
m_forces.push_back(gravity_force);
|
||||
// add a few rigid bodies
|
||||
}
|
||||
Ctor_RbUpStack(10);
|
||||
getDeformableDynamicsWorld()->setImplicit(false);
|
||||
getDeformableDynamicsWorld()->setLineSearch(false);
|
||||
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
|
||||
}
|
||||
|
||||
void DeformableRigid::exitPhysics()
|
||||
{
|
||||
//cleanup in the reverse order of creation/initialization
|
||||
removePickingConstraint();
|
||||
//remove the rigidbodies from the dynamics world and delete them
|
||||
int i;
|
||||
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
|
||||
{
|
||||
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
|
||||
btRigidBody* body = btRigidBody::upcast(obj);
|
||||
if (body && body->getMotionState())
|
||||
{
|
||||
delete body->getMotionState();
|
||||
}
|
||||
m_dynamicsWorld->removeCollisionObject(obj);
|
||||
delete obj;
|
||||
}
|
||||
// delete forces
|
||||
for (int j = 0; j < m_forces.size(); j++)
|
||||
{
|
||||
btDeformableLagrangianForce* force = m_forces[j];
|
||||
delete force;
|
||||
}
|
||||
m_forces.clear();
|
||||
//delete collision shapes
|
||||
for (int j = 0; j < m_collisionShapes.size(); j++)
|
||||
{
|
||||
btCollisionShape* shape = m_collisionShapes[j];
|
||||
delete shape;
|
||||
}
|
||||
m_collisionShapes.clear();
|
||||
|
||||
delete m_dynamicsWorld;
|
||||
|
||||
delete m_solver;
|
||||
|
||||
delete m_broadphase;
|
||||
|
||||
delete m_dispatcher;
|
||||
|
||||
delete m_collisionConfiguration;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class CommonExampleInterface* DeformableRigidCreateFunc(struct CommonExampleOptions& options)
|
||||
{
|
||||
return new DeformableRigid(options.m_guiHelper);
|
||||
}
|
||||
|
||||
|
||||
19
Engine/lib/bullet/examples/DeformableDemo/DeformableRigid.h
Normal file
19
Engine/lib/bullet/examples/DeformableDemo/DeformableRigid.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 Google Inc. http://bulletphysics.org
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef _DEFORMABLE_RIGID_H
|
||||
#define _DEFORMABLE_RIGID_H
|
||||
|
||||
class CommonExampleInterface* DeformableRigidCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
#endif //_DEFORMABLE_RIGID_H
|
||||
|
|
@ -0,0 +1,223 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 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 "DeformableSelfCollision.h"
|
||||
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
|
||||
#include "BulletSoftBody/btSoftBody.h"
|
||||
#include "BulletSoftBody/btSoftBodyHelpers.h"
|
||||
#include "BulletSoftBody/btDeformableBodySolver.h"
|
||||
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
|
||||
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
|
||||
#include <stdio.h> //printf debugging
|
||||
|
||||
#include "../CommonInterfaces/CommonDeformableBodyBase.h"
|
||||
#include "../Utils/b3ResourcePath.h"
|
||||
|
||||
///The DeformableSelfCollision shows deformable self collisions
|
||||
class DeformableSelfCollision : public CommonDeformableBodyBase
|
||||
{
|
||||
public:
|
||||
DeformableSelfCollision(struct GUIHelperInterface* helper)
|
||||
: CommonDeformableBodyBase(helper)
|
||||
{
|
||||
m_maxPickingForce = 0.004;
|
||||
}
|
||||
virtual ~DeformableSelfCollision()
|
||||
{
|
||||
}
|
||||
void initPhysics();
|
||||
|
||||
void exitPhysics();
|
||||
|
||||
void resetCamera()
|
||||
{
|
||||
float dist = 2.0;
|
||||
float pitch = -8;
|
||||
float yaw = 100;
|
||||
float targetPos[3] = {0, -1.0, 0};
|
||||
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
|
||||
}
|
||||
|
||||
void stepSimulation(float deltaTime)
|
||||
{
|
||||
float internalTimeStep = 1. / 240.f;
|
||||
m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep);
|
||||
}
|
||||
|
||||
void addCloth(const btVector3& origin);
|
||||
|
||||
virtual void renderScene()
|
||||
{
|
||||
CommonDeformableBodyBase::renderScene();
|
||||
}
|
||||
};
|
||||
|
||||
void DeformableSelfCollision::initPhysics()
|
||||
{
|
||||
m_guiHelper->setUpAxis(1);
|
||||
///collision configuration contains default setup for memory, collision setup
|
||||
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
|
||||
|
||||
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
|
||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
||||
|
||||
m_broadphase = new btDbvtBroadphase();
|
||||
btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
|
||||
|
||||
///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
|
||||
btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
|
||||
sol->setDeformableSolver(deformableBodySolver);
|
||||
m_solver = sol;
|
||||
|
||||
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
|
||||
// deformableBodySolver->setWorld(getDeformableDynamicsWorld());
|
||||
// m_dynamicsWorld->getSolverInfo().m_singleAxisDeformableThreshold = 0.f;//faster but lower quality
|
||||
btVector3 gravity = btVector3(0, -9.8, 0);
|
||||
m_dynamicsWorld->setGravity(gravity);
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.setDefaultVoxelsz(0.25);
|
||||
|
||||
// getDeformableDynamicsWorld()->before_solver_callbacks.push_back(dynamics);
|
||||
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
|
||||
|
||||
{
|
||||
///create a ground
|
||||
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(2.5), btScalar(150.)));
|
||||
groundShape->setMargin(0.02);
|
||||
m_collisionShapes.push_back(groundShape);
|
||||
|
||||
btTransform groundTransform;
|
||||
groundTransform.setIdentity();
|
||||
groundTransform.setOrigin(btVector3(0, -3.5, 0));
|
||||
groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0));
|
||||
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
|
||||
btScalar mass(0.);
|
||||
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
bool isDynamic = (mass != 0.f);
|
||||
|
||||
btVector3 localInertia(0, 0, 0);
|
||||
if (isDynamic)
|
||||
groundShape->calculateLocalInertia(mass, localInertia);
|
||||
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
|
||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
|
||||
btRigidBody* body = new btRigidBody(rbInfo);
|
||||
body->setFriction(4);
|
||||
|
||||
//add the ground to the dynamics world
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
}
|
||||
addCloth(btVector3(0, -0.2, 0));
|
||||
addCloth(btVector3(0, -0.1, 0));
|
||||
getDeformableDynamicsWorld()->setImplicit(false);
|
||||
getDeformableDynamicsWorld()->setLineSearch(false);
|
||||
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
|
||||
}
|
||||
void DeformableSelfCollision::addCloth(const btVector3& origin)
|
||||
// create a piece of cloth
|
||||
{
|
||||
const btScalar s = 0.6;
|
||||
const btScalar h = 0;
|
||||
|
||||
btSoftBody* psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, h, -2*s),
|
||||
btVector3(+s, h, -2*s),
|
||||
btVector3(-s, h, +2*s),
|
||||
btVector3(+s, h, +2*s),
|
||||
15,30,
|
||||
// 4,4,
|
||||
0, true, 0.0);
|
||||
|
||||
|
||||
psb->getCollisionShape()->setMargin(0.02);
|
||||
psb->generateBendingConstraints(2);
|
||||
psb->setTotalMass(.5);
|
||||
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
|
||||
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
|
||||
psb->m_cfg.kDF = 0.1;
|
||||
// psb->rotate(btQuaternion(0, SIMD_PI / 2, 0));
|
||||
btTransform clothTransform;
|
||||
clothTransform.setIdentity();
|
||||
clothTransform.setOrigin(btVector3(0,0.2,0)+origin);
|
||||
psb->transform(clothTransform);
|
||||
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
|
||||
psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDN;
|
||||
psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDF;
|
||||
psb->m_cfg.collisions |= btSoftBody::fCollision::VF_DD;
|
||||
getDeformableDynamicsWorld()->addSoftBody(psb);
|
||||
psb->setSelfCollision(true);
|
||||
|
||||
btDeformableMassSpringForce* mass_spring = new btDeformableMassSpringForce(2,0.2, true);
|
||||
psb->setSpringStiffness(4);
|
||||
getDeformableDynamicsWorld()->addForce(psb, mass_spring);
|
||||
m_forces.push_back(mass_spring);
|
||||
btVector3 gravity = btVector3(0, -9.8, 0);
|
||||
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
|
||||
getDeformableDynamicsWorld()->addForce(psb, gravity_force);
|
||||
getDeformableDynamicsWorld()->setUseProjection(true);
|
||||
m_forces.push_back(gravity_force);
|
||||
}
|
||||
|
||||
void DeformableSelfCollision::exitPhysics()
|
||||
{
|
||||
//cleanup in the reverse order of creation/initialization
|
||||
removePickingConstraint();
|
||||
//remove the rigidbodies from the dynamics world and delete them
|
||||
int i;
|
||||
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
|
||||
{
|
||||
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
|
||||
btRigidBody* body = btRigidBody::upcast(obj);
|
||||
if (body && body->getMotionState())
|
||||
{
|
||||
delete body->getMotionState();
|
||||
}
|
||||
m_dynamicsWorld->removeCollisionObject(obj);
|
||||
delete obj;
|
||||
}
|
||||
// delete forces
|
||||
for (int j = 0; j < m_forces.size(); j++)
|
||||
{
|
||||
btDeformableLagrangianForce* force = m_forces[j];
|
||||
delete force;
|
||||
}
|
||||
m_forces.clear();
|
||||
//delete collision shapes
|
||||
for (int j = 0; j < m_collisionShapes.size(); j++)
|
||||
{
|
||||
btCollisionShape* shape = m_collisionShapes[j];
|
||||
delete shape;
|
||||
}
|
||||
m_collisionShapes.clear();
|
||||
|
||||
delete m_dynamicsWorld;
|
||||
|
||||
delete m_solver;
|
||||
|
||||
delete m_broadphase;
|
||||
|
||||
delete m_dispatcher;
|
||||
|
||||
delete m_collisionConfiguration;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class CommonExampleInterface* DeformableSelfCollisionCreateFunc(struct CommonExampleOptions& options)
|
||||
{
|
||||
return new DeformableSelfCollision(options.m_guiHelper);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 Google Inc. http://bulletphysics.org
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef DEFORMABLE_SELF_COLLISION_H
|
||||
#define DEFORMABLE_SELF_COLLISION_H
|
||||
|
||||
class CommonExampleInterface* DeformableSelfCollisionCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
#endif //_DEFORMABLE_SELF_COLLISION_H
|
||||
563
Engine/lib/bullet/examples/DeformableDemo/GraspDeformable.cpp
Normal file
563
Engine/lib/bullet/examples/DeformableDemo/GraspDeformable.cpp
Normal file
|
|
@ -0,0 +1,563 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 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 "GraspDeformable.h"
|
||||
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
|
||||
#include "BulletSoftBody/btSoftBody.h"
|
||||
#include "BulletSoftBody/btSoftBodyHelpers.h"
|
||||
#include "BulletSoftBody/btDeformableBodySolver.h"
|
||||
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
|
||||
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
|
||||
#include "BulletDynamics/Featherstone/btMultiBodyJointMotor.h"
|
||||
#include <stdio.h> //printf debugging
|
||||
|
||||
#include "../CommonInterfaces/CommonDeformableBodyBase.h"
|
||||
#include "../Utils/b3ResourcePath.h"
|
||||
#include "../Importers/ImportURDFDemo/BulletUrdfImporter.h"
|
||||
#include "../Importers/ImportURDFDemo/MyMultiBodyCreator.h"
|
||||
#include "../Importers/ImportURDFDemo/URDF2Bullet.h"
|
||||
#include "../Utils/b3BulletDefaultFileIO.h"
|
||||
#include "../CommonInterfaces/CommonMultiBodyBase.h"
|
||||
#include "../CommonInterfaces/CommonGraphicsAppInterface.h"
|
||||
#include "../CommonInterfaces/CommonParameterInterface.h"
|
||||
#include "../CommonInterfaces/CommonFileIOInterface.h"
|
||||
#include "Bullet3Common/b3FileUtils.h"
|
||||
|
||||
///The GraspDeformable shows grasping a volumetric deformable objects with multibody gripper with moter constraints.
|
||||
static btScalar sGripperVerticalVelocity = 0.f;
|
||||
static btScalar sGripperClosingTargetVelocity = 0.f;
|
||||
static float friction = 1.;
|
||||
struct TetraCube
|
||||
{
|
||||
#include "../SoftDemo/cube.inl"
|
||||
};
|
||||
|
||||
struct TetraBunny
|
||||
{
|
||||
#include "../SoftDemo/bunny.inl"
|
||||
};
|
||||
|
||||
static bool supportsJointMotor(btMultiBody* mb, int mbLinkIndex)
|
||||
{
|
||||
bool canHaveMotor = (mb->getLink(mbLinkIndex).m_jointType == btMultibodyLink::eRevolute
|
||||
|| mb->getLink(mbLinkIndex).m_jointType == btMultibodyLink::ePrismatic);
|
||||
return canHaveMotor;
|
||||
}
|
||||
|
||||
class GraspDeformable : public CommonDeformableBodyBase
|
||||
{
|
||||
btAlignedObjectArray<btDeformableLagrangianForce*> m_forces;
|
||||
public:
|
||||
GraspDeformable(struct GUIHelperInterface* helper)
|
||||
:CommonDeformableBodyBase(helper)
|
||||
{
|
||||
}
|
||||
virtual ~GraspDeformable()
|
||||
{
|
||||
}
|
||||
void initPhysics();
|
||||
|
||||
void exitPhysics();
|
||||
|
||||
void resetCamera()
|
||||
{
|
||||
float dist = 0.3;
|
||||
float pitch = -45;
|
||||
float yaw = 100;
|
||||
float targetPos[3] = {0, -0.1, 0};
|
||||
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
|
||||
}
|
||||
|
||||
btMultiBody* createFeatherstoneMultiBody(btMultiBodyDynamicsWorld* pWorld,const btVector3& basePosition, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents, bool floating);
|
||||
|
||||
void addColliders(btMultiBody* pMultiBody, btMultiBodyDynamicsWorld* pWorld, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents);
|
||||
|
||||
btMultiBody* createFeatherstoneMultiBody_testMultiDof(btMultiBodyDynamicsWorld* pWorld, int numLinks, const btVector3& basePosition, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents, bool spherical, bool floating);
|
||||
|
||||
void stepSimulation(float deltaTime)
|
||||
{
|
||||
double fingerTargetVelocities[2] = {sGripperVerticalVelocity, sGripperClosingTargetVelocity};
|
||||
int num_multiBody = getDeformableDynamicsWorld()->getNumMultibodies();
|
||||
for (int i = 0; i < num_multiBody; ++i)
|
||||
{
|
||||
btMultiBody* mb = getDeformableDynamicsWorld()->btMultiBodyDynamicsWorld::getMultiBody(i);
|
||||
mb->setBaseVel(btVector3(0,sGripperVerticalVelocity, 0));
|
||||
int dofIndex = 6; //skip the 3 linear + 3 angular degree of freedom entries of the base
|
||||
for (int link = 0; link < mb->getNumLinks(); link++)
|
||||
{
|
||||
if (supportsJointMotor(mb, link))
|
||||
{
|
||||
btMultiBodyJointMotor* motor = (btMultiBodyJointMotor*)mb->getLink(link).m_userPtr;
|
||||
if (motor)
|
||||
{
|
||||
if (dofIndex == 6)
|
||||
{
|
||||
motor->setVelocityTarget(-fingerTargetVelocities[1], 1);
|
||||
motor->setMaxAppliedImpulse(20);
|
||||
}
|
||||
if (dofIndex == 7)
|
||||
{
|
||||
motor->setVelocityTarget(fingerTargetVelocities[1], 1);
|
||||
motor->setMaxAppliedImpulse(20);
|
||||
}
|
||||
motor->setMaxAppliedImpulse(1);
|
||||
}
|
||||
}
|
||||
dofIndex += mb->getLink(link).m_dofCount;
|
||||
}
|
||||
}
|
||||
|
||||
//use a smaller internal timestep, there are stability issues
|
||||
float internalTimeStep = 1. / 240.f;
|
||||
m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep);
|
||||
}
|
||||
|
||||
void createGrip()
|
||||
{
|
||||
int count = 2;
|
||||
float mass = 2;
|
||||
btCollisionShape* shape[] = {
|
||||
new btBoxShape(btVector3(3, 3, 0.5)),
|
||||
};
|
||||
static const int nshapes = sizeof(shape) / sizeof(shape[0]);
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
btTransform startTransform;
|
||||
startTransform.setIdentity();
|
||||
startTransform.setOrigin(btVector3(10, 0, 0));
|
||||
startTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.));
|
||||
createRigidBody(mass, startTransform, shape[i % nshapes]);
|
||||
}
|
||||
}
|
||||
|
||||
virtual const btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld() const
|
||||
{
|
||||
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
|
||||
}
|
||||
|
||||
virtual btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld()
|
||||
{
|
||||
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
|
||||
}
|
||||
|
||||
virtual void renderScene()
|
||||
{
|
||||
CommonDeformableBodyBase::renderScene();
|
||||
btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
|
||||
|
||||
for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
|
||||
{
|
||||
btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i];
|
||||
{
|
||||
btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer());
|
||||
btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), fDrawFlags::Faces);// deformableWorld->getDrawFlags());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool movePickedBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual void removePickingConstraint(){}
|
||||
};
|
||||
|
||||
|
||||
void GraspDeformable::initPhysics()
|
||||
{
|
||||
m_guiHelper->setUpAxis(1);
|
||||
|
||||
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
|
||||
|
||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
||||
|
||||
m_broadphase = new btDbvtBroadphase();
|
||||
btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
|
||||
|
||||
btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
|
||||
sol->setDeformableSolver(deformableBodySolver);
|
||||
m_solver = sol;
|
||||
|
||||
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
|
||||
btVector3 gravity = btVector3(0, -9.81, 0);
|
||||
m_dynamicsWorld->setGravity(gravity);
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
|
||||
getDeformableDynamicsWorld()->getSolverInfo().m_deformable_erp = 0.1;
|
||||
getDeformableDynamicsWorld()->getSolverInfo().m_deformable_cfm = 0;
|
||||
getDeformableDynamicsWorld()->getSolverInfo().m_numIterations = 150;
|
||||
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
|
||||
m_maxPickingForce = 0.001;
|
||||
// build a gripper
|
||||
if(1)
|
||||
{
|
||||
bool damping = true;
|
||||
bool gyro = false;
|
||||
bool canSleep = false;
|
||||
bool selfCollide = true;
|
||||
int numLinks = 2;
|
||||
btVector3 linkHalfExtents(0.02, 0.018, .003);
|
||||
btVector3 baseHalfExtents(0.02, 0.002, .002);
|
||||
btMultiBody* mbC = createFeatherstoneMultiBody(getDeformableDynamicsWorld(), btVector3(0.f, 0.05f,0.f), linkHalfExtents, baseHalfExtents, false);
|
||||
|
||||
mbC->setCanSleep(canSleep);
|
||||
mbC->setHasSelfCollision(selfCollide);
|
||||
mbC->setUseGyroTerm(gyro);
|
||||
|
||||
for (int i = 0; i < numLinks; i++)
|
||||
{
|
||||
int mbLinkIndex = i;
|
||||
double maxMotorImpulse = 1;
|
||||
|
||||
if (supportsJointMotor(mbC, mbLinkIndex))
|
||||
{
|
||||
int dof = 0;
|
||||
btScalar desiredVelocity = 0.f;
|
||||
btMultiBodyJointMotor* motor = new btMultiBodyJointMotor(mbC, mbLinkIndex, dof, desiredVelocity, maxMotorImpulse);
|
||||
motor->setPositionTarget(0, 0);
|
||||
motor->setVelocityTarget(0, 1);
|
||||
mbC->getLink(mbLinkIndex).m_userPtr = motor;
|
||||
getDeformableDynamicsWorld()->addMultiBodyConstraint(motor);
|
||||
motor->finalizeMultiDof();
|
||||
}
|
||||
}
|
||||
|
||||
if (!damping)
|
||||
{
|
||||
mbC->setLinearDamping(0.0f);
|
||||
mbC->setAngularDamping(0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
mbC->setLinearDamping(0.04f);
|
||||
mbC->setAngularDamping(0.04f);
|
||||
}
|
||||
btScalar q0 = 0.f * SIMD_PI / 180.f;
|
||||
if (numLinks > 0)
|
||||
mbC->setJointPosMultiDof(0, &q0);
|
||||
addColliders(mbC, getDeformableDynamicsWorld(), baseHalfExtents, linkHalfExtents);
|
||||
}
|
||||
|
||||
//create a ground
|
||||
{
|
||||
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(10.), btScalar(5.), btScalar(10.)));
|
||||
groundShape->setMargin(0.001);
|
||||
m_collisionShapes.push_back(groundShape);
|
||||
|
||||
btTransform groundTransform;
|
||||
groundTransform.setIdentity();
|
||||
groundTransform.setOrigin(btVector3(0, -5.1, 0));
|
||||
groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0));
|
||||
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
|
||||
btScalar mass(0.);
|
||||
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
bool isDynamic = (mass != 0.f);
|
||||
|
||||
btVector3 localInertia(0, 0, 0);
|
||||
if (isDynamic)
|
||||
groundShape->calculateLocalInertia(mass, localInertia);
|
||||
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
|
||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
|
||||
btRigidBody* body = new btRigidBody(rbInfo);
|
||||
body->setFriction(0.5);
|
||||
|
||||
//add the ground to the dynamics world
|
||||
m_dynamicsWorld->addRigidBody(body,1,1+2);
|
||||
}
|
||||
|
||||
// create a soft block
|
||||
if (0)
|
||||
{
|
||||
char absolute_path[1024];
|
||||
b3BulletDefaultFileIO fileio;
|
||||
// fileio.findResourcePath("ditto.vtk", absolute_path, 1024);
|
||||
// fileio.findResourcePath("banana.vtk", absolute_path, 1024);
|
||||
fileio.findResourcePath("ball.vtk", absolute_path, 1024);
|
||||
// fileio.findResourcePath("deformable_crumpled_napkin_sim.vtk", absolute_path, 1024);
|
||||
// fileio.findResourcePath("single_tet.vtk", absolute_path, 1024);
|
||||
// fileio.findResourcePath("tube.vtk", absolute_path, 1024);
|
||||
// fileio.findResourcePath("torus.vtk", absolute_path, 1024);
|
||||
// fileio.findResourcePath("paper_roll.vtk", absolute_path, 1024);
|
||||
// fileio.findResourcePath("bread.vtk", absolute_path, 1024);
|
||||
// fileio.findResourcePath("boot.vtk", absolute_path, 1024);
|
||||
btSoftBody* psb = btSoftBodyHelpers::CreateFromTetGenData(getDeformableDynamicsWorld()->getWorldInfo(),
|
||||
TetraCube::getElements(),
|
||||
0,
|
||||
TetraCube::getNodes(),
|
||||
false, true, true);
|
||||
btSoftBodyHelpers::generateBoundaryFaces(psb);
|
||||
// btSoftBody* psb = btSoftBodyHelpers::CreateFromVtkFile(getDeformableDynamicsWorld()->getWorldInfo(), absolute_path);
|
||||
|
||||
// psb->scale(btVector3(30, 30, 30)); // for banana
|
||||
// psb->scale(btVector3(.7, .7, .7));
|
||||
psb->scale(btVector3(.2, .2, .2));
|
||||
// psb->scale(btVector3(.3, .3, .3)); // for tube, torus, boot
|
||||
// psb->scale(btVector3(.1, .1, .1)); // for ditto
|
||||
// psb->translate(btVector3(.25, 10, 0.4));
|
||||
psb->getCollisionShape()->setMargin(0.01);
|
||||
psb->setMaxStress(50);
|
||||
psb->setTotalMass(.1);
|
||||
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
|
||||
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
|
||||
psb->m_cfg.kDF = 2;
|
||||
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
|
||||
psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDF;
|
||||
psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_MDF;
|
||||
getDeformableDynamicsWorld()->addSoftBody(psb);
|
||||
|
||||
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
|
||||
getDeformableDynamicsWorld()->addForce(psb, gravity_force);
|
||||
m_forces.push_back(gravity_force);
|
||||
|
||||
btDeformableNeoHookeanForce* neohookean = new btDeformableNeoHookeanForce(20,80,.01);
|
||||
getDeformableDynamicsWorld()->addForce(psb, neohookean);
|
||||
m_forces.push_back(neohookean);
|
||||
}
|
||||
getDeformableDynamicsWorld()->setImplicit(false);
|
||||
|
||||
// create a piece of cloth
|
||||
if(1)
|
||||
{
|
||||
bool onGround = false;
|
||||
const btScalar s = .05;
|
||||
const btScalar h = -0.02;
|
||||
btSoftBody* psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, h, -s),
|
||||
btVector3(+s, h, -s),
|
||||
btVector3(-s, h, +s),
|
||||
btVector3(+s, h, +s),
|
||||
10,10,
|
||||
0, true);
|
||||
|
||||
if (onGround)
|
||||
psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, 0, -s),
|
||||
btVector3(+s, 0, -s),
|
||||
btVector3(-s, 0, +s),
|
||||
btVector3(+s, 0, +s),
|
||||
// 20,20,
|
||||
2,2,
|
||||
0, true);
|
||||
|
||||
psb->getCollisionShape()->setMargin(0.001);
|
||||
psb->generateBendingConstraints(2);
|
||||
psb->setTotalMass(0.01);
|
||||
psb->setSpringStiffness(10);
|
||||
psb->setDampingCoefficient(0.05);
|
||||
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
|
||||
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
|
||||
psb->m_cfg.kDF = 1;
|
||||
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
|
||||
psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_MDF;
|
||||
psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDF;
|
||||
getDeformableDynamicsWorld()->addSoftBody(psb);
|
||||
getDeformableDynamicsWorld()->addForce(psb, new btDeformableMassSpringForce(0.05,0.005, true));
|
||||
getDeformableDynamicsWorld()->addForce(psb, new btDeformableGravityForce(gravity*0.1));
|
||||
}
|
||||
|
||||
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
|
||||
|
||||
{
|
||||
SliderParams slider("Moving velocity", &sGripperVerticalVelocity);
|
||||
slider.m_minVal = -.02;
|
||||
slider.m_maxVal = .02;
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
}
|
||||
|
||||
{
|
||||
SliderParams slider("Closing velocity", &sGripperClosingTargetVelocity);
|
||||
slider.m_minVal = -1;
|
||||
slider.m_maxVal = 1;
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GraspDeformable::exitPhysics()
|
||||
{
|
||||
//cleanup in the reverse order of creation/initialization
|
||||
removePickingConstraint();
|
||||
//remove the rigidbodies from the dynamics world and delete them
|
||||
int i;
|
||||
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
|
||||
{
|
||||
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
|
||||
btRigidBody* body = btRigidBody::upcast(obj);
|
||||
if (body && body->getMotionState())
|
||||
{
|
||||
delete body->getMotionState();
|
||||
}
|
||||
m_dynamicsWorld->removeCollisionObject(obj);
|
||||
delete obj;
|
||||
}
|
||||
// delete forces
|
||||
for (int j = 0; j < m_forces.size(); j++)
|
||||
{
|
||||
btDeformableLagrangianForce* force = m_forces[j];
|
||||
delete force;
|
||||
}
|
||||
m_forces.clear();
|
||||
|
||||
//delete collision shapes
|
||||
for (int j = 0; j < m_collisionShapes.size(); j++)
|
||||
{
|
||||
btCollisionShape* shape = m_collisionShapes[j];
|
||||
delete shape;
|
||||
}
|
||||
m_collisionShapes.clear();
|
||||
|
||||
delete m_dynamicsWorld;
|
||||
|
||||
delete m_solver;
|
||||
|
||||
delete m_broadphase;
|
||||
|
||||
delete m_dispatcher;
|
||||
|
||||
delete m_collisionConfiguration;
|
||||
}
|
||||
|
||||
btMultiBody* GraspDeformable::createFeatherstoneMultiBody(btMultiBodyDynamicsWorld* pWorld, const btVector3& basePosition, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents, bool floating)
|
||||
{
|
||||
//init the base
|
||||
btVector3 baseInertiaDiag(0.f, 0.f, 0.f);
|
||||
float baseMass = 0.1;
|
||||
float linkMass = 0.1;
|
||||
int numLinks = 2;
|
||||
|
||||
if (baseMass)
|
||||
{
|
||||
btCollisionShape* pTempBox = new btBoxShape(btVector3(baseHalfExtents[0], baseHalfExtents[1], baseHalfExtents[2]));
|
||||
pTempBox->calculateLocalInertia(baseMass, baseInertiaDiag);
|
||||
delete pTempBox;
|
||||
}
|
||||
|
||||
bool canSleep = false;
|
||||
btMultiBody* pMultiBody = new btMultiBody(numLinks, baseMass, baseInertiaDiag, !floating, canSleep);
|
||||
|
||||
btQuaternion baseOriQuat(0.f, 0.f, 0.f, 1.f);
|
||||
pMultiBody->setBasePos(basePosition);
|
||||
pMultiBody->setWorldToBaseRot(baseOriQuat);
|
||||
|
||||
//init the links
|
||||
btVector3 hingeJointAxis(1, 0, 0);
|
||||
|
||||
btVector3 linkInertiaDiag(0.f, 0.f, 0.f);
|
||||
|
||||
btCollisionShape* pTempBox = new btBoxShape(btVector3(linkHalfExtents[0], linkHalfExtents[1], linkHalfExtents[2]));
|
||||
pTempBox->calculateLocalInertia(linkMass, linkInertiaDiag);
|
||||
delete pTempBox;
|
||||
|
||||
//y-axis assumed up
|
||||
btAlignedObjectArray<btVector3> parentComToCurrentCom;
|
||||
parentComToCurrentCom.push_back(btVector3(0, -linkHalfExtents[1] * 8.f, -baseHalfExtents[2] * 2.f));
|
||||
parentComToCurrentCom.push_back(btVector3(0, -linkHalfExtents[1] * 8.f, +baseHalfExtents[2] * 2.f));//par body's COM to cur body's COM offset
|
||||
|
||||
btVector3 currentPivotToCurrentCom(0, -linkHalfExtents[1]*8.f, 0); //cur body's COM to cur body's PIV offset
|
||||
|
||||
btAlignedObjectArray<btVector3> parentComToCurrentPivot;
|
||||
parentComToCurrentPivot.push_back(btVector3(parentComToCurrentCom[0] - currentPivotToCurrentCom));
|
||||
parentComToCurrentPivot.push_back(btVector3(parentComToCurrentCom[1] - currentPivotToCurrentCom));//par body's COM to cur body's PIV offset
|
||||
|
||||
//////
|
||||
btScalar q0 = 0.f * SIMD_PI / 180.f;
|
||||
btQuaternion quat0(btVector3(0, 1, 0).normalized(), q0);
|
||||
quat0.normalize();
|
||||
/////
|
||||
|
||||
for (int i = 0; i < numLinks; ++i)
|
||||
{
|
||||
pMultiBody->setupRevolute(i, linkMass, linkInertiaDiag, - 1, btQuaternion(0.f, 0.f, 0.f, 1.f), hingeJointAxis, parentComToCurrentPivot[i], currentPivotToCurrentCom, true);
|
||||
}
|
||||
pMultiBody->finalizeMultiDof();
|
||||
///
|
||||
pWorld->addMultiBody(pMultiBody);
|
||||
///
|
||||
return pMultiBody;
|
||||
}
|
||||
|
||||
void GraspDeformable::addColliders(btMultiBody* pMultiBody, btMultiBodyDynamicsWorld* pWorld, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents)
|
||||
{
|
||||
btAlignedObjectArray<btQuaternion> world_to_local;
|
||||
world_to_local.resize(pMultiBody->getNumLinks() + 1);
|
||||
|
||||
btAlignedObjectArray<btVector3> local_origin;
|
||||
local_origin.resize(pMultiBody->getNumLinks() + 1);
|
||||
world_to_local[0] = pMultiBody->getWorldToBaseRot();
|
||||
local_origin[0] = pMultiBody->getBasePos();
|
||||
|
||||
{
|
||||
btScalar quat[4] = {-world_to_local[0].x(), -world_to_local[0].y(), -world_to_local[0].z(), world_to_local[0].w()};
|
||||
|
||||
if (1)
|
||||
{
|
||||
btCollisionShape* box = new btBoxShape(baseHalfExtents);
|
||||
box->setMargin(0.001);
|
||||
btMultiBodyLinkCollider* col = new btMultiBodyLinkCollider(pMultiBody, -1);
|
||||
col->setCollisionShape(box);
|
||||
|
||||
btTransform tr;
|
||||
tr.setIdentity();
|
||||
tr.setOrigin(local_origin[0]);
|
||||
tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3]));
|
||||
col->setWorldTransform(tr);
|
||||
|
||||
pWorld->addCollisionObject(col, 2, 1 + 2);
|
||||
|
||||
col->setFriction(friction);
|
||||
pMultiBody->setBaseCollider(col);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < pMultiBody->getNumLinks(); ++i)
|
||||
{
|
||||
const int parent = pMultiBody->getParent(i);
|
||||
world_to_local[i + 1] = pMultiBody->getParentToLocalRot(i) * world_to_local[parent + 1];
|
||||
local_origin[i + 1] = local_origin[parent + 1] + (quatRotate(world_to_local[i + 1].inverse(), pMultiBody->getRVector(i)));
|
||||
}
|
||||
|
||||
for (int i = 0; i < pMultiBody->getNumLinks(); ++i)
|
||||
{
|
||||
btVector3 posr = local_origin[i + 1];
|
||||
|
||||
btScalar quat[4] = {-world_to_local[i + 1].x(), -world_to_local[i + 1].y(), -world_to_local[i + 1].z(), world_to_local[i + 1].w()};
|
||||
|
||||
btCollisionShape* box = new btBoxShape(linkHalfExtents);
|
||||
box->setMargin(0.001);
|
||||
btMultiBodyLinkCollider* col = new btMultiBodyLinkCollider(pMultiBody, i);
|
||||
|
||||
col->setCollisionShape(box);
|
||||
btTransform tr;
|
||||
tr.setIdentity();
|
||||
tr.setOrigin(posr);
|
||||
tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3]));
|
||||
col->setWorldTransform(tr);
|
||||
col->setFriction(friction);
|
||||
pWorld->addCollisionObject(col, 2, 1 + 2);
|
||||
|
||||
pMultiBody->getLink(i).m_collider = col;
|
||||
}
|
||||
}
|
||||
|
||||
class CommonExampleInterface* GraspDeformableCreateFunc(struct CommonExampleOptions& options)
|
||||
{
|
||||
return new GraspDeformable(options.m_guiHelper);
|
||||
}
|
||||
|
||||
|
||||
19
Engine/lib/bullet/examples/DeformableDemo/GraspDeformable.h
Normal file
19
Engine/lib/bullet/examples/DeformableDemo/GraspDeformable.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 Google Inc. http://bulletphysics.org
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef _GRASP_DEFORMABLE_H
|
||||
#define _GRASP_DEFORMABLE_H
|
||||
|
||||
class CommonExampleInterface* GraspDeformableCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
#endif //_GRASP_DEFORMABLE_H
|
||||
262
Engine/lib/bullet/examples/DeformableDemo/LargeDeformation.cpp
Normal file
262
Engine/lib/bullet/examples/DeformableDemo/LargeDeformation.cpp
Normal file
|
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 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 "LargeDeformation.h"
|
||||
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
|
||||
#include "BulletSoftBody/btSoftBody.h"
|
||||
#include "BulletSoftBody/btSoftBodyHelpers.h"
|
||||
#include "BulletSoftBody/btDeformableBodySolver.h"
|
||||
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
|
||||
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
|
||||
#include "../CommonInterfaces/CommonParameterInterface.h"
|
||||
#include <stdio.h> //printf debugging
|
||||
|
||||
#include "../CommonInterfaces/CommonDeformableBodyBase.h"
|
||||
#include "../Utils/b3ResourcePath.h"
|
||||
|
||||
///The LargeDeformation shows the contact between volumetric deformable objects and rigid objects.
|
||||
static btScalar E = 50;
|
||||
static btScalar nu = 0.3;
|
||||
static btScalar damping_alpha = 0.1;
|
||||
static btScalar damping_beta = 0.01;
|
||||
|
||||
struct TetraCube
|
||||
{
|
||||
#include "../SoftDemo/cube.inl"
|
||||
};
|
||||
|
||||
class LargeDeformation : public CommonDeformableBodyBase
|
||||
{
|
||||
btDeformableLinearElasticityForce* m_linearElasticity;
|
||||
|
||||
public:
|
||||
LargeDeformation(struct GUIHelperInterface* helper)
|
||||
: CommonDeformableBodyBase(helper)
|
||||
{
|
||||
m_linearElasticity = 0;
|
||||
}
|
||||
virtual ~LargeDeformation()
|
||||
{
|
||||
}
|
||||
void initPhysics();
|
||||
|
||||
void exitPhysics();
|
||||
|
||||
void resetCamera()
|
||||
{
|
||||
float dist = 20;
|
||||
float pitch = -45;
|
||||
float yaw = 100;
|
||||
float targetPos[3] = {0, 3, 0};
|
||||
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
|
||||
}
|
||||
|
||||
void stepSimulation(float deltaTime)
|
||||
{
|
||||
m_linearElasticity->setPoissonRatio(nu);
|
||||
m_linearElasticity->setYoungsModulus(E);
|
||||
m_linearElasticity->setDamping(damping_alpha, damping_beta);
|
||||
float internalTimeStep = 1. / 60.f;
|
||||
m_dynamicsWorld->stepSimulation(deltaTime, 1, internalTimeStep);
|
||||
}
|
||||
|
||||
virtual void renderScene()
|
||||
{
|
||||
CommonDeformableBodyBase::renderScene();
|
||||
btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
|
||||
|
||||
for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
|
||||
{
|
||||
btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i];
|
||||
{
|
||||
btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer());
|
||||
btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), deformableWorld->getDrawFlags());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void LargeDeformation::initPhysics()
|
||||
{
|
||||
m_guiHelper->setUpAxis(1);
|
||||
|
||||
///collision configuration contains default setup for memory, collision setup
|
||||
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
|
||||
|
||||
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
|
||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
||||
|
||||
m_broadphase = new btDbvtBroadphase();
|
||||
btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
|
||||
|
||||
btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
|
||||
sol->setDeformableSolver(deformableBodySolver);
|
||||
m_solver = sol;
|
||||
|
||||
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
|
||||
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
|
||||
|
||||
// create volumetric soft body
|
||||
{
|
||||
btSoftBody* psb = btSoftBodyHelpers::CreateFromTetGenData(getDeformableDynamicsWorld()->getWorldInfo(),
|
||||
TetraCube::getElements(),
|
||||
0,
|
||||
TetraCube::getNodes(),
|
||||
false, true, true);
|
||||
getDeformableDynamicsWorld()->addSoftBody(psb);
|
||||
psb->scale(btVector3(2, 2, 2));
|
||||
psb->translate(btVector3(0, 5, 0));
|
||||
psb->getCollisionShape()->setMargin(0.1);
|
||||
psb->setTotalMass(0.5);
|
||||
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
|
||||
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
|
||||
psb->m_cfg.kDF = 0.5;
|
||||
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
|
||||
psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDN;
|
||||
psb->m_sleepingThreshold = 0;
|
||||
btSoftBodyHelpers::generateBoundaryFaces(psb);
|
||||
for (int i = 0; i < psb->m_nodes.size(); ++i)
|
||||
{
|
||||
for (int j = 0; j < 3; ++j)
|
||||
psb->m_nodes[i].m_x[j] = ((double) 2*rand() / (RAND_MAX))-1.0;
|
||||
psb->m_nodes[i].m_x[1]+=8;
|
||||
}
|
||||
|
||||
btDeformableLinearElasticityForce* linearElasticity = new btDeformableLinearElasticityForce(100,100,0.01);
|
||||
m_linearElasticity = linearElasticity;
|
||||
getDeformableDynamicsWorld()->addForce(psb, linearElasticity);
|
||||
m_forces.push_back(linearElasticity);
|
||||
}
|
||||
getDeformableDynamicsWorld()->setImplicit(true);
|
||||
getDeformableDynamicsWorld()->setLineSearch(false);
|
||||
getDeformableDynamicsWorld()->setUseProjection(true);
|
||||
getDeformableDynamicsWorld()->getSolverInfo().m_deformable_erp = 0.1;
|
||||
getDeformableDynamicsWorld()->getSolverInfo().m_deformable_maxErrorReduction = btScalar(20);
|
||||
getDeformableDynamicsWorld()->getSolverInfo().m_leastSquaresResidualThreshold = 1e-3;
|
||||
getDeformableDynamicsWorld()->getSolverInfo().m_splitImpulse = true;
|
||||
getDeformableDynamicsWorld()->getSolverInfo().m_numIterations = 100;
|
||||
// add a few rigid bodies
|
||||
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
|
||||
|
||||
{
|
||||
SliderParams slider("Young's Modulus", &E);
|
||||
slider.m_minVal = 0;
|
||||
slider.m_maxVal = 2000;
|
||||
if (m_guiHelper->getParameterInterface())
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
}
|
||||
{
|
||||
SliderParams slider("Poisson Ratio", &nu);
|
||||
slider.m_minVal = 0.05;
|
||||
slider.m_maxVal = 0.49;
|
||||
if (m_guiHelper->getParameterInterface())
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
}
|
||||
{
|
||||
SliderParams slider("Mass Damping", &damping_alpha);
|
||||
slider.m_minVal = 0;
|
||||
slider.m_maxVal = 1;
|
||||
if (m_guiHelper->getParameterInterface())
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
}
|
||||
{
|
||||
SliderParams slider("Stiffness Damping", &damping_beta);
|
||||
slider.m_minVal = 0;
|
||||
slider.m_maxVal = 0.1;
|
||||
if (m_guiHelper->getParameterInterface())
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
}
|
||||
// {
|
||||
// SliderParams slider("Young's Modulus", &E);
|
||||
// slider.m_minVal = 0;
|
||||
// slider.m_maxVal = 200;
|
||||
// if (m_guiHelper->getParameterInterface())
|
||||
// m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
// }
|
||||
// {
|
||||
// SliderParams slider("Poisson Ratio", &nu);
|
||||
// slider.m_minVal = 0.05;
|
||||
// slider.m_maxVal = 0.40;
|
||||
// if (m_guiHelper->getParameterInterface())
|
||||
// m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
// }
|
||||
// {
|
||||
// SliderParams slider("Mass Damping", &damping_alpha);
|
||||
// slider.m_minVal = 0.001;
|
||||
// slider.m_maxVal = 0.01;
|
||||
// if (m_guiHelper->getParameterInterface())
|
||||
// m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
// }
|
||||
// {
|
||||
// SliderParams slider("Stiffness Damping", &damping_beta);
|
||||
// slider.m_minVal = 0.001;
|
||||
// slider.m_maxVal = 0.01;
|
||||
// if (m_guiHelper->getParameterInterface())
|
||||
// m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
// }
|
||||
}
|
||||
|
||||
void LargeDeformation::exitPhysics()
|
||||
{
|
||||
//cleanup in the reverse order of creation/initialization
|
||||
removePickingConstraint();
|
||||
//remove the rigidbodies from the dynamics world and delete them
|
||||
int i;
|
||||
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
|
||||
{
|
||||
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
|
||||
btRigidBody* body = btRigidBody::upcast(obj);
|
||||
if (body && body->getMotionState())
|
||||
{
|
||||
delete body->getMotionState();
|
||||
}
|
||||
m_dynamicsWorld->removeCollisionObject(obj);
|
||||
delete obj;
|
||||
}
|
||||
// delete forces
|
||||
for (int j = 0; j < m_forces.size(); j++)
|
||||
{
|
||||
btDeformableLagrangianForce* force = m_forces[j];
|
||||
delete force;
|
||||
}
|
||||
m_forces.clear();
|
||||
|
||||
//delete collision shapes
|
||||
for (int j = 0; j < m_collisionShapes.size(); j++)
|
||||
{
|
||||
btCollisionShape* shape = m_collisionShapes[j];
|
||||
delete shape;
|
||||
}
|
||||
m_collisionShapes.clear();
|
||||
|
||||
delete m_dynamicsWorld;
|
||||
|
||||
delete m_solver;
|
||||
|
||||
delete m_broadphase;
|
||||
|
||||
delete m_dispatcher;
|
||||
|
||||
delete m_collisionConfiguration;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class CommonExampleInterface* LargeDeformationCreateFunc(struct CommonExampleOptions& options)
|
||||
{
|
||||
return new LargeDeformation(options.m_guiHelper);
|
||||
}
|
||||
|
||||
|
||||
19
Engine/lib/bullet/examples/DeformableDemo/LargeDeformation.h
Normal file
19
Engine/lib/bullet/examples/DeformableDemo/LargeDeformation.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 Google Inc. http://bulletphysics.org
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef _LARGE_DEFORMATION_H
|
||||
#define _LARGE_DEFORMATION_H
|
||||
|
||||
class CommonExampleInterface* LargeDeformationCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
#endif //_LARGE_DEFORMATION_H
|
||||
405
Engine/lib/bullet/examples/DeformableDemo/LoadDeformed.cpp
Normal file
405
Engine/lib/bullet/examples/DeformableDemo/LoadDeformed.cpp
Normal file
|
|
@ -0,0 +1,405 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 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 "LoadDeformed.h"
|
||||
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
|
||||
#include "BulletSoftBody/btSoftBody.h"
|
||||
#include "BulletSoftBody/btSoftBodyHelpers.h"
|
||||
#include "BulletSoftBody/btDeformableBodySolver.h"
|
||||
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
|
||||
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
|
||||
#include "../CommonInterfaces/CommonParameterInterface.h"
|
||||
#include <stdio.h> //printf debugging
|
||||
|
||||
#include "../CommonInterfaces/CommonDeformableBodyBase.h"
|
||||
#include "../Utils/b3ResourcePath.h"
|
||||
#include "../Utils/b3BulletDefaultFileIO.h"
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <string.h>
|
||||
|
||||
struct CustomSoftBodyHelper : public btSoftBodyHelpers
|
||||
{
|
||||
static std::string loadDeformableState(btAlignedObjectArray<btVector3>& qs, btAlignedObjectArray<btVector3>& vs, const char* filename, CommonFileIOInterface* fileIO);
|
||||
|
||||
};
|
||||
|
||||
static inline bool isSpace(const char c)
|
||||
{
|
||||
return (c == ' ') || (c == '\t');
|
||||
}
|
||||
static inline bool isNewLine(const char c)
|
||||
{
|
||||
return (c == '\r') || (c == '\n') || (c == '\0');
|
||||
}
|
||||
static inline float parseFloat(const char*& token)
|
||||
{
|
||||
token += strspn(token, " \t");
|
||||
float f = (float)atof(token);
|
||||
token += strcspn(token, " \t\r");
|
||||
return f;
|
||||
}
|
||||
static inline void parseFloat3(
|
||||
float& x, float& y, float& z,
|
||||
const char*& token)
|
||||
{
|
||||
x = parseFloat(token);
|
||||
y = parseFloat(token);
|
||||
z = parseFloat(token);
|
||||
}
|
||||
|
||||
|
||||
std::string CustomSoftBodyHelper::loadDeformableState(btAlignedObjectArray<btVector3>& qs, btAlignedObjectArray<btVector3>& vs, const char* filename, CommonFileIOInterface* fileIO)
|
||||
{
|
||||
{
|
||||
qs.clear();
|
||||
vs.clear();
|
||||
std::string tmp = filename;
|
||||
std::stringstream err;
|
||||
#ifdef USE_STREAM
|
||||
std::ifstream ifs(filename);
|
||||
if (!ifs)
|
||||
{
|
||||
err << "Cannot open file [" << filename << "]" << std::endl;
|
||||
return err.str();
|
||||
}
|
||||
#else
|
||||
int fileHandle = fileIO->fileOpen(filename, "r");
|
||||
if (fileHandle < 0)
|
||||
{
|
||||
err << "Cannot open file [" << filename << "]" << std::endl;
|
||||
return err.str();
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string name;
|
||||
|
||||
int maxchars = 8192; // Alloc enough size.
|
||||
std::vector<char> buf(maxchars); // Alloc enough size.
|
||||
std::string linebuf;
|
||||
linebuf.reserve(maxchars);
|
||||
|
||||
#ifdef USE_STREAM
|
||||
while (ifs.peek() != -1)
|
||||
#else
|
||||
char* line = 0;
|
||||
do
|
||||
#endif
|
||||
{
|
||||
linebuf.resize(0);
|
||||
#ifdef USE_STREAM
|
||||
safeGetline(ifs, linebuf);
|
||||
#else
|
||||
char tmpBuf[1024];
|
||||
line = fileIO->readLine(fileHandle, tmpBuf, 1024);
|
||||
if (line)
|
||||
{
|
||||
linebuf = line;
|
||||
}
|
||||
#endif
|
||||
// Trim newline '\r\n' or '\r'
|
||||
if (linebuf.size() > 0)
|
||||
{
|
||||
if (linebuf[linebuf.size() - 1] == '\n') linebuf.erase(linebuf.size() - 1);
|
||||
}
|
||||
if (linebuf.size() > 0)
|
||||
{
|
||||
if (linebuf[linebuf.size() - 1] == '\n') linebuf.erase(linebuf.size() - 1);
|
||||
}
|
||||
|
||||
// Skip if empty line.
|
||||
if (linebuf.empty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip leading space.
|
||||
const char* token = linebuf.c_str();
|
||||
token += strspn(token, " \t");
|
||||
|
||||
btAssert(token);
|
||||
if (token[0] == '\0') continue; // empty line
|
||||
|
||||
if (token[0] == '#') continue; // comment line
|
||||
|
||||
// q
|
||||
if (token[0] == 'q' && isSpace((token[1])))
|
||||
{
|
||||
token += 2;
|
||||
float x, y, z;
|
||||
parseFloat3(x, y, z, token);
|
||||
qs.push_back(btVector3(x, y, z));
|
||||
continue;
|
||||
}
|
||||
|
||||
// v
|
||||
if (token[0] == 'v' && isSpace((token[1])))
|
||||
{
|
||||
token += 3;
|
||||
float x, y, z;
|
||||
parseFloat3(x, y, z, token);
|
||||
vs.push_back(btVector3(x, y, z));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore unknown command.
|
||||
}
|
||||
#ifndef USE_STREAM
|
||||
while (line)
|
||||
;
|
||||
#endif
|
||||
|
||||
if (fileHandle >= 0)
|
||||
{
|
||||
fileIO->fileClose(fileHandle);
|
||||
}
|
||||
return err.str();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class LoadDeformed : public CommonDeformableBodyBase
|
||||
{
|
||||
int steps;
|
||||
btSoftBody* psb;
|
||||
char filename;
|
||||
int reset_frame;
|
||||
float sim_time;
|
||||
|
||||
public:
|
||||
LoadDeformed(struct GUIHelperInterface* helper)
|
||||
: CommonDeformableBodyBase(helper)
|
||||
{
|
||||
steps = 0;
|
||||
psb = nullptr;
|
||||
reset_frame = 0;
|
||||
sim_time = 0;
|
||||
}
|
||||
virtual ~LoadDeformed()
|
||||
{
|
||||
}
|
||||
void initPhysics();
|
||||
|
||||
void exitPhysics();
|
||||
|
||||
void resetCamera()
|
||||
{
|
||||
float dist = 2;
|
||||
float pitch = -45;
|
||||
float yaw = 100;
|
||||
float targetPos[3] = {0, 0, 0};
|
||||
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
|
||||
}
|
||||
|
||||
void stepSimulation(float deltaTime)
|
||||
{
|
||||
steps++;
|
||||
sim_time += deltaTime;
|
||||
//// int seconds = 1/deltaTime;
|
||||
if (0)
|
||||
{
|
||||
// if (reset_frame==0 && steps<100){
|
||||
//// printf("steps %d, seconds %d, steps/seconds %d\n", steps,seconds,steps/seconds);
|
||||
char filename[100];
|
||||
sprintf(filename, "%s_%d_%d.txt", "states", reset_frame, steps);
|
||||
btSoftBodyHelpers::writeState(filename, psb);
|
||||
}
|
||||
if (sim_time + reset_frame * 0.05 >= 5) exit(0);
|
||||
float internalTimeStep = 1. / 240.f;
|
||||
// float internalTimeStep = 0.1f;
|
||||
m_dynamicsWorld->stepSimulation(deltaTime, deltaTime / internalTimeStep, internalTimeStep);
|
||||
}
|
||||
|
||||
void addCloth(const btVector3& origin);
|
||||
|
||||
virtual void renderScene()
|
||||
{
|
||||
CommonDeformableBodyBase::renderScene();
|
||||
btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
|
||||
|
||||
for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
|
||||
{
|
||||
btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i];
|
||||
{
|
||||
btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer());
|
||||
btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), deformableWorld->getDrawFlags());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void LoadDeformed::initPhysics()
|
||||
{
|
||||
m_guiHelper->setUpAxis(1);
|
||||
|
||||
///collision configuration contains default setup for memory, collision setup
|
||||
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
|
||||
|
||||
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
|
||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
||||
|
||||
m_broadphase = new btDbvtBroadphase();
|
||||
btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
|
||||
|
||||
btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
|
||||
sol->setDeformableSolver(deformableBodySolver);
|
||||
m_solver = sol;
|
||||
|
||||
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
|
||||
btVector3 gravity = btVector3(0, -9.8, 0);
|
||||
m_dynamicsWorld->setGravity(gravity);
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.setDefaultVoxelsz(0.25);
|
||||
|
||||
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
|
||||
|
||||
{
|
||||
///create a ground
|
||||
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(2.5), btScalar(150.)));
|
||||
groundShape->setMargin(0.02);
|
||||
m_collisionShapes.push_back(groundShape);
|
||||
|
||||
btTransform groundTransform;
|
||||
groundTransform.setIdentity();
|
||||
groundTransform.setOrigin(btVector3(0, -3.5, 0));
|
||||
groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0));
|
||||
btScalar mass(0.);
|
||||
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
bool isDynamic = (mass != 0.f);
|
||||
|
||||
btVector3 localInertia(0, 0, 0);
|
||||
if (isDynamic)
|
||||
groundShape->calculateLocalInertia(mass, localInertia);
|
||||
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
|
||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
|
||||
btRigidBody* body = new btRigidBody(rbInfo);
|
||||
body->setFriction(4);
|
||||
|
||||
//add the ground to the dynamics world
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
}
|
||||
addCloth(btVector3(0, 1, 0));
|
||||
getDeformableDynamicsWorld()->setImplicit(false);
|
||||
getDeformableDynamicsWorld()->setLineSearch(false);
|
||||
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
|
||||
}
|
||||
|
||||
void LoadDeformed::addCloth(const btVector3& origin)
|
||||
// create a piece of cloth
|
||||
{
|
||||
const btScalar s = 0.6;
|
||||
const btScalar h = 0;
|
||||
|
||||
psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, h, -2 * s),
|
||||
btVector3(+s, h, -2 * s),
|
||||
btVector3(-s, h, +2 * s),
|
||||
btVector3(+s, h, +2 * s),
|
||||
15, 30,
|
||||
0, true, 0.0);
|
||||
|
||||
psb->getCollisionShape()->setMargin(0.02);
|
||||
psb->generateBendingConstraints(2);
|
||||
psb->setTotalMass(.5);
|
||||
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
|
||||
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
|
||||
psb->m_cfg.kDF = 0.1;
|
||||
psb->rotate(btQuaternion(0, SIMD_PI / 2, 0));
|
||||
btTransform clothTransform;
|
||||
clothTransform.setIdentity();
|
||||
clothTransform.setOrigin(btVector3(0, 0.2, 0) + origin);
|
||||
psb->transform(clothTransform);
|
||||
|
||||
b3BulletDefaultFileIO fileio;
|
||||
char absolute_path[1024];
|
||||
char filename[100];
|
||||
sprintf(filename, "/Users/fuchuyuan/Documents/mybullet/build_cmake/examples/ExampleBrowser/states_0_%d.txt", reset_frame);
|
||||
fileio.findResourcePath(filename, absolute_path, 1024);
|
||||
btAlignedObjectArray<btVector3> qs;
|
||||
btAlignedObjectArray<btVector3> vs;
|
||||
CustomSoftBodyHelper::loadDeformableState(qs, vs, absolute_path, &fileio);
|
||||
if (reset_frame > 0)
|
||||
psb->updateState(qs, vs);
|
||||
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
|
||||
psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_MDF;
|
||||
psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDF;
|
||||
// psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDN;
|
||||
psb->setCollisionFlags(0);
|
||||
psb->setCacheBarycenter(true);
|
||||
getDeformableDynamicsWorld()->addSoftBody(psb);
|
||||
psb->setSelfCollision(false);
|
||||
|
||||
btDeformableMassSpringForce* mass_spring = new btDeformableMassSpringForce(2, 0.2, true);
|
||||
psb->setSpringStiffness(4);
|
||||
getDeformableDynamicsWorld()->addForce(psb, mass_spring);
|
||||
m_forces.push_back(mass_spring);
|
||||
btVector3 gravity = btVector3(0, -9.8, 0);
|
||||
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
|
||||
getDeformableDynamicsWorld()->addForce(psb, gravity_force);
|
||||
// getDeformableDynamicsWorld()->setUseProjection(true);
|
||||
m_forces.push_back(gravity_force);
|
||||
}
|
||||
|
||||
void LoadDeformed::exitPhysics()
|
||||
{
|
||||
//cleanup in the reverse order of creation/initialization
|
||||
removePickingConstraint();
|
||||
//remove the rigidbodies from the dynamics world and delete them
|
||||
int i;
|
||||
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
|
||||
{
|
||||
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
|
||||
btRigidBody* body = btRigidBody::upcast(obj);
|
||||
if (body && body->getMotionState())
|
||||
{
|
||||
delete body->getMotionState();
|
||||
}
|
||||
m_dynamicsWorld->removeCollisionObject(obj);
|
||||
delete obj;
|
||||
}
|
||||
// delete forces
|
||||
for (int j = 0; j < m_forces.size(); j++)
|
||||
{
|
||||
btDeformableLagrangianForce* force = m_forces[j];
|
||||
delete force;
|
||||
}
|
||||
m_forces.clear();
|
||||
|
||||
//delete collision shapes
|
||||
for (int j = 0; j < m_collisionShapes.size(); j++)
|
||||
{
|
||||
btCollisionShape* shape = m_collisionShapes[j];
|
||||
delete shape;
|
||||
}
|
||||
m_collisionShapes.clear();
|
||||
|
||||
delete m_dynamicsWorld;
|
||||
|
||||
delete m_solver;
|
||||
|
||||
delete m_broadphase;
|
||||
|
||||
delete m_dispatcher;
|
||||
|
||||
delete m_collisionConfiguration;
|
||||
}
|
||||
|
||||
class CommonExampleInterface* LoadDeformedCreateFunc(struct CommonExampleOptions& options)
|
||||
{
|
||||
return new LoadDeformed(options.m_guiHelper);
|
||||
}
|
||||
19
Engine/lib/bullet/examples/DeformableDemo/LoadDeformed.h
Normal file
19
Engine/lib/bullet/examples/DeformableDemo/LoadDeformed.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 Google Inc. http://bulletphysics.org
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef _LOAD_DEFORMED_H
|
||||
#define _LOAD_DEFORMED_H
|
||||
|
||||
class CommonExampleInterface* LoadDeformedCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
#endif //_LOAD_DEFORMED_H
|
||||
|
|
@ -0,0 +1,381 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 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 "MultibodyClothAnchor.h"
|
||||
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
|
||||
#include "BulletSoftBody/btSoftBody.h"
|
||||
#include "BulletSoftBody/btSoftBodyHelpers.h"
|
||||
#include "BulletSoftBody/btDeformableBodySolver.h"
|
||||
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
|
||||
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
|
||||
#include <stdio.h> //printf debugging
|
||||
|
||||
#include "../CommonInterfaces/CommonDeformableBodyBase.h"
|
||||
#include "../Utils/b3ResourcePath.h"
|
||||
|
||||
///The MultibodyClothAnchor shows contact between deformable objects and rigid objects.
|
||||
class MultibodyClothAnchor : public CommonDeformableBodyBase
|
||||
{
|
||||
public:
|
||||
MultibodyClothAnchor(struct GUIHelperInterface* helper)
|
||||
: CommonDeformableBodyBase(helper)
|
||||
{
|
||||
}
|
||||
virtual ~MultibodyClothAnchor()
|
||||
{
|
||||
}
|
||||
void initPhysics();
|
||||
|
||||
void exitPhysics();
|
||||
|
||||
void resetCamera()
|
||||
{
|
||||
float dist = 20;
|
||||
float pitch = -45;
|
||||
float yaw = 100;
|
||||
float targetPos[3] = {0, -3, 0};
|
||||
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
|
||||
}
|
||||
|
||||
void stepSimulation(float deltaTime)
|
||||
{
|
||||
//use a smaller internal timestep, there are stability issues
|
||||
float internalTimeStep = 1. / 240.f;
|
||||
m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep);
|
||||
}
|
||||
|
||||
virtual void renderScene()
|
||||
{
|
||||
CommonDeformableBodyBase::renderScene();
|
||||
btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
|
||||
|
||||
for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
|
||||
{
|
||||
btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i];
|
||||
//if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe)))
|
||||
{
|
||||
btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer());
|
||||
btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), fDrawFlags::Faces);// deformableWorld->getDrawFlags());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
btMultiBody* createMultiBody(class btMultiBodyDynamicsWorld* world, int numLinks, const btVector3& basePosition, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents, bool spherical = false, bool floating = false);
|
||||
|
||||
void addColliders(btMultiBody* pMultiBody, btMultiBodyDynamicsWorld* pWorld, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents);
|
||||
};
|
||||
|
||||
void MultibodyClothAnchor::initPhysics()
|
||||
{
|
||||
m_guiHelper->setUpAxis(1);
|
||||
|
||||
///collision configuration contains default setup for memory, collision setup
|
||||
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
|
||||
|
||||
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
|
||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
||||
|
||||
m_broadphase = new btDbvtBroadphase();
|
||||
btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
|
||||
|
||||
///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
|
||||
btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
|
||||
sol->setDeformableSolver(deformableBodySolver);
|
||||
m_solver = sol;
|
||||
|
||||
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
|
||||
// deformableBodySolver->setWorld(getDeformableDynamicsWorld());
|
||||
// m_dynamicsWorld->getSolverInfo().m_singleAxisDeformableThreshold = 0.f;//faster but lower quality
|
||||
btVector3 gravity = btVector3(0, -20, 0);
|
||||
m_dynamicsWorld->setGravity(gravity);
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
|
||||
|
||||
// getDeformableDynamicsWorld()->before_solver_callbacks.push_back(dynamics);
|
||||
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
|
||||
|
||||
{
|
||||
///create a ground
|
||||
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(25.), btScalar(150.)));
|
||||
|
||||
m_collisionShapes.push_back(groundShape);
|
||||
|
||||
btTransform groundTransform;
|
||||
groundTransform.setIdentity();
|
||||
groundTransform.setOrigin(btVector3(0, -35, 0));
|
||||
groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.));
|
||||
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
|
||||
btScalar mass(0.);
|
||||
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
bool isDynamic = (mass != 0.f);
|
||||
|
||||
btVector3 localInertia(0, 0, 0);
|
||||
if (isDynamic)
|
||||
groundShape->calculateLocalInertia(mass, localInertia);
|
||||
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
|
||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
|
||||
btRigidBody* body = new btRigidBody(rbInfo);
|
||||
body->setFriction(1);
|
||||
|
||||
//add the ground to the dynamics world
|
||||
m_dynamicsWorld->addRigidBody(body,1,1+2);
|
||||
}
|
||||
|
||||
// create a piece of cloth
|
||||
{
|
||||
const btScalar s = 4;
|
||||
const btScalar h = 6;
|
||||
const int r = 9;
|
||||
btSoftBody* psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, h, -s),
|
||||
btVector3(+s, h, -s),
|
||||
btVector3(-s, h, +s),
|
||||
btVector3(+s, h, +s), r, r, 4 + 8, true);
|
||||
psb->getCollisionShape()->setMargin(0.01);
|
||||
psb->generateBendingConstraints(2);
|
||||
psb->setTotalMass(1);
|
||||
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
|
||||
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
|
||||
psb->m_cfg.kDF = 2;
|
||||
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
|
||||
psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDF;
|
||||
getDeformableDynamicsWorld()->addSoftBody(psb);
|
||||
|
||||
btDeformableMassSpringForce* mass_spring = new btDeformableMassSpringForce(30,1, true);
|
||||
getDeformableDynamicsWorld()->addForce(psb, mass_spring);
|
||||
m_forces.push_back(mass_spring);
|
||||
|
||||
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
|
||||
getDeformableDynamicsWorld()->addForce(psb, gravity_force);
|
||||
m_forces.push_back(gravity_force);
|
||||
|
||||
bool damping = true;
|
||||
bool gyro = false;
|
||||
int numLinks = 5;
|
||||
bool spherical = false; //set it ot false -to use 1DoF hinges instead of 3DoF sphericals
|
||||
bool canSleep = false;
|
||||
bool selfCollide = true;
|
||||
btVector3 linkHalfExtents(1.5, .5, .5);
|
||||
btVector3 baseHalfExtents(1.5, .5, .5);
|
||||
|
||||
btMultiBody* mbC = createMultiBody(getDeformableDynamicsWorld(), numLinks, btVector3(s+3.5f, h, -s-0.6f), linkHalfExtents, baseHalfExtents, spherical, true);
|
||||
|
||||
mbC->setCanSleep(canSleep);
|
||||
mbC->setHasSelfCollision(selfCollide);
|
||||
mbC->setUseGyroTerm(gyro);
|
||||
//
|
||||
if (!damping)
|
||||
{
|
||||
mbC->setLinearDamping(0.0f);
|
||||
mbC->setAngularDamping(0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
mbC->setLinearDamping(0.04f);
|
||||
mbC->setAngularDamping(0.04f);
|
||||
}
|
||||
|
||||
if (numLinks > 0)
|
||||
{
|
||||
btScalar q0 = 0.f * SIMD_PI / 180.f;
|
||||
if (!spherical)
|
||||
{
|
||||
mbC->setJointPosMultiDof(0, &q0);
|
||||
}
|
||||
else
|
||||
{
|
||||
btQuaternion quat0(btVector3(1, 1, 0).normalized(), q0);
|
||||
quat0.normalize();
|
||||
mbC->setJointPosMultiDof(0, quat0);
|
||||
}
|
||||
}
|
||||
///
|
||||
addColliders(mbC, getDeformableDynamicsWorld(), baseHalfExtents, linkHalfExtents);
|
||||
|
||||
// quick hack: advance time to populate the variables in multibody
|
||||
m_dynamicsWorld->stepSimulation(SIMD_EPSILON, 0);
|
||||
btAlignedObjectArray<btQuaternion> scratch_q;
|
||||
btAlignedObjectArray<btVector3> scratch_m;
|
||||
mbC->forwardKinematics(scratch_q, scratch_m);
|
||||
psb->appendDeformableAnchor(0, mbC->getLink(3).m_collider);
|
||||
psb->appendDeformableAnchor(r - 1, mbC->getLink(0).m_collider);
|
||||
}
|
||||
getDeformableDynamicsWorld()->setImplicit(false);
|
||||
getDeformableDynamicsWorld()->setLineSearch(false);
|
||||
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
|
||||
}
|
||||
|
||||
void MultibodyClothAnchor::exitPhysics()
|
||||
{
|
||||
//cleanup in the reverse order of creation/initialization
|
||||
removePickingConstraint();
|
||||
//remove the rigidbodies from the dynamics world and delete them
|
||||
int i;
|
||||
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
|
||||
{
|
||||
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
|
||||
btRigidBody* body = btRigidBody::upcast(obj);
|
||||
if (body && body->getMotionState())
|
||||
{
|
||||
delete body->getMotionState();
|
||||
}
|
||||
m_dynamicsWorld->removeCollisionObject(obj);
|
||||
delete obj;
|
||||
}
|
||||
// delete forces
|
||||
for (int j = 0; j < m_forces.size(); j++)
|
||||
{
|
||||
btDeformableLagrangianForce* force = m_forces[j];
|
||||
delete force;
|
||||
}
|
||||
m_forces.clear();
|
||||
//delete collision shapes
|
||||
for (int j = 0; j < m_collisionShapes.size(); j++)
|
||||
{
|
||||
btCollisionShape* shape = m_collisionShapes[j];
|
||||
delete shape;
|
||||
}
|
||||
m_collisionShapes.clear();
|
||||
|
||||
delete m_dynamicsWorld;
|
||||
|
||||
delete m_solver;
|
||||
|
||||
delete m_broadphase;
|
||||
|
||||
delete m_dispatcher;
|
||||
|
||||
delete m_collisionConfiguration;
|
||||
}
|
||||
|
||||
btMultiBody* MultibodyClothAnchor::createMultiBody(btMultiBodyDynamicsWorld* pWorld, int numLinks, const btVector3& basePosition, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents, bool spherical, bool floating)
|
||||
{
|
||||
//init the base
|
||||
btVector3 baseInertiaDiag(0.f, 0.f, 0.f);
|
||||
float baseMass = 1.f;
|
||||
|
||||
if (baseMass)
|
||||
{
|
||||
btCollisionShape* pTempBox = new btBoxShape(btVector3(baseHalfExtents[0], baseHalfExtents[1], baseHalfExtents[2]));
|
||||
pTempBox->calculateLocalInertia(baseMass, baseInertiaDiag);
|
||||
delete pTempBox;
|
||||
}
|
||||
|
||||
bool canSleep = false;
|
||||
|
||||
btMultiBody* pMultiBody = new btMultiBody(numLinks, baseMass, baseInertiaDiag, !floating, canSleep);
|
||||
|
||||
btQuaternion baseOriQuat(0.f, 0.f, 0.f, 1.f);
|
||||
pMultiBody->setBasePos(basePosition);
|
||||
pMultiBody->setWorldToBaseRot(baseOriQuat);
|
||||
btVector3 vel(0, 0, 0);
|
||||
|
||||
//init the links
|
||||
btVector3 hingeJointAxis(0, 1, 0);
|
||||
float linkMass = 1.f;
|
||||
btVector3 linkInertiaDiag(0.f, 0.f, 0.f);
|
||||
|
||||
btCollisionShape* pTempBox = new btBoxShape(btVector3(linkHalfExtents[0], linkHalfExtents[1], linkHalfExtents[2]));
|
||||
pTempBox->calculateLocalInertia(linkMass, linkInertiaDiag);
|
||||
delete pTempBox;
|
||||
|
||||
//y-axis assumed up
|
||||
btVector3 parentComToCurrentCom(-linkHalfExtents[0] * 2.f, 0, 0); //par body's COM to cur body's COM offset
|
||||
btVector3 currentPivotToCurrentCom(-linkHalfExtents[0], 0, 0); //cur body's COM to cur body's PIV offset
|
||||
btVector3 parentComToCurrentPivot = parentComToCurrentCom - currentPivotToCurrentCom; //par body's COM to cur body's PIV offset
|
||||
|
||||
//////
|
||||
btScalar q0 = 0.f * SIMD_PI / 180.f;
|
||||
btQuaternion quat0(btVector3(0, 1, 0).normalized(), q0);
|
||||
quat0.normalize();
|
||||
/////
|
||||
|
||||
for (int i = 0; i < numLinks; ++i)
|
||||
{
|
||||
if (!spherical)
|
||||
pMultiBody->setupRevolute(i, linkMass, linkInertiaDiag, i - 1, btQuaternion(0.f, 0.f, 0.f, 1.f), hingeJointAxis, parentComToCurrentPivot, currentPivotToCurrentCom, true);
|
||||
else
|
||||
pMultiBody->setupSpherical(i, linkMass, linkInertiaDiag, i - 1, btQuaternion(0.f, 0.f, 0.f, 1.f), parentComToCurrentPivot, currentPivotToCurrentCom, true);
|
||||
}
|
||||
|
||||
pMultiBody->finalizeMultiDof();
|
||||
|
||||
///
|
||||
pWorld->addMultiBody(pMultiBody);
|
||||
///
|
||||
return pMultiBody;
|
||||
}
|
||||
|
||||
void MultibodyClothAnchor::addColliders(btMultiBody* pMultiBody, btMultiBodyDynamicsWorld* pWorld, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents)
|
||||
{
|
||||
btAlignedObjectArray<btQuaternion> world_to_local;
|
||||
world_to_local.resize(pMultiBody->getNumLinks() + 1);
|
||||
|
||||
btAlignedObjectArray<btVector3> local_origin;
|
||||
local_origin.resize(pMultiBody->getNumLinks() + 1);
|
||||
world_to_local[0] = pMultiBody->getWorldToBaseRot();
|
||||
local_origin[0] = pMultiBody->getBasePos();
|
||||
|
||||
{
|
||||
btScalar quat[4] = {-world_to_local[0].x(), -world_to_local[0].y(), -world_to_local[0].z(), world_to_local[0].w()};
|
||||
|
||||
btCollisionShape* box = new btBoxShape(baseHalfExtents);
|
||||
btMultiBodyLinkCollider* col = new btMultiBodyLinkCollider(pMultiBody, -1);
|
||||
col->setCollisionShape(box);
|
||||
|
||||
btTransform tr;
|
||||
tr.setIdentity();
|
||||
tr.setOrigin(local_origin[0]);
|
||||
tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3]));
|
||||
col->setWorldTransform(tr);
|
||||
pWorld->addCollisionObject(col, 2, 1+2);
|
||||
col->setFriction(1);
|
||||
pMultiBody->setBaseCollider(col);
|
||||
}
|
||||
|
||||
for (int i = 0; i < pMultiBody->getNumLinks(); ++i)
|
||||
{
|
||||
const int parent = pMultiBody->getParent(i);
|
||||
world_to_local[i + 1] = pMultiBody->getParentToLocalRot(i) * world_to_local[parent + 1];
|
||||
local_origin[i + 1] = local_origin[parent + 1] + (quatRotate(world_to_local[i + 1].inverse(), pMultiBody->getRVector(i)));
|
||||
}
|
||||
|
||||
for (int i = 0; i < pMultiBody->getNumLinks(); ++i)
|
||||
{
|
||||
btVector3 posr = local_origin[i + 1];
|
||||
|
||||
btScalar quat[4] = {-world_to_local[i + 1].x(), -world_to_local[i + 1].y(), -world_to_local[i + 1].z(), world_to_local[i + 1].w()};
|
||||
|
||||
btCollisionShape* box = new btBoxShape(linkHalfExtents);
|
||||
btMultiBodyLinkCollider* col = new btMultiBodyLinkCollider(pMultiBody, i);
|
||||
|
||||
col->setCollisionShape(box);
|
||||
btTransform tr;
|
||||
tr.setIdentity();
|
||||
tr.setOrigin(posr);
|
||||
tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3]));
|
||||
col->setWorldTransform(tr);
|
||||
col->setFriction(1);
|
||||
pWorld->addCollisionObject(col, 2, 1+2);
|
||||
pMultiBody->getLink(i).m_collider = col;
|
||||
}
|
||||
}
|
||||
|
||||
class CommonExampleInterface* MultibodyClothAnchorCreateFunc(struct CommonExampleOptions& options)
|
||||
{
|
||||
return new MultibodyClothAnchor(options.m_guiHelper);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 Google Inc. http://bulletphysics.org
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef MULTIBODY_CLOTH_ANCHOR_H
|
||||
#define MULTIBODY_CLOTH_ANCHOR_H
|
||||
|
||||
class CommonExampleInterface* MultibodyClothAnchorCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
#endif //MULTIBODY_CLOTH_ANCHOR_H
|
||||
377
Engine/lib/bullet/examples/DeformableDemo/Pinch.cpp
Normal file
377
Engine/lib/bullet/examples/DeformableDemo/Pinch.cpp
Normal file
|
|
@ -0,0 +1,377 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 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 "Pinch.h"
|
||||
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
|
||||
#include "BulletSoftBody/btSoftBody.h"
|
||||
#include "BulletSoftBody/btSoftBodyHelpers.h"
|
||||
#include "BulletSoftBody/btDeformableBodySolver.h"
|
||||
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
|
||||
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
|
||||
#include <stdio.h> //printf debugging
|
||||
|
||||
#include "../CommonInterfaces/CommonDeformableBodyBase.h"
|
||||
#include "../Utils/b3ResourcePath.h"
|
||||
|
||||
///The Pinch shows the frictional contact between kinematic rigid objects with deformable objects
|
||||
|
||||
struct TetraCube
|
||||
{
|
||||
#include "../SoftDemo/cube.inl"
|
||||
};
|
||||
|
||||
class Pinch : public CommonDeformableBodyBase
|
||||
{
|
||||
public:
|
||||
Pinch(struct GUIHelperInterface* helper)
|
||||
: CommonDeformableBodyBase(helper)
|
||||
{
|
||||
}
|
||||
virtual ~Pinch()
|
||||
{
|
||||
}
|
||||
void initPhysics();
|
||||
|
||||
void exitPhysics();
|
||||
|
||||
void resetCamera()
|
||||
{
|
||||
float dist = 25;
|
||||
float pitch = -30;
|
||||
float yaw = 100;
|
||||
float targetPos[3] = {0, -0, 0};
|
||||
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
|
||||
}
|
||||
|
||||
void stepSimulation(float deltaTime)
|
||||
{
|
||||
//use a smaller internal timestep, there are stability issues
|
||||
float internalTimeStep = 1. / 240.f;
|
||||
m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep);
|
||||
}
|
||||
|
||||
void createGrip()
|
||||
{
|
||||
int count = 2;
|
||||
float mass = 1e6;
|
||||
btCollisionShape* shape[] = {
|
||||
new btBoxShape(btVector3(3, 3, 0.5)),
|
||||
};
|
||||
static const int nshapes = sizeof(shape) / sizeof(shape[0]);
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
btTransform startTransform;
|
||||
startTransform.setIdentity();
|
||||
startTransform.setOrigin(btVector3(10, 0, 0));
|
||||
startTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.));
|
||||
createRigidBody(mass, startTransform, shape[i % nshapes]);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void renderScene()
|
||||
{
|
||||
CommonDeformableBodyBase::renderScene();
|
||||
btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
|
||||
|
||||
for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
|
||||
{
|
||||
btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i];
|
||||
{
|
||||
btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer());
|
||||
btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), deformableWorld->getDrawFlags());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void dynamics(btScalar time, btDeformableMultiBodyDynamicsWorld* world)
|
||||
{
|
||||
btAlignedObjectArray<btRigidBody*>& rbs = world->getNonStaticRigidBodies();
|
||||
if (rbs.size()<2)
|
||||
return;
|
||||
btRigidBody* rb0 = rbs[0];
|
||||
btScalar pressTime = 0.9;
|
||||
btScalar liftTime = 2.5;
|
||||
btScalar shiftTime = 3.5;
|
||||
btScalar holdTime = 4.5*1000;
|
||||
btScalar dropTime = 5.3*1000;
|
||||
btTransform rbTransform;
|
||||
rbTransform.setIdentity();
|
||||
btVector3 translation;
|
||||
btVector3 velocity;
|
||||
|
||||
btVector3 initialTranslationLeft = btVector3(0.5,3,4);
|
||||
btVector3 initialTranslationRight = btVector3(0.5,3,-4);
|
||||
btVector3 pinchVelocityLeft = btVector3(0,0,-2);
|
||||
btVector3 pinchVelocityRight = btVector3(0,0,2);
|
||||
btVector3 liftVelocity = btVector3(0,5,0);
|
||||
btVector3 shiftVelocity = btVector3(0,0,5);
|
||||
btVector3 holdVelocity = btVector3(0,0,0);
|
||||
btVector3 openVelocityLeft = btVector3(0,0,4);
|
||||
btVector3 openVelocityRight = btVector3(0,0,-4);
|
||||
|
||||
if (time < pressTime)
|
||||
{
|
||||
velocity = pinchVelocityLeft;
|
||||
translation = initialTranslationLeft + pinchVelocityLeft * time;
|
||||
}
|
||||
else if (time < liftTime)
|
||||
{
|
||||
velocity = liftVelocity;
|
||||
translation = initialTranslationLeft + pinchVelocityLeft * pressTime + liftVelocity * (time - pressTime);
|
||||
|
||||
}
|
||||
else if (time < shiftTime)
|
||||
{
|
||||
velocity = shiftVelocity;
|
||||
translation = initialTranslationLeft + pinchVelocityLeft * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (time - liftTime);
|
||||
}
|
||||
else if (time < holdTime)
|
||||
{
|
||||
velocity = btVector3(0,0,0);
|
||||
translation = initialTranslationLeft + pinchVelocityLeft * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (time - shiftTime);
|
||||
}
|
||||
else if (time < dropTime)
|
||||
{
|
||||
velocity = openVelocityLeft;
|
||||
translation = initialTranslationLeft + pinchVelocityLeft * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (holdTime - shiftTime)+ openVelocityLeft * (time - holdTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
velocity = holdVelocity;
|
||||
translation = initialTranslationLeft + pinchVelocityLeft * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (holdTime - shiftTime)+ openVelocityLeft * (dropTime - holdTime);
|
||||
}
|
||||
rbTransform.setOrigin(translation);
|
||||
rbTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0));
|
||||
rb0->setCenterOfMassTransform(rbTransform);
|
||||
rb0->setAngularVelocity(btVector3(0,0,0));
|
||||
rb0->setLinearVelocity(velocity);
|
||||
|
||||
btRigidBody* rb1 = rbs[1];
|
||||
if (time < pressTime)
|
||||
{
|
||||
velocity = pinchVelocityRight;
|
||||
translation = initialTranslationRight + pinchVelocityRight * time;
|
||||
}
|
||||
else if (time < liftTime)
|
||||
{
|
||||
velocity = liftVelocity;
|
||||
translation = initialTranslationRight + pinchVelocityRight * pressTime + liftVelocity * (time - pressTime);
|
||||
|
||||
}
|
||||
else if (time < shiftTime)
|
||||
{
|
||||
velocity = shiftVelocity;
|
||||
translation = initialTranslationRight + pinchVelocityRight * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (time - liftTime);
|
||||
}
|
||||
else if (time < holdTime)
|
||||
{
|
||||
velocity = btVector3(0,0,0);
|
||||
translation = initialTranslationRight + pinchVelocityRight * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (time - shiftTime);
|
||||
}
|
||||
else if (time < dropTime)
|
||||
{
|
||||
velocity = openVelocityRight;
|
||||
translation = initialTranslationRight + pinchVelocityRight * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (holdTime - shiftTime)+ openVelocityRight * (time - holdTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
velocity = holdVelocity;
|
||||
translation = initialTranslationRight + pinchVelocityRight * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (holdTime - shiftTime)+ openVelocityRight * (dropTime - holdTime);
|
||||
}
|
||||
rbTransform.setOrigin(translation);
|
||||
rbTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0));
|
||||
rb1->setCenterOfMassTransform(rbTransform);
|
||||
rb1->setAngularVelocity(btVector3(0,0,0));
|
||||
rb1->setLinearVelocity(velocity);
|
||||
|
||||
rb0->setFriction(20);
|
||||
rb1->setFriction(20);
|
||||
}
|
||||
|
||||
void Pinch::initPhysics()
|
||||
{
|
||||
m_guiHelper->setUpAxis(1);
|
||||
|
||||
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
|
||||
|
||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
||||
|
||||
m_broadphase = new btDbvtBroadphase();
|
||||
btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
|
||||
|
||||
btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
|
||||
sol->setDeformableSolver(deformableBodySolver);
|
||||
m_solver = sol;
|
||||
|
||||
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
|
||||
btVector3 gravity = btVector3(0, -10, 0);
|
||||
m_dynamicsWorld->setGravity(gravity);
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.setDefaultVoxelsz(0.25);
|
||||
getDeformableDynamicsWorld()->setSolverCallback(dynamics);
|
||||
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
|
||||
|
||||
//create a ground
|
||||
{
|
||||
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(25.), btScalar(150.)));
|
||||
|
||||
m_collisionShapes.push_back(groundShape);
|
||||
|
||||
btTransform groundTransform;
|
||||
groundTransform.setIdentity();
|
||||
groundTransform.setOrigin(btVector3(0, -25, 0));
|
||||
groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0));
|
||||
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
|
||||
btScalar mass(0.);
|
||||
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
bool isDynamic = (mass != 0.f);
|
||||
|
||||
btVector3 localInertia(0, 0, 0);
|
||||
if (isDynamic)
|
||||
groundShape->calculateLocalInertia(mass, localInertia);
|
||||
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
|
||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
|
||||
btRigidBody* body = new btRigidBody(rbInfo);
|
||||
body->setFriction(0.5);
|
||||
|
||||
//add the ground to the dynamics world
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
}
|
||||
|
||||
// create a soft block
|
||||
{
|
||||
btScalar verts[24] = {0.f, 0.f, 0.f,
|
||||
1.f, 0.f, 0.f,
|
||||
0.f, 1.f, 0.f,
|
||||
0.f, 0.f, 1.f,
|
||||
1.f, 1.f, 0.f,
|
||||
0.f, 1.f, 1.f,
|
||||
1.f, 0.f, 1.f,
|
||||
1.f, 1.f, 1.f
|
||||
};
|
||||
int triangles[60] = {0, 6, 3,
|
||||
0,1,6,
|
||||
7,5,3,
|
||||
7,3,6,
|
||||
4,7,6,
|
||||
4,6,1,
|
||||
7,2,5,
|
||||
7,4,2,
|
||||
0,3,2,
|
||||
2,3,5,
|
||||
0,2,4,
|
||||
0,4,1,
|
||||
0,6,5,
|
||||
0,6,4,
|
||||
3,4,2,
|
||||
3,4,7,
|
||||
2,7,3,
|
||||
2,7,1,
|
||||
4,5,0,
|
||||
4,5,6,
|
||||
};
|
||||
// btSoftBody* psb = btSoftBodyHelpers::CreateFromTriMesh(getDeformableDynamicsWorld()->getWorldInfo(), &verts[0], &triangles[0], 20);
|
||||
////
|
||||
btSoftBody* psb = btSoftBodyHelpers::CreateFromTetGenData(getDeformableDynamicsWorld()->getWorldInfo(),
|
||||
TetraCube::getElements(),
|
||||
0,
|
||||
TetraCube::getNodes(),
|
||||
false, true, true);
|
||||
|
||||
psb->scale(btVector3(2, 2, 2));
|
||||
psb->translate(btVector3(0, 4, 0));
|
||||
psb->getCollisionShape()->setMargin(0.01);
|
||||
psb->setTotalMass(1);
|
||||
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
|
||||
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
|
||||
psb->m_cfg.kDF = .5;
|
||||
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
|
||||
psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDF;
|
||||
getDeformableDynamicsWorld()->addSoftBody(psb);
|
||||
btSoftBodyHelpers::generateBoundaryFaces(psb);
|
||||
|
||||
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
|
||||
getDeformableDynamicsWorld()->addForce(psb, gravity_force);
|
||||
m_forces.push_back(gravity_force);
|
||||
|
||||
btDeformableNeoHookeanForce* neohookean = new btDeformableNeoHookeanForce(8,3, 0.02);
|
||||
neohookean->setPoissonRatio(0.3);
|
||||
neohookean->setYoungsModulus(25);
|
||||
neohookean->setDamping(0.01);
|
||||
psb->m_cfg.drag = 0.001;
|
||||
getDeformableDynamicsWorld()->addForce(psb, neohookean);
|
||||
m_forces.push_back(neohookean);
|
||||
// add a grippers
|
||||
createGrip();
|
||||
}
|
||||
getDeformableDynamicsWorld()->setImplicit(false);
|
||||
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
|
||||
}
|
||||
|
||||
void Pinch::exitPhysics()
|
||||
{
|
||||
//cleanup in the reverse order of creation/initialization
|
||||
removePickingConstraint();
|
||||
//remove the rigidbodies from the dynamics world and delete them
|
||||
int i;
|
||||
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
|
||||
{
|
||||
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
|
||||
btRigidBody* body = btRigidBody::upcast(obj);
|
||||
if (body && body->getMotionState())
|
||||
{
|
||||
delete body->getMotionState();
|
||||
}
|
||||
m_dynamicsWorld->removeCollisionObject(obj);
|
||||
delete obj;
|
||||
}
|
||||
// delete forces
|
||||
for (int j = 0; j < m_forces.size(); j++)
|
||||
{
|
||||
btDeformableLagrangianForce* force = m_forces[j];
|
||||
delete force;
|
||||
}
|
||||
m_forces.clear();
|
||||
//delete collision shapes
|
||||
for (int j = 0; j < m_collisionShapes.size(); j++)
|
||||
{
|
||||
btCollisionShape* shape = m_collisionShapes[j];
|
||||
delete shape;
|
||||
}
|
||||
m_collisionShapes.clear();
|
||||
|
||||
delete m_dynamicsWorld;
|
||||
|
||||
delete m_solver;
|
||||
|
||||
delete m_broadphase;
|
||||
|
||||
delete m_dispatcher;
|
||||
|
||||
delete m_collisionConfiguration;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class CommonExampleInterface* PinchCreateFunc(struct CommonExampleOptions& options)
|
||||
{
|
||||
return new Pinch(options.m_guiHelper);
|
||||
}
|
||||
|
||||
|
||||
19
Engine/lib/bullet/examples/DeformableDemo/Pinch.h
Normal file
19
Engine/lib/bullet/examples/DeformableDemo/Pinch.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 Google Inc. http://bulletphysics.org
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef _PINCH_H
|
||||
#define _PINCH_H
|
||||
|
||||
class CommonExampleInterface* PinchCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
#endif //_PINCH_H
|
||||
406
Engine/lib/bullet/examples/DeformableDemo/PinchFriction.cpp
Normal file
406
Engine/lib/bullet/examples/DeformableDemo/PinchFriction.cpp
Normal file
|
|
@ -0,0 +1,406 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 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 "PinchFriction.h"
|
||||
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
|
||||
#include "BulletSoftBody/btSoftBody.h"
|
||||
#include "BulletSoftBody/btSoftBodyHelpers.h"
|
||||
#include "BulletSoftBody/btDeformableBodySolver.h"
|
||||
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
|
||||
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
|
||||
#include <stdio.h> //printf debugging
|
||||
|
||||
#include "../CommonInterfaces/CommonDeformableBodyBase.h"
|
||||
#include "../Utils/b3ResourcePath.h"
|
||||
|
||||
///The PinchFriction shows the frictional contacts among volumetric deformable objects
|
||||
|
||||
struct TetraCube
|
||||
{
|
||||
#include "../SoftDemo/cube.inl"
|
||||
};
|
||||
|
||||
class PinchFriction : public CommonDeformableBodyBase
|
||||
{
|
||||
btAlignedObjectArray<btDeformableLagrangianForce*> m_forces;
|
||||
public:
|
||||
PinchFriction(struct GUIHelperInterface* helper)
|
||||
: CommonDeformableBodyBase(helper)
|
||||
{
|
||||
}
|
||||
virtual ~PinchFriction()
|
||||
{
|
||||
}
|
||||
void initPhysics();
|
||||
|
||||
void exitPhysics();
|
||||
|
||||
void resetCamera()
|
||||
{
|
||||
float dist = 25;
|
||||
float pitch = -30;
|
||||
float yaw = 100;
|
||||
float targetPos[3] = {0, -0, 0};
|
||||
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
|
||||
}
|
||||
|
||||
void stepSimulation(float deltaTime)
|
||||
{
|
||||
//use a smaller internal timestep, there are stability issues
|
||||
float internalTimeStep = 1. / 240.f;
|
||||
m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep);
|
||||
}
|
||||
|
||||
void createGrip()
|
||||
{
|
||||
int count = 2;
|
||||
float mass = 1e6;
|
||||
btCollisionShape* shape[] = {
|
||||
new btBoxShape(btVector3(3, 3, 0.5)),
|
||||
};
|
||||
static const int nshapes = sizeof(shape) / sizeof(shape[0]);
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
btTransform startTransform;
|
||||
startTransform.setIdentity();
|
||||
startTransform.setOrigin(btVector3(10, 0, 0));
|
||||
startTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.));
|
||||
createRigidBody(mass, startTransform, shape[i % nshapes]);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void renderScene()
|
||||
{
|
||||
CommonDeformableBodyBase::renderScene();
|
||||
}
|
||||
|
||||
virtual bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool movePickedBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual void removePickingConstraint(){}
|
||||
};
|
||||
|
||||
void dynamics2(btScalar time, btDeformableMultiBodyDynamicsWorld* world)
|
||||
{
|
||||
btAlignedObjectArray<btRigidBody*>& rbs = world->getNonStaticRigidBodies();
|
||||
if (rbs.size()<2)
|
||||
return;
|
||||
btRigidBody* rb0 = rbs[0];
|
||||
btScalar pressTime = 0.45;
|
||||
btScalar liftTime = 5;
|
||||
btScalar shiftTime = 1.75;
|
||||
btScalar holdTime = 7.5;
|
||||
btScalar dropTime = 8.3;
|
||||
btTransform rbTransform;
|
||||
rbTransform.setIdentity();
|
||||
btVector3 translation;
|
||||
btVector3 velocity;
|
||||
|
||||
btVector3 initialTranslationLeft = btVector3(0.5,3,4);
|
||||
btVector3 initialTranslationRight = btVector3(0.5,3,-4);
|
||||
btVector3 PinchFrictionVelocityLeft = btVector3(0,0,-2);
|
||||
btVector3 PinchFrictionVelocityRight = btVector3(0,0,2);
|
||||
btVector3 liftVelocity = btVector3(0,2,0);
|
||||
btVector3 shiftVelocity = btVector3(0,0,0);
|
||||
btVector3 holdVelocity = btVector3(0,0,0);
|
||||
btVector3 openVelocityLeft = btVector3(0,0,4);
|
||||
btVector3 openVelocityRight = btVector3(0,0,-4);
|
||||
|
||||
if (time < pressTime)
|
||||
{
|
||||
velocity = PinchFrictionVelocityLeft;
|
||||
translation = initialTranslationLeft + PinchFrictionVelocityLeft * time;
|
||||
}
|
||||
else if (time < liftTime)
|
||||
{
|
||||
velocity = liftVelocity;
|
||||
translation = initialTranslationLeft + PinchFrictionVelocityLeft * pressTime + liftVelocity * (time - pressTime);
|
||||
|
||||
}
|
||||
else if (time < shiftTime)
|
||||
{
|
||||
velocity = shiftVelocity;
|
||||
translation = initialTranslationLeft + PinchFrictionVelocityLeft * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (time - liftTime);
|
||||
}
|
||||
else if (time < holdTime)
|
||||
{
|
||||
velocity = btVector3(0,0,0);
|
||||
translation = initialTranslationLeft + PinchFrictionVelocityLeft * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (time - shiftTime);
|
||||
}
|
||||
else if (time < dropTime)
|
||||
{
|
||||
velocity = openVelocityLeft;
|
||||
translation = initialTranslationLeft + PinchFrictionVelocityLeft * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (holdTime - shiftTime)+ openVelocityLeft * (time - holdTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
velocity = holdVelocity;
|
||||
translation = initialTranslationLeft + PinchFrictionVelocityLeft * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (holdTime - shiftTime)+ openVelocityLeft * (dropTime - holdTime);
|
||||
}
|
||||
rbTransform.setOrigin(translation);
|
||||
rbTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0));
|
||||
rb0->setCenterOfMassTransform(rbTransform);
|
||||
rb0->setAngularVelocity(btVector3(0,0,0));
|
||||
rb0->setLinearVelocity(velocity);
|
||||
|
||||
btRigidBody* rb1 = rbs[1];
|
||||
if (time < pressTime)
|
||||
{
|
||||
velocity = PinchFrictionVelocityRight;
|
||||
translation = initialTranslationRight + PinchFrictionVelocityRight * time;
|
||||
}
|
||||
else if (time < liftTime)
|
||||
{
|
||||
velocity = liftVelocity;
|
||||
translation = initialTranslationRight + PinchFrictionVelocityRight * pressTime + liftVelocity * (time - pressTime);
|
||||
|
||||
}
|
||||
else if (time < shiftTime)
|
||||
{
|
||||
velocity = shiftVelocity;
|
||||
translation = initialTranslationRight + PinchFrictionVelocityRight * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (time - liftTime);
|
||||
}
|
||||
else if (time < holdTime)
|
||||
{
|
||||
velocity = btVector3(0,0,0);
|
||||
translation = initialTranslationRight + PinchFrictionVelocityRight * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (time - shiftTime);
|
||||
}
|
||||
else if (time < dropTime)
|
||||
{
|
||||
velocity = openVelocityRight;
|
||||
translation = initialTranslationRight + PinchFrictionVelocityRight * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (holdTime - shiftTime)+ openVelocityRight * (time - holdTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
velocity = holdVelocity;
|
||||
translation = initialTranslationRight + PinchFrictionVelocityRight * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (holdTime - shiftTime)+ openVelocityRight * (dropTime - holdTime);
|
||||
}
|
||||
rbTransform.setOrigin(translation);
|
||||
rbTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0));
|
||||
rb1->setCenterOfMassTransform(rbTransform);
|
||||
rb1->setAngularVelocity(btVector3(0,0,0));
|
||||
rb1->setLinearVelocity(velocity);
|
||||
|
||||
rb0->setFriction(200);
|
||||
rb1->setFriction(200);
|
||||
}
|
||||
|
||||
void PinchFriction::initPhysics()
|
||||
{
|
||||
m_guiHelper->setUpAxis(1);
|
||||
|
||||
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
|
||||
|
||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
||||
|
||||
m_broadphase = new btDbvtBroadphase();
|
||||
btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
|
||||
|
||||
btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
|
||||
sol->setDeformableSolver(deformableBodySolver);
|
||||
m_solver = sol;
|
||||
|
||||
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
|
||||
btVector3 gravity = btVector3(0, -10, 0);
|
||||
m_dynamicsWorld->setGravity(gravity);
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.setDefaultVoxelsz(0.25);
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.Reset();
|
||||
getDeformableDynamicsWorld()->setSolverCallback(dynamics2);
|
||||
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
|
||||
|
||||
//create a ground
|
||||
{
|
||||
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(25.), btScalar(150.)));
|
||||
|
||||
m_collisionShapes.push_back(groundShape);
|
||||
|
||||
btTransform groundTransform;
|
||||
groundTransform.setIdentity();
|
||||
groundTransform.setOrigin(btVector3(0, -25, 0));
|
||||
groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0));
|
||||
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
|
||||
btScalar mass(0.);
|
||||
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
bool isDynamic = (mass != 0.f);
|
||||
|
||||
btVector3 localInertia(0, 0, 0);
|
||||
if (isDynamic)
|
||||
groundShape->calculateLocalInertia(mass, localInertia);
|
||||
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
|
||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
|
||||
btRigidBody* body = new btRigidBody(rbInfo);
|
||||
body->setFriction(0.5);
|
||||
|
||||
//add the ground to the dynamics world
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
}
|
||||
|
||||
// create a soft block
|
||||
{
|
||||
btSoftBody* psb = btSoftBodyHelpers::CreateFromTetGenData(getDeformableDynamicsWorld()->getWorldInfo(),
|
||||
TetraCube::getElements(),
|
||||
0,
|
||||
TetraCube::getNodes(),
|
||||
false, true, true);
|
||||
|
||||
psb->scale(btVector3(2, 2, 1));
|
||||
psb->translate(btVector3(0, 2.1, 2.2));
|
||||
psb->getCollisionShape()->setMargin(0.025);
|
||||
psb->setSpringStiffness(10);
|
||||
psb->setTotalMass(.6);
|
||||
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
|
||||
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
|
||||
psb->m_cfg.kDF = 2;
|
||||
btSoftBodyHelpers::generateBoundaryFaces(psb);
|
||||
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
|
||||
psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDF;
|
||||
psb->m_cfg.collisions |= btSoftBody::fCollision::VF_DD;
|
||||
getDeformableDynamicsWorld()->addSoftBody(psb);
|
||||
|
||||
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
|
||||
getDeformableDynamicsWorld()->addForce(psb, gravity_force);
|
||||
m_forces.push_back(gravity_force);
|
||||
|
||||
btDeformableNeoHookeanForce* neohookean = new btDeformableNeoHookeanForce(6,6,.003);
|
||||
getDeformableDynamicsWorld()->addForce(psb, neohookean);
|
||||
m_forces.push_back(neohookean);
|
||||
}
|
||||
|
||||
// create a second soft block
|
||||
{
|
||||
btSoftBody* psb2 = btSoftBodyHelpers::CreateFromTetGenData(getDeformableDynamicsWorld()->getWorldInfo(),
|
||||
TetraCube::getElements(),
|
||||
0,
|
||||
TetraCube::getNodes(),
|
||||
false, true, true);
|
||||
|
||||
psb2->scale(btVector3(2, 2, 1));
|
||||
psb2->translate(btVector3(0, 2.1, -2.2));
|
||||
psb2->getCollisionShape()->setMargin(0.025);
|
||||
psb2->setTotalMass(.6);
|
||||
psb2->m_cfg.kKHR = 1; // collision hardness with kinematic objects
|
||||
psb2->m_cfg.kCHR = 1; // collision hardness with rigid body
|
||||
psb2->m_cfg.kDF = 2;
|
||||
psb2->setSpringStiffness(10);
|
||||
psb2->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
|
||||
psb2->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDF;
|
||||
psb2->m_cfg.collisions |= btSoftBody::fCollision::VF_DD;
|
||||
btSoftBodyHelpers::generateBoundaryFaces(psb2);
|
||||
getDeformableDynamicsWorld()->addSoftBody(psb2);
|
||||
|
||||
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
|
||||
getDeformableDynamicsWorld()->addForce(psb2, gravity_force);
|
||||
m_forces.push_back(gravity_force);
|
||||
|
||||
btDeformableNeoHookeanForce* neohookean = new btDeformableNeoHookeanForce(6,6,.003);
|
||||
getDeformableDynamicsWorld()->addForce(psb2, neohookean);
|
||||
m_forces.push_back(neohookean);
|
||||
}
|
||||
|
||||
// create a third soft block
|
||||
{
|
||||
btSoftBody* psb3 = btSoftBodyHelpers::CreateFromTetGenData(getDeformableDynamicsWorld()->getWorldInfo(),
|
||||
TetraCube::getElements(),
|
||||
0,
|
||||
TetraCube::getNodes(),
|
||||
false, true, true);
|
||||
|
||||
psb3->scale(btVector3(2, 2, 1));
|
||||
psb3->translate(btVector3(0, 2.1, 0));
|
||||
psb3->getCollisionShape()->setMargin(0.025);
|
||||
psb3->setTotalMass(.6);
|
||||
psb3->setSpringStiffness(10);
|
||||
psb3->m_cfg.kKHR = 1; // collision hardness with kinematic objects
|
||||
psb3->m_cfg.kCHR = 1; // collision hardness with rigid body
|
||||
psb3->m_cfg.kDF = 2;
|
||||
psb3->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
|
||||
psb3->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDF;
|
||||
psb3->m_cfg.collisions |= btSoftBody::fCollision::VF_DD;
|
||||
btSoftBodyHelpers::generateBoundaryFaces(psb3);
|
||||
getDeformableDynamicsWorld()->addSoftBody(psb3);
|
||||
|
||||
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
|
||||
getDeformableDynamicsWorld()->addForce(psb3, gravity_force);
|
||||
m_forces.push_back(gravity_force);
|
||||
|
||||
btDeformableNeoHookeanForce* neohookean = new btDeformableNeoHookeanForce(6,6,.003);
|
||||
getDeformableDynamicsWorld()->addForce(psb3, neohookean);
|
||||
m_forces.push_back(neohookean);
|
||||
}
|
||||
getDeformableDynamicsWorld()->setImplicit(false);
|
||||
// add a pair of grippers
|
||||
createGrip();
|
||||
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
|
||||
}
|
||||
|
||||
void PinchFriction::exitPhysics()
|
||||
{
|
||||
//cleanup in the reverse order of creation/initialization
|
||||
removePickingConstraint();
|
||||
//remove the rigidbodies from the dynamics world and delete them
|
||||
int i;
|
||||
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
|
||||
{
|
||||
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
|
||||
btRigidBody* body = btRigidBody::upcast(obj);
|
||||
if (body && body->getMotionState())
|
||||
{
|
||||
delete body->getMotionState();
|
||||
}
|
||||
m_dynamicsWorld->removeCollisionObject(obj);
|
||||
delete obj;
|
||||
}
|
||||
// delete forces
|
||||
for (int j = 0; j < m_forces.size(); j++)
|
||||
{
|
||||
btDeformableLagrangianForce* force = m_forces[j];
|
||||
delete force;
|
||||
}
|
||||
m_forces.clear();
|
||||
//delete collision shapes
|
||||
for (int j = 0; j < m_collisionShapes.size(); j++)
|
||||
{
|
||||
btCollisionShape* shape = m_collisionShapes[j];
|
||||
delete shape;
|
||||
}
|
||||
m_collisionShapes.clear();
|
||||
|
||||
delete m_dynamicsWorld;
|
||||
|
||||
delete m_solver;
|
||||
|
||||
delete m_broadphase;
|
||||
|
||||
delete m_dispatcher;
|
||||
|
||||
delete m_collisionConfiguration;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class CommonExampleInterface* PinchFrictionCreateFunc(struct CommonExampleOptions& options)
|
||||
{
|
||||
return new PinchFriction(options.m_guiHelper);
|
||||
}
|
||||
|
||||
|
||||
19
Engine/lib/bullet/examples/DeformableDemo/PinchFriction.h
Normal file
19
Engine/lib/bullet/examples/DeformableDemo/PinchFriction.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 Google Inc. http://bulletphysics.org
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef _PINCH_FRICTION_H
|
||||
#define _PINCH_FRICTION_H
|
||||
|
||||
class CommonExampleInterface* PinchFrictionCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
#endif //_PINCH_FRICTION_H
|
||||
238
Engine/lib/bullet/examples/DeformableDemo/SplitImpulse.cpp
Normal file
238
Engine/lib/bullet/examples/DeformableDemo/SplitImpulse.cpp
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 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 "SplitImpulse.h"
|
||||
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
|
||||
#include "BulletSoftBody/btSoftBody.h"
|
||||
#include "BulletSoftBody/btSoftBodyHelpers.h"
|
||||
#include "BulletSoftBody/btDeformableBodySolver.h"
|
||||
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
|
||||
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
|
||||
#include <stdio.h> //printf debugging
|
||||
|
||||
#include "../CommonInterfaces/CommonDeformableBodyBase.h"
|
||||
#include "../Utils/b3ResourcePath.h"
|
||||
|
||||
///The SplitImpulse shows the effect of split impulse in deformable rigid contact.
|
||||
class SplitImpulse : public CommonDeformableBodyBase
|
||||
{
|
||||
public:
|
||||
SplitImpulse(struct GUIHelperInterface* helper)
|
||||
: CommonDeformableBodyBase(helper)
|
||||
{
|
||||
}
|
||||
virtual ~SplitImpulse()
|
||||
{
|
||||
}
|
||||
void initPhysics();
|
||||
|
||||
void exitPhysics();
|
||||
|
||||
void resetCamera()
|
||||
{
|
||||
float dist = 20;
|
||||
float pitch = -45;
|
||||
float yaw = 100;
|
||||
float targetPos[3] = {0, -3, 0};
|
||||
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
|
||||
}
|
||||
|
||||
void stepSimulation(float deltaTime)
|
||||
{
|
||||
//use a smaller internal timestep, there are stability issues
|
||||
float internalTimeStep = 1. / 240.f;
|
||||
m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep);
|
||||
}
|
||||
|
||||
void Ctor_RbUpStack(int count)
|
||||
{
|
||||
float mass = 0.2;
|
||||
|
||||
btCollisionShape* shape[] = {
|
||||
new btBoxShape(btVector3(1, 1, 1)),
|
||||
};
|
||||
btTransform startTransform;
|
||||
startTransform.setIdentity();
|
||||
startTransform.setOrigin(btVector3(0, 0.7, 0));
|
||||
createRigidBody(mass, startTransform, shape[0]);
|
||||
}
|
||||
|
||||
virtual void renderScene()
|
||||
{
|
||||
CommonDeformableBodyBase::renderScene();
|
||||
btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
|
||||
|
||||
for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
|
||||
{
|
||||
btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i];
|
||||
//if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe)))
|
||||
{
|
||||
btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer());
|
||||
btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), deformableWorld->getDrawFlags());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void SplitImpulse::initPhysics()
|
||||
{
|
||||
m_guiHelper->setUpAxis(1);
|
||||
|
||||
///collision configuration contains default setup for memory, collision setup
|
||||
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
|
||||
|
||||
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
|
||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
||||
|
||||
m_broadphase = new btDbvtBroadphase();
|
||||
btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
|
||||
|
||||
///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
|
||||
btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
|
||||
sol->setDeformableSolver(deformableBodySolver);
|
||||
m_solver = sol;
|
||||
|
||||
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
|
||||
// deformableBodySolver->setWorld(getDeformableDynamicsWorld());
|
||||
// m_dynamicsWorld->getSolverInfo().m_singleAxisDeformableThreshold = 0.f;//faster but lower quality
|
||||
btVector3 gravity = btVector3(0, -50, 0);
|
||||
m_dynamicsWorld->setGravity(gravity);
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.setDefaultVoxelsz(0.25);
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.Reset();
|
||||
|
||||
// getDeformableDynamicsWorld()->before_solver_callbacks.push_back(dynamics);
|
||||
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
|
||||
|
||||
{
|
||||
///create a ground
|
||||
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(25.), btScalar(150.)));
|
||||
|
||||
m_collisionShapes.push_back(groundShape);
|
||||
|
||||
btTransform groundTransform;
|
||||
groundTransform.setIdentity();
|
||||
groundTransform.setOrigin(btVector3(0, -32, 0));
|
||||
groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.));
|
||||
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
|
||||
btScalar mass(0.);
|
||||
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
bool isDynamic = (mass != 0.f);
|
||||
|
||||
btVector3 localInertia(0, 0, 0);
|
||||
if (isDynamic)
|
||||
groundShape->calculateLocalInertia(mass, localInertia);
|
||||
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
|
||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
|
||||
btRigidBody* body = new btRigidBody(rbInfo);
|
||||
body->setFriction(1);
|
||||
|
||||
//add the ground to the dynamics world
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
}
|
||||
|
||||
// create a piece of cloth
|
||||
{
|
||||
const btScalar s = 4;
|
||||
const btScalar h = 0;
|
||||
|
||||
btSoftBody* psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, h, -s),
|
||||
btVector3(+s, h, -s),
|
||||
btVector3(-s, h, +s),
|
||||
btVector3(+s, h, +s),
|
||||
// 3,3,
|
||||
20,20,
|
||||
1 + 2 + 4 + 8, true);
|
||||
// 0, true);
|
||||
|
||||
|
||||
psb->getCollisionShape()->setMargin(0.015);
|
||||
psb->generateBendingConstraints(2);
|
||||
psb->setTotalMass(1);
|
||||
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
|
||||
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
|
||||
psb->m_cfg.kDF = 1;
|
||||
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
|
||||
psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDF;
|
||||
getDeformableDynamicsWorld()->addSoftBody(psb);
|
||||
|
||||
btDeformableMassSpringForce* mass_spring = new btDeformableMassSpringForce(30,1, true);
|
||||
getDeformableDynamicsWorld()->addForce(psb, mass_spring);
|
||||
m_forces.push_back(mass_spring);
|
||||
|
||||
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
|
||||
getDeformableDynamicsWorld()->addForce(psb, gravity_force);
|
||||
m_forces.push_back(gravity_force);
|
||||
// add a few rigid bodies
|
||||
Ctor_RbUpStack(1);
|
||||
}
|
||||
getDeformableDynamicsWorld()->setImplicit(false);
|
||||
getDeformableDynamicsWorld()->setLineSearch(false);
|
||||
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
|
||||
}
|
||||
|
||||
void SplitImpulse::exitPhysics()
|
||||
{
|
||||
//cleanup in the reverse order of creation/initialization
|
||||
removePickingConstraint();
|
||||
//remove the rigidbodies from the dynamics world and delete them
|
||||
int i;
|
||||
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
|
||||
{
|
||||
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
|
||||
btRigidBody* body = btRigidBody::upcast(obj);
|
||||
if (body && body->getMotionState())
|
||||
{
|
||||
delete body->getMotionState();
|
||||
}
|
||||
m_dynamicsWorld->removeCollisionObject(obj);
|
||||
delete obj;
|
||||
}
|
||||
// delete forces
|
||||
for (int j = 0; j < m_forces.size(); j++)
|
||||
{
|
||||
btDeformableLagrangianForce* force = m_forces[j];
|
||||
delete force;
|
||||
}
|
||||
m_forces.clear();
|
||||
//delete collision shapes
|
||||
for (int j = 0; j < m_collisionShapes.size(); j++)
|
||||
{
|
||||
btCollisionShape* shape = m_collisionShapes[j];
|
||||
delete shape;
|
||||
}
|
||||
m_collisionShapes.clear();
|
||||
|
||||
delete m_dynamicsWorld;
|
||||
|
||||
delete m_solver;
|
||||
|
||||
delete m_broadphase;
|
||||
|
||||
delete m_dispatcher;
|
||||
|
||||
delete m_collisionConfiguration;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class CommonExampleInterface* SplitImpulseCreateFunc(struct CommonExampleOptions& options)
|
||||
{
|
||||
return new SplitImpulse(options.m_guiHelper);
|
||||
}
|
||||
|
||||
|
||||
19
Engine/lib/bullet/examples/DeformableDemo/SplitImpulse.h
Normal file
19
Engine/lib/bullet/examples/DeformableDemo/SplitImpulse.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 Google Inc. http://bulletphysics.org
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef _SPLIT_IMPULSE_H
|
||||
#define _SPLIT_IMPULSE_H
|
||||
|
||||
class CommonExampleInterface* SplitImpulseCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
#endif //_SPLIT_IMPULSE_H
|
||||
|
|
@ -0,0 +1,326 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 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 "VolumetricDeformable.h"
|
||||
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
|
||||
#include "BulletSoftBody/btSoftBody.h"
|
||||
#include "BulletSoftBody/btSoftBodyHelpers.h"
|
||||
#include "BulletSoftBody/btDeformableBodySolver.h"
|
||||
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
|
||||
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
|
||||
#include "../CommonInterfaces/CommonParameterInterface.h"
|
||||
#include <stdio.h> //printf debugging
|
||||
|
||||
#include "../CommonInterfaces/CommonDeformableBodyBase.h"
|
||||
#include "../Utils/b3ResourcePath.h"
|
||||
|
||||
///The VolumetricDeformable shows the contact between volumetric deformable objects and rigid objects.
|
||||
static btScalar E = 50;
|
||||
static btScalar nu = 0.3;
|
||||
static btScalar damping_alpha = 0.1;
|
||||
static btScalar damping_beta = 0.01;
|
||||
|
||||
struct TetraCube
|
||||
{
|
||||
#include "../SoftDemo/cube.inl"
|
||||
};
|
||||
|
||||
class VolumetricDeformable : public CommonDeformableBodyBase
|
||||
{
|
||||
btDeformableLinearElasticityForce* m_linearElasticity;
|
||||
|
||||
public:
|
||||
VolumetricDeformable(struct GUIHelperInterface* helper)
|
||||
: CommonDeformableBodyBase(helper)
|
||||
{
|
||||
m_linearElasticity = 0;
|
||||
m_pickingForceElasticStiffness = 100;
|
||||
m_pickingForceDampingStiffness = 0;
|
||||
m_maxPickingForce = 1e10; // allow large picking force with implicit scheme.
|
||||
}
|
||||
virtual ~VolumetricDeformable()
|
||||
{
|
||||
}
|
||||
void initPhysics();
|
||||
|
||||
void exitPhysics();
|
||||
|
||||
void resetCamera()
|
||||
{
|
||||
float dist = 20;
|
||||
float pitch = -45;
|
||||
float yaw = 100;
|
||||
float targetPos[3] = {0, 3, 0};
|
||||
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
|
||||
}
|
||||
|
||||
void stepSimulation(float deltaTime)
|
||||
{
|
||||
m_linearElasticity->setPoissonRatio(nu);
|
||||
m_linearElasticity->setYoungsModulus(E);
|
||||
m_linearElasticity->setDamping(damping_alpha, damping_beta);
|
||||
//use a smaller internal timestep, there are stability issues
|
||||
float internalTimeStep = 1. / 240;
|
||||
m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep);
|
||||
}
|
||||
|
||||
void createStaticBox(const btVector3& halfEdge, const btVector3& translation)
|
||||
{
|
||||
btCollisionShape* box = new btBoxShape(halfEdge);
|
||||
m_collisionShapes.push_back(box);
|
||||
|
||||
btTransform Transform;
|
||||
Transform.setIdentity();
|
||||
Transform.setOrigin(translation);
|
||||
Transform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.0));
|
||||
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
|
||||
btScalar mass(0.);
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
bool isDynamic = (mass != 0.f);
|
||||
btVector3 localInertia(0, 0, 0);
|
||||
if (isDynamic)
|
||||
box->calculateLocalInertia(mass, localInertia);
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
btDefaultMotionState* myMotionState = new btDefaultMotionState(Transform);
|
||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, box, localInertia);
|
||||
btRigidBody* body = new btRigidBody(rbInfo);
|
||||
body->setFriction(0.5);
|
||||
|
||||
//add the ground to the dynamics world
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
}
|
||||
|
||||
void Ctor_RbUpStack(int count)
|
||||
{
|
||||
float mass = 2;
|
||||
|
||||
btCompoundShape* cylinderCompound = new btCompoundShape;
|
||||
btCollisionShape* cylinderShape = new btCylinderShapeX(btVector3(2, .5, .5));
|
||||
btCollisionShape* boxShape = new btBoxShape(btVector3(2, .5, .5));
|
||||
btTransform localTransform;
|
||||
localTransform.setIdentity();
|
||||
cylinderCompound->addChildShape(localTransform, boxShape);
|
||||
btQuaternion orn(SIMD_HALF_PI, 0, 0);
|
||||
localTransform.setRotation(orn);
|
||||
// localTransform.setOrigin(btVector3(1,1,1));
|
||||
cylinderCompound->addChildShape(localTransform, cylinderShape);
|
||||
|
||||
btCollisionShape* shape[] = {
|
||||
new btBoxShape(btVector3(1, 1, 1)),
|
||||
};
|
||||
static const int nshapes = sizeof(shape) / sizeof(shape[0]);
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
btTransform startTransform;
|
||||
startTransform.setIdentity();
|
||||
startTransform.setOrigin(btVector3(i, 10 + 2 * i, i-1));
|
||||
createRigidBody(mass, startTransform, shape[i % nshapes]);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void renderScene()
|
||||
{
|
||||
CommonDeformableBodyBase::renderScene();
|
||||
btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
|
||||
|
||||
for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
|
||||
{
|
||||
btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i];
|
||||
{
|
||||
btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer());
|
||||
btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), deformableWorld->getDrawFlags());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void VolumetricDeformable::initPhysics()
|
||||
{
|
||||
m_guiHelper->setUpAxis(1);
|
||||
|
||||
///collision configuration contains default setup for memory, collision setup
|
||||
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
|
||||
|
||||
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
|
||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
||||
|
||||
m_broadphase = new btDbvtBroadphase();
|
||||
btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
|
||||
|
||||
btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
|
||||
sol->setDeformableSolver(deformableBodySolver);
|
||||
m_solver = sol;
|
||||
|
||||
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
|
||||
btVector3 gravity = btVector3(0, -100, 0);
|
||||
m_dynamicsWorld->setGravity(gravity);
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.setDefaultVoxelsz(0.25);
|
||||
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.Reset();
|
||||
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
|
||||
|
||||
{
|
||||
///create a ground
|
||||
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(50.), btScalar(150.)));
|
||||
m_collisionShapes.push_back(groundShape);
|
||||
|
||||
btTransform groundTransform;
|
||||
groundTransform.setIdentity();
|
||||
groundTransform.setOrigin(btVector3(0, -50, 0));
|
||||
groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.0));
|
||||
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
|
||||
btScalar mass(0.);
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
bool isDynamic = (mass != 0.f);
|
||||
btVector3 localInertia(0, 0, 0);
|
||||
if (isDynamic)
|
||||
groundShape->calculateLocalInertia(mass, localInertia);
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
|
||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
|
||||
btRigidBody* body = new btRigidBody(rbInfo);
|
||||
body->setFriction(1);
|
||||
|
||||
//add the ground to the dynamics world
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
}
|
||||
|
||||
createStaticBox(btVector3(1, 5, 5), btVector3(-5,0,0));
|
||||
createStaticBox(btVector3(1, 5, 5), btVector3(5,0,0));
|
||||
createStaticBox(btVector3(5, 5, 1), btVector3(0,0,5));
|
||||
createStaticBox(btVector3(5, 5, 1), btVector3(0,0,-5));
|
||||
|
||||
// create volumetric soft body
|
||||
{
|
||||
btSoftBody* psb = btSoftBodyHelpers::CreateFromTetGenData(getDeformableDynamicsWorld()->getWorldInfo(),
|
||||
TetraCube::getElements(),
|
||||
0,
|
||||
TetraCube::getNodes(),
|
||||
false, true, true);
|
||||
getDeformableDynamicsWorld()->addSoftBody(psb);
|
||||
psb->scale(btVector3(2, 2, 2));
|
||||
psb->translate(btVector3(0, 5, 0));
|
||||
psb->getCollisionShape()->setMargin(0.1);
|
||||
psb->setTotalMass(0.5);
|
||||
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
|
||||
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
|
||||
psb->m_cfg.kDF = 2;
|
||||
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
|
||||
psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDN;
|
||||
psb->m_sleepingThreshold = 0;
|
||||
btSoftBodyHelpers::generateBoundaryFaces(psb);
|
||||
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
|
||||
getDeformableDynamicsWorld()->addForce(psb, gravity_force);
|
||||
m_forces.push_back(gravity_force);
|
||||
|
||||
btDeformableLinearElasticityForce* linearElasticity = new btDeformableLinearElasticityForce(100,100,0.01);
|
||||
m_linearElasticity = linearElasticity;
|
||||
getDeformableDynamicsWorld()->addForce(psb, linearElasticity);
|
||||
m_forces.push_back(linearElasticity);
|
||||
}
|
||||
getDeformableDynamicsWorld()->setImplicit(true);
|
||||
getDeformableDynamicsWorld()->setLineSearch(false);
|
||||
getDeformableDynamicsWorld()->setUseProjection(true);
|
||||
getDeformableDynamicsWorld()->getSolverInfo().m_deformable_erp = 0.3;
|
||||
getDeformableDynamicsWorld()->getSolverInfo().m_deformable_maxErrorReduction = btScalar(200);
|
||||
getDeformableDynamicsWorld()->getSolverInfo().m_leastSquaresResidualThreshold = 1e-3;
|
||||
getDeformableDynamicsWorld()->getSolverInfo().m_splitImpulse = true;
|
||||
getDeformableDynamicsWorld()->getSolverInfo().m_numIterations = 100;
|
||||
// add a few rigid bodies
|
||||
Ctor_RbUpStack(4);
|
||||
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
|
||||
|
||||
{
|
||||
SliderParams slider("Young's Modulus", &E);
|
||||
slider.m_minVal = 0;
|
||||
slider.m_maxVal = 2000;
|
||||
if (m_guiHelper->getParameterInterface())
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
}
|
||||
{
|
||||
SliderParams slider("Poisson Ratio", &nu);
|
||||
slider.m_minVal = 0.05;
|
||||
slider.m_maxVal = 0.49;
|
||||
if (m_guiHelper->getParameterInterface())
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
}
|
||||
{
|
||||
SliderParams slider("Mass Damping", &damping_alpha);
|
||||
slider.m_minVal = 0;
|
||||
slider.m_maxVal = 1;
|
||||
if (m_guiHelper->getParameterInterface())
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
}
|
||||
{
|
||||
SliderParams slider("Stiffness Damping", &damping_beta);
|
||||
slider.m_minVal = 0;
|
||||
slider.m_maxVal = 0.1;
|
||||
if (m_guiHelper->getParameterInterface())
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
|
||||
}
|
||||
}
|
||||
|
||||
void VolumetricDeformable::exitPhysics()
|
||||
{
|
||||
//cleanup in the reverse order of creation/initialization
|
||||
removePickingConstraint();
|
||||
//remove the rigidbodies from the dynamics world and delete them
|
||||
int i;
|
||||
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
|
||||
{
|
||||
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
|
||||
btRigidBody* body = btRigidBody::upcast(obj);
|
||||
if (body && body->getMotionState())
|
||||
{
|
||||
delete body->getMotionState();
|
||||
}
|
||||
m_dynamicsWorld->removeCollisionObject(obj);
|
||||
delete obj;
|
||||
}
|
||||
// delete forces
|
||||
for (int j = 0; j < m_forces.size(); j++)
|
||||
{
|
||||
btDeformableLagrangianForce* force = m_forces[j];
|
||||
delete force;
|
||||
}
|
||||
m_forces.clear();
|
||||
|
||||
//delete collision shapes
|
||||
for (int j = 0; j < m_collisionShapes.size(); j++)
|
||||
{
|
||||
btCollisionShape* shape = m_collisionShapes[j];
|
||||
delete shape;
|
||||
}
|
||||
m_collisionShapes.clear();
|
||||
|
||||
delete m_dynamicsWorld;
|
||||
|
||||
delete m_solver;
|
||||
|
||||
delete m_broadphase;
|
||||
|
||||
delete m_dispatcher;
|
||||
|
||||
delete m_collisionConfiguration;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class CommonExampleInterface* VolumetricDeformableCreateFunc(struct CommonExampleOptions& options)
|
||||
{
|
||||
return new VolumetricDeformable(options.m_guiHelper);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2019 Google Inc. http://bulletphysics.org
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef _VOLUMETRIC_DEFORMABLE_H
|
||||
#define _VOLUMETRIC_DEFORMABLE_H
|
||||
|
||||
class CommonExampleInterface* VolumetricDeformableCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
#endif //_VOLUMETRIC_DEFORMABLE__H
|
||||
|
|
@ -13,12 +13,12 @@ subject to the following restrictions:
|
|||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
|
||||
#include "LinearMath/btIDebugDraw.h"
|
||||
#include "MotorDemo.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
class btBroadphaseInterface;
|
||||
|
|
@ -34,85 +34,80 @@ class btDefaultCollisionConfiguration;
|
|||
class MotorDemo : public CommonRigidBodyBase
|
||||
{
|
||||
float m_Time;
|
||||
float m_fCyclePeriod; // in milliseconds
|
||||
float m_fCyclePeriod; // in milliseconds
|
||||
float m_fMuscleStrength;
|
||||
|
||||
|
||||
btAlignedObjectArray<class TestRig*> m_rigs;
|
||||
|
||||
|
||||
|
||||
public:
|
||||
MotorDemo(struct GUIHelperInterface* helper)
|
||||
:CommonRigidBodyBase(helper)
|
||||
: CommonRigidBodyBase(helper)
|
||||
{
|
||||
}
|
||||
|
||||
void initPhysics();
|
||||
|
||||
|
||||
void exitPhysics();
|
||||
|
||||
|
||||
virtual ~MotorDemo()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void spawnTestRig(const btVector3& startOffset, bool bFixed);
|
||||
|
||||
// virtual void keyboardCallback(unsigned char key, int x, int y);
|
||||
|
||||
|
||||
// virtual void keyboardCallback(unsigned char key, int x, int y);
|
||||
|
||||
void setMotorTargets(btScalar deltaTime);
|
||||
|
||||
|
||||
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]);
|
||||
float pitch = -35;
|
||||
float yaw = 52;
|
||||
float targetPos[3] = {0, 0.46, 0};
|
||||
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#ifndef M_PI_2
|
||||
#define M_PI_2 1.57079632679489661923
|
||||
#define M_PI_2 1.57079632679489661923
|
||||
#endif
|
||||
|
||||
#ifndef M_PI_4
|
||||
#define M_PI_4 0.785398163397448309616
|
||||
#define M_PI_4 0.785398163397448309616
|
||||
#endif
|
||||
|
||||
#ifndef M_PI_8
|
||||
#define M_PI_8 0.5 * M_PI_4
|
||||
#define M_PI_8 0.5 * M_PI_4
|
||||
#endif
|
||||
|
||||
|
||||
// /LOCAL FUNCTIONS
|
||||
|
||||
|
||||
|
||||
#define NUM_LEGS 6
|
||||
#define BODYPART_COUNT 2 * NUM_LEGS + 1
|
||||
#define JOINT_COUNT BODYPART_COUNT - 1
|
||||
|
||||
class TestRig
|
||||
{
|
||||
btDynamicsWorld* m_ownerWorld;
|
||||
btCollisionShape* m_shapes[BODYPART_COUNT];
|
||||
btRigidBody* m_bodies[BODYPART_COUNT];
|
||||
btTypedConstraint* m_joints[JOINT_COUNT];
|
||||
btDynamicsWorld* m_ownerWorld;
|
||||
btCollisionShape* m_shapes[BODYPART_COUNT];
|
||||
btRigidBody* m_bodies[BODYPART_COUNT];
|
||||
btTypedConstraint* m_joints[JOINT_COUNT];
|
||||
|
||||
btRigidBody* localCreateRigidBody (btScalar mass, const btTransform& startTransform, btCollisionShape* shape)
|
||||
btRigidBody* localCreateRigidBody(btScalar mass, const btTransform& startTransform, btCollisionShape* shape)
|
||||
{
|
||||
bool isDynamic = (mass != 0.f);
|
||||
|
||||
btVector3 localInertia(0,0,0);
|
||||
btVector3 localInertia(0, 0, 0);
|
||||
if (isDynamic)
|
||||
shape->calculateLocalInertia(mass,localInertia);
|
||||
shape->calculateLocalInertia(mass, localInertia);
|
||||
|
||||
btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
|
||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,shape,localInertia);
|
||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, shape, localInertia);
|
||||
btRigidBody* body = new btRigidBody(rbInfo);
|
||||
|
||||
m_ownerWorld->addRigidBody(body);
|
||||
|
|
@ -120,33 +115,33 @@ class TestRig
|
|||
return body;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
TestRig (btDynamicsWorld* ownerWorld, const btVector3& positionOffset, bool bFixed)
|
||||
: m_ownerWorld (ownerWorld)
|
||||
TestRig(btDynamicsWorld* ownerWorld, const btVector3& positionOffset, bool bFixed)
|
||||
: m_ownerWorld(ownerWorld)
|
||||
{
|
||||
btVector3 vUp(0, 1, 0);
|
||||
|
||||
//
|
||||
// Setup geometry
|
||||
//
|
||||
float fBodySize = 0.25f;
|
||||
float fBodySize = 0.25f;
|
||||
float fLegLength = 0.45f;
|
||||
float fForeLegLength = 0.75f;
|
||||
m_shapes[0] = new btCapsuleShape(btScalar(fBodySize), btScalar(0.10));
|
||||
int i;
|
||||
for ( i=0; i<NUM_LEGS; i++)
|
||||
for (i = 0; i < NUM_LEGS; i++)
|
||||
{
|
||||
m_shapes[1 + 2*i] = new btCapsuleShape(btScalar(0.10), btScalar(fLegLength));
|
||||
m_shapes[2 + 2*i] = new btCapsuleShape(btScalar(0.08), btScalar(fForeLegLength));
|
||||
m_shapes[1 + 2 * i] = new btCapsuleShape(btScalar(0.10), btScalar(fLegLength));
|
||||
m_shapes[2 + 2 * i] = new btCapsuleShape(btScalar(0.08), btScalar(fForeLegLength));
|
||||
}
|
||||
|
||||
//
|
||||
// Setup rigid bodies
|
||||
//
|
||||
float fHeight = 0.5;
|
||||
btTransform offset; offset.setIdentity();
|
||||
offset.setOrigin(positionOffset);
|
||||
btTransform offset;
|
||||
offset.setIdentity();
|
||||
offset.setOrigin(positionOffset);
|
||||
|
||||
// root
|
||||
btVector3 vRoot = btVector3(btScalar(0.), btScalar(fHeight), btScalar(0.));
|
||||
|
|
@ -155,32 +150,33 @@ public:
|
|||
transform.setOrigin(vRoot);
|
||||
if (bFixed)
|
||||
{
|
||||
m_bodies[0] = localCreateRigidBody(btScalar(0.), offset*transform, m_shapes[0]);
|
||||
} else
|
||||
m_bodies[0] = localCreateRigidBody(btScalar(0.), offset * transform, m_shapes[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bodies[0] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[0]);
|
||||
m_bodies[0] = localCreateRigidBody(btScalar(1.), offset * transform, m_shapes[0]);
|
||||
}
|
||||
// legs
|
||||
for ( i=0; i<NUM_LEGS; i++)
|
||||
for (i = 0; i < NUM_LEGS; i++)
|
||||
{
|
||||
float fAngle = 2 * M_PI * i / NUM_LEGS;
|
||||
float fSin = sin(fAngle);
|
||||
float fCos = cos(fAngle);
|
||||
float fSin = std::sin(fAngle);
|
||||
float fCos = std::cos(fAngle);
|
||||
|
||||
transform.setIdentity();
|
||||
btVector3 vBoneOrigin = btVector3(btScalar(fCos*(fBodySize+0.5*fLegLength)), btScalar(fHeight), btScalar(fSin*(fBodySize+0.5*fLegLength)));
|
||||
btVector3 vBoneOrigin = btVector3(btScalar(fCos * (fBodySize + 0.5 * fLegLength)), btScalar(fHeight), btScalar(fSin * (fBodySize + 0.5 * fLegLength)));
|
||||
transform.setOrigin(vBoneOrigin);
|
||||
|
||||
// thigh
|
||||
btVector3 vToBone = (vBoneOrigin - vRoot).normalize();
|
||||
btVector3 vAxis = vToBone.cross(vUp);
|
||||
btVector3 vAxis = vToBone.cross(vUp);
|
||||
transform.setRotation(btQuaternion(vAxis, M_PI_2));
|
||||
m_bodies[1+2*i] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[1+2*i]);
|
||||
m_bodies[1 + 2 * i] = localCreateRigidBody(btScalar(1.), offset * transform, m_shapes[1 + 2 * i]);
|
||||
|
||||
// shin
|
||||
transform.setIdentity();
|
||||
transform.setOrigin(btVector3(btScalar(fCos*(fBodySize+fLegLength)), btScalar(fHeight-0.5*fForeLegLength), btScalar(fSin*(fBodySize+fLegLength))));
|
||||
m_bodies[2+2*i] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[2+2*i]);
|
||||
transform.setOrigin(btVector3(btScalar(fCos * (fBodySize + fLegLength)), btScalar(fHeight - 0.5 * fForeLegLength), btScalar(fSin * (fBodySize + fLegLength))));
|
||||
m_bodies[2 + 2 * i] = localCreateRigidBody(btScalar(1.), offset * transform, m_shapes[2 + 2 * i]);
|
||||
}
|
||||
|
||||
// Setup some damping on the m_bodies
|
||||
|
|
@ -192,7 +188,6 @@ public:
|
|||
m_bodies[i]->setSleepingThresholds(0.5f, 0.5f);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Setup the constraints
|
||||
//
|
||||
|
|
@ -201,74 +196,76 @@ public:
|
|||
|
||||
btTransform localA, localB, localC;
|
||||
|
||||
for ( i=0; i<NUM_LEGS; i++)
|
||||
for (i = 0; i < NUM_LEGS; i++)
|
||||
{
|
||||
float fAngle = 2 * M_PI * i / NUM_LEGS;
|
||||
float fSin = sin(fAngle);
|
||||
float fCos = cos(fAngle);
|
||||
float fSin = std::sin(fAngle);
|
||||
float fCos = std::cos(fAngle);
|
||||
|
||||
// hip joints
|
||||
localA.setIdentity(); localB.setIdentity();
|
||||
localA.getBasis().setEulerZYX(0,-fAngle,0); localA.setOrigin(btVector3(btScalar(fCos*fBodySize), btScalar(0.), btScalar(fSin*fBodySize)));
|
||||
localB = m_bodies[1+2*i]->getWorldTransform().inverse() * m_bodies[0]->getWorldTransform() * localA;
|
||||
hingeC = new btHingeConstraint(*m_bodies[0], *m_bodies[1+2*i], localA, localB);
|
||||
localA.setIdentity();
|
||||
localB.setIdentity();
|
||||
localA.getBasis().setEulerZYX(0, -fAngle, 0);
|
||||
localA.setOrigin(btVector3(btScalar(fCos * fBodySize), btScalar(0.), btScalar(fSin * fBodySize)));
|
||||
localB = m_bodies[1 + 2 * i]->getWorldTransform().inverse() * m_bodies[0]->getWorldTransform() * localA;
|
||||
hingeC = new btHingeConstraint(*m_bodies[0], *m_bodies[1 + 2 * i], localA, localB);
|
||||
hingeC->setLimit(btScalar(-0.75 * M_PI_4), btScalar(M_PI_8));
|
||||
//hingeC->setLimit(btScalar(-0.1), btScalar(0.1));
|
||||
m_joints[2*i] = hingeC;
|
||||
m_ownerWorld->addConstraint(m_joints[2*i], true);
|
||||
m_joints[2 * i] = hingeC;
|
||||
m_ownerWorld->addConstraint(m_joints[2 * i], true);
|
||||
|
||||
// knee joints
|
||||
localA.setIdentity(); localB.setIdentity(); localC.setIdentity();
|
||||
localA.getBasis().setEulerZYX(0,-fAngle,0); localA.setOrigin(btVector3(btScalar(fCos*(fBodySize+fLegLength)), btScalar(0.), btScalar(fSin*(fBodySize+fLegLength))));
|
||||
localB = m_bodies[1+2*i]->getWorldTransform().inverse() * m_bodies[0]->getWorldTransform() * localA;
|
||||
localC = m_bodies[2+2*i]->getWorldTransform().inverse() * m_bodies[0]->getWorldTransform() * localA;
|
||||
hingeC = new btHingeConstraint(*m_bodies[1+2*i], *m_bodies[2+2*i], localB, localC);
|
||||
localA.setIdentity();
|
||||
localB.setIdentity();
|
||||
localC.setIdentity();
|
||||
localA.getBasis().setEulerZYX(0, -fAngle, 0);
|
||||
localA.setOrigin(btVector3(btScalar(fCos * (fBodySize + fLegLength)), btScalar(0.), btScalar(fSin * (fBodySize + fLegLength))));
|
||||
localB = m_bodies[1 + 2 * i]->getWorldTransform().inverse() * m_bodies[0]->getWorldTransform() * localA;
|
||||
localC = m_bodies[2 + 2 * i]->getWorldTransform().inverse() * m_bodies[0]->getWorldTransform() * localA;
|
||||
hingeC = new btHingeConstraint(*m_bodies[1 + 2 * i], *m_bodies[2 + 2 * i], localB, localC);
|
||||
//hingeC->setLimit(btScalar(-0.01), btScalar(0.01));
|
||||
hingeC->setLimit(btScalar(-M_PI_8), btScalar(0.2));
|
||||
m_joints[1+2*i] = hingeC;
|
||||
m_ownerWorld->addConstraint(m_joints[1+2*i], true);
|
||||
m_joints[1 + 2 * i] = hingeC;
|
||||
m_ownerWorld->addConstraint(m_joints[1 + 2 * i], true);
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~TestRig ()
|
||||
virtual ~TestRig()
|
||||
{
|
||||
int i;
|
||||
|
||||
// Remove all constraints
|
||||
for ( i = 0; i < JOINT_COUNT; ++i)
|
||||
for (i = 0; i < JOINT_COUNT; ++i)
|
||||
{
|
||||
m_ownerWorld->removeConstraint(m_joints[i]);
|
||||
delete m_joints[i]; m_joints[i] = 0;
|
||||
delete m_joints[i];
|
||||
m_joints[i] = 0;
|
||||
}
|
||||
|
||||
// Remove all bodies and shapes
|
||||
for ( i = 0; i < BODYPART_COUNT; ++i)
|
||||
for (i = 0; i < BODYPART_COUNT; ++i)
|
||||
{
|
||||
m_ownerWorld->removeRigidBody(m_bodies[i]);
|
||||
|
||||
|
||||
delete m_bodies[i]->getMotionState();
|
||||
|
||||
delete m_bodies[i]; m_bodies[i] = 0;
|
||||
delete m_shapes[i]; m_shapes[i] = 0;
|
||||
delete m_bodies[i];
|
||||
m_bodies[i] = 0;
|
||||
delete m_shapes[i];
|
||||
m_shapes[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
btTypedConstraint** GetJoints() {return &m_joints[0];}
|
||||
|
||||
btTypedConstraint** GetJoints() { return &m_joints[0]; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
void motorPreTickCallback (btDynamicsWorld *world, btScalar timeStep)
|
||||
void motorPreTickCallback(btDynamicsWorld* world, btScalar timeStep)
|
||||
{
|
||||
MotorDemo* motorDemo = (MotorDemo*)world->getWorldUserInfo();
|
||||
|
||||
motorDemo->setMotorTargets(timeStep);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MotorDemo::initPhysics()
|
||||
{
|
||||
m_guiHelper->setUpAxis(1);
|
||||
|
|
@ -276,70 +273,62 @@ void MotorDemo::initPhysics()
|
|||
// Setup the basic world
|
||||
|
||||
m_Time = 0;
|
||||
m_fCyclePeriod = 2000.f; // in milliseconds
|
||||
m_fCyclePeriod = 2000.f; // in milliseconds
|
||||
|
||||
// m_fMuscleStrength = 0.05f;
|
||||
// m_fMuscleStrength = 0.05f;
|
||||
// new SIMD solver for joints clips accumulated impulse, so the new limits for the motor
|
||||
// should be (numberOfsolverIterations * oldLimits)
|
||||
// currently solver uses 10 iterations, so:
|
||||
m_fMuscleStrength = 0.5f;
|
||||
|
||||
|
||||
m_collisionConfiguration = new btDefaultCollisionConfiguration();
|
||||
|
||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
||||
|
||||
btVector3 worldAabbMin(-10000,-10000,-10000);
|
||||
btVector3 worldAabbMax(10000,10000,10000);
|
||||
m_broadphase = new btAxisSweep3 (worldAabbMin, worldAabbMax);
|
||||
btVector3 worldAabbMin(-10000, -10000, -10000);
|
||||
btVector3 worldAabbMax(10000, 10000, 10000);
|
||||
m_broadphase = new btAxisSweep3(worldAabbMin, worldAabbMax);
|
||||
|
||||
m_solver = new btSequentialImpulseConstraintSolver;
|
||||
|
||||
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
|
||||
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration);
|
||||
|
||||
m_dynamicsWorld->setInternalTickCallback(motorPreTickCallback,this,true);
|
||||
m_dynamicsWorld->setInternalTickCallback(motorPreTickCallback, this, true);
|
||||
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
|
||||
|
||||
|
||||
// Setup a big ground box
|
||||
{
|
||||
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.),btScalar(10.),btScalar(200.)));
|
||||
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.), btScalar(10.), btScalar(200.)));
|
||||
m_collisionShapes.push_back(groundShape);
|
||||
btTransform groundTransform;
|
||||
groundTransform.setIdentity();
|
||||
groundTransform.setOrigin(btVector3(0,-10,0));
|
||||
createRigidBody(btScalar(0.),groundTransform,groundShape);
|
||||
groundTransform.setOrigin(btVector3(0, -10, 0));
|
||||
createRigidBody(btScalar(0.), groundTransform, groundShape);
|
||||
}
|
||||
|
||||
// Spawn one ragdoll
|
||||
btVector3 startOffset(1,0.5,0);
|
||||
btVector3 startOffset(1, 0.5, 0);
|
||||
spawnTestRig(startOffset, false);
|
||||
startOffset.setValue(-2,0.5,0);
|
||||
startOffset.setValue(-2, 0.5, 0);
|
||||
spawnTestRig(startOffset, true);
|
||||
|
||||
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
|
||||
}
|
||||
|
||||
|
||||
void MotorDemo::spawnTestRig(const btVector3& startOffset, bool bFixed)
|
||||
{
|
||||
TestRig* rig = new TestRig(m_dynamicsWorld, startOffset, bFixed);
|
||||
m_rigs.push_back(rig);
|
||||
}
|
||||
|
||||
void PreStep()
|
||||
void PreStep()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void MotorDemo::setMotorTargets(btScalar deltaTime)
|
||||
{
|
||||
|
||||
float ms = deltaTime*1000000.;
|
||||
float minFPS = 1000000.f/60.f;
|
||||
float ms = deltaTime * 1000000.;
|
||||
float minFPS = 1000000.f / 60.f;
|
||||
if (ms > minFPS)
|
||||
ms = minFPS;
|
||||
|
||||
|
|
@ -347,24 +336,22 @@ void MotorDemo::setMotorTargets(btScalar deltaTime)
|
|||
|
||||
//
|
||||
// set per-frame sinusoidal position targets using angular motor (hacky?)
|
||||
//
|
||||
for (int r=0; r<m_rigs.size(); r++)
|
||||
//
|
||||
for (int r = 0; r < m_rigs.size(); r++)
|
||||
{
|
||||
for (int i=0; i<2*NUM_LEGS; i++)
|
||||
for (int i = 0; i < 2 * NUM_LEGS; i++)
|
||||
{
|
||||
btHingeConstraint* hingeC = static_cast<btHingeConstraint*>(m_rigs[r]->GetJoints()[i]);
|
||||
btScalar fCurAngle = hingeC->getHingeAngle();
|
||||
|
||||
btScalar fCurAngle = hingeC->getHingeAngle();
|
||||
|
||||
btScalar fTargetPercent = (int(m_Time / 1000) % int(m_fCyclePeriod)) / m_fCyclePeriod;
|
||||
btScalar fTargetAngle = 0.5 * (1 + sin(2 * M_PI * fTargetPercent));
|
||||
btScalar fTargetAngle = 0.5 * (1 + sin(2 * M_PI * fTargetPercent));
|
||||
btScalar fTargetLimitAngle = hingeC->getLowerLimit() + fTargetAngle * (hingeC->getUpperLimit() - hingeC->getLowerLimit());
|
||||
btScalar fAngleError = fTargetLimitAngle - fCurAngle;
|
||||
btScalar fDesiredAngularVel = 1000000.f * fAngleError/ms;
|
||||
btScalar fAngleError = fTargetLimitAngle - fCurAngle;
|
||||
btScalar fDesiredAngularVel = 1000000.f * fAngleError / ms;
|
||||
hingeC->enableAngularMotor(true, fDesiredAngularVel, m_fMuscleStrength);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
|
@ -392,14 +379,11 @@ void MotorDemo::keyboardCallback(unsigned char key, int x, int y)
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void MotorDemo::exitPhysics()
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
for (i=0;i<m_rigs.size();i++)
|
||||
for (i = 0; i < m_rigs.size(); i++)
|
||||
{
|
||||
TestRig* rig = m_rigs[i];
|
||||
delete rig;
|
||||
|
|
@ -408,8 +392,8 @@ void MotorDemo::exitPhysics()
|
|||
//cleanup in the reverse order of creation/initialization
|
||||
|
||||
//remove the rigidbodies from the dynamics world and delete them
|
||||
|
||||
for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--)
|
||||
|
||||
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
|
||||
{
|
||||
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
|
||||
btRigidBody* body = btRigidBody::upcast(obj);
|
||||
|
|
@ -417,12 +401,12 @@ void MotorDemo::exitPhysics()
|
|||
{
|
||||
delete body->getMotionState();
|
||||
}
|
||||
m_dynamicsWorld->removeCollisionObject( obj );
|
||||
m_dynamicsWorld->removeCollisionObject(obj);
|
||||
delete obj;
|
||||
}
|
||||
|
||||
//delete collision shapes
|
||||
for (int j=0;j<m_collisionShapes.size();j++)
|
||||
for (int j = 0; j < m_collisionShapes.size(); j++)
|
||||
{
|
||||
btCollisionShape* shape = m_collisionShapes[j];
|
||||
delete shape;
|
||||
|
|
@ -440,11 +424,10 @@ void MotorDemo::exitPhysics()
|
|||
//delete dispatcher
|
||||
delete m_dispatcher;
|
||||
|
||||
delete m_collisionConfiguration;
|
||||
delete m_collisionConfiguration;
|
||||
}
|
||||
|
||||
|
||||
class CommonExampleInterface* MotorControlCreateFunc(struct CommonExampleOptions& options)
|
||||
class CommonExampleInterface* MotorControlCreateFunc(struct CommonExampleOptions& options)
|
||||
{
|
||||
return new MotorDemo(options.m_guiHelper);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,11 +13,9 @@ subject to the following restrictions:
|
|||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MOTORDEMO_H
|
||||
#define MOTORDEMO_H
|
||||
|
||||
class CommonExampleInterface* MotorControlCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
class CommonExampleInterface* MotorControlCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
1137
Engine/lib/bullet/examples/Evolution/NN3DWalkers.cpp
Normal file
1137
Engine/lib/bullet/examples/Evolution/NN3DWalkers.cpp
Normal file
File diff suppressed because it is too large
Load diff
21
Engine/lib/bullet/examples/Evolution/NN3DWalkers.h
Normal file
21
Engine/lib/bullet/examples/Evolution/NN3DWalkers.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2015 Google Inc. http://bulletphysics.org
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef ET_NN_3D_WALKERS_EXAMPLE_H
|
||||
#define ET_NN_3D_WALKERS_EXAMPLE_H
|
||||
|
||||
class CommonExampleInterface* ET_NN3DWalkersCreateFunc(struct CommonExampleOptions& options);
|
||||
|
||||
#endif //ET_NN_3D_WALKERS_EXAMPLE_H
|
||||
950
Engine/lib/bullet/examples/Evolution/NN3DWalkersTimeWarpBase.h
Normal file
950
Engine/lib/bullet/examples/Evolution/NN3DWalkersTimeWarpBase.h
Normal file
|
|
@ -0,0 +1,950 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2015 Google Inc. http://bulletphysics.org
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef NN3D_WALKERS_TIME_WARP_BASE_H
|
||||
#define NN3D_WALKERS_TIME_WARP_BASE_H
|
||||
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "LinearMath/btVector3.h"
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
#include "LinearMath/btQuickprof.h" // Use your own timer, this timer is only used as we lack another timer
|
||||
|
||||
#include "../CommonInterfaces/CommonRigidBodyBase.h"
|
||||
#include "../CommonInterfaces/CommonParameterInterface.h"
|
||||
|
||||
//Solvers
|
||||
#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
|
||||
#include "BulletDynamics/ConstraintSolver/btNNCGConstraintSolver.h"
|
||||
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
|
||||
#include "BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h"
|
||||
#include "BulletDynamics/MLCPSolvers/btDantzigSolver.h"
|
||||
#include "BulletDynamics/MLCPSolvers/btSolveProjectedGaussSeidel.h"
|
||||
#include "BulletDynamics/MLCPSolvers/btLemkeSolver.h"
|
||||
#include "BulletDynamics/MLCPSolvers/btMLCPSolver.h"
|
||||
|
||||
#include "../Utils/b3ERPCFMHelper.hpp" // ERP/CFM setting utils
|
||||
|
||||
static btScalar gSimulationSpeed = 1; // default simulation speed at startup
|
||||
|
||||
// the current simulation speeds to choose from (the slider will snap to those using a custom form of snapping)
|
||||
namespace SimulationSpeeds
|
||||
{
|
||||
static double /*0*/ PAUSE = 0;
|
||||
static double /*1*/ QUARTER_SPEED = 0.25;
|
||||
static double /*2*/ HALF_SPEED = 0.5;
|
||||
static double /*3*/ NORMAL_SPEED = 1;
|
||||
static double /*4*/ DOUBLE_SPEED = 2;
|
||||
static double /*5*/ QUADRUPLE_SPEED = 4;
|
||||
static double /*6*/ DECUPLE_SPEED = 10;
|
||||
static double /*7*/ CENTUPLE_SPEED = 100;
|
||||
static double /*8*/ QUINCENTUPLE_SPEED = 500;
|
||||
static double /*9*/ MILLITUPLE_SPEED = 1000;
|
||||
static double /*0*/ MAX_SPEED = MILLITUPLE_SPEED;
|
||||
static double /**/ NUM_SPEEDS = 10;
|
||||
}; // namespace SimulationSpeeds
|
||||
|
||||
// add speeds from the namespace here
|
||||
static double speeds[] = {
|
||||
SimulationSpeeds::PAUSE,
|
||||
SimulationSpeeds::QUARTER_SPEED, SimulationSpeeds::HALF_SPEED,
|
||||
SimulationSpeeds::NORMAL_SPEED, SimulationSpeeds::DOUBLE_SPEED,
|
||||
SimulationSpeeds::QUADRUPLE_SPEED, SimulationSpeeds::DECUPLE_SPEED,
|
||||
SimulationSpeeds::CENTUPLE_SPEED, SimulationSpeeds::QUINCENTUPLE_SPEED,
|
||||
SimulationSpeeds::MILLITUPLE_SPEED};
|
||||
|
||||
static btScalar gSolverIterations = 10; // default number of solver iterations for the iterative solvers
|
||||
|
||||
static bool gIsHeadless = false; // demo runs with graphics by default
|
||||
|
||||
static bool gChangeErpCfm = false; // flag to make recalculation of ERP/CFM
|
||||
|
||||
static int gMinSpeed = SimulationSpeeds::PAUSE; // the minimum simulation speed
|
||||
|
||||
static int gMaxSpeed = SimulationSpeeds::MAX_SPEED; // the maximum simulation speed
|
||||
|
||||
static bool gMaximumSpeed = false; // the demo does not try to achieve maximum stepping speed by default
|
||||
|
||||
static bool gInterpolate = false; // the demo does not use any bullet interpolated physics substeps
|
||||
|
||||
static bool useSplitImpulse = true; // split impulse fixes issues with restitution in Baumgarte stabilization
|
||||
// http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=7117&p=24631&hilit=Baumgarte#p24631
|
||||
// disabling continuous collision detection can also fix issues with restitution, though CCD is disabled by default an only kicks in at higher speeds
|
||||
// set CCD speed threshold and testing sphere radius per rigidbody (rb->setCCDSpeedThreshold())
|
||||
|
||||
// all supported solvers by bullet
|
||||
enum SolverEnumType
|
||||
{
|
||||
SEQUENTIALIMPULSESOLVER = 0,
|
||||
GAUSSSEIDELSOLVER = 1,
|
||||
NNCGSOLVER = 2,
|
||||
DANZIGSOLVER = 3,
|
||||
LEMKESOLVER = 4,
|
||||
|
||||
NUM_SOLVERS = 6
|
||||
};
|
||||
|
||||
// solvers can be changed by drop down menu
|
||||
namespace SolverType
|
||||
{
|
||||
static char SEQUENTIALIMPULSESOLVER[] = "Sequential Impulse Solver";
|
||||
static char GAUSSSEIDELSOLVER[] = "Gauss-Seidel Solver";
|
||||
static char NNCGSOLVER[] = "NNCG Solver";
|
||||
static char DANZIGSOLVER[] = "Danzig Solver";
|
||||
static char LEMKESOLVER[] = "Lemke Solver";
|
||||
|
||||
}; // namespace SolverType
|
||||
|
||||
static const char* solverTypes[NUM_SOLVERS];
|
||||
|
||||
static SolverEnumType SOLVER_TYPE = SEQUENTIALIMPULSESOLVER; // You can switch the solver here
|
||||
|
||||
//TODO:s===
|
||||
//TODO: Give specific explanations about solver values
|
||||
|
||||
/**
|
||||
* Step size of the bullet physics simulator (solverAccuracy). Accuracy versus speed.
|
||||
*/
|
||||
// Choose an appropriate number of steps per second for your needs
|
||||
static btScalar gPhysicsStepsPerSecond = 60.0f; // Default number of steps
|
||||
//static btScalar gPhysicsStepsPerSecond = 120.0f; // Double steps for more accuracy
|
||||
//static btScalar gPhysicsStepsPerSecond = 240.0f; // For high accuracy
|
||||
//static btScalar gPhysicsStepsPerSecond = 1000.0f; // Very high accuracy
|
||||
|
||||
// appropriate inverses for seconds and milliseconds
|
||||
static double fixedPhysicsStepSizeSec = 1.0f / gPhysicsStepsPerSecond; // steps size in seconds
|
||||
static double fixedPhysicsStepSizeMilli = 1000.0f / gPhysicsStepsPerSecond; // step size in milliseconds
|
||||
|
||||
static btScalar gApplicationFrequency = 60.0f; // number of internal application ticks per second
|
||||
static int gApplicationTick = 1000.0f / gApplicationFrequency; //ms
|
||||
|
||||
static btScalar gFramesPerSecond = 30.0f; // number of frames per second
|
||||
|
||||
static btScalar gERPSpringK = 10;
|
||||
static btScalar gERPDamperC = 1;
|
||||
|
||||
static btScalar gCFMSpringK = 10;
|
||||
static btScalar gCFMDamperC = 1;
|
||||
static btScalar gCFMSingularityAvoidance = 0;
|
||||
|
||||
//GUI related parameter changing helpers
|
||||
|
||||
inline void twxChangePhysicsStepsPerSecond(float physicsStepsPerSecond, void*)
|
||||
{ // function to change simulation physics steps per second
|
||||
gPhysicsStepsPerSecond = physicsStepsPerSecond;
|
||||
}
|
||||
|
||||
inline void twxChangeFPS(float framesPerSecond, void*)
|
||||
{
|
||||
gFramesPerSecond = framesPerSecond;
|
||||
}
|
||||
|
||||
inline void twxChangeERPCFM(float notUsed, void*)
|
||||
{ // function to change ERP/CFM appropriately
|
||||
gChangeErpCfm = true;
|
||||
}
|
||||
|
||||
inline void changeSolver(int comboboxId, const char* item, void* userPointer)
|
||||
{ // function to change the solver
|
||||
for (int i = 0; i < NUM_SOLVERS; i++)
|
||||
{
|
||||
if (strcmp(solverTypes[i], item) == 0)
|
||||
{ // if the strings are equal
|
||||
SOLVER_TYPE = ((SolverEnumType)i);
|
||||
b3Printf("=%s=\n Reset the simulation by double clicking it in the menu list.", item);
|
||||
return;
|
||||
}
|
||||
}
|
||||
b3Printf("No Change");
|
||||
}
|
||||
|
||||
inline void twxChangeSolverIterations(float notUsed, void* userPtr)
|
||||
{ // change the solver iterations
|
||||
}
|
||||
|
||||
inline void clampToCustomSpeedNotches(float speed, void*)
|
||||
{ // function to clamp to custom speed notches
|
||||
double minSpeed = 0;
|
||||
double minSpeedDist = SimulationSpeeds::MAX_SPEED;
|
||||
for (int i = 0; i < SimulationSpeeds::NUM_SPEEDS; i++)
|
||||
{
|
||||
double speedDist = (speeds[i] - speed >= 0) ? speeds[i] - speed : speed - speeds[i]; // float absolute
|
||||
|
||||
if (minSpeedDist > speedDist)
|
||||
{
|
||||
minSpeedDist = speedDist;
|
||||
minSpeed = speeds[i];
|
||||
}
|
||||
}
|
||||
gSimulationSpeed = minSpeed;
|
||||
}
|
||||
|
||||
inline void switchInterpolated(int buttonId, bool buttonState, void* userPointer)
|
||||
{ // toggle if interpolation steps are taken
|
||||
gInterpolate = !gInterpolate;
|
||||
// b3Printf("Interpolate substeps %s", gInterpolate?"on":"off");
|
||||
}
|
||||
|
||||
inline void switchHeadless(int buttonId, bool buttonState, void* userPointer)
|
||||
{ // toggle if the demo should run headless
|
||||
gIsHeadless = !gIsHeadless;
|
||||
// b3Printf("Run headless %s", gIsHeadless?"on":"off");
|
||||
}
|
||||
|
||||
inline void switchMaximumSpeed(int buttonId, bool buttonState, void* userPointer)
|
||||
{ // toggle it the demo should run as fast as possible
|
||||
// b3Printf("Run maximum speed %s", gMaximumSpeed?"on":"off");
|
||||
}
|
||||
|
||||
inline void setApplicationTick(float frequency, void*)
|
||||
{ // set internal application tick
|
||||
gApplicationTick = 1000.0f / frequency;
|
||||
}
|
||||
|
||||
/**
|
||||
* @link: Gaffer on Games - Fix your timestep: http://gafferongames.com/game-physics/fix-your-timestep/
|
||||
*/
|
||||
struct NN3DWalkersTimeWarpBase : public CommonRigidBodyBase
|
||||
{
|
||||
NN3DWalkersTimeWarpBase(struct GUIHelperInterface* helper) : CommonRigidBodyBase(helper),
|
||||
mPhysicsStepsPerSecondUpdated(false),
|
||||
mFramesPerSecondUpdated(false),
|
||||
mSolverIterationsUpdated(false)
|
||||
{
|
||||
// main frame timer initialization
|
||||
mApplicationStart = mLoopTimer.getTimeMilliseconds(); /**!< Initialize when the application started running */
|
||||
mInputClock = mApplicationStart; /**!< Initialize the last time the input was updated */
|
||||
mPreviousModelIteration = mApplicationStart;
|
||||
mThisModelIteration = mApplicationStart;
|
||||
mApplicationRuntime = mThisModelIteration - mApplicationStart; /**!< Initialize the application runtime */
|
||||
|
||||
// sub frame time initializations
|
||||
mGraphicsStart = mApplicationStart; /** !< Initialize the last graphics start */
|
||||
mModelStart = mApplicationStart; /** !< Initialize the last model start */
|
||||
mInputStart = mApplicationStart; /** !< Initialize the last input start */
|
||||
|
||||
mPhysicsStepStart = mApplicationStart; /**!< Initialize the physics step start */
|
||||
mPhysicsStepEnd = mApplicationStart; /**!< Initialize the physics step end */
|
||||
|
||||
//durations
|
||||
mLastGraphicsTick = 0;
|
||||
mLastModelTick = 0;
|
||||
mLastInputTick = 0;
|
||||
mPhysicsTick = 0;
|
||||
|
||||
mInputDt = 0;
|
||||
mModelAccumulator = 0;
|
||||
mFrameTime = 0;
|
||||
|
||||
fpsTimeStamp = mLoopTimer.getTimeMilliseconds(); // to time the fps
|
||||
fpsStep = 1000.0f / gFramesPerSecond;
|
||||
|
||||
// performance measurements for this demo
|
||||
performanceTimestamp = 0;
|
||||
performedTime = 0; // time the physics steps consumed
|
||||
speedUpPrintTimeStamp = mLoopTimer.getTimeSeconds(); // timer to print the speed up periodically
|
||||
mLoopTimer.reset();
|
||||
}
|
||||
|
||||
~NN3DWalkersTimeWarpBase()
|
||||
{
|
||||
}
|
||||
|
||||
void initPhysics()
|
||||
{ // initialize the demo
|
||||
|
||||
setupBasicParamInterface(); // setup adjustable sliders and buttons for parameters
|
||||
|
||||
m_guiHelper->setUpAxis(1); // Set Y axis as Up axis
|
||||
|
||||
createEmptyDynamicsWorld(); // create an empty dynamic world
|
||||
|
||||
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
|
||||
}
|
||||
|
||||
void setupBasicParamInterface()
|
||||
{ // setup the adjustable sliders and button for parameters
|
||||
|
||||
{ // create a slider to adjust the simulation speed
|
||||
// Force increase the simulation speed to run the simulation with the same accuracy but a higher speed
|
||||
SliderParams slider("Simulation speed",
|
||||
&gSimulationSpeed);
|
||||
slider.m_minVal = gMinSpeed;
|
||||
slider.m_maxVal = gMaxSpeed;
|
||||
slider.m_callback = clampToCustomSpeedNotches;
|
||||
slider.m_clampToNotches = false;
|
||||
if (m_guiHelper->getParameterInterface())
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
|
||||
slider);
|
||||
}
|
||||
|
||||
{ // create a button to switch to headless simulation
|
||||
// This turns off the graphics update and therefore results in more time for the model update
|
||||
ButtonParams button("Run headless", 0, true);
|
||||
button.m_callback = switchHeadless;
|
||||
if (m_guiHelper->getParameterInterface())
|
||||
m_guiHelper->getParameterInterface()->registerButtonParameter(
|
||||
button);
|
||||
}
|
||||
|
||||
{ // create a button to switch to maximum speed simulation (fully deterministic)
|
||||
// Interesting to test the maximal achievable speed on this hardware
|
||||
ButtonParams button("Run maximum speed", 0, true);
|
||||
button.m_callback = switchMaximumSpeed;
|
||||
if (m_guiHelper->getParameterInterface())
|
||||
m_guiHelper->getParameterInterface()->registerButtonParameter(
|
||||
button);
|
||||
}
|
||||
|
||||
{ // create a button to switch bullet to perform interpolated substeps to speed up simulation
|
||||
// generally, interpolated steps are a good speed-up and should only be avoided if higher accuracy is needed (research purposes etc.)
|
||||
ButtonParams button("Perform interpolated substeps", 0, true);
|
||||
button.m_callback = switchInterpolated;
|
||||
if (m_guiHelper->getParameterInterface())
|
||||
m_guiHelper->getParameterInterface()->registerButtonParameter(
|
||||
button);
|
||||
}
|
||||
}
|
||||
|
||||
void setupAdvancedParamInterface()
|
||||
{
|
||||
solverTypes[0] = SolverType::SEQUENTIALIMPULSESOLVER;
|
||||
solverTypes[1] = SolverType::GAUSSSEIDELSOLVER;
|
||||
solverTypes[2] = SolverType::NNCGSOLVER;
|
||||
solverTypes[3] = SolverType::DANZIGSOLVER;
|
||||
solverTypes[4] = SolverType::LEMKESOLVER;
|
||||
|
||||
|
||||
{
|
||||
ComboBoxParams comboParams;
|
||||
comboParams.m_comboboxId = 0;
|
||||
comboParams.m_numItems = NUM_SOLVERS;
|
||||
comboParams.m_startItem = SOLVER_TYPE;
|
||||
comboParams.m_callback = changeSolver;
|
||||
|
||||
comboParams.m_items = solverTypes;
|
||||
m_guiHelper->getParameterInterface()->registerComboBox(comboParams);
|
||||
}
|
||||
|
||||
{ // create a slider to adjust the number of internal application ticks
|
||||
// The set application tick should contain enough time to perform a full cycle of model update (physics and input)
|
||||
// and view update (graphics) with average application load. The graphics and input update determine the remaining time
|
||||
// for the physics update
|
||||
SliderParams slider("Application Ticks",
|
||||
&gApplicationFrequency);
|
||||
slider.m_minVal = gMinSpeed;
|
||||
slider.m_maxVal = gMaxSpeed;
|
||||
slider.m_callback = setApplicationTick;
|
||||
slider.m_clampToNotches = false;
|
||||
if (m_guiHelper->getParameterInterface())
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
|
||||
slider);
|
||||
}
|
||||
|
||||
{ // create a slider to adjust the number of physics steps per second
|
||||
// The default number of steps is at 60, which is appropriate for most general simulations
|
||||
// For simulations with higher complexity or if you experience undesired behavior, try increasing the number of steps per second
|
||||
// Alternatively, try increasing the number of solver iterations if you experience jittering constraints due to non-converging solutions
|
||||
SliderParams slider("Physics steps per second", &gPhysicsStepsPerSecond);
|
||||
slider.m_minVal = 0;
|
||||
slider.m_maxVal = 1000;
|
||||
slider.m_callback = twxChangePhysicsStepsPerSecond;
|
||||
slider.m_clampToNotches = false;
|
||||
if (m_guiHelper->getParameterInterface())
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
|
||||
slider);
|
||||
}
|
||||
|
||||
{ // create a slider to adjust the number of frames per second
|
||||
SliderParams slider("Frames per second", &gFramesPerSecond);
|
||||
slider.m_minVal = 0;
|
||||
slider.m_maxVal = 200;
|
||||
slider.m_callback = twxChangeFPS;
|
||||
slider.m_clampToNotches = false;
|
||||
if (m_guiHelper->getParameterInterface())
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
|
||||
slider);
|
||||
}
|
||||
|
||||
{ // create a slider to adjust the number of solver iterations to converge to a solution
|
||||
// more complex simulations might need a higher number of iterations to converge, it also
|
||||
// depends on the type of solver.
|
||||
SliderParams slider(
|
||||
"Solver interations",
|
||||
&gSolverIterations);
|
||||
slider.m_minVal = 0;
|
||||
slider.m_maxVal = 1000;
|
||||
slider.m_callback = twxChangePhysicsStepsPerSecond;
|
||||
slider.m_clampToIntegers = true;
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
|
||||
slider);
|
||||
}
|
||||
|
||||
// ERP/CFM sliders
|
||||
// Advanced users: Check descriptions of ERP/CFM in BulletUtils.cpp
|
||||
|
||||
{ // create a slider to adjust ERP Spring k constant
|
||||
SliderParams slider("Global ERP Spring k (F=k*x)", &gERPSpringK);
|
||||
slider.m_minVal = 0;
|
||||
slider.m_maxVal = 10;
|
||||
slider.m_callback = twxChangeERPCFM;
|
||||
slider.m_clampToNotches = false;
|
||||
if (m_guiHelper->getParameterInterface())
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
|
||||
slider);
|
||||
}
|
||||
|
||||
{ // create a slider to adjust ERP damper c constant
|
||||
SliderParams slider("Global ERP damper c (F=c*xdot)", &gERPDamperC);
|
||||
slider.m_minVal = 0;
|
||||
slider.m_maxVal = 10;
|
||||
slider.m_callback = twxChangeERPCFM;
|
||||
slider.m_clampToNotches = false;
|
||||
if (m_guiHelper->getParameterInterface())
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
|
||||
slider);
|
||||
}
|
||||
|
||||
{ // create a slider to adjust CFM Spring k constant
|
||||
SliderParams slider("Global CFM Spring k (F=k*x)", &gCFMSpringK);
|
||||
slider.m_minVal = 0;
|
||||
slider.m_maxVal = 10;
|
||||
slider.m_callback = twxChangeERPCFM;
|
||||
slider.m_clampToNotches = false;
|
||||
if (m_guiHelper->getParameterInterface())
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
|
||||
slider);
|
||||
}
|
||||
|
||||
{ // create a slider to adjust CFM damper c constant
|
||||
SliderParams slider("Global CFM damper c (F=c*xdot)", &gCFMDamperC);
|
||||
slider.m_minVal = 0;
|
||||
slider.m_maxVal = 10;
|
||||
slider.m_callback = twxChangeERPCFM;
|
||||
slider.m_clampToNotches = false;
|
||||
if (m_guiHelper->getParameterInterface())
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
|
||||
slider);
|
||||
}
|
||||
|
||||
{ // create a slider to adjust CFM damper c constant
|
||||
SliderParams slider("Global CFM singularity avoidance", &gCFMSingularityAvoidance);
|
||||
slider.m_minVal = 0;
|
||||
slider.m_maxVal = 10;
|
||||
slider.m_callback = twxChangeERPCFM;
|
||||
slider.m_clampToNotches = false;
|
||||
if (m_guiHelper->getParameterInterface())
|
||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(
|
||||
slider);
|
||||
}
|
||||
}
|
||||
|
||||
void createEmptyDynamicsWorld()
|
||||
{ // create an empty dynamics worlds according to the chosen settings via statics (top section of code)
|
||||
|
||||
///collision configuration contains default setup for memory, collision setup
|
||||
m_collisionConfiguration = new btDefaultCollisionConfiguration();
|
||||
//m_collisionConfiguration->setConvexConvexMultipointIterations();
|
||||
|
||||
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
|
||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
||||
|
||||
// default broadphase
|
||||
m_broadphase = new btDbvtBroadphase();
|
||||
|
||||
// different solvers require different settings
|
||||
switch (SOLVER_TYPE)
|
||||
{
|
||||
case SEQUENTIALIMPULSESOLVER:
|
||||
{
|
||||
// b3Printf("=%s=",SolverType::SEQUENTIALIMPULSESOLVER);
|
||||
m_solver = new btSequentialImpulseConstraintSolver();
|
||||
break;
|
||||
}
|
||||
case NNCGSOLVER:
|
||||
{
|
||||
// b3Printf("=%s=",SolverType::NNCGSOLVER);
|
||||
m_solver = new btNNCGConstraintSolver();
|
||||
break;
|
||||
}
|
||||
case DANZIGSOLVER:
|
||||
{
|
||||
// b3Printf("=%s=",SolverType::DANZIGSOLVER);
|
||||
btDantzigSolver* mlcp = new btDantzigSolver();
|
||||
m_solver = new btMLCPSolver(mlcp);
|
||||
break;
|
||||
}
|
||||
case GAUSSSEIDELSOLVER:
|
||||
{
|
||||
// b3Printf("=%s=",SolverType::GAUSSSEIDELSOLVER);
|
||||
btSolveProjectedGaussSeidel* mlcp = new btSolveProjectedGaussSeidel();
|
||||
m_solver = new btMLCPSolver(mlcp);
|
||||
break;
|
||||
}
|
||||
case LEMKESOLVER:
|
||||
{
|
||||
// b3Printf("=%s=",SolverType::LEMKESOLVER);
|
||||
btLemkeSolver* mlcp = new btLemkeSolver();
|
||||
m_solver = new btMLCPSolver(mlcp);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (1)
|
||||
{
|
||||
//TODO: Set parameters for other solvers
|
||||
|
||||
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,
|
||||
m_broadphase, m_solver, m_collisionConfiguration);
|
||||
|
||||
if (SOLVER_TYPE == DANZIGSOLVER || SOLVER_TYPE == GAUSSSEIDELSOLVER)
|
||||
{
|
||||
m_dynamicsWorld->getSolverInfo().m_minimumSolverBatchSize = 1; //for mlcp solver it is better to have a small A matrix
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dynamicsWorld->getSolverInfo().m_minimumSolverBatchSize = 128; //for direct solver, it is better to solve multiple objects together, small batches have high overhead
|
||||
}
|
||||
|
||||
m_dynamicsWorld->getDispatchInfo().m_useContinuous = true; // set continuous collision
|
||||
}
|
||||
else
|
||||
{
|
||||
//use btMultiBodyDynamicsWorld for Featherstone btMultiBody support
|
||||
m_dynamicsWorld = new btMultiBodyDynamicsWorld(m_dispatcher,
|
||||
m_broadphase, (btMultiBodyConstraintSolver*)m_solver,
|
||||
m_collisionConfiguration);
|
||||
}
|
||||
|
||||
changeERPCFM(); // set appropriate ERP/CFM values according to the string and damper properties of the constraint
|
||||
|
||||
if (useSplitImpulse)
|
||||
{ // If you experience strong repulsion forces in your constraints, it might help to enable the split impulse feature
|
||||
m_dynamicsWorld->getSolverInfo().m_splitImpulse = 1; //enable split impulse feature
|
||||
// m_dynamicsWorld->getSolverInfo().m_splitImpulsePenetrationThreshold =
|
||||
// -0.02;
|
||||
// m_dynamicsWorld->getSolverInfo().m_erp2 = BulletUtils::getERP(
|
||||
// fixedPhysicsStepSizeSec, 10, 1);
|
||||
// m_dynamicsWorld->getSolverInfo().m_splitImpulseTurnErp =
|
||||
// BulletUtils::getERP(fixedPhysicsStepSizeSec, 10, 1);
|
||||
// b3Printf("Using split impulse feature with ERP/TurnERP: (%f,%f)",
|
||||
// m_dynamicsWorld->getSolverInfo().m_erp2,
|
||||
// m_dynamicsWorld->getSolverInfo().m_splitImpulseTurnErp);
|
||||
}
|
||||
|
||||
m_dynamicsWorld->getSolverInfo().m_numIterations = gSolverIterations; // set the number of solver iterations for iteration based solvers
|
||||
|
||||
m_dynamicsWorld->setGravity(btVector3(0, -9.81f, 0)); // set gravity to -9.81
|
||||
}
|
||||
|
||||
btScalar calculatePerformedSpeedup()
|
||||
{ // calculate performed speedup
|
||||
// we calculate the performed speed up
|
||||
btScalar speedUp = ((double)performedTime * 1000.0) / ((double)(mLoopTimer.getTimeMilliseconds() - performanceTimestamp));
|
||||
// b3Printf("Avg Effective speedup: %f",speedUp);
|
||||
performedTime = 0;
|
||||
performanceTimestamp = mLoopTimer.getTimeMilliseconds();
|
||||
return speedUp;
|
||||
}
|
||||
|
||||
void timeWarpSimulation(float deltaTime) // Override this
|
||||
{
|
||||
}
|
||||
|
||||
void stepSimulation(float deltaTime)
|
||||
{ // customly step the simulation
|
||||
do
|
||||
{
|
||||
// // settings
|
||||
if (mPhysicsStepsPerSecondUpdated)
|
||||
{
|
||||
changePhysicsStepsPerSecond(gPhysicsStepsPerSecond);
|
||||
mPhysicsStepsPerSecondUpdated = false;
|
||||
}
|
||||
|
||||
if (mFramesPerSecondUpdated)
|
||||
{
|
||||
changeFPS(gFramesPerSecond);
|
||||
mFramesPerSecondUpdated = false;
|
||||
}
|
||||
|
||||
if (gChangeErpCfm)
|
||||
{
|
||||
changeERPCFM();
|
||||
gChangeErpCfm = false;
|
||||
}
|
||||
|
||||
if (mSolverIterationsUpdated)
|
||||
{
|
||||
changeSolverIterations(gSolverIterations);
|
||||
mSolverIterationsUpdated = false;
|
||||
}
|
||||
|
||||
// structure according to the canonical game loop
|
||||
// http://www.bulletphysics.org/mediawiki-1.5.8/index.php/Canonical_Game_Loop
|
||||
|
||||
//##############
|
||||
// breaking conditions - if the loop should stop, then check it here
|
||||
|
||||
//#############
|
||||
// model update - here you perform updates of your model, be it the physics model, the game or simulation state or anything not related to graphics and input
|
||||
|
||||
timeWarpSimulation(deltaTime);
|
||||
if (mLoopTimer.getTimeSeconds() - speedUpPrintTimeStamp > 1)
|
||||
{
|
||||
// on reset, we calculate the performed speed up
|
||||
//double speedUp = ((double)performedTime*1000.0)/((double)(mLoopTimer.getTimeMilliseconds()-performanceTimestamp));
|
||||
// b3Printf("Avg Effective speedup: %f",speedUp);
|
||||
performedTime = 0;
|
||||
performanceTimestamp = mLoopTimer.getTimeMilliseconds();
|
||||
speedUpPrintTimeStamp = mLoopTimer.getTimeSeconds();
|
||||
}
|
||||
|
||||
// update timers
|
||||
mThisModelIteration = mLoopTimer.getTimeMilliseconds();
|
||||
mFrameTime = mThisModelIteration - mPreviousModelIteration; /**!< Calculate the frame time (in Milliseconds) */
|
||||
mPreviousModelIteration = mThisModelIteration;
|
||||
|
||||
// b3Printf("Current Frame time: % u", mFrameTime);
|
||||
|
||||
mApplicationRuntime = mThisModelIteration - mApplicationStart; /**!< Update main frame timer (in Milliseconds) */
|
||||
|
||||
mModelStart = mLoopTimer.getTimeMilliseconds(); /**!< Begin with the model update (in Milliseconds)*/
|
||||
mLastGraphicsTick = mModelStart - mGraphicsStart; /**!< Update graphics timer (in Milliseconds) */
|
||||
|
||||
if (gMaximumSpeed /** If maximum speed is enabled*/)
|
||||
{
|
||||
performMaxStep();
|
||||
}
|
||||
else
|
||||
{ /**!< This mode tries to progress as much time as it is expected from the game loop*/
|
||||
performSpeedStep();
|
||||
}
|
||||
|
||||
mInputStart = mLoopTimer.getTimeMilliseconds(); /**!< Start the input update */
|
||||
mLastModelTick = mInputStart - mModelStart; /**!< Calculate the time the model update took */
|
||||
|
||||
//#############
|
||||
// Input update - Game Clock part of the loop
|
||||
/** This runs once every gApplicationTick milliseconds on average */
|
||||
mInputDt = mThisModelIteration - mInputClock;
|
||||
if (mInputDt >= gApplicationTick)
|
||||
{
|
||||
mInputClock = mThisModelIteration;
|
||||
// mInputHandler.injectInput(); /**!< Inject input into handlers */
|
||||
// mInputHandler.update(mInputClock); /**!< update elements that work on the current input state */
|
||||
}
|
||||
|
||||
mGraphicsStart = mLoopTimer.getTimeMilliseconds(); /**!< Start the graphics update */
|
||||
mLastInputTick = mGraphicsStart - mInputStart; /**!< Calculate the time the input injection took */
|
||||
|
||||
//#############
|
||||
// Graphics update - Here you perform the representation of your model, meaning graphics rendering according to what your game or simulation model describes
|
||||
// In the example browser, there is a separate method called renderScene() for this
|
||||
|
||||
// Uncomment this for some detailed output about the application ticks
|
||||
// b3Printf(
|
||||
// "Physics time: %u milliseconds / Graphics time: %u milliseconds / Input time: %u milliseconds / Total time passed: %u milliseconds",
|
||||
// mLastModelTick, mLastGraphicsTick, mLastInputTick, mApplicationRuntime);
|
||||
|
||||
} while (mLoopTimer.getTimeMilliseconds() - fpsTimeStamp < fpsStep); // escape the loop if it is time to render
|
||||
// Unfortunately, the input is not included in the loop, therefore the input update frequency is equal to the fps
|
||||
|
||||
fpsTimeStamp = mLoopTimer.getTimeMilliseconds();
|
||||
}
|
||||
|
||||
virtual bool keyboardCallback(int key, int state)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case '1':
|
||||
{
|
||||
gSimulationSpeed = SimulationSpeeds::QUARTER_SPEED;
|
||||
gMaximumSpeed = false;
|
||||
return true;
|
||||
}
|
||||
case '2':
|
||||
{
|
||||
gSimulationSpeed = SimulationSpeeds::HALF_SPEED;
|
||||
gMaximumSpeed = false;
|
||||
return true;
|
||||
}
|
||||
case '3':
|
||||
{
|
||||
gSimulationSpeed = SimulationSpeeds::NORMAL_SPEED;
|
||||
gMaximumSpeed = false;
|
||||
return true;
|
||||
}
|
||||
case '4':
|
||||
{
|
||||
gSimulationSpeed = SimulationSpeeds::DOUBLE_SPEED;
|
||||
gMaximumSpeed = false;
|
||||
return true;
|
||||
}
|
||||
case '5':
|
||||
{
|
||||
gSimulationSpeed = SimulationSpeeds::QUADRUPLE_SPEED;
|
||||
gMaximumSpeed = false;
|
||||
return true;
|
||||
}
|
||||
case '6':
|
||||
{
|
||||
gSimulationSpeed = SimulationSpeeds::DECUPLE_SPEED;
|
||||
gMaximumSpeed = false;
|
||||
return true;
|
||||
}
|
||||
case '7':
|
||||
{
|
||||
gSimulationSpeed = SimulationSpeeds::CENTUPLE_SPEED;
|
||||
gMaximumSpeed = false;
|
||||
return true;
|
||||
}
|
||||
case '8':
|
||||
{
|
||||
gSimulationSpeed = SimulationSpeeds::QUINCENTUPLE_SPEED;
|
||||
gMaximumSpeed = false;
|
||||
return true;
|
||||
}
|
||||
case '9':
|
||||
{
|
||||
gSimulationSpeed = SimulationSpeeds::MILLITUPLE_SPEED;
|
||||
gMaximumSpeed = false;
|
||||
return true;
|
||||
}
|
||||
case '0':
|
||||
{
|
||||
gSimulationSpeed = SimulationSpeeds::MAX_SPEED;
|
||||
gMaximumSpeed = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return CommonRigidBodyBase::keyboardCallback(key, state);
|
||||
}
|
||||
|
||||
void changePhysicsStepsPerSecond(float physicsStepsPerSecond)
|
||||
{ // change the simulation accuracy
|
||||
if (m_dynamicsWorld && physicsStepsPerSecond)
|
||||
{
|
||||
fixedPhysicsStepSizeSec = 1.0f / physicsStepsPerSecond;
|
||||
fixedPhysicsStepSizeMilli = 1000.0f / physicsStepsPerSecond;
|
||||
|
||||
changeERPCFM();
|
||||
}
|
||||
}
|
||||
|
||||
void changeERPCFM()
|
||||
{ // Change ERP/CFM appropriately to the timestep and the ERP/CFM parameters above
|
||||
if (m_dynamicsWorld)
|
||||
{
|
||||
m_dynamicsWorld->getSolverInfo().m_erp = b3ERPCFMHelper::getERP( // set the error reduction parameter
|
||||
fixedPhysicsStepSizeSec, // step size per second
|
||||
gERPSpringK, // k of a spring in the equation F = k * x (x:position)
|
||||
gERPDamperC); // k of a damper in the equation F = k * v (v:velocity)
|
||||
|
||||
m_dynamicsWorld->getSolverInfo().m_globalCfm = b3ERPCFMHelper::getCFM( // set the constraint force mixing according to the time step
|
||||
gCFMSingularityAvoidance, // singularity avoidance (if you experience unsolvable constraints, increase this value
|
||||
fixedPhysicsStepSizeSec, // steps size per second
|
||||
gCFMSpringK, // k of a spring in the equation F = k * x (x:position)
|
||||
gCFMDamperC); // k of a damper in the equation F = k * v (v:velocity)
|
||||
|
||||
// b3Printf("Bullet DynamicsWorld ERP: %f",
|
||||
// m_dynamicsWorld->getSolverInfo().m_erp);
|
||||
|
||||
// b3Printf("Bullet DynamicsWorld CFM: %f",
|
||||
// m_dynamicsWorld->getSolverInfo().m_globalCfm);
|
||||
}
|
||||
}
|
||||
|
||||
void changeSolverIterations(int iterations)
|
||||
{ // change the number of iterations
|
||||
m_dynamicsWorld->getSolverInfo().m_numIterations = iterations;
|
||||
}
|
||||
|
||||
void changeFPS(float framesPerSecond)
|
||||
{ // change the frames per second
|
||||
fpsStep = 1000.0f / gFramesPerSecond;
|
||||
}
|
||||
|
||||
void performTrueSteps(btScalar timeStep)
|
||||
{ // physics stepping without interpolated substeps
|
||||
int subSteps = floor((timeStep / fixedPhysicsStepSizeSec) + 0.5); /**!< Calculate the number of full normal time steps we can take */
|
||||
|
||||
for (int i = 0; i < subSteps; i++)
|
||||
{ /**!< Perform the number of substeps to reach the timestep*/
|
||||
if (timeStep && m_dynamicsWorld)
|
||||
{
|
||||
// since we want to perform all proper steps, we perform no interpolated substeps
|
||||
int subSteps = 1;
|
||||
|
||||
m_dynamicsWorld->stepSimulation(btScalar(timeStep),
|
||||
btScalar(subSteps), btScalar(fixedPhysicsStepSizeSec));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void performInterpolatedSteps(btScalar timeStep)
|
||||
{ // physics stepping with interpolated substeps
|
||||
int subSteps = 1 + floor((timeStep / fixedPhysicsStepSizeSec) + 0.5); /**!< Calculate the number of full normal time steps we can take, plus 1 for safety of not losing time */
|
||||
if (timeStep && m_dynamicsWorld)
|
||||
{
|
||||
m_dynamicsWorld->stepSimulation(btScalar(timeStep), btScalar(subSteps),
|
||||
btScalar(fixedPhysicsStepSizeSec)); /**!< Perform the number of substeps to reach the timestep*/
|
||||
}
|
||||
}
|
||||
|
||||
void performMaxStep()
|
||||
{ // perform as many steps as possible
|
||||
if (gApplicationTick >= mLastGraphicsTick + mLastInputTick)
|
||||
{ // if the remaining time for graphics is going to be positive
|
||||
mPhysicsTick = gApplicationTick /**!< calculate the remaining time for physics (in Milliseconds) */
|
||||
- mLastGraphicsTick - mLastInputTick;
|
||||
}
|
||||
else
|
||||
{
|
||||
mPhysicsTick = 0; // no time for physics left / The internal application step is too high
|
||||
}
|
||||
|
||||
// b3Printf("Application tick: %u",gApplicationTick);
|
||||
// b3Printf("Graphics tick: %u",mLastGraphicsTick);
|
||||
// b3Printf("Input tick: %u",mLastInputTick);
|
||||
// b3Printf("Physics tick: %u",mPhysicsTick);
|
||||
|
||||
if (mPhysicsTick > 0)
|
||||
{ // with positive physics tick we perform as many update steps until the time for it is used up
|
||||
|
||||
mPhysicsStepStart = mLoopTimer.getTimeMilliseconds(); /**!< The physics updates start (in Milliseconds)*/
|
||||
mPhysicsStepEnd = mPhysicsStepStart;
|
||||
|
||||
while (mPhysicsTick > mPhysicsStepEnd - mPhysicsStepStart)
|
||||
{ /**!< Update the physics until we run out of time (in Milliseconds) */
|
||||
// b3Printf("Physics passed: %u", mPhysicsStepEnd - mPhysicsStepStart);
|
||||
double timeStep = fixedPhysicsStepSizeSec; /**!< update the world (in Seconds) */
|
||||
|
||||
if (gInterpolate)
|
||||
{
|
||||
performInterpolatedSteps(timeStep);
|
||||
}
|
||||
else
|
||||
{
|
||||
performTrueSteps(timeStep);
|
||||
}
|
||||
performedTime += timeStep;
|
||||
mPhysicsStepEnd = mLoopTimer.getTimeMilliseconds(); /**!< Update the last physics step end to stop updating in time (in Milliseconds) */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void performSpeedStep()
|
||||
{ // force-perform the number of steps needed to achieve a certain speed (safe to too high speeds, meaning the application will lose time, not the physics)
|
||||
if (mFrameTime > gApplicationTick)
|
||||
{ /** cap frametime to make the application lose time, not the physics (in Milliseconds) */
|
||||
mFrameTime = gApplicationTick; // This prevents the physics time accumulator to sum up too much time
|
||||
} // The simulation therefore gets slower, but still performs all requested physics steps
|
||||
|
||||
mModelAccumulator += mFrameTime; /**!< Accumulate the time the physics simulation has to perform in order to stay in real-time (in Milliseconds) */
|
||||
// b3Printf("Model time accumulator: %u", mModelAccumulator);
|
||||
|
||||
int steps = floor(mModelAccumulator / fixedPhysicsStepSizeMilli); /**!< Calculate the number of time steps we can take */
|
||||
// b3Printf("Next steps: %i", steps);
|
||||
|
||||
if (steps > 0)
|
||||
{ /**!< Update if we can take at least one step */
|
||||
|
||||
double timeStep = gSimulationSpeed * steps * fixedPhysicsStepSizeSec; /**!< update the universe (in Seconds) */
|
||||
|
||||
if (gInterpolate)
|
||||
{
|
||||
performInterpolatedSteps(timeStep); // perform interpolated steps
|
||||
}
|
||||
else
|
||||
{
|
||||
performTrueSteps(timeStep); // perform full steps
|
||||
}
|
||||
performedTime += timeStep; // sum up the performed time for measuring the speed up
|
||||
mModelAccumulator -= steps * fixedPhysicsStepSizeMilli; /**!< Remove the time performed by the physics simulation from the accumulator, the remaining time carries over to the next cycle (in Milliseconds) */
|
||||
}
|
||||
}
|
||||
|
||||
void renderScene()
|
||||
{ // render the scene
|
||||
if (!gIsHeadless)
|
||||
{ // while the simulation is not running headlessly, render to screen
|
||||
CommonRigidBodyBase::renderScene();
|
||||
|
||||
if (m_dynamicsWorld->getDebugDrawer())
|
||||
{
|
||||
debugDraw(m_dynamicsWorld->getDebugDrawer()->getDebugMode());
|
||||
}
|
||||
}
|
||||
mIsHeadless = gIsHeadless;
|
||||
}
|
||||
void resetCamera()
|
||||
{ // reset the camera to its original position
|
||||
float dist = 41;
|
||||
float pitch = 52;
|
||||
float yaw = 35;
|
||||
float targetPos[3] = {0, 0.46, 0};
|
||||
m_guiHelper->resetCamera(dist, pitch, yaw, targetPos[0], targetPos[1],
|
||||
targetPos[2]);
|
||||
}
|
||||
|
||||
// loop timing components ###################
|
||||
//# loop timestamps
|
||||
btClock mLoopTimer; /**!< The loop timer to time the loop correctly */
|
||||
unsigned long int mApplicationStart; /**!< The time the application was started (absolute, in Milliseconds) */
|
||||
unsigned long int mPreviousModelIteration; /**!< The previous model iteration timestamp (absolute, in Milliseconds) */
|
||||
unsigned long int mThisModelIteration; /**!< This model iteration timestamp (absolute, in Milliseconds) */
|
||||
|
||||
//# loop durations
|
||||
long int mModelAccumulator; /**!< The time to forward the model in this loop iteration (relative, in Milliseconds) */
|
||||
unsigned long int mFrameTime; /**!< The time to render a frame (relative, in Milliseconds) */
|
||||
unsigned long int mApplicationRuntime; /**!< The total application runtime (relative, in Milliseconds) */
|
||||
|
||||
long int mInputDt; /**!< The time difference of input that has to be fed in */
|
||||
unsigned long int mInputClock;
|
||||
|
||||
long int mLastGraphicsTick; /*!< The time it took the graphics rendering last time (relative, in Milliseconds) */
|
||||
unsigned long int mGraphicsStart;
|
||||
|
||||
long int mLastInputTick; /**!< The time it took the input to process last time (relative, in Milliseconds) */
|
||||
unsigned long int mInputStart;
|
||||
|
||||
long int mLastModelTick; /**!< The time it took the model to update last time
|
||||
This includes the bullet physics update */
|
||||
unsigned long int mModelStart; /**!< The timestamp the model started updating last (absolute, in Milliseconds)*/
|
||||
|
||||
long int mPhysicsTick; /**!< The time remaining in the loop to update the physics (relative, in Milliseconds)*/
|
||||
unsigned long int mPhysicsStepStart; /**!< The physics start timestamp (absolute, in Milliseconds) */
|
||||
unsigned long int mPhysicsStepEnd; /**!< The last physics step end (absolute, in Milliseconds) */
|
||||
|
||||
// to measure the performance of the demo
|
||||
double performedTime;
|
||||
unsigned long int performanceTimestamp;
|
||||
|
||||
unsigned long int speedUpPrintTimeStamp;
|
||||
|
||||
unsigned long int fpsTimeStamp; /**!< FPS timing variables */
|
||||
double fpsStep;
|
||||
|
||||
//store old values
|
||||
bool mPhysicsStepsPerSecondUpdated;
|
||||
bool mFramesPerSecondUpdated;
|
||||
bool mSolverIterationsUpdated;
|
||||
bool mIsHeadless;
|
||||
};
|
||||
|
||||
#endif //NN3D_WALKERS_TIME_WARP_BASE_H
|
||||
|
|
@ -11,7 +11,7 @@ FILE(GLOB GwenGUISupport_HDRS "GwenGUISupport/*" )
|
|||
|
||||
IF (WIN32)
|
||||
INCLUDE_DIRECTORIES(
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/Glew
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/glad
|
||||
)
|
||||
ADD_DEFINITIONS(-DGLEW_STATIC)
|
||||
ELSE(WIN32)
|
||||
|
|
@ -21,7 +21,7 @@ ELSE(WIN32)
|
|||
ADD_DEFINITIONS("-DGLEW_INIT_OPENGL11_FUNCTIONS=1")
|
||||
ADD_DEFINITIONS("-DGLEW_STATIC")
|
||||
ADD_DEFINITIONS("-DGLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS=1")
|
||||
INCLUDE_DIRECTORIES( ${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/Glew )
|
||||
INCLUDE_DIRECTORIES( ${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/glad )
|
||||
ENDIF(APPLE)
|
||||
ENDIF(WIN32)
|
||||
|
||||
|
|
@ -34,8 +34,12 @@ ADD_LIBRARY(BulletExampleBrowserLib
|
|||
CollisionShape2TriangleMesh.h
|
||||
../Utils/b3Clock.cpp
|
||||
../Utils/b3Clock.h
|
||||
../Utils/ChromeTraceUtil.cpp
|
||||
../Utils/ChromeTraceUtil.h
|
||||
../Utils/b3ResourcePath.cpp
|
||||
../Utils/b3ResourcePath.h
|
||||
../Utils/b3ERPCFMHelper.hpp
|
||||
../Utils/b3ReferenceFrameHelper.hpp
|
||||
${GwenGUISupport_SRCS}
|
||||
${GwenGUISupport_HDRS}
|
||||
|
||||
|
|
@ -57,16 +61,22 @@ IF (BUILD_SHARED_LIBS)
|
|||
BulletInverseDynamics LinearMath OpenGLWindow gwen BussIK
|
||||
${COCOA} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}
|
||||
)
|
||||
ELSE(APPLE)
|
||||
ELSE(APPLE)
|
||||
FIND_PACKAGE(Threads)
|
||||
TARGET_LINK_LIBRARIES(
|
||||
BulletExampleBrowserLib Bullet3Common BulletSoftBody BulletDynamics BulletCollision BulletInverseDynamicsUtils
|
||||
BulletInverseDynamics LinearMath OpenGLWindow gwen BussIK
|
||||
pthread dl
|
||||
${CMAKE_THREAD_LIBS_INIT} ${DL}
|
||||
)
|
||||
ENDIF(APPLE)
|
||||
ENDIF(WIN32)
|
||||
ENDIF(BUILD_SHARED_LIBS)
|
||||
|
||||
INSTALL(TARGETS BulletExampleBrowserLib
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib${LIB_SUFFIX}
|
||||
ARCHIVE DESTINATION lib${LIB_SUFFIX})
|
||||
|
||||
####################
|
||||
#
|
||||
# Bullet Example Browser main app
|
||||
|
|
@ -76,6 +86,7 @@ ENDIF(BUILD_SHARED_LIBS)
|
|||
INCLUDE_DIRECTORIES(
|
||||
.
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/src
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/examples/SharedMemory
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs
|
||||
)
|
||||
|
||||
|
|
@ -84,9 +95,12 @@ LINK_LIBRARIES(
|
|||
BulletExampleBrowserLib Bullet3Common BulletSoftBody BulletDynamics BulletCollision BulletInverseDynamicsUtils BulletInverseDynamics LinearMath OpenGLWindow gwen BussIK
|
||||
)
|
||||
|
||||
|
||||
add_definitions(-DINCLUDE_CLOTH_DEMOS)
|
||||
|
||||
IF (WIN32)
|
||||
INCLUDE_DIRECTORIES(
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/Glew
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/glad
|
||||
)
|
||||
LINK_LIBRARIES(
|
||||
${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}
|
||||
|
|
@ -97,46 +111,78 @@ ELSE(WIN32)
|
|||
find_library(COCOA NAMES Cocoa)
|
||||
MESSAGE(${COCOA})
|
||||
link_libraries(${COCOA} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY})
|
||||
INCLUDE_DIRECTORIES( ${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/glad )
|
||||
ELSE(APPLE)
|
||||
ADD_DEFINITIONS("-DGLEW_INIT_OPENGL11_FUNCTIONS=1")
|
||||
ADD_DEFINITIONS("-DGLEW_STATIC")
|
||||
ADD_DEFINITIONS("-DGLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS=1")
|
||||
INCLUDE_DIRECTORIES( ${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/Glew )
|
||||
LINK_LIBRARIES( pthread dl)
|
||||
INCLUDE_DIRECTORIES( ${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/glad )
|
||||
FIND_PACKAGE(Threads)
|
||||
LINK_LIBRARIES( ${CMAKE_THREAD_LIBS_INIT} ${DL} )
|
||||
ENDIF(APPLE)
|
||||
ENDIF(WIN32)
|
||||
|
||||
|
||||
SET(ExtendedTutorialsSources
|
||||
../ExtendedTutorials/SimpleBox.cpp
|
||||
../ExtendedTutorials/MultipleBoxes.cpp
|
||||
../ExtendedTutorials/SimpleJoint.cpp
|
||||
../ExtendedTutorials/SimpleCloth.cpp
|
||||
../ExtendedTutorials/Chain.cpp
|
||||
../ExtendedTutorials/Bridge.cpp
|
||||
../ExtendedTutorials/Chain.h
|
||||
../ExtendedTutorials/Bridge.cpp
|
||||
../ExtendedTutorials/Bridge.h
|
||||
../ExtendedTutorials/RigidBodyFromObj.cpp
|
||||
../ExtendedTutorials/RigidBodyFromObj.h
|
||||
../ExtendedTutorials/SimpleBox.cpp
|
||||
../ExtendedTutorials/SimpleBox.h
|
||||
../ExtendedTutorials/MultipleBoxes.cpp
|
||||
../ExtendedTutorials/MultipleBoxes.h
|
||||
../ExtendedTutorials/CompoundBoxes.cpp
|
||||
../ExtendedTutorials/CompoundBoxes.h
|
||||
../ExtendedTutorials/SimpleCloth.cpp
|
||||
../ExtendedTutorials/SimpleCloth.h
|
||||
../ExtendedTutorials/SimpleJoint.cpp
|
||||
../ExtendedTutorials/SimpleJoint.h
|
||||
../ExtendedTutorials/NewtonsCradle.cpp
|
||||
../ExtendedTutorials/NewtonsCradle.h
|
||||
../ExtendedTutorials/InclinedPlane.cpp
|
||||
../ExtendedTutorials/InclinedPlane.h
|
||||
../ExtendedTutorials/NewtonsCradle.cpp
|
||||
../ExtendedTutorials/MultiPendulum.cpp
|
||||
../ExtendedTutorials/MultiPendulum.h
|
||||
)
|
||||
|
||||
SET(BulletExampleBrowser_SRCS
|
||||
|
||||
../BulletRobotics/FixJointBoxes.cpp
|
||||
|
||||
../BulletRobotics/BoxStack.cpp
|
||||
../BulletRobotics/JointLimit.cpp
|
||||
# ../BulletRobotics/GraspBox.cpp
|
||||
|
||||
../TinyRenderer/geometry.cpp
|
||||
../TinyRenderer/model.cpp
|
||||
../TinyRenderer/tgaimage.cpp
|
||||
../TinyRenderer/our_gl.cpp
|
||||
../TinyRenderer/TinyRenderer.cpp
|
||||
../SharedMemory/TinyRendererVisualShapeConverter.cpp
|
||||
../SharedMemory/TinyRendererVisualShapeConverter.h
|
||||
../SharedMemory/plugins/collisionFilterPlugin/collisionFilterPlugin.cpp
|
||||
../SharedMemory/plugins/collisionFilterPlugin/collisionFilterPlugin.h
|
||||
../SharedMemory/plugins/pdControlPlugin/pdControlPlugin.cpp
|
||||
../SharedMemory/plugins/pdControlPlugin/pdControlPlugin.h
|
||||
../SharedMemory/plugins/tinyRendererPlugin/tinyRendererPlugin.cpp
|
||||
../SharedMemory/plugins/tinyRendererPlugin/TinyRendererVisualShapeConverter.cpp
|
||||
../SharedMemory/IKTrajectoryHelper.cpp
|
||||
../SharedMemory/IKTrajectoryHelper.h
|
||||
|
||||
../SharedMemory/PhysicsServer.cpp
|
||||
../SharedMemory/PhysicsClientSharedMemory.cpp
|
||||
../SharedMemory/PhysicsClientSharedMemory_C_API.cpp
|
||||
../SharedMemory/PhysicsClient.cpp
|
||||
../SharedMemory/PhysicsClientC_API.cpp
|
||||
../SharedMemory/GraphicsServerExample.cpp
|
||||
../SharedMemory/GraphicsClientExample.cpp
|
||||
../SharedMemory/RemoteGUIHelper.cpp
|
||||
../SharedMemory/GraphicsServerExample.h
|
||||
../SharedMemory/GraphicsClientExample.h
|
||||
../SharedMemory/RemoteGUIHelper.h
|
||||
../SharedMemory/GraphicsSharedMemoryCommands.h
|
||||
../SharedMemory/GraphicsSharedMemoryPublic.h
|
||||
../SharedMemory/PhysicsServerExample.cpp
|
||||
../SharedMemory/PhysicsServerExampleBullet2.cpp
|
||||
../SharedMemory/PhysicsClientExample.cpp
|
||||
../SharedMemory/PosixSharedMemory.cpp
|
||||
../SharedMemory/Win32SharedMemory.cpp
|
||||
|
|
@ -153,6 +199,15 @@ SET(BulletExampleBrowser_SRCS
|
|||
../SharedMemory/PhysicsLoopBackC_API.h
|
||||
../SharedMemory/PhysicsServerCommandProcessor.cpp
|
||||
../SharedMemory/PhysicsServerCommandProcessor.h
|
||||
../SharedMemory/SharedMemoryCommands.h
|
||||
../SharedMemory/SharedMemoryPublic.h
|
||||
../SharedMemory/b3PluginManager.cpp
|
||||
../SharedMemory/b3RobotSimulatorClientAPI_NoGUI.cpp
|
||||
../SharedMemory/b3RobotSimulatorClientAPI_NoGUI.h
|
||||
../SharedMemory/b3RobotSimulatorClientAPI_NoDirect.cpp
|
||||
../SharedMemory/b3RobotSimulatorClientAPI_NoDirect.h
|
||||
../RobotSimulator/b3RobotSimulatorClientAPI.cpp
|
||||
../RobotSimulator/b3RobotSimulatorClientAPI.h
|
||||
../BasicDemo/BasicExample.cpp
|
||||
../BasicDemo/BasicExample.h
|
||||
../InverseDynamics/InverseDynamicsExample.cpp
|
||||
|
|
@ -161,26 +216,21 @@ SET(BulletExampleBrowser_SRCS
|
|||
../InverseKinematics/InverseKinematicsExample.h
|
||||
../ForkLift/ForkLiftDemo.cpp
|
||||
../ForkLift/ForkLiftDemo.h
|
||||
../MultiThreadedDemo/MultiThreadedDemo.cpp
|
||||
../MultiThreadedDemo/MultiThreadedDemo.h
|
||||
../MultiThreadedDemo/CommonRigidBodyMTBase.cpp
|
||||
../MultiThreadedDemo/CommonRigidBodyMTBase.h
|
||||
../Heightfield/HeightfieldExample.cpp
|
||||
../Heightfield/HeightfieldExample.h
|
||||
../Tutorial/Tutorial.cpp
|
||||
../Tutorial/Tutorial.h
|
||||
../Tutorial/Dof6ConstraintTutorial.cpp
|
||||
../Tutorial/Dof6ConstraintTutorial.h
|
||||
../ExtendedTutorials/SimpleBox.cpp
|
||||
../ExtendedTutorials/SimpleBox.h
|
||||
../ExtendedTutorials/MultipleBoxes.cpp
|
||||
../ExtendedTutorials/MultipleBoxes.h
|
||||
../ExtendedTutorials/SimpleCloth.cpp
|
||||
../ExtendedTutorials/SimpleCloth.h
|
||||
../ExtendedTutorials/SimpleJoint.cpp
|
||||
../ExtendedTutorials/SimpleJoint.h
|
||||
../ExtendedTutorials/NewtonsCradle.cpp
|
||||
../ExtendedTutorials/NewtonsCradle.h
|
||||
../Evolution/NN3DWalkers.cpp
|
||||
../Evolution/NN3DWalkers.h
|
||||
../Evolution/NN3DWalkersTimeWarpBase.h
|
||||
../ExtendedTutorials/NewtonsRopeCradle.cpp
|
||||
../ExtendedTutorials/NewtonsRopeCradle.h
|
||||
../ExtendedTutorials/InclinedPlane.cpp
|
||||
../ExtendedTutorials/InclinedPlane.h
|
||||
../ExtendedTutorials/MultiPendulum.cpp
|
||||
../ExtendedTutorials/MultiPendulum.h
|
||||
../Collision/CollisionSdkC_Api.cpp
|
||||
../Collision/CollisionSdkC_Api.h
|
||||
../Collision/CollisionTutorialBullet2.cpp
|
||||
|
|
@ -220,8 +270,6 @@ SET(BulletExampleBrowser_SRCS
|
|||
|
||||
../RoboticsLearning/GripperGraspExample.cpp
|
||||
../RoboticsLearning/GripperGraspExample.h
|
||||
../RoboticsLearning/b3RobotSimAPI.cpp
|
||||
../RoboticsLearning/b3RobotSimAPI.h
|
||||
../RoboticsLearning/R2D2GraspExample.cpp
|
||||
../RoboticsLearning/R2D2GraspExample.h
|
||||
../RoboticsLearning/KukaGraspExample.cpp
|
||||
|
|
@ -244,6 +292,7 @@ SET(BulletExampleBrowser_SRCS
|
|||
../Importers/ImportMeshUtility/b3ImportMeshUtility.cpp
|
||||
../Importers/ImportMeshUtility/b3ImportMeshUtility.h
|
||||
../../Extras/Serialize/BulletWorldImporter/btWorldImporter.cpp
|
||||
../../Extras/Serialize/BulletWorldImporter/btMultiBodyWorldImporter.cpp
|
||||
../../Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.cpp
|
||||
../../Extras/Serialize/BulletFileLoader/bChunk.cpp
|
||||
../../Extras/Serialize/BulletFileLoader/bFile.cpp
|
||||
|
|
@ -265,6 +314,11 @@ SET(BulletExampleBrowser_SRCS
|
|||
../Importers/ImportURDFDemo/ImportURDFSetup.h
|
||||
../Importers/ImportURDFDemo/URDF2Bullet.h
|
||||
../Importers/ImportURDFDemo/urdf_samples.h
|
||||
../Importers/ImportURDFDemo/urdf_samples.h
|
||||
../Importers/ImportMJCFDemo/BulletMJCFImporter.cpp
|
||||
../Importers/ImportMJCFDemo/BulletMJCFImporter.h
|
||||
../Importers/ImportMJCFDemo/ImportMJCFSetup.cpp
|
||||
../Importers/ImportMJCFDemo/ImportMJCFSetup.h
|
||||
../Importers/ImportBsp/BspConverter.cpp
|
||||
../Importers/ImportBsp/BspLoader.cpp
|
||||
../Importers/ImportBsp/ImportBspExample.cpp
|
||||
|
|
@ -280,6 +334,8 @@ SET(BulletExampleBrowser_SRCS
|
|||
../Importers/ImportURDFDemo/MyMultiBodyCreator.cpp
|
||||
../Importers/ImportURDFDemo/MyMultiBodyCreator.h
|
||||
../Importers/ImportURDFDemo/UrdfParser.cpp
|
||||
../Utils/RobotLoggingUtil.cpp
|
||||
../Utils/RobotLoggingUtil.h
|
||||
../Importers/ImportURDFDemo/urdfStringSplit.cpp
|
||||
../Importers/ImportURDFDemo/urdfStringSplit.h
|
||||
../Importers/ImportURDFDemo/BulletUrdfImporter.cpp
|
||||
|
|
@ -296,10 +352,62 @@ SET(BulletExampleBrowser_SRCS
|
|||
../MultiBody/TestJointTorqueSetup.h
|
||||
../MultiBody/InvertedPendulumPDControl.cpp
|
||||
../MultiBody/InvertedPendulumPDControl.h
|
||||
../MultiBody/MultiBodyConstraintFeedback.cpp
|
||||
../MultiBody/MultiBodyConstraintFeedback.cpp
|
||||
../MultiBody/KinematicMultiBodyExample.cpp
|
||||
../SoftDemo/SoftDemo.cpp
|
||||
../SoftDemo/SoftDemo.h
|
||||
../DeformableDemo/DeformableContact.cpp
|
||||
../DeformableDemo/DeformableContact.h
|
||||
../DeformableDemo/GraspDeformable.cpp
|
||||
../DeformableDemo/GraspDeformable.h
|
||||
../DeformableDemo/Pinch.cpp
|
||||
../DeformableDemo/Pinch.h
|
||||
../DeformableDemo/DeformableSelfCollision.cpp
|
||||
../DeformableDemo/DeformableSelfCollision.h
|
||||
../DeformableDemo/PinchFriction.cpp
|
||||
../DeformableDemo/PinchFriction.h
|
||||
../DeformableDemo/ClothFriction.cpp
|
||||
../DeformableDemo/ClothFriction.h
|
||||
../DeformableDemo/DeformableMultibody.cpp
|
||||
../DeformableDemo/DeformableMultibody.h
|
||||
../DeformableDemo/DeformableRigid.cpp
|
||||
../DeformableDemo/DeformableRigid.h
|
||||
../DeformableDemo/SplitImpulse.cpp
|
||||
../DeformableDemo/SplitImpulse.h
|
||||
../DeformableDemo/VolumetricDeformable.cpp
|
||||
../DeformableDemo/VolumetricDeformable.h
|
||||
../DeformableDemo/Collide.cpp
|
||||
../DeformableDemo/Collide.h
|
||||
../DeformableDemo/LargeDeformation.cpp
|
||||
../DeformableDemo/LoadDeformed.h
|
||||
../DeformableDemo/LoadDeformed.cpp
|
||||
../DeformableDemo/LargeDeformation.h
|
||||
../DeformableDemo/DeformableClothAnchor.cpp
|
||||
../DeformableDemo/DeformableClothAnchor.h
|
||||
../DeformableDemo/MultibodyClothAnchor.cpp
|
||||
../DeformableDemo/MultibodyClothAnchor.h
|
||||
../MultiBody/MultiDofDemo.cpp
|
||||
../MultiBody/MultiDofDemo.h
|
||||
../RigidBody/RigidBodySoftContact.cpp
|
||||
../RigidBody/KinematicRigidBodyExample.cpp
|
||||
../ReducedDeformableDemo/ConservationTest.cpp
|
||||
../ReducedDeformableDemo/ConservationTest.h
|
||||
../ReducedDeformableDemo/Springboard.cpp
|
||||
../ReducedDeformableDemo/Springboard.h
|
||||
../ReducedDeformableDemo/ModeVisualizer.cpp
|
||||
../ReducedDeformableDemo/ModeVisualizer.h
|
||||
../ReducedDeformableDemo/FreeFall.cpp
|
||||
../ReducedDeformableDemo/FreeFall.h
|
||||
../ReducedDeformableDemo/FrictionSlope.cpp
|
||||
../ReducedDeformableDemo/FrictionSlope.h
|
||||
../ReducedDeformableDemo/ReducedCollide.cpp
|
||||
../ReducedDeformableDemo/ReducedCollide.h
|
||||
../ReducedDeformableDemo/ReducedGrasp.cpp
|
||||
../ReducedDeformableDemo/ReducedGrasp.h
|
||||
../ReducedDeformableDemo/ReducedBenchmark.cpp
|
||||
../ReducedDeformableDemo/ReducedBenchmark.h
|
||||
../ReducedDeformableDemo/ReducedMotorGrasp.cpp
|
||||
../ReducedDeformableDemo/ReducedMotorGrasp.h
|
||||
../Constraints/TestHingeTorque.cpp
|
||||
../Constraints/TestHingeTorque.h
|
||||
../Constraints/ConstraintDemo.cpp
|
||||
|
|
@ -312,17 +420,10 @@ SET(BulletExampleBrowser_SRCS
|
|||
|
||||
../ThirdPartyLibs/stb_image/stb_image.cpp
|
||||
../ThirdPartyLibs/stb_image/stb_image.h
|
||||
|
||||
../ThirdPartyLibs/stb_image/stb_image_write.cpp
|
||||
../ThirdPartyLibs/Wavefront/tiny_obj_loader.cpp
|
||||
../ThirdPartyLibs/tinyxml/tinystr.cpp
|
||||
../ThirdPartyLibs/tinyxml/tinyxml.cpp
|
||||
../ThirdPartyLibs/tinyxml/tinyxmlerror.cpp
|
||||
../ThirdPartyLibs/tinyxml/tinyxmlparser.cpp
|
||||
|
||||
../ThirdPartyLibs/tinyxml/tinystr.cpp
|
||||
../ThirdPartyLibs/tinyxml/tinyxml.cpp
|
||||
../ThirdPartyLibs/tinyxml/tinyxmlerror.cpp
|
||||
../ThirdPartyLibs/tinyxml/tinyxmlparser.cpp
|
||||
|
||||
../ThirdPartyLibs/tinyxml2/tinyxml2.cpp
|
||||
InProcessExampleBrowser.cpp
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/build3/bullet.rc
|
||||
)
|
||||
|
|
@ -345,9 +446,26 @@ ADD_CUSTOM_COMMAND(
|
|||
COMMAND ${CMAKE_COMMAND} ARGS -E copy_directory ${BULLET_PHYSICS_SOURCE_DIR}/data ${PROJECT_BINARY_DIR}/data
|
||||
)
|
||||
|
||||
IF (BULLET2_USE_TBB_MULTITHREADING AND WIN32)
|
||||
# add a post build command to copy some dlls to the executable directory
|
||||
set(TBB_VC_VER "vc12")
|
||||
set(TBB_VC_ARCH "ia32")
|
||||
# assume 32-bit build in VC12 for now
|
||||
# checks can be added here at a later time
|
||||
ADD_CUSTOM_COMMAND(TARGET App_ExampleBrowser POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${BULLET2_TBB_INCLUDE_DIR}/../bin/${TBB_VC_ARCH}/${TBB_VC_VER}/tbb.dll"
|
||||
$<TARGET_FILE_DIR:App_ExampleBrowser>)
|
||||
ADD_CUSTOM_COMMAND(TARGET App_ExampleBrowser POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${BULLET2_TBB_INCLUDE_DIR}/../bin/${TBB_VC_ARCH}/${TBB_VC_VER}/tbbmalloc.dll"
|
||||
$<TARGET_FILE_DIR:App_ExampleBrowser>)
|
||||
ENDIF (BULLET2_USE_TBB_MULTITHREADING AND WIN32)
|
||||
|
||||
|
||||
IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES)
|
||||
SET_TARGET_PROPERTIES(App_ExampleBrowser PROPERTIES DEBUG_POSTFIX "_Debug")
|
||||
SET_TARGET_PROPERTIES(App_ExampleBrowser PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel")
|
||||
SET_TARGET_PROPERTIES(App_ExampleBrowser PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo")
|
||||
ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES)
|
||||
|
||||
|
|
|
|||
|
|
@ -2,12 +2,13 @@
|
|||
#include "CollisionShape2TriangleMesh.h"
|
||||
|
||||
#include "btBulletCollisionCommon.h"
|
||||
#include "BulletCollision/CollisionShapes/btShapeHull.h"//to create a tesselation of a generic btConvexShape
|
||||
#include "BulletCollision/CollisionShapes/btShapeHull.h" //to create a tesselation of a generic btConvexShape
|
||||
#include "BulletCollision/CollisionShapes/btConvexPolyhedron.h"
|
||||
|
||||
void CollisionShape2TriangleMesh(btCollisionShape* collisionShape, const btTransform& parentTransform, btAlignedObjectArray<btVector3>& vertexPositions, btAlignedObjectArray<btVector3>& vertexNormals, btAlignedObjectArray<int>& indicesOut)
|
||||
|
||||
{
|
||||
//todo: support all collision shape types
|
||||
//todo: support all collision shape types
|
||||
switch (collisionShape->getShapeType())
|
||||
{
|
||||
case SOFTBODY_SHAPE_PROXYTYPE:
|
||||
|
|
@ -22,31 +23,30 @@ void CollisionShape2TriangleMesh(btCollisionShape* collisionShape, const btTrans
|
|||
btScalar planeConst = staticPlaneShape->getPlaneConstant();
|
||||
const btVector3& planeNormal = staticPlaneShape->getPlaneNormal();
|
||||
btVector3 planeOrigin = planeNormal * planeConst;
|
||||
btVector3 vec0,vec1;
|
||||
btPlaneSpace1(planeNormal,vec0,vec1);
|
||||
btVector3 vec0, vec1;
|
||||
btPlaneSpace1(planeNormal, vec0, vec1);
|
||||
btScalar vecLen = 100.f;
|
||||
btVector3 verts[4];
|
||||
|
||||
verts[0] = planeOrigin + vec0*vecLen + vec1*vecLen;
|
||||
verts[1] = planeOrigin - vec0*vecLen + vec1*vecLen;
|
||||
verts[2] = planeOrigin - vec0*vecLen - vec1*vecLen;
|
||||
verts[3] = planeOrigin + vec0*vecLen - vec1*vecLen;
|
||||
|
||||
verts[0] = planeOrigin + vec0 * vecLen + vec1 * vecLen;
|
||||
verts[1] = planeOrigin - vec0 * vecLen + vec1 * vecLen;
|
||||
verts[2] = planeOrigin - vec0 * vecLen - vec1 * vecLen;
|
||||
verts[3] = planeOrigin + vec0 * vecLen - vec1 * vecLen;
|
||||
|
||||
int startIndex = vertexPositions.size();
|
||||
indicesOut.push_back(startIndex+0);
|
||||
indicesOut.push_back(startIndex+1);
|
||||
indicesOut.push_back(startIndex+2);
|
||||
indicesOut.push_back(startIndex+0);
|
||||
indicesOut.push_back(startIndex+2);
|
||||
indicesOut.push_back(startIndex+3);
|
||||
indicesOut.push_back(startIndex + 0);
|
||||
indicesOut.push_back(startIndex + 1);
|
||||
indicesOut.push_back(startIndex + 2);
|
||||
indicesOut.push_back(startIndex + 0);
|
||||
indicesOut.push_back(startIndex + 2);
|
||||
indicesOut.push_back(startIndex + 3);
|
||||
|
||||
btVector3 triNormal = parentTransform.getBasis()*planeNormal;
|
||||
|
||||
btVector3 triNormal = parentTransform.getBasis() * planeNormal;
|
||||
|
||||
for (int i=0;i<4;i++)
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
btVector3 vtxPos;
|
||||
btVector3 pos =parentTransform*verts[i];
|
||||
btVector3 pos = parentTransform * verts[i];
|
||||
vertexPositions.push_back(pos);
|
||||
vertexNormals.push_back(triNormal);
|
||||
}
|
||||
|
|
@ -54,53 +54,55 @@ void CollisionShape2TriangleMesh(btCollisionShape* collisionShape, const btTrans
|
|||
}
|
||||
case TRIANGLE_MESH_SHAPE_PROXYTYPE:
|
||||
{
|
||||
|
||||
|
||||
btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*) collisionShape;
|
||||
btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)collisionShape;
|
||||
btVector3 trimeshScaling = trimesh->getLocalScaling();
|
||||
btStridingMeshInterface* meshInterface = trimesh->getMeshInterface();
|
||||
btAlignedObjectArray<btVector3> vertices;
|
||||
btAlignedObjectArray<int> indices;
|
||||
|
||||
for (int partId=0;partId<meshInterface->getNumSubParts();partId++)
|
||||
|
||||
for (int partId = 0; partId < meshInterface->getNumSubParts(); partId++)
|
||||
{
|
||||
|
||||
const unsigned char *vertexbase = 0;
|
||||
const unsigned char* vertexbase = 0;
|
||||
int numverts = 0;
|
||||
PHY_ScalarType type = PHY_INTEGER;
|
||||
int stride = 0;
|
||||
const unsigned char *indexbase = 0;
|
||||
const unsigned char* indexbase = 0;
|
||||
int indexstride = 0;
|
||||
int numfaces = 0;
|
||||
PHY_ScalarType indicestype = PHY_INTEGER;
|
||||
//PHY_ScalarType indexType=0;
|
||||
|
||||
|
||||
btVector3 triangleVerts[3];
|
||||
meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase,numverts, type,stride,&indexbase,indexstride,numfaces,indicestype,partId);
|
||||
btVector3 aabbMin,aabbMax;
|
||||
|
||||
for (int triangleIndex = 0 ; triangleIndex < numfaces;triangleIndex++)
|
||||
meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase, numverts, type, stride, &indexbase, indexstride, numfaces, indicestype, partId);
|
||||
btVector3 aabbMin, aabbMax;
|
||||
|
||||
for (int triangleIndex = 0; triangleIndex < numfaces; triangleIndex++)
|
||||
{
|
||||
unsigned int* gfxbase = (unsigned int*)(indexbase+triangleIndex*indexstride);
|
||||
|
||||
for (int j=2;j>=0;j--)
|
||||
unsigned int* gfxbase = (unsigned int*)(indexbase + triangleIndex * indexstride);
|
||||
|
||||
for (int j = 2; j >= 0; j--)
|
||||
{
|
||||
|
||||
int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
|
||||
int graphicsindex;
|
||||
switch (indicestype) {
|
||||
case PHY_INTEGER: graphicsindex = gfxbase[j]; break;
|
||||
case PHY_SHORT: graphicsindex = ((unsigned short*)gfxbase)[j]; break;
|
||||
case PHY_UCHAR: graphicsindex = ((unsigned char*)gfxbase)[j]; break;
|
||||
default: btAssert(0);
|
||||
}
|
||||
if (type == PHY_FLOAT)
|
||||
{
|
||||
float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
|
||||
float* graphicsbase = (float*)(vertexbase + graphicsindex * stride);
|
||||
triangleVerts[j] = btVector3(
|
||||
graphicsbase[0]*trimeshScaling.getX(),
|
||||
graphicsbase[1]*trimeshScaling.getY(),
|
||||
graphicsbase[2]*trimeshScaling.getZ());
|
||||
graphicsbase[0] * trimeshScaling.getX(),
|
||||
graphicsbase[1] * trimeshScaling.getY(),
|
||||
graphicsbase[2] * trimeshScaling.getZ());
|
||||
}
|
||||
else
|
||||
{
|
||||
double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
|
||||
triangleVerts[j] = btVector3( btScalar(graphicsbase[0]*trimeshScaling.getX()),
|
||||
btScalar(graphicsbase[1]*trimeshScaling.getY()),
|
||||
btScalar(graphicsbase[2]*trimeshScaling.getZ()));
|
||||
double* graphicsbase = (double*)(vertexbase + graphicsindex * stride);
|
||||
triangleVerts[j] = btVector3(btScalar(graphicsbase[0] * trimeshScaling.getX()),
|
||||
btScalar(graphicsbase[1] * trimeshScaling.getY()),
|
||||
btScalar(graphicsbase[2] * trimeshScaling.getZ()));
|
||||
}
|
||||
}
|
||||
indices.push_back(vertices.size());
|
||||
|
|
@ -110,23 +112,24 @@ void CollisionShape2TriangleMesh(btCollisionShape* collisionShape, const btTrans
|
|||
indices.push_back(vertices.size());
|
||||
vertices.push_back(triangleVerts[2]);
|
||||
|
||||
btVector3 triNormal = (triangleVerts[1]-triangleVerts[0]).cross(triangleVerts[2]-triangleVerts[0]);
|
||||
triNormal.normalize();
|
||||
btVector3 triNormal = (triangleVerts[1] - triangleVerts[0]).cross(triangleVerts[2] - triangleVerts[0]);
|
||||
btScalar dot = triNormal.dot(triNormal);
|
||||
|
||||
for (int v=0;v<3;v++)
|
||||
//cull degenerate triangles
|
||||
if (dot >= SIMD_EPSILON * SIMD_EPSILON)
|
||||
{
|
||||
|
||||
btVector3 pos =parentTransform*triangleVerts[v];
|
||||
indicesOut.push_back(vertexPositions.size());
|
||||
vertexPositions.push_back(pos);
|
||||
vertexNormals.push_back(triNormal);
|
||||
|
||||
triNormal /= btSqrt(dot);
|
||||
for (int v = 0; v < 3; v++)
|
||||
{
|
||||
btVector3 pos = parentTransform * triangleVerts[v];
|
||||
indicesOut.push_back(vertexPositions.size());
|
||||
vertexPositions.push_back(pos);
|
||||
vertexNormals.push_back(triNormal);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
@ -135,59 +138,93 @@ void CollisionShape2TriangleMesh(btCollisionShape* collisionShape, const btTrans
|
|||
{
|
||||
btConvexShape* convex = (btConvexShape*)collisionShape;
|
||||
{
|
||||
btShapeHull* hull = new btShapeHull(convex);
|
||||
hull->buildHull(0.0);
|
||||
|
||||
const btConvexPolyhedron* pol = 0;
|
||||
if (convex->isPolyhedral())
|
||||
{
|
||||
//int strideInBytes = 9*sizeof(float);
|
||||
//int numVertices = hull->numVertices();
|
||||
//int numIndices =hull->numIndices();
|
||||
btPolyhedralConvexShape* poly = (btPolyhedralConvexShape*)convex;
|
||||
pol = poly->getConvexPolyhedron();
|
||||
}
|
||||
|
||||
for (int t=0;t<hull->numTriangles();t++)
|
||||
if (pol)
|
||||
{
|
||||
int baseIndex = vertexPositions.size();
|
||||
for (int v = 0; v < pol->m_vertices.size(); v++)
|
||||
{
|
||||
|
||||
btVector3 triNormal;
|
||||
|
||||
int index0 = hull->getIndexPointer()[t*3+0];
|
||||
int index1 = hull->getIndexPointer()[t*3+1];
|
||||
int index2 = hull->getIndexPointer()[t*3+2];
|
||||
btVector3 pos0 =parentTransform*hull->getVertexPointer()[index0];
|
||||
btVector3 pos1 =parentTransform*hull->getVertexPointer()[index1];
|
||||
btVector3 pos2 =parentTransform*hull->getVertexPointer()[index2];
|
||||
triNormal = (pos1-pos0).cross(pos2-pos0);
|
||||
triNormal.normalize();
|
||||
|
||||
for (int v=0;v<3;v++)
|
||||
vertexPositions.push_back(pol->m_vertices[v]);
|
||||
btVector3 norm = pol->m_vertices[v];
|
||||
norm.safeNormalize();
|
||||
vertexNormals.push_back(norm);
|
||||
}
|
||||
for (int f = 0; f < pol->m_faces.size(); f++)
|
||||
{
|
||||
for (int ii = 2; ii < pol->m_faces[f].m_indices.size(); ii++)
|
||||
{
|
||||
int index = hull->getIndexPointer()[t*3+v];
|
||||
btVector3 pos =parentTransform*hull->getVertexPointer()[index];
|
||||
indicesOut.push_back(vertexPositions.size());
|
||||
vertexPositions.push_back(pos);
|
||||
vertexNormals.push_back(triNormal);
|
||||
indicesOut.push_back(baseIndex+pol->m_faces[f].m_indices[0]);
|
||||
indicesOut.push_back(baseIndex + pol->m_faces[f].m_indices[ii - 1]);
|
||||
indicesOut.push_back(baseIndex + pol->m_faces[f].m_indices[ii]);
|
||||
}
|
||||
}
|
||||
}
|
||||
delete hull;
|
||||
else
|
||||
{
|
||||
btShapeHull* hull = new btShapeHull(convex);
|
||||
hull->buildHull(0.0, 1);
|
||||
|
||||
{
|
||||
//int strideInBytes = 9*sizeof(float);
|
||||
//int numVertices = hull->numVertices();
|
||||
//int numIndices =hull->numIndices();
|
||||
|
||||
for (int t = 0; t < hull->numTriangles(); t++)
|
||||
{
|
||||
btVector3 triNormal;
|
||||
|
||||
int index0 = hull->getIndexPointer()[t * 3 + 0];
|
||||
int index1 = hull->getIndexPointer()[t * 3 + 1];
|
||||
int index2 = hull->getIndexPointer()[t * 3 + 2];
|
||||
btVector3 pos0 = parentTransform * hull->getVertexPointer()[index0];
|
||||
btVector3 pos1 = parentTransform * hull->getVertexPointer()[index1];
|
||||
btVector3 pos2 = parentTransform * hull->getVertexPointer()[index2];
|
||||
triNormal = (pos1 - pos0).cross(pos2 - pos0);
|
||||
triNormal.safeNormalize();
|
||||
|
||||
for (int v = 0; v < 3; v++)
|
||||
{
|
||||
int index = hull->getIndexPointer()[t * 3 + v];
|
||||
btVector3 pos = parentTransform * hull->getVertexPointer()[index];
|
||||
indicesOut.push_back(vertexPositions.size());
|
||||
vertexPositions.push_back(pos);
|
||||
vertexNormals.push_back(triNormal);
|
||||
}
|
||||
}
|
||||
}
|
||||
delete hull;
|
||||
}
|
||||
}
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
if (collisionShape->isCompound())
|
||||
{
|
||||
btCompoundShape* compound = (btCompoundShape*) collisionShape;
|
||||
for (int i=0;i<compound->getNumChildShapes();i++)
|
||||
btCompoundShape* compound = (btCompoundShape*)collisionShape;
|
||||
for (int i = 0; i < compound->getNumChildShapes(); i++)
|
||||
{
|
||||
|
||||
btTransform childWorldTrans = parentTransform * compound->getChildTransform(i);
|
||||
CollisionShape2TriangleMesh(compound->getChildShape(i),childWorldTrans,vertexPositions,vertexNormals,indicesOut);
|
||||
CollisionShape2TriangleMesh(compound->getChildShape(i), childWorldTrans, vertexPositions, vertexNormals, indicesOut);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (collisionShape->getShapeType() == SDF_SHAPE_PROXYTYPE)
|
||||
{
|
||||
//not yet
|
||||
}
|
||||
else
|
||||
{
|
||||
btAssert(0);
|
||||
}
|
||||
} else
|
||||
{
|
||||
btAssert(0);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,4 +7,4 @@ class btCollisionShape;
|
|||
|
||||
void CollisionShape2TriangleMesh(btCollisionShape* collisionShape, const btTransform& parentTransform, btAlignedObjectArray<btVector3>& vertexPositions, btAlignedObjectArray<btVector3>& vertexNormals, btAlignedObjectArray<int>& indicesOut);
|
||||
|
||||
#endif //COLLISION_SHAPE_2_GRAPHICS_H
|
||||
#endif //COLLISION_SHAPE_2_GRAPHICS_H
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
class EmptyBrowser : public ExampleBrowserInterface
|
||||
{
|
||||
public:
|
||||
|
||||
EmptyExample m_emptyExample;
|
||||
|
||||
virtual CommonExampleInterface* getCurrentExample()
|
||||
|
|
@ -29,10 +28,18 @@ public:
|
|||
m_emptyExample.stepSimulation(deltaTime);
|
||||
}
|
||||
|
||||
virtual void updateGraphics()
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool requestedExit()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void setSharedMemoryInterface(class SharedMemoryInterface* sharedMem)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#endif //EMPTY_BROWSER
|
||||
#endif //EMPTY_BROWSER
|
||||
|
|
|
|||
|
|
@ -6,27 +6,22 @@
|
|||
class EmptyExample : public CommonExampleInterface
|
||||
{
|
||||
public:
|
||||
|
||||
EmptyExample() {}
|
||||
virtual ~EmptyExample(){}
|
||||
virtual ~EmptyExample() {}
|
||||
|
||||
static CommonExampleInterface* CreateFunc(struct CommonExampleOptions& /* unusedOptions*/)
|
||||
{
|
||||
return new EmptyExample;
|
||||
}
|
||||
|
||||
virtual void initPhysics(){}
|
||||
virtual void exitPhysics(){}
|
||||
virtual void stepSimulation(float deltaTime){}
|
||||
virtual void renderScene(){}
|
||||
virtual void physicsDebugDraw(int 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;}
|
||||
|
||||
virtual void initPhysics() {}
|
||||
virtual void exitPhysics() {}
|
||||
virtual void stepSimulation(float deltaTime) {}
|
||||
virtual void renderScene() {}
|
||||
virtual void physicsDebugDraw(int 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; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //EMPTY_EXAMPLE_H
|
||||
|
||||
#endif //EMPTY_EXAMPLE_H
|
||||
|
|
|
|||
|
|
@ -5,19 +5,20 @@
|
|||
|
||||
class ExampleBrowserInterface
|
||||
{
|
||||
public:
|
||||
|
||||
public:
|
||||
virtual ~ExampleBrowserInterface() {}
|
||||
|
||||
virtual CommonExampleInterface* getCurrentExample() = 0;
|
||||
|
||||
virtual bool init(int argc, char* argv[])=0;
|
||||
|
||||
virtual void update(float deltaTime)=0;
|
||||
virtual bool init(int argc, char* argv[]) = 0;
|
||||
|
||||
virtual bool requestedExit()=0;
|
||||
virtual void update(float deltaTime) = 0;
|
||||
|
||||
virtual void updateGraphics() = 0;
|
||||
|
||||
virtual bool requestedExit() = 0;
|
||||
|
||||
virtual void setSharedMemoryInterface(class SharedMemoryInterface* sharedMem) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //EXAMPLE_BROWSER_GUI_H
|
||||
#endif //EXAMPLE_BROWSER_GUI_H
|
||||
|
|
@ -2,12 +2,17 @@
|
|||
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
#include "EmptyExample.h"
|
||||
#include "../Heightfield/HeightfieldExample.h"
|
||||
#include "../RenderingExamples/RenderInstancingDemo.h"
|
||||
#include "../RenderingExamples/CoordinateSystemDemo.h"
|
||||
#include "../RenderingExamples/RaytracerSetup.h"
|
||||
#include "../RenderingExamples/TinyRendererSetup.h"
|
||||
#include "../RenderingExamples/DynamicTexturedCubeDemo.h"
|
||||
#include "../SharedMemory/GraphicsServerExample.h"
|
||||
#include "../SharedMemory/GraphicsClientExample.h"
|
||||
|
||||
#include "../ForkLift/ForkLiftDemo.h"
|
||||
#include "../MultiThreadedDemo/MultiThreadedDemo.h"
|
||||
#include "../BasicDemo/BasicExample.h"
|
||||
#include "../Planar2D/Planar2D.h"
|
||||
#include "../Benchmarks/BenchmarkDemo.h"
|
||||
|
|
@ -17,6 +22,7 @@
|
|||
#include "../Importers/ImportSTLDemo/ImportSTLSetup.h"
|
||||
#include "../Importers/ImportURDFDemo/ImportURDFSetup.h"
|
||||
#include "../Importers/ImportSDFDemo/ImportSDFSetup.h"
|
||||
#include "../Importers/ImportMJCFDemo/ImportMJCFSetup.h"
|
||||
#include "../Collision/CollisionTutorialBullet2.h"
|
||||
#include "../GyroscopicDemo/GyroscopicSetup.h"
|
||||
#include "../Constraints/Dof6Spring2Setup.h"
|
||||
|
|
@ -27,7 +33,10 @@
|
|||
#include "../MultiBody/MultiBodyConstraintFeedback.h"
|
||||
#include "../MultiBody/MultiDofDemo.h"
|
||||
#include "../MultiBody/InvertedPendulumPDControl.h"
|
||||
#include "../MultiBody/KinematicMultiBodyExample.h"
|
||||
|
||||
#include "../RigidBody/RigidBodySoftContact.h"
|
||||
#include "../RigidBody/KinematicRigidBodyExample.h"
|
||||
#include "../VoronoiFracture/VoronoiFractureDemo.h"
|
||||
#include "../SoftDemo/SoftDemo.h"
|
||||
#include "../Constraints/ConstraintDemo.h"
|
||||
|
|
@ -37,6 +46,22 @@
|
|||
#include "../FractureDemo/FractureDemo.h"
|
||||
#include "../DynamicControlDemo/MotorDemo.h"
|
||||
#include "../RollingFrictionDemo/RollingFrictionDemo.h"
|
||||
#include "../DeformableDemo/DeformableRigid.h"
|
||||
#include "../DeformableDemo/SplitImpulse.h"
|
||||
#include "../DeformableDemo/ClothFriction.h"
|
||||
#include "../DeformableDemo/Pinch.h"
|
||||
#include "../DeformableDemo/DeformableSelfCollision.h"
|
||||
#include "../DeformableDemo/PinchFriction.h"
|
||||
#include "../DeformableDemo/DeformableMultibody.h"
|
||||
#include "../DeformableDemo/VolumetricDeformable.h"
|
||||
#include "../DeformableDemo/LargeDeformation.h"
|
||||
#include "../DeformableDemo/LoadDeformed.h"
|
||||
#include "../DeformableDemo/Collide.h"
|
||||
#include "../DeformableDemo/GraspDeformable.h"
|
||||
#include "../DeformableDemo/DeformableContact.h"
|
||||
#include "../DeformableDemo/DeformableClothAnchor.h"
|
||||
#include "../DeformableDemo/MultibodyClothAnchor.h"
|
||||
#include "../SharedMemory/PhysicsServerExampleBullet2.h"
|
||||
#include "../SharedMemory/PhysicsServerExample.h"
|
||||
#include "../SharedMemory/PhysicsClientExample.h"
|
||||
#include "../Constraints/TestHingeTorque.h"
|
||||
|
|
@ -48,8 +73,21 @@
|
|||
#include "../RoboticsLearning/R2D2GraspExample.h"
|
||||
#include "../RoboticsLearning/KukaGraspExample.h"
|
||||
#include "../RoboticsLearning/GripperGraspExample.h"
|
||||
#include "../ReducedDeformableDemo/ConservationTest.h"
|
||||
#include "../ReducedDeformableDemo/ModeVisualizer.h"
|
||||
#include "../ReducedDeformableDemo/Springboard.h"
|
||||
#include "../ReducedDeformableDemo/FreeFall.h"
|
||||
#include "../ReducedDeformableDemo/FrictionSlope.h"
|
||||
#include "../ReducedDeformableDemo/ReducedCollide.h"
|
||||
#include "../ReducedDeformableDemo/ReducedGrasp.h"
|
||||
#include "../ReducedDeformableDemo/ReducedMotorGrasp.h"
|
||||
#include "../ReducedDeformableDemo/ReducedBenchmark.h"
|
||||
#include "../InverseKinematics/InverseKinematicsExample.h"
|
||||
|
||||
#ifdef B3_ENABLE_TINY_AUDIO
|
||||
#include "../TinyAudio/TinyAudioExample.h"
|
||||
#endif //B3_ENABLE_TINY_AUDIO
|
||||
|
||||
#ifdef ENABLE_LUA
|
||||
#include "../LuaDemo/LuaPhysicsSetup.h"
|
||||
#endif
|
||||
|
|
@ -59,11 +97,12 @@
|
|||
#include "../OpenCL/broadphase/PairBench.h"
|
||||
#include "../OpenCL/rigidbody/GpuConvexScene.h"
|
||||
#endif
|
||||
#endif //B3_USE_CLEW
|
||||
#endif //B3_USE_CLEW
|
||||
|
||||
//Extended Tutorial Includes Added by Mobeen and Benelot
|
||||
#include "../ExtendedTutorials/SimpleBox.h"
|
||||
#include "../ExtendedTutorials/MultipleBoxes.h"
|
||||
#include "../ExtendedTutorials/CompoundBoxes.h"
|
||||
#include "../ExtendedTutorials/SimpleJoint.h"
|
||||
#include "../ExtendedTutorials/SimpleCloth.h"
|
||||
#include "../ExtendedTutorials/Chain.h"
|
||||
|
|
@ -73,263 +112,304 @@
|
|||
#include "../ExtendedTutorials/NewtonsCradle.h"
|
||||
#include "../ExtendedTutorials/NewtonsRopeCradle.h"
|
||||
#include "../ExtendedTutorials/MultiPendulum.h"
|
||||
#include "../Evolution/NN3DWalkers.h"
|
||||
|
||||
struct ExampleEntry
|
||||
{
|
||||
int m_menuLevel;
|
||||
const char* m_name;
|
||||
const char* m_description;
|
||||
CommonExampleInterface::CreateFunc* m_createFunc;
|
||||
int m_option;
|
||||
int m_menuLevel;
|
||||
const char* m_name;
|
||||
const char* m_description;
|
||||
CommonExampleInterface::CreateFunc* m_createFunc;
|
||||
int m_option;
|
||||
|
||||
ExampleEntry(int menuLevel, const char* name)
|
||||
:m_menuLevel(menuLevel), m_name(name), m_description(0), m_createFunc(0), m_option(0)
|
||||
: m_menuLevel(menuLevel), m_name(name), m_description(0), m_createFunc(0), m_option(0)
|
||||
{
|
||||
}
|
||||
|
||||
ExampleEntry(int menuLevel, const char* name,const char* description, CommonExampleInterface::CreateFunc* createFunc, int option=0)
|
||||
:m_menuLevel(menuLevel), m_name(name), m_description(description), m_createFunc(createFunc), m_option(option)
|
||||
ExampleEntry(int menuLevel, const char* name, const char* description, CommonExampleInterface::CreateFunc* createFunc, int option = 0)
|
||||
: m_menuLevel(menuLevel), m_name(name), m_description(description), m_createFunc(createFunc), m_option(option)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
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.",
|
||||
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.",
|
||||
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(1, "Kinematic Body", "Let the user set the transform, the physics engine computes the velocity for one-way contact and friction interaction.", KinematicRigidBodyExampleCreateFunc),
|
||||
|
||||
ExampleEntry(0, "MultiBody"),
|
||||
ExampleEntry(1, "MultiDof", "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),
|
||||
ExampleEntry(1, "Kinematic MultiBody", "Let the user set the transform, the physics engine computes the velocity for one-way contact and friction interaction.", KinematicMultiBodyExampleCreateFunc),
|
||||
|
||||
ExampleEntry(0, "Physics Client-Server"),
|
||||
ExampleEntry(1, "Physics Server", "Create a physics server that communicates with a physics client over shared memory. You can connect to the server using pybullet, a PhysicsClient or a UDP/TCP Bridge.",
|
||||
PhysicsServerCreateFuncBullet2),
|
||||
ExampleEntry(1, "Physics Client (Shared Mem)", "Create a physics client that can communicate with a physics server over shared memory.", PhysicsClientCreateFunc),
|
||||
|
||||
ExampleEntry(1, "Physics Server (Logging)", "Create a physics server that communicates with a physics client over shared memory. It will log all commands to a file.",
|
||||
PhysicsServerCreateFuncBullet2, PHYSICS_SERVER_ENABLE_COMMAND_LOGGING),
|
||||
ExampleEntry(1, "Physics Server (Replay Log)", "Create a physics server that replay a command log from disk.",
|
||||
PhysicsServerCreateFuncBullet2, PHYSICS_SERVER_REPLAY_FROM_COMMAND_LOG),
|
||||
ExampleEntry(1, "Graphics Server", "Create a graphics server.",GraphicsServerCreateFuncBullet),
|
||||
ExampleEntry(1, "Graphics Client", "Create a graphics client.", GraphicsClientCreateFunc),
|
||||
|
||||
//
|
||||
// ExampleEntry(1, "Physics Client (Direct)", "Create a physics client that can communicate with a physics server directly in-process.", PhysicsClientCreateFunc,eCLIENTEXAMPLE_DIRECT),
|
||||
|
||||
|
||||
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,"API"),
|
||||
ExampleEntry(0, "Inverse Kinematics"),
|
||||
ExampleEntry(1, "SDLS", "Selectively Damped Least Squares by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_SDLS),
|
||||
ExampleEntry(1, "DLS", "Damped Least Squares by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_DLS),
|
||||
ExampleEntry(1, "DLS-SVD", "Damped Least Squares with Singular Value Decomposition by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_DLS_SVD),
|
||||
|
||||
ExampleEntry(1,"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.",
|
||||
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.",
|
||||
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),
|
||||
|
||||
|
||||
ExampleEntry(0,"Inverse Dynamics"),
|
||||
ExampleEntry(1,"Inverse Dynamics URDF", "Create a btMultiBody from URDF. Create an inverse MultiBodyTree model from that. Use either decoupled PD control or computed torque control using the inverse model to track joint position targets", InverseDynamicsExampleCreateFunc,BT_ID_LOAD_URDF),
|
||||
ExampleEntry(1,"Inverse Dynamics Prog", "Create a btMultiBody programatically. Create an inverse MultiBodyTree model from that. Use either decoupled PD control or computed torque control using the inverse model to track joint position targets", InverseDynamicsExampleCreateFunc,BT_ID_PROGRAMMATICALLY),
|
||||
|
||||
ExampleEntry(0, "Inverse Kinematics"),
|
||||
ExampleEntry(1, "SDLS", "Selectively Damped Least Squares by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_SDLS),
|
||||
ExampleEntry(1, "DLS", "Damped Least Squares by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_DLS),
|
||||
ExampleEntry(1, "DLS-SVD", "Damped Least Squares with Singular Value Decomposition by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_DLS_SVD),
|
||||
|
||||
|
||||
|
||||
ExampleEntry(1, "Jacobi Transpose", "Jacobi Transpose by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_JACOB_TRANS),
|
||||
ExampleEntry(1, "Jacobi Pseudo Inv", "Jacobi Pseudo Inverse Method by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_PURE_PSEUDO),
|
||||
|
||||
|
||||
ExampleEntry(0,"Tutorial"),
|
||||
ExampleEntry(1,"Constant Velocity","Free moving rigid body, without external or constraint forces", TutorialCreateFunc,TUT_VELOCITY),
|
||||
ExampleEntry(1,"Gravity Acceleration","Motion of a free falling rigid body under constant gravitational acceleration", TutorialCreateFunc,TUT_ACCELERATION),
|
||||
ExampleEntry(1,"Contact Computation","Discrete Collision Detection for sphere-sphere", TutorialCreateFunc,TUT_COLLISION),
|
||||
ExampleEntry(1,"Solve Contact Constraint","Compute and apply the impulses needed to satisfy non-penetrating contact constraints", TutorialCreateFunc,TUT_SOLVE_CONTACT_CONSTRAINT),
|
||||
ExampleEntry(1,"Spring constraint","A rigid body with a spring constraint attached", Dof6ConstraintTutorialCreateFunc,0),
|
||||
|
||||
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),
|
||||
ExampleEntry(1, "Jacobi Transpose", "Jacobi Transpose by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_JACOB_TRANS),
|
||||
ExampleEntry(1, "Jacobi Pseudo Inv", "Jacobi Pseudo Inverse Method by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_PURE_PSEUDO),
|
||||
|
||||
ExampleEntry(0, "Tutorial"),
|
||||
ExampleEntry(1, "Constant Velocity", "Free moving rigid body, without external or constraint forces", TutorialCreateFunc, TUT_VELOCITY),
|
||||
ExampleEntry(1, "Gravity Acceleration", "Motion of a free falling rigid body under constant gravitational acceleration", TutorialCreateFunc, TUT_ACCELERATION),
|
||||
ExampleEntry(1, "Contact Computation", "Discrete Collision Detection for sphere-sphere", TutorialCreateFunc, TUT_COLLISION),
|
||||
ExampleEntry(1, "Solve Contact Constraint", "Compute and apply the impulses needed to satisfy non-penetrating contact constraints", TutorialCreateFunc, TUT_SOLVE_CONTACT_CONSTRAINT),
|
||||
ExampleEntry(1, "Spring constraint", "A rigid body with a spring constraint attached", Dof6ConstraintTutorialCreateFunc, 0),
|
||||
|
||||
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),
|
||||
|
||||
ExampleEntry(0, "Deformabe Body"),
|
||||
ExampleEntry(1, "Deformable Self Collision", "Deformable Self Collision", DeformableSelfCollisionCreateFunc),
|
||||
ExampleEntry(1, "Deformable-Deformable Contact", "Deformable contact", DeformableContactCreateFunc),
|
||||
ExampleEntry(1, "Cloth Friction", "Cloth friction contact", ClothFrictionCreateFunc),
|
||||
ExampleEntry(1, "Deformable-Deformable Friction Contact", "Deformable friction contact", PinchFrictionCreateFunc),
|
||||
ExampleEntry(1, "Deformable-RigidBody Contact", "Deformable test", DeformableRigidCreateFunc),
|
||||
ExampleEntry(1, "Split Impulse Contact", "Split impulse test", SplitImpulseCreateFunc),
|
||||
ExampleEntry(1, "Grasp Deformable Cube", "Grasping test", PinchCreateFunc),
|
||||
ExampleEntry(1, "Grasp Deformable with Motor", "Grasping test", GraspDeformableCreateFunc),
|
||||
ExampleEntry(1, "Volumetric Deformable Objects", "Volumetric Deformable test", VolumetricDeformableCreateFunc),
|
||||
ExampleEntry(1, "Extreme Deformation", "Recovery from extreme deformation", LargeDeformationCreateFunc),
|
||||
ExampleEntry(1, "Load Deformed", "Reconstruct a deformed object", LoadDeformedCreateFunc),
|
||||
ExampleEntry(1, "Colliding Test", "Volumetric deformable collide with rigid box", CollideCreateFunc),
|
||||
ExampleEntry(1, "Rigid Cloth Anchor", "Deformable Rigid body Anchor test", DeformableClothAnchorCreateFunc),
|
||||
ExampleEntry(1, "Multibody Cloth Anchor", "Deformable Multibody Anchor test", MultibodyClothAnchorCreateFunc),
|
||||
ExampleEntry(1, "Deformable-MultiBody Contact", "MultiBody and Deformable contact", DeformableMultibodyCreateFunc),
|
||||
// ExampleEntry(1, "MultiBody Baseline", "MultiBody Baseline", MultiBodyBaselineCreateFunc),
|
||||
|
||||
ExampleEntry(0, "Reduced Deformabe Body"),
|
||||
ExampleEntry(1, "Mode Visualizer", "Visualizer the modes for reduced deformable objects", ReducedModeVisualizerCreateFunc),
|
||||
ExampleEntry(1, "Reduced Conservation Test", "Momentum conservation test for the reduced deformable objects", ReducedConservationTestCreateFunc),
|
||||
ExampleEntry(1, "Reduced Springboard", "Moving rigid object colliding with a fixed reduced deformable objects", ReducedSpringboardCreateFunc),
|
||||
ExampleEntry(1, "Reduced Free Fall", "Free fall ground contact test for the reduced deformable model", ReducedFreeFallCreateFunc),
|
||||
ExampleEntry(1, "Reduced Collision Test", "Collision between a reduced block and the a rigid block", ReducedCollideCreateFunc),
|
||||
ExampleEntry(1, "Reduced Grasp", "Grasp a reduced deformable block", ReducedGraspCreateFunc),
|
||||
ExampleEntry(1, "Reduced Motor Grasp", "Grasp a reduced deformable block with motor", ReducedMotorGraspCreateFunc),
|
||||
ExampleEntry(1, "Reduced Friction Slope", "Grasp a reduced deformable block", FrictionSlopeCreateFunc),
|
||||
ExampleEntry(1, "Reduced Benchmark", "Reduced deformable performance benchmark example", ReducedBenchmarkCreateFunc),
|
||||
// ExampleEntry(1, "Simple Reduced Deformable Test", "Simple dynamics test for the reduced deformable objects", ReducedBasicTestCreateFunc),
|
||||
|
||||
#ifdef INCLUDE_CLOTH_DEMOS
|
||||
ExampleEntry(0,"Soft Body"),
|
||||
ExampleEntry(1,"Cloth","Simulate a patch of cloth.", SoftDemoCreateFunc,0),
|
||||
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),
|
||||
ExampleEntry(1,"Rope Attach","Simulate a rigid body connected to a rope.", SoftDemoCreateFunc,4),
|
||||
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, "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),
|
||||
ExampleEntry(1, "Rope Attach", "Simulate a rigid body connected to a rope.", SoftDemoCreateFunc, 4),
|
||||
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),
|
||||
ExampleEntry(1,"Impact","Soft body impact",SoftDemoCreateFunc,11),
|
||||
ExampleEntry(1,"Aero","Rudimentary aero dynamics simulation", SoftDemoCreateFunc,12),
|
||||
ExampleEntry(1,"Aero 2","Rudimentary aero dynamics simulation",SoftDemoCreateFunc,13),
|
||||
ExampleEntry(1,"Friction","Simulate soft body friction with friction coefficients ranging from 0 to 1.", SoftDemoCreateFunc,14),
|
||||
ExampleEntry(1,"Torus","Simulate a soft body torus.",SoftDemoCreateFunc,15),
|
||||
ExampleEntry(1,"Torus (Shape Match)","Simulate a soft body torus using shape matching.", SoftDemoCreateFunc,16),
|
||||
ExampleEntry(1,"Bunny","Simulate the Stanford bunny as deformable object.", SoftDemoCreateFunc,17),
|
||||
ExampleEntry(1,"Bunny (Shape Match)","Simulate the Stanford bunny as deformable object including shape matching.", SoftDemoCreateFunc,18),
|
||||
ExampleEntry(1,"Cutting","Allow cutting of the soft body, by clicking on the cloth", SoftDemoCreateFunc,19),
|
||||
ExampleEntry(1,"Cluster Deform","Soft body collision detection using convex collision clusters.", SoftDemoCreateFunc,20),
|
||||
ExampleEntry(1,"Cluster Collide1","Collision detection between soft bodies using convex collision clusters.", SoftDemoCreateFunc,21),
|
||||
ExampleEntry(1,"Cluster Collide2","Collision detection between soft bodies using convex collision clusters.",SoftDemoCreateFunc,22),
|
||||
ExampleEntry(1,"Cluster Socket","Soft bodies connected by a point to point (ball-socket) constraints. This requires collision clusters, in order to define a frame of reference for the constraint."
|
||||
, SoftDemoCreateFunc,23),
|
||||
ExampleEntry(1,"Cluster Hinge","Soft bodies connected by a hinge constraints. This requires collision clusters, in order to define a frame of reference for the constraint.", SoftDemoCreateFunc,24),
|
||||
ExampleEntry(1,"Cluster Combine","Simulate soft bodies using collision clusters.", SoftDemoCreateFunc,25),
|
||||
ExampleEntry(1,"Cluster Car","Simulate the Stanford bunny by multiple soft bodies connected by constraints.", SoftDemoCreateFunc,26),
|
||||
ExampleEntry(1,"Cluster Robot","A rigid body base connected by soft body wheels, connected by constraints.", SoftDemoCreateFunc,27),
|
||||
ExampleEntry(1,"Cluster Stack Soft","Stacking of soft bodies.", SoftDemoCreateFunc,28),
|
||||
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),
|
||||
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),
|
||||
ExampleEntry(1, "Impact", "Soft body impact", SoftDemoCreateFunc, 11),
|
||||
ExampleEntry(1, "Aero", "Rudimentary aero dynamics simulation", SoftDemoCreateFunc, 12),
|
||||
ExampleEntry(1, "Aero 2", "Rudimentary aero dynamics simulation", SoftDemoCreateFunc, 13),
|
||||
ExampleEntry(1, "Friction", "Simulate soft body friction with friction coefficients ranging from 0 to 1.", SoftDemoCreateFunc, 14),
|
||||
ExampleEntry(1, "Torus", "Simulate a soft body torus.", SoftDemoCreateFunc, 15),
|
||||
ExampleEntry(1, "Torus (Shape Match)", "Simulate a soft body torus using shape matching.", SoftDemoCreateFunc, 16),
|
||||
ExampleEntry(1, "Bunny", "Simulate the Stanford bunny as deformable object.", SoftDemoCreateFunc, 17),
|
||||
ExampleEntry(1, "Bunny (Shape Match)", "Simulate the Stanford bunny as deformable object including shape matching.", SoftDemoCreateFunc, 18),
|
||||
ExampleEntry(1, "Cutting", "Allow cutting of the soft body, by clicking on the cloth", SoftDemoCreateFunc, 19),
|
||||
ExampleEntry(1, "Cluster Deform", "Soft body collision detection using convex collision clusters.", SoftDemoCreateFunc, 20),
|
||||
ExampleEntry(1, "Cluster Collide1", "Collision detection between soft bodies using convex collision clusters.", SoftDemoCreateFunc, 21),
|
||||
ExampleEntry(1, "Cluster Collide2", "Collision detection between soft bodies using convex collision clusters.", SoftDemoCreateFunc, 22),
|
||||
ExampleEntry(1, "Cluster Socket", "Soft bodies connected by a point to point (ball-socket) constraints. This requires collision clusters, in order to define a frame of reference for the constraint.", SoftDemoCreateFunc, 23),
|
||||
ExampleEntry(1, "Cluster Hinge", "Soft bodies connected by a hinge constraints. This requires collision clusters, in order to define a frame of reference for the constraint.", SoftDemoCreateFunc, 24),
|
||||
ExampleEntry(1, "Cluster Combine", "Simulate soft bodies using collision clusters.", SoftDemoCreateFunc, 25),
|
||||
ExampleEntry(1, "Cluster Car", "Simulate the Stanford bunny by multiple soft bodies connected by constraints.", SoftDemoCreateFunc, 26),
|
||||
ExampleEntry(1, "Cluster Robot", "A rigid body base connected by soft body wheels, connected by constraints.", SoftDemoCreateFunc, 27),
|
||||
ExampleEntry(1, "Cluster Stack Soft", "Stacking of soft bodies.", SoftDemoCreateFunc, 28),
|
||||
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
|
||||
#endif //INCLUDE_CLOTH_DEMOS
|
||||
|
||||
///we disable the benchmarks in debug mode, they are way too slow and benchmarking in debug mode is not recommended
|
||||
//#ifndef _DEBUG
|
||||
ExampleEntry(0,"Benchmarks"),
|
||||
ExampleEntry(1,"3000 boxes", "Benchmark a stack of 3000 boxes. It will stress the collision detection, a specialized box-box implementation based on the separating axis test, and the constraint solver. ", BenchmarkCreateFunc, 1),
|
||||
ExampleEntry(1,"1000 stack", "Benchmark a stack of 3000 boxes. It will stress the collision detection, a specialized box-box implementation based on the separating axis test, and the constraint solver. ",
|
||||
BenchmarkCreateFunc, 2),
|
||||
ExampleEntry(1,"Ragdolls", "Benchmark the performance of the ragdoll constraints, btHingeConstraint and btConeTwistConstraint, in addition to capsule collision detection.", BenchmarkCreateFunc, 3),
|
||||
ExampleEntry(1,"Convex stack", "Benchmark the performance and stability of rigid bodies using btConvexHullShape.", BenchmarkCreateFunc, 4),
|
||||
ExampleEntry(1,"Prim vs Mesh", "Benchmark the performance and stability of rigid bodies using primitive collision shapes (btSphereShape, btBoxShape), resting on a triangle mesh, btBvhTriangleMeshShape.", BenchmarkCreateFunc, 5),
|
||||
ExampleEntry(1,"Convex vs Mesh", "Benchmark the performance and stability of rigid bodies using convex hull collision shapes (btConvexHullShape), resting on a triangle mesh, btBvhTriangleMeshShape.", BenchmarkCreateFunc, 6),
|
||||
ExampleEntry(1,"Raycast", "Benchmark the performance of the btCollisionWorld::rayTest. Note that currently the rays are not rendered.", BenchmarkCreateFunc, 7),
|
||||
//#endif
|
||||
///we disable the benchmarks in debug mode, they are way too slow and benchmarking in debug mode is not recommended
|
||||
//#ifndef _DEBUG
|
||||
ExampleEntry(0, "Benchmarks"),
|
||||
ExampleEntry(1, "3000 boxes", "Benchmark a stack of 3000 boxes. It will stress the collision detection, a specialized box-box implementation based on the separating axis test, and the constraint solver. ", BenchmarkCreateFunc, 1),
|
||||
ExampleEntry(1, "1000 stack", "Benchmark a stack of 3000 boxes. It will stress the collision detection, a specialized box-box implementation based on the separating axis test, and the constraint solver. ",
|
||||
BenchmarkCreateFunc, 2),
|
||||
ExampleEntry(1, "Ragdolls", "Benchmark the performance of the ragdoll constraints, btHingeConstraint and btConeTwistConstraint, in addition to capsule collision detection.", BenchmarkCreateFunc, 3),
|
||||
ExampleEntry(1, "Convex stack", "Benchmark the performance and stability of rigid bodies using btConvexHullShape.", BenchmarkCreateFunc, 4),
|
||||
ExampleEntry(1, "Prim vs Mesh", "Benchmark the performance and stability of rigid bodies using primitive collision shapes (btSphereShape, btBoxShape), resting on a triangle mesh, btBvhTriangleMeshShape.", BenchmarkCreateFunc, 5),
|
||||
ExampleEntry(1, "Convex vs Mesh", "Benchmark the performance and stability of rigid bodies using convex hull collision shapes (btConvexHullShape), resting on a triangle mesh, btBvhTriangleMeshShape.", BenchmarkCreateFunc, 6),
|
||||
ExampleEntry(1, "Raycast", "Benchmark the performance of the btCollisionWorld::rayTest. Note that currently the rays are not rendered.", BenchmarkCreateFunc, 7),
|
||||
ExampleEntry(1, "Convex Pack", "Benchmark the performance of the convex hull primitive.", BenchmarkCreateFunc, 8),
|
||||
ExampleEntry(1, "Heightfield", "Raycast against a btHeightfieldTerrainShape", HeightfieldExampleCreateFunc),
|
||||
//#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),
|
||||
ExampleEntry(1, "Wavefront Obj", "Import a Wavefront .obj file", ImportObjCreateFunc, 0),
|
||||
ExampleEntry(1, "Obj2RigidBody (Show Obj)", "Load a triangle mesh from Wavefront .obj and turn it in a convex hull collision shape, connected to a rigid body. We can use the original .obj mesh data to visualize the rigid body. In 'debug' wireframe mode (press 'w' to toggle) we still see the convex hull data.", ET_RigidBodyFromObjCreateFunc),
|
||||
ExampleEntry(1, "Obj2RigidBody (Show Hull)", "Load a triangle mesh from Wavefront .obj and turn it in a convex hull collision shape, connected to a rigid body", ET_RigidBodyFromObjCreateFunc, ObjUseConvexHullForRendering),
|
||||
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. ",
|
||||
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).",
|
||||
ImportURDFCreateFunc, 1),
|
||||
ExampleEntry(1, "MJCF (MultiBody)", "Import a MJCF xml file, create multiple multibodies etc", ImportMJCFCreateFunc),
|
||||
|
||||
ExampleEntry(1, "SDF (MultiBody)", "Import an SDF file, create multiple multibodies etc", ImportSDFCreateFunc),
|
||||
|
||||
ExampleEntry(0,"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),
|
||||
ExampleEntry(1,"Wavefront Obj", "Import a Wavefront .obj file", ImportObjCreateFunc, 0),
|
||||
ExampleEntry(1,"Obj2RigidBody (Show Obj)", "Load a triangle mesh from Wavefront .obj and turn it in a convex hull collision shape, connected to a rigid body. We can use the original .obj mesh data to visualize the rigid body. In 'debug' wireframe mode (press 'w' to toggle) we still see the convex hull data.", ET_RigidBodyFromObjCreateFunc),
|
||||
ExampleEntry(1,"Obj2RigidBody (Show Hull)", "Load a triangle mesh from Wavefront .obj and turn it in a convex hull collision shape, connected to a rigid body", ET_RigidBodyFromObjCreateFunc,ObjUseConvexHullForRendering),
|
||||
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(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.",
|
||||
ForkLiftCreateFunc),
|
||||
|
||||
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. ",
|
||||
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).",
|
||||
ImportURDFCreateFunc, 1),
|
||||
ExampleEntry(1,"SDF (MultiBody)", "Import an SDF file, create multiple multibodies etc", ImportSDFCreateFunc),
|
||||
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.",
|
||||
RayTracerCreateFunc),
|
||||
|
||||
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.",
|
||||
ForkLiftCreateFunc),
|
||||
ExampleEntry(0, "Experiments"),
|
||||
|
||||
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.",
|
||||
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 (Shared Mem)", "Create a physics client that can communicate with a physics server over shared memory.", PhysicsClientCreateFunc),
|
||||
ExampleEntry(1, "Physics Client (Direct)", "Create a physics client that can communicate with a physics server directly in-process.", PhysicsClientCreateFunc,eCLIENTEXAMPLE_DIRECT),
|
||||
|
||||
ExampleEntry(1,"R2D2 Grasp","Load the R2D2 robot from URDF file and control it to grasp objects", R2D2GraspExampleCreateFunc, eROBOTIC_LEARN_GRASP),
|
||||
ExampleEntry(1,"Kuka IK","Control a Kuka IIWA robot to follow a target using IK. This IK is not setup properly yet.", KukaGraspExampleCreateFunc,0),
|
||||
ExampleEntry(1,"URDF Compliant Contact","Work-in-progress, experiment/improve compliant rigid contact using parameters from URDF file (contact_cfm, contact_erp, lateral_friction, rolling_friction)", R2D2GraspExampleCreateFunc,eROBOTIC_LEARN_COMPLIANT_CONTACT),
|
||||
ExampleEntry(1,"Rolling friction","Experiment on multibody rolling friction", R2D2GraspExampleCreateFunc,eROBOTIC_LEARN_ROLLING_FRICTION),
|
||||
ExampleEntry(1,"Gripper Grasp","Grasp experiment with a gripper to improve contact model", GripperGraspExampleCreateFunc,eGRIPPER_GRASP),
|
||||
ExampleEntry(1,"Two Point Grasp","Grasp experiment with two point contact to test rolling friction", GripperGraspExampleCreateFunc, eTWO_POINT_GRASP),
|
||||
ExampleEntry(1,"One Motor Gripper Grasp","Grasp experiment with a gripper with one motor to test slider constraint for closed loop structure", GripperGraspExampleCreateFunc, eONE_MOTOR_GRASP),
|
||||
ExampleEntry(1, "Robot Control", "Create a physics client and server to create and control robots.",
|
||||
PhysicsClientCreateFunc, eCLIENTEXAMPLE_SERVER),
|
||||
|
||||
ExampleEntry(1, "R2D2 Grasp", "Load the R2D2 robot from URDF file and control it to grasp objects", R2D2GraspExampleCreateFunc, eROBOTIC_LEARN_GRASP),
|
||||
ExampleEntry(1, "Kuka IK", "Control a Kuka IIWA robot to follow a target using IK. This IK is not setup properly yet.", KukaGraspExampleCreateFunc, 0),
|
||||
ExampleEntry(1, "URDF Compliant Contact", "Work-in-progress, experiment/improve compliant rigid contact using parameters from URDF file (contact_cfm, contact_erp, lateral_friction, rolling_friction)", R2D2GraspExampleCreateFunc, eROBOTIC_LEARN_COMPLIANT_CONTACT),
|
||||
ExampleEntry(1, "Rolling friction", "Experiment on multibody rolling friction", R2D2GraspExampleCreateFunc, eROBOTIC_LEARN_ROLLING_FRICTION),
|
||||
ExampleEntry(1, "Gripper Grasp", "Grasp experiment with a gripper to improve contact model", GripperGraspExampleCreateFunc, eGRIPPER_GRASP),
|
||||
ExampleEntry(1, "Two Point Grasp", "Grasp experiment with two point contact to test rolling friction", GripperGraspExampleCreateFunc, eTWO_POINT_GRASP),
|
||||
ExampleEntry(1, "Grasp Deformable Cloth", "Grasp experiment with deformable cloth", GripperGraspExampleCreateFunc, eGRASP_DEFORMABLE_CLOTH),
|
||||
ExampleEntry(1, "One Motor Gripper Grasp", "Grasp experiment with a gripper with one motor to test slider constraint for closed loop structure", GripperGraspExampleCreateFunc, eONE_MOTOR_GRASP),
|
||||
#ifndef SKIP_SOFT_BODY_MULTI_BODY_DYNAMICS_WORLD
|
||||
ExampleEntry(1, "Grasp Soft Body", "Grasp soft body experiment", GripperGraspExampleCreateFunc, eGRASP_SOFT_BODY),
|
||||
ExampleEntry(1, "Softbody Multibody Coupling", "Two way coupling between soft body and multibody experiment", GripperGraspExampleCreateFunc, eSOFTBODY_MULTIBODY_COUPLING),
|
||||
#endif //SKIP_SOFT_BODY_MULTI_BODY_DYNAMICS_WORLD
|
||||
|
||||
#ifdef ENABLE_LUA
|
||||
ExampleEntry(1,"Lua Script", "Create the dynamics world, collision shapes and rigid bodies using Lua scripting",
|
||||
LuaDemoCreateFunc),
|
||||
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, "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, "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, "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),
|
||||
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),
|
||||
#if BT_THREADSAFE
|
||||
// only enable MultiThreaded demo if a task scheduler is available
|
||||
ExampleEntry(1, "Multithreaded Demo",
|
||||
"Stacks of boxes that do not sleep. Good for testing performance with large numbers of bodies and contacts. Sliders can be used to change the number of stacks (restart needed after each change).",
|
||||
MultiThreadedDemoCreateFunc),
|
||||
#endif
|
||||
|
||||
ExampleEntry(0, "Rendering"),
|
||||
ExampleEntry(1, "Instanced Rendering", "Simple example of fast instanced rendering, only active when using OpenGL3+.", RenderInstancingCreateFunc),
|
||||
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),
|
||||
ExampleEntry(1, "Dynamic Texture", "Dynamic updated textured applied to a cube.", DynamicTexturedCubeDemoCreateFunc),
|
||||
|
||||
#ifdef B3_ENABLE_TINY_AUDIO
|
||||
ExampleEntry(0, "Audio"),
|
||||
ExampleEntry(1, "Simple Audio", "Play some sound", TinyAudioExampleCreateFunc),
|
||||
#endif
|
||||
|
||||
ExampleEntry(0,"Rendering"),
|
||||
ExampleEntry(1,"Instanced Rendering", "Simple example of fast instanced rendering, only active when using OpenGL3+.",RenderInstancingCreateFunc),
|
||||
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),
|
||||
ExampleEntry(1,"Dynamic Texture", "Dynamic updated textured applied to a cube.", DynamicTexturedCubeDemoCreateFunc),
|
||||
//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),
|
||||
ExampleEntry(1, "Multiple Boxes", "Add multiple box rigid bodies that fall under gravity", ET_MultipleBoxesCreateFunc),
|
||||
ExampleEntry(1, "Compound Boxes", "Add multiple boxes to a single CompoundShape to form a simple rigid L-beam, that falls under gravity", ET_CompoundBoxesCreateFunc),
|
||||
ExampleEntry(1, "Simple Joint", "Create a single distance constraint between two box rigid bodies", ET_SimpleJointCreateFunc),
|
||||
ExampleEntry(1, "Simple Cloth", "Create a simple piece of cloth", ET_SimpleClothCreateFunc),
|
||||
ExampleEntry(1, "Simple Chain", "Create a simple chain using a pair of point2point/distance constraints. You may click and drag any box to see the chain respond.", ET_ChainCreateFunc),
|
||||
ExampleEntry(1, "Simple Bridge", "Create a simple bridge using a pair of point2point/distance constraints. You may click and drag any plank to see the bridge respond.", ET_BridgeCreateFunc),
|
||||
ExampleEntry(1, "Inclined Plane", "Create an inclined plane to show restitution and different types of friction. Use the sliders to vary restitution and friction and press space to reset the scene.", ET_InclinedPlaneCreateFunc),
|
||||
ExampleEntry(1, "Newton's Cradle", "Create a Newton's Cradle using a pair of point2point/slider constraints. Press 1/2 to lengthen/shorten the pendula, press 3 to displace pendula. Use the sliders to select the number (reset simulation), length and restitution of pendula, the number of displaced pendula and apply the displacement force.", ET_NewtonsCradleCreateFunc),
|
||||
ExampleEntry(1, "Newton's Rope Cradle", "Create a Newton's Cradle using ropes. Press 3 to displace pendula. Use the sliders to select the number (reset simulation), length and restitution of pendula and the number of displaced pendula and apply the displacement force.", ET_NewtonsRopeCradleCreateFunc),
|
||||
ExampleEntry(1, "Multi-Pendulum", "Create a Multi-Pendulum using point2point/slider constraints. Press 1/2 to lengthen/shorten the pendula, press 3 to displace pendula. Use the sliders to select the number (reset simulation), length and restitution of pendula, the number of displaced pendula and apply the displacement force.", ET_MultiPendulumCreateFunc),
|
||||
|
||||
|
||||
|
||||
//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),
|
||||
ExampleEntry(1,"Multiple Boxes", "Add multiple box rigid bodies that fall under gravity", ET_MultipleBoxesCreateFunc),
|
||||
ExampleEntry(1,"Simple Joint", "Create a single distance constraint between two box rigid bodies", ET_SimpleJointCreateFunc),
|
||||
ExampleEntry(1,"Simple Cloth", "Create a simple piece of cloth", ET_SimpleClothCreateFunc),
|
||||
ExampleEntry(1,"Simple Chain", "Create a simple chain using a pair of point2point/distance constraints. You may click and drag any box to see the chain respond.", ET_ChainCreateFunc),
|
||||
ExampleEntry(1,"Simple Bridge", "Create a simple bridge using a pair of point2point/distance constraints. You may click and drag any plank to see the bridge respond.", ET_BridgeCreateFunc),
|
||||
ExampleEntry(1,"Inclined Plane", "Create an inclined plane to show restitution and different types of friction. Use the sliders to vary restitution and friction and press space to reset the scene.", ET_InclinedPlaneCreateFunc),
|
||||
ExampleEntry(1,"Newton's Cradle", "Create a Newton's Cradle using a pair of point2point/slider constraints. Press 1/2 to lengthen/shorten the pendula, press 3 to displace pendula. Use the sliders to select the number (reset simulation), length and restitution of pendula, the number of displaced pendula and apply the displacement force.", ET_NewtonsCradleCreateFunc),
|
||||
ExampleEntry(1,"Newton's Rope Cradle", "Create a Newton's Cradle using ropes. Press 3 to displace pendula. Use the sliders to select the number (reset simulation), length and restitution of pendula and the number of displaced pendula and apply the displacement force.",ET_NewtonsRopeCradleCreateFunc),
|
||||
ExampleEntry(1,"Multi-Pendulum", "Create a Multi-Pendulum using point2point/slider constraints. Press 1/2 to lengthen/shorten the pendula, press 3 to displace pendula. Use the sliders to select the number (reset simulation), length and restitution of pendula, the number of displaced pendula and apply the displacement force.",ET_MultiPendulumCreateFunc),
|
||||
|
||||
|
||||
//todo: create a category/tutorial about advanced topics, such as optimizations, using different collision detection algorithm, different constraint solvers etc.
|
||||
//ExampleEntry(0,"Advanced"),
|
||||
//ExampleEntry(1,"Obj2RigidBody Add Features", "Load a triangle mesh from Wavefront .obj and create polyhedral features to perform the separating axis test (instead of GJK/MPR). It is best to combine optimization and polyhedral feature generation.", ET_RigidBodyFromObjCreateFunc,OptimizeConvexObj+ComputePolyhedralFeatures),
|
||||
ExampleEntry(9, "Evolution"),
|
||||
ExampleEntry(1, "Neural Network 3D Walkers", "A simple example of using evolution to make a creature walk.", ET_NN3DWalkersCreateFunc),
|
||||
|
||||
//todo: create a category/tutorial about advanced topics, such as optimizations, using different collision detection algorithm, different constraint solvers etc.
|
||||
//ExampleEntry(0,"Advanced"),
|
||||
//ExampleEntry(1,"Obj2RigidBody Add Features", "Load a triangle mesh from Wavefront .obj and create polyhedral features to perform the separating axis test (instead of GJK/MPR). It is best to combine optimization and polyhedral feature generation.", ET_RigidBodyFromObjCreateFunc,OptimizeConvexObj+ComputePolyhedralFeatures),
|
||||
|
||||
};
|
||||
|
||||
#ifdef B3_USE_CLEW
|
||||
#ifndef NO_OPENGL3
|
||||
static ExampleEntry gOpenCLExamples[]=
|
||||
{
|
||||
ExampleEntry(0,"OpenCL (experimental)"),
|
||||
ExampleEntry(1,"Box-Box", "Full OpenCL implementation of the entire physics and collision detection pipeline, showing box-box rigid body",
|
||||
OpenCLBoxBoxCreateFunc),
|
||||
ExampleEntry(1,"Pair Bench", "Benchmark of overlapping pair search using OpenCL.", PairBenchOpenCLCreateFunc),
|
||||
static ExampleEntry gOpenCLExamples[] =
|
||||
{
|
||||
ExampleEntry(0, "OpenCL (experimental)"),
|
||||
ExampleEntry(1, "Box-Box", "Full OpenCL implementation of the entire physics and collision detection pipeline, showing box-box rigid body",
|
||||
OpenCLBoxBoxCreateFunc),
|
||||
ExampleEntry(1, "Pair Bench", "Benchmark of overlapping pair search using OpenCL.", PairBenchOpenCLCreateFunc),
|
||||
|
||||
};
|
||||
#endif
|
||||
#endif //
|
||||
#endif //
|
||||
static btAlignedObjectArray<ExampleEntry> gAdditionalRegisteredExamples;
|
||||
|
||||
|
||||
struct ExampleEntriesInternalData
|
||||
{
|
||||
btAlignedObjectArray<ExampleEntry> m_allExamples;
|
||||
|
|
@ -349,51 +429,47 @@ void ExampleEntriesAll::initOpenCLExampleEntries()
|
|||
{
|
||||
#ifdef B3_USE_CLEW
|
||||
#ifndef NO_OPENGL3
|
||||
int numDefaultEntries = sizeof(gOpenCLExamples)/sizeof(ExampleEntry);
|
||||
for (int i=0;i<numDefaultEntries;i++)
|
||||
int numDefaultEntries = sizeof(gOpenCLExamples) / sizeof(ExampleEntry);
|
||||
for (int i = 0; i < numDefaultEntries; i++)
|
||||
{
|
||||
m_data->m_allExamples.push_back(gOpenCLExamples[i]);
|
||||
}
|
||||
#endif
|
||||
#endif //B3_USE_CLEW
|
||||
#endif //B3_USE_CLEW
|
||||
}
|
||||
|
||||
void ExampleEntriesAll::initExampleEntries()
|
||||
{
|
||||
m_data->m_allExamples.clear();
|
||||
|
||||
for (int i=0;i<gAdditionalRegisteredExamples.size();i++)
|
||||
for (int i = 0; i < gAdditionalRegisteredExamples.size(); i++)
|
||||
{
|
||||
m_data->m_allExamples.push_back(gAdditionalRegisteredExamples[i]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int numDefaultEntries = sizeof(gDefaultExamples)/sizeof(ExampleEntry);
|
||||
for (int i=0;i<numDefaultEntries;i++)
|
||||
int numDefaultEntries = sizeof(gDefaultExamples) / sizeof(ExampleEntry);
|
||||
for (int i = 0; i < numDefaultEntries; i++)
|
||||
{
|
||||
m_data->m_allExamples.push_back(gDefaultExamples[i]);
|
||||
}
|
||||
|
||||
if (m_data->m_allExamples.size()==0)
|
||||
if (m_data->m_allExamples.size() == 0)
|
||||
{
|
||||
|
||||
{
|
||||
ExampleEntry e(0,"Empty");
|
||||
ExampleEntry e(0, "Empty");
|
||||
m_data->m_allExamples.push_back(e);
|
||||
}
|
||||
|
||||
{
|
||||
ExampleEntry e(1,"Empty","Empty Description", EmptyExample::CreateFunc);
|
||||
ExampleEntry e(1, "Empty", "Empty Description", EmptyExample::CreateFunc);
|
||||
m_data->m_allExamples.push_back(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ExampleEntriesAll::registerExampleEntry(int menuLevel, const char* name,const char* description, CommonExampleInterface::CreateFunc* createFunc, int option)
|
||||
void ExampleEntriesAll::registerExampleEntry(int menuLevel, const char* name, const char* description, CommonExampleInterface::CreateFunc* createFunc, int option)
|
||||
{
|
||||
ExampleEntry e( menuLevel,name,description, createFunc, option);
|
||||
ExampleEntry e(menuLevel, name, description, createFunc, option);
|
||||
gAdditionalRegisteredExamples.push_back(e);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,36 +4,29 @@
|
|||
|
||||
#include "../CommonInterfaces/CommonExampleInterface.h"
|
||||
|
||||
|
||||
|
||||
class ExampleEntriesAll : public ExampleEntries
|
||||
{
|
||||
|
||||
struct ExampleEntriesInternalData* m_data;
|
||||
|
||||
public:
|
||||
|
||||
ExampleEntriesAll();
|
||||
virtual ~ExampleEntriesAll();
|
||||
|
||||
static void registerExampleEntry(int menuLevel, const char* name,const char* description, CommonExampleInterface::CreateFunc* createFunc, int option=0);
|
||||
|
||||
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);
|
||||
|
||||
virtual int getExampleOption(int index);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //EXAMPLE_ENTRIES_H
|
||||
#endif //EXAMPLE_ENTRIES_H
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
Copyright (c) 2003-2006 Erwin Coumans https://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.
|
||||
|
|
@ -30,48 +30,52 @@ class GL_ShapeDrawer
|
|||
protected:
|
||||
struct ShapeCache
|
||||
{
|
||||
struct Edge { btVector3 n[2];int v[2]; };
|
||||
ShapeCache(btConvexShape* s) : m_shapehull(s) {}
|
||||
btShapeHull m_shapehull;
|
||||
btAlignedObjectArray<Edge> m_edges;
|
||||
struct Edge
|
||||
{
|
||||
btVector3 n[2];
|
||||
int v[2];
|
||||
};
|
||||
ShapeCache(btConvexShape* s) : m_shapehull(s) {}
|
||||
btShapeHull m_shapehull;
|
||||
btAlignedObjectArray<Edge> m_edges;
|
||||
};
|
||||
//clean-up memory of dynamically created shape hulls
|
||||
btAlignedObjectArray<ShapeCache*> m_shapecaches;
|
||||
unsigned int m_texturehandle;
|
||||
bool m_textureenabled;
|
||||
bool m_textureinitialized;
|
||||
|
||||
btAlignedObjectArray<ShapeCache*> m_shapecaches;
|
||||
unsigned int m_texturehandle;
|
||||
bool m_textureenabled;
|
||||
bool m_textureinitialized;
|
||||
|
||||
ShapeCache* cache(btConvexShape*);
|
||||
ShapeCache* cache(btConvexShape*);
|
||||
|
||||
virtual void drawSceneInternal(const btDiscreteDynamicsWorld* world, int pass);
|
||||
virtual void drawSceneInternal(const btDiscreteDynamicsWorld* world, int pass, int cameraUpAxis);
|
||||
|
||||
public:
|
||||
GL_ShapeDrawer();
|
||||
GL_ShapeDrawer();
|
||||
|
||||
virtual ~GL_ShapeDrawer();
|
||||
virtual ~GL_ShapeDrawer();
|
||||
|
||||
|
||||
virtual void drawScene(const btDiscreteDynamicsWorld* world, bool useShadows, int cameraUpAxis);
|
||||
|
||||
virtual void drawScene(const btDiscreteDynamicsWorld* world, bool useShadows);
|
||||
///drawOpenGL might allocate temporary memoty, stores pointer in shape userpointer
|
||||
virtual void drawOpenGL(btScalar* m, const btCollisionShape* shape, const btVector3& color, int debugMode, const btVector3& worldBoundsMin, const btVector3& worldBoundsMax);
|
||||
virtual void drawShadow(btScalar* m, const btVector3& extrusion, const btCollisionShape* shape, const btVector3& worldBoundsMin, const btVector3& worldBoundsMax);
|
||||
|
||||
///drawOpenGL might allocate temporary memoty, stores pointer in shape userpointer
|
||||
virtual void drawOpenGL(btScalar* m, const btCollisionShape* shape, const btVector3& color,int debugMode,const btVector3& worldBoundsMin,const btVector3& worldBoundsMax);
|
||||
virtual void drawShadow(btScalar* m, const btVector3& extrusion,const btCollisionShape* shape,const btVector3& worldBoundsMin,const btVector3& worldBoundsMax);
|
||||
|
||||
bool enableTexture(bool enable) { bool p=m_textureenabled;m_textureenabled=enable;return(p); }
|
||||
bool hasTextureEnabled() const
|
||||
{
|
||||
return m_textureenabled;
|
||||
}
|
||||
|
||||
void drawSphere(btScalar r, int lats, int longs);
|
||||
static void drawCoordSystem();
|
||||
|
||||
bool enableTexture(bool enable)
|
||||
{
|
||||
bool p = m_textureenabled;
|
||||
m_textureenabled = enable;
|
||||
return (p);
|
||||
}
|
||||
bool hasTextureEnabled() const
|
||||
{
|
||||
return m_textureenabled;
|
||||
}
|
||||
|
||||
void drawSphere(btScalar r, int lats, int longs);
|
||||
static void drawCoordSystem();
|
||||
};
|
||||
|
||||
void OGL_displaylist_register_shape(btCollisionShape * shape);
|
||||
void OGL_displaylist_register_shape(btCollisionShape* shape);
|
||||
void OGL_displaylist_clean();
|
||||
|
||||
#endif //GL_SHAPE_DRAWER_H
|
||||
|
||||
#endif //GL_SHAPE_DRAWER_H
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@
|
|||
#include <assert.h>
|
||||
|
||||
GraphingTexture::GraphingTexture()
|
||||
:m_textureId(0),
|
||||
m_width(0),
|
||||
m_height(0)
|
||||
: m_textureId(0),
|
||||
m_width(0),
|
||||
m_height(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -18,10 +18,9 @@ void GraphingTexture::destroy()
|
|||
{
|
||||
//TODO(erwincoumans) release memory etc...
|
||||
m_width = 0;
|
||||
m_height=0;
|
||||
glDeleteTextures(1,(GLuint*)&m_textureId);
|
||||
m_textureId=0;
|
||||
|
||||
m_height = 0;
|
||||
glDeleteTextures(1, (GLuint*)&m_textureId);
|
||||
m_textureId = 0;
|
||||
}
|
||||
|
||||
bool GraphingTexture::create(int texWidth, int texHeight)
|
||||
|
|
@ -29,50 +28,46 @@ bool GraphingTexture::create(int texWidth, int texHeight)
|
|||
m_width = texWidth;
|
||||
m_height = texHeight;
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
m_imageData.resize(texWidth*texHeight*4);
|
||||
for(int y=0;y<texHeight;++y)
|
||||
|
||||
m_imageData.resize(texWidth * texHeight * 4);
|
||||
for (int y = 0; y < texHeight; ++y)
|
||||
{
|
||||
// const int t=y>>5;
|
||||
GLubyte* pi=&m_imageData[y*texWidth*4];
|
||||
for(int x=0;x<texWidth;++x)
|
||||
GLubyte* pi = &m_imageData[y * texWidth * 4];
|
||||
for (int x = 0; x < texWidth; ++x)
|
||||
{
|
||||
if (x>=y)//x<2||y<2||x>253||y>253)
|
||||
if (x >= y) //x<2||y<2||x>253||y>253)
|
||||
{
|
||||
pi[0]=0;
|
||||
pi[1]=0;
|
||||
pi[2]=255;
|
||||
pi[3]=255;
|
||||
} else
|
||||
{
|
||||
pi[0]=255;
|
||||
pi[1]=0;
|
||||
pi[2]=0;
|
||||
pi[3]=255;
|
||||
pi[0] = 0;
|
||||
pi[1] = 0;
|
||||
pi[2] = 255;
|
||||
pi[3] = 255;
|
||||
}
|
||||
|
||||
pi+=4;
|
||||
else
|
||||
{
|
||||
pi[0] = 255;
|
||||
pi[1] = 0;
|
||||
pi[2] = 0;
|
||||
pi[3] = 255;
|
||||
}
|
||||
|
||||
pi += 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
glGenTextures(1,(GLuint*)&m_textureId);
|
||||
|
||||
|
||||
glGenTextures(1, (GLuint*)&m_textureId);
|
||||
|
||||
uploadImageData();
|
||||
return true;
|
||||
}
|
||||
|
||||
void GraphingTexture::uploadImageData()
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D,m_textureId);
|
||||
assert(glGetError()==GL_NO_ERROR);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width,m_height,0,GL_RGBA,GL_UNSIGNED_BYTE,&m_imageData[0]);
|
||||
glBindTexture(GL_TEXTURE_2D, m_textureId);
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &m_imageData[0]);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
assert(glGetError()==GL_NO_ERROR);
|
||||
|
||||
|
||||
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -9,38 +9,37 @@ struct GraphingTexture
|
|||
btAlignedObjectArray<unsigned char> m_imageData;
|
||||
int m_width;
|
||||
int m_height;
|
||||
|
||||
|
||||
GraphingTexture();
|
||||
virtual ~GraphingTexture();
|
||||
|
||||
|
||||
bool create(int texWidth, int texHeight);
|
||||
void destroy();
|
||||
|
||||
void destroy();
|
||||
|
||||
void setPixel(int x, int y, unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha)
|
||||
{
|
||||
if (y>=0 && y<m_height && x>=0 && x<m_width)
|
||||
if (y >= 0 && y < m_height && x >= 0 && x < m_width)
|
||||
{
|
||||
m_imageData[x*4+y*4*m_width+0] = red;
|
||||
m_imageData[x*4+y*4*m_width+1] = green;
|
||||
m_imageData[x*4+y*4*m_width+2] = blue;
|
||||
m_imageData[x*4+y*4*m_width+3] = alpha;
|
||||
m_imageData[x * 4 + y * 4 * m_width + 0] = red;
|
||||
m_imageData[x * 4 + y * 4 * m_width + 1] = green;
|
||||
m_imageData[x * 4 + y * 4 * m_width + 2] = blue;
|
||||
m_imageData[x * 4 + y * 4 * m_width + 3] = alpha;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void getPixel(int x, int y, unsigned char& red, unsigned char& green, unsigned char& blue, unsigned char& alpha)
|
||||
{
|
||||
red = m_imageData[x*4+y*4*m_width+0];
|
||||
green = m_imageData[x*4+y*4*m_width+1];
|
||||
blue = m_imageData[x*4+y*4*m_width+2];
|
||||
alpha = m_imageData[x*4+y*4*m_width+3];
|
||||
red = m_imageData[x * 4 + y * 4 * m_width + 0];
|
||||
green = m_imageData[x * 4 + y * 4 * m_width + 1];
|
||||
blue = m_imageData[x * 4 + y * 4 * m_width + 2];
|
||||
alpha = m_imageData[x * 4 + y * 4 * m_width + 3];
|
||||
}
|
||||
void uploadImageData();
|
||||
|
||||
|
||||
int getTextureId()
|
||||
{
|
||||
return m_textureId;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //GRAPHING_TEXTURE_H
|
||||
|
||||
#endif //GRAPHING_TEXTURE_H
|
||||
|
|
|
|||
|
|
@ -1,51 +1,64 @@
|
|||
#include "GwenParameterInterface.h"
|
||||
#include "gwenInternalData.h"
|
||||
|
||||
#include <cstring>
|
||||
#ifdef _WIN32
|
||||
#define safe_printf _snprintf
|
||||
#else
|
||||
#define safe_printf snprintf
|
||||
#endif
|
||||
struct MyButtonEventHandler : public Gwen::Event::Handler
|
||||
{
|
||||
Gwen::Controls::Button* m_buttonControl;
|
||||
ButtonParamChangedCallback m_callback;
|
||||
void* m_userPointer;
|
||||
int m_buttonId;
|
||||
|
||||
MyButtonEventHandler(ButtonParamChangedCallback callback, int buttonId, void* userPointer)
|
||||
:m_callback(callback),
|
||||
m_userPointer(userPointer),
|
||||
m_buttonId(buttonId)
|
||||
MyButtonEventHandler(Gwen::Controls::Button* buttonControl, ButtonParamChangedCallback callback, int buttonId, void* userPointer)
|
||||
: m_buttonControl(buttonControl),
|
||||
m_callback(callback),
|
||||
m_userPointer(userPointer),
|
||||
m_buttonId(buttonId)
|
||||
{
|
||||
}
|
||||
|
||||
void onButtonPress( Gwen::Controls::Base* pControl )
|
||||
void onButtonPress(Gwen::Controls::Base* pControl)
|
||||
{
|
||||
if (m_callback)
|
||||
{
|
||||
(*m_callback)(m_buttonId, true, m_userPointer);
|
||||
bool buttonState = true;
|
||||
if (m_buttonControl->IsToggle())
|
||||
{
|
||||
buttonState = m_buttonControl->GetToggleState();
|
||||
}
|
||||
(*m_callback)(m_buttonId, buttonState, m_userPointer);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
struct MySliderEventHandler : public Gwen::Event::Handler
|
||||
{
|
||||
SliderParamChangedCallback m_callback;
|
||||
void* m_userPointer;
|
||||
Gwen::Controls::TextBox* m_label;
|
||||
Gwen::Controls::Slider* m_pSlider;
|
||||
char m_variableName[1024];
|
||||
T* m_targetValue;
|
||||
bool m_showValue;
|
||||
bool m_showValue;
|
||||
|
||||
MySliderEventHandler(const char* varName, Gwen::Controls::TextBox* label, Gwen::Controls::Slider* pSlider, T* target, SliderParamChangedCallback callback, void* userPtr)
|
||||
: m_callback(callback),
|
||||
m_userPointer(userPtr),
|
||||
m_label(label),
|
||||
m_pSlider(pSlider),
|
||||
m_targetValue(target),
|
||||
m_showValue(true)
|
||||
|
||||
MySliderEventHandler(const char* varName, Gwen::Controls::TextBox* label, Gwen::Controls::Slider* pSlider,T* target,SliderParamChangedCallback callback)
|
||||
:m_label(label),
|
||||
m_pSlider(pSlider),
|
||||
m_targetValue(target),
|
||||
m_showValue(true),
|
||||
m_callback(callback)
|
||||
{
|
||||
memcpy(m_variableName,varName,strlen(varName)+1);
|
||||
strncpy(m_variableName, varName, sizeof(m_variableName));
|
||||
}
|
||||
|
||||
|
||||
void SliderMoved( Gwen::Controls::Base* pControl )
|
||||
void SliderMoved(Gwen::Controls::Base* pControl)
|
||||
{
|
||||
Gwen::Controls::Slider* pSlider = (Gwen::Controls::Slider*)pControl;
|
||||
//printf("value = %f\n", pSlider->GetValue());//UnitPrint( Utility::Format( L"Slider Value: %.2f", pSlider->GetValue() ) );
|
||||
|
|
@ -55,12 +68,11 @@ struct MySliderEventHandler : public Gwen::Event::Handler
|
|||
|
||||
if (m_callback)
|
||||
{
|
||||
(*m_callback)(v);
|
||||
(*m_callback)(v, m_userPointer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SetValue(T v)
|
||||
void SetValue(T v)
|
||||
{
|
||||
if (v < m_pSlider->GetRangeMin())
|
||||
{
|
||||
|
|
@ -69,24 +81,21 @@ struct MySliderEventHandler : public Gwen::Event::Handler
|
|||
|
||||
if (v > m_pSlider->GetRangeMax())
|
||||
{
|
||||
printf("?\n");
|
||||
|
||||
printf("?\n");
|
||||
}
|
||||
m_pSlider->SetValue(v,true);
|
||||
m_pSlider->SetValue(v, true);
|
||||
(*m_targetValue) = v;
|
||||
float val = float(v);//todo: specialize on template type
|
||||
if (m_showValue)
|
||||
{
|
||||
char txt[1024];
|
||||
sprintf(txt,"%s : %.3f", m_variableName,val);
|
||||
m_label->SetText(txt);
|
||||
}
|
||||
|
||||
float val = float(v); //todo: specialize on template type
|
||||
if (m_showValue)
|
||||
{
|
||||
char txt[1024];
|
||||
safe_printf(txt, sizeof(txt), "%s : %.3f", m_variableName, val);
|
||||
m_label->SetText(txt);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct GwenParameters
|
||||
struct GwenParameters
|
||||
{
|
||||
b3AlignedObjectArray<MySliderEventHandler<btScalar>*> m_sliderEventHandlers;
|
||||
b3AlignedObjectArray<Gwen::Controls::HorizontalSlider*> m_sliders;
|
||||
|
|
@ -98,112 +107,103 @@ struct GwenParameters
|
|||
};
|
||||
|
||||
GwenParameterInterface::GwenParameterInterface(GwenInternalData* gwenInternalData)
|
||||
:m_gwenInternalData(gwenInternalData)
|
||||
: m_gwenInternalData(gwenInternalData)
|
||||
{
|
||||
m_paramInternalData = new GwenParameters;
|
||||
m_paramInternalData->m_savedYposition = m_gwenInternalData->m_curYposition;
|
||||
|
||||
}
|
||||
|
||||
GwenParameterInterface::~GwenParameterInterface()
|
||||
{
|
||||
|
||||
removeAllParameters();
|
||||
delete m_paramInternalData;
|
||||
}
|
||||
|
||||
|
||||
void GwenParameterInterface::setSliderValue(int sliderIndex, double sliderValue)
|
||||
{
|
||||
int sliderCapped = sliderValue+4;
|
||||
sliderCapped /= 8;
|
||||
sliderCapped *= 8;
|
||||
|
||||
if (sliderIndex>=0 && sliderIndex<m_paramInternalData->m_sliders.size())
|
||||
{
|
||||
m_paramInternalData->m_sliders[sliderIndex]->GetRangeMin();
|
||||
|
||||
m_paramInternalData->m_sliders[sliderIndex]->GetRangeMax();
|
||||
float mappedValue =m_paramInternalData->m_sliders[sliderIndex]->GetRangeMin()+
|
||||
(m_paramInternalData->m_sliders[sliderIndex]->GetRangeMax()-
|
||||
m_paramInternalData->m_sliders[sliderIndex]->GetRangeMin())*sliderCapped/128.f;
|
||||
printf("mappedValue = %f\n",mappedValue);
|
||||
m_paramInternalData->m_sliders[sliderIndex]->SetValue(mappedValue);
|
||||
}
|
||||
int sliderCapped = sliderValue + 4;
|
||||
sliderCapped /= 8;
|
||||
sliderCapped *= 8;
|
||||
|
||||
if (sliderIndex >= 0 && sliderIndex < m_paramInternalData->m_sliders.size())
|
||||
{
|
||||
m_paramInternalData->m_sliders[sliderIndex]->GetRangeMin();
|
||||
|
||||
m_paramInternalData->m_sliders[sliderIndex]->GetRangeMax();
|
||||
float mappedValue = m_paramInternalData->m_sliders[sliderIndex]->GetRangeMin() +
|
||||
(m_paramInternalData->m_sliders[sliderIndex]->GetRangeMax() -
|
||||
m_paramInternalData->m_sliders[sliderIndex]->GetRangeMin()) *
|
||||
sliderCapped / 128.f;
|
||||
printf("mappedValue = %f\n", mappedValue);
|
||||
m_paramInternalData->m_sliders[sliderIndex]->SetValue(mappedValue);
|
||||
}
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void GwenParameterInterface::registerButtonParameter(ButtonParams& params)
|
||||
{
|
||||
|
||||
Gwen::Controls::Button* button = new Gwen::Controls::Button(m_gwenInternalData->m_demoPage->GetPage());
|
||||
MyButtonEventHandler* handler = new MyButtonEventHandler(params.m_callback,params.m_buttonId,params.m_userPointer);
|
||||
MyButtonEventHandler* handler = new MyButtonEventHandler(button, params.m_callback, params.m_buttonId, params.m_userPointer);
|
||||
button->SetText(params.m_name);
|
||||
button->onPress.Add( handler, &MyButtonEventHandler::onButtonPress );
|
||||
button->SetIsToggle(params.m_isTrigger);
|
||||
|
||||
button->onPress.Add(handler, &MyButtonEventHandler::onButtonPress);
|
||||
button->SetIsToggle(params.m_isTrigger);
|
||||
button->SetToggleState(params.m_initialState);
|
||||
|
||||
m_paramInternalData->m_buttons.push_back(button);
|
||||
m_paramInternalData->m_buttonEventHandlers.push_back(handler);
|
||||
|
||||
button->SetPos( 5, m_gwenInternalData->m_curYposition );
|
||||
button->SetPos(5, m_gwenInternalData->m_curYposition);
|
||||
button->SetWidth(220);
|
||||
|
||||
m_gwenInternalData->m_curYposition+=22;
|
||||
|
||||
m_gwenInternalData->m_curYposition += 22;
|
||||
}
|
||||
|
||||
struct MyComboBoxHander2 :public Gwen::Event::Handler
|
||||
struct MyComboBoxHander2 : public Gwen::Event::Handler
|
||||
{
|
||||
GwenInternalData* m_data;
|
||||
int m_buttonId;
|
||||
ComboBoxCallback m_callback;
|
||||
void* m_userPointer;
|
||||
GwenInternalData* m_data;
|
||||
int m_buttonId;
|
||||
ComboBoxCallback m_callback;
|
||||
void* m_userPointer;
|
||||
|
||||
MyComboBoxHander2 (GwenInternalData* data, int buttonId,ComboBoxCallback callback, void* userPointer)
|
||||
:m_data(data),
|
||||
m_buttonId(buttonId),
|
||||
m_callback(callback),
|
||||
m_userPointer(userPointer)
|
||||
MyComboBoxHander2(GwenInternalData* data, int buttonId, ComboBoxCallback callback, void* userPointer)
|
||||
: m_data(data),
|
||||
m_buttonId(buttonId),
|
||||
m_callback(callback),
|
||||
m_userPointer(userPointer)
|
||||
{
|
||||
}
|
||||
|
||||
void onSelect( Gwen::Controls::Base* pControl )
|
||||
void onSelect(Gwen::Controls::Base* pControl)
|
||||
{
|
||||
Gwen::Controls::ComboBox* but = (Gwen::Controls::ComboBox*) pControl;
|
||||
Gwen::Controls::ComboBox* but = (Gwen::Controls::ComboBox*)pControl;
|
||||
|
||||
Gwen::String str = Gwen::Utility::UnicodeToString( but->GetSelectedItem()->GetText());
|
||||
Gwen::String str = Gwen::Utility::UnicodeToString(but->GetSelectedItem()->GetText());
|
||||
|
||||
if (m_callback)
|
||||
(*m_callback)(m_buttonId,str.c_str(),m_userPointer);
|
||||
(*m_callback)(m_buttonId, str.c_str(), m_userPointer);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
void GwenParameterInterface::registerComboBox(ComboBoxParams& params)
|
||||
{
|
||||
Gwen::Controls::ComboBox* combobox = new Gwen::Controls::ComboBox(m_gwenInternalData->m_demoPage->GetPage());
|
||||
m_paramInternalData->m_comboBoxes.push_back(combobox);
|
||||
MyComboBoxHander2* handler = new MyComboBoxHander2(m_gwenInternalData, params.m_comboboxId,params.m_callback, params.m_userPointer);
|
||||
MyComboBoxHander2* handler = new MyComboBoxHander2(m_gwenInternalData, params.m_comboboxId, params.m_callback, params.m_userPointer);
|
||||
m_gwenInternalData->m_handlers.push_back(handler);
|
||||
|
||||
combobox->onSelection.Add(handler,&MyComboBoxHander2::onSelect);
|
||||
combobox->onSelection.Add(handler, &MyComboBoxHander2::onSelect);
|
||||
int ypos = m_gwenInternalData->m_curYposition;
|
||||
m_gwenInternalData->m_curYposition+=22;
|
||||
combobox->SetPos(5, ypos );
|
||||
combobox->SetWidth( 220 );
|
||||
m_gwenInternalData->m_curYposition += 22;
|
||||
combobox->SetPos(5, ypos);
|
||||
combobox->SetWidth(220);
|
||||
//box->SetPos(120,130);
|
||||
for (int i=0;i<params.m_numItems;i++)
|
||||
for (int i = 0; i < params.m_numItems; i++)
|
||||
{
|
||||
Gwen::Controls::MenuItem* item = combobox->AddItem(Gwen::Utility::StringToUnicode(params.m_items[i]));
|
||||
if (i==params.m_startItem)
|
||||
if (i == params.m_startItem)
|
||||
combobox->OnItemSelected(item);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void GwenParameterInterface::registerSliderFloatParameter(SliderParams& params)
|
||||
|
|
@ -211,91 +211,94 @@ void GwenParameterInterface::registerSliderFloatParameter(SliderParams& params)
|
|||
Gwen::Controls::TextBox* label = new Gwen::Controls::TextBox(m_gwenInternalData->m_demoPage->GetPage());
|
||||
m_paramInternalData->m_textLabels.push_back(label);
|
||||
//m_data->m_myControls.push_back(label);
|
||||
label->SetText( params.m_name);
|
||||
label->SetPos( 10, 10 + 25 );
|
||||
label->SetText(params.m_name);
|
||||
label->SetPos(10, 10 + 25);
|
||||
label->SetWidth(210);
|
||||
label->SetPos(10,m_gwenInternalData->m_curYposition);
|
||||
m_gwenInternalData->m_curYposition+=22;
|
||||
label->SetPos(10, m_gwenInternalData->m_curYposition);
|
||||
m_gwenInternalData->m_curYposition += 22;
|
||||
|
||||
Gwen::Controls::HorizontalSlider* pSlider = new Gwen::Controls::HorizontalSlider( m_gwenInternalData->m_demoPage->GetPage());
|
||||
Gwen::Controls::HorizontalSlider* pSlider = new Gwen::Controls::HorizontalSlider(m_gwenInternalData->m_demoPage->GetPage());
|
||||
m_paramInternalData->m_sliders.push_back(pSlider);
|
||||
//m_data->m_myControls.push_back(pSlider);
|
||||
pSlider->SetPos( 10, m_gwenInternalData->m_curYposition );
|
||||
pSlider->SetSize( 200, 20 );
|
||||
pSlider->SetRange( params.m_minVal, params.m_maxVal);
|
||||
pSlider->SetNotchCount(16);//float(params.m_maxVal-params.m_minVal)/100.f);
|
||||
pSlider->SetClampToNotches( params.m_clampToNotches );
|
||||
pSlider->SetValue( *params.m_paramValuePointer);//dimensions[i] );
|
||||
pSlider->SetPos(10, m_gwenInternalData->m_curYposition);
|
||||
pSlider->SetSize(200, 20);
|
||||
pSlider->SetRange(params.m_minVal, params.m_maxVal);
|
||||
if (params.m_clampToIntegers)
|
||||
{
|
||||
pSlider->SetNotchCount(int(params.m_maxVal - params.m_minVal));
|
||||
pSlider->SetClampToNotches(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
pSlider->SetNotchCount(16); //float(params.m_maxVal-params.m_minVal)/100.f);
|
||||
pSlider->SetClampToNotches(params.m_clampToNotches);
|
||||
}
|
||||
pSlider->SetValue(*params.m_paramValuePointer); //dimensions[i] );
|
||||
char labelName[1024];
|
||||
sprintf(labelName,"%s",params.m_name);//axisNames[0]);
|
||||
MySliderEventHandler<btScalar>* handler = new MySliderEventHandler<btScalar>(labelName,label,pSlider,params.m_paramValuePointer,params.m_callback);
|
||||
handler->m_showValue = params.m_showValues;
|
||||
safe_printf(labelName, sizeof(labelName), "%s", params.m_name); //axisNames[0]);
|
||||
MySliderEventHandler<btScalar>* handler = new MySliderEventHandler<btScalar>(labelName, label, pSlider, params.m_paramValuePointer, params.m_callback, params.m_userPointer);
|
||||
handler->m_showValue = params.m_showValues;
|
||||
m_paramInternalData->m_sliderEventHandlers.push_back(handler);
|
||||
|
||||
pSlider->onValueChanged.Add( handler, &MySliderEventHandler<btScalar>::SliderMoved );
|
||||
pSlider->onValueChanged.Add(handler, &MySliderEventHandler<btScalar>::SliderMoved);
|
||||
handler->SliderMoved(pSlider);
|
||||
// float v = pSlider->GetValue();
|
||||
m_gwenInternalData->m_curYposition+=22;
|
||||
// float v = pSlider->GetValue();
|
||||
m_gwenInternalData->m_curYposition += 22;
|
||||
}
|
||||
|
||||
void GwenParameterInterface::syncParameters()
|
||||
{
|
||||
for (int i=0;i<m_paramInternalData->m_sliderEventHandlers.size();i++)
|
||||
for (int i = 0; i < m_paramInternalData->m_sliderEventHandlers.size(); i++)
|
||||
{
|
||||
MySliderEventHandler<btScalar>* handler = m_paramInternalData->m_sliderEventHandlers[i];
|
||||
handler->m_pSlider->SetValue(*handler->m_targetValue,true);
|
||||
handler->m_pSlider->SetValue(*handler->m_targetValue, true);
|
||||
}
|
||||
}
|
||||
|
||||
void GwenParameterInterface::removeAllParameters()
|
||||
{
|
||||
|
||||
for (int i=0;i<m_paramInternalData->m_buttons.size();i++)
|
||||
for (int i = 0; i < m_paramInternalData->m_buttons.size(); i++)
|
||||
{
|
||||
delete m_paramInternalData->m_buttons[i];
|
||||
}
|
||||
m_paramInternalData->m_buttons.clear();
|
||||
|
||||
for (int i=0;i<m_paramInternalData->m_buttonEventHandlers.size();i++)
|
||||
|
||||
for (int i = 0; i < m_paramInternalData->m_buttonEventHandlers.size(); i++)
|
||||
{
|
||||
delete m_paramInternalData->m_buttonEventHandlers[i];
|
||||
}
|
||||
m_paramInternalData->m_buttonEventHandlers.clear();
|
||||
|
||||
|
||||
m_gwenInternalData->m_curYposition+=22;
|
||||
|
||||
|
||||
for (int i=0;i<m_paramInternalData->m_sliders.size();i++)
|
||||
m_gwenInternalData->m_curYposition += 22;
|
||||
|
||||
for (int i = 0; i < m_paramInternalData->m_sliders.size(); i++)
|
||||
{
|
||||
delete m_paramInternalData->m_sliders[i];
|
||||
}
|
||||
m_paramInternalData->m_sliders.clear();
|
||||
|
||||
for (int i=0;i<m_paramInternalData->m_sliderEventHandlers.size();i++)
|
||||
for (int i = 0; i < m_paramInternalData->m_sliderEventHandlers.size(); i++)
|
||||
{
|
||||
delete m_paramInternalData->m_sliderEventHandlers[i];
|
||||
}
|
||||
m_paramInternalData->m_sliderEventHandlers.clear();
|
||||
|
||||
for (int i=0;i<m_paramInternalData->m_textLabels.size();i++)
|
||||
|
||||
for (int i = 0; i < m_paramInternalData->m_textLabels.size(); i++)
|
||||
{
|
||||
delete m_paramInternalData->m_textLabels[i];
|
||||
}
|
||||
m_paramInternalData->m_textLabels.clear();
|
||||
|
||||
for (int i=0;i<m_paramInternalData->m_comboBoxes.size();i++)
|
||||
|
||||
for (int i = 0; i < m_paramInternalData->m_comboBoxes.size(); i++)
|
||||
{
|
||||
delete m_paramInternalData->m_comboBoxes[i];
|
||||
}
|
||||
m_paramInternalData->m_comboBoxes.clear();
|
||||
|
||||
m_gwenInternalData->m_curYposition = this->m_paramInternalData->m_savedYposition;
|
||||
for (int i=0;i<m_gwenInternalData->m_handlers.size();i++)
|
||||
for (int i = 0; i < m_gwenInternalData->m_handlers.size(); i++)
|
||||
{
|
||||
delete m_gwenInternalData->m_handlers[i];
|
||||
}
|
||||
m_gwenInternalData->m_handlers.clear();
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ struct GwenParameterInterface : public CommonParameterInterface
|
|||
{
|
||||
struct GwenInternalData* m_gwenInternalData;
|
||||
|
||||
struct GwenParameters* m_paramInternalData;
|
||||
struct GwenParameters* m_paramInternalData;
|
||||
|
||||
GwenParameterInterface(struct GwenInternalData* gwenInternalData);
|
||||
virtual ~GwenParameterInterface();
|
||||
|
|
@ -15,12 +15,9 @@ struct GwenParameterInterface : public CommonParameterInterface
|
|||
virtual void registerButtonParameter(ButtonParams& params);
|
||||
virtual void registerComboBox(ComboBoxParams& params);
|
||||
|
||||
virtual void setSliderValue(int sliderIndex, double sliderValue);
|
||||
virtual void setSliderValue(int sliderIndex, double sliderValue);
|
||||
virtual void syncParameters();
|
||||
virtual void removeAllParameters();
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif//GWEN_PARAMETER_INTERFACE_H
|
||||
#endif //GWEN_PARAMETER_INTERFACE_H
|
||||
|
|
|
|||
|
|
@ -3,297 +3,271 @@
|
|||
#include "gwenInternalData.h"
|
||||
#include "LinearMath/btQuickprof.h"
|
||||
|
||||
|
||||
#ifndef BT_NO_PROFILE
|
||||
|
||||
#ifndef BT_NO_PROFILE
|
||||
|
||||
class MyProfileWindow : public Gwen::Controls::WindowControl
|
||||
{
|
||||
|
||||
// Gwen::Controls::TabControl* m_TabControl;
|
||||
//Gwen::Controls::ListBox* m_TextOutput;
|
||||
unsigned int m_iFrames;
|
||||
float m_fLastSecond;
|
||||
|
||||
unsigned int m_iFrames;
|
||||
float m_fLastSecond;
|
||||
|
||||
Gwen::Controls::TreeNode* m_node;
|
||||
Gwen::Controls::TreeControl* m_ctrl;
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
void onButtonA( Gwen::Controls::Base* pControl )
|
||||
void onButtonA(Gwen::Controls::Base* pControl)
|
||||
{
|
||||
// OpenTissue::glut::toggleIdle();
|
||||
// OpenTissue::glut::toggleIdle();
|
||||
}
|
||||
|
||||
void SliderMoved(Gwen::Controls::Base* pControl )
|
||||
|
||||
void SliderMoved(Gwen::Controls::Base* pControl)
|
||||
{
|
||||
// Gwen::Controls::Slider* pSlider = (Gwen::Controls::Slider*)pControl;
|
||||
// Gwen::Controls::Slider* pSlider = (Gwen::Controls::Slider*)pControl;
|
||||
//this->m_app->scaleYoungModulus(pSlider->GetValue());
|
||||
// printf("Slider Value: %.2f", pSlider->GetValue() );
|
||||
}
|
||||
|
||||
|
||||
void OnCheckChangedStiffnessWarping (Gwen::Controls::Base* pControl)
|
||||
|
||||
void OnCheckChangedStiffnessWarping(Gwen::Controls::Base* pControl)
|
||||
{
|
||||
// Gwen::Controls::CheckBox* labeled = (Gwen::Controls::CheckBox* )pControl;
|
||||
// bool checked = labeled->IsChecked();
|
||||
// Gwen::Controls::CheckBox* labeled = (Gwen::Controls::CheckBox* )pControl;
|
||||
// bool checked = labeled->IsChecked();
|
||||
//m_app->m_stiffness_warp_on = checked;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
|
||||
CProfileIterator* profIter;
|
||||
|
||||
class MyMenuItems* m_menuItems;
|
||||
MyProfileWindow ( Gwen::Controls::Base* pParent)
|
||||
: Gwen::Controls::WindowControl( pParent ),
|
||||
profIter(0)
|
||||
|
||||
class MyMenuItems3* m_menuItems;
|
||||
MyProfileWindow(Gwen::Controls::Base* pParent)
|
||||
: Gwen::Controls::WindowControl(pParent),
|
||||
profIter(0)
|
||||
{
|
||||
SetTitle( L"Time Profiler" );
|
||||
|
||||
SetSize( 450, 450 );
|
||||
this->SetPos(10,400);
|
||||
|
||||
// this->Dock( Gwen::Pos::Bottom);
|
||||
|
||||
|
||||
|
||||
SetTitle(L"Time Profiler");
|
||||
|
||||
SetSize(450, 450);
|
||||
this->SetPos(10, 400);
|
||||
|
||||
// this->Dock( Gwen::Pos::Bottom);
|
||||
|
||||
{
|
||||
m_ctrl = new Gwen::Controls::TreeControl( this );
|
||||
m_node = m_ctrl->AddNode( L"Total Parent Time" );
|
||||
|
||||
|
||||
m_ctrl = new Gwen::Controls::TreeControl(this);
|
||||
m_node = m_ctrl->AddNode(L"Total Parent Time");
|
||||
|
||||
//Gwen::Controls::TreeNode* pNode = ctrl->AddNode( L"Node Two" );
|
||||
//pNode->AddNode( L"Node Two Inside" );
|
||||
//pNode->AddNode( L"Eyes" );
|
||||
//pNode->AddNode( L"Brown" )->AddNode( L"Node Two Inside" )->AddNode( L"Eyes" )->AddNode( L"Brown" );
|
||||
//Gwen::Controls::TreeNode* node = ctrl->AddNode( L"Node Three" );
|
||||
|
||||
|
||||
|
||||
|
||||
//m_ctrl->Dock(Gwen::Pos::Bottom);
|
||||
|
||||
|
||||
m_ctrl->ExpandAll();
|
||||
m_ctrl->SetKeyboardInputEnabled(true);
|
||||
m_ctrl->SetBounds( this->GetInnerBounds().x,this->GetInnerBounds().y,this->GetInnerBounds().w,this->GetInnerBounds().h);
|
||||
|
||||
m_ctrl->SetKeyboardInputEnabled(true);
|
||||
m_ctrl->SetBounds(this->GetInnerBounds().x, this->GetInnerBounds().y, this->GetInnerBounds().w, this->GetInnerBounds().h);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
virtual ~MyProfileWindow()
|
||||
{
|
||||
|
||||
delete m_node;
|
||||
delete m_ctrl;
|
||||
}
|
||||
|
||||
float dumpRecursive(CProfileIterator* profileIterator, Gwen::Controls::TreeNode* parentNode)
|
||||
|
||||
float dumpRecursive(CProfileIterator* profileIterator, Gwen::Controls::TreeNode* parentNode)
|
||||
{
|
||||
profileIterator->First();
|
||||
if (profileIterator->Is_Done())
|
||||
return 0.f;
|
||||
|
||||
float accumulated_time=0,parent_time = profileIterator->Is_Root() ? CProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time();
|
||||
|
||||
float accumulated_time = 0, parent_time = profileIterator->Is_Root() ? CProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time();
|
||||
int i;
|
||||
int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset();
|
||||
if (0==frames_since_reset)
|
||||
if (0 == frames_since_reset)
|
||||
return 0.f;
|
||||
|
||||
|
||||
//printf("Profiling: %s (total running time: %.3f ms) ---\n", profileIterator->Get_Current_Parent_Name(), parent_time );
|
||||
float totalTime = 0.f;
|
||||
|
||||
|
||||
|
||||
int numChildren = 0;
|
||||
Gwen::UnicodeString txt;
|
||||
std::vector<Gwen::Controls::TreeNode*> nodes;
|
||||
|
||||
for (i = 0; !profileIterator->Is_Done(); i++,profileIterator->Next())
|
||||
|
||||
for (i = 0; !profileIterator->Is_Done(); i++, profileIterator->Next())
|
||||
{
|
||||
numChildren++;
|
||||
float current_total_time = profileIterator->Get_Current_Total_Time();
|
||||
accumulated_time += current_total_time;
|
||||
double fraction = parent_time > SIMD_EPSILON ? (current_total_time / parent_time) * 100 : 0.f;
|
||||
|
||||
|
||||
Gwen::String name(profileIterator->Get_Current_Name());
|
||||
#ifdef _WIN32
|
||||
Gwen::UnicodeString uname = Gwen::Utility::StringToUnicode(name);
|
||||
|
||||
txt = Gwen::Utility::Format(L"%s (%.2f %%) :: %.3f ms / frame (%d calls)",uname.c_str(), fraction,(current_total_time / (double)frames_since_reset),profileIterator->Get_Current_Total_Calls());
|
||||
|
||||
|
||||
txt = Gwen::Utility::Format(L"%s (%.2f %%) :: %.3f ms / frame (%d calls)", uname.c_str(), fraction, (current_total_time / (double)frames_since_reset), profileIterator->Get_Current_Total_Calls());
|
||||
|
||||
#else
|
||||
txt = Gwen::Utility::Format(L"%s (%.2f %%) :: %.3f ms / frame (%d calls)",name.c_str(), fraction,(current_total_time / (double)frames_since_reset),profileIterator->Get_Current_Total_Calls());
|
||||
|
||||
txt = Gwen::Utility::Format(L"%s (%.2f %%) :: %.3f ms / frame (%d calls)", name.c_str(), fraction, (current_total_time / (double)frames_since_reset), profileIterator->Get_Current_Total_Calls());
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Gwen::Controls::TreeNode* childNode = (Gwen::Controls::TreeNode*)profileIterator->Get_Current_UserPointer();
|
||||
if (!childNode)
|
||||
{
|
||||
childNode = parentNode->AddNode(L"");
|
||||
profileIterator->Set_Current_UserPointer(childNode);
|
||||
childNode = parentNode->AddNode(L"");
|
||||
profileIterator->Set_Current_UserPointer(childNode);
|
||||
}
|
||||
childNode->SetText(txt);
|
||||
nodes.push_back(childNode);
|
||||
|
||||
|
||||
totalTime += current_total_time;
|
||||
//recurse into children
|
||||
}
|
||||
|
||||
for (i=0;i<numChildren;i++)
|
||||
|
||||
for (i = 0; i < numChildren; i++)
|
||||
{
|
||||
profileIterator->Enter_Child(i);
|
||||
Gwen::Controls::TreeNode* curNode = nodes[i];
|
||||
|
||||
|
||||
dumpRecursive(profileIterator, curNode);
|
||||
|
||||
|
||||
profileIterator->Enter_Parent();
|
||||
}
|
||||
return accumulated_time;
|
||||
|
||||
}
|
||||
|
||||
void UpdateText(CProfileIterator* profileIterator, bool idle)
|
||||
|
||||
void UpdateText(CProfileIterator* profileIterator, bool idle)
|
||||
{
|
||||
|
||||
// static bool update=true;
|
||||
|
||||
m_ctrl->SetBounds(0,0,this->GetInnerBounds().w,this->GetInnerBounds().h);
|
||||
|
||||
// if (!update)
|
||||
// return;
|
||||
// update=false;
|
||||
|
||||
|
||||
// static bool update=true;
|
||||
|
||||
m_ctrl->SetBounds(0, 0, this->GetInnerBounds().w, this->GetInnerBounds().h);
|
||||
|
||||
// if (!update)
|
||||
// return;
|
||||
// update=false;
|
||||
|
||||
static int test = 1;
|
||||
test++;
|
||||
|
||||
|
||||
static double time_since_reset = 0.f;
|
||||
if (!idle)
|
||||
{
|
||||
time_since_reset = CProfileManager::Get_Time_Since_Reset();
|
||||
}
|
||||
|
||||
|
||||
//Gwen::UnicodeString txt = Gwen::Utility::Format( L"FEM Settings %i fps", test );
|
||||
{
|
||||
//recompute profiling data, and store profile strings
|
||||
|
||||
// char blockTime[128];
|
||||
|
||||
// double totalTime = 0;
|
||||
|
||||
// int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset();
|
||||
|
||||
profileIterator->First();
|
||||
|
||||
double parent_time = profileIterator->Is_Root() ? time_since_reset : profileIterator->Get_Current_Parent_Total_Time();
|
||||
|
||||
|
||||
// Gwen::Controls::TreeNode* curParent = m_node;
|
||||
|
||||
double accumulated_time = dumpRecursive(profileIterator,m_node);
|
||||
|
||||
const char* name = profileIterator->Get_Current_Parent_Name();
|
||||
//recompute profiling data, and store profile strings
|
||||
|
||||
// char blockTime[128];
|
||||
|
||||
// double totalTime = 0;
|
||||
|
||||
// int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset();
|
||||
|
||||
profileIterator->First();
|
||||
|
||||
double parent_time = profileIterator->Is_Root() ? time_since_reset : profileIterator->Get_Current_Parent_Total_Time();
|
||||
|
||||
// Gwen::Controls::TreeNode* curParent = m_node;
|
||||
|
||||
double accumulated_time = dumpRecursive(profileIterator, m_node);
|
||||
|
||||
const char* name = profileIterator->Get_Current_Parent_Name();
|
||||
#ifdef _WIN32
|
||||
Gwen::UnicodeString uname = Gwen::Utility::StringToUnicode(name);
|
||||
Gwen::UnicodeString txt = Gwen::Utility::Format( L"Profiling: %s total time: %.3f ms, unaccounted %.3f %% :: %.3f ms", uname.c_str(), parent_time ,
|
||||
parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time);
|
||||
Gwen::UnicodeString uname = Gwen::Utility::StringToUnicode(name);
|
||||
Gwen::UnicodeString txt = Gwen::Utility::Format(L"Profiling: %s total time: %.3f ms, unaccounted %.3f %% :: %.3f ms", uname.c_str(), parent_time,
|
||||
parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time);
|
||||
#else
|
||||
Gwen::UnicodeString txt = Gwen::Utility::Format( L"Profiling: %s total time: %.3f ms, unaccounted %.3f %% :: %.3f ms", name, parent_time ,
|
||||
parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time);
|
||||
Gwen::UnicodeString txt = Gwen::Utility::Format(L"Profiling: %s total time: %.3f ms, unaccounted %.3f %% :: %.3f ms", name, parent_time,
|
||||
parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time);
|
||||
#endif
|
||||
//sprintf(blockTime,"--- Profiling: %s (total running time: %.3f ms) ---", profileIterator->Get_Current_Parent_Name(), parent_time );
|
||||
//displayProfileString(xOffset,yStart,blockTime);
|
||||
m_node->SetText(txt);
|
||||
|
||||
|
||||
//sprintf(blockTime,"--- Profiling: %s (total running time: %.3f ms) ---", profileIterator->Get_Current_Parent_Name(), parent_time );
|
||||
//displayProfileString(xOffset,yStart,blockTime);
|
||||
m_node->SetText(txt);
|
||||
|
||||
//printf("%s (%.3f %%) :: %.3f ms\n", "Unaccounted:",);
|
||||
|
||||
|
||||
}
|
||||
|
||||
static int counter=10;
|
||||
|
||||
static int counter = 10;
|
||||
if (counter)
|
||||
{
|
||||
counter--;
|
||||
counter--;
|
||||
m_ctrl->ExpandAll();
|
||||
}
|
||||
|
||||
}
|
||||
void PrintText( const Gwen::UnicodeString& str )
|
||||
void PrintText(const Gwen::UnicodeString& str)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Render( Gwen::Skin::Base* skin )
|
||||
|
||||
void Render(Gwen::Skin::Base* skin)
|
||||
{
|
||||
m_iFrames++;
|
||||
|
||||
if ( m_fLastSecond < Gwen::Platform::GetTimeInSeconds() )
|
||||
|
||||
if (m_fLastSecond < Gwen::Platform::GetTimeInSeconds())
|
||||
{
|
||||
SetTitle( Gwen::Utility::Format( L"Profiler %i fps", m_iFrames ) );
|
||||
|
||||
SetTitle(Gwen::Utility::Format(L"Profiler %i fps", m_iFrames));
|
||||
|
||||
m_fLastSecond = Gwen::Platform::GetTimeInSeconds() + 1.0f;
|
||||
m_iFrames = 0;
|
||||
}
|
||||
|
||||
Gwen::Controls::WindowControl::Render( skin );
|
||||
|
||||
|
||||
Gwen::Controls::WindowControl::Render(skin);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
class MyMenuItems : public Gwen::Controls::Base
|
||||
class MyMenuItems3 : public Gwen::Controls::Base
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
class MyProfileWindow* m_profWindow;
|
||||
MyMenuItems() :Gwen::Controls::Base(0)
|
||||
{
|
||||
}
|
||||
|
||||
void MenuItemSelect(Gwen::Controls::Base* pControl)
|
||||
{
|
||||
MyMenuItems3() : Gwen::Controls::Base(0)
|
||||
{
|
||||
}
|
||||
virtual ~MyMenuItems3() {}
|
||||
|
||||
void MenuItemSelect(Gwen::Controls::Base* pControl)
|
||||
{
|
||||
if (m_profWindow->Hidden())
|
||||
{
|
||||
m_profWindow->SetHidden(false);
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
m_profWindow->SetHidden(true);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
MyProfileWindow* setupProfileWindow(GwenInternalData* data)
|
||||
{
|
||||
MyMenuItems* menuItems = new MyMenuItems;
|
||||
|
||||
MyMenuItems3* menuItems = new MyMenuItems3;
|
||||
|
||||
MyProfileWindow* profWindow = new MyProfileWindow(data->pCanvas);
|
||||
//profWindow->SetHidden(true);
|
||||
|
||||
//profWindow->SetHidden(true);
|
||||
|
||||
profWindow->m_menuItems = menuItems;
|
||||
//profWindow->profIter = CProfileManager::Get_Iterator();
|
||||
data->m_viewMenu->GetMenu()->AddItem( L"Profiler", menuItems,(Gwen::Event::Handler::Function)&MyMenuItems::MenuItemSelect);
|
||||
|
||||
profWindow->profIter = CProfileManager::Get_Iterator();
|
||||
data->m_viewMenu->GetMenu()->AddItem(L"Profiler", menuItems, (Gwen::Event::Handler::Function)&MyMenuItems3::MenuItemSelect);
|
||||
|
||||
menuItems->m_profWindow = profWindow;
|
||||
|
||||
|
||||
return profWindow;
|
||||
}
|
||||
|
||||
|
||||
void processProfileData( MyProfileWindow* profWindow, bool idle)
|
||||
void processProfileData(MyProfileWindow* profWindow, bool idle)
|
||||
{
|
||||
if (profWindow)
|
||||
{
|
||||
|
||||
profWindow->UpdateText(profWindow->profIter, idle);
|
||||
}
|
||||
if (profWindow->profIter)
|
||||
{
|
||||
profWindow->UpdateText(profWindow->profIter, idle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool isProfileWindowVisible(MyProfileWindow* window)
|
||||
{
|
||||
return !window->Hidden();
|
||||
}
|
||||
|
||||
void profileWindowSetVisible(MyProfileWindow* window, bool visible)
|
||||
|
|
@ -303,7 +277,9 @@ void profileWindowSetVisible(MyProfileWindow* window, bool visible)
|
|||
void destroyProfileWindow(MyProfileWindow* window)
|
||||
{
|
||||
CProfileManager::Release_Iterator(window->profIter);
|
||||
delete window->m_menuItems;
|
||||
delete window;
|
||||
CProfileManager::CleanupMemory();
|
||||
}
|
||||
|
||||
#endif //BT_NO_PROFILE
|
||||
#endif //BT_NO_PROFILE
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
class MyProfileWindow* setupProfileWindow(struct GwenInternalData* data);
|
||||
void processProfileData(MyProfileWindow* window, bool idle);
|
||||
void profileWindowSetVisible(MyProfileWindow* window, bool visible);
|
||||
bool isProfileWindowVisible(MyProfileWindow* window);
|
||||
|
||||
void destroyProfileWindow(MyProfileWindow* window);
|
||||
|
||||
#endif//GWEN_PROFILE_WINDOW_H
|
||||
|
||||
|
||||
#endif //GWEN_PROFILE_WINDOW_H
|
||||
|
|
|
|||
|
|
@ -3,79 +3,70 @@
|
|||
#include "gwenInternalData.h"
|
||||
#include "Gwen/Controls/ImagePanel.h"
|
||||
|
||||
|
||||
|
||||
class MyGraphWindow : public Gwen::Controls::WindowControl
|
||||
{
|
||||
Gwen::Controls::ImagePanel* m_imgPanel;
|
||||
|
||||
public:
|
||||
|
||||
class MyMenuItems2* m_menuItems;
|
||||
|
||||
MyGraphWindow ( const MyGraphInput& input)
|
||||
: Gwen::Controls::WindowControl( input.m_data->pCanvas ),
|
||||
m_menuItems(0)
|
||||
|
||||
MyGraphWindow(const MyGraphInput& input)
|
||||
: Gwen::Controls::WindowControl(input.m_data->pCanvas),
|
||||
m_menuItems(0)
|
||||
{
|
||||
Gwen::UnicodeString str = Gwen::Utility::StringToUnicode(input.m_name);
|
||||
SetTitle( str );
|
||||
SetTitle(str);
|
||||
|
||||
SetPos(input.m_xPos, input.m_yPos);
|
||||
SetSize(12 + input.m_width + 2 * input.m_borderWidth, 30 + input.m_height + 2 * input.m_borderWidth);
|
||||
|
||||
SetPos(input.m_xPos,input.m_yPos);
|
||||
SetSize( 12+input.m_width+2*input.m_borderWidth, 30+input.m_height+2*input.m_borderWidth );
|
||||
|
||||
m_imgPanel = new Gwen::Controls::ImagePanel( this );
|
||||
m_imgPanel = new Gwen::Controls::ImagePanel(this);
|
||||
if (input.m_texName)
|
||||
{
|
||||
Gwen::UnicodeString texName = Gwen::Utility::StringToUnicode(input.m_texName);
|
||||
m_imgPanel->SetImage( texName );
|
||||
m_imgPanel->SetImage(texName);
|
||||
}
|
||||
m_imgPanel->SetBounds( input.m_borderWidth, input.m_borderWidth,
|
||||
input.m_width,
|
||||
input.m_height );
|
||||
// this->Dock( Gwen::Pos::Bottom);
|
||||
m_imgPanel->SetBounds(input.m_borderWidth, input.m_borderWidth,
|
||||
input.m_width,
|
||||
input.m_height);
|
||||
// this->Dock( Gwen::Pos::Bottom);
|
||||
}
|
||||
virtual ~MyGraphWindow()
|
||||
{
|
||||
delete m_imgPanel;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
class MyMenuItems2 : public Gwen::Controls::Base
|
||||
class MyMenuItems2 : public Gwen::Controls::Base
|
||||
{
|
||||
MyGraphWindow* m_graphWindow;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
Gwen::Controls::MenuItem* m_item;
|
||||
|
||||
MyMenuItems2(MyGraphWindow* graphWindow)
|
||||
:Gwen::Controls::Base(0),
|
||||
m_graphWindow(graphWindow),
|
||||
m_item(0)
|
||||
{
|
||||
}
|
||||
|
||||
void MenuItemSelect(Gwen::Controls::Base* pControl)
|
||||
{
|
||||
|
||||
MyMenuItems2(MyGraphWindow* graphWindow)
|
||||
: Gwen::Controls::Base(0),
|
||||
m_graphWindow(graphWindow),
|
||||
m_item(0)
|
||||
{
|
||||
}
|
||||
|
||||
void MenuItemSelect(Gwen::Controls::Base* pControl)
|
||||
{
|
||||
if (m_graphWindow->Hidden())
|
||||
{
|
||||
m_graphWindow->SetHidden(false);
|
||||
//@TODO(erwincoumans) setCheck/SetCheckable drawing is broken, need to see what's wrong
|
||||
// if (m_item)
|
||||
// m_item->SetCheck(false);
|
||||
|
||||
} else
|
||||
// if (m_item)
|
||||
// m_item->SetCheck(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_graphWindow->SetHidden(true);
|
||||
// if (m_item)
|
||||
// m_item->SetCheck(true);
|
||||
|
||||
// if (m_item)
|
||||
// m_item->SetCheck(true);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
MyGraphWindow* setupTextureWindow(const MyGraphInput& input)
|
||||
|
|
@ -83,13 +74,12 @@ MyGraphWindow* setupTextureWindow(const MyGraphInput& input)
|
|||
MyGraphWindow* graphWindow = new MyGraphWindow(input);
|
||||
MyMenuItems2* menuItems = new MyMenuItems2(graphWindow);
|
||||
graphWindow->m_menuItems = menuItems;
|
||||
|
||||
|
||||
Gwen::UnicodeString str = Gwen::Utility::StringToUnicode(input.m_name);
|
||||
menuItems->m_item = input.m_data->m_viewMenu->GetMenu()->AddItem( str, menuItems,(Gwen::Event::Handler::Function)&MyMenuItems2::MenuItemSelect);
|
||||
// menuItems->m_item->SetCheckable(true);
|
||||
menuItems->m_item = input.m_data->m_viewMenu->GetMenu()->AddItem(str, menuItems, (Gwen::Event::Handler::Function)&MyMenuItems2::MenuItemSelect);
|
||||
// menuItems->m_item->SetCheckable(true);
|
||||
|
||||
return graphWindow;
|
||||
|
||||
}
|
||||
|
||||
void destroyTextureWindow(MyGraphWindow* window)
|
||||
|
|
|
|||
|
|
@ -14,19 +14,18 @@ struct MyGraphInput
|
|||
const char* m_name;
|
||||
const char* m_texName;
|
||||
MyGraphInput(struct GwenInternalData* data)
|
||||
:m_data(data),
|
||||
m_xPos(0),
|
||||
m_yPos(0),
|
||||
m_width(400),
|
||||
m_height(400),
|
||||
m_borderWidth(0),
|
||||
m_name("GraphWindow"),
|
||||
m_texName(0)
|
||||
: m_data(data),
|
||||
m_xPos(0),
|
||||
m_yPos(0),
|
||||
m_width(400),
|
||||
m_height(400),
|
||||
m_borderWidth(0),
|
||||
m_name("GraphWindow"),
|
||||
m_texName(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
class MyGraphWindow* setupTextureWindow(const MyGraphInput& input);
|
||||
void destroyTextureWindow(MyGraphWindow* window);
|
||||
|
||||
|
||||
#endif //GWEN_TEXTURE_WINDOW_H
|
||||
#endif //GWEN_TEXTURE_WINDOW_H
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue