add initial examples, replacing the 'Demos/Demos3'. Will make it work cross-platform, OpenGL3/OpenGL2 and add more examples to it.

This commit is contained in:
erwincoumans
2015-04-16 09:55:32 -07:00
parent d9feaf2d2a
commit a1bf9c5556
425 changed files with 255913 additions and 0 deletions

View File

@@ -0,0 +1,131 @@
INCLUDE_DIRECTORIES(
${BULLET_PHYSICS_SOURCE_DIR}/src
${BULLET_PHYSICS_SOURCE_DIR}/btgui
${BULLET_PHYSICS_SOURCE_DIR}/btgui/lua-5.2.3/src
${BULLET_PHYSICS_SOURCE_DIR}/Demos3/FiniteElementMethod
)
SET(App_AllBullet2Demos_SRCS
main.cpp
BulletDemoEntries.h
../../Demos/BasicDemo/BasicDemoPhysicsSetup.cpp
../../Demos/BasicDemo/BasicDemoPhysicsSetup.h
../../Demos/CcdPhysicsDemo/CcdPhysicsSetup.cpp
../../Demos/CcdPhysicsDemo/CcdPhysicsSetup.h
../../Demos/Raytracer/RaytracerSetup.cpp
../../Demos/Raytracer/RaytracerSetup.h
../../Demos/GyroscopicDemo/GyroscopicSetup.cpp
../../Demos/GyroscopicDemo/GyroscopicSetup.h
../../Demos/ForkLiftDemo/ForkLiftPhysicsSetup.cpp
../../Demos/ForkLiftDemo/ForkLiftPhysicsSetup.h
../../Demos/SerializeDemo/SerializeSetup.cpp
../../Extras/Serialize/BulletFileLoader/bChunk.cpp
../../Extras/Serialize/BulletFileLoader/bDNA.cpp
../../Extras/Serialize/BulletFileLoader/bFile.cpp
../../Extras/Serialize/BulletFileLoader/btBulletFile.cpp
../../Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.cpp
../../Extras/Serialize/BulletWorldImporter/btWorldImporter.cpp
../bullet2/MultiBodyDemo/TestJointTorqueSetup.cpp
../bullet2/MultiBodyDemo/MultiBodyVehicle.cpp
../bullet2/ConstraintDemo/ConstraintPhysicsSetup.cpp
../bullet2/ConstraintDemo/ConstraintPhysicsSetup.h
../bullet2/ConstraintDemo/Dof6Spring2Setup.cpp
../bullet2/ConstraintDemo/Dof6Spring2Setup.h
../bullet2/CoordinateFrameDemo/CoordinateFrameDemoPhysicsSetup.cpp
../bullet2/CoordinateFrameDemo/CoordinateFrameDemoPhysicsSetup.h
../bullet2/FeatherstoneMultiBodyDemo/BulletMultiBodyDemos.cpp
../bullet2/FeatherstoneMultiBodyDemo/BulletMultiBodyDemos.h
../bullet2/FeatherstoneMultiBodyDemo/MultiDofDemo.cpp
../bullet2/FeatherstoneMultiBodyDemo/MultiDofDemo.h
../bullet2/BasicDemo/BasicDemo.cpp
../bullet2/BasicDemo/BasicDemo.h
# ../bullet2/SoftDemo/SoftDemo.cpp
# the next few demos are not converted to 'newer' structure yet
# target is to convert all Bullet 2 demos in new structure but need to settle down on features
# ../bullet2/BasicDemo/HingeDemo.cpp
# ../bullet2/BasicDemo/HingeDemo.h
# ../bullet2/ChainDemo/ChainDemo.cpp
# ../bullet2/ChainDemo/ChainDemo.h
# ../bullet2/RagdollDemo/RagdollDemo.cpp
# ../bullet2/RagdollDemo/RagdollDemo.h
../bullet2/LuaDemo/LuaPhysicsSetup.cpp
../bullet2/LuaDemo/LuaPhysicsSetup.h
../ImportURDFDemo/URDF2Bullet.cpp
../ImportURDFDemo/ImportURDFSetup.cpp
../ImportURDFDemo/ImportURDFSetup.h
../ImportObjDemo/ImportObjSetup.cpp
../ImportObjDemo/LoadMeshFromObj.cpp
../ImportObjDemo/LoadMeshFromObj.h
../ImportObjDemo/Wavefront2GLInstanceGraphicsShape.cpp
../ImportColladaDemo/ImportColladaSetup.cpp
../ImportColladaDemo/LoadMeshFromCollada.cpp
../ImportSTLDemo/ImportSTLSetup.cpp
../Wavefront/tiny_obj_loader.cpp
../Wavefront/tiny_obj_loader.h
../FiniteElementMethod/FiniteElementDemo.cpp
../../btgui/Bullet3AppSupport/b3Clock.cpp
../../btgui/Bullet3AppSupport/b3Clock.h
../../btgui/urdf/urdfdom/urdf_parser/src/pose.cpp
../../btgui/urdf/urdfdom/urdf_parser/src/model.cpp
../../btgui/urdf/urdfdom/urdf_parser/src/link.cpp
../../btgui/urdf/urdfdom/urdf_parser/src/joint.cpp
../../btgui/urdf/urdfdom/urdf_parser/include/urdf_parser/urdf_parser.h
../../btgui/urdf/urdfdom_headers/urdf_exception/include/urdf_exception/exception.h
../../btgui/urdf/urdfdom_headers/urdf_model/include/urdf_model/pose.h
../../btgui/urdf/urdfdom_headers/urdf_model/include/urdf_model/model.h
../../btgui/urdf/urdfdom_headers/urdf_model/include/urdf_model/link.h
../../btgui/urdf/urdfdom_headers/urdf_model/include/urdf_model/joint.h
../../btgui/tinyxml/tinystr.cpp
../../btgui/tinyxml/tinyxml.cpp
../../btgui/tinyxml/tinyxmlerror.cpp
../../btgui/tinyxml/tinyxmlparser.cpp
../../btgui/urdf/boost_replacement/lexical_cast.h
../../btgui/urdf/boost_replacement/shared_ptr.h
../../btgui/urdf/boost_replacement/printf_console.cpp
../../btgui/urdf/boost_replacement/printf_console.h
../../btgui/urdf/boost_replacement/string_split.cpp
../../btgui/urdf/boost_replacement/string_split.h
${BULLET_PHYSICS_SOURCE_DIR}/build3/bullet.rc
)
LINK_LIBRARIES(
Bullet3AppSupport lua-5.2.3 Bullet3Common BulletSoftBody BulletDynamics BulletCollision LinearMath OpenGLWindow gwen ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}
)
IF (WIN32)
SET(App_AllBullet2Demos_SRCS ${App_AllBullet2Demos_SRCS} ${App_AllBullet2Demos_Common_SRCS})
INCLUDE_DIRECTORIES(
${BULLET_PHYSICS_SOURCE_DIR}/btgui/OpenGLWindow/GlewWindows
)
ADD_DEFINITIONS(-DGLEW_STATIC)
ELSE(WIN32)
IF(APPLE)
find_library(COCOA NAMES Cocoa)
MESSAGE(${COCOA})
link_libraries(${COCOA})
ELSE(APPLE)
ADD_DEFINITIONS("-DGLEW_INIT_OPENGL11_FUNCTIONS=1")
ADD_DEFINITIONS("-DGLEW_STATIC")
ADD_DEFINITIONS("-DGLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS=1")
INCLUDE_DIRECTORIES(
${BULLET_PHYSICS_SOURCE_DIR}/btgui/OpenGLWindow/GlewWindows
)
LINK_LIBRARIES( pthread dl)
ENDIF(APPLE)
ENDIF(WIN32)
ADD_EXECUTABLE(App_AllBullet2Demos
${App_AllBullet2Demos_SRCS}
)
IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES)
SET_TARGET_PROPERTIES(App_AllBullet2Demos PROPERTIES DEBUG_POSTFIX "_Debug")
SET_TARGET_PROPERTIES(App_AllBullet2Demos PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel")
SET_TARGET_PROPERTIES(App_AllBullet2Demos PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo")
ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES)

View File

@@ -0,0 +1,38 @@
#ifndef EMPTY_BROWSER
#define EMPTY_BROWSER
#include "ExampleBrowserInterface.h"
#include "EmptyExample.h"
class EmptyBrowser : public ExampleBrowserInterface
{
public:
EmptyExample m_emptyExample;
virtual ExampleInterface* getCurrentExample()
{
return &m_emptyExample;
}
EmptyBrowser(class ExampleEntries* examples)
{
}
virtual bool init(int /*argc*/, char* argv[])
{
return true;
}
virtual void update(float deltaTime)
{
m_emptyExample.stepSimulation(deltaTime);
}
virtual bool requestedExit()
{
return false;
}
};
#endif //EMPTY_BROWSER

View File

@@ -0,0 +1,32 @@
#ifndef EMPTY_EXAMPLE_H
#define EMPTY_EXAMPLE_H
#include "../CommonInterfaces/ExampleInterface.h"
class EmptyExample : public ExampleInterface
{
public:
EmptyExample() {}
virtual ~EmptyExample(){}
static ExampleInterface* CreateFunc(struct PhysicsInterface* pint, struct GUIHelperInterface* helper, int option)
{
return new EmptyExample;
}
virtual void initPhysics(){}
virtual void exitPhysics(){}
virtual void stepSimulation(float deltaTime){}
virtual void renderScene(){}
virtual void physicsDebugDraw(int debugFlags){}
virtual bool mouseMoveCallback(float x,float y){ return false;}
virtual bool mouseButtonCallback(int button, int state, float x, float y){return false;}
virtual bool keyboardCallback(int key, int state){return false;}
};
#endif //EMPTY_EXAMPLE_H

View File

@@ -0,0 +1,23 @@
#ifndef EXAMPLE_BROWSER_GUI_H
#define EXAMPLE_BROWSER_GUI_H
#include "../CommonInterfaces/ExampleInterface.h"
class ExampleBrowserInterface
{
public:
virtual ~ExampleBrowserInterface() {}
virtual ExampleInterface* getCurrentExample() = 0;
virtual bool init(int argc, char* argv[])=0;
virtual void update(float deltaTime)=0;
virtual bool requestedExit()=0;
};
#endif //EXAMPLE_BROWSER_GUI_H

View File

@@ -0,0 +1,136 @@
#include "ExampleEntries.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "EmptyExample.h"
#include "../RenderingExamples/RenderInstancingDemo.h"
#include "../RenderingExamples/CoordinateSystemDemo.h"
#include "../RenderingExamples/RaytracerSetup.h"
#include "../ForkLift/ForkLiftDemo.h"
#include "../BasicDemo/BasicExample.h"
#include "../Planar2D/Planar2D.h"
#include "../Benchmarks/BenchmarkDemo.h"
#include "../Importers/ImportObjDemo/ImportObjExample.h"
#include "../Importers/ImportBsp/ImportBspExample.h"
#include "../Importers/ImportColladaDemo/ImportColladaSetup.h"
#include "../Importers/ImportSTLDemo/ImportSTLSetup.h"
#include "../Importers/ImportURDFDemo/ImportURDFSetup.h"
#include "../GyroscopicDemo/GyroscopicSetup.h"
struct ExampleEntry
{
int m_menuLevel;
const char* m_name;
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)
{
}
};
static ExampleEntry gDefaultExamples[]=
{
ExampleEntry(0,"Rendering",0),
ExampleEntry(1,"Instanced Rendering", RenderInstancingCreateFunc),
ExampleEntry(1,"CoordinateSystemDemo",CoordinateSystemCreateFunc),
ExampleEntry(1,"Raytracer",RayTracerCreateFunc),
ExampleEntry(0,"API",0),
ExampleEntry(1,"Basic Example",BasicExampleCreateFunc),
ExampleEntry(1,"Gyroscopic", GyroscopicCreateFunc),
ExampleEntry(1,"Planar 2D",Planar2DCreateFunc),
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,"7", BenchmarkCreateFunc, 7),
ExampleEntry(0,"Importers", 0),
ExampleEntry(1,"Wavefront Obj", 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(0,"Vehicles",0),
ExampleEntry(1,"ForkLift",ForkLiftCreateFunc),
};
static btAlignedObjectArray<ExampleEntry> gAdditionalRegisteredExamples;
struct ExampleEntriesInternalData
{
btAlignedObjectArray<ExampleEntry> m_allExamples;
};
ExampleEntries::ExampleEntries()
{
m_data = new ExampleEntriesInternalData;
}
ExampleEntries::~ExampleEntries()
{
delete m_data;
}
void ExampleEntries::initExampleEntries()
{
m_data->m_allExamples.clear();
{
ExampleEntry e(0,"Basic Concepts", 0);
m_data->m_allExamples.push_back(e);
}
{
ExampleEntry e(1,"Empty",EmptyExample::CreateFunc);
m_data->m_allExamples.push_back(e);
}
int numDefaultEntries = sizeof(gDefaultExamples)/sizeof(ExampleEntry);
for (int i=0;i<numDefaultEntries;i++)
{
m_data->m_allExamples.push_back(gDefaultExamples[i]);
}
}
void ExampleEntries::registerExampleEntry(int menuLevel, const char* name,ExampleInterface::CreateFunc* createFunc, int option)
{
ExampleEntry e( menuLevel,name,createFunc, option);
gAdditionalRegisteredExamples.push_back(e);
}
int ExampleEntries::getNumRegisteredExamples()
{
return m_data->m_allExamples.size();
}
ExampleInterface::CreateFunc* ExampleEntries::getExampleCreateFunc(int index)
{
return m_data->m_allExamples[index].m_createFunc;
}
int ExampleEntries::getExampleOption(int index)
{
return m_data->m_allExamples[index].m_option;
}
const char* ExampleEntries::getExampleName(int index)
{
return m_data->m_allExamples[index].m_name;
}

View File

@@ -0,0 +1,36 @@
#ifndef EXAMPLE_ENTRIES_H
#define EXAMPLE_ENTRIES_H
#include "../CommonInterfaces/ExampleInterface.h"
class ExampleEntries
{
struct ExampleEntriesInternalData* m_data;
public:
ExampleEntries();
virtual ~ExampleEntries();
static void registerExampleEntry(int menuLevel, const char* name,ExampleInterface::CreateFunc* createFunc, int option=0);
void initExampleEntries();
int getNumRegisteredExamples();
ExampleInterface::CreateFunc* getExampleCreateFunc(int index);
const char* getExampleName(int index);
int getExampleOption(int index);
};
#endif //EXAMPLE_ENTRIES_H

View File

@@ -0,0 +1,2 @@
#include "GUIHelperInterface.h"

View File

@@ -0,0 +1,75 @@
#ifndef GUI_HELPER_INTERFACE_H
#define GUI_HELPER_INTERFACE_H
class btRigidBody;
class btVector3;
class btCollisionObject;
class btDiscreteDynamicsWorld;
class btCollisionShape;
///The Bullet 2 GraphicsPhysicsBridge let's the graphics engine create graphics representation and synchronize
struct GUIHelperInterface
{
virtual ~GUIHelperInterface() {}
virtual void createRigidBodyGraphicsObject(btRigidBody* body,const btVector3& color)
{
}
virtual void createCollisionObjectGraphicsObject(btCollisionObject* obj,const btVector3& color)
{
}
virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape)
{
}
virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld)
{
}
virtual void createPhysicsDebugDrawer( btDiscreteDynamicsWorld* rbWorld)
{
}
virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices) { return -1; }//, int primitiveType = B3_GL_TRIANGLES, int textureIndex = -1);
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) { return -1;}
virtual struct Common2dCanvasInterface* get2dCanvasInterface()
{
return 0;
}
virtual struct CommonParameterInterface* getParameterInterface()
{
return 0;
}
virtual struct CommonRenderInterface* getRenderInterface()
{
return 0;
}
virtual struct CommonGraphicsApp* getAppInterface()
{
return 0;
}
virtual void setUpAxis(int axis)
{
}
virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld)
{
}
virtual void drawText3D( const char* txt, float posX, float posZY, float posZ, float size)
{
}
};
#endif //GUI_HELPER_INTERFACE_H

View File

@@ -0,0 +1,189 @@
#include "GraphingTexture.h"
#include "../OpenGLWindow/OpenGLInclude.h"
#include <assert.h>
GraphingTexture::GraphingTexture()
:m_textureId(0),
m_width(0),
m_height(0)
{
}
GraphingTexture::~GraphingTexture()
{
destroy();
}
void GraphingTexture::destroy()
{
//TODO(erwincoumans) release memory etc...
m_width = 0;
m_height=0;
glDeleteTextures(1,(GLuint*)&m_textureId);
m_textureId=0;
}
bool GraphingTexture::create(int texWidth, int texHeight)
{
m_width = texWidth;
m_height = texHeight;
glActiveTexture(GL_TEXTURE0);
m_imageData.resize(texWidth*texHeight*4);
for(int y=0;y<texHeight;++y)
{
// const int t=y>>5;
GLubyte* pi=&m_imageData[y*texWidth*4];
for(int x=0;x<texWidth;++x)
{
if (x>=y)//x<2||y<2||x>253||y>253)
{
pi[0]=0;
pi[1]=0;
pi[2]=255;
pi[3]=255;
} else
{
pi[0]=255;
pi[1]=0;
pi[2]=0;
pi[3]=255;
}
pi+=4;
}
}
glGenTextures(1,(GLuint*)&m_textureId);
uploadImageData();
return true;
}
void GraphingTexture::uploadImageData()
{
glBindTexture(GL_TEXTURE_2D,m_textureId);
assert(glGetError()==GL_NO_ERROR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width,m_height,0,GL_RGBA,GL_UNSIGNED_BYTE,&m_imageData[0]);
glGenerateMipmap(GL_TEXTURE_2D);
assert(glGetError()==GL_NO_ERROR);
}
#if 0
//shift the image one pixel
for(int y=0;y<texHeight;++y)
{
// const int t=y>>5;
for(int x=1;x<texWidth;++x)
{
GLubyte* org=image+(x+y*texWidth)*4;
GLubyte* dst=image+(x-1+y*texWidth)*4;
dst[0] = org[0];
dst[1] = org[1];
dst[2] = org[2];
dst[3] = org[3];
}
}
//render a new row at the right
for(int y=0;y<texHeight;++y)
{
GLubyte* pi=image+(texWidth-1+y*texWidth)*4;
pi[0]=255;
pi[1]=255;
pi[2]=255;
pi[3]=255;
if (y==texHeight*0.5)
{
pi[0]=200;
pi[1]=200;
pi[2]=200;
pi[3]=255;
}
}
{
static float timer = 0.f;
static int prevValue=0;
timer+= 0.01;
float value = 128+100*sinf(timer);
MyClamp(value,0.f,float(texHeight-1));
GLubyte* org=image+(texWidth-1+(int)value*texWidth)*4;
org[0] = 0;
org[1] = 0;
org[2] = 0;
org[3] = 255;
if (prevValue<value)
{
} else
{
}
}
{
static float timer = 1.4f;
timer+= 0.04;
float value = 128+150*sinf(timer);
MyClamp(value,0.f,float(texHeight-1));
GLubyte* org=image+(texWidth-1+(int)value*texWidth)*4;
org[0] = 0;
org[1] = 255;
org[2] = 0;
org[3] = 255;
}
{
static float timer = 1.4f;
timer+= 0.02;
float value =256+400*sinf(timer);
MyClamp(value,0.f,float(texHeight-1));
static int prevValue = 0;
GLubyte* org=image+(texWidth-1+(int)value*texWidth)*4;
org[0] = 0;
org[1] = 0;
org[2] = 255;
org[3] = 255;
if (prevValue<value)
{
for (int i=prevValue;i<value;i++)
{
GLubyte* org=image+(texHeight-1+(int)i*texWidth)*4;
org[0] = 0;
org[1] = 0;
org[2] = 255;
org[3] = 255;
}
} else
{
for (int i=value;i<prevValue;i++)
{
GLubyte* org=image+(texHeight-1+(int)i*texWidth)*4;
org[0] = 0;
org[1] = 0;
org[2] = 255;
org[3] = 255;
}
}
prevValue = value;
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth,texHeight,0,GL_RGBA,GL_UNSIGNED_BYTE,image);
glGenerateMipmap(GL_TEXTURE_2D);
#endif

View File

@@ -0,0 +1,36 @@
#ifndef GRAPHING_TEXTURE_H
#define GRAPHING_TEXTURE_H
#include "LinearMath/btAlignedObjectArray.h"
struct GraphingTexture
{
int m_textureId;
//assume rgba (8 bit per component, total of 32bit per pixel, for m_width*m_height pixels)
btAlignedObjectArray<unsigned char> m_imageData;
int m_width;
int m_height;
GraphingTexture();
virtual ~GraphingTexture();
bool create(int texWidth, int texHeight);
void destroy();
void setPixel(int x, int y, unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha)
{
m_imageData[x*4+y*4*m_width+0] = red;
m_imageData[x*4+y*4*m_width+1] = green;
m_imageData[x*4+y*4*m_width+2] = blue;
m_imageData[x*4+y*4*m_width+3] = alpha;
}
void uploadImageData();
int getTextureId()
{
return m_textureId;
}
};
#endif //GRAPHING_TEXTURE_H

View File

@@ -0,0 +1,167 @@
#include "GwenParameterInterface.h"
#include "gwenInternalData.h"
template<typename T>
struct MySliderEventHandler : public Gwen::Event::Handler
{
Gwen::Controls::TextBox* m_label;
Gwen::Controls::Slider* m_pSlider;
char m_variableName[1024];
T* m_targetValue;
bool m_showValue;
MySliderEventHandler(const char* varName, Gwen::Controls::TextBox* label, Gwen::Controls::Slider* pSlider,T* target)
:m_label(label),
m_pSlider(pSlider),
m_targetValue(target),
m_showValue(true)
{
memcpy(m_variableName,varName,strlen(varName)+1);
}
void SliderMoved( Gwen::Controls::Base* pControl )
{
Gwen::Controls::Slider* pSlider = (Gwen::Controls::Slider*)pControl;
//printf("value = %f\n", pSlider->GetValue());//UnitPrint( Utility::Format( L"Slider Value: %.2f", pSlider->GetValue() ) );
float bla = pSlider->GetValue();
T v = T(bla);
SetValue(v);
}
void SetValue(T v)
{
if (v < m_pSlider->GetRangeMin())
{
printf("?\n");
}
if (v > m_pSlider->GetRangeMax())
{
printf("?\n");
}
m_pSlider->SetValue(v,true);
(*m_targetValue) = v;
float val = float(v);//todo: specialize on template type
if (m_showValue)
{
char txt[1024];
sprintf(txt,"%s : %.3f", m_variableName,val);
m_label->SetText(txt);
}
}
};
struct GwenParameters
{
b3AlignedObjectArray<MySliderEventHandler<btScalar>*> m_sliderEventHandlers;
b3AlignedObjectArray<Gwen::Controls::HorizontalSlider*> m_sliders;
b3AlignedObjectArray<Gwen::Controls::TextBox*> m_textLabels;
int m_savedYposition;
};
GwenParameterInterface::GwenParameterInterface(GwenInternalData* gwenInternalData)
:m_gwenInternalData(gwenInternalData)
{
m_paramInternalData = new GwenParameters;
m_paramInternalData->m_savedYposition = m_gwenInternalData->m_curYposition;
}
GwenParameterInterface::~GwenParameterInterface()
{
removeAllParameters();
delete m_paramInternalData;
}
void GwenParameterInterface::setSliderValue(int sliderIndex, double sliderValue)
{
int sliderCapped = sliderValue+4;
sliderCapped /= 8;
sliderCapped *= 8;
if (sliderIndex>=0 && sliderIndex<m_paramInternalData->m_sliders.size())
{
m_paramInternalData->m_sliders[sliderIndex]->GetRangeMin();
m_paramInternalData->m_sliders[sliderIndex]->GetRangeMax();
float mappedValue =m_paramInternalData->m_sliders[sliderIndex]->GetRangeMin()+
(m_paramInternalData->m_sliders[sliderIndex]->GetRangeMax()-
m_paramInternalData->m_sliders[sliderIndex]->GetRangeMin())*sliderCapped/128.f;
printf("mappedValue = %f\n",mappedValue);
m_paramInternalData->m_sliders[sliderIndex]->SetValue(mappedValue);
}
}
#include <stdio.h>
void GwenParameterInterface::registerSliderFloatParameter(SliderParams& params)
{
Gwen::Controls::TextBox* label = new Gwen::Controls::TextBox(m_gwenInternalData->m_demoPage->GetPage());
m_paramInternalData->m_textLabels.push_back(label);
//m_data->m_myControls.push_back(label);
label->SetText( params.m_name);
label->SetPos( 10, 10 + 25 );
label->SetWidth(110);
label->SetPos(10,m_gwenInternalData->m_curYposition);
m_gwenInternalData->m_curYposition+=22;
Gwen::Controls::HorizontalSlider* pSlider = new Gwen::Controls::HorizontalSlider( m_gwenInternalData->m_demoPage->GetPage());
m_paramInternalData->m_sliders.push_back(pSlider);
//m_data->m_myControls.push_back(pSlider);
pSlider->SetPos( 10, m_gwenInternalData->m_curYposition );
pSlider->SetSize( 100, 20 );
pSlider->SetRange( params.m_minVal, params.m_maxVal);
pSlider->SetNotchCount(128);//float(params.m_maxVal-params.m_minVal)/100.f);
pSlider->SetClampToNotches( params.m_clampToNotches );
pSlider->SetValue( *params.m_paramValuePointer);//dimensions[i] );
char labelName[1024];
sprintf(labelName,"%s",params.m_name);//axisNames[0]);
MySliderEventHandler<btScalar>* handler = new MySliderEventHandler<btScalar>(labelName,label,pSlider,params.m_paramValuePointer);
handler->m_showValue = params.m_showValues;
m_paramInternalData->m_sliderEventHandlers.push_back(handler);
pSlider->onValueChanged.Add( handler, &MySliderEventHandler<btScalar>::SliderMoved );
handler->SliderMoved(pSlider);
// float v = pSlider->GetValue();
m_gwenInternalData->m_curYposition+=22;
}
void GwenParameterInterface::syncParameters()
{
for (int i=0;i<m_paramInternalData->m_sliderEventHandlers.size();i++)
{
MySliderEventHandler<btScalar>* handler = m_paramInternalData->m_sliderEventHandlers[i];
handler->m_pSlider->SetValue(*handler->m_targetValue,true);
}
}
void GwenParameterInterface::removeAllParameters()
{
for (int i=0;i<m_paramInternalData->m_sliders.size();i++)
{
delete m_paramInternalData->m_sliders[i];
}
m_paramInternalData->m_sliders.clear();
for (int i=0;i<m_paramInternalData->m_sliderEventHandlers.size();i++)
{
delete m_paramInternalData->m_sliderEventHandlers[i];
}
m_paramInternalData->m_sliderEventHandlers.clear();
for (int i=0;i<m_paramInternalData->m_textLabels.size();i++)
{
delete m_paramInternalData->m_textLabels[i];
}
m_paramInternalData->m_textLabels.clear();
m_gwenInternalData->m_curYposition = this->m_paramInternalData->m_savedYposition;
}

View File

@@ -0,0 +1,21 @@
#ifndef GWEN_PARAMETER_INTERFACE_H
#define GWEN_PARAMETER_INTERFACE_H
#include "../CommonInterfaces/CommonParameterInterface.h"
struct GwenParameterInterface : public CommonParameterInterface
{
struct GwenInternalData* m_gwenInternalData;
struct GwenParameters* m_paramInternalData;
GwenParameterInterface(struct GwenInternalData* gwenInternalData);
virtual ~GwenParameterInterface();
virtual void registerSliderFloatParameter(SliderParams& params);
virtual void setSliderValue(int sliderIndex, double sliderValue);
virtual void syncParameters();
virtual void removeAllParameters();
};
#endif//GWEN_PARAMETER_INTERFACE_H

View File

@@ -0,0 +1,292 @@
#include "GwenProfileWindow.h"
#include "gwenUserInterface.h"
#include "gwenInternalData.h"
#include "LinearMath/btQuickprof.h"
class MyProfileWindow : public Gwen::Controls::WindowControl
{
// Gwen::Controls::TabControl* m_TabControl;
//Gwen::Controls::ListBox* m_TextOutput;
unsigned int m_iFrames;
float m_fLastSecond;
Gwen::Controls::TreeNode* m_node;
Gwen::Controls::TreeControl* m_ctrl;
protected:
void onButtonA( Gwen::Controls::Base* pControl )
{
// OpenTissue::glut::toggleIdle();
}
void SliderMoved(Gwen::Controls::Base* pControl )
{
// Gwen::Controls::Slider* pSlider = (Gwen::Controls::Slider*)pControl;
//this->m_app->scaleYoungModulus(pSlider->GetValue());
// printf("Slider Value: %.2f", pSlider->GetValue() );
}
void OnCheckChangedStiffnessWarping (Gwen::Controls::Base* pControl)
{
// Gwen::Controls::CheckBox* labeled = (Gwen::Controls::CheckBox* )pControl;
// bool checked = labeled->IsChecked();
//m_app->m_stiffness_warp_on = checked;
}
public:
CProfileIterator* profIter;
MyProfileWindow ( Gwen::Controls::Base* pParent)
: Gwen::Controls::WindowControl( pParent ),
profIter(0)
{
SetTitle( L"Time Profiler" );
SetSize( 450, 450 );
this->SetPos(10,400);
// this->Dock( Gwen::Pos::Bottom);
{
m_ctrl = new Gwen::Controls::TreeControl( this );
m_node = m_ctrl->AddNode( L"Total Parent Time" );
//Gwen::Controls::TreeNode* pNode = ctrl->AddNode( L"Node Two" );
//pNode->AddNode( L"Node Two Inside" );
//pNode->AddNode( L"Eyes" );
//pNode->AddNode( L"Brown" )->AddNode( L"Node Two Inside" )->AddNode( L"Eyes" )->AddNode( L"Brown" );
//Gwen::Controls::TreeNode* node = ctrl->AddNode( L"Node Three" );
//m_ctrl->Dock(Gwen::Pos::Bottom);
m_ctrl->ExpandAll();
m_ctrl->SetKeyboardInputEnabled(true);
m_ctrl->SetBounds( this->GetInnerBounds().x,this->GetInnerBounds().y,this->GetInnerBounds().w,this->GetInnerBounds().h);
}
}
float dumpRecursive(CProfileIterator* profileIterator, Gwen::Controls::TreeNode* parentNode)
{
profileIterator->First();
if (profileIterator->Is_Done())
return 0.f;
float accumulated_time=0,parent_time = profileIterator->Is_Root() ? CProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time();
int i;
int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset();
//printf("Profiling: %s (total running time: %.3f ms) ---\n", profileIterator->Get_Current_Parent_Name(), parent_time );
float totalTime = 0.f;
int numChildren = 0;
Gwen::UnicodeString txt;
std::vector<Gwen::Controls::TreeNode*> nodes;
for (i = 0; !profileIterator->Is_Done(); i++,profileIterator->Next())
{
numChildren++;
float current_total_time = profileIterator->Get_Current_Total_Time();
accumulated_time += current_total_time;
double fraction = parent_time > SIMD_EPSILON ? (current_total_time / parent_time) * 100 : 0.f;
Gwen::String name(profileIterator->Get_Current_Name());
#ifdef _WIN32
Gwen::UnicodeString uname = Gwen::Utility::StringToUnicode(name);
txt = Gwen::Utility::Format(L"%s (%.2f %%) :: %.3f ms / frame (%d calls)",uname.c_str(), fraction,(current_total_time / (double)frames_since_reset),profileIterator->Get_Current_Total_Calls());
#else
txt = Gwen::Utility::Format(L"%s (%.2f %%) :: %.3f ms / frame (%d calls)",name.c_str(), fraction,(current_total_time / (double)frames_since_reset),profileIterator->Get_Current_Total_Calls());
#endif
Gwen::Controls::TreeNode* childNode = (Gwen::Controls::TreeNode*)profileIterator->Get_Current_UserPointer();
if (!childNode)
{
childNode = parentNode->AddNode(L"");
profileIterator->Set_Current_UserPointer(childNode);
}
childNode->SetText(txt);
nodes.push_back(childNode);
totalTime += current_total_time;
//recurse into children
}
for (i=0;i<numChildren;i++)
{
profileIterator->Enter_Child(i);
Gwen::Controls::TreeNode* curNode = nodes[i];
dumpRecursive(profileIterator, curNode);
profileIterator->Enter_Parent();
}
return accumulated_time;
}
void UpdateText(CProfileIterator* profileIterator, bool idle)
{
// static bool update=true;
m_ctrl->SetBounds(0,0,this->GetInnerBounds().w,this->GetInnerBounds().h);
// if (!update)
// return;
// update=false;
static int test = 1;
test++;
static double time_since_reset = 0.f;
if (!idle)
{
time_since_reset = CProfileManager::Get_Time_Since_Reset();
}
//Gwen::UnicodeString txt = Gwen::Utility::Format( L"FEM Settings %i fps", test );
{
//recompute profiling data, and store profile strings
// char blockTime[128];
// double totalTime = 0;
// int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset();
profileIterator->First();
double parent_time = profileIterator->Is_Root() ? time_since_reset : profileIterator->Get_Current_Parent_Total_Time();
// Gwen::Controls::TreeNode* curParent = m_node;
double accumulated_time = dumpRecursive(profileIterator,m_node);
const char* name = profileIterator->Get_Current_Parent_Name();
#ifdef _WIN32
Gwen::UnicodeString uname = Gwen::Utility::StringToUnicode(name);
Gwen::UnicodeString txt = Gwen::Utility::Format( L"Profiling: %s total time: %.3f ms, unaccounted %.3f %% :: %.3f ms", uname.c_str(), parent_time ,
parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time);
#else
Gwen::UnicodeString txt = Gwen::Utility::Format( L"Profiling: %s total time: %.3f ms, unaccounted %.3f %% :: %.3f ms", name, parent_time ,
parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time);
#endif
//sprintf(blockTime,"--- Profiling: %s (total running time: %.3f ms) ---", profileIterator->Get_Current_Parent_Name(), parent_time );
//displayProfileString(xOffset,yStart,blockTime);
m_node->SetText(txt);
//printf("%s (%.3f %%) :: %.3f ms\n", "Unaccounted:",);
}
static int counter=10;
if (counter)
{
counter--;
m_ctrl->ExpandAll();
}
}
void PrintText( const Gwen::UnicodeString& str )
{
}
void Render( Gwen::Skin::Base* skin )
{
m_iFrames++;
if ( m_fLastSecond < Gwen::Platform::GetTimeInSeconds() )
{
SetTitle( Gwen::Utility::Format( L"Profiler %i fps", m_iFrames ) );
m_fLastSecond = Gwen::Platform::GetTimeInSeconds() + 1.0f;
m_iFrames = 0;
}
Gwen::Controls::WindowControl::Render( skin );
}
};
class MyMenuItems : public Gwen::Controls::Base
{
public:
class MyProfileWindow* m_profWindow;
MyMenuItems() :Gwen::Controls::Base(0)
{
}
void MenuItemSelect(Gwen::Controls::Base* pControl)
{
if (m_profWindow->Hidden())
{
m_profWindow->SetHidden(false);
} else
{
m_profWindow->SetHidden(true);
}
}
};
MyProfileWindow* setupProfileWindow(GwenInternalData* data)
{
MyMenuItems* menuItems = new MyMenuItems;
MyProfileWindow* profWindow = new MyProfileWindow(data->pCanvas);
//profWindow->SetHidden(true);
profWindow->profIter = CProfileManager::Get_Iterator();
data->m_viewMenu->GetMenu()->AddItem( L"Profiler", menuItems,(Gwen::Event::Handler::Function)&MyMenuItems::MenuItemSelect);
menuItems->m_profWindow = profWindow;
return profWindow;
}
void processProfileData( MyProfileWindow* profWindow, bool idle)
{
if (profWindow)
{
profWindow->UpdateText(profWindow->profIter, idle);
}
}
void profileWindowSetVisible(MyProfileWindow* window, bool visible)
{
window->SetHidden(!visible);
}
void destroyProfileWindow(MyProfileWindow* window)
{
delete window;
}

View File

@@ -0,0 +1,11 @@
#ifndef GWEN_PROFILE_WINDOW_H
#define GWEN_PROFILE_WINDOW_H
class MyProfileWindow* setupProfileWindow(struct GwenInternalData* data);
void processProfileData(MyProfileWindow* window, bool idle);
void profileWindowSetVisible(MyProfileWindow* window, bool visible);
void destroyProfileWindow(MyProfileWindow* window);
#endif//GWEN_PROFILE_WINDOW_H

View File

@@ -0,0 +1,100 @@
#include "GwenTextureWindow.h"
#include "gwenUserInterface.h"
#include "gwenInternalData.h"
#include "Gwen/Controls/ImagePanel.h"
class MyGraphWindow : public Gwen::Controls::WindowControl
{
Gwen::Controls::ImagePanel* m_imgPanel;
public:
class MyMenuItems2* m_menuItems;
MyGraphWindow ( const MyGraphInput& input)
: Gwen::Controls::WindowControl( input.m_data->pCanvas ),
m_menuItems(0)
{
Gwen::UnicodeString str = Gwen::Utility::StringToUnicode(input.m_name);
SetTitle( str );
SetPos(input.m_xPos,input.m_yPos);
SetSize( 12+input.m_width+2*input.m_borderWidth, 30+input.m_height+2*input.m_borderWidth );
m_imgPanel = new Gwen::Controls::ImagePanel( this );
if (input.m_texName)
{
Gwen::UnicodeString texName = Gwen::Utility::StringToUnicode(input.m_texName);
m_imgPanel->SetImage( texName );
}
m_imgPanel->SetBounds( input.m_borderWidth, input.m_borderWidth,
input.m_width,
input.m_height );
// this->Dock( Gwen::Pos::Bottom);
}
virtual ~MyGraphWindow()
{
delete m_imgPanel;
}
};
class MyMenuItems2 : public Gwen::Controls::Base
{
MyGraphWindow* m_graphWindow;
public:
Gwen::Controls::MenuItem* m_item;
MyMenuItems2(MyGraphWindow* graphWindow)
:Gwen::Controls::Base(0),
m_graphWindow(graphWindow),
m_item(0)
{
}
void MenuItemSelect(Gwen::Controls::Base* pControl)
{
if (m_graphWindow->Hidden())
{
m_graphWindow->SetHidden(false);
//@TODO(erwincoumans) setCheck/SetCheckable drawing is broken, need to see what's wrong
// if (m_item)
// m_item->SetCheck(false);
} else
{
m_graphWindow->SetHidden(true);
// if (m_item)
// m_item->SetCheck(true);
}
}
};
MyGraphWindow* setupTextureWindow(const MyGraphInput& input)
{
MyGraphWindow* graphWindow = new MyGraphWindow(input);
MyMenuItems2* menuItems = new MyMenuItems2(graphWindow);
graphWindow->m_menuItems = menuItems;
Gwen::UnicodeString str = Gwen::Utility::StringToUnicode(input.m_name);
menuItems->m_item = input.m_data->m_viewMenu->GetMenu()->AddItem( str, menuItems,(Gwen::Event::Handler::Function)&MyMenuItems2::MenuItemSelect);
// menuItems->m_item->SetCheckable(true);
return graphWindow;
}
void destroyTextureWindow(MyGraphWindow* window)
{
delete window->m_menuItems->m_item;
delete window->m_menuItems;
delete window;
}

View File

@@ -0,0 +1,32 @@
#ifndef GWEN_TEXTURE_WINDOW_H
#define GWEN_TEXTURE_WINDOW_H
struct MyGraphInput
{
struct GwenInternalData* m_data;
int m_xPos;
int m_yPos;
int m_width;
int m_height;
int m_borderWidth;
const char* m_name;
const char* m_texName;
MyGraphInput(struct GwenInternalData* data)
:m_data(data),
m_xPos(0),
m_yPos(0),
m_width(400),
m_height(400),
m_borderWidth(0),
m_name("GraphWindow"),
m_texName(0)
{
}
};
class MyGraphWindow* setupTextureWindow(const MyGraphInput& input);
void destroyTextureWindow(MyGraphWindow* window);
#endif //GWEN_TEXTURE_WINDOW_H

View File

@@ -0,0 +1,57 @@
#ifndef GWEN_INTERNAL_DATA_H
#define GWEN_INTERNAL_DATA_H
#include "../OpenGLWindow/GwenOpenGL3CoreRenderer.h"
#include "../OpenGLWindow/GLPrimitiveRenderer.h"
#include "Gwen/Platform.h"
#include "Gwen/Controls/TreeControl.h"
#include "Gwen/Controls/RadioButtonController.h"
#include "Gwen/Controls/VerticalSlider.h"
#include "Gwen/Controls/HorizontalSlider.h"
#include "Gwen/Controls/GroupBox.h"
#include "Gwen/Controls/CheckBox.h"
#include "Gwen/Controls/StatusBar.h"
#include "Gwen/Controls/Button.h"
#include "Gwen/Controls/ComboBox.h"
#include "Gwen/Controls/MenuStrip.h"
#include "Gwen/Controls/Slider.h"
#include "Gwen/Controls/Property/Text.h"
#include "Gwen/Controls/SplitterBar.h"
#include "Bullet3Common/b3AlignedObjectArray.h"
#include "Gwen/Gwen.h"
#include "Gwen/Align.h"
#include "Gwen/Utility.h"
#include "Gwen/Controls/WindowControl.h"
#include "Gwen/Controls/TabControl.h"
#include "Gwen/Controls/ListBox.h"
#include "Gwen/Skins/Simple.h"
//#include "Gwen/Skins/TexturedBase.h"
#include "gwenUserInterface.h"
struct GwenInternalData
{
//struct sth_stash;
//class GwenOpenGL3CoreRenderer* pRenderer;
Gwen::Renderer::Base* pRenderer;
Gwen::Skin::Simple skin;
Gwen::Controls::Canvas* pCanvas;
//GLPrimitiveRenderer* m_primRenderer;
Gwen::Controls::TabButton* m_demoPage;
Gwen::Controls::TabButton* m_explorerPage;
Gwen::Controls::TreeControl* m_explorerTreeCtrl;
Gwen::Controls::MenuItem* m_viewMenu;
class MyMenuItems* m_menuItems;
int m_curYposition;
Gwen::Controls::Label* m_rightStatusBar;
Gwen::Controls::Label* m_leftStatusBar;
b3AlignedObjectArray<class Gwen::Event::Handler*> m_handlers;
b3ToggleButtonCallback m_toggleButtonCallback;
b3ComboBoxCallback m_comboBoxCallback;
};
#endif//GWEN_INTERNAL_DATA_H

View File

@@ -0,0 +1,463 @@
#include "gwenUserInterface.h"
#include "gwenInternalData.h"
#include "Gwen/Controls/ImagePanel.h"
class MyGraphWindow* graphWindow = 0;
GwenUserInterface::GwenUserInterface()
{
m_data = new GwenInternalData();
m_data->m_toggleButtonCallback = 0;
m_data->m_comboBoxCallback = 0;
}
GwenUserInterface::~GwenUserInterface()
{
for (int i=0;i<m_data->m_handlers.size();i++)
{
delete m_data->m_handlers[i];
}
m_data->m_handlers.clear();
delete m_data->pCanvas;
delete m_data;
}
class MyMenuItems : public Gwen::Controls::Base
{
public:
b3FileOpenCallback m_fileOpenCallback;
MyMenuItems() :Gwen::Controls::Base(0),m_fileOpenCallback(0)
{
}
void myQuitApp( Gwen::Controls::Base* pControl )
{
exit(0);
}
void fileOpen( Gwen::Controls::Base* pControl )
{
if (m_fileOpenCallback)
{
(*m_fileOpenCallback)();
}
}
};
struct MyTestMenuBar : public Gwen::Controls::MenuStrip
{
Gwen::Controls::MenuItem* m_fileMenu;
Gwen::Controls::MenuItem* m_viewMenu;
MyMenuItems* m_menuItems;
MyTestMenuBar(Gwen::Controls::Base* pParent)
:Gwen::Controls::MenuStrip(pParent)
{
// Gwen::Controls::MenuStrip* menu = new Gwen::Controls::MenuStrip( pParent );
{
m_menuItems = new MyMenuItems();
m_menuItems->m_fileOpenCallback = 0;
m_fileMenu = AddItem( L"File" );
m_fileMenu->GetMenu()->AddItem(L"Open",m_menuItems,(Gwen::Event::Handler::Function)&MyMenuItems::fileOpen);
m_fileMenu->GetMenu()->AddItem(L"Quit",m_menuItems,(Gwen::Event::Handler::Function)&MyMenuItems::myQuitApp);
m_viewMenu = AddItem( L"View" );
}
}
};
void GwenUserInterface::resize(int width, int height)
{
m_data->pCanvas->SetSize(width,height);
}
struct MyComboBoxHander :public Gwen::Event::Handler
{
GwenInternalData* m_data;
int m_buttonId;
MyComboBoxHander (GwenInternalData* data, int buttonId)
:m_data(data),
m_buttonId(buttonId)
{
}
void onSelect( Gwen::Controls::Base* pControl )
{
Gwen::Controls::ComboBox* but = (Gwen::Controls::ComboBox*) pControl;
Gwen::String str = Gwen::Utility::UnicodeToString( but->GetSelectedItem()->GetText());
if (m_data->m_comboBoxCallback)
(*m_data->m_comboBoxCallback)(m_buttonId,str.c_str());
}
};
struct MyButtonHander :public Gwen::Event::Handler
{
GwenInternalData* m_data;
int m_buttonId;
MyButtonHander (GwenInternalData* data, int buttonId)
:m_data(data),
m_buttonId(buttonId)
{
}
void onButtonA( Gwen::Controls::Base* pControl )
{
Gwen::Controls::Button* but = (Gwen::Controls::Button*) pControl;
// int dep = but->IsDepressed();
int tog = but->GetToggleState();
if (m_data->m_toggleButtonCallback)
(*m_data->m_toggleButtonCallback)(m_buttonId,tog);
}
};
void GwenUserInterface::setStatusBarMessage(const char* message, bool isLeft)
{
Gwen::UnicodeString msg = Gwen::Utility::StringToUnicode(message);
if (isLeft)
{
m_data->m_leftStatusBar->SetText( msg);
} else
{
m_data->m_rightStatusBar->SetText( msg);
}
}
void GwenUserInterface::registerFileOpenCallback(b3FileOpenCallback callback)
{
m_data->m_menuItems->m_fileOpenCallback = callback;
}
void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* renderer,float retinaScale)
{
m_data->m_curYposition = 20;
//m_data->m_primRenderer = new GLPrimitiveRenderer(width,height);
m_data->pRenderer = renderer;//new GwenOpenGL3CoreRenderer(m_data->m_primRenderer,stash,width,height,retinaScale);
m_data->skin.SetRender( m_data->pRenderer );
m_data->pCanvas= new Gwen::Controls::Canvas( &m_data->skin );
m_data->pCanvas->SetSize( width,height);
m_data->pCanvas->SetDrawBackground( false);
m_data->pCanvas->SetBackgroundColor( Gwen::Color( 150, 170, 170, 255 ) );
MyTestMenuBar* menubar = new MyTestMenuBar(m_data->pCanvas);
m_data->m_viewMenu = menubar->m_viewMenu;
m_data->m_menuItems = menubar->m_menuItems;
Gwen::Controls::StatusBar* bar = new Gwen::Controls::StatusBar(m_data->pCanvas);
m_data->m_rightStatusBar = new Gwen::Controls::Label( bar );
m_data->m_rightStatusBar->SetWidth(width/2);
//m_data->m_rightStatusBar->SetText( L"Label Added to Right" );
bar->AddControl( m_data->m_rightStatusBar, true );
m_data->m_leftStatusBar = new Gwen::Controls::Label( bar );
//m_data->m_leftStatusBar->SetText( L"Label Added to Left" );
m_data->m_leftStatusBar->SetWidth(width/2);
bar->AddControl( m_data->m_leftStatusBar,false);
//Gwen::KeyboardFocus
/*Gwen::Controls::GroupBox* box = new Gwen::Controls::GroupBox(m_data->pCanvas);
box->SetText("text");
box->SetName("name");
box->SetHeight(500);
*/
Gwen::Controls::ScrollControl* windowRight= new Gwen::Controls::ScrollControl(m_data->pCanvas);
windowRight->Dock(Gwen::Pos::Right);
windowRight->SetWidth(150);
windowRight->SetHeight(250);
windowRight->SetScroll(false,true);
//windowLeft->SetSkin(
Gwen::Controls::TabControl* tab = new Gwen::Controls::TabControl(windowRight);
//tab->SetHeight(300);
tab->SetWidth(140);
tab->SetHeight(250);
//tab->Dock(Gwen::Pos::Left);
tab->Dock( Gwen::Pos::Fill );
//tab->SetMargin( Gwen::Margin( 2, 2, 2, 2 ) );
Gwen::UnicodeString str1(L"Params");
m_data->m_demoPage = tab->AddPage(str1);
// Gwen::UnicodeString str2(L"OpenCL");
// tab->AddPage(str2);
//Gwen::UnicodeString str3(L"page3");
// tab->AddPage(str3);
//but->onPress.Add(handler, &MyHander::onButtonA);
//box->Dock(Gwen::Pos::Left);
/*Gwen::Controls::WindowControl* windowBottom = new Gwen::Controls::WindowControl(m_data->pCanvas);
windowBottom->SetHeight(100);
windowBottom->Dock(Gwen::Pos::Bottom);
windowBottom->SetTitle("bottom");
*/
// Gwen::Controls::Property::Text* prop = new Gwen::Controls::Property::Text(m_data->pCanvas);
//prop->Dock(Gwen::Pos::Bottom);
/*Gwen::Controls::SplitterBar* split = new Gwen::Controls::SplitterBar(m_data->pCanvas);
split->Dock(Gwen::Pos::Center);
split->SetHeight(300);
split->SetWidth(300);
*/
/*
*/
Gwen::Controls::ScrollControl* windowLeft = new Gwen::Controls::ScrollControl(m_data->pCanvas);
windowLeft->Dock(Gwen::Pos::Left);
// windowLeft->SetTitle("title");
windowLeft->SetScroll(false, false);
windowLeft->SetWidth(250);
windowLeft->SetPos(50, 50);
windowLeft->SetHeight(500);
//windowLeft->SetClosable(false);
// windowLeft->SetShouldDrawBackground(true);
windowLeft->SetTabable(true);
Gwen::Controls::TabControl* explorerTab = new Gwen::Controls::TabControl(windowLeft);
//tab->SetHeight(300);
// explorerTab->SetWidth(230);
explorerTab->SetHeight(250);
//tab->Dock(Gwen::Pos::Left);
explorerTab->Dock(Gwen::Pos::Fill);
Gwen::UnicodeString explorerStr1(L"Explorer");
m_data->m_explorerPage = explorerTab->AddPage(explorerStr1);
Gwen::UnicodeString shapesStr1(L"Shapes");
explorerTab->AddPage(shapesStr1);
Gwen::UnicodeString testStr1(L"Test");
explorerTab->AddPage(testStr1);
Gwen::Controls::TreeControl* ctrl = new Gwen::Controls::TreeControl(m_data->m_explorerPage->GetPage());
m_data->m_explorerTreeCtrl = ctrl;
ctrl->SetKeyboardInputEnabled(true);
ctrl->Focus();
ctrl->SetBounds(2, 10, 236, 400);
}
void GwenUserInterface::forceUpdateScrollBars()
{
b3Assert(m_data);
b3Assert(m_data->m_explorerTreeCtrl);
if (m_data && m_data->m_explorerTreeCtrl)
{
m_data->m_explorerTreeCtrl->ForceUpdateScrollBars();
}
}
void GwenUserInterface::setFocus()
{
b3Assert(m_data);
b3Assert(m_data->m_explorerTreeCtrl);
if (m_data && m_data->m_explorerTreeCtrl)
{
m_data->m_explorerTreeCtrl->Focus();
}
}
b3ToggleButtonCallback GwenUserInterface::getToggleButtonCallback()
{
return m_data->m_toggleButtonCallback;
}
void GwenUserInterface::setToggleButtonCallback(b3ToggleButtonCallback callback)
{
m_data->m_toggleButtonCallback = callback;
}
void GwenUserInterface::registerToggleButton(int buttonId, const char* name)
{
assert(m_data);
assert(m_data->m_demoPage);
Gwen::Controls::Button* but = new Gwen::Controls::Button(m_data->m_demoPage->GetPage());
///some heuristic to find the button location
int ypos = m_data->m_curYposition;
but->SetPos(10, ypos );
but->SetWidth( 100 );
//but->SetBounds( 200, 30, 300, 200 );
MyButtonHander* handler = new MyButtonHander(m_data, buttonId);
m_data->m_handlers.push_back(handler);
m_data->m_curYposition+=22;
but->onToggle.Add(handler, &MyButtonHander::onButtonA);
but->SetIsToggle(true);
but->SetToggleState(false);
but->SetText(name);
}
void GwenUserInterface::setComboBoxCallback(b3ComboBoxCallback callback)
{
m_data->m_comboBoxCallback = callback;
}
b3ComboBoxCallback GwenUserInterface::getComboBoxCallback()
{
return m_data->m_comboBoxCallback;
}
void GwenUserInterface::registerComboBox(int comboboxId, int numItems, const char** items, int startItem)
{
Gwen::Controls::ComboBox* combobox = new Gwen::Controls::ComboBox(m_data->m_demoPage->GetPage());
MyComboBoxHander* handler = new MyComboBoxHander(m_data, comboboxId);
m_data->m_handlers.push_back(handler);
combobox->onSelection.Add(handler,&MyComboBoxHander::onSelect);
int ypos = m_data->m_curYposition;
combobox->SetPos(10, ypos );
combobox->SetWidth( 100 );
//box->SetPos(120,130);
for (int i=0;i<numItems;i++)
{
Gwen::Controls::MenuItem* item = combobox->AddItem(Gwen::Utility::StringToUnicode(items[i]));
if (i==startItem)
combobox->OnItemSelected(item);
}
m_data->m_curYposition+=22;
}
void GwenUserInterface::draw(int width, int height)
{
// printf("width = %d, height=%d\n", width,height);
if (m_data->pCanvas)
{
m_data->pCanvas->SetSize(width,height);
//m_data->m_primRenderer->setScreenSize(width,height);
m_data->pRenderer->Resize(width,height);
m_data->pCanvas->RenderCanvas();
//restoreOpenGLState();
}
}
bool GwenUserInterface::mouseMoveCallback( float x, float y)
{
bool handled = false;
static int m_lastmousepos[2] = {0,0};
static bool isInitialized = false;
if (m_data->pCanvas)
{
if (!isInitialized)
{
isInitialized = true;
m_lastmousepos[0] = x+1;
m_lastmousepos[1] = y+1;
}
handled = m_data->pCanvas->InputMouseMoved(x,y,m_lastmousepos[0],m_lastmousepos[1]);
}
return handled;
}
#include "../CommonInterfaces/CommonWindowInterface.h"
bool GwenUserInterface::keyboardCallback(int bulletKey, int state)
{
int key = -1;
if (m_data->pCanvas)
{
//convert 'Bullet' keys into 'Gwen' keys
switch (bulletKey)
{
case B3G_RETURN:
{
key = Gwen::Key::Return;
break;
}
case B3G_LEFT_ARROW:
key = Gwen::Key::Left;
break;
case B3G_RIGHT_ARROW:
key = Gwen::Key::Right;
break;
case B3G_UP_ARROW:
key = Gwen::Key::Up;
break;
case B3G_DOWN_ARROW:
key = Gwen::Key::Down;
break;
default:
{
}
};
bool bDown = (state == 1);
return m_data->pCanvas->InputKey(key, bDown);
}
return false;
}
bool GwenUserInterface::mouseButtonCallback(int button, int state, float x, float y)
{
bool handled = false;
if (m_data->pCanvas)
{
handled = m_data->pCanvas->InputMouseMoved(x,y,x, y);
if (button>=0)
{
handled = m_data->pCanvas->InputMouseButton(button,(bool)state);
if (handled)
{
//if (!state)
// return false;
}
}
}
return handled;
}

View File

@@ -0,0 +1,63 @@
#ifndef _GWEN_USER_INTERFACE_H
#define _GWEN_USER_INTERFACE_H
struct GwenInternalData;
typedef void (*b3ComboBoxCallback) (int combobox, const char* item);
typedef void (*b3ToggleButtonCallback)(int button, int state);
typedef void (*b3FileOpenCallback)();
namespace Gwen
{
namespace Renderer
{
class Base;
};
};
class GwenUserInterface
{
GwenInternalData* m_data;
public:
GwenUserInterface();
virtual ~GwenUserInterface();
void init(int width, int height,Gwen::Renderer::Base* gwenRenderer,float retinaScale);
void setFocus();
void forceUpdateScrollBars();
void draw(int width, int height);
void resize(int width, int height);
bool mouseMoveCallback( float x, float y);
bool mouseButtonCallback(int button, int state, float x, float y);
bool keyboardCallback(int key, int state);
void setToggleButtonCallback(b3ToggleButtonCallback callback);
b3ToggleButtonCallback getToggleButtonCallback();
void registerToggleButton(int buttonId, const char* name);
void setComboBoxCallback(b3ComboBoxCallback callback);
b3ComboBoxCallback getComboBoxCallback();
void registerComboBox(int buttonId, int numItems, const char** items, int startItem = 0);
void setStatusBarMessage(const char* message, bool isLeft=true);
void registerFileOpenCallback(b3FileOpenCallback callback);
GwenInternalData* getInternalData()
{
return m_data;
}
};
#endif //_GWEN_USER_INTERFACE_H

View File

@@ -0,0 +1,780 @@
#include "OpenGLExampleBrowser.h"
#include "LinearMath/btQuickprof.h"
#include "../OpenGLWindow/OpenGLInclude.h"
#include "../OpenGLWindow/SimpleOpenGL2App.h"
#include "../OpenGLWindow/SimpleOpenGL3App.h"
#include "../CommonInterfaces/CommonRenderInterface.h"
#ifdef __APPLE__
#include "OpenGLWindow/MacOpenGLWindow.h"
#else
#include "GL/glew.h"
#ifdef _WIN32
#include "../OpenGLWindow/Win32OpenGLWindow.h"
#else
//let's cross the fingers it is Linux/X11
#include "../OpenGLWindow/X11OpenGLWindow.h"
#endif //_WIN32
#endif//__APPLE__
#include "../ThirdPartyLibs/Gwen/Renderers/OpenGL_DebugFont.h"
#include "Bullet3Common/b3Vector3.h"
#include "assert.h"
#include <stdio.h>
#include "GwenGUISupport/gwenInternalData.h"
#include "GwenGUISupport/gwenUserInterface.h"
#include "../Utils/b3Clock.h"
#include "GwenGUISupport/GwenParameterInterface.h"
#include "GwenGUISupport/GwenProfileWindow.h"
#include "GwenGUISupport/GwenTextureWindow.h"
#include "GwenGUISupport/GraphingTexture.h"
#include "../CommonInterfaces/Common2dCanvasInterface.h"
#include "../CommonInterfaces/ExampleInterface.h"
#include "Bullet3Common/b3CommandLineArgs.h"
#include "../OpenGLWindow/SimpleCamera.h"
#include "../OpenGLWindow/SimpleOpenGL2Renderer.h"
#include "ExampleEntries.h"
#include "OpenGLGuiHelper.h"
#include "LinearMath/btIDebugDraw.h"
CommonGraphicsApp* s_app=0;
b3gWindowInterface* s_window = 0;
CommonParameterInterface* s_parameterInterface=0;
CommonRenderInterface* s_instancingRenderer=0;
OpenGLGuiHelper* s_guiHelper=0;
#define DEMO_SELECTION_COMBOBOX 13
const char* startFileName = "bulletDemo.txt";
static GwenUserInterface* gui = 0;
static int sCurrentDemoIndex = 0;
static int sCurrentHightlighted = 0;
static ExampleInterface* sCurrentDemo = 0;
static b3AlignedObjectArray<const char*> allNames;
static class ExampleEntries* gAllExamples=0;
bool drawGUI=true;
extern bool useShadowMap;
static bool visualWireframe=false;
static bool renderVisualGeometry=true;
static bool renderGrid = true;
int gDebugDrawFlags = btIDebugDraw::DBG_DrawWireframe;
static bool pauseSimulation=false;
int midiBaseIndex = 176;
extern bool gDisableDeactivation;
//#include <float.h>
//unsigned int fp_control_state = _controlfp(_EM_INEXACT, _MCW_EM);
b3KeyboardCallback prevKeyboardCallback = 0;
void MyKeyboardCallback(int key, int state)
{
//printf("key=%d, state=%d\n", key, state);
bool handled = false;
if (!handled && sCurrentDemo)
{
handled = sCurrentDemo->keyboardCallback(key,state);
}
if (gui && !handled )
{
handled = gui->keyboardCallback(key, state);
}
//checkout: is it desired to ignore keys, if the demo already handles them?
//if (handled)
// return;
if (key=='a' && state)
{
gDebugDrawFlags ^= btIDebugDraw::DBG_DrawAabb;
}
if (key=='c' && state)
{
gDebugDrawFlags ^= btIDebugDraw::DBG_DrawConstraints;
gDebugDrawFlags ^= btIDebugDraw::DBG_DrawContactPoints;
}
if (key == 'd' && state)
{
gDebugDrawFlags ^= btIDebugDraw::DBG_NoDeactivation;
gDisableDeactivation = ((gDebugDrawFlags & btIDebugDraw::DBG_NoDeactivation) != 0);
}
if (key=='l' && state)
{
gDebugDrawFlags ^= btIDebugDraw::DBG_DrawConstraintLimits;
}
if (key=='w' && state)
{
visualWireframe=!visualWireframe;
gDebugDrawFlags ^= btIDebugDraw::DBG_DrawWireframe;
}
if (key=='v' && state)
{
renderVisualGeometry = !renderVisualGeometry;
}
if (key=='g' && state)
{
renderGrid = !renderGrid;
}
if (key=='i' && state)
{
pauseSimulation = !pauseSimulation;
}
if (key=='s' && state)
{
useShadowMap=!useShadowMap;
}
if (key==B3G_ESCAPE && s_window)
{
s_window->setRequestExit();
}
if (prevKeyboardCallback)
prevKeyboardCallback(key,state);
}
b3MouseMoveCallback prevMouseMoveCallback = 0;
static void MyMouseMoveCallback( float x, float y)
{
bool handled = false;
if (sCurrentDemo)
handled = sCurrentDemo->mouseMoveCallback(x,y);
if (!handled && gui)
handled = gui->mouseMoveCallback(x,y);
if (!handled)
{
if (prevMouseMoveCallback)
prevMouseMoveCallback(x,y);
}
}
b3MouseButtonCallback prevMouseButtonCallback = 0;
static void MyMouseButtonCallback(int button, int state, float x, float y)
{
bool handled = false;
//try picking first
if (sCurrentDemo)
handled = sCurrentDemo->mouseButtonCallback(button,state,x,y);
if (!handled && gui)
handled = gui->mouseButtonCallback(button,state,x,y);
if (!handled)
{
if (prevMouseButtonCallback )
prevMouseButtonCallback (button,state,x,y);
}
// b3DefaultMouseButtonCallback(button,state,x,y);
}
#include <string.h>
void openURDFDemo(const char* filename)
{
#if 0
if (sCurrentDemo)
{
sCurrentDemo->exitPhysics();
s_instancingRenderer->removeAllInstances();
delete sCurrentDemo;
sCurrentDemo=0;
}
s_parameterInterface->removeAllParameters();
ImportUrdfSetup* physicsSetup = new ImportUrdfSetup();
physicsSetup->setFileName(filename);
sCurrentDemo = new BasicDemo(s_app, physicsSetup);
s_app->setUpAxis(2);
if (sCurrentDemo)
{
sCurrentDemo->initPhysics();
}
#endif
}
void selectDemo(int demoIndex)
{
sCurrentDemoIndex = demoIndex;
sCurrentHightlighted = demoIndex;
int numDemos = gAllExamples->getNumRegisteredExamples();
if (demoIndex>numDemos)
{
demoIndex = 0;
}
if (sCurrentDemo)
{
sCurrentDemo->exitPhysics();
s_instancingRenderer->removeAllInstances();
delete sCurrentDemo;
sCurrentDemo=0;
delete s_guiHelper;
s_guiHelper = 0;
}
ExampleInterface::CreateFunc* func = gAllExamples->getExampleCreateFunc(demoIndex);
if (func)
{
s_parameterInterface->removeAllParameters();
int option = gAllExamples->getExampleOption(demoIndex);
s_guiHelper= new OpenGLGuiHelper(s_app);
sCurrentDemo = (*func)(0,s_guiHelper, option);
if (sCurrentDemo)
{
if (gui)
{
bool isLeft = true;
gui->setStatusBarMessage("Status: OK", false);
}
sCurrentDemo->initPhysics();
}
}
}
#include <stdio.h>
static void saveCurrentDemoEntry(int currentEntry,const char* startFileName)
{
FILE* f = fopen(startFileName,"w");
if (f)
{
fprintf(f,"%d\n",currentEntry);
fclose(f);
}
};
static int loadCurrentDemoEntry(const char* startFileName)
{
int currentEntry= 0;
FILE* f = fopen(startFileName,"r");
if (f)
{
int result;
result = fscanf(f,"%d",&currentEntry);
if (result)
{
return currentEntry;
}
fclose(f);
}
return 0;
};
void MyComboBoxCallback(int comboId, const char* item)
{
//printf("comboId = %d, item = %s\n",comboId, item);
if (comboId==DEMO_SELECTION_COMBOBOX)
{
//find selected item
for (int i=0;i<allNames.size();i++)
{
if (strcmp(item,allNames[i])==0)
{
selectDemo(i);
saveCurrentDemoEntry(sCurrentDemoIndex,startFileName);
break;
}
}
}
}
void MyStatusBarPrintf(const char* msg)
{
printf("b3Printf: %s\n", msg);
if (gui)
{
bool isLeft = true;
gui->setStatusBarMessage(msg,isLeft);
}
}
void MyStatusBarWarning(const char* msg)
{
printf("Warning: %s\n", msg);
if (gui)
{
bool isLeft = false;
gui->setStatusBarMessage(msg,isLeft);
}
}
struct MyMenuItemHander :public Gwen::Event::Handler
{
int m_buttonId;
MyMenuItemHander( int buttonId)
:m_buttonId(buttonId)
{
}
void onButtonA(Gwen::Controls::Base* pControl)
{
//const Gwen::String& name = pControl->GetName();
Gwen::Controls::TreeNode* node = (Gwen::Controls::TreeNode*)pControl;
// Gwen::Controls::Label* l = node->GetButton();
Gwen::UnicodeString la = node->GetButton()->GetText();// node->GetButton()->GetName();// GetText();
Gwen::String laa = Gwen::Utility::UnicodeToString(la);
// const char* ha = laa.c_str();
//printf("selected %s\n", ha);
//int dep = but->IsDepressed();
//int tog = but->GetToggleState();
// if (m_data->m_toggleButtonCallback)
// (*m_data->m_toggleButtonCallback)(m_buttonId, tog);
}
void onButtonB(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();
bool handled = false;
selectDemo(sCurrentHightlighted);
saveCurrentDemoEntry(sCurrentDemoIndex, startFileName);
}
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();
// printf("onButtonC ! %s\n", ha);
}
void onButtonD(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();
*/
// printf("onKeyReturn ! \n");
selectDemo(sCurrentHightlighted);
saveCurrentDemoEntry(sCurrentDemoIndex, startFileName);
}
void onButtonE(Gwen::Controls::Base* pControl)
{
// printf("select %d\n",m_buttonId);
sCurrentHightlighted = m_buttonId;
}
void onButtonF(Gwen::Controls::Base* pControl)
{
//printf("selection changed!\n");
}
void onButtonG(Gwen::Controls::Base* pControl)
{
//printf("onButtonG !\n");
}
};
#include "Bullet3Common/b3HashMap.h"
struct GL3TexLoader : public MyTextureLoader
{
b3HashMap<b3HashString,GLint> m_hashMap;
virtual void LoadTexture( Gwen::Texture* pTexture )
{
Gwen::String namestr = pTexture->name.Get();
const char* n = namestr.c_str();
GLint* texIdPtr = m_hashMap[n];
if (texIdPtr)
{
pTexture->m_intData = *texIdPtr;
}
}
virtual void FreeTexture( Gwen::Texture* pTexture )
{
}
};
void fileOpenCallback()
{
char filename[1024];
int len = s_window->fileOpenDialog(filename,1024);
if (len)
{
//todo(erwincoumans) check if it is actually URDF
//printf("file open:%s\n", filename);
openURDFDemo(filename);
}
}
#define MAX_GRAPH_WINDOWS 5
struct QuickCanvas : public Common2dCanvasInterface
{
GL3TexLoader* m_myTexLoader;
MyGraphWindow* m_gw[MAX_GRAPH_WINDOWS];
GraphingTexture* m_gt[MAX_GRAPH_WINDOWS];
int m_curNumGraphWindows;
QuickCanvas(GL3TexLoader* myTexLoader)
:m_myTexLoader(myTexLoader),
m_curNumGraphWindows(0)
{
for (int i=0;i<MAX_GRAPH_WINDOWS;i++)
{
m_gw[i] = 0;
m_gt[i] = 0;
}
}
virtual ~QuickCanvas() {}
virtual int createCanvas(const char* canvasName, int width, int height)
{
if (m_curNumGraphWindows<MAX_GRAPH_WINDOWS)
{
//find a slot
int slot = 0;//hardcoded for now
m_curNumGraphWindows++;
MyGraphInput input(gui->getInternalData());
input.m_width=width;
input.m_height=height;
input.m_xPos = 300;
input.m_yPos = height-input.m_height;
input.m_name=canvasName;
input.m_texName = canvasName;
m_gt[slot] = new GraphingTexture;
m_gt[slot]->create(width,height);
int texId = m_gt[slot]->getTextureId();
m_myTexLoader->m_hashMap.insert(canvasName, texId);
m_gw[slot] = setupTextureWindow(input);
return slot;
}
return -1;
}
virtual void destroyCanvas(int canvasId)
{
btAssert(canvasId==0);//hardcoded to zero for now, only a single canvas
btAssert(m_curNumGraphWindows==1);
destroyTextureWindow(m_gw[canvasId]);
m_curNumGraphWindows--;
}
virtual void setPixel(int canvasId, int x, int y, unsigned char red, unsigned char green,unsigned char blue, unsigned char alpha)
{
btAssert(canvasId==0);//hardcoded
btAssert(m_curNumGraphWindows==1);
m_gt[canvasId]->setPixel(x,y,red,green,blue,alpha);
}
virtual void refreshImageData(int canvasId)
{
m_gt[canvasId]->uploadImageData();
}
};
OpenGLExampleBrowser::OpenGLExampleBrowser(class ExampleEntries* examples)
{
gAllExamples = examples;
}
OpenGLExampleBrowser::~OpenGLExampleBrowser()
{
gAllExamples = 0;
}
#include "EmptyExample.h"
bool OpenGLExampleBrowser::init(int argc, char* argv[])
{
b3CommandLineArgs args(argc,argv);
int width = 1024;
int height=768;
SimpleOpenGL3App* simpleApp=0;
bool useOpenGL2=false;
if (useOpenGL2)
{
s_app = new SimpleOpenGL2App("AllBullet2Demos",width,height);
s_app->m_renderer = new SimpleOpenGL2Renderer(width,height);
} else
{
simpleApp = new SimpleOpenGL3App("AllBullet2Demos",width,height);
s_app = simpleApp;
}
char* gVideoFileName = 0;
args.GetCmdLineArgument("mp4",gVideoFileName);
if (gVideoFileName)
simpleApp->dumpFramesToVideo(gVideoFileName);
s_instancingRenderer = s_app->m_renderer;
s_window = s_app->m_window;
prevMouseMoveCallback = s_window->getMouseMoveCallback();
s_window->setMouseMoveCallback(MyMouseMoveCallback);
prevMouseButtonCallback = s_window->getMouseButtonCallback();
s_window->setMouseButtonCallback(MyMouseButtonCallback);
prevKeyboardCallback = s_window->getKeyboardCallback();
s_window->setKeyboardCallback(MyKeyboardCallback);
s_app->m_renderer->setCameraDistance(13);
s_app->m_renderer->setCameraPitch(0);
s_app->m_renderer->setCameraTargetPosition(0,0,0);
b3SetCustomWarningMessageFunc(MyStatusBarWarning);
b3SetCustomPrintfFunc(MyStatusBarPrintf);
assert(glGetError()==GL_NO_ERROR);
gui = new GwenUserInterface;
GL3TexLoader* myTexLoader = new GL3TexLoader;
Gwen::Renderer::Base* gwenRenderer = 0;
if (useOpenGL2)
{
gwenRenderer = new Gwen::Renderer::OpenGL_DebugFont();
} else
{
sth_stash* fontstash=simpleApp->getFontStash();
gwenRenderer = new GwenOpenGL3CoreRenderer(simpleApp->m_primRenderer,fontstash,width,height,s_window->getRetinaScale(),myTexLoader);
}
//
gui->init(width,height,gwenRenderer,s_window->getRetinaScale());
// gui->getInternalData()->m_explorerPage
Gwen::Controls::TreeControl* tree = gui->getInternalData()->m_explorerTreeCtrl;
//gui->getInternalData()->pRenderer->setTextureLoader(myTexLoader);
MyProfileWindow* profWindow = setupProfileWindow(gui->getInternalData());
profileWindowSetVisible(profWindow,false);
gui->setFocus();
s_parameterInterface = s_app->m_parameterInterface = new GwenParameterInterface(gui->getInternalData());
s_app->m_2dCanvasInterface = new QuickCanvas(myTexLoader);
///add some demos to the gAllExamples
int numDemos = gAllExamples->getNumRegisteredExamples();
//char nodeText[1024];
//int curDemo = 0;
int selectedDemo = loadCurrentDemoEntry(startFileName);
Gwen::Controls::TreeNode* curNode = tree;
MyMenuItemHander* handler2 = new MyMenuItemHander(-1);
tree->onReturnKeyDown.Add(handler2, &MyMenuItemHander::onButtonD);
int firstAvailableDemoIndex=-1;
Gwen::Controls::TreeNode* firstNode=0;
for (int d = 0; d<numDemos; d++)
{
// sprintf(nodeText, "Node %d", i);
Gwen::UnicodeString nodeUText = Gwen::Utility::StringToUnicode(gAllExamples->getExampleName(d));
if (gAllExamples->getExampleCreateFunc(d))//was test for gAllExamples[d].m_menuLevel==1
{
Gwen::Controls::TreeNode* pNode = curNode->AddNode(nodeUText);
if (firstAvailableDemoIndex<0)
{
firstAvailableDemoIndex = d;
firstNode = pNode;
}
if (d == selectedDemo)
{
pNode->SetSelected(true);
tree->ExpandAll();
selectDemo(d);
}
MyMenuItemHander* handler = new MyMenuItemHander(d);
pNode->onNamePress.Add(handler, &MyMenuItemHander::onButtonA);
pNode->GetButton()->onDoubleClick.Add(handler, &MyMenuItemHander::onButtonB);
pNode->GetButton()->onDown.Add(handler, &MyMenuItemHander::onButtonC);
pNode->onSelect.Add(handler, &MyMenuItemHander::onButtonE);
pNode->onReturnKeyDown.Add(handler, &MyMenuItemHander::onButtonG);
pNode->onSelectChange.Add(handler, &MyMenuItemHander::onButtonF);
// pNode->onKeyReturn.Add(handler, &MyMenuItemHander::onButtonD);
// pNode->GetButton()->onKeyboardReturn.Add(handler, &MyMenuItemHander::onButtonD);
// pNode->onNamePress.Add(handler, &MyMenuItemHander::onButtonD);
// pNode->onKeyboardPressed.Add(handler, &MyMenuItemHander::onButtonD);
// pNode->OnKeyPress
}
else
{
curNode = tree->AddNode(nodeUText);
}
}
if (sCurrentDemo==0)
{
if (firstAvailableDemoIndex>=0)
{
firstNode->SetSelected(true);
tree->ExpandAll();
selectDemo(firstAvailableDemoIndex);
}
}
btAssert(sCurrentDemo!=0);
if (sCurrentDemo==0)
{
printf("Error, no demo/example\n");
exit(0);
}
gui->registerFileOpenCallback(fileOpenCallback);
return true;
}
ExampleInterface* OpenGLExampleBrowser::getCurrentExample()
{
btAssert(sCurrentDemo);
return sCurrentDemo;
}
bool OpenGLExampleBrowser::requestedExit()
{
return s_window->requestedExit();
}
void OpenGLExampleBrowser::update(float deltaTime)
{
/* if (sCurrentDemo)
{
sCurrentDemo->stepSimulation(deltaTime);
}
*/
assert(glGetError()==GL_NO_ERROR);
s_instancingRenderer->init();
DrawGridData dg;
dg.upAxis = s_app->getUpAxis();
{
BT_PROFILE("Update Camera");
s_instancingRenderer->updateCamera(dg.upAxis);
}
if (renderGrid)
{
BT_PROFILE("Draw Grid");
s_app->drawGrid(dg);
}
static int frameCount = 0;
frameCount++;
if (0)
{
BT_PROFILE("Draw frame counter");
char bla[1024];
sprintf(bla,"Frame %d", frameCount);
s_app->drawText(bla,10,10);
}
if (sCurrentDemo)
{
if (!pauseSimulation)
{
//printf("---------------------------------------------------\n");
//printf("Framecount = %d\n",frameCount);
sCurrentDemo->stepSimulation(deltaTime);//1./60.f);
}
if (renderVisualGeometry)
{
if (visualWireframe)
{
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
}
BT_PROFILE("Render Scene");
sCurrentDemo->renderScene();
}
{
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
sCurrentDemo->physicsDebugDraw(gDebugDrawFlags);
}
}
static int toggle = 1;
if (1)
{
//if (!pauseSimulation)
// processProfileData(profWindow,false);
{
// if (useOpenGL2)
//{
// saveOpenGLState(width,height);
//}
BT_PROFILE("Draw Gwen GUI");
gui->draw(s_instancingRenderer->getScreenWidth(),s_instancingRenderer->getScreenHeight());
//if (useOpenGL2)
//{
// restoreOpenGLState();
//}
}
}
toggle=1-toggle;
{
BT_PROFILE("Sync Parameters");
s_parameterInterface->syncParameters();
}
{
BT_PROFILE("Swap Buffers");
s_app->swapBuffer();
}
gui->forceUpdateScrollBars();
}

View File

@@ -0,0 +1,23 @@
#ifndef OPENGL_BROWSER_GUI_H
#define OPENGL_BROWSER_GUI_H
#include "ExampleBrowserInterface.h"
class OpenGLExampleBrowser : public ExampleBrowserInterface
{
public:
OpenGLExampleBrowser(class ExampleEntries* examples);
virtual ~OpenGLExampleBrowser();
virtual ExampleInterface* getCurrentExample();
virtual bool init(int argc, char* argv[]);
virtual void update(float deltaTime);
virtual bool requestedExit();
};
#endif //OPENGL_BROWSER_GUI_H

View File

@@ -0,0 +1,518 @@
#include "OpenGLGuiHelper.h"
#include "btBulletDynamicsCommon.h"
#include "../CommonInterfaces/CommonGraphicsAppInterface.h"
#include "../CommonInterfaces/CommonRenderInterface.h"
#include "Bullet3Common/b3Scalar.h"
#include "BulletCollision/CollisionShapes/btShapeHull.h"//to create a tesselation of a generic btConvexShape
#include "../OpenGLWindow/GLInstanceGraphicsShape.h"
#define BT_LINE_BATCH_SIZE 512
struct MyDebugVec3
{
MyDebugVec3(const btVector3& org)
:x(org.x()),
y(org.y()),
z(org.z())
{
}
float x;
float y;
float z;
};
class MyDebugDrawer : public btIDebugDraw
{
CommonGraphicsApp* m_glApp;
int m_debugMode;
btAlignedObjectArray<MyDebugVec3> m_linePoints;
btAlignedObjectArray<unsigned int> m_lineIndices;
btVector3 m_currentLineColor;
public:
MyDebugDrawer(CommonGraphicsApp* app)
: m_glApp(app)
,m_debugMode(btIDebugDraw::DBG_DrawWireframe|btIDebugDraw::DBG_DrawAabb),
m_currentLineColor(-1,-1,-1)
{
}
virtual void drawLine(const btVector3& from1,const btVector3& to1,const btVector3& color1)
{
//float from[4] = {from1[0],from1[1],from1[2],from1[3]};
//float to[4] = {to1[0],to1[1],to1[2],to1[3]};
//float color[4] = {color1[0],color1[1],color1[2],color1[3]};
//m_glApp->m_instancingRenderer->drawLine(from,to,color);
if (m_currentLineColor!=color1 || m_linePoints.size() >= BT_LINE_BATCH_SIZE)
{
flushLines();
m_currentLineColor = color1;
}
MyDebugVec3 from(from1);
MyDebugVec3 to(to1);
m_linePoints.push_back(from);
m_linePoints.push_back(to);
m_lineIndices.push_back(m_lineIndices.size());
m_lineIndices.push_back(m_lineIndices.size());
}
virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color)
{
drawLine(PointOnB,PointOnB+normalOnB,color);
}
virtual void reportErrorWarning(const char* warningString)
{
}
virtual void draw3dText(const btVector3& location,const char* textString)
{
}
virtual void setDebugMode(int debugMode)
{
m_debugMode = debugMode;
}
virtual int getDebugMode() const
{
return m_debugMode;
}
virtual void flushLines()
{
int sz = m_linePoints.size();
if (sz)
{
float debugColor[4];
debugColor[0] = m_currentLineColor.x();
debugColor[1] = m_currentLineColor.y();
debugColor[2] = m_currentLineColor.z();
debugColor[3] = 1.f;
m_glApp->m_renderer->drawLines(&m_linePoints[0].x,debugColor,
m_linePoints.size(),sizeof(MyDebugVec3),
&m_lineIndices[0],
m_lineIndices.size(),
1);
m_linePoints.clear();
m_lineIndices.clear();
}
}
};
static btVector4 sColors[4] =
{
btVector4(0.3,0.3,1,1),
btVector4(1,0,0,1),
btVector4(0,1,0,1),
btVector4(0,1,1,1),
//btVector4(1,1,0,1),
};
struct OpenGLGuiHelperInternalData
{
struct CommonGraphicsApp* m_glApp;
class MyDebugDrawer* m_debugDraw;
int m_curColor;
};
OpenGLGuiHelper::OpenGLGuiHelper(CommonGraphicsApp* glApp)
{
m_data = new OpenGLGuiHelperInternalData;
m_data->m_glApp = glApp;
m_data->m_debugDraw = 0;
m_data->m_curColor = 0;
}
OpenGLGuiHelper::~OpenGLGuiHelper()
{
delete m_data;
}
struct CommonRenderInterface* OpenGLGuiHelper::getRenderInterface()
{
return m_data->m_glApp->m_renderer;
}
void OpenGLGuiHelper::createRigidBodyGraphicsObject(btRigidBody* body, const btVector3& color)
{
createCollisionObjectGraphicsObject(body,color);
}
void OpenGLGuiHelper::createCollisionObjectGraphicsObject(btCollisionObject* body, const btVector3& color)
{
btCollisionShape* shape = body->getCollisionShape();
btTransform startTransform = body->getWorldTransform();
int graphicsShapeId = shape->getUserIndex();
if (graphicsShapeId>=0)
{
// btAssert(graphicsShapeId >= 0);
btVector3 localScaling = shape->getLocalScaling();
int graphicsInstanceId = m_data->m_glApp->m_renderer->registerGraphicsInstance(graphicsShapeId, startTransform.getOrigin(), startTransform.getRotation(), color, localScaling);
body->setUserIndex(graphicsInstanceId);
}
}
int OpenGLGuiHelper::registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices)
{
int shapeId = m_data->m_glApp->m_renderer->registerShape(vertices, numvertices,indices,numIndices);
return shapeId;
}
int OpenGLGuiHelper::registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling)
{
return m_data->m_glApp->m_renderer->registerGraphicsInstance(shapeIndex,position,quaternion,color,scaling);
}
static void createCollisionShapeGraphicsObjectInternal(btCollisionShape* collisionShape, const btTransform& parentTransform, btAlignedObjectArray<GLInstanceVertex>& verticesOut, btAlignedObjectArray<int>& indicesOut)
{
//todo: support all collision shape types
switch (collisionShape->getShapeType())
{
case STATIC_PLANE_PROXYTYPE:
{
//draw a box, oriented along the plane normal
const btStaticPlaneShape* staticPlaneShape = static_cast<const btStaticPlaneShape*>(collisionShape);
btScalar planeConst = staticPlaneShape->getPlaneConstant();
const btVector3& planeNormal = staticPlaneShape->getPlaneNormal();
btVector3 planeOrigin = planeNormal * planeConst;
btVector3 vec0,vec1;
btPlaneSpace1(planeNormal,vec0,vec1);
btScalar vecLen = 100.f;
btVector3 verts[4];
verts[0] = planeOrigin + vec0*vecLen + vec1*vecLen;
verts[1] = planeOrigin - vec0*vecLen + vec1*vecLen;
verts[2] = planeOrigin - vec0*vecLen - vec1*vecLen;
verts[3] = planeOrigin + vec0*vecLen - vec1*vecLen;
int startIndex = verticesOut.size();
indicesOut.push_back(startIndex+0);
indicesOut.push_back(startIndex+1);
indicesOut.push_back(startIndex+2);
indicesOut.push_back(startIndex+0);
indicesOut.push_back(startIndex+2);
indicesOut.push_back(startIndex+3);
btVector3 triNormal = parentTransform.getBasis()*planeNormal;
for (int i=0;i<4;i++)
{
GLInstanceVertex vtx;
btVector3 pos =parentTransform*verts[i];
vtx.xyzw[0] = pos.x();
vtx.xyzw[1] = pos.y();
vtx.xyzw[2] = pos.z();
vtx.xyzw[3] = 0.f;
vtx.normal[0] =triNormal.x();
vtx.normal[1] =triNormal.y();
vtx.normal[2] =triNormal.z();
vtx.uv[0] = 0.5f;
vtx.uv[1] = 0.5f;
verticesOut.push_back(vtx);
}
break;
}
case TRIANGLE_MESH_SHAPE_PROXYTYPE:
{
btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*) collisionShape;
btVector3 trimeshScaling = trimesh->getLocalScaling();
btStridingMeshInterface* meshInterface = trimesh->getMeshInterface();
btAlignedObjectArray<btVector3> vertices;
btAlignedObjectArray<int> indices;
for (int partId=0;partId<meshInterface->getNumSubParts();partId++)
{
const unsigned char *vertexbase = 0;
int numverts = 0;
PHY_ScalarType type = PHY_INTEGER;
int stride = 0;
const unsigned char *indexbase = 0;
int indexstride = 0;
int numfaces = 0;
PHY_ScalarType indicestype = PHY_INTEGER;
//PHY_ScalarType indexType=0;
btVector3 triangleVerts[3];
meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase,numverts, type,stride,&indexbase,indexstride,numfaces,indicestype,partId);
btVector3 aabbMin,aabbMax;
for (int triangleIndex = 0 ; triangleIndex < numfaces;triangleIndex++)
{
unsigned int* gfxbase = (unsigned int*)(indexbase+triangleIndex*indexstride);
for (int j=2;j>=0;j--)
{
int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
if (type == PHY_FLOAT)
{
float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
triangleVerts[j] = btVector3(
graphicsbase[0]*trimeshScaling.getX(),
graphicsbase[1]*trimeshScaling.getY(),
graphicsbase[2]*trimeshScaling.getZ());
}
else
{
double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
triangleVerts[j] = btVector3( btScalar(graphicsbase[0]*trimeshScaling.getX()),
btScalar(graphicsbase[1]*trimeshScaling.getY()),
btScalar(graphicsbase[2]*trimeshScaling.getZ()));
}
}
indices.push_back(vertices.size());
vertices.push_back(triangleVerts[0]);
indices.push_back(vertices.size());
vertices.push_back(triangleVerts[1]);
indices.push_back(vertices.size());
vertices.push_back(triangleVerts[2]);
btVector3 triNormal = (triangleVerts[1]-triangleVerts[0]).cross(triangleVerts[2]-triangleVerts[0]);
triNormal.normalize();
for (int v=0;v<3;v++)
{
GLInstanceVertex vtx;
btVector3 pos =parentTransform*triangleVerts[v];
vtx.xyzw[0] = pos.x();
vtx.xyzw[1] = pos.y();
vtx.xyzw[2] = pos.z();
vtx.xyzw[3] = 0.f;
vtx.normal[0] =triNormal.x();
vtx.normal[1] =triNormal.y();
vtx.normal[2] =triNormal.z();
vtx.uv[0] = 0.5f;
vtx.uv[1] = 0.5f;
indicesOut.push_back(verticesOut.size());
verticesOut.push_back(vtx);
}
}
}
break;
}
default:
{
if (collisionShape->isConvex())
{
btConvexShape* convex = (btConvexShape*)collisionShape;
{
btShapeHull* hull = new btShapeHull(convex);
hull->buildHull(0.0);
{
//int strideInBytes = 9*sizeof(float);
//int numVertices = hull->numVertices();
//int numIndices =hull->numIndices();
for (int t=0;t<hull->numTriangles();t++)
{
btVector3 triNormal;
int index0 = hull->getIndexPointer()[t*3+0];
int index1 = hull->getIndexPointer()[t*3+1];
int index2 = hull->getIndexPointer()[t*3+2];
btVector3 pos0 =parentTransform*hull->getVertexPointer()[index0];
btVector3 pos1 =parentTransform*hull->getVertexPointer()[index1];
btVector3 pos2 =parentTransform*hull->getVertexPointer()[index2];
triNormal = (pos1-pos0).cross(pos2-pos0);
triNormal.normalize();
for (int v=0;v<3;v++)
{
int index = hull->getIndexPointer()[t*3+v];
GLInstanceVertex vtx;
btVector3 pos =parentTransform*hull->getVertexPointer()[index];
vtx.xyzw[0] = pos.x();
vtx.xyzw[1] = pos.y();
vtx.xyzw[2] = pos.z();
vtx.xyzw[3] = 0.f;
vtx.normal[0] =triNormal.x();
vtx.normal[1] =triNormal.y();
vtx.normal[2] =triNormal.z();
vtx.uv[0] = 0.5f;
vtx.uv[1] = 0.5f;
indicesOut.push_back(verticesOut.size());
verticesOut.push_back(vtx);
}
}
}
}
} else
{
if (collisionShape->isCompound())
{
btCompoundShape* compound = (btCompoundShape*) collisionShape;
for (int i=0;i<compound->getNumChildShapes();i++)
{
btTransform childWorldTrans = parentTransform * compound->getChildTransform(i);
createCollisionShapeGraphicsObjectInternal(compound->getChildShape(i),childWorldTrans,verticesOut,indicesOut);
}
} else
{
btAssert(0);
}
}
}
};
}
void OpenGLGuiHelper::createCollisionShapeGraphicsObject(btCollisionShape* collisionShape)
{
//already has a graphics object?
if (collisionShape->getUserIndex()>=0)
return;
btAlignedObjectArray<GLInstanceVertex> vertices;
btAlignedObjectArray<int> indices;
btTransform startTrans;startTrans.setIdentity();
createCollisionShapeGraphicsObjectInternal(collisionShape,startTrans,vertices,indices);
if (vertices.size() && indices.size())
{
int shapeId = m_data->m_glApp->m_renderer->registerShape(&vertices[0].xyzw[0],vertices.size(),&indices[0],indices.size());
collisionShape->setUserIndex(shapeId);
}
}
void OpenGLGuiHelper::syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld)
{
int numCollisionObjects = rbWorld->getNumCollisionObjects();
for (int i = 0; i<numCollisionObjects; i++)
{
btCollisionObject* colObj = rbWorld->getCollisionObjectArray()[i];
btVector3 pos = colObj->getWorldTransform().getOrigin();
btQuaternion orn = colObj->getWorldTransform().getRotation();
int index = colObj->getUserIndex();
if (index >= 0)
{
m_data->m_glApp->m_renderer->writeSingleInstanceTransformToCPU(pos, orn, index);
}
}
m_data->m_glApp->m_renderer->writeTransforms();
}
void OpenGLGuiHelper::createPhysicsDebugDrawer(btDiscreteDynamicsWorld* rbWorld)
{
btAssert(rbWorld);
m_data->m_debugDraw = new MyDebugDrawer(m_data->m_glApp);
rbWorld->setDebugDrawer(m_data->m_debugDraw );
m_data->m_debugDraw->setDebugMode(
btIDebugDraw::DBG_DrawWireframe
+btIDebugDraw::DBG_DrawAabb
//btIDebugDraw::DBG_DrawContactPoints
);
}
struct Common2dCanvasInterface* OpenGLGuiHelper::get2dCanvasInterface()
{
return m_data->m_glApp->m_2dCanvasInterface;
}
CommonParameterInterface* OpenGLGuiHelper::getParameterInterface()
{
return m_data->m_glApp->m_parameterInterface;
}
void OpenGLGuiHelper::setUpAxis(int axis)
{
m_data->m_glApp->setUpAxis(axis);
}
btVector3 OpenGLGuiHelper::selectColor()
{
btVector4 color = sColors[m_data->m_curColor];
m_data->m_curColor++;
m_data->m_curColor&=3;
return color;
}
struct MyConvertPointerSizeT
{
union
{
const void* m_ptr;
size_t m_int;
};
};
bool shapePointerCompareFunc(const btCollisionObject* colA, const btCollisionObject* colB)
{
MyConvertPointerSizeT a,b;
a.m_ptr = colA->getCollisionShape();
b.m_ptr = colB->getCollisionShape();
return (a.m_int<b.m_int);
}
void OpenGLGuiHelper::autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld)
{
//sort the collision objects based on collision shape, the gfx library requires instances that re-use a shape to be added after eachother
btAlignedObjectArray<btCollisionObject*> sortedObjects;
sortedObjects.reserve(rbWorld->getNumCollisionObjects());
for (int i=0;i<rbWorld->getNumCollisionObjects();i++)
{
btCollisionObject* colObj = rbWorld->getCollisionObjectArray()[i];
sortedObjects.push_back(colObj);
}
sortedObjects.quickSort(shapePointerCompareFunc);
for (int i=0;i<sortedObjects.size();i++)
{
btCollisionObject* colObj = sortedObjects[i];
//btRigidBody* body = btRigidBody::upcast(colObj);
//does this also work for btMultiBody/btMultiBodyLinkCollider?
createCollisionShapeGraphicsObject(colObj->getCollisionShape());
btVector3 color= selectColor();
createCollisionObjectGraphicsObject(colObj,color);
}
}
void OpenGLGuiHelper::drawText3D( const char* txt, float posX, float posY, float posZ, float size)
{
btAssert(m_data->m_glApp);
m_data->m_glApp->drawText3D(txt,posX,posY,posZ,size);
}
struct CommonGraphicsApp* OpenGLGuiHelper::getAppInterface()
{
return m_data->m_glApp;
}

View File

@@ -0,0 +1,52 @@
#ifndef OPENGL_GUI_HELPER_H
#define OPENGL_GUI_HELPER_H
#include "GUIHelperInterface.h"
class btCollisionShape;
class btTransform;
#include "LinearMath/btAlignedObjectArray.h"
struct OpenGLGuiHelper : public GUIHelperInterface
{
struct OpenGLGuiHelperInternalData* m_data;
OpenGLGuiHelper(struct CommonGraphicsApp* glApp);
virtual ~OpenGLGuiHelper();
virtual struct CommonRenderInterface* getRenderInterface();
virtual void createRigidBodyGraphicsObject(btRigidBody* body, const btVector3& color);
virtual void createCollisionObjectGraphicsObject(btCollisionObject* body, const btVector3& color);
virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices);
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling);
virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape);
virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld);
virtual void createPhysicsDebugDrawer(btDiscreteDynamicsWorld* rbWorld);
virtual struct Common2dCanvasInterface* get2dCanvasInterface();
virtual CommonParameterInterface* getParameterInterface();
virtual struct CommonGraphicsApp* getAppInterface();
virtual void setUpAxis(int axis);
btVector3 selectColor();
virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld) ;
virtual void drawText3D( const char* txt, float posX, float posY, float posZ, float size);
};
#endif //OPENGL_GUI_HELPER_H

View File

@@ -0,0 +1,39 @@
//#define EXAMPLE_CONSOLE_ONLY
#ifdef EXAMPLE_CONSOLE_ONLY
#include "EmptyBrowser.h"
typedef EmptyBrowser DefaultBrowser;
#else
#include "OpenGLExampleBrowser.h"
typedef OpenGLExampleBrowser DefaultBrowser;
#endif //EXAMPLE_CONSOLE_ONLY
#include "Bullet3Common/b3CommandLineArgs.h"
#include "../Utils/b3Clock.h"
#include "ExampleEntries.h"
int main(int argc, char* argv[])
{
b3CommandLineArgs args(argc,argv);
b3Clock clock;
ExampleEntries examples;
examples.initExampleEntries();
ExampleBrowserInterface* exampleBrowser = new DefaultBrowser(&examples);
bool init = exampleBrowser->init(argc,argv);
if (init)
{
do
{
float deltaTimeInSeconds = 1./120.f;
exampleBrowser->update(deltaTimeInSeconds);
} while (!exampleBrowser->requestedExit());
}
delete exampleBrowser;
return 0;
}

View File

@@ -0,0 +1,64 @@
project "App_ExampleBrowser"
language "C++"
kind "ConsoleApp"
includedirs {
".",
"../../src",
"../ThirdPartyLibs",
}
links{"gwen", "OpenGL_Window","BulletDynamics","BulletCollision","LinearMath","Bullet3Common"}
initOpenGL()
initGlew()
files {
"**.cpp",
"**.h",
"../BasicDemo/BasicExample.*",
"../Benchmarks/*",
"../CommonInterfaces/*",
"../ForkLift/ForkLiftDemo.*",
"../Importers/**",
"../Planar2D/Planar2D.*",
"../RenderingExamples/*",
"../ThirdPartyLibs/Wavefront/tiny_obj_loader.*",
"../ThirdPartyLibs/tinyxml/*",
"../Utils/b3Clock.*",
"../GyroscopicDemo/GyroscopicSetup.cpp",
"../GyroscopicDemo/GyroscopicSetup.h",
"../ThirdPartyLibs/urdf/urdfdom/urdf_parser/src/pose.cpp",
"../ThirdPartyLibs/urdf/urdfdom/urdf_parser/src/model.cpp",
"../ThirdPartyLibs/urdf/urdfdom/urdf_parser/src/link.cpp",
"../ThirdPartyLibs/urdf/urdfdom/urdf_parser/src/joint.cpp",
"../ThirdPartyLibs/urdf/urdfdom/urdf_parser/include/urdf_parser/urdf_parser.h",
"../ThirdPartyLibs/urdf/urdfdom_headers/urdf_exception/include/urdf_exception/exception.h",
"../ThirdPartyLibs/urdf/urdfdom_headers/urdf_model/include/urdf_model/pose.h",
"../ThirdPartyLibs/urdf/urdfdom_headers/urdf_model/include/urdf_model/model.h",
"../ThirdPartyLibs/urdf/urdfdom_headers/urdf_model/include/urdf_model/link.h",
"../ThirdPartyLibs/urdf/urdfdom_headers/urdf_model/include/urdf_model/joint.h",
"../ThirdPartyLibs/tinyxml/tinystr.cpp",
"../ThirdPartyLibs/tinyxml/tinyxml.cpp",
"../ThirdPartyLibs/tinyxml/tinyxmlerror.cpp",
"../ThirdPartyLibs/tinyxml/tinyxmlparser.cpp",
"../ThirdPartyLibs/urdf/boost_replacement/lexical_cast.h",
"../ThirdPartyLibs/urdf/boost_replacement/shared_ptr.h",
"../ThirdPartyLibs/urdf/boost_replacement/printf_console.cpp",
"../ThirdPartyLibs/urdf/boost_replacement/printf_console.h",
"../ThirdPartyLibs/urdf/boost_replacement/string_split.cpp",
"../ThirdPartyLibs/urdf/boost_replacement/string_split.h",
}
if os.is("Linux") then
initX11()
end
if os.is("MacOSX") then
links{"Cocoa.framework"}
end