add SoftDemo examples
add example description for all examples (with word-wrap) add the VoronoiFractureDemo, note that the collision are disabled after breaking constraints. add optional GwenOpenGLTest, to make it easier to see Gwen user interface features.
This commit is contained in:
@@ -45,6 +45,12 @@ struct CommonRigidBodyBase : public ExampleInterface
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
btDiscreteDynamicsWorld* getDynamicsWorld()
|
||||
{
|
||||
return m_dynamicsWorld;
|
||||
}
|
||||
|
||||
virtual void createEmptyDynamicsWorld()
|
||||
{
|
||||
///collision configuration contains default setup for memory, collision setup
|
||||
|
||||
@@ -22,16 +22,25 @@
|
||||
#include "../MultiBody/TestJointTorqueSetup.h"
|
||||
#include "../MultiBody/MultiDofDemo.h"
|
||||
#include "../MultiBody/MultiBodyCustomURDFDemo.h"
|
||||
#include "../VoronoiFracture/VoronoiFractureDemo.h"
|
||||
#include "../SoftDemo/SoftDemo.h"
|
||||
|
||||
|
||||
struct ExampleEntry
|
||||
{
|
||||
int m_menuLevel;
|
||||
const char* m_name;
|
||||
const char* m_description;
|
||||
ExampleInterface::CreateFunc* m_createFunc;
|
||||
int m_option;
|
||||
|
||||
ExampleEntry(int menuLevel, const char* name,ExampleInterface::CreateFunc* createFunc, int option=0)
|
||||
:m_menuLevel(menuLevel), m_name(name), m_createFunc(createFunc), m_option(option)
|
||||
ExampleEntry(int menuLevel, const char* name)
|
||||
:m_menuLevel(menuLevel), m_name(name), m_description(0), m_createFunc(0), m_option(0)
|
||||
{
|
||||
}
|
||||
|
||||
ExampleEntry(int menuLevel, const char* name,const char* description, ExampleInterface::CreateFunc* createFunc, int option=0)
|
||||
:m_menuLevel(menuLevel), m_name(name), m_description(description), m_createFunc(createFunc), m_option(option)
|
||||
{
|
||||
}
|
||||
};
|
||||
@@ -41,50 +50,101 @@ static ExampleEntry gDefaultExamples[]=
|
||||
{
|
||||
|
||||
|
||||
ExampleEntry(0,"API",0),
|
||||
ExampleEntry(1,"Basic Example",BasicExampleCreateFunc),
|
||||
ExampleEntry(0,"API"),
|
||||
ExampleEntry(1,"Basic Example","Create some rigid bodies using box collision shapes.", BasicExampleCreateFunc),
|
||||
|
||||
ExampleEntry(1,"Gyroscopic", GyroscopicCreateFunc),
|
||||
ExampleEntry(1,"Gyroscopic", "Show the Dzhanibekov effect using various settings of the gyroscopic mode.", GyroscopicCreateFunc),
|
||||
|
||||
ExampleEntry(1,"Planar 2D",Planar2DCreateFunc),
|
||||
ExampleEntry(1,"Constraints",ConstraintCreateFunc),
|
||||
ExampleEntry(1,"6DofSpring2",Dof6Spring2CreateFunc),
|
||||
ExampleEntry(1,"Planar 2D","Show the use of 2D collision shapes and rigid body simulation.",Planar2DCreateFunc),
|
||||
ExampleEntry(1,"Constraints","Basic use of a btHingeConstraint.", ConstraintCreateFunc),
|
||||
ExampleEntry(1,"6DofSpring2","Show the use of the btGeneric6DofSpring2Constraint.",
|
||||
Dof6Spring2CreateFunc),
|
||||
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(0,"MultiBody"),
|
||||
ExampleEntry(1,"MultiDofCreateFunc","Create a basic btMultiBody.", MultiDofCreateFunc),
|
||||
ExampleEntry(1,"TestJointTorque","Apply a torque to a btMultiBody.", TestJointTorqueCreateFunc),
|
||||
ExampleEntry(1,"Custom URDF","Load a URDF file to allow creation of custom data structures.", MultiBodyCustomURDFDemoCreateFunc),
|
||||
|
||||
ExampleEntry(0,"MultiBody",0),
|
||||
ExampleEntry(1,"TestJointTorque",TestJointTorqueCreateFunc),
|
||||
ExampleEntry(1,"MultiDofCreateFunc",MultiDofCreateFunc),
|
||||
ExampleEntry(1,"Custom URDF",MultiBodyCustomURDFDemoCreateFunc),
|
||||
|
||||
#ifdef INCLUDE_CLOTH_DEMOS
|
||||
ExampleEntry(0,"Soft Body"),
|
||||
ExampleEntry(1,"Cloth","Simulate a patch of cloth.", SoftDemoCreateFunc,0),
|
||||
|
||||
ExampleEntry(1,"Pressure","Simulate 3d soft body using a pressure constraint.",SoftDemoCreateFunc,1),
|
||||
ExampleEntry(1,"Volume","Simulate 3d soft body using a volume constraint.",SoftDemoCreateFunc,2),
|
||||
ExampleEntry(1,"Ropes","Simulate ropes", SoftDemoCreateFunc,3),
|
||||
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),
|
||||
|
||||
#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", 0),
|
||||
ExampleEntry(1,"3000 boxes", BenchmarkCreateFunc, 1),
|
||||
ExampleEntry(1,"1000 stack", BenchmarkCreateFunc, 2),
|
||||
ExampleEntry(1,"Ragdolls", BenchmarkCreateFunc, 3),
|
||||
ExampleEntry(1,"Convex stack", BenchmarkCreateFunc, 4),
|
||||
ExampleEntry(1,"Prim vs Mesh", BenchmarkCreateFunc, 5),
|
||||
ExampleEntry(1,"Convex vs Mesh", BenchmarkCreateFunc, 6),
|
||||
ExampleEntry(1,"Raycast", BenchmarkCreateFunc, 7),
|
||||
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
|
||||
|
||||
|
||||
ExampleEntry(0,"Importers", 0),
|
||||
ExampleEntry(1,"Wavefront Obj", ImportObjCreateFunc, 0),
|
||||
ExampleEntry(0,"Importers"),
|
||||
ExampleEntry(1,"Wavefront Obj", "Import a Wavefront .obj file", ImportObjCreateFunc, 0),
|
||||
|
||||
ExampleEntry(1,"Quake BSP", ImportBspCreateFunc, 0),
|
||||
ExampleEntry(1,"COLLADA dae", ImportColladaCreateFunc, 0),
|
||||
ExampleEntry(1,"STL", ImportSTLCreateFunc, 0),
|
||||
ExampleEntry(1,"URDF (RigidBody)", ImportURDFCreateFunc, 0),
|
||||
ExampleEntry(1,"URDF (MultiBody)", ImportURDFCreateFunc, 1),
|
||||
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(0,"Vehicles",0),
|
||||
ExampleEntry(0,"Vehicles"),
|
||||
|
||||
ExampleEntry(1,"ForkLift",ForkLiftCreateFunc),
|
||||
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,"Rendering",0),
|
||||
ExampleEntry(1,"Instanced Rendering", RenderInstancingCreateFunc),
|
||||
ExampleEntry(1,"CoordinateSystemDemo",CoordinateSystemCreateFunc),
|
||||
ExampleEntry(1,"Raytracer",RayTracerCreateFunc),
|
||||
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,"Raytracer","Implement an extremely simple ray tracer using the ray trace functionality in btCollisionWorld.",
|
||||
RayTracerCreateFunc),
|
||||
|
||||
};
|
||||
|
||||
@@ -124,21 +184,21 @@ void ExampleEntries::initExampleEntries()
|
||||
{
|
||||
|
||||
{
|
||||
ExampleEntry e(0,"Empty", 0);
|
||||
ExampleEntry e(0,"Empty");
|
||||
m_data->m_allExamples.push_back(e);
|
||||
}
|
||||
|
||||
{
|
||||
ExampleEntry e(1,"Empty",EmptyExample::CreateFunc);
|
||||
ExampleEntry e(1,"Empty","Empty Description", EmptyExample::CreateFunc);
|
||||
m_data->m_allExamples.push_back(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ExampleEntries::registerExampleEntry(int menuLevel, const char* name,ExampleInterface::CreateFunc* createFunc, int option)
|
||||
void ExampleEntries::registerExampleEntry(int menuLevel, const char* name,const char* description, ExampleInterface::CreateFunc* createFunc, int option)
|
||||
{
|
||||
ExampleEntry e( menuLevel,name,createFunc, option);
|
||||
ExampleEntry e( menuLevel,name,description, createFunc, option);
|
||||
gAdditionalRegisteredExamples.push_back(e);
|
||||
}
|
||||
|
||||
@@ -161,3 +221,8 @@ const char* ExampleEntries::getExampleName(int index)
|
||||
{
|
||||
return m_data->m_allExamples[index].m_name;
|
||||
}
|
||||
|
||||
const char* ExampleEntries::getExampleDescription(int index)
|
||||
{
|
||||
return m_data->m_allExamples[index].m_description;
|
||||
}
|
||||
@@ -17,7 +17,7 @@ public:
|
||||
ExampleEntries();
|
||||
virtual ~ExampleEntries();
|
||||
|
||||
static void registerExampleEntry(int menuLevel, const char* name,ExampleInterface::CreateFunc* createFunc, int option=0);
|
||||
static void registerExampleEntry(int menuLevel, const char* name,const char* description, ExampleInterface::CreateFunc* createFunc, int option=0);
|
||||
|
||||
void initExampleEntries();
|
||||
|
||||
@@ -26,6 +26,8 @@ public:
|
||||
ExampleInterface::CreateFunc* getExampleCreateFunc(int index);
|
||||
|
||||
const char* getExampleName(int index);
|
||||
|
||||
const char* getExampleDescription(int index);
|
||||
|
||||
int getExampleOption(int index);
|
||||
|
||||
|
||||
@@ -42,6 +42,10 @@ struct GwenInternalData
|
||||
Gwen::Controls::TreeControl* m_explorerTreeCtrl;
|
||||
Gwen::Controls::MenuItem* m_viewMenu;
|
||||
class MyMenuItems* m_menuItems;
|
||||
Gwen::Controls::ListBox* m_TextOutput;
|
||||
Gwen::Controls::Label* m_exampleInfoGroupBox;
|
||||
Gwen::Controls::ListBox* m_exampleInfoTextOutput;
|
||||
|
||||
|
||||
int m_curYposition;
|
||||
|
||||
|
||||
@@ -140,6 +140,78 @@ struct MyButtonHander :public Gwen::Event::Handler
|
||||
};
|
||||
|
||||
|
||||
void GwenUserInterface::textOutput(const char* message)
|
||||
{
|
||||
Gwen::UnicodeString msg = Gwen::Utility::StringToUnicode(message);
|
||||
m_data->m_TextOutput->AddItem( msg );
|
||||
m_data->m_TextOutput->Scroller()->ScrollToBottom();
|
||||
}
|
||||
|
||||
|
||||
void GwenUserInterface::setExampleDescription(const char* message)
|
||||
{
|
||||
//Gwen apparently doesn't have text/word wrap, so do rudimentary brute-force implementation here.
|
||||
|
||||
std::string wrapmessage=message;
|
||||
int startPos = 0;
|
||||
|
||||
std::string lastFit = "";
|
||||
bool hasSpace = false;
|
||||
std::string lastFitSpace = "";
|
||||
int spacePos = 0;
|
||||
|
||||
m_data->m_exampleInfoTextOutput->Clear();
|
||||
int fixedWidth = m_data->m_exampleInfoTextOutput->GetBounds().w-25;
|
||||
|
||||
for (int endPos=0;endPos<=wrapmessage.length();endPos++)
|
||||
{
|
||||
std::string sub = wrapmessage.substr(startPos,(endPos-startPos));
|
||||
Gwen::Point pt = m_data->pRenderer->MeasureText(m_data->pCanvas->GetSkin()->GetDefaultFont(),sub);
|
||||
|
||||
if (pt.x <= fixedWidth)
|
||||
{
|
||||
lastFit = sub;
|
||||
|
||||
if (message[endPos]==' ' ||message[endPos]=='.' || message[endPos]==',' )
|
||||
{
|
||||
hasSpace = true;
|
||||
lastFitSpace = sub;
|
||||
spacePos = endPos;
|
||||
}
|
||||
} else
|
||||
{
|
||||
//submit and
|
||||
if (hasSpace)
|
||||
{
|
||||
endPos = spacePos+1;
|
||||
hasSpace = false;
|
||||
lastFit = lastFitSpace;
|
||||
startPos = endPos;
|
||||
} else
|
||||
{
|
||||
startPos = endPos-1;
|
||||
}
|
||||
Gwen::UnicodeString msg = Gwen::Utility::StringToUnicode(lastFit);
|
||||
|
||||
m_data->m_exampleInfoTextOutput->AddItem( msg );
|
||||
m_data->m_exampleInfoTextOutput->Scroller()->ScrollToBottom();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (lastFit.length())
|
||||
{
|
||||
Gwen::UnicodeString msg = Gwen::Utility::StringToUnicode(lastFit);
|
||||
m_data->m_exampleInfoTextOutput->AddItem( msg );
|
||||
m_data->m_exampleInfoTextOutput->Scroller()->ScrollToBottom();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void GwenUserInterface::setStatusBarMessage(const char* message, bool isLeft)
|
||||
{
|
||||
Gwen::UnicodeString msg = Gwen::Utility::StringToUnicode(message);
|
||||
@@ -171,10 +243,13 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere
|
||||
m_data->pCanvas->SetDrawBackground( false);
|
||||
m_data->pCanvas->SetBackgroundColor( Gwen::Color( 150, 170, 170, 255 ) );
|
||||
|
||||
|
||||
|
||||
MyTestMenuBar* menubar = new MyTestMenuBar(m_data->pCanvas);
|
||||
m_data->m_viewMenu = menubar->m_viewMenu;
|
||||
m_data->m_menuItems = menubar->m_menuItems;
|
||||
|
||||
|
||||
|
||||
|
||||
Gwen::Controls::StatusBar* bar = new Gwen::Controls::StatusBar(m_data->pCanvas);
|
||||
@@ -183,6 +258,10 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere
|
||||
//m_data->m_rightStatusBar->SetText( L"Label Added to Right" );
|
||||
bar->AddControl( m_data->m_rightStatusBar, true );
|
||||
|
||||
m_data->m_TextOutput = new Gwen::Controls::ListBox( m_data->pCanvas );
|
||||
m_data->m_TextOutput->Dock( Gwen::Pos::Bottom );
|
||||
m_data->m_TextOutput->SetHeight( 100 );
|
||||
|
||||
m_data->m_leftStatusBar = new Gwen::Controls::Label( bar );
|
||||
//m_data->m_leftStatusBar->SetText( L"Label Added to Left" );
|
||||
m_data->m_leftStatusBar->SetWidth(width/2);
|
||||
@@ -266,6 +345,14 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere
|
||||
//tab->Dock(Gwen::Pos::Left);
|
||||
explorerTab->Dock(Gwen::Pos::Fill);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//m_data->m_exampleInfoTextOutput->SetBounds(2, 10, 236, 400);
|
||||
|
||||
//windowRight
|
||||
|
||||
Gwen::UnicodeString explorerStr1(L"Explorer");
|
||||
m_data->m_explorerPage = explorerTab->AddPage(explorerStr1);
|
||||
Gwen::UnicodeString shapesStr1(L"Shapes");
|
||||
@@ -279,6 +366,21 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere
|
||||
ctrl->Focus();
|
||||
ctrl->SetBounds(2, 10, 236, 400);
|
||||
|
||||
m_data->m_exampleInfoGroupBox = new Gwen::Controls::Label( m_data->m_explorerPage->GetPage() );
|
||||
m_data->m_exampleInfoGroupBox->SetPos(2, 414);
|
||||
m_data->m_exampleInfoGroupBox->SetHeight( 15 );
|
||||
m_data->m_exampleInfoGroupBox->SetWidth(234);
|
||||
m_data->m_exampleInfoGroupBox->SetText("Example Description");
|
||||
|
||||
m_data->m_exampleInfoTextOutput = new Gwen::Controls::ListBox(m_data->m_explorerPage->GetPage());
|
||||
|
||||
|
||||
//m_data->m_exampleInfoTextOutput->Dock( Gwen::Pos::Bottom );
|
||||
m_data->m_exampleInfoTextOutput->SetPos(2, 432);
|
||||
m_data->m_exampleInfoTextOutput->SetHeight( 150 );
|
||||
m_data->m_exampleInfoTextOutput->SetWidth(233);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,10 @@ class GwenUserInterface
|
||||
|
||||
void setStatusBarMessage(const char* message, bool isLeft=true);
|
||||
|
||||
void textOutput(const char* msg);
|
||||
void setExampleDescription(const char* msg);
|
||||
|
||||
|
||||
void registerFileOpenCallback(b3FileOpenCallback callback);
|
||||
|
||||
GwenInternalData* getInternalData()
|
||||
|
||||
@@ -246,7 +246,8 @@ void selectDemo(int demoIndex)
|
||||
bool isLeft = true;
|
||||
gui->setStatusBarMessage("Status: OK", false);
|
||||
}
|
||||
|
||||
b3Printf("Selected demo: %s",gAllExamples->getExampleName(demoIndex));
|
||||
gui->setExampleDescription(gAllExamples->getExampleDescription(demoIndex));
|
||||
sCurrentDemo->initPhysics();
|
||||
}
|
||||
}
|
||||
@@ -303,6 +304,17 @@ void MyComboBoxCallback(int comboId, const char* item)
|
||||
}
|
||||
|
||||
|
||||
void MyGuiPrintf(const char* msg)
|
||||
{
|
||||
printf("b3Printf: %s\n",msg);
|
||||
if (gui)
|
||||
{
|
||||
gui->textOutput(msg);
|
||||
gui->forceUpdateScrollBars();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MyStatusBarPrintf(const char* msg)
|
||||
{
|
||||
@@ -364,13 +376,14 @@ struct MyMenuItemHander :public Gwen::Event::Handler
|
||||
}
|
||||
void onButtonC(Gwen::Controls::Base* pControl)
|
||||
{
|
||||
// Gwen::Controls::Label* label = (Gwen::Controls::Label*) pControl;
|
||||
// Gwen::UnicodeString la = label->GetText();// node->GetButton()->GetName();// GetText();
|
||||
// Gwen::String laa = Gwen::Utility::UnicodeToString(la);
|
||||
// const char* ha = laa.c_str();
|
||||
/*Gwen::Controls::Label* label = (Gwen::Controls::Label*) pControl;
|
||||
Gwen::UnicodeString la = label->GetText();// node->GetButton()->GetName();// GetText();
|
||||
Gwen::String laa = Gwen::Utility::UnicodeToString(la);
|
||||
const char* ha = laa.c_str();
|
||||
|
||||
|
||||
// printf("onButtonC ! %s\n", ha);
|
||||
printf("onButtonC ! %s\n", ha);
|
||||
*/
|
||||
}
|
||||
void onButtonD(Gwen::Controls::Base* pControl)
|
||||
{
|
||||
@@ -390,6 +403,7 @@ struct MyMenuItemHander :public Gwen::Event::Handler
|
||||
{
|
||||
// printf("select %d\n",m_buttonId);
|
||||
sCurrentHightlighted = m_buttonId;
|
||||
gui->setExampleDescription(gAllExamples->getExampleDescription(sCurrentHightlighted));
|
||||
}
|
||||
|
||||
void onButtonF(Gwen::Controls::Base* pControl)
|
||||
@@ -559,7 +573,8 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
|
||||
s_app->m_renderer->getActiveCamera()->setCameraTargetPosition(0,0,0);
|
||||
|
||||
b3SetCustomWarningMessageFunc(MyStatusBarWarning);
|
||||
b3SetCustomPrintfFunc(MyStatusBarPrintf);
|
||||
//b3SetCustomPrintfFunc(MyStatusBarPrintf);
|
||||
b3SetCustomPrintfFunc(MyGuiPrintf);
|
||||
|
||||
|
||||
assert(glGetError()==GL_NO_ERROR);
|
||||
@@ -580,6 +595,10 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
|
||||
//
|
||||
|
||||
gui->init(width,height,gwenRenderer,s_window->getRetinaScale());
|
||||
|
||||
|
||||
|
||||
|
||||
// gui->getInternalData()->m_explorerPage
|
||||
Gwen::Controls::TreeControl* tree = gui->getInternalData()->m_explorerTreeCtrl;
|
||||
|
||||
@@ -727,6 +746,7 @@ void OpenGLExampleBrowser::update(float deltaTime)
|
||||
s_app->drawText(bla,10,10);
|
||||
}
|
||||
|
||||
|
||||
if (sCurrentDemo)
|
||||
{
|
||||
if (!pauseSimulation)
|
||||
@@ -758,19 +778,18 @@ void OpenGLExampleBrowser::update(float deltaTime)
|
||||
//if (!pauseSimulation)
|
||||
// processProfileData(profWindow,false);
|
||||
|
||||
{
|
||||
if (sUseOpenGL2)
|
||||
{
|
||||
if (sUseOpenGL2)
|
||||
{
|
||||
|
||||
saveOpenGLState(s_instancingRenderer->getScreenWidth(),s_instancingRenderer->getScreenHeight());
|
||||
}
|
||||
BT_PROFILE("Draw Gwen GUI");
|
||||
gui->draw(s_instancingRenderer->getScreenWidth(),s_instancingRenderer->getScreenHeight());
|
||||
if (sUseOpenGL2)
|
||||
{
|
||||
restoreOpenGLState();
|
||||
}
|
||||
saveOpenGLState(s_instancingRenderer->getScreenWidth(),s_instancingRenderer->getScreenHeight());
|
||||
}
|
||||
BT_PROFILE("Draw Gwen GUI");
|
||||
gui->draw(s_instancingRenderer->getScreenWidth(),s_instancingRenderer->getScreenHeight());
|
||||
if (sUseOpenGL2)
|
||||
{
|
||||
restoreOpenGLState();
|
||||
}
|
||||
|
||||
}
|
||||
toggle=1-toggle;
|
||||
{
|
||||
@@ -781,7 +800,7 @@ void OpenGLExampleBrowser::update(float deltaTime)
|
||||
BT_PROFILE("Swap Buffers");
|
||||
s_app->swapBuffer();
|
||||
}
|
||||
|
||||
|
||||
gui->forceUpdateScrollBars();
|
||||
|
||||
}
|
||||
|
||||
@@ -195,6 +195,11 @@ static void createCollisionShapeGraphicsObjectInternal(btCollisionShape* collisi
|
||||
//todo: support all collision shape types
|
||||
switch (collisionShape->getShapeType())
|
||||
{
|
||||
case SOFTBODY_SHAPE_PROXYTYPE:
|
||||
{
|
||||
//skip the soft body collision shape for now
|
||||
break;
|
||||
}
|
||||
case STATIC_PLANE_PROXYTYPE:
|
||||
{
|
||||
//draw a box, oriented along the plane normal
|
||||
|
||||
@@ -12,11 +12,12 @@
|
||||
}
|
||||
|
||||
|
||||
links{"gwen", "OpenGL_Window","BulletDynamics","BulletCollision","LinearMath","Bullet3Common"}
|
||||
links{"gwen", "OpenGL_Window","BulletSoftBody", "BulletDynamics","BulletCollision","LinearMath","Bullet3Common"}
|
||||
initOpenGL()
|
||||
initGlew()
|
||||
|
||||
|
||||
defines {"INCLUDE_CLOTH_DEMOS"}
|
||||
|
||||
files {
|
||||
"**.cpp",
|
||||
"**.h",
|
||||
@@ -27,6 +28,8 @@
|
||||
"../Importers/**",
|
||||
"../Planar2D/Planar2D.*",
|
||||
"../RenderingExamples/*",
|
||||
"../VoronoiFracture/*",
|
||||
"../SoftDemo/*",
|
||||
"../Constraints/*",
|
||||
"../MultiBody/MultiBodyCustomURDFDemo.cpp",
|
||||
"../MultiBody/MultiDofDemo.cpp",
|
||||
|
||||
1379
examples/SoftDemo/BunnyMesh.h
Normal file
1379
examples/SoftDemo/BunnyMesh.h
Normal file
File diff suppressed because it is too large
Load Diff
2332
examples/SoftDemo/SoftDemo.cpp
Normal file
2332
examples/SoftDemo/SoftDemo.cpp
Normal file
File diff suppressed because it is too large
Load Diff
30
examples/SoftDemo/SoftDemo.h
Normal file
30
examples/SoftDemo/SoftDemo.h
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
///btSoftBody implementation by Nathanael Presson
|
||||
|
||||
#ifndef SOFT_DEMO_H
|
||||
#define SOFT_DEMO_H
|
||||
|
||||
class ExampleInterface* SoftDemoCreateFunc(struct PhysicsInterface* pint, struct GUIHelperInterface* helper, int option);
|
||||
|
||||
|
||||
#endif //CCD_PHYSICS_DEMO_H
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
921
examples/SoftDemo/TorusMesh.h
Normal file
921
examples/SoftDemo/TorusMesh.h
Normal file
@@ -0,0 +1,921 @@
|
||||
#ifndef TORUS_MESH_H_
|
||||
#define TORUS_MESH_H_
|
||||
|
||||
|
||||
//*************************** NOT REALLY FAMOUS TORUS ********************************************//
|
||||
|
||||
#define Real btScalar
|
||||
const int NUM_TRIANGLES =600;
|
||||
const int NUM_VERTICES = 300;
|
||||
const int NUM_INDICES = NUM_TRIANGLES * 3;
|
||||
|
||||
|
||||
static Real gVertices[NUM_VERTICES * 3] = {
|
||||
Real(2.5), Real(0), Real(0),
|
||||
Real(2.405), Real(0.294), Real(0),
|
||||
Real(2.155), Real(0.476), Real(0),
|
||||
Real(1.845), Real(0.476), Real(0),
|
||||
Real(1.595), Real(0.294), Real(0),
|
||||
Real(1.5), Real(0 ), Real(0),
|
||||
Real(1.595), Real(-0.294), Real(0),
|
||||
Real(1.845), Real(-0.476), Real(0),
|
||||
Real(2.155), Real(-0.476), Real(0),
|
||||
Real(2.405), Real(-0.294), Real(0),
|
||||
Real(2.445), Real(0 ), Real(0.52 ),
|
||||
Real(2.352), Real(0.294), Real(0.5 ),
|
||||
Real(2.107), Real(0.476), Real(0.448),
|
||||
Real(1.805), Real(0.476), Real(0.384),
|
||||
Real(1.561), Real(0.294), Real(0.332),
|
||||
Real(1.467), Real(0 ), Real(0.312),
|
||||
Real(1.561), Real(-0.294), Real(0.332),
|
||||
Real(1.805), Real(-0.476), Real(0.384),
|
||||
Real(2.107), Real(-0.476), Real(0.448),
|
||||
Real(2.352), Real(-0.294), Real(0.5 ),
|
||||
Real(2.284), Real(0), Real(1.017),
|
||||
Real(2.197), Real(0.294), Real(0.978),
|
||||
Real(1.968), Real(0.476), Real(0.876),
|
||||
Real(1.686), Real(0.476), Real(0.751),
|
||||
Real(1.458), Real(0.294), Real(0.649),
|
||||
Real(1.37), Real(0), Real(0.61 ),
|
||||
Real(1.458), Real(-0.294), Real(0.649),
|
||||
Real(1.686), Real(-0.476), Real(0.751),
|
||||
Real(1.968), Real(-0.476), Real(0.876),
|
||||
Real(2.197), Real(-0.294), Real(0.978),
|
||||
Real(2.023), Real(0), Real(1.469),
|
||||
Real(1.945), Real(0.294), Real(1.413),
|
||||
Real(1.743), Real(0.476), Real(1.266),
|
||||
Real(1.493), Real(0.476), Real(1.085),
|
||||
Real(1.291), Real(0.294), Real(0.938),
|
||||
Real(1.214), Real(0), Real(0.882),
|
||||
Real(1.291), Real(-0.294), Real(0.938),
|
||||
Real(1.493), Real(-0.476), Real(1.085),
|
||||
Real(1.743), Real(-0.476), Real(1.266),
|
||||
Real(1.945), Real(-0.294), Real(1.413),
|
||||
Real(1.673), Real(0), Real(1.858),
|
||||
Real(1.609), Real(0.294), Real(1.787),
|
||||
Real(1.442), Real(0.476), Real(1.601),
|
||||
Real(1.235), Real(0.476), Real(1.371),
|
||||
Real(1.068), Real(0.294), Real(1.186),
|
||||
Real(1.004), Real(0), Real(1.115),
|
||||
Real(1.068), Real(-0.294), Real(1.186),
|
||||
Real(1.235), Real(-0.476), Real(1.371),
|
||||
Real(1.442), Real(-0.476), Real(1.601),
|
||||
Real(1.609), Real(-0.294), Real(1.787),
|
||||
Real(1.25), Real(0), Real(2.165),
|
||||
Real(1.202), Real(0.294), Real(2.082),
|
||||
Real(1.077), Real(0.476), Real(1.866),
|
||||
Real(0.923), Real(0.476), Real(1.598),
|
||||
Real(0.798), Real(0.294), Real(1.382),
|
||||
Real(0.75), Real(0), Real(1.299),
|
||||
Real(0.798), Real(-0.294), Real(1.382),
|
||||
Real(0.923), Real(-0.476), Real(1.598),
|
||||
Real(1.077), Real(-0.476), Real(1.866),
|
||||
Real(1.202), Real(-0.294), Real(2.082),
|
||||
Real(0.773), Real(0), Real(2.378),
|
||||
Real(0.743), Real(0.294), Real(2.287),
|
||||
Real(0.666), Real(0.476), Real(2.049),
|
||||
Real(0.57), Real(0.476), Real(1.755),
|
||||
Real(0.493), Real(0.294), Real(1.517),
|
||||
Real(0.464), Real(0), Real(1.427),
|
||||
Real(0.493), Real(-0.294), Real(1.517),
|
||||
Real(0.57), Real(-0.476), Real(1.755),
|
||||
Real(0.666), Real(-0.476), Real(2.049),
|
||||
Real(0.743), Real(-0.294), Real(2.287),
|
||||
Real(0.261), Real(0), Real(2.486),
|
||||
Real(0.251), Real(0.294), Real(2.391),
|
||||
Real(0.225), Real(0.476), Real(2.143),
|
||||
Real(0.193), Real(0.476), Real(1.835),
|
||||
Real(0.167), Real(0.294), Real(1.587),
|
||||
Real(0.157), Real(0), Real(1.492),
|
||||
Real(0.167), Real(-0.294), Real(1.587),
|
||||
Real(0.193), Real(-0.476), Real(1.835),
|
||||
Real(0.225), Real(-0.476), Real(2.143),
|
||||
Real(0.251), Real(-0.294), Real(2.391),
|
||||
Real(-0.261), Real(0), Real(2.486),
|
||||
Real(-0.251), Real(0.294), Real(2.391),
|
||||
Real(-0.225), Real(0.476), Real(2.143),
|
||||
Real(-0.193), Real(0.476), Real(1.835),
|
||||
Real(-0.167), Real(0.294), Real(1.587),
|
||||
Real(-0.157), Real(0), Real(1.492),
|
||||
Real(-0.167), Real(-0.294), Real(1.587),
|
||||
Real(-0.193), Real(-0.476), Real(1.835),
|
||||
Real(-0.225), Real(-0.476), Real(2.143),
|
||||
Real(-0.251), Real(-0.294), Real(2.391),
|
||||
Real(-0.773), Real(0), Real(2.378),
|
||||
Real(-0.743), Real(0.294), Real(2.287),
|
||||
Real(-0.666), Real(0.476), Real(2.049),
|
||||
Real(-0.57), Real(0.476), Real(1.755),
|
||||
Real(-0.493), Real(0.294), Real(1.517),
|
||||
Real(-0.464), Real(0), Real(1.427),
|
||||
Real(-0.493), Real(-0.294), Real(1.517),
|
||||
Real(-0.57), Real(-0.476), Real(1.755),
|
||||
Real(-0.666), Real(-0.476), Real(2.049),
|
||||
Real(-0.743), Real(-0.294), Real(2.287),
|
||||
Real(-1.25 ), Real(0), Real(2.165),
|
||||
Real(-1.202), Real(0.294), Real(2.082),
|
||||
Real(-1.077), Real(0.476), Real(1.866),
|
||||
Real(-0.923), Real(0.476), Real(1.598),
|
||||
Real(-0.798), Real(0.294), Real(1.382),
|
||||
Real(-0.75), Real(0), Real(1.299),
|
||||
Real(-0.798), Real(-0.294), Real(1.382),
|
||||
Real(-0.923), Real(-0.476), Real(1.598),
|
||||
Real(-1.077), Real(-0.476), Real(1.866),
|
||||
Real(-1.202), Real(-0.294), Real(2.082),
|
||||
Real(-1.673), Real(0), Real(1.858),
|
||||
Real(-1.609), Real(0.294), Real(1.787),
|
||||
Real(-1.442), Real(0.476), Real(1.601),
|
||||
Real(-1.235), Real(0.476), Real(1.371),
|
||||
Real(-1.068), Real(0.294), Real(1.186),
|
||||
Real(-1.004), Real(0), Real(1.115),
|
||||
Real(-1.068), Real(-0.294), Real(1.186),
|
||||
Real(-1.235), Real(-0.476), Real(1.371),
|
||||
Real(-1.442), Real(-0.476), Real(1.601),
|
||||
Real(-1.609), Real(-0.294), Real(1.787),
|
||||
Real(-2.023), Real(0), Real(1.469),
|
||||
Real(-1.945), Real(0.294), Real(1.413),
|
||||
Real(-1.743), Real(0.476), Real(1.266),
|
||||
Real(-1.493), Real(0.476), Real(1.085),
|
||||
Real(-1.291), Real(0.294), Real(0.938),
|
||||
Real(-1.214), Real(0), Real(0.882),
|
||||
Real(-1.291), Real(-0.294), Real(0.938),
|
||||
Real(-1.493), Real(-0.476), Real(1.085),
|
||||
Real(-1.743), Real(-0.476), Real(1.266),
|
||||
Real(-1.945), Real(-0.294), Real(1.413),
|
||||
Real(-2.284), Real(0), Real(1.017),
|
||||
Real(-2.197), Real(0.294), Real(0.978),
|
||||
Real(-1.968), Real(0.476), Real(0.876),
|
||||
Real(-1.686), Real(0.476), Real(0.751),
|
||||
Real(-1.458), Real(0.294), Real(0.649),
|
||||
Real(-1.37), Real(0), Real(0.61 ),
|
||||
Real(-1.458), Real(-0.294), Real(0.649),
|
||||
Real(-1.686), Real(-0.476), Real(0.751),
|
||||
Real(-1.968), Real(-0.476), Real(0.876),
|
||||
Real(-2.197), Real(-0.294), Real(0.978),
|
||||
Real(-2.445), Real(0), Real(0.52),
|
||||
Real(-2.352), Real(0.294), Real(0.5),
|
||||
Real(-2.107), Real(0.476), Real(0.448),
|
||||
Real(-1.805), Real(0.476), Real(0.384),
|
||||
Real(-1.561), Real(0.294), Real(0.332),
|
||||
Real(-1.467), Real(0), Real(0.312),
|
||||
Real(-1.561), Real(-0.294), Real(0.332),
|
||||
Real(-1.805), Real(-0.476), Real(0.384),
|
||||
Real(-2.107), Real(-0.476), Real(0.448),
|
||||
Real(-2.352), Real(-0.294), Real(0.5),
|
||||
Real(-2.5 ), Real(0), Real(0),
|
||||
Real(-2.405), Real(0.294), Real(0),
|
||||
Real(-2.155), Real(0.476), Real(0),
|
||||
Real(-1.845), Real(0.476), Real(0),
|
||||
Real(-1.595), Real(0.294), Real(0),
|
||||
Real(-1.5), Real(0), Real(0),
|
||||
Real(-1.595), Real(-0.294), Real(0),
|
||||
Real(-1.845), Real(-0.476), Real(0),
|
||||
Real(-2.155), Real(-0.476), Real(0),
|
||||
Real(-2.405), Real(-0.294), Real(0),
|
||||
Real(-2.445), Real(0), Real(-0.52),
|
||||
Real(-2.352), Real(0.294), Real(-0.5),
|
||||
Real(-2.107), Real(0.476), Real(-0.448),
|
||||
Real(-1.805), Real(0.476), Real(-0.384),
|
||||
Real(-1.561), Real(0.294), Real(-0.332),
|
||||
Real(-1.467), Real(0), Real(-0.312),
|
||||
Real(-1.561), Real(-0.294), Real(-0.332),
|
||||
Real(-1.805), Real(-0.476), Real(-0.384),
|
||||
Real(-2.107), Real(-0.476), Real(-0.448),
|
||||
Real(-2.352), Real(-0.294), Real(-0.5),
|
||||
Real(-2.284), Real(0), Real(-1.017),
|
||||
Real(-2.197), Real(0.294), Real(-0.978),
|
||||
Real(-1.968), Real(0.476), Real(-0.876),
|
||||
Real(-1.686), Real(0.476), Real(-0.751),
|
||||
Real(-1.458), Real(0.294), Real(-0.649),
|
||||
Real(-1.37), Real(0), Real(-0.61),
|
||||
Real(-1.458), Real(-0.294), Real(-0.649),
|
||||
Real(-1.686), Real(-0.476), Real(-0.751),
|
||||
Real(-1.968), Real(-0.476), Real(-0.876),
|
||||
Real(-2.197), Real(-0.294), Real(-0.978),
|
||||
Real(-2.023), Real(0), Real(-1.469),
|
||||
Real(-1.945), Real(0.294), Real(-1.413),
|
||||
Real(-1.743), Real(0.476), Real(-1.266),
|
||||
Real(-1.493), Real(0.476), Real(-1.085),
|
||||
Real(-1.291), Real(0.294), Real(-0.938),
|
||||
Real(-1.214), Real(0), Real(-0.882),
|
||||
Real(-1.291), Real(-0.294), Real(-0.938),
|
||||
Real(-1.493), Real(-0.476), Real(-1.085),
|
||||
Real(-1.743), Real(-0.476), Real(-1.266),
|
||||
Real(-1.945), Real(-0.294), Real(-1.413),
|
||||
Real(-1.673), Real(0), Real(-1.858),
|
||||
Real(-1.609), Real(0.294), Real(-1.787),
|
||||
Real(-1.442), Real(0.476), Real(-1.601),
|
||||
Real(-1.235), Real(0.476), Real(-1.371),
|
||||
Real(-1.068), Real(0.294), Real(-1.186),
|
||||
Real(-1.004), Real(0), Real(-1.115),
|
||||
Real(-1.068), Real(-0.294), Real(-1.186),
|
||||
Real(-1.235), Real(-0.476), Real(-1.371),
|
||||
Real(-1.442), Real(-0.476), Real(-1.601),
|
||||
Real(-1.609), Real(-0.294), Real(-1.787),
|
||||
Real(-1.25 ), Real(0), Real(-2.165),
|
||||
Real(-1.202), Real(0.294), Real(-2.082),
|
||||
Real(-1.077), Real(0.476), Real(-1.866),
|
||||
Real(-0.923), Real(0.476), Real(-1.598),
|
||||
Real(-0.798), Real(0.294), Real(-1.382),
|
||||
Real(-0.75), Real(0), Real(-1.299),
|
||||
Real(-0.798), Real(-0.294), Real(-1.382),
|
||||
Real(-0.923), Real(-0.476), Real(-1.598),
|
||||
Real(-1.077), Real(-0.476), Real(-1.866),
|
||||
Real(-1.202), Real(-0.294), Real(-2.082),
|
||||
Real(-0.773), Real(0), Real(-2.378),
|
||||
Real(-0.743), Real(0.294), Real(-2.287),
|
||||
Real(-0.666), Real(0.476), Real(-2.049),
|
||||
Real(-0.57), Real(0.476), Real(-1.755),
|
||||
Real(-0.493), Real(0.294), Real(-1.517),
|
||||
Real(-0.464), Real(0), Real(-1.427),
|
||||
Real(-0.493), Real(-0.294), Real(-1.517),
|
||||
Real(-0.57), Real(-0.476), Real(-1.755),
|
||||
Real(-0.666), Real(-0.476), Real(-2.049),
|
||||
Real(-0.743), Real(-0.294), Real(-2.287),
|
||||
Real(-0.261), Real(0), Real(-2.486),
|
||||
Real(-0.251), Real(0.294), Real(-2.391),
|
||||
Real(-0.225), Real(0.476), Real(-2.143),
|
||||
Real(-0.193), Real(0.476), Real(-1.835),
|
||||
Real(-0.167), Real(0.294), Real(-1.587),
|
||||
Real(-0.157), Real(0), Real(-1.492),
|
||||
Real(-0.167), Real(-0.294), Real(-1.587),
|
||||
Real(-0.193), Real(-0.476), Real(-1.835),
|
||||
Real(-0.225), Real(-0.476), Real(-2.143),
|
||||
Real(-0.251), Real(-0.294), Real(-2.391),
|
||||
Real(0.261), Real(0), Real(-2.486),
|
||||
Real(0.251), Real(0.294), Real(-2.391),
|
||||
Real(0.225), Real(0.476), Real(-2.143),
|
||||
Real(0.193), Real(0.476), Real(-1.835),
|
||||
Real(0.167), Real(0.294), Real(-1.587),
|
||||
Real(0.157), Real(0), Real(-1.492),
|
||||
Real(0.167), Real(-0.294), Real(-1.587),
|
||||
Real(0.193), Real(-0.476), Real(-1.835),
|
||||
Real(0.225), Real(-0.476), Real(-2.143),
|
||||
Real(0.251), Real(-0.294), Real(-2.391),
|
||||
Real(0.773), Real(0), Real(-2.378),
|
||||
Real(0.743), Real(0.294), Real(-2.287),
|
||||
Real(0.666), Real(0.476), Real(-2.049),
|
||||
Real(0.57), Real(0.476), Real(-1.755),
|
||||
Real(0.493), Real(0.294), Real(-1.517),
|
||||
Real(0.464), Real(0), Real(-1.427),
|
||||
Real(0.493), Real(-0.294), Real(-1.517),
|
||||
Real(0.57), Real(-0.476), Real(-1.755),
|
||||
Real(0.666), Real(-0.476), Real(-2.049),
|
||||
Real(0.743), Real(-0.294), Real(-2.287),
|
||||
Real(1.25), Real(0), Real(-2.165),
|
||||
Real(1.202), Real(0.294), Real(-2.082),
|
||||
Real(1.077), Real(0.476), Real(-1.866),
|
||||
Real(0.923), Real(0.476), Real(-1.598),
|
||||
Real(0.798), Real(0.294), Real(-1.382),
|
||||
Real(0.75), Real(0), Real(-1.299),
|
||||
Real(0.798), Real(-0.294), Real(-1.382),
|
||||
Real(0.923), Real(-0.476), Real(-1.598),
|
||||
Real(1.077), Real(-0.476), Real(-1.866),
|
||||
Real(1.202), Real(-0.294), Real(-2.082),
|
||||
Real(1.673), Real(0), Real(-1.858),
|
||||
Real(1.609), Real(0.294), Real(-1.787),
|
||||
Real(1.442), Real(0.476), Real(-1.601),
|
||||
Real(1.235), Real(0.476), Real(-1.371),
|
||||
Real(1.068), Real(0.294), Real(-1.186),
|
||||
Real(1.004), Real(0), Real(-1.115),
|
||||
Real(1.068), Real(-0.294), Real(-1.186),
|
||||
Real(1.235), Real(-0.476), Real(-1.371),
|
||||
Real(1.442), Real(-0.476), Real(-1.601),
|
||||
Real(1.609), Real(-0.294), Real(-1.787),
|
||||
Real(2.023), Real(0), Real(-1.469),
|
||||
Real(1.945), Real(0.294), Real(-1.413),
|
||||
Real(1.743), Real(0.476), Real(-1.266),
|
||||
Real(1.493), Real(0.476), Real(-1.085),
|
||||
Real(1.291), Real(0.294), Real(-0.938),
|
||||
Real(1.214), Real(0), Real(-0.882),
|
||||
Real(1.291), Real(-0.294), Real(-0.938),
|
||||
Real(1.493), Real(-0.476), Real(-1.085),
|
||||
Real(1.743), Real(-0.476), Real(-1.266),
|
||||
Real(1.945), Real(-0.294), Real(-1.413),
|
||||
Real(2.284), Real(0), Real(-1.017),
|
||||
Real(2.197), Real(0.294), Real(-0.978),
|
||||
Real(1.968), Real(0.476), Real(-0.876),
|
||||
Real(1.686), Real(0.476), Real(-0.751),
|
||||
Real(1.458), Real(0.294), Real(-0.649),
|
||||
Real(1.37), Real(0), Real(-0.61 ),
|
||||
Real(1.458), Real(-0.294), Real(-0.649),
|
||||
Real(1.686), Real(-0.476), Real(-0.751),
|
||||
Real(1.968), Real(-0.476), Real(-0.876),
|
||||
Real(2.197), Real(-0.294), Real(-0.978),
|
||||
Real(2.445), Real(0), Real(-0.52 ),
|
||||
Real(2.352), Real(0.294), Real(-0.5 ),
|
||||
Real(2.107), Real(0.476), Real(-0.448),
|
||||
Real(1.805), Real(0.476), Real(-0.384),
|
||||
Real(1.561), Real(0.294), Real(-0.332),
|
||||
Real(1.467), Real(0), Real(-0.312),
|
||||
Real(1.561), Real(-0.294), Real(-0.332),
|
||||
Real(1.805), Real(-0.476), Real(-0.384),
|
||||
Real(2.107), Real(-0.476), Real(-0.448),
|
||||
Real(2.352), Real(-0.294), Real(-0.5)
|
||||
};
|
||||
|
||||
|
||||
static int gIndices[NUM_TRIANGLES][3] = {
|
||||
{0, 1, 11},
|
||||
{1, 2, 12},
|
||||
{2, 3, 13},
|
||||
{3, 4, 14},
|
||||
{4, 5, 15},
|
||||
{5, 6, 16},
|
||||
{6, 7, 17},
|
||||
{7, 8, 18},
|
||||
{8, 9, 19},
|
||||
{9, 0, 10},
|
||||
{10, 11, 21},
|
||||
{11, 12, 22},
|
||||
{12, 13, 23},
|
||||
{13, 14, 24},
|
||||
{14, 15, 25},
|
||||
{15, 16, 26},
|
||||
{16, 17, 27},
|
||||
{17, 18, 28},
|
||||
{18, 19, 29},
|
||||
{19, 10, 20},
|
||||
{20, 21, 31},
|
||||
{21, 22, 32},
|
||||
{22, 23, 33},
|
||||
{23, 24, 34},
|
||||
{24, 25, 35},
|
||||
{25, 26, 36},
|
||||
{26, 27, 37},
|
||||
{27, 28, 38},
|
||||
{28, 29, 39},
|
||||
{29, 20, 30},
|
||||
{30, 31, 41},
|
||||
{31, 32, 42},
|
||||
{32, 33, 43},
|
||||
{33, 34, 44},
|
||||
{34, 35, 45},
|
||||
{35, 36, 46},
|
||||
{36, 37, 47},
|
||||
{37, 38, 48},
|
||||
{38, 39, 49},
|
||||
{39, 30, 40},
|
||||
{40, 41, 51},
|
||||
{41, 42, 52},
|
||||
{42, 43, 53},
|
||||
{43, 44, 54},
|
||||
{44, 45, 55},
|
||||
{45, 46, 56},
|
||||
{46, 47, 57},
|
||||
{47, 48, 58},
|
||||
{48, 49, 59},
|
||||
{49, 40, 50},
|
||||
{50, 51, 61},
|
||||
{51, 52, 62},
|
||||
{52, 53, 63},
|
||||
{53, 54, 64},
|
||||
{54, 55, 65},
|
||||
{55, 56, 66},
|
||||
{56, 57, 67},
|
||||
{57, 58, 68},
|
||||
{58, 59, 69},
|
||||
{59, 50, 60},
|
||||
{60, 61, 71},
|
||||
{61, 62, 72},
|
||||
{62, 63, 73},
|
||||
{63, 64, 74},
|
||||
{64, 65, 75},
|
||||
{65, 66, 76},
|
||||
{66, 67, 77},
|
||||
{67, 68, 78},
|
||||
{68, 69, 79},
|
||||
{69, 60, 70},
|
||||
{70, 71, 81},
|
||||
{71, 72, 82},
|
||||
{72, 73, 83},
|
||||
{73, 74, 84},
|
||||
{74, 75, 85},
|
||||
{75, 76, 86},
|
||||
{76, 77, 87},
|
||||
{77, 78, 88},
|
||||
{78, 79, 89},
|
||||
{79, 70, 80},
|
||||
{80, 81, 91},
|
||||
{81, 82, 92},
|
||||
{82, 83, 93},
|
||||
{83, 84, 94},
|
||||
{84, 85, 95},
|
||||
{85, 86, 96},
|
||||
{86, 87, 97},
|
||||
{87, 88, 98},
|
||||
{88, 89, 99},
|
||||
{89, 80, 90},
|
||||
{90, 91, 101},
|
||||
{91, 92, 102},
|
||||
{92, 93, 103},
|
||||
{93, 94, 104},
|
||||
{94, 95, 105},
|
||||
{95, 96, 106},
|
||||
{96, 97, 107},
|
||||
{97, 98, 108},
|
||||
{98, 99, 109},
|
||||
{99, 90, 100},
|
||||
{100, 101, 111},
|
||||
{101, 102, 112},
|
||||
{102, 103, 113},
|
||||
{103, 104, 114},
|
||||
{104, 105, 115},
|
||||
{105, 106, 116},
|
||||
{106, 107, 117},
|
||||
{107, 108, 118},
|
||||
{108, 109, 119},
|
||||
{109, 100, 110},
|
||||
{110, 111, 121},
|
||||
{111, 112, 122},
|
||||
{112, 113, 123},
|
||||
{113, 114, 124},
|
||||
{114, 115, 125},
|
||||
{115, 116, 126},
|
||||
{116, 117, 127},
|
||||
{117, 118, 128},
|
||||
{118, 119, 129},
|
||||
{119, 110, 120},
|
||||
{120, 121, 131},
|
||||
{121, 122, 132},
|
||||
{122, 123, 133},
|
||||
{123, 124, 134},
|
||||
{124, 125, 135},
|
||||
{125, 126, 136},
|
||||
{126, 127, 137},
|
||||
{127, 128, 138},
|
||||
{128, 129, 139},
|
||||
{129, 120, 130},
|
||||
{130, 131, 141},
|
||||
{131, 132, 142},
|
||||
{132, 133, 143},
|
||||
{133, 134, 144},
|
||||
{134, 135, 145},
|
||||
{135, 136, 146},
|
||||
{136, 137, 147},
|
||||
{137, 138, 148},
|
||||
{138, 139, 149},
|
||||
{139, 130, 140},
|
||||
{140, 141, 151},
|
||||
{141, 142, 152},
|
||||
{142, 143, 153},
|
||||
{143, 144, 154},
|
||||
{144, 145, 155},
|
||||
{145, 146, 156},
|
||||
{146, 147, 157},
|
||||
{147, 148, 158},
|
||||
{148, 149, 159},
|
||||
{149, 140, 150},
|
||||
{150, 151, 161},
|
||||
{151, 152, 162},
|
||||
{152, 153, 163},
|
||||
{153, 154, 164},
|
||||
{154, 155, 165},
|
||||
{155, 156, 166},
|
||||
{156, 157, 167},
|
||||
{157, 158, 168},
|
||||
{158, 159, 169},
|
||||
{159, 150, 160},
|
||||
{160, 161, 171},
|
||||
{161, 162, 172},
|
||||
{162, 163, 173},
|
||||
{163, 164, 174},
|
||||
{164, 165, 175},
|
||||
{165, 166, 176},
|
||||
{166, 167, 177},
|
||||
{167, 168, 178},
|
||||
{168, 169, 179},
|
||||
{169, 160, 170},
|
||||
{170, 171, 181},
|
||||
{171, 172, 182},
|
||||
{172, 173, 183},
|
||||
{173, 174, 184},
|
||||
{174, 175, 185},
|
||||
{175, 176, 186},
|
||||
{176, 177, 187},
|
||||
{177, 178, 188},
|
||||
{178, 179, 189},
|
||||
{179, 170, 180},
|
||||
{180, 181, 191},
|
||||
{181, 182, 192},
|
||||
{182, 183, 193},
|
||||
{183, 184, 194},
|
||||
{184, 185, 195},
|
||||
{185, 186, 196},
|
||||
{186, 187, 197},
|
||||
{187, 188, 198},
|
||||
{188, 189, 199},
|
||||
{189, 180, 190},
|
||||
{190, 191, 201},
|
||||
{191, 192, 202},
|
||||
{192, 193, 203},
|
||||
{193, 194, 204},
|
||||
{194, 195, 205},
|
||||
{195, 196, 206},
|
||||
{196, 197, 207},
|
||||
{197, 198, 208},
|
||||
{198, 199, 209},
|
||||
{199, 190, 200},
|
||||
{200, 201, 211},
|
||||
{201, 202, 212},
|
||||
{202, 203, 213},
|
||||
{203, 204, 214},
|
||||
{204, 205, 215},
|
||||
{205, 206, 216},
|
||||
{206, 207, 217},
|
||||
{207, 208, 218},
|
||||
{208, 209, 219},
|
||||
{209, 200, 210},
|
||||
{210, 211, 221},
|
||||
{211, 212, 222},
|
||||
{212, 213, 223},
|
||||
{213, 214, 224},
|
||||
{214, 215, 225},
|
||||
{215, 216, 226},
|
||||
{216, 217, 227},
|
||||
{217, 218, 228},
|
||||
{218, 219, 229},
|
||||
{219, 210, 220},
|
||||
{220, 221, 231},
|
||||
{221, 222, 232},
|
||||
{222, 223, 233},
|
||||
{223, 224, 234},
|
||||
{224, 225, 235},
|
||||
{225, 226, 236},
|
||||
{226, 227, 237},
|
||||
{227, 228, 238},
|
||||
{228, 229, 239},
|
||||
{229, 220, 230},
|
||||
{230, 231, 241},
|
||||
{231, 232, 242},
|
||||
{232, 233, 243},
|
||||
{233, 234, 244},
|
||||
{234, 235, 245},
|
||||
{235, 236, 246},
|
||||
{236, 237, 247},
|
||||
{237, 238, 248},
|
||||
{238, 239, 249},
|
||||
{239, 230, 240},
|
||||
{240, 241, 251},
|
||||
{241, 242, 252},
|
||||
{242, 243, 253},
|
||||
{243, 244, 254},
|
||||
{244, 245, 255},
|
||||
{245, 246, 256},
|
||||
{246, 247, 257},
|
||||
{247, 248, 258},
|
||||
{248, 249, 259},
|
||||
{249, 240, 250},
|
||||
{250, 251, 261},
|
||||
{251, 252, 262},
|
||||
{252, 253, 263},
|
||||
{253, 254, 264},
|
||||
{254, 255, 265},
|
||||
{255, 256, 266},
|
||||
{256, 257, 267},
|
||||
{257, 258, 268},
|
||||
{258, 259, 269},
|
||||
{259, 250, 260},
|
||||
{260, 261, 271},
|
||||
{261, 262, 272},
|
||||
{262, 263, 273},
|
||||
{263, 264, 274},
|
||||
{264, 265, 275},
|
||||
{265, 266, 276},
|
||||
{266, 267, 277},
|
||||
{267, 268, 278},
|
||||
{268, 269, 279},
|
||||
{269, 260, 270},
|
||||
{270, 271, 281},
|
||||
{271, 272, 282},
|
||||
{272, 273, 283},
|
||||
{273, 274, 284},
|
||||
{274, 275, 285},
|
||||
{275, 276, 286},
|
||||
{276, 277, 287},
|
||||
{277, 278, 288},
|
||||
{278, 279, 289},
|
||||
{279, 270, 280},
|
||||
{280, 281, 291},
|
||||
{281, 282, 292},
|
||||
{282, 283, 293},
|
||||
{283, 284, 294},
|
||||
{284, 285, 295},
|
||||
{285, 286, 296},
|
||||
{286, 287, 297},
|
||||
{287, 288, 298},
|
||||
{288, 289, 299},
|
||||
{289, 280, 290},
|
||||
{290, 291, 1},
|
||||
{291, 292, 2},
|
||||
{292, 293, 3},
|
||||
{293, 294, 4},
|
||||
{294, 295, 5},
|
||||
{295, 296, 6},
|
||||
{296, 297, 7},
|
||||
{297, 298, 8},
|
||||
{298, 299, 9},
|
||||
{299, 290, 0},
|
||||
{0, 11, 10},
|
||||
{1, 12, 11},
|
||||
{2, 13, 12},
|
||||
{3, 14, 13},
|
||||
{4, 15, 14},
|
||||
{5, 16, 15},
|
||||
{6, 17, 16},
|
||||
{7, 18, 17},
|
||||
{8, 19, 18},
|
||||
{9, 10, 19},
|
||||
{10, 21, 20},
|
||||
{11, 22, 21},
|
||||
{12, 23, 22},
|
||||
{13, 24, 23},
|
||||
{14, 25, 24},
|
||||
{15, 26, 25},
|
||||
{16, 27, 26},
|
||||
{17, 28, 27},
|
||||
{18, 29, 28},
|
||||
{19, 20, 29},
|
||||
{20, 31, 30},
|
||||
{21, 32, 31},
|
||||
{22, 33, 32},
|
||||
{23, 34, 33},
|
||||
{24, 35, 34},
|
||||
{25, 36, 35},
|
||||
{26, 37, 36},
|
||||
{27, 38, 37},
|
||||
{28, 39, 38},
|
||||
{29, 30, 39},
|
||||
{30, 41, 40},
|
||||
{31, 42, 41},
|
||||
{32, 43, 42},
|
||||
{33, 44, 43},
|
||||
{34, 45, 44},
|
||||
{35, 46, 45},
|
||||
{36, 47, 46},
|
||||
{37, 48, 47},
|
||||
{38, 49, 48},
|
||||
{39, 40, 49},
|
||||
{40, 51, 50},
|
||||
{41, 52, 51},
|
||||
{42, 53, 52},
|
||||
{43, 54, 53},
|
||||
{44, 55, 54},
|
||||
{45, 56, 55},
|
||||
{46, 57, 56},
|
||||
{47, 58, 57},
|
||||
{48, 59, 58},
|
||||
{49, 50, 59},
|
||||
{50, 61, 60},
|
||||
{51, 62, 61},
|
||||
{52, 63, 62},
|
||||
{53, 64, 63},
|
||||
{54, 65, 64},
|
||||
{55, 66, 65},
|
||||
{56, 67, 66},
|
||||
{57, 68, 67},
|
||||
{58, 69, 68},
|
||||
{59, 60, 69},
|
||||
{60, 71, 70},
|
||||
{61, 72, 71},
|
||||
{62, 73, 72},
|
||||
{63, 74, 73},
|
||||
{64, 75, 74},
|
||||
{65, 76, 75},
|
||||
{66, 77, 76},
|
||||
{67, 78, 77},
|
||||
{68, 79, 78},
|
||||
{69, 70, 79},
|
||||
{70, 81, 80},
|
||||
{71, 82, 81},
|
||||
{72, 83, 82},
|
||||
{73, 84, 83},
|
||||
{74, 85, 84},
|
||||
{75, 86, 85},
|
||||
{76, 87, 86},
|
||||
{77, 88, 87},
|
||||
{78, 89, 88},
|
||||
{79, 80, 89},
|
||||
{80, 91, 90},
|
||||
{81, 92, 91},
|
||||
{82, 93, 92},
|
||||
{83, 94, 93},
|
||||
{84, 95, 94},
|
||||
{85, 96, 95},
|
||||
{86, 97, 96},
|
||||
{87, 98, 97},
|
||||
{88, 99, 98},
|
||||
{89, 90, 99},
|
||||
{90, 101, 100},
|
||||
{91, 102, 101},
|
||||
{92, 103, 102},
|
||||
{93, 104, 103},
|
||||
{94, 105, 104},
|
||||
{95, 106, 105},
|
||||
{96, 107, 106},
|
||||
{97, 108, 107},
|
||||
{98, 109, 108},
|
||||
{99, 100, 109},
|
||||
{100, 111, 110},
|
||||
{101, 112, 111},
|
||||
{102, 113, 112},
|
||||
{103, 114, 113},
|
||||
{104, 115, 114},
|
||||
{105, 116, 115},
|
||||
{106, 117, 116},
|
||||
{107, 118, 117},
|
||||
{108, 119, 118},
|
||||
{109, 110, 119},
|
||||
{110, 121, 120},
|
||||
{111, 122, 121},
|
||||
{112, 123, 122},
|
||||
{113, 124, 123},
|
||||
{114, 125, 124},
|
||||
{115, 126, 125},
|
||||
{116, 127, 126},
|
||||
{117, 128, 127},
|
||||
{118, 129, 128},
|
||||
{119, 120, 129},
|
||||
{120, 131, 130},
|
||||
{121, 132, 131},
|
||||
{122, 133, 132},
|
||||
{123, 134, 133},
|
||||
{124, 135, 134},
|
||||
{125, 136, 135},
|
||||
{126, 137, 136},
|
||||
{127, 138, 137},
|
||||
{128, 139, 138},
|
||||
{129, 130, 139},
|
||||
{130, 141, 140},
|
||||
{131, 142, 141},
|
||||
{132, 143, 142},
|
||||
{133, 144, 143},
|
||||
{134, 145, 144},
|
||||
{135, 146, 145},
|
||||
{136, 147, 146},
|
||||
{137, 148, 147},
|
||||
{138, 149, 148},
|
||||
{139, 140, 149},
|
||||
{140, 151, 150},
|
||||
{141, 152, 151},
|
||||
{142, 153, 152},
|
||||
{143, 154, 153},
|
||||
{144, 155, 154},
|
||||
{145, 156, 155},
|
||||
{146, 157, 156},
|
||||
{147, 158, 157},
|
||||
{148, 159, 158},
|
||||
{149, 150, 159},
|
||||
{150, 161, 160},
|
||||
{151, 162, 161},
|
||||
{152, 163, 162},
|
||||
{153, 164, 163},
|
||||
{154, 165, 164},
|
||||
{155, 166, 165},
|
||||
{156, 167, 166},
|
||||
{157, 168, 167},
|
||||
{158, 169, 168},
|
||||
{159, 160, 169},
|
||||
{160, 171, 170},
|
||||
{161, 172, 171},
|
||||
{162, 173, 172},
|
||||
{163, 174, 173},
|
||||
{164, 175, 174},
|
||||
{165, 176, 175},
|
||||
{166, 177, 176},
|
||||
{167, 178, 177},
|
||||
{168, 179, 178},
|
||||
{169, 170, 179},
|
||||
{170, 181, 180},
|
||||
{171, 182, 181},
|
||||
{172, 183, 182},
|
||||
{173, 184, 183},
|
||||
{174, 185, 184},
|
||||
{175, 186, 185},
|
||||
{176, 187, 186},
|
||||
{177, 188, 187},
|
||||
{178, 189, 188},
|
||||
{179, 180, 189},
|
||||
{180, 191, 190},
|
||||
{181, 192, 191},
|
||||
{182, 193, 192},
|
||||
{183, 194, 193},
|
||||
{184, 195, 194},
|
||||
{185, 196, 195},
|
||||
{186, 197, 196},
|
||||
{187, 198, 197},
|
||||
{188, 199, 198},
|
||||
{189, 190, 199},
|
||||
{190, 201, 200},
|
||||
{191, 202, 201},
|
||||
{192, 203, 202},
|
||||
{193, 204, 203},
|
||||
{194, 205, 204},
|
||||
{195, 206, 205},
|
||||
{196, 207, 206},
|
||||
{197, 208, 207},
|
||||
{198, 209, 208},
|
||||
{199, 200, 209},
|
||||
{200, 211, 210},
|
||||
{201, 212, 211},
|
||||
{202, 213, 212},
|
||||
{203, 214, 213},
|
||||
{204, 215, 214},
|
||||
{205, 216, 215},
|
||||
{206, 217, 216},
|
||||
{207, 218, 217},
|
||||
{208, 219, 218},
|
||||
{209, 210, 219},
|
||||
{210, 221, 220},
|
||||
{211, 222, 221},
|
||||
{212, 223, 222},
|
||||
{213, 224, 223},
|
||||
{214, 225, 224},
|
||||
{215, 226, 225},
|
||||
{216, 227, 226},
|
||||
{217, 228, 227},
|
||||
{218, 229, 228},
|
||||
{219, 220, 229},
|
||||
{220, 231, 230},
|
||||
{221, 232, 231},
|
||||
{222, 233, 232},
|
||||
{223, 234, 233},
|
||||
{224, 235, 234},
|
||||
{225, 236, 235},
|
||||
{226, 237, 236},
|
||||
{227, 238, 237},
|
||||
{228, 239, 238},
|
||||
{229, 230, 239},
|
||||
{230, 241, 240},
|
||||
{231, 242, 241},
|
||||
{232, 243, 242},
|
||||
{233, 244, 243},
|
||||
{234, 245, 244},
|
||||
{235, 246, 245},
|
||||
{236, 247, 246},
|
||||
{237, 248, 247},
|
||||
{238, 249, 248},
|
||||
{239, 240, 249},
|
||||
{240, 251, 250},
|
||||
{241, 252, 251},
|
||||
{242, 253, 252},
|
||||
{243, 254, 253},
|
||||
{244, 255, 254},
|
||||
{245, 256, 255},
|
||||
{246, 257, 256},
|
||||
{247, 258, 257},
|
||||
{248, 259, 258},
|
||||
{249, 250, 259},
|
||||
{250, 261, 260},
|
||||
{251, 262, 261},
|
||||
{252, 263, 262},
|
||||
{253, 264, 263},
|
||||
{254, 265, 264},
|
||||
{255, 266, 265},
|
||||
{256, 267, 266},
|
||||
{257, 268, 267},
|
||||
{258, 269, 268},
|
||||
{259, 260, 269},
|
||||
{260, 271, 270},
|
||||
{261, 272, 271},
|
||||
{262, 273, 272},
|
||||
{263, 274, 273},
|
||||
{264, 275, 274},
|
||||
{265, 276, 275},
|
||||
{266, 277, 276},
|
||||
{267, 278, 277},
|
||||
{268, 279, 278},
|
||||
{269, 270, 279},
|
||||
{270, 281, 280},
|
||||
{271, 282, 281},
|
||||
{272, 283, 282},
|
||||
{273, 284, 283},
|
||||
{274, 285, 284},
|
||||
{275, 286, 285},
|
||||
{276, 287, 286},
|
||||
{277, 288, 287},
|
||||
{278, 289, 288},
|
||||
{279, 280, 289},
|
||||
{280, 291, 290},
|
||||
{281, 292, 291},
|
||||
{282, 293, 292},
|
||||
{283, 294, 293},
|
||||
{284, 295, 294},
|
||||
{285, 296, 295},
|
||||
{286, 297, 296},
|
||||
{287, 298, 297},
|
||||
{288, 299, 298},
|
||||
{289, 290, 299},
|
||||
{290, 1, 0},
|
||||
{291, 2, 1},
|
||||
{292, 3, 2},
|
||||
{293, 4, 3},
|
||||
{294, 5, 4},
|
||||
{295, 6, 5},
|
||||
{296, 7, 6},
|
||||
{297, 8, 7},
|
||||
{298, 9, 8},
|
||||
{299, 0, 9},
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
4
examples/SoftDemo/bunny.inl
Normal file
4
examples/SoftDemo/bunny.inl
Normal file
File diff suppressed because one or more lines are too long
4
examples/SoftDemo/cube.inl
Normal file
4
examples/SoftDemo/cube.inl
Normal file
File diff suppressed because one or more lines are too long
@@ -144,7 +144,8 @@ void TreeNode::Open()
|
||||
m_InnerPanel->Show();
|
||||
if ( m_ToggleButton ) m_ToggleButton->SetToggleState( true );
|
||||
Invalidate();
|
||||
m_TreeControl->ForceUpdateScrollBars();
|
||||
if (m_TreeControl)
|
||||
m_TreeControl->ForceUpdateScrollBars();
|
||||
}
|
||||
|
||||
void TreeNode::Close()
|
||||
@@ -153,7 +154,8 @@ void TreeNode::Close()
|
||||
if ( m_ToggleButton ) m_ToggleButton->SetToggleState( false );
|
||||
|
||||
Invalidate();
|
||||
m_TreeControl->ForceUpdateScrollBars();
|
||||
if (m_TreeControl)
|
||||
m_TreeControl->ForceUpdateScrollBars();
|
||||
}
|
||||
|
||||
void TreeNode::ExpandAll()
|
||||
|
||||
819
examples/VoronoiFracture/VoronoiFractureDemo.cpp
Normal file
819
examples/VoronoiFracture/VoronoiFractureDemo.cpp
Normal file
@@ -0,0 +1,819 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
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.
|
||||
*/
|
||||
/*
|
||||
Voronoi fracture and shatter code and demo copyright (c) 2011 Alain Ducharme
|
||||
- Reset scene (press spacebar) to generate new random voronoi shattered cuboids
|
||||
- Check console for total time required to: compute and mesh all 3D shards, calculate volumes and centers of mass and create rigid bodies
|
||||
- Modify VORONOIPOINTS define below to change number of potential voronoi shards
|
||||
- Note that demo's visual cracks between voronoi shards are NOT present in the internally generated voronoi mesh!
|
||||
*/
|
||||
|
||||
//Number of random voronoi points to generate for shattering
|
||||
#define VORONOIPOINTS 100
|
||||
|
||||
//maximum number of objects (and allow user to shoot additional boxes)
|
||||
#define MAX_PROXIES (2048)
|
||||
#define BREAKING_THRESHOLD 3
|
||||
#define CONVEX_MARGIN 0.04
|
||||
static int useMpr = 0;
|
||||
|
||||
#include "VoronoiFractureDemo.h"
|
||||
|
||||
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include <stdio.h> //printf debugging
|
||||
|
||||
|
||||
static bool useGenericConstraint = false;
|
||||
|
||||
#include "btConvexConvexMprAlgorithm.h"
|
||||
|
||||
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
#include "LinearMath/btConvexHullComputer.h"
|
||||
#include "LinearMath/btQuaternion.h"
|
||||
#include <set>
|
||||
#include <time.h>
|
||||
|
||||
class btBroadphaseInterface;
|
||||
class btCollisionShape;
|
||||
class btOverlappingPairCache;
|
||||
class btCollisionDispatcher;
|
||||
class btConstraintSolver;
|
||||
struct btCollisionAlgorithmCreateFunc;
|
||||
class btDefaultCollisionConfiguration;
|
||||
|
||||
#include "../CommonInterfaces/CommonRigidBodyBase.h"
|
||||
|
||||
|
||||
class VoronoiFractureDemo : public CommonRigidBodyBase
|
||||
{
|
||||
//keep the collision shapes, for deletion/cleanup
|
||||
btAlignedObjectArray<btCollisionShape*> m_collisionShapes;
|
||||
|
||||
btBroadphaseInterface* m_broadphase;
|
||||
|
||||
btCollisionDispatcher* m_dispatcher;
|
||||
|
||||
btConstraintSolver* m_solver;
|
||||
|
||||
btDefaultCollisionConfiguration* m_collisionConfiguration;
|
||||
|
||||
btClock m_perfmTimer;
|
||||
|
||||
public:
|
||||
|
||||
VoronoiFractureDemo(struct GUIHelperInterface* helper)
|
||||
:CommonRigidBodyBase(helper)
|
||||
{
|
||||
srand((unsigned)time(NULL)); // Seed it...
|
||||
}
|
||||
virtual ~VoronoiFractureDemo()
|
||||
{
|
||||
btAssert(m_dynamicsWorld==0);
|
||||
}
|
||||
void initPhysics();
|
||||
|
||||
void exitPhysics();
|
||||
|
||||
//virtual void renderme();
|
||||
|
||||
void getVerticesInsidePlanes(const btAlignedObjectArray<btVector3>& planes, btAlignedObjectArray<btVector3>& verticesOut, std::set<int>& planeIndicesOut);
|
||||
void voronoiBBShatter(const btAlignedObjectArray<btVector3>& points, const btVector3& bbmin, const btVector3& bbmax, const btQuaternion& bbq, const btVector3& bbt, btScalar matDensity);
|
||||
void voronoiConvexHullShatter(const btAlignedObjectArray<btVector3>& points, const btAlignedObjectArray<btVector3>& verts, const btQuaternion& bbq, const btVector3& bbt, btScalar matDensity);
|
||||
|
||||
//virtual void clientMoveAndDisplay();
|
||||
|
||||
//virtual void displayCallback();
|
||||
//virtual void clientResetScene();
|
||||
|
||||
//virtual void keyboardCallback(unsigned char key, int x, int y);
|
||||
|
||||
void attachFixedConstraints();
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
void VoronoiFractureDemo::attachFixedConstraints()
|
||||
{
|
||||
btAlignedObjectArray<btRigidBody*> bodies;
|
||||
|
||||
int numManifolds = m_dynamicsWorld->getDispatcher()->getNumManifolds();
|
||||
|
||||
for (int i=0;i<numManifolds;i++)
|
||||
{
|
||||
btPersistentManifold* manifold = m_dynamicsWorld->getDispatcher()->getManifoldByIndexInternal(i);
|
||||
if (!manifold->getNumContacts())
|
||||
continue;
|
||||
|
||||
btScalar minDist = 1e30f;
|
||||
int minIndex = -1;
|
||||
for (int v=0;v<manifold->getNumContacts();v++)
|
||||
{
|
||||
if (minDist >manifold->getContactPoint(v).getDistance())
|
||||
{
|
||||
minDist = manifold->getContactPoint(v).getDistance();
|
||||
minIndex = v;
|
||||
}
|
||||
}
|
||||
if (minDist>0.)
|
||||
continue;
|
||||
|
||||
btCollisionObject* colObj0 = (btCollisionObject*)manifold->getBody0();
|
||||
btCollisionObject* colObj1 = (btCollisionObject*)manifold->getBody1();
|
||||
// int tag0 = (colObj0)->getIslandTag();
|
||||
// int tag1 = (colObj1)->getIslandTag();
|
||||
btRigidBody* body0 = btRigidBody::upcast(colObj0);
|
||||
btRigidBody* body1 = btRigidBody::upcast(colObj1);
|
||||
if (bodies.findLinearSearch(body0)==bodies.size())
|
||||
bodies.push_back(body0);
|
||||
if (bodies.findLinearSearch(body1)==bodies.size())
|
||||
bodies.push_back(body1);
|
||||
|
||||
if (body0 && body1)
|
||||
{
|
||||
if (!colObj0->isStaticOrKinematicObject() && !colObj1->isStaticOrKinematicObject())
|
||||
{
|
||||
if (body0->checkCollideWithOverride(body1))
|
||||
{
|
||||
{
|
||||
btTransform trA,trB;
|
||||
trA.setIdentity();
|
||||
trB.setIdentity();
|
||||
btVector3 contactPosWorld = manifold->getContactPoint(minIndex).m_positionWorldOnA;
|
||||
btTransform globalFrame;
|
||||
globalFrame.setIdentity();
|
||||
globalFrame.setOrigin(contactPosWorld);
|
||||
|
||||
trA = body0->getWorldTransform().inverse()*globalFrame;
|
||||
trB = body1->getWorldTransform().inverse()*globalFrame;
|
||||
float totalMass = 1.f/body0->getInvMass() + 1.f/body1->getInvMass();
|
||||
|
||||
|
||||
if (useGenericConstraint)
|
||||
{
|
||||
btGeneric6DofConstraint* dof6 = new btGeneric6DofConstraint(*body0,*body1,trA,trB,true);
|
||||
dof6->setOverrideNumSolverIterations(30);
|
||||
|
||||
|
||||
dof6->setBreakingImpulseThreshold(BREAKING_THRESHOLD*totalMass);
|
||||
|
||||
for (int i=0;i<6;i++)
|
||||
dof6->setLimit(i,0,0);
|
||||
m_dynamicsWorld->addConstraint(dof6,true);
|
||||
|
||||
} else
|
||||
{
|
||||
btFixedConstraint* fixed = new btFixedConstraint(*body0,*body1,trA,trB);
|
||||
fixed->setBreakingImpulseThreshold(BREAKING_THRESHOLD*totalMass);
|
||||
fixed ->setOverrideNumSolverIterations(30);
|
||||
m_dynamicsWorld->addConstraint(fixed,true);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (int i=0;i<bodies.size();i++)
|
||||
{
|
||||
m_dynamicsWorld->removeRigidBody(bodies[i]);
|
||||
m_dynamicsWorld->addRigidBody(bodies[i]);
|
||||
}
|
||||
}
|
||||
/*
|
||||
void VoronoiFractureDemo::keyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
if (key == 'g')
|
||||
{
|
||||
attachFixedConstraints();
|
||||
}else
|
||||
{
|
||||
PlatformDemoApplication::keyboardCallback(key,x,y);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void VoronoiFractureDemo::getVerticesInsidePlanes(const btAlignedObjectArray<btVector3>& planes, btAlignedObjectArray<btVector3>& verticesOut, std::set<int>& planeIndicesOut)
|
||||
{
|
||||
// Based on btGeometryUtil.cpp (Gino van den Bergen / Erwin Coumans)
|
||||
verticesOut.resize(0);
|
||||
planeIndicesOut.clear();
|
||||
const int numPlanes = planes.size();
|
||||
int i, j, k, l;
|
||||
for (i=0;i<numPlanes;i++)
|
||||
{
|
||||
const btVector3& N1 = planes[i];
|
||||
for (j=i+1;j<numPlanes;j++)
|
||||
{
|
||||
const btVector3& N2 = planes[j];
|
||||
btVector3 n1n2 = N1.cross(N2);
|
||||
if (n1n2.length2() > btScalar(0.0001))
|
||||
{
|
||||
for (k=j+1;k<numPlanes;k++)
|
||||
{
|
||||
const btVector3& N3 = planes[k];
|
||||
btVector3 n2n3 = N2.cross(N3);
|
||||
btVector3 n3n1 = N3.cross(N1);
|
||||
if ((n2n3.length2() > btScalar(0.0001)) && (n3n1.length2() > btScalar(0.0001) ))
|
||||
{
|
||||
btScalar quotient = (N1.dot(n2n3));
|
||||
if (btFabs(quotient) > btScalar(0.0001))
|
||||
{
|
||||
btVector3 potentialVertex = (n2n3 * N1[3] + n3n1 * N2[3] + n1n2 * N3[3]) * (btScalar(-1.) / quotient);
|
||||
for (l=0; l<numPlanes; l++)
|
||||
{
|
||||
const btVector3& NP = planes[l];
|
||||
if (btScalar(NP.dot(potentialVertex))+btScalar(NP[3]) > btScalar(0.000001))
|
||||
break;
|
||||
}
|
||||
if (l == numPlanes)
|
||||
{
|
||||
// vertex (three plane intersection) inside all planes
|
||||
verticesOut.push_back(potentialVertex);
|
||||
planeIndicesOut.insert(i);
|
||||
planeIndicesOut.insert(j);
|
||||
planeIndicesOut.insert(k);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static btVector3 curVoronoiPoint;
|
||||
|
||||
struct pointCmp
|
||||
{
|
||||
bool operator()(const btVector3& p1, const btVector3& p2) const
|
||||
{
|
||||
float v1 = (p1-curVoronoiPoint).length2();
|
||||
float v2 = (p2-curVoronoiPoint).length2();
|
||||
bool result0 = v1 < v2;
|
||||
//bool result1 = ((btScalar)(p1-curVoronoiPoint).length2()) < ((btScalar)(p2-curVoronoiPoint).length2());
|
||||
//apparently result0 is not always result1, because extended precision used in registered is different from precision when values are stored in memory
|
||||
return result0;
|
||||
}
|
||||
};
|
||||
|
||||
void VoronoiFractureDemo::voronoiBBShatter(const btAlignedObjectArray<btVector3>& points, const btVector3& bbmin, const btVector3& bbmax, const btQuaternion& bbq, const btVector3& bbt, btScalar matDensity) {
|
||||
// points define voronoi cells in world space (avoid duplicates)
|
||||
// bbmin & bbmax = bounding box min and max in local space
|
||||
// bbq & bbt = bounding box quaternion rotation and translation
|
||||
// matDensity = Material density for voronoi shard mass calculation
|
||||
btVector3 bbvx = quatRotate(bbq, btVector3(1.0, 0.0, 0.0));
|
||||
btVector3 bbvy = quatRotate(bbq, btVector3(0.0, 1.0, 0.0));
|
||||
btVector3 bbvz = quatRotate(bbq, btVector3(0.0, 0.0, 1.0));
|
||||
btQuaternion bbiq = bbq.inverse();
|
||||
btConvexHullComputer* convexHC = new btConvexHullComputer();
|
||||
btAlignedObjectArray<btVector3> vertices;
|
||||
btVector3 rbb, nrbb;
|
||||
btScalar nlength, maxDistance, distance;
|
||||
btAlignedObjectArray<btVector3> sortedVoronoiPoints;
|
||||
sortedVoronoiPoints.copyFromArray(points);
|
||||
btVector3 normal, plane;
|
||||
btAlignedObjectArray<btVector3> planes;
|
||||
std::set<int> planeIndices;
|
||||
std::set<int>::iterator planeIndicesIter;
|
||||
int numplaneIndices;
|
||||
int cellnum = 0;
|
||||
int i, j, k;
|
||||
|
||||
int numpoints = points.size();
|
||||
for (i=0; i < numpoints ;i++) {
|
||||
curVoronoiPoint = points[i];
|
||||
btVector3 icp = quatRotate(bbiq, curVoronoiPoint - bbt);
|
||||
rbb = icp - bbmax;
|
||||
nrbb = bbmin - icp;
|
||||
planes.resize(6);
|
||||
planes[0] = bbvx; planes[0][3] = rbb.x();
|
||||
planes[1] = bbvy; planes[1][3] = rbb.y();
|
||||
planes[2] = bbvz; planes[2][3] = rbb.z();
|
||||
planes[3] = -bbvx; planes[3][3] = nrbb.x();
|
||||
planes[4] = -bbvy; planes[4][3] = nrbb.y();
|
||||
planes[5] = -bbvz; planes[5][3] = nrbb.z();
|
||||
maxDistance = SIMD_INFINITY;
|
||||
sortedVoronoiPoints.heapSort(pointCmp());
|
||||
for (j=1; j < numpoints; j++) {
|
||||
normal = sortedVoronoiPoints[j] - curVoronoiPoint;
|
||||
nlength = normal.length();
|
||||
if (nlength > maxDistance)
|
||||
break;
|
||||
plane = normal.normalized();
|
||||
plane[3] = -nlength / btScalar(2.);
|
||||
planes.push_back(plane);
|
||||
getVerticesInsidePlanes(planes, vertices, planeIndices);
|
||||
if (vertices.size() == 0)
|
||||
break;
|
||||
numplaneIndices = planeIndices.size();
|
||||
if (numplaneIndices != planes.size()) {
|
||||
planeIndicesIter = planeIndices.begin();
|
||||
for (k=0; k < numplaneIndices; k++) {
|
||||
if (k != *planeIndicesIter)
|
||||
planes[k] = planes[*planeIndicesIter];
|
||||
planeIndicesIter++;
|
||||
}
|
||||
planes.resize(numplaneIndices);
|
||||
}
|
||||
maxDistance = vertices[0].length();
|
||||
for (k=1; k < vertices.size(); k++) {
|
||||
distance = vertices[k].length();
|
||||
if (maxDistance < distance)
|
||||
maxDistance = distance;
|
||||
}
|
||||
maxDistance *= btScalar(2.);
|
||||
}
|
||||
if (vertices.size() == 0)
|
||||
continue;
|
||||
|
||||
// Clean-up voronoi convex shard vertices and generate edges & faces
|
||||
convexHC->compute(&vertices[0].getX(), sizeof(btVector3), vertices.size(),CONVEX_MARGIN,0.0);
|
||||
|
||||
// At this point we have a complete 3D voronoi shard mesh contained in convexHC
|
||||
|
||||
// Calculate volume and center of mass (Stan Melax volume integration)
|
||||
int numFaces = convexHC->faces.size();
|
||||
int v0, v1, v2; // Triangle vertices
|
||||
btScalar volume = btScalar(0.);
|
||||
btVector3 com(0., 0., 0.);
|
||||
for (j=0; j < numFaces; j++) {
|
||||
const btConvexHullComputer::Edge* edge = &convexHC->edges[convexHC->faces[j]];
|
||||
v0 = edge->getSourceVertex();
|
||||
v1 = edge->getTargetVertex();
|
||||
edge = edge->getNextEdgeOfFace();
|
||||
v2 = edge->getTargetVertex();
|
||||
while (v2 != v0) {
|
||||
// Counter-clockwise triangulated voronoi shard mesh faces (v0-v1-v2) and edges here...
|
||||
btScalar vol = convexHC->vertices[v0].triple(convexHC->vertices[v1], convexHC->vertices[v2]);
|
||||
volume += vol;
|
||||
com += vol * (convexHC->vertices[v0] + convexHC->vertices[v1] + convexHC->vertices[v2]);
|
||||
edge = edge->getNextEdgeOfFace();
|
||||
v1 = v2;
|
||||
v2 = edge->getTargetVertex();
|
||||
}
|
||||
}
|
||||
com /= volume * btScalar(4.);
|
||||
volume /= btScalar(6.);
|
||||
|
||||
// Shift all vertices relative to center of mass
|
||||
int numVerts = convexHC->vertices.size();
|
||||
for (j=0; j < numVerts; j++)
|
||||
{
|
||||
convexHC->vertices[j] -= com;
|
||||
}
|
||||
|
||||
// Note:
|
||||
// At this point convex hulls contained in convexHC should be accurate (line up flush with other pieces, no cracks),
|
||||
// ...however Bullet Physics rigid bodies demo visualizations appear to produce some visible cracks.
|
||||
// Use the mesh in convexHC for visual display or to perform boolean operations with.
|
||||
|
||||
// Create Bullet Physics rigid body shards
|
||||
btCollisionShape* shardShape = new btConvexHullShape(&(convexHC->vertices[0].getX()), convexHC->vertices.size());
|
||||
shardShape->setMargin(CONVEX_MARGIN); // for this demo; note convexHC has optional margin parameter for this
|
||||
m_collisionShapes.push_back(shardShape);
|
||||
btTransform shardTransform;
|
||||
shardTransform.setIdentity();
|
||||
shardTransform.setOrigin(curVoronoiPoint + com); // Shard's adjusted location
|
||||
btDefaultMotionState* shardMotionState = new btDefaultMotionState(shardTransform);
|
||||
btScalar shardMass(volume * matDensity);
|
||||
btVector3 shardInertia(0.,0.,0.);
|
||||
shardShape->calculateLocalInertia(shardMass, shardInertia);
|
||||
btRigidBody::btRigidBodyConstructionInfo shardRBInfo(shardMass, shardMotionState, shardShape, shardInertia);
|
||||
btRigidBody* shardBody = new btRigidBody(shardRBInfo);
|
||||
m_dynamicsWorld->addRigidBody(shardBody);
|
||||
|
||||
cellnum ++;
|
||||
|
||||
}
|
||||
printf("Generated %d voronoi btRigidBody shards\n", cellnum);
|
||||
}
|
||||
|
||||
void VoronoiFractureDemo::voronoiConvexHullShatter(const btAlignedObjectArray<btVector3>& points, const btAlignedObjectArray<btVector3>& verts, const btQuaternion& bbq, const btVector3& bbt, btScalar matDensity) {
|
||||
// points define voronoi cells in world space (avoid duplicates)
|
||||
// verts = source (convex hull) mesh vertices in local space
|
||||
// bbq & bbt = source (convex hull) mesh quaternion rotation and translation
|
||||
// matDensity = Material density for voronoi shard mass calculation
|
||||
btConvexHullComputer* convexHC = new btConvexHullComputer();
|
||||
btAlignedObjectArray<btVector3> vertices, chverts;
|
||||
btVector3 rbb, nrbb;
|
||||
btScalar nlength, maxDistance, distance;
|
||||
btAlignedObjectArray<btVector3> sortedVoronoiPoints;
|
||||
sortedVoronoiPoints.copyFromArray(points);
|
||||
btVector3 normal, plane;
|
||||
btAlignedObjectArray<btVector3> planes, convexPlanes;
|
||||
std::set<int> planeIndices;
|
||||
std::set<int>::iterator planeIndicesIter;
|
||||
int numplaneIndices;
|
||||
int cellnum = 0;
|
||||
int i, j, k;
|
||||
|
||||
// Convert verts to world space and get convexPlanes
|
||||
int numverts = verts.size();
|
||||
chverts.resize(verts.size());
|
||||
for (i=0; i < numverts ;i++) {
|
||||
chverts[i] = quatRotate(bbq, verts[i]) + bbt;
|
||||
}
|
||||
//btGeometryUtil::getPlaneEquationsFromVertices(chverts, convexPlanes);
|
||||
// Using convexHullComputer faster than getPlaneEquationsFromVertices for large meshes...
|
||||
convexHC->compute(&chverts[0].getX(), sizeof(btVector3), numverts, 0.0, 0.0);
|
||||
int numFaces = convexHC->faces.size();
|
||||
int v0, v1, v2; // vertices
|
||||
for (i=0; i < numFaces; i++) {
|
||||
const btConvexHullComputer::Edge* edge = &convexHC->edges[convexHC->faces[i]];
|
||||
v0 = edge->getSourceVertex();
|
||||
v1 = edge->getTargetVertex();
|
||||
edge = edge->getNextEdgeOfFace();
|
||||
v2 = edge->getTargetVertex();
|
||||
plane = (convexHC->vertices[v1]-convexHC->vertices[v0]).cross(convexHC->vertices[v2]-convexHC->vertices[v0]).normalize();
|
||||
plane[3] = -plane.dot(convexHC->vertices[v0]);
|
||||
convexPlanes.push_back(plane);
|
||||
}
|
||||
const int numconvexPlanes = convexPlanes.size();
|
||||
|
||||
int numpoints = points.size();
|
||||
for (i=0; i < numpoints ;i++) {
|
||||
curVoronoiPoint = points[i];
|
||||
planes.copyFromArray(convexPlanes);
|
||||
for (j=0; j < numconvexPlanes ;j++) {
|
||||
planes[j][3] += planes[j].dot(curVoronoiPoint);
|
||||
}
|
||||
maxDistance = SIMD_INFINITY;
|
||||
sortedVoronoiPoints.heapSort(pointCmp());
|
||||
for (j=1; j < numpoints; j++) {
|
||||
normal = sortedVoronoiPoints[j] - curVoronoiPoint;
|
||||
nlength = normal.length();
|
||||
if (nlength > maxDistance)
|
||||
break;
|
||||
plane = normal.normalized();
|
||||
plane[3] = -nlength / btScalar(2.);
|
||||
planes.push_back(plane);
|
||||
getVerticesInsidePlanes(planes, vertices, planeIndices);
|
||||
if (vertices.size() == 0)
|
||||
break;
|
||||
numplaneIndices = planeIndices.size();
|
||||
if (numplaneIndices != planes.size()) {
|
||||
planeIndicesIter = planeIndices.begin();
|
||||
for (k=0; k < numplaneIndices; k++) {
|
||||
if (k != *planeIndicesIter)
|
||||
planes[k] = planes[*planeIndicesIter];
|
||||
planeIndicesIter++;
|
||||
}
|
||||
planes.resize(numplaneIndices);
|
||||
}
|
||||
maxDistance = vertices[0].length();
|
||||
for (k=1; k < vertices.size(); k++) {
|
||||
distance = vertices[k].length();
|
||||
if (maxDistance < distance)
|
||||
maxDistance = distance;
|
||||
}
|
||||
maxDistance *= btScalar(2.);
|
||||
}
|
||||
if (vertices.size() == 0)
|
||||
continue;
|
||||
|
||||
// Clean-up voronoi convex shard vertices and generate edges & faces
|
||||
convexHC->compute(&vertices[0].getX(), sizeof(btVector3), vertices.size(),0.0,0.0);
|
||||
|
||||
// At this point we have a complete 3D voronoi shard mesh contained in convexHC
|
||||
|
||||
// Calculate volume and center of mass (Stan Melax volume integration)
|
||||
numFaces = convexHC->faces.size();
|
||||
btScalar volume = btScalar(0.);
|
||||
btVector3 com(0., 0., 0.);
|
||||
for (j=0; j < numFaces; j++) {
|
||||
const btConvexHullComputer::Edge* edge = &convexHC->edges[convexHC->faces[j]];
|
||||
v0 = edge->getSourceVertex();
|
||||
v1 = edge->getTargetVertex();
|
||||
edge = edge->getNextEdgeOfFace();
|
||||
v2 = edge->getTargetVertex();
|
||||
while (v2 != v0) {
|
||||
// Counter-clockwise triangulated voronoi shard mesh faces (v0-v1-v2) and edges here...
|
||||
btScalar vol = convexHC->vertices[v0].triple(convexHC->vertices[v1], convexHC->vertices[v2]);
|
||||
volume += vol;
|
||||
com += vol * (convexHC->vertices[v0] + convexHC->vertices[v1] + convexHC->vertices[v2]);
|
||||
edge = edge->getNextEdgeOfFace();
|
||||
v1 = v2;
|
||||
v2 = edge->getTargetVertex();
|
||||
}
|
||||
}
|
||||
com /= volume * btScalar(4.);
|
||||
volume /= btScalar(6.);
|
||||
|
||||
// Shift all vertices relative to center of mass
|
||||
int numVerts = convexHC->vertices.size();
|
||||
for (j=0; j < numVerts; j++)
|
||||
{
|
||||
convexHC->vertices[j] -= com;
|
||||
}
|
||||
|
||||
// Note:
|
||||
// At this point convex hulls contained in convexHC should be accurate (line up flush with other pieces, no cracks),
|
||||
// ...however Bullet Physics rigid bodies demo visualizations appear to produce some visible cracks.
|
||||
// Use the mesh in convexHC for visual display or to perform boolean operations with.
|
||||
|
||||
// Create Bullet Physics rigid body shards
|
||||
btCollisionShape* shardShape = new btConvexHullShape(&(convexHC->vertices[0].getX()), convexHC->vertices.size());
|
||||
shardShape->setMargin(CONVEX_MARGIN); // for this demo; note convexHC has optional margin parameter for this
|
||||
m_collisionShapes.push_back(shardShape);
|
||||
btTransform shardTransform;
|
||||
shardTransform.setIdentity();
|
||||
shardTransform.setOrigin(curVoronoiPoint + com); // Shard's adjusted location
|
||||
btDefaultMotionState* shardMotionState = new btDefaultMotionState(shardTransform);
|
||||
btScalar shardMass(volume * matDensity);
|
||||
btVector3 shardInertia(0.,0.,0.);
|
||||
shardShape->calculateLocalInertia(shardMass, shardInertia);
|
||||
btRigidBody::btRigidBodyConstructionInfo shardRBInfo(shardMass, shardMotionState, shardShape, shardInertia);
|
||||
btRigidBody* shardBody = new btRigidBody(shardRBInfo);
|
||||
m_dynamicsWorld->addRigidBody(shardBody);
|
||||
|
||||
cellnum ++;
|
||||
|
||||
}
|
||||
printf("Generated %d voronoi btRigidBody shards\n", cellnum);
|
||||
}
|
||||
|
||||
/*
|
||||
void VoronoiFractureDemo::clientMoveAndDisplay()
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
//simple dynamics world doesn't handle fixed-time-stepping
|
||||
float ms = getDeltaTimeMicroseconds();
|
||||
|
||||
///step the simulation
|
||||
if (m_dynamicsWorld)
|
||||
{
|
||||
m_dynamicsWorld->stepSimulation(1. / 60., 0);// ms / 1000000.f);
|
||||
//optional but useful: debug drawing
|
||||
m_dynamicsWorld->debugDrawWorld();
|
||||
}
|
||||
|
||||
renderme();
|
||||
|
||||
glFlush();
|
||||
|
||||
swapBuffers();
|
||||
}
|
||||
*/
|
||||
/*
|
||||
void VoronoiFractureDemo::displayCallback(void) {
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
renderme();
|
||||
|
||||
//optional but useful: debug drawing to detect problems
|
||||
if (m_dynamicsWorld)
|
||||
m_dynamicsWorld->debugDrawWorld();
|
||||
|
||||
glFlush();
|
||||
swapBuffers();
|
||||
}
|
||||
*/
|
||||
/*
|
||||
void VoronoiFractureDemo::renderme()
|
||||
{
|
||||
DemoApplication::renderme();
|
||||
char buf[124];
|
||||
|
||||
int lineWidth = 200;
|
||||
int xStart = m_glutScreenWidth - lineWidth;
|
||||
|
||||
if (useMpr)
|
||||
{
|
||||
sprintf(buf, "Using GJK+MPR");
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buf, "Using GJK+EPA");
|
||||
}
|
||||
GLDebugDrawString(xStart, 20, buf);
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
void VoronoiFractureDemo::initPhysics()
|
||||
{
|
||||
srand(13);
|
||||
useGenericConstraint = !useGenericConstraint;
|
||||
printf("useGenericConstraint = %d\n", useGenericConstraint);
|
||||
|
||||
|
||||
|
||||
///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);
|
||||
|
||||
useMpr = 1 - useMpr;
|
||||
|
||||
if (useMpr)
|
||||
{
|
||||
printf("using GJK+MPR convex-convex collision detection\n");
|
||||
btConvexConvexMprAlgorithm::CreateFunc* cf = new btConvexConvexMprAlgorithm::CreateFunc;
|
||||
m_dispatcher->registerCollisionCreateFunc(CONVEX_HULL_SHAPE_PROXYTYPE, CONVEX_HULL_SHAPE_PROXYTYPE, cf);
|
||||
m_dispatcher->registerCollisionCreateFunc(CONVEX_HULL_SHAPE_PROXYTYPE, BOX_SHAPE_PROXYTYPE, cf);
|
||||
m_dispatcher->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE, CONVEX_HULL_SHAPE_PROXYTYPE, cf);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("using default (GJK+EPA) convex-convex collision detection\n");
|
||||
}
|
||||
|
||||
m_broadphase = new btDbvtBroadphase();
|
||||
|
||||
///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
|
||||
btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver;
|
||||
m_solver = sol;
|
||||
|
||||
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
|
||||
m_dynamicsWorld->getSolverInfo().m_splitImpulse = true;
|
||||
|
||||
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
|
||||
|
||||
|
||||
m_dynamicsWorld->setGravity(btVector3(0,-10,0));
|
||||
|
||||
///create a few basic rigid bodies
|
||||
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));
|
||||
// btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50);
|
||||
|
||||
m_collisionShapes.push_back(groundShape);
|
||||
|
||||
btTransform groundTransform;
|
||||
groundTransform.setIdentity();
|
||||
groundTransform.setOrigin(btVector3(0,-50,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);
|
||||
|
||||
//add the body to the dynamics world
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
}
|
||||
|
||||
{
|
||||
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(10.),btScalar(8.),btScalar(1.)));
|
||||
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);
|
||||
groundTransform.setOrigin(btVector3(0,0,0));
|
||||
//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);
|
||||
|
||||
//add the body to the dynamics world
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
}
|
||||
|
||||
// ==> Voronoi Shatter Basic Demo: Random Cuboid
|
||||
|
||||
// Random size cuboid (defined by bounding box max and min)
|
||||
btVector3 bbmax(btScalar(rand() / btScalar(RAND_MAX)) * 12. +0.5, btScalar(rand() / btScalar(RAND_MAX)) * 1. +0.5, btScalar(rand() / btScalar(RAND_MAX)) * 1. +0.5);
|
||||
btVector3 bbmin = -bbmax;
|
||||
// Place it 10 units above ground
|
||||
btVector3 bbt(0,15,0);
|
||||
// Use an arbitrary material density for shards (should be consitent/relative with/to rest of RBs in world)
|
||||
btScalar matDensity = 1;
|
||||
// Using random rotation
|
||||
btQuaternion bbq(btScalar(rand() / btScalar(RAND_MAX)) * 2. -1.,btScalar(rand() / btScalar(RAND_MAX)) * 2. -1.,btScalar(rand() / btScalar(RAND_MAX)) * 2. -1.,btScalar(rand() / btScalar(RAND_MAX)) * 2. -1.);
|
||||
bbq.normalize();
|
||||
// Generate random points for voronoi cells
|
||||
btAlignedObjectArray<btVector3> points;
|
||||
btVector3 point;
|
||||
btVector3 diff = bbmax - bbmin;
|
||||
for (int i=0; i < VORONOIPOINTS; i++) {
|
||||
// Place points within box area (points are in world coordinates)
|
||||
point = quatRotate(bbq, btVector3(btScalar(rand() / btScalar(RAND_MAX)) * diff.x() -diff.x()/2., btScalar(rand() / btScalar(RAND_MAX)) * diff.y() -diff.y()/2., btScalar(rand() / btScalar(RAND_MAX)) * diff.z() -diff.z()/2.)) + bbt;
|
||||
points.push_back(point);
|
||||
}
|
||||
m_perfmTimer.reset();
|
||||
voronoiBBShatter(points, bbmin, bbmax, bbq, bbt, matDensity);
|
||||
printf("Total Time: %f seconds\n", m_perfmTimer.getTimeMilliseconds()/1000.);
|
||||
|
||||
for (int i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--)
|
||||
{
|
||||
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
|
||||
obj->getCollisionShape()->setMargin(CONVEX_MARGIN+0.01);
|
||||
}
|
||||
m_dynamicsWorld->performDiscreteCollisionDetection();
|
||||
|
||||
for (int i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--)
|
||||
{
|
||||
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
|
||||
obj->getCollisionShape()->setMargin(CONVEX_MARGIN);
|
||||
}
|
||||
|
||||
attachFixedConstraints();
|
||||
|
||||
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
|
||||
}
|
||||
|
||||
|
||||
void VoronoiFractureDemo::exitPhysics()
|
||||
{
|
||||
|
||||
//cleanup in the reverse order of creation/initialization
|
||||
|
||||
int i;
|
||||
//remove all constraints
|
||||
for (i=m_dynamicsWorld->getNumConstraints()-1;i>=0;i--)
|
||||
{
|
||||
btTypedConstraint* constraint = m_dynamicsWorld->getConstraint(i);
|
||||
m_dynamicsWorld->removeConstraint(constraint);
|
||||
delete constraint;
|
||||
}
|
||||
|
||||
//remove the rigidbodies from the dynamics world and delete them
|
||||
|
||||
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 collision shapes
|
||||
for (int j=0;j<m_collisionShapes.size();j++)
|
||||
{
|
||||
btCollisionShape* shape = m_collisionShapes[j];
|
||||
delete shape;
|
||||
}
|
||||
m_collisionShapes.clear();
|
||||
|
||||
delete m_dynamicsWorld;
|
||||
m_dynamicsWorld = 0;
|
||||
|
||||
delete m_solver;
|
||||
m_solver=0;
|
||||
|
||||
delete m_broadphase;
|
||||
m_broadphase=0;
|
||||
|
||||
delete m_dispatcher;
|
||||
m_dispatcher=0;
|
||||
|
||||
delete m_collisionConfiguration;
|
||||
m_collisionConfiguration=0;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
static DemoApplication* Create()
|
||||
{
|
||||
VoronoiFractureDemo* demo = new VoronoiFractureDemo;
|
||||
demo->myinit();
|
||||
demo->initPhysics();
|
||||
return demo;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
ExampleInterface* VoronoiFractureCreateFunc(PhysicsInterface* pint, GUIHelperInterface* helper, int option)
|
||||
{
|
||||
return new VoronoiFractureDemo(helper);
|
||||
}
|
||||
21
examples/VoronoiFracture/VoronoiFractureDemo.h
Normal file
21
examples/VoronoiFracture/VoronoiFractureDemo.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
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 VORONOI_FRACTURE_DEMO_H
|
||||
#define VORONOI_FRACTURE_DEMO_H
|
||||
|
||||
class ExampleInterface* VoronoiFractureCreateFunc(struct PhysicsInterface* pint, struct GUIHelperInterface* helper, int option);
|
||||
|
||||
#endif //VORONOI_FRACTURE_DEMO_H
|
||||
|
||||
288
examples/VoronoiFracture/btConvexConvexMprAlgorithm.cpp
Normal file
288
examples/VoronoiFracture/btConvexConvexMprAlgorithm.cpp
Normal file
@@ -0,0 +1,288 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2014 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
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 "btConvexConvexMprAlgorithm.h"
|
||||
|
||||
//#include <stdio.h>
|
||||
#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
|
||||
#include "BulletCollision/CollisionShapes/btConvexShape.h"
|
||||
|
||||
#include "BulletCollision/CollisionShapes/btTriangleShape.h"
|
||||
|
||||
|
||||
|
||||
#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
|
||||
#include "BulletCollision/CollisionShapes/btBoxShape.h"
|
||||
#include "BulletCollision/CollisionDispatch/btManifoldResult.h"
|
||||
|
||||
#include "BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h"
|
||||
#include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h"
|
||||
#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
|
||||
#include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h"
|
||||
|
||||
|
||||
|
||||
#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
|
||||
#include "BulletCollision/CollisionShapes/btSphereShape.h"
|
||||
|
||||
#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h"
|
||||
|
||||
#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h"
|
||||
#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
|
||||
#include "BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
|
||||
|
||||
#include "BulletCollision/NarrowPhaseCollision/btComputeGjkEpaPenetration.h"
|
||||
#include "BulletCollision/NarrowPhaseCollision/btGjkEpa3.h"
|
||||
#include "BulletCollision/NarrowPhaseCollision/btMprPenetration.h"
|
||||
|
||||
//this is just an internal debug variable to switch between GJK+MPR or GJK+EPA
|
||||
bool gUseMprCollisionFunction = true;
|
||||
|
||||
btConvexConvexMprAlgorithm::CreateFunc::CreateFunc()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
btConvexConvexMprAlgorithm::CreateFunc::~CreateFunc()
|
||||
{
|
||||
}
|
||||
|
||||
btConvexConvexMprAlgorithm::btConvexConvexMprAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
|
||||
: btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap),
|
||||
m_ownManifold (false),
|
||||
m_manifoldPtr(mf)
|
||||
{
|
||||
(void)body0Wrap;
|
||||
(void)body1Wrap;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
btConvexConvexMprAlgorithm::~btConvexConvexMprAlgorithm()
|
||||
{
|
||||
if (m_ownManifold)
|
||||
{
|
||||
if (m_manifoldPtr)
|
||||
m_dispatcher->releaseManifold(m_manifoldPtr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
btVector3 btBulletShapeSupportFunc(const void* shapeAptr, const btVector3& dir, bool includeMargin)
|
||||
{
|
||||
btConvexShape* shape = (btConvexShape*) shapeAptr;
|
||||
if (includeMargin)
|
||||
{
|
||||
return shape->localGetSupportingVertex(dir);
|
||||
}
|
||||
|
||||
return shape->localGetSupportingVertexWithoutMargin(dir);
|
||||
}
|
||||
|
||||
btVector3 btBulletShapeCenterFunc(const void* shapeAptr)
|
||||
{
|
||||
return btVector3(0,0,0);
|
||||
}
|
||||
|
||||
|
||||
struct btMprConvexWrap
|
||||
{
|
||||
const btConvexShape* m_convex;
|
||||
btTransform m_worldTrans;
|
||||
inline btScalar getMargin() const
|
||||
{
|
||||
return m_convex->getMargin();
|
||||
}
|
||||
inline btVector3 getObjectCenterInWorld() const
|
||||
{
|
||||
return m_worldTrans.getOrigin();
|
||||
}
|
||||
inline const btTransform& getWorldTransform() const
|
||||
{
|
||||
return m_worldTrans;
|
||||
}
|
||||
inline btVector3 getLocalSupportWithMargin(const btVector3& dir) const
|
||||
{
|
||||
return m_convex->localGetSupportingVertex(dir);
|
||||
}
|
||||
inline btVector3 getLocalSupportWithoutMargin(const btVector3& dir) const
|
||||
{
|
||||
return m_convex->localGetSupportingVertexWithoutMargin(dir);
|
||||
}
|
||||
};
|
||||
|
||||
struct btMyDistanceInfo
|
||||
{
|
||||
btVector3 m_pointOnA;
|
||||
btVector3 m_pointOnB;
|
||||
btVector3 m_normalBtoA;
|
||||
btScalar m_distance;
|
||||
};
|
||||
|
||||
//
|
||||
// Convex-Convex collision algorithm
|
||||
//
|
||||
void btConvexConvexMprAlgorithm ::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
|
||||
{
|
||||
|
||||
if (!m_manifoldPtr)
|
||||
{
|
||||
//swapped?
|
||||
m_manifoldPtr = m_dispatcher->getNewManifold(body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject());
|
||||
m_ownManifold = true;
|
||||
}
|
||||
resultOut->setPersistentManifold(m_manifoldPtr);
|
||||
|
||||
//comment-out next line to test multi-contact generation
|
||||
//resultOut->getPersistentManifold()->clearManifold();
|
||||
|
||||
|
||||
const btConvexShape* min0 = static_cast<const btConvexShape*>(body0Wrap->getCollisionShape());
|
||||
const btConvexShape* min1 = static_cast<const btConvexShape*>(body1Wrap->getCollisionShape());
|
||||
|
||||
btVector3 normalOnB;
|
||||
btVector3 pointOnBWorld;
|
||||
|
||||
btGjkPairDetector::ClosestPointInput input;
|
||||
|
||||
btVoronoiSimplexSolver vs;
|
||||
btGjkEpaPenetrationDepthSolver epa;
|
||||
|
||||
|
||||
if (gUseMprCollisionFunction)
|
||||
{
|
||||
|
||||
btMprConvexWrap a,b;
|
||||
a.m_worldTrans = body0Wrap->getWorldTransform();
|
||||
b.m_worldTrans = body1Wrap->getWorldTransform();
|
||||
a.m_convex = (const btConvexShape*)body0Wrap->getCollisionShape();
|
||||
b.m_convex = (const btConvexShape*)body1Wrap->getCollisionShape();
|
||||
btVoronoiSimplexSolver simplexSolver;
|
||||
simplexSolver.reset();
|
||||
btGjkCollisionDescription colDesc;
|
||||
btMyDistanceInfo distInfo;
|
||||
int res = btComputeGjkDistance(a,b,colDesc,&distInfo);
|
||||
if (res==0)
|
||||
{
|
||||
//printf("use GJK results in distance %f\n",distInfo.m_distance);
|
||||
} else
|
||||
{
|
||||
btMprCollisionDescription mprDesc;
|
||||
res = btComputeMprPenetration(a,b,mprDesc, &distInfo);
|
||||
|
||||
//printf("use MPR results in distance %f\n",distInfo.m_distance);
|
||||
|
||||
}
|
||||
if (res == 0)
|
||||
{
|
||||
#if 0
|
||||
printf("Dist=%f,normalOnB[%f,%f,%f],pA=[%f,%f,%f],pB[%f,%f,%f]\n",
|
||||
distInfo.m_distance, distInfo.m_normalBtoA[0], distInfo.m_normalBtoA[1], distInfo.m_normalBtoA[2],
|
||||
distInfo.m_pointOnA[0], distInfo.m_pointOnA[1], distInfo.m_pointOnA[2],
|
||||
distInfo.m_pointOnB[0], distInfo.m_pointOnB[1], distInfo.m_pointOnB[2]);
|
||||
#endif
|
||||
|
||||
if (distInfo.m_distance<=0)
|
||||
{
|
||||
resultOut->addContactPoint(distInfo.m_normalBtoA, distInfo.m_pointOnB, distInfo.m_distance);
|
||||
}
|
||||
//ASSERT_EQ(0,result);
|
||||
//ASSERT_NEAR(btFabs(btScalar(i-z))-btScalar(j)-ssd.m_radiusB, distInfo.m_distance, abs_error);
|
||||
//btVector3 computedA = distInfo.m_pointOnB+distInfo.m_distance*distInfo.m_normalBtoA;
|
||||
//ASSERT_NEAR(computedA.x(),distInfo.m_pointOnA.x(),abs_error);
|
||||
//ASSERT_NEAR(computedA.y(),distInfo.m_pointOnA.y(),abs_error);
|
||||
//ASSERT_NEAR(computedA.z(),distInfo.m_pointOnA.z(),abs_error);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
btCollisionDescription colDesc;
|
||||
colDesc.m_objA = min0;
|
||||
colDesc.m_objB = min1;
|
||||
colDesc.m_localSupportFuncA = &btBulletShapeSupportFunc;
|
||||
colDesc.m_localSupportFuncB = &btBulletShapeSupportFunc;
|
||||
colDesc.m_localOriginFuncA = &btBulletShapeCenterFunc;
|
||||
colDesc.m_localOriginFuncB = &btBulletShapeCenterFunc;
|
||||
|
||||
colDesc.m_transformA = body0Wrap->getWorldTransform();
|
||||
colDesc.m_transformB = body1Wrap->getWorldTransform();
|
||||
colDesc.m_marginA = body0Wrap->getCollisionShape()->getMargin();
|
||||
colDesc.m_marginB = body1Wrap->getCollisionShape()->getMargin();
|
||||
btDistanceInfo distInfo;
|
||||
//int result = btComputeGjkEpaPenetration(colDesc, &distInfo);
|
||||
//int result = btComputeGjkEpaPenetration2(colDesc, &distInfo);
|
||||
int result = btComputeMprPenetration(colDesc, &distInfo);
|
||||
|
||||
if (result==0)
|
||||
{
|
||||
resultOut->addContactPoint(distInfo.m_normalBtoA,distInfo.m_pointOnB,distInfo.m_distance);
|
||||
}
|
||||
|
||||
//bool res = b3MprPenetration(pairIndex,bodyIndexA,bodyIndexB,cpuBodyBuf,convexData,collidable2,cpuVertices,sepAxis,hasSepAxis,depthOut,dirOut,posOut);
|
||||
|
||||
/*btCollisionDescription colDesc;
|
||||
btDistanceInfo distInfo;
|
||||
int btComputeGjkEpaPenetration(min0, min1, &colDesc, &distInfo);
|
||||
*/
|
||||
#endif
|
||||
} else
|
||||
{
|
||||
|
||||
btGjkPairDetector gjkPairDetector(min0,min1,&vs,&epa);//m_simplexSolver,m_pdSolver);
|
||||
//TODO: if (dispatchInfo.m_useContinuous)
|
||||
gjkPairDetector.setMinkowskiA(min0);
|
||||
gjkPairDetector.setMinkowskiB(min1);
|
||||
|
||||
{
|
||||
//if (dispatchInfo.m_convexMaxDistanceUseCPT)
|
||||
//{
|
||||
// input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactProcessingThreshold();
|
||||
//} else
|
||||
//{
|
||||
input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold();
|
||||
// }
|
||||
|
||||
input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared;
|
||||
}
|
||||
|
||||
input.m_transformA = body0Wrap->getWorldTransform();
|
||||
input.m_transformB = body1Wrap->getWorldTransform();
|
||||
|
||||
|
||||
gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
|
||||
}
|
||||
if (m_ownManifold)
|
||||
{
|
||||
resultOut->refreshContactPoints();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
btScalar btConvexConvexMprAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
|
||||
{
|
||||
(void)resultOut;
|
||||
(void)dispatchInfo;
|
||||
btAssert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
87
examples/VoronoiFracture/btConvexConvexMprAlgorithm.h
Normal file
87
examples/VoronoiFracture/btConvexConvexMprAlgorithm.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
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 BT_CONVEX_CONVEX_MPR_ALGORITHM_H
|
||||
#define BT_CONVEX_CONVEX_MPR_ALGORITHM_H
|
||||
|
||||
#include "BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h"
|
||||
#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
|
||||
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
|
||||
#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
|
||||
#include "LinearMath/btTransformUtil.h" //for btConvexSeparatingDistanceUtil
|
||||
|
||||
class btConvexPenetrationDepthSolver;
|
||||
|
||||
///Enabling USE_SEPDISTANCE_UTIL2 requires 100% reliable distance computation. However, when using large size ratios GJK can be imprecise
|
||||
///so the distance is not conservative. In that case, enabling this USE_SEPDISTANCE_UTIL2 would result in failing/missing collisions.
|
||||
///Either improve GJK for large size ratios (testing a 100 units versus a 0.1 unit object) or only enable the util
|
||||
///for certain pairs that have a small size ratio
|
||||
|
||||
///The convexConvexAlgorithm collision algorithm implements time of impact, convex closest points and penetration depth calculations between two convex objects.
|
||||
///Multiple contact points are calculated by perturbing the orientation of the smallest object orthogonal to the separating normal.
|
||||
///This idea was described by Gino van den Bergen in this forum topic http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=4&t=288&p=888#p888
|
||||
class btConvexConvexMprAlgorithm : public btActivatingCollisionAlgorithm
|
||||
{
|
||||
|
||||
|
||||
bool m_ownManifold;
|
||||
btPersistentManifold* m_manifoldPtr;
|
||||
///cache separating vector to speedup collision detection
|
||||
|
||||
public:
|
||||
|
||||
btConvexConvexMprAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap);
|
||||
|
||||
virtual ~btConvexConvexMprAlgorithm();
|
||||
|
||||
virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
|
||||
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
|
||||
virtual void getAllContactManifolds(btManifoldArray& manifoldArray)
|
||||
{
|
||||
///should we use m_ownManifold to avoid adding duplicates?
|
||||
if (m_manifoldPtr && m_ownManifold)
|
||||
manifoldArray.push_back(m_manifoldPtr);
|
||||
}
|
||||
|
||||
const btPersistentManifold* getManifold()
|
||||
{
|
||||
return m_manifoldPtr;
|
||||
}
|
||||
|
||||
struct CreateFunc :public btCollisionAlgorithmCreateFunc
|
||||
{
|
||||
|
||||
|
||||
|
||||
CreateFunc();
|
||||
|
||||
virtual ~CreateFunc();
|
||||
|
||||
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
|
||||
{
|
||||
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConvexMprAlgorithm));
|
||||
return new(mem) btConvexConvexMprAlgorithm(ci.m_manifold,ci,body0Wrap,body1Wrap);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif //BT_CONVEX_CONVEX_MPR_ALGORITHM_H
|
||||
Reference in New Issue
Block a user