Merge pull request #701 from erwincoumans/master

Remove many memory leaks/technical debt in example code.
This commit is contained in:
erwincoumans
2016-07-16 22:01:19 -07:00
committed by GitHub
35 changed files with 803 additions and 418 deletions

Binary file not shown.

View File

@@ -63,7 +63,7 @@ struct CommonMultiBodyBase : public CommonExampleInterface
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase(); m_broadphase = new btDbvtBroadphase();//btSimpleBroadphase();
m_solver = new btMultiBodyConstraintSolver; m_solver = new btMultiBodyConstraintSolver;
@@ -97,6 +97,20 @@ struct CommonMultiBodyBase : public CommonExampleInterface
{ {
m_dynamicsWorld->removeConstraint(m_dynamicsWorld->getConstraint(i)); m_dynamicsWorld->removeConstraint(m_dynamicsWorld->getConstraint(i));
} }
for (i = m_dynamicsWorld->getNumMultiBodyConstraints() - 1; i >= 0; i--)
{
btMultiBodyConstraint* mbc = m_dynamicsWorld->getMultiBodyConstraint(i);
m_dynamicsWorld->removeMultiBodyConstraint(mbc);
delete mbc;
}
for (i = m_dynamicsWorld->getNumMultibodies() - 1; i >= 0; i--)
{
btMultiBody* mb = m_dynamicsWorld->getMultiBody(i);
m_dynamicsWorld->removeMultiBody(mb);
delete mb;
}
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--) for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
{ {
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];

View File

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

View File

@@ -44,7 +44,7 @@ public:
CProfileIterator* profIter; CProfileIterator* profIter;
class MyMenuItems* m_menuItems;
MyProfileWindow ( Gwen::Controls::Base* pParent) MyProfileWindow ( Gwen::Controls::Base* pParent)
: Gwen::Controls::WindowControl( pParent ), : Gwen::Controls::WindowControl( pParent ),
profIter(0) profIter(0)
@@ -83,6 +83,12 @@ public:
} }
virtual ~MyProfileWindow()
{
delete m_node;
delete m_ctrl;
}
float dumpRecursive(CProfileIterator* profileIterator, Gwen::Controls::TreeNode* parentNode) float dumpRecursive(CProfileIterator* profileIterator, Gwen::Controls::TreeNode* parentNode)
{ {
@@ -266,11 +272,16 @@ public:
MyProfileWindow* setupProfileWindow(GwenInternalData* data) MyProfileWindow* setupProfileWindow(GwenInternalData* data)
{ {
MyMenuItems* menuItems = new MyMenuItems; MyMenuItems* menuItems = new MyMenuItems;
MyProfileWindow* profWindow = new MyProfileWindow(data->pCanvas); MyProfileWindow* profWindow = new MyProfileWindow(data->pCanvas);
//profWindow->SetHidden(true); //profWindow->SetHidden(true);
profWindow->profIter = CProfileManager::Get_Iterator();
profWindow->m_menuItems = menuItems;
//profWindow->profIter = CProfileManager::Get_Iterator();
data->m_viewMenu->GetMenu()->AddItem( L"Profiler", menuItems,(Gwen::Event::Handler::Function)&MyMenuItems::MenuItemSelect); data->m_viewMenu->GetMenu()->AddItem( L"Profiler", menuItems,(Gwen::Event::Handler::Function)&MyMenuItems::MenuItemSelect);
menuItems->m_profWindow = profWindow; menuItems->m_profWindow = profWindow;
return profWindow; return profWindow;
} }
@@ -290,5 +301,6 @@ void profileWindowSetVisible(MyProfileWindow* window, bool visible)
} }
void destroyProfileWindow(MyProfileWindow* window) void destroyProfileWindow(MyProfileWindow* window)
{ {
CProfileManager::Release_Iterator(window->profIter);
delete window; delete window;
} }

View File

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

View File

@@ -17,6 +17,83 @@ GwenUserInterface::GwenUserInterface()
} }
class MyMenuItems : public Gwen::Controls::Base
{
public:
b3FileOpenCallback m_fileOpenCallback;
b3QuitCallback m_quitCallback;
MyMenuItems() :Gwen::Controls::Base(0), m_fileOpenCallback(0)
{
}
void myQuitApp(Gwen::Controls::Base* pControl)
{
if (m_quitCallback)
{
(*m_quitCallback)();
}
}
void fileOpen(Gwen::Controls::Base* pControl)
{
if (m_fileOpenCallback)
{
(*m_fileOpenCallback)();
}
}
};
struct MyTestMenuBar : public Gwen::Controls::MenuStrip
{
Gwen::Controls::MenuItem* m_fileMenu;
Gwen::Controls::MenuItem* m_viewMenu;
MyMenuItems* m_menuItems;
MyTestMenuBar(Gwen::Controls::Base* pParent)
:Gwen::Controls::MenuStrip(pParent)
{
// Gwen::Controls::MenuStrip* menu = new Gwen::Controls::MenuStrip( pParent );
{
m_menuItems = new MyMenuItems();
m_menuItems->m_fileOpenCallback = 0;
m_menuItems->m_quitCallback = 0;
m_fileMenu = AddItem(L"File");
m_fileMenu->GetMenu()->AddItem(L"Open", m_menuItems, (Gwen::Event::Handler::Function)&MyMenuItems::fileOpen);
m_fileMenu->GetMenu()->AddItem(L"Quit", m_menuItems, (Gwen::Event::Handler::Function)&MyMenuItems::myQuitApp);
m_viewMenu = AddItem(L"View");
}
}
virtual ~MyTestMenuBar()
{
delete m_menuItems;
}
};
void GwenUserInterface::exit()
{
//m_data->m_menubar->RemoveAllChildren();
delete m_data->m_tab;
delete m_data->m_windowRight;
delete m_data->m_leftStatusBar;
delete m_data->m_TextOutput;
delete m_data->m_rightStatusBar;
delete m_data->m_bar;
delete m_data->m_menubar;
m_data->m_menubar = 0;
delete m_data->pCanvas;
m_data->pCanvas = 0;
}
GwenUserInterface::~GwenUserInterface() GwenUserInterface::~GwenUserInterface()
{ {
for (int i=0;i<m_data->m_handlers.size();i++) for (int i=0;i<m_data->m_handlers.size();i++)
@@ -27,71 +104,14 @@ GwenUserInterface::~GwenUserInterface()
m_data->m_handlers.clear(); m_data->m_handlers.clear();
delete m_data->pCanvas;
delete m_data; delete m_data;
} }
class MyMenuItems : public Gwen::Controls::Base
{
public:
b3FileOpenCallback m_fileOpenCallback;
b3QuitCallback m_quitCallback;
MyMenuItems() :Gwen::Controls::Base(0),m_fileOpenCallback(0)
{
}
void myQuitApp( Gwen::Controls::Base* pControl )
{
if (m_quitCallback)
{
(*m_quitCallback)();
}
}
void fileOpen( Gwen::Controls::Base* pControl )
{
if (m_fileOpenCallback)
{
(*m_fileOpenCallback)();
}
}
};
struct MyTestMenuBar : public Gwen::Controls::MenuStrip
{
Gwen::Controls::MenuItem* m_fileMenu;
Gwen::Controls::MenuItem* m_viewMenu;
MyMenuItems* m_menuItems;
MyTestMenuBar(Gwen::Controls::Base* pParent)
:Gwen::Controls::MenuStrip(pParent)
{
// Gwen::Controls::MenuStrip* menu = new Gwen::Controls::MenuStrip( pParent );
{
m_menuItems = new MyMenuItems();
m_menuItems->m_fileOpenCallback = 0;
m_menuItems->m_quitCallback = 0;
m_fileMenu = AddItem( L"File" );
m_fileMenu->GetMenu()->AddItem(L"Open",m_menuItems,(Gwen::Event::Handler::Function)&MyMenuItems::fileOpen);
m_fileMenu->GetMenu()->AddItem(L"Quit",m_menuItems,(Gwen::Event::Handler::Function)&MyMenuItems::myQuitApp);
m_viewMenu = AddItem( L"View" );
}
}
};
void GwenUserInterface::resize(int width, int height) void GwenUserInterface::resize(int width, int height)
{ {
@@ -232,6 +252,7 @@ void GwenUserInterface::setStatusBarMessage(const char* message, bool isLeft)
} }
} }
void GwenUserInterface::registerFileOpenCallback(b3FileOpenCallback callback) void GwenUserInterface::registerFileOpenCallback(b3FileOpenCallback callback)
{ {
m_data->m_menuItems->m_fileOpenCallback = callback; m_data->m_menuItems->m_fileOpenCallback = callback;
@@ -250,6 +271,7 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere
m_data->skin.SetRender( m_data->pRenderer ); m_data->skin.SetRender( m_data->pRenderer );
m_data->pCanvas= new Gwen::Controls::Canvas( &m_data->skin ); m_data->pCanvas= new Gwen::Controls::Canvas( &m_data->skin );
m_data->pCanvas->SetSize( width,height); m_data->pCanvas->SetSize( width,height);
m_data->pCanvas->SetDrawBackground( false); m_data->pCanvas->SetDrawBackground( false);
@@ -260,24 +282,31 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere
MyTestMenuBar* menubar = new MyTestMenuBar(m_data->pCanvas); MyTestMenuBar* menubar = new MyTestMenuBar(m_data->pCanvas);
m_data->m_viewMenu = menubar->m_viewMenu; m_data->m_viewMenu = menubar->m_viewMenu;
m_data->m_menuItems = menubar->m_menuItems; m_data->m_menuItems = menubar->m_menuItems;
m_data->m_menubar = menubar;
Gwen::Controls::StatusBar* bar = new Gwen::Controls::StatusBar(m_data->pCanvas); Gwen::Controls::StatusBar* bar = new Gwen::Controls::StatusBar(m_data->pCanvas);
m_data->m_bar = bar;
m_data->m_rightStatusBar = new Gwen::Controls::Label( bar ); m_data->m_rightStatusBar = new Gwen::Controls::Label( bar );
m_data->m_rightStatusBar->SetWidth(width/2); m_data->m_rightStatusBar->SetWidth(width/2);
//m_data->m_rightStatusBar->SetText( L"Label Added to Right" ); //m_data->m_rightStatusBar->SetText( L"Label Added to Right" );
bar->AddControl( m_data->m_rightStatusBar, true ); bar->AddControl( m_data->m_rightStatusBar, true );
m_data->m_TextOutput = new Gwen::Controls::ListBox( m_data->pCanvas ); m_data->m_TextOutput = new Gwen::Controls::ListBox( m_data->pCanvas );
m_data->m_TextOutput->Dock( Gwen::Pos::Bottom ); m_data->m_TextOutput->Dock( Gwen::Pos::Bottom );
m_data->m_TextOutput->SetHeight( 100 ); m_data->m_TextOutput->SetHeight( 100 );
m_data->m_leftStatusBar = new Gwen::Controls::Label( bar ); m_data->m_leftStatusBar = new Gwen::Controls::Label( bar );
//m_data->m_leftStatusBar->SetText( L"Label Added to Left" ); //m_data->m_leftStatusBar->SetText( L"Label Added to Left" );
m_data->m_leftStatusBar->SetWidth(width/2); m_data->m_leftStatusBar->SetWidth(width/2);
bar->AddControl( m_data->m_leftStatusBar,false); bar->AddControl( m_data->m_leftStatusBar,false);
//Gwen::KeyboardFocus //Gwen::KeyboardFocus
/*Gwen::Controls::GroupBox* box = new Gwen::Controls::GroupBox(m_data->pCanvas); /*Gwen::Controls::GroupBox* box = new Gwen::Controls::GroupBox(m_data->pCanvas);
box->SetText("text"); box->SetText("text");
@@ -289,11 +318,14 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere
windowRight->SetWidth(250); windowRight->SetWidth(250);
windowRight->SetHeight(250); windowRight->SetHeight(250);
windowRight->SetScroll(false,true); windowRight->SetScroll(false,true);
m_data->m_windowRight = windowRight;
//windowLeft->SetSkin( //windowLeft->SetSkin(
Gwen::Controls::TabControl* tab = new Gwen::Controls::TabControl(windowRight); Gwen::Controls::TabControl* tab = new Gwen::Controls::TabControl(windowRight);
m_data->m_tab = tab;
//tab->SetHeight(300); //tab->SetHeight(300);
tab->SetWidth(240); tab->SetWidth(240);
@@ -308,6 +340,7 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere
// Gwen::UnicodeString str2(L"OpenCL"); // Gwen::UnicodeString str2(L"OpenCL");
// tab->AddPage(str2); // tab->AddPage(str2);
//Gwen::UnicodeString str3(L"page3"); //Gwen::UnicodeString str3(L"page3");
@@ -389,7 +422,6 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere
m_data->m_exampleInfoTextOutput = new Gwen::Controls::ListBox(m_data->m_explorerPage->GetPage()); 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->Dock( Gwen::Pos::Bottom );
m_data->m_exampleInfoTextOutput->SetPos(2, 332); m_data->m_exampleInfoTextOutput->SetPos(2, 332);
m_data->m_exampleInfoTextOutput->SetHeight( 150 ); m_data->m_exampleInfoTextOutput->SetHeight( 150 );

View File

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

View File

@@ -42,19 +42,65 @@
#include "../Importers/ImportURDFDemo/ImportURDFSetup.h" #include "../Importers/ImportURDFDemo/ImportURDFSetup.h"
#include "../Importers/ImportBullet/SerializeSetup.h" #include "../Importers/ImportBullet/SerializeSetup.h"
#include "Bullet3Common/b3HashMap.h"
struct GL3TexLoader : public MyTextureLoader
{
b3HashMap<b3HashString, GLint> m_hashMap;
virtual void LoadTexture(Gwen::Texture* pTexture)
{
Gwen::String namestr = pTexture->name.Get();
const char* n = namestr.c_str();
GLint* texIdPtr = m_hashMap[n];
if (texIdPtr)
{
pTexture->m_intData = *texIdPtr;
}
}
virtual void FreeTexture(Gwen::Texture* pTexture)
{
}
};
struct OpenGLExampleBrowserInternalData
{
Gwen::Renderer::Base* m_gwenRenderer;
CommonGraphicsApp* m_app;
// MyProfileWindow* m_profWindow;
btAlignedObjectArray<Gwen::Controls::TreeNode*> m_nodes;
GwenUserInterface* m_gui;
GL3TexLoader* m_myTexLoader;
struct MyMenuItemHander* m_handler2;
btAlignedObjectArray<MyMenuItemHander*> m_handlers;
OpenGLExampleBrowserInternalData()
: m_gwenRenderer(0),
m_app(0),
// m_profWindow(0),
m_gui(0),
m_myTexLoader(0),
m_handler2(0)
{
}
};
static CommonGraphicsApp* s_app=0; static CommonGraphicsApp* s_app=0;
static CommonWindowInterface* s_window = 0; static CommonWindowInterface* s_window = 0;
static CommonParameterInterface* s_parameterInterface=0; static CommonParameterInterface* s_parameterInterface=0;
static CommonRenderInterface* s_instancingRenderer=0; static CommonRenderInterface* s_instancingRenderer=0;
static OpenGLGuiHelper* s_guiHelper=0; static OpenGLGuiHelper* s_guiHelper=0;
static MyProfileWindow* s_profWindow =0; //static MyProfileWindow* s_profWindow =0;
static SharedMemoryInterface* sSharedMem = 0; static SharedMemoryInterface* sSharedMem = 0;
#define DEMO_SELECTION_COMBOBOX 13 #define DEMO_SELECTION_COMBOBOX 13
const char* startFileName = "0_Bullet3Demo.txt"; const char* startFileName = "0_Bullet3Demo.txt";
char staticPngFileName[1024]; char staticPngFileName[1024];
static GwenUserInterface* gui = 0; //static GwenUserInterface* gui = 0;
static GwenUserInterface* gui2 = 0;
static int sCurrentDemoIndex = -1; static int sCurrentDemoIndex = -1;
static int sCurrentHightlighted = 0; static int sCurrentHightlighted = 0;
static CommonExampleInterface* sCurrentDemo = 0; static CommonExampleInterface* sCurrentDemo = 0;
@@ -123,9 +169,9 @@ void MyKeyboardCallback(int key, int state)
//b3Printf("key=%d, state=%d", key, state); //b3Printf("key=%d, state=%d", key, state);
bool handled = false; bool handled = false;
if (gui && !handled ) if (gui2 && !handled )
{ {
handled = gui->keyboardCallback(key, state); handled = gui2->keyboardCallback(key, state);
} }
if (!handled && sCurrentDemo) if (!handled && sCurrentDemo)
@@ -226,8 +272,8 @@ static void MyMouseMoveCallback( float x, float y)
bool handled = false; bool handled = false;
if (sCurrentDemo) if (sCurrentDemo)
handled = sCurrentDemo->mouseMoveCallback(x,y); handled = sCurrentDemo->mouseMoveCallback(x,y);
if (!handled && gui) if (!handled && gui2)
handled = gui->mouseMoveCallback(x,y); handled = gui2->mouseMoveCallback(x,y);
if (!handled) if (!handled)
{ {
if (prevMouseMoveCallback) if (prevMouseMoveCallback)
@@ -244,8 +290,8 @@ static void MyMouseButtonCallback(int button, int state, float x, float y)
if (sCurrentDemo) if (sCurrentDemo)
handled = sCurrentDemo->mouseButtonCallback(button,state,x,y); handled = sCurrentDemo->mouseButtonCallback(button,state,x,y);
if (!handled && gui) if (!handled && gui2)
handled = gui->mouseButtonCallback(button,state,x,y); handled = gui2->mouseButtonCallback(button,state,x,y);
if (!handled) if (!handled)
{ {
@@ -333,7 +379,10 @@ void selectDemo(int demoIndex)
CommonExampleInterface::CreateFunc* func = gAllExamples->getExampleCreateFunc(demoIndex); CommonExampleInterface::CreateFunc* func = gAllExamples->getExampleCreateFunc(demoIndex);
if (func) if (func)
{ {
s_parameterInterface->removeAllParameters(); if (s_parameterInterface)
{
s_parameterInterface->removeAllParameters();
}
int option = gAllExamples->getExampleOption(demoIndex); int option = gAllExamples->getExampleOption(demoIndex);
s_guiHelper= new OpenGLGuiHelper(s_app, sUseOpenGL2); s_guiHelper= new OpenGLGuiHelper(s_app, sUseOpenGL2);
CommonExampleOptions options(s_guiHelper, option); CommonExampleOptions options(s_guiHelper, option);
@@ -341,12 +390,15 @@ void selectDemo(int demoIndex)
sCurrentDemo = (*func)(options); sCurrentDemo = (*func)(options);
if (sCurrentDemo) if (sCurrentDemo)
{ {
if (gui) if (gui2)
{ {
gui->setStatusBarMessage("Status: OK", false); gui2->setStatusBarMessage("Status: OK", false);
} }
b3Printf("Selected demo: %s",gAllExamples->getExampleName(demoIndex)); b3Printf("Selected demo: %s",gAllExamples->getExampleName(demoIndex));
gui->setExampleDescription(gAllExamples->getExampleDescription(demoIndex)); if (gui2)
{
gui2->setExampleDescription(gAllExamples->getExampleDescription(demoIndex));
}
sCurrentDemo->initPhysics(); sCurrentDemo->initPhysics();
if(resetCamera) if(resetCamera)
@@ -437,10 +489,10 @@ void MyComboBoxCallback(int comboId, const char* item)
void MyGuiPrintf(const char* msg) void MyGuiPrintf(const char* msg)
{ {
printf("b3Printf: %s\n",msg); printf("b3Printf: %s\n",msg);
if (gui) if (gui2)
{ {
gui->textOutput(msg); gui2->textOutput(msg);
gui->forceUpdateScrollBars(); gui2->forceUpdateScrollBars();
} }
} }
@@ -449,10 +501,10 @@ void MyGuiPrintf(const char* msg)
void MyStatusBarPrintf(const char* msg) void MyStatusBarPrintf(const char* msg)
{ {
printf("b3Printf: %s\n", msg); printf("b3Printf: %s\n", msg);
if (gui) if (gui2)
{ {
bool isLeft = true; bool isLeft = true;
gui->setStatusBarMessage(msg,isLeft); gui2->setStatusBarMessage(msg,isLeft);
} }
} }
@@ -460,12 +512,12 @@ void MyStatusBarPrintf(const char* msg)
void MyStatusBarError(const char* msg) void MyStatusBarError(const char* msg)
{ {
printf("Warning: %s\n", msg); printf("Warning: %s\n", msg);
if (gui) if (gui2)
{ {
bool isLeft = false; bool isLeft = false;
gui->setStatusBarMessage(msg,isLeft); gui2->setStatusBarMessage(msg,isLeft);
gui->textOutput(msg); gui2->textOutput(msg);
gui->forceUpdateScrollBars(); gui2->forceUpdateScrollBars();
} }
} }
@@ -534,7 +586,7 @@ struct MyMenuItemHander :public Gwen::Event::Handler
{ {
// printf("select %d\n",m_buttonId); // printf("select %d\n",m_buttonId);
sCurrentHightlighted = m_buttonId; sCurrentHightlighted = m_buttonId;
gui->setExampleDescription(gAllExamples->getExampleDescription(sCurrentHightlighted)); gui2->setExampleDescription(gAllExamples->getExampleDescription(sCurrentHightlighted));
} }
void onButtonF(Gwen::Controls::Base* pControl) void onButtonF(Gwen::Controls::Base* pControl)
@@ -549,26 +601,6 @@ struct MyMenuItemHander :public Gwen::Event::Handler
};
#include "Bullet3Common/b3HashMap.h"
struct GL3TexLoader : public MyTextureLoader
{
b3HashMap<b3HashString,GLint> m_hashMap;
virtual void LoadTexture( Gwen::Texture* pTexture )
{
Gwen::String namestr = pTexture->name.Get();
const char* n = namestr.c_str();
GLint* texIdPtr = m_hashMap[n];
if (texIdPtr)
{
pTexture->m_intData = *texIdPtr;
}
}
virtual void FreeTexture( Gwen::Texture* pTexture )
{
}
}; };
void quitCallback() void quitCallback()
@@ -623,7 +655,7 @@ struct QuickCanvas : public Common2dCanvasInterface
m_curNumGraphWindows++; m_curNumGraphWindows++;
MyGraphInput input(gui->getInternalData()); MyGraphInput input(gui2->getInternalData());
input.m_width=width; input.m_width=width;
input.m_height=height; input.m_height=height;
input.m_xPos = 10000;//GUI will clamp it to the right//300; input.m_xPos = 10000;//GUI will clamp it to the right//300;
@@ -643,7 +675,10 @@ struct QuickCanvas : public Common2dCanvasInterface
virtual void destroyCanvas(int canvasId) virtual void destroyCanvas(int canvasId)
{ {
btAssert(canvasId>=0); btAssert(canvasId>=0);
delete m_gt[canvasId];
m_gt[canvasId] = 0;
destroyTextureWindow(m_gw[canvasId]); destroyTextureWindow(m_gw[canvasId]);
m_gw[canvasId] = 0;
m_curNumGraphWindows--; m_curNumGraphWindows--;
} }
virtual void setPixel(int canvasId, int x, int y, unsigned char red, unsigned char green,unsigned char blue, unsigned char alpha) virtual void setPixel(int canvasId, int x, int y, unsigned char red, unsigned char green,unsigned char blue, unsigned char alpha)
@@ -669,12 +704,51 @@ struct QuickCanvas : public Common2dCanvasInterface
OpenGLExampleBrowser::OpenGLExampleBrowser(class ExampleEntries* examples) OpenGLExampleBrowser::OpenGLExampleBrowser(class ExampleEntries* examples)
{ {
m_internalData = new OpenGLExampleBrowserInternalData;
gAllExamples = examples; gAllExamples = examples;
} }
OpenGLExampleBrowser::~OpenGLExampleBrowser() OpenGLExampleBrowser::~OpenGLExampleBrowser()
{ {
deleteDemo(); deleteDemo();
for (int i = 0; i < m_internalData->m_nodes.size(); i++)
{
delete m_internalData->m_nodes[i];
}
delete m_internalData->m_handler2;
for (int i = 0; i < m_internalData->m_handlers.size(); i++)
{
delete m_internalData->m_handlers[i];
}
m_internalData->m_handlers.clear();
m_internalData->m_nodes.clear();
delete s_parameterInterface;
s_parameterInterface = 0;
delete s_app->m_2dCanvasInterface;
s_app->m_2dCanvasInterface = 0;
m_internalData->m_gui->exit();
delete m_internalData->m_gui;
delete m_internalData->m_gwenRenderer;
delete m_internalData->m_myTexLoader;
delete m_internalData->m_app;
s_app = 0;
// delete m_internalData->m_profWindow;
delete m_internalData;
gFileImporterByExtension.clear();
gAllExamples = 0; gAllExamples = 0;
} }
@@ -732,11 +806,10 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
char title[1024]; char title[1024];
sprintf(title,"%s using OpenGL3+. %s", appTitle,optMode); sprintf(title,"%s using OpenGL3+. %s", appTitle,optMode);
simpleApp = new SimpleOpenGL3App(title,width,height, gAllowRetina); simpleApp = new SimpleOpenGL3App(title,width,height, gAllowRetina);
s_app = simpleApp; s_app = simpleApp;
} }
#endif #endif
m_internalData->m_app = s_app;
char* gVideoFileName = 0; char* gVideoFileName = 0;
args.GetCmdLineArgument("mp4",gVideoFileName); args.GetCmdLineArgument("mp4",gVideoFileName);
#ifndef NO_OPENGL3 #ifndef NO_OPENGL3
@@ -792,42 +865,66 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
assert(glGetError()==GL_NO_ERROR); assert(glGetError()==GL_NO_ERROR);
{
GL3TexLoader* myTexLoader = new GL3TexLoader;
m_internalData->m_myTexLoader = myTexLoader;
gui = new GwenUserInterface; sth_stash* fontstash = simpleApp->getFontStash();
GL3TexLoader* myTexLoader = new GL3TexLoader;
Gwen::Renderer::Base* gwenRenderer = 0; if (sUseOpenGL2)
if (sUseOpenGL2 ) {
{ m_internalData->m_gwenRenderer = new Gwen::Renderer::OpenGL_DebugFont();
gwenRenderer = new Gwen::Renderer::OpenGL_DebugFont(); }
}
#ifndef NO_OPENGL3 #ifndef NO_OPENGL3
else else
{ {
sth_stash* fontstash=simpleApp->getFontStash(); sth_stash* fontstash = simpleApp->getFontStash();
gwenRenderer = new GwenOpenGL3CoreRenderer(simpleApp->m_primRenderer,fontstash,width,height,s_window->getRetinaScale(),myTexLoader); m_internalData->m_gwenRenderer = new GwenOpenGL3CoreRenderer(simpleApp->m_primRenderer, fontstash, width, height, s_window->getRetinaScale(), myTexLoader);
} }
#endif #endif
gui2 = new GwenUserInterface;
m_internalData->m_gui = gui2;
m_internalData->m_myTexLoader = myTexLoader;
gui2->init(width, height, m_internalData->m_gwenRenderer, s_window->getRetinaScale());
}
//gui = 0;// new GwenUserInterface;
GL3TexLoader* myTexLoader = m_internalData->m_myTexLoader;
// = myTexLoader;
// //
gui->init(width,height,gwenRenderer,s_window->getRetinaScale()); if (gui2)
{
// gui->getInternalData()->m_explorerPage
Gwen::Controls::TreeControl* tree = gui->getInternalData()->m_explorerTreeCtrl; // gui->getInternalData()->m_explorerPage
Gwen::Controls::TreeControl* tree = gui2->getInternalData()->m_explorerTreeCtrl;
//gui->getInternalData()->pRenderer->setTextureLoader(myTexLoader); //gui->getInternalData()->pRenderer->setTextureLoader(myTexLoader);
s_profWindow= setupProfileWindow(gui->getInternalData()); // s_profWindow= setupProfileWindow(gui2->getInternalData());
profileWindowSetVisible(s_profWindow,false); //m_internalData->m_profWindow = s_profWindow;
gui->setFocus(); // profileWindowSetVisible(s_profWindow,false);
gui2->setFocus();
s_parameterInterface = s_app->m_parameterInterface = new GwenParameterInterface(gui->getInternalData()); s_parameterInterface = s_app->m_parameterInterface = new GwenParameterInterface(gui2->getInternalData());
s_app->m_2dCanvasInterface = new QuickCanvas(myTexLoader); s_app->m_2dCanvasInterface = new QuickCanvas(myTexLoader);
///add some demos to the gAllExamples ///add some demos to the gAllExamples
@@ -839,7 +936,7 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
//int curDemo = 0; //int curDemo = 0;
int selectedDemo = 0; int selectedDemo = 0;
Gwen::Controls::TreeNode* curNode = tree; Gwen::Controls::TreeNode* curNode = tree;
MyMenuItemHander* handler2 = new MyMenuItemHander(-1); m_internalData->m_handler2 = new MyMenuItemHander(-1);
char* demoNameFromCommandOption = 0; char* demoNameFromCommandOption = 0;
args.GetCmdLineArgument("start_demo_name", demoNameFromCommandOption); args.GetCmdLineArgument("start_demo_name", demoNameFromCommandOption);
@@ -847,7 +944,7 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
selectedDemo = -1; selectedDemo = -1;
} }
tree->onReturnKeyDown.Add(handler2, &MyMenuItemHander::onButtonD); tree->onReturnKeyDown.Add(m_internalData->m_handler2, &MyMenuItemHander::onButtonD);
int firstAvailableDemoIndex=-1; int firstAvailableDemoIndex=-1;
Gwen::Controls::TreeNode* firstNode=0; Gwen::Controls::TreeNode* firstNode=0;
@@ -894,13 +991,18 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
} }
} }
#if 1
MyMenuItemHander* handler = new MyMenuItemHander(d); MyMenuItemHander* handler = new MyMenuItemHander(d);
m_internalData->m_handlers.push_back(handler);
pNode->onNamePress.Add(handler, &MyMenuItemHander::onButtonA); pNode->onNamePress.Add(handler, &MyMenuItemHander::onButtonA);
pNode->GetButton()->onDoubleClick.Add(handler, &MyMenuItemHander::onButtonB); pNode->GetButton()->onDoubleClick.Add(handler, &MyMenuItemHander::onButtonB);
pNode->GetButton()->onDown.Add(handler, &MyMenuItemHander::onButtonC); pNode->GetButton()->onDown.Add(handler, &MyMenuItemHander::onButtonC);
pNode->onSelect.Add(handler, &MyMenuItemHander::onButtonE); pNode->onSelect.Add(handler, &MyMenuItemHander::onButtonE);
pNode->onReturnKeyDown.Add(handler, &MyMenuItemHander::onButtonG); pNode->onReturnKeyDown.Add(handler, &MyMenuItemHander::onButtonG);
pNode->onSelectChange.Add(handler, &MyMenuItemHander::onButtonF); pNode->onSelectChange.Add(handler, &MyMenuItemHander::onButtonF);
#endif
// pNode->onKeyReturn.Add(handler, &MyMenuItemHander::onButtonD); // pNode->onKeyReturn.Add(handler, &MyMenuItemHander::onButtonD);
// pNode->GetButton()->onKeyboardReturn.Add(handler, &MyMenuItemHander::onButtonD); // pNode->GetButton()->onKeyboardReturn.Add(handler, &MyMenuItemHander::onButtonD);
// pNode->onNamePress.Add(handler, &MyMenuItemHander::onButtonD); // pNode->onNamePress.Add(handler, &MyMenuItemHander::onButtonD);
@@ -910,6 +1012,7 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
else else
{ {
curNode = tree->AddNode(nodeUText); curNode = tree->AddNode(nodeUText);
m_internalData->m_nodes.push_back(curNode);
} }
} }
@@ -928,6 +1031,9 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
} }
} }
free(demoNameFromCommandOption);
demoNameFromCommandOption = 0;
btAssert(sCurrentDemo!=0); btAssert(sCurrentDemo!=0);
if (sCurrentDemo==0) if (sCurrentDemo==0)
{ {
@@ -935,8 +1041,10 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
exit(0); exit(0);
} }
gui->registerFileOpenCallback(fileOpenCallback); gui2->registerFileOpenCallback(fileOpenCallback);
gui->registerQuitCallback(quitCallback); gui2->registerQuitCallback(quitCallback);
}
return true; return true;
} }
@@ -1044,7 +1152,7 @@ void OpenGLExampleBrowser::update(float deltaTime)
{ {
if (s_guiHelper && s_guiHelper->getRenderInterface() && s_guiHelper->getRenderInterface()->getActiveCamera()) if (gui2 && s_guiHelper && s_guiHelper->getRenderInterface() && s_guiHelper->getRenderInterface()->getActiveCamera())
{ {
char msg[1024]; char msg[1024];
float camDist = s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraDistance(); float camDist = s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraDistance();
@@ -1053,7 +1161,7 @@ void OpenGLExampleBrowser::update(float deltaTime)
float camTarget[3]; float camTarget[3];
s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraTargetPosition(camTarget); s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraTargetPosition(camTarget);
sprintf(msg,"dist=%f, pitch=%f, yaw=%f,target=%f,%f,%f", camDist,pitch,yaw,camTarget[0],camTarget[1],camTarget[2]); sprintf(msg,"dist=%f, pitch=%f, yaw=%f,target=%f,%f,%f", camDist,pitch,yaw,camTarget[0],camTarget[1],camTarget[2]);
gui->setStatusBarMessage(msg, true); gui2->setStatusBarMessage(msg, true);
} }
} }
@@ -1061,16 +1169,24 @@ void OpenGLExampleBrowser::update(float deltaTime)
static int toggle = 1; static int toggle = 1;
if (renderGui) if (renderGui)
{ {
if (!pauseSimulation) // if (!pauseSimulation)
processProfileData(s_profWindow,false); // processProfileData(s_profWindow,false);
if (sUseOpenGL2) if (sUseOpenGL2)
{ {
saveOpenGLState(s_instancingRenderer->getScreenWidth(),s_instancingRenderer->getScreenHeight()); saveOpenGLState(s_instancingRenderer->getScreenWidth(), s_instancingRenderer->getScreenHeight());
} }
BT_PROFILE("Draw Gwen GUI"); BT_PROFILE("Draw Gwen GUI");
gui->draw(s_instancingRenderer->getScreenWidth(),s_instancingRenderer->getScreenHeight()); if (m_internalData->m_gui)
{
m_internalData->m_gui->draw(s_instancingRenderer->getScreenWidth(), s_instancingRenderer->getScreenHeight());
}
if (gui2)
{
gui2->draw(s_instancingRenderer->getScreenWidth(), s_instancingRenderer->getScreenHeight());
}
if (sUseOpenGL2) if (sUseOpenGL2)
{ {
restoreOpenGLState(); restoreOpenGLState();
@@ -1084,14 +1200,20 @@ void OpenGLExampleBrowser::update(float deltaTime)
toggle=1-toggle; toggle=1-toggle;
{ {
BT_PROFILE("Sync Parameters"); BT_PROFILE("Sync Parameters");
s_parameterInterface->syncParameters(); if (s_parameterInterface)
{
s_parameterInterface->syncParameters();
}
} }
{ {
BT_PROFILE("Swap Buffers"); BT_PROFILE("Swap Buffers");
s_app->swapBuffer(); s_app->swapBuffer();
} }
gui->forceUpdateScrollBars(); if (gui2)
{
gui2->forceUpdateScrollBars();
}
} }

View File

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

View File

@@ -167,6 +167,7 @@ OpenGLGuiHelper::OpenGLGuiHelper(CommonGraphicsApp* glApp, bool useOpenGL2)
OpenGLGuiHelper::~OpenGLGuiHelper() OpenGLGuiHelper::~OpenGLGuiHelper()
{ {
delete m_data->m_debugDraw;
delete m_data->m_gl2ShapeDrawer; delete m_data->m_gl2ShapeDrawer;
delete m_data; delete m_data;
} }

View File

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

View File

@@ -1058,13 +1058,14 @@ btCollisionShape* BulletURDFImporter::getAllocatedCollisionShape(int index)
{ {
const UrdfCollision& col = link->m_collisionArray[v]; const UrdfCollision& col = link->m_collisionArray[v];
btCollisionShape* childShape = convertURDFToCollisionShape(&col ,pathPrefix); btCollisionShape* childShape = convertURDFToCollisionShape(&col ,pathPrefix);
m_data->m_allocatedCollisionShapes.push_back(childShape);
if (childShape) if (childShape)
{ {
btTransform childTrans = col.m_linkLocalFrame; btTransform childTrans = col.m_linkLocalFrame;
compoundShape->addChildShape(localInertiaFrame.inverse()*childTrans,childShape); compoundShape->addChildShape(localInertiaFrame.inverse()*childTrans,childShape);
} }
} }
} }

View File

@@ -207,7 +207,7 @@ void ImportUrdfSetup::initPhysics()
BulletURDFImporter u2b(m_guiHelper, 0); BulletURDFImporter u2b(m_guiHelper, 0);
bool loadOk = u2b.loadURDF(m_fileName); bool loadOk = u2b.loadURDF(m_fileName);
#ifdef TEST_MULTIBODY_SERIALIZATION #ifdef TEST_MULTIBODY_SERIALIZATION
//test to serialize a multibody to disk or shared memory, with base, link and joint names //test to serialize a multibody to disk or shared memory, with base, link and joint names
@@ -238,6 +238,10 @@ void ImportUrdfSetup::initPhysics()
m_data->m_rb = creation.getRigidBody(); m_data->m_rb = creation.getRigidBody();
m_data->m_mb = creation.getBulletMultiBody(); m_data->m_mb = creation.getBulletMultiBody();
btMultiBody* mb = m_data->m_mb; btMultiBody* mb = m_data->m_mb;
for (int i = 0; i < u2b.getNumAllocatedCollisionShapes(); i++)
{
m_collisionShapes.push_back(u2b.getAllocatedCollisionShape(i));
}
if (m_useMultiBody && mb ) if (m_useMultiBody && mb )
{ {
@@ -348,6 +352,7 @@ void ImportUrdfSetup::initPhysics()
btVector3 groundHalfExtents(20,20,20); btVector3 groundHalfExtents(20,20,20);
groundHalfExtents[upAxis]=1.f; groundHalfExtents[upAxis]=1.f;
btBoxShape* box = new btBoxShape(groundHalfExtents); btBoxShape* box = new btBoxShape(groundHalfExtents);
m_collisionShapes.push_back(box);
box->initializePolyhedralFeatures(); box->initializePolyhedralFeatures();
m_guiHelper->createCollisionShapeGraphicsObject(box); m_guiHelper->createCollisionShapeGraphicsObject(box);

View File

@@ -61,7 +61,9 @@ static bool parseVector4(btVector4& vec4, const std::string& vector_str)
vec4.setZero(); vec4.setZero();
btArray<std::string> pieces; btArray<std::string> pieces;
btArray<float> rgba; btArray<float> rgba;
urdfStringSplit(pieces, vector_str, urdfIsAnyOf(" ")); btAlignedObjectArray<std::string> strArray;
urdfIsAnyOf(" ", strArray);
urdfStringSplit(pieces, vector_str, strArray);
for (int i = 0; i < pieces.size(); ++i) for (int i = 0; i < pieces.size(); ++i)
{ {
if (!pieces[i].empty()) if (!pieces[i].empty())
@@ -82,7 +84,9 @@ static bool parseVector3(btVector3& vec3, const std::string& vector_str, ErrorLo
vec3.setZero(); vec3.setZero();
btArray<std::string> pieces; btArray<std::string> pieces;
btArray<float> rgba; btArray<float> rgba;
urdfStringSplit(pieces, vector_str, urdfIsAnyOf(" ")); btAlignedObjectArray<std::string> strArray;
urdfIsAnyOf(" ", strArray);
urdfStringSplit(pieces, vector_str, strArray);
for (int i = 0; i < pieces.size(); ++i) for (int i = 0; i < pieces.size(); ++i)
{ {
if (!pieces[i].empty()) if (!pieces[i].empty())

View File

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

View File

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

View File

@@ -105,7 +105,7 @@ InverseDynamicsExample::InverseDynamicsExample(struct GUIHelperInterface* helper
InverseDynamicsExample::~InverseDynamicsExample() InverseDynamicsExample::~InverseDynamicsExample()
{ {
delete m_multiBody;
delete m_inverseModel; delete m_inverseModel;
delete m_timeSeriesCanvas; delete m_timeSeriesCanvas;
} }
@@ -166,6 +166,10 @@ void InverseDynamicsExample::initPhysics()
btTransform identityTrans; btTransform identityTrans;
identityTrans.setIdentity(); identityTrans.setIdentity();
ConvertURDF2Bullet(u2b,creation, identityTrans,m_dynamicsWorld,true,u2b.getPathPrefix()); ConvertURDF2Bullet(u2b,creation, identityTrans,m_dynamicsWorld,true,u2b.getPathPrefix());
for (int i = 0; i < u2b.getNumAllocatedCollisionShapes(); i++)
{
m_collisionShapes.push_back(u2b.getAllocatedCollisionShape(i));
}
m_multiBody = creation.getBulletMultiBody(); m_multiBody = creation.getBulletMultiBody();
if (m_multiBody) if (m_multiBody)
{ {

View File

@@ -650,9 +650,14 @@ void SimpleOpenGL3App::setBackgroundColor(float red, float green, float blue)
SimpleOpenGL3App::~SimpleOpenGL3App() SimpleOpenGL3App::~SimpleOpenGL3App()
{ {
delete m_primRenderer ;
delete m_instancingRenderer;
delete m_primRenderer ;
sth_delete(m_data->m_fontStash);
delete m_data->m_renderCallbacks;
TwDeleteDefaultFonts();
m_window->closeWindow(); m_window->closeWindow();
delete m_window; delete m_window;
delete m_data ; delete m_data ;
} }

View File

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

View File

@@ -31,6 +31,10 @@ struct UrdfLinkNameMapUtil
UrdfLinkNameMapUtil():m_mb(0),m_memSerializer(0) UrdfLinkNameMapUtil():m_mb(0),m_memSerializer(0)
{ {
} }
virtual ~UrdfLinkNameMapUtil()
{
delete m_memSerializer;
}
}; };
@@ -701,15 +705,6 @@ bool PhysicsServerCommandProcessor::loadSdf(const char* fileName, char* bufferSe
{ {
btCollisionShape* shape =u2b.getAllocatedCollisionShape(i); btCollisionShape* shape =u2b.getAllocatedCollisionShape(i);
m_data->m_collisionShapes.push_back(shape); m_data->m_collisionShapes.push_back(shape);
if (shape->isCompound())
{
btCompoundShape* compound = (btCompoundShape*) shape;
for (int childIndex=0;childIndex<compound->getNumChildShapes();childIndex++)
{
m_data->m_collisionShapes.push_back(compound->getChildShape(childIndex));
}
}
} }
btTransform rootTrans; btTransform rootTrans;
@@ -851,15 +846,6 @@ bool PhysicsServerCommandProcessor::loadUrdf(const char* fileName, const btVecto
{ {
btCollisionShape* shape =u2b.getAllocatedCollisionShape(i); btCollisionShape* shape =u2b.getAllocatedCollisionShape(i);
m_data->m_collisionShapes.push_back(shape); m_data->m_collisionShapes.push_back(shape);
if (shape->isCompound())
{
btCompoundShape* compound = (btCompoundShape*) shape;
for (int childIndex=0;childIndex<compound->getNumChildShapes();childIndex++)
{
m_data->m_collisionShapes.push_back(compound->getChildShape(childIndex));
}
}
} }
btMultiBody* mb = creation.getBulletMultiBody(); btMultiBody* mb = creation.getBulletMultiBody();

View File

@@ -78,7 +78,6 @@ PhysicsServerSharedMemory::PhysicsServerSharedMemory(SharedMemoryInterface* shar
} }
m_data->m_commandProcessor = new PhysicsServerCommandProcessor; m_data->m_commandProcessor = new PhysicsServerCommandProcessor;
m_data->m_commandProcessor ->createEmptyDynamicsWorld();
} }

View File

@@ -701,7 +701,16 @@ void TinyRendererVisualShapeConverter::copyCameraImageData(unsigned char* pixels
void TinyRendererVisualShapeConverter::resetAll() void TinyRendererVisualShapeConverter::resetAll()
{ {
//todo: free memory for (int i=0;i<m_data->m_swRenderInstances.size();i++)
{
TinyRendererObjectArray** ptrptr = m_data->m_swRenderInstances.getAtIndex(i);
if (ptrptr && *ptrptr)
{
TinyRendererObjectArray* ptr = *ptrptr;
delete ptr;
}
}
m_data->m_swRenderInstances.clear(); m_data->m_swRenderInstances.clear();
} }

View File

@@ -1,3 +1,6 @@
#include "OpenGLWindow/SimpleOpenGL3App.h" #include "OpenGLWindow/SimpleOpenGL3App.h"
#include "Bullet3Common/b3Quaternion.h" #include "Bullet3Common/b3Quaternion.h"
#include "Bullet3Common/b3CommandLineArgs.h" #include "Bullet3Common/b3CommandLineArgs.h"
@@ -58,98 +61,103 @@ void MyKeyboardCallback(int keycode, int state)
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
b3CommandLineArgs myArgs(argc,argv);
SimpleOpenGL3App* app = new SimpleOpenGL3App("SimpleOpenGL3App",gWidth,gHeight,true);
app->m_instancingRenderer->getActiveCamera()->setCameraDistance(13);
app->m_instancingRenderer->getActiveCamera()->setCameraPitch(0);
app->m_instancingRenderer->getActiveCamera()->setCameraTargetPosition(0,0,0);
sOldKeyboardCB = app->m_window->getKeyboardCallback();
app->m_window->setKeyboardCallback(MyKeyboardCallback);
sOldMouseMoveCB = app->m_window->getMouseMoveCallback();
app->m_window->setMouseMoveCallback(MyMouseMoveCallback);
sOldMouseButtonCB = app->m_window->getMouseButtonCallback();
app->m_window->setMouseButtonCallback(MyMouseButtonCallback);
sOldWheelCB = app->m_window->getWheelCallback();
app->m_window->setWheelCallback(MyWheelCallback);
sOldResizeCB = app->m_window->getResizeCallback();
app->m_window->setResizeCallback(MyResizeCallback);
myArgs.GetCmdLineArgument("mp4_file",gVideoFileName);
if (gVideoFileName)
app->dumpFramesToVideo(gVideoFileName);
myArgs.GetCmdLineArgument("png_file",gPngFileName);
char fileName[1024];
int textureWidth = 128;
int textureHeight = 128;
unsigned char* image=new unsigned char[textureWidth*textureHeight*4];
int textureHandle = app->m_renderer->registerTexture(image,textureWidth,textureHeight);
int cubeIndex = app->registerCubeShape(1,1,1);
b3Vector3 pos = b3MakeVector3(0,0,0);
b3Quaternion orn(0,0,0,1);
b3Vector3 color=b3MakeVector3(1,0,0);
b3Vector3 scaling=b3MakeVector3 (1,1,1);
app->m_renderer->registerGraphicsInstance(cubeIndex,pos,orn,color,scaling);
app->m_renderer->writeTransforms();
do
{ {
static int frameCount = 0; b3CommandLineArgs myArgs(argc, argv);
frameCount++;
if (gPngFileName)
{
printf("gPngFileName=%s\n",gPngFileName);
sprintf(fileName,"%s%d.png",gPngFileName,frameCount++);
app->dumpNextFrameToPng(fileName); SimpleOpenGL3App* app = new SimpleOpenGL3App("SimpleOpenGL3App", gWidth, gHeight, true);
}
app->m_instancingRenderer->getActiveCamera()->setCameraDistance(13);
app->m_instancingRenderer->getActiveCamera()->setCameraPitch(0);
app->m_instancingRenderer->getActiveCamera()->setCameraTargetPosition(0, 0, 0);
sOldKeyboardCB = app->m_window->getKeyboardCallback();
app->m_window->setKeyboardCallback(MyKeyboardCallback);
sOldMouseMoveCB = app->m_window->getMouseMoveCallback();
app->m_window->setMouseMoveCallback(MyMouseMoveCallback);
sOldMouseButtonCB = app->m_window->getMouseButtonCallback();
app->m_window->setMouseButtonCallback(MyMouseButtonCallback);
sOldWheelCB = app->m_window->getWheelCallback();
app->m_window->setWheelCallback(MyWheelCallback);
sOldResizeCB = app->m_window->getResizeCallback();
app->m_window->setResizeCallback(MyResizeCallback);
myArgs.GetCmdLineArgument("mp4_file", gVideoFileName);
if (gVideoFileName)
app->dumpFramesToVideo(gVideoFileName);
myArgs.GetCmdLineArgument("png_file", gPngFileName);
char fileName[1024];
int textureWidth = 128;
int textureHeight = 128;
unsigned char* image = new unsigned char[textureWidth*textureHeight * 4];
int textureHandle = app->m_renderer->registerTexture(image, textureWidth, textureHeight);
int cubeIndex = app->registerCubeShape(1, 1, 1);
b3Vector3 pos = b3MakeVector3(0, 0, 0);
b3Quaternion orn(0, 0, 0, 1);
b3Vector3 color = b3MakeVector3(1, 0, 0);
b3Vector3 scaling = b3MakeVector3 (1, 1, 1);
app->m_renderer->registerGraphicsInstance(cubeIndex, pos, orn, color, scaling);
app->m_renderer->writeTransforms();
do
{
static int frameCount = 0;
frameCount++;
if (gPngFileName)
{
printf("gPngFileName=%s\n", gPngFileName);
sprintf(fileName, "%s%d.png", gPngFileName, frameCount++);
app->dumpNextFrameToPng(fileName);
}
//update the texels of the texture using a simple pattern, animated using frame index //update the texels of the texture using a simple pattern, animated using frame index
for(int y=0;y<textureHeight;++y) for (int y = 0; y < textureHeight; ++y)
{ {
const int t=(y+frameCount)>>4; const int t = (y + frameCount) >> 4;
unsigned char* pi=image+y*textureWidth*3; unsigned char* pi = image + y*textureWidth * 3;
for(int x=0;x<textureWidth;++x) for (int x = 0; x < textureWidth; ++x)
{ {
const int s=x>>4; const int s = x >> 4;
const unsigned char b=180; const unsigned char b = 180;
unsigned char c=b+((s+(t&1))&1)*(255-b); unsigned char c = b + ((s + (t & 1)) & 1)*(255 - b);
pi[0]=pi[1]=pi[2]=pi[3]=c;pi+=3; pi[0] = pi[1] = pi[2] = pi[3] = c; pi += 3;
} }
} }
app->m_renderer->activateTexture(textureHandle); app->m_renderer->activateTexture(textureHandle);
app->m_renderer->updateTexture(textureHandle,image); app->m_renderer->updateTexture(textureHandle, image);
float color[4] = {255,1,1,1}; float color[4] = { 255, 1, 1, 1 };
app->m_primRenderer->drawTexturedRect(100,200,gWidth/2-50,gHeight/2-50,color,0,0,1,1,true); app->m_primRenderer->drawTexturedRect(100, 200, gWidth / 2 - 50, gHeight / 2 - 50, color, 0, 0, 1, 1, true);
app->m_instancingRenderer->init(); app->m_instancingRenderer->init();
app->m_instancingRenderer->updateCamera(); app->m_instancingRenderer->updateCamera();
app->m_renderer->renderScene(); app->m_renderer->renderScene();
app->drawGrid(); app->drawGrid();
char bla[1024]; char bla[1024];
sprintf(bla,"Simple test frame %d", frameCount); sprintf(bla, "Simple test frame %d", frameCount);
app->drawText(bla,10,10); app->drawText(bla, 10, 10);
app->swapBuffer(); app->swapBuffer();
} while (!app->m_window->requestedExit()); } while (!app->m_window->requestedExit());
delete app;
delete app;
delete[] image;
}
return 0; return 0;
} }

View File

@@ -28,22 +28,22 @@ subject to the following restrictions:
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
DummyGUIHelper noGfx;
CommonExampleOptions options(&noGfx);
CommonExampleInterface* example = StandaloneExampleCreateFunc(options);
example->initPhysics();
for (int i=0;i<1000;i++)
{ {
printf("Simulating step %d\n",i); DummyGUIHelper noGfx;
example->stepSimulation(1.f/60.f);
CommonExampleOptions options(&noGfx);
CommonExampleInterface* example = StandaloneExampleCreateFunc(options);
example->initPhysics();
for (int i = 0; i < 1000; i++)
{
printf("Simulating step %d\n", i);
example->stepSimulation(1.f / 60.f);
}
example->exitPhysics();
delete example;
} }
example->exitPhysics();
delete example;
return 0; return 0;
} }

View File

@@ -122,6 +122,7 @@ subject to the following restrictions:
#error "DBVT_INT0_IMPL undefined" #error "DBVT_INT0_IMPL undefined"
#endif #endif
// //
// Defaults volumes // Defaults volumes
// //
@@ -188,6 +189,9 @@ struct btDbvtNode
}; };
}; };
typedef btAlignedObjectArray<const btDbvtNode*> btNodeStack;
///The btDbvt class implements a fast dynamic bounding volume tree based on axis aligned bounding boxes (aabb tree). ///The btDbvt class implements a fast dynamic bounding volume tree based on axis aligned bounding boxes (aabb tree).
///This btDbvt is used for soft body collision detection and for the btDbvtBroadphase. It has a fast insert, remove and update of nodes. ///This btDbvt is used for soft body collision detection and for the btDbvtBroadphase. It has a fast insert, remove and update of nodes.
///Unlike the btQuantizedBvh, nodes can be dynamically moved around, which allows for change in topology of the underlying data structure. ///Unlike the btQuantizedBvh, nodes can be dynamically moved around, which allows for change in topology of the underlying data structure.
@@ -325,6 +329,16 @@ struct btDbvt
void collideTV( const btDbvtNode* root, void collideTV( const btDbvtNode* root,
const btDbvtVolume& volume, const btDbvtVolume& volume,
DBVT_IPOLICY) const; DBVT_IPOLICY) const;
DBVT_PREFIX
void collideTVNoStackAlloc( const btDbvtNode* root,
const btDbvtVolume& volume,
btNodeStack& stack,
DBVT_IPOLICY) const;
///rayTest is a re-entrant ray test, and can be called in parallel as long as the btAlignedAlloc is thread-safe (uses locking etc) ///rayTest is a re-entrant ray test, and can be called in parallel as long as the btAlignedAlloc is thread-safe (uses locking etc)
///rayTest is slower than rayTestInternal, because it builds a local stack, using memory allocations, and it recomputes signs/rayDirectionInverses each time ///rayTest is slower than rayTestInternal, because it builds a local stack, using memory allocations, and it recomputes signs/rayDirectionInverses each time
DBVT_PREFIX DBVT_PREFIX
@@ -917,39 +931,72 @@ inline void btDbvt::collideTT( const btDbvtNode* root0,
} }
#endif #endif
//
DBVT_PREFIX DBVT_PREFIX
inline void btDbvt::collideTV( const btDbvtNode* root, inline void btDbvt::collideTV( const btDbvtNode* root,
const btDbvtVolume& vol, const btDbvtVolume& vol,
DBVT_IPOLICY) const DBVT_IPOLICY) const
{ {
DBVT_CHECKTYPE DBVT_CHECKTYPE
if(root) if(root)
{ {
ATTRIBUTE_ALIGNED16(btDbvtVolume) volume(vol); ATTRIBUTE_ALIGNED16(btDbvtVolume) volume(vol);
btAlignedObjectArray<const btDbvtNode*> stack; btAlignedObjectArray<const btDbvtNode*> stack;
stack.resize(0); stack.resize(0);
stack.reserve(SIMPLE_STACKSIZE); stack.reserve(SIMPLE_STACKSIZE);
stack.push_back(root); stack.push_back(root);
do { do {
const btDbvtNode* n=stack[stack.size()-1]; const btDbvtNode* n=stack[stack.size()-1];
stack.pop_back(); stack.pop_back();
if(Intersect(n->volume,volume)) if(Intersect(n->volume,volume))
{
if(n->isinternal())
{ {
if(n->isinternal()) stack.push_back(n->childs[0]);
{ stack.push_back(n->childs[1]);
stack.push_back(n->childs[0]);
stack.push_back(n->childs[1]);
}
else
{
policy.Process(n);
}
} }
} while(stack.size()>0); else
} {
policy.Process(n);
}
}
} while(stack.size()>0);
}
} }
//
DBVT_PREFIX
inline void btDbvt::collideTVNoStackAlloc( const btDbvtNode* root,
const btDbvtVolume& vol,
btNodeStack& stack,
DBVT_IPOLICY) const
{
DBVT_CHECKTYPE
if(root)
{
ATTRIBUTE_ALIGNED16(btDbvtVolume) volume(vol);
stack.resize(0);
stack.reserve(SIMPLE_STACKSIZE);
stack.push_back(root);
do {
const btDbvtNode* n=stack[stack.size()-1];
stack.pop_back();
if(Intersect(n->volume,volume))
{
if(n->isinternal())
{
stack.push_back(n->childs[0]);
stack.push_back(n->childs[1]);
}
else
{
policy.Process(n);
}
}
} while(stack.size()>0);
}
}
DBVT_PREFIX DBVT_PREFIX
inline void btDbvt::rayTestInternal( const btDbvtNode* root, inline void btDbvt::rayTestInternal( const btDbvtNode* root,
const btVector3& rayFrom, const btVector3& rayFrom,

View File

@@ -244,7 +244,7 @@ void btCompoundCollisionAlgorithm::processCollision (const btCollisionObjectWrap
///so we should add a 'refreshManifolds' in the btCollisionAlgorithm ///so we should add a 'refreshManifolds' in the btCollisionAlgorithm
{ {
int i; int i;
btManifoldArray manifoldArray; manifoldArray.resize(0);
for (i=0;i<m_childCollisionAlgorithms.size();i++) for (i=0;i<m_childCollisionAlgorithms.size();i++)
{ {
if (m_childCollisionAlgorithms[i]) if (m_childCollisionAlgorithms[i])
@@ -274,7 +274,7 @@ void btCompoundCollisionAlgorithm::processCollision (const btCollisionObjectWrap
const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax); const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax);
//process all children, that overlap with the given AABB bounds //process all children, that overlap with the given AABB bounds
tree->collideTV(tree->m_root,bounds,callback); tree->collideTVNoStackAlloc(tree->m_root,bounds,stack2,callback);
} else } else
{ {
@@ -291,7 +291,7 @@ void btCompoundCollisionAlgorithm::processCollision (const btCollisionObjectWrap
//iterate over all children, perform an AABB check inside ProcessChildShape //iterate over all children, perform an AABB check inside ProcessChildShape
int numChildren = m_childCollisionAlgorithms.size(); int numChildren = m_childCollisionAlgorithms.size();
int i; int i;
btManifoldArray manifoldArray; manifoldArray.resize(0);
const btCollisionShape* childShape = 0; const btCollisionShape* childShape = 0;
btTransform orgTrans; btTransform orgTrans;

View File

@@ -26,6 +26,7 @@ class btDispatcher;
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "btCollisionCreateFunc.h" #include "btCollisionCreateFunc.h"
#include "LinearMath/btAlignedObjectArray.h" #include "LinearMath/btAlignedObjectArray.h"
#include "BulletCollision/BroadphaseCollision/btDbvt.h"
class btDispatcher; class btDispatcher;
class btCollisionObject; class btCollisionObject;
@@ -36,6 +37,9 @@ extern btShapePairCallback gCompoundChildShapePairCallback;
/// btCompoundCollisionAlgorithm supports collision between CompoundCollisionShapes and other collision shapes /// btCompoundCollisionAlgorithm supports collision between CompoundCollisionShapes and other collision shapes
class btCompoundCollisionAlgorithm : public btActivatingCollisionAlgorithm class btCompoundCollisionAlgorithm : public btActivatingCollisionAlgorithm
{ {
btNodeStack stack2;
btManifoldArray manifoldArray;
protected: protected:
btAlignedObjectArray<btCollisionAlgorithm*> m_childCollisionAlgorithms; btAlignedObjectArray<btCollisionAlgorithm*> m_childCollisionAlgorithms;
bool m_isSwapped; bool m_isSwapped;

View File

@@ -503,9 +503,11 @@ void btConvexConvexAlgorithm ::processCollision (const btCollisionObjectWrapper*
// printf("sepNormalWorldSpace=%f,%f,%f\n",sepNormalWorldSpace.getX(),sepNormalWorldSpace.getY(),sepNormalWorldSpace.getZ()); // printf("sepNormalWorldSpace=%f,%f,%f\n",sepNormalWorldSpace.getX(),sepNormalWorldSpace.getY(),sepNormalWorldSpace.getZ());
worldVertsB1.resize(0);
btPolyhedralContactClipping::clipHullAgainstHull(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(), btPolyhedralContactClipping::clipHullAgainstHull(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(),
body0Wrap->getWorldTransform(), body0Wrap->getWorldTransform(),
body1Wrap->getWorldTransform(), minDist-threshold, threshold, *resultOut); body1Wrap->getWorldTransform(), minDist-threshold, threshold, worldVertsB1,worldVertsB2,
*resultOut);
} }
if (m_ownManifold) if (m_ownManifold)
@@ -568,8 +570,9 @@ void btConvexConvexAlgorithm ::processCollision (const btCollisionObjectWrapper*
if (foundSepAxis) if (foundSepAxis)
{ {
worldVertsB2.resize(0);
btPolyhedralContactClipping::clipFaceAgainstHull(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(), btPolyhedralContactClipping::clipFaceAgainstHull(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(),
body0Wrap->getWorldTransform(), vertices, minDist-threshold, maxDist, *resultOut); body0Wrap->getWorldTransform(), vertices, worldVertsB2,minDist-threshold, maxDist, *resultOut);
} }

View File

@@ -24,6 +24,7 @@ subject to the following restrictions:
#include "btCollisionCreateFunc.h" #include "btCollisionCreateFunc.h"
#include "btCollisionDispatcher.h" #include "btCollisionDispatcher.h"
#include "LinearMath/btTransformUtil.h" //for btConvexSeparatingDistanceUtil #include "LinearMath/btTransformUtil.h" //for btConvexSeparatingDistanceUtil
#include "BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h"
class btConvexPenetrationDepthSolver; class btConvexPenetrationDepthSolver;
@@ -45,6 +46,8 @@ class btConvexConvexAlgorithm : public btActivatingCollisionAlgorithm
btSimplexSolverInterface* m_simplexSolver; btSimplexSolverInterface* m_simplexSolver;
btConvexPenetrationDepthSolver* m_pdSolver; btConvexPenetrationDepthSolver* m_pdSolver;
btVertexArray worldVertsB1;
btVertexArray worldVertsB2;
bool m_ownManifold; bool m_ownManifold;
btPersistentManifold* m_manifoldPtr; btPersistentManifold* m_manifoldPtr;

View File

@@ -411,9 +411,9 @@ bool btPolyhedralContactClipping::findSeparatingAxis( const btConvexPolyhedron&
return true; return true;
} }
void btPolyhedralContactClipping::clipFaceAgainstHull(const btVector3& separatingNormal, const btConvexPolyhedron& hullA, const btTransform& transA, btVertexArray& worldVertsB1, const btScalar minDist, btScalar maxDist,btDiscreteCollisionDetectorInterface::Result& resultOut) void btPolyhedralContactClipping::clipFaceAgainstHull(const btVector3& separatingNormal, const btConvexPolyhedron& hullA, const btTransform& transA, btVertexArray& worldVertsB1,btVertexArray& worldVertsB2, const btScalar minDist, btScalar maxDist,btDiscreteCollisionDetectorInterface::Result& resultOut)
{ {
btVertexArray worldVertsB2; worldVertsB2.resize(0);
btVertexArray* pVtxIn = &worldVertsB1; btVertexArray* pVtxIn = &worldVertsB1;
btVertexArray* pVtxOut = &worldVertsB2; btVertexArray* pVtxOut = &worldVertsB2;
pVtxOut->reserve(pVtxIn->size()); pVtxOut->reserve(pVtxIn->size());
@@ -527,7 +527,7 @@ void btPolyhedralContactClipping::clipFaceAgainstHull(const btVector3& separatin
void btPolyhedralContactClipping::clipHullAgainstHull(const btVector3& separatingNormal1, const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, const btScalar minDist, btScalar maxDist,btDiscreteCollisionDetectorInterface::Result& resultOut) void btPolyhedralContactClipping::clipHullAgainstHull(const btVector3& separatingNormal1, const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, const btScalar minDist, btScalar maxDist,btVertexArray& worldVertsB1,btVertexArray& worldVertsB2,btDiscreteCollisionDetectorInterface::Result& resultOut)
{ {
btVector3 separatingNormal = separatingNormal1.normalized(); btVector3 separatingNormal = separatingNormal1.normalized();
@@ -552,7 +552,7 @@ void btPolyhedralContactClipping::clipHullAgainstHull(const btVector3& separatin
} }
} }
} }
btVertexArray worldVertsB1; worldVertsB1.resize(0);
{ {
const btFace& polyB = hullB.m_faces[closestFaceB]; const btFace& polyB = hullB.m_faces[closestFaceB];
const int numVertices = polyB.m_indices.size(); const int numVertices = polyB.m_indices.size();
@@ -565,6 +565,6 @@ void btPolyhedralContactClipping::clipHullAgainstHull(const btVector3& separatin
if (closestFaceB>=0) if (closestFaceB>=0)
clipFaceAgainstHull(separatingNormal, hullA, transA,worldVertsB1, minDist, maxDist,resultOut); clipFaceAgainstHull(separatingNormal, hullA, transA,worldVertsB1, worldVertsB2,minDist, maxDist,resultOut);
} }

View File

@@ -32,8 +32,11 @@ typedef btAlignedObjectArray<btVector3> btVertexArray;
// Clips a face to the back of a plane // Clips a face to the back of a plane
struct btPolyhedralContactClipping struct btPolyhedralContactClipping
{ {
static void clipHullAgainstHull(const btVector3& separatingNormal, const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, const btScalar minDist, btScalar maxDist, btDiscreteCollisionDetectorInterface::Result& resultOut);
static void clipFaceAgainstHull(const btVector3& separatingNormal, const btConvexPolyhedron& hullA, const btTransform& transA, btVertexArray& worldVertsB1, const btScalar minDist, btScalar maxDist,btDiscreteCollisionDetectorInterface::Result& resultOut); static void clipHullAgainstHull(const btVector3& separatingNormal1, const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, const btScalar minDist, btScalar maxDist,btVertexArray& worldVertsB1,btVertexArray& worldVertsB2,btDiscreteCollisionDetectorInterface::Result& resultOut);
static void clipFaceAgainstHull(const btVector3& separatingNormal, const btConvexPolyhedron& hullA, const btTransform& transA, btVertexArray& worldVertsB1,btVertexArray& worldVertsB2, const btScalar minDist, btScalar maxDist,btDiscreteCollisionDetectorInterface::Result& resultOut);
static bool findSeparatingAxis( const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, btVector3& sep, btDiscreteCollisionDetectorInterface::Result& resultOut); static bool findSeparatingAxis( const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, btVector3& sep, btDiscreteCollisionDetectorInterface::Result& resultOut);

View File

@@ -396,22 +396,17 @@ btMultiBodyDynamicsWorld::~btMultiBodyDynamicsWorld ()
void btMultiBodyDynamicsWorld::forwardKinematics() void btMultiBodyDynamicsWorld::forwardKinematics()
{ {
btAlignedObjectArray<btQuaternion> world_to_local;
btAlignedObjectArray<btVector3> local_origin;
for (int b=0;b<m_multiBodies.size();b++) for (int b=0;b<m_multiBodies.size();b++)
{ {
btMultiBody* bod = m_multiBodies[b]; btMultiBody* bod = m_multiBodies[b];
bod->forwardKinematics(world_to_local,local_origin); bod->forwardKinematics(m_scratch_world_to_local,m_scratch_local_origin);
} }
} }
void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
{ {
forwardKinematics(); forwardKinematics();
btAlignedObjectArray<btScalar> scratch_r;
btAlignedObjectArray<btVector3> scratch_v;
btAlignedObjectArray<btMatrix3x3> scratch_m;
BT_PROFILE("solveConstraints"); BT_PROFILE("solveConstraints");
@@ -463,9 +458,9 @@ void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
if (!isSleeping) if (!isSleeping)
{ {
//useless? they get resized in stepVelocities once again (AND DIFFERENTLY) //useless? they get resized in stepVelocities once again (AND DIFFERENTLY)
scratch_r.resize(bod->getNumLinks()+1); //multidof? ("Y"s use it and it is used to store qdd) m_scratch_r.resize(bod->getNumLinks()+1); //multidof? ("Y"s use it and it is used to store qdd)
scratch_v.resize(bod->getNumLinks()+1); m_scratch_v.resize(bod->getNumLinks()+1);
scratch_m.resize(bod->getNumLinks()+1); m_scratch_m.resize(bod->getNumLinks()+1);
bod->addBaseForce(m_gravity * bod->getBaseMass()); bod->addBaseForce(m_gravity * bod->getBaseMass());
@@ -500,15 +495,15 @@ void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
if (!isSleeping) if (!isSleeping)
{ {
//useless? they get resized in stepVelocities once again (AND DIFFERENTLY) //useless? they get resized in stepVelocities once again (AND DIFFERENTLY)
scratch_r.resize(bod->getNumLinks()+1); //multidof? ("Y"s use it and it is used to store qdd) m_scratch_r.resize(bod->getNumLinks()+1); //multidof? ("Y"s use it and it is used to store qdd)
scratch_v.resize(bod->getNumLinks()+1); m_scratch_v.resize(bod->getNumLinks()+1);
scratch_m.resize(bod->getNumLinks()+1); m_scratch_m.resize(bod->getNumLinks()+1);
bool doNotUpdatePos = false; bool doNotUpdatePos = false;
{ {
if(!bod->isUsingRK4Integration()) if(!bod->isUsingRK4Integration())
{ {
bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(solverInfo.m_timeStep, scratch_r, scratch_v, scratch_m); bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(solverInfo.m_timeStep, m_scratch_r, m_scratch_v, m_scratch_m);
} }
else else
{ {
@@ -594,9 +589,9 @@ void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
// //
btScalar h = solverInfo.m_timeStep; btScalar h = solverInfo.m_timeStep;
#define output &scratch_r[bod->getNumDofs()] #define output &m_scratch_r[bod->getNumDofs()]
//calc qdd0 from: q0 & qd0 //calc qdd0 from: q0 & qd0
bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(0., scratch_r, scratch_v, scratch_m); bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(0., m_scratch_r, m_scratch_v, m_scratch_m);
pCopy(output, scratch_qdd0, 0, numDofs); pCopy(output, scratch_qdd0, 0, numDofs);
//calc q1 = q0 + h/2 * qd0 //calc q1 = q0 + h/2 * qd0
pResetQx(); pResetQx();
@@ -606,7 +601,7 @@ void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
// //
//calc qdd1 from: q1 & qd1 //calc qdd1 from: q1 & qd1
pCopyToVelocityVector(bod, scratch_qd1); pCopyToVelocityVector(bod, scratch_qd1);
bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(0., scratch_r, scratch_v, scratch_m); bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(0., m_scratch_r, m_scratch_v, m_scratch_m);
pCopy(output, scratch_qdd1, 0, numDofs); pCopy(output, scratch_qdd1, 0, numDofs);
//calc q2 = q0 + h/2 * qd1 //calc q2 = q0 + h/2 * qd1
pResetQx(); pResetQx();
@@ -616,7 +611,7 @@ void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
// //
//calc qdd2 from: q2 & qd2 //calc qdd2 from: q2 & qd2
pCopyToVelocityVector(bod, scratch_qd2); pCopyToVelocityVector(bod, scratch_qd2);
bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(0., scratch_r, scratch_v, scratch_m); bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(0., m_scratch_r, m_scratch_v, m_scratch_m);
pCopy(output, scratch_qdd2, 0, numDofs); pCopy(output, scratch_qdd2, 0, numDofs);
//calc q3 = q0 + h * qd2 //calc q3 = q0 + h * qd2
pResetQx(); pResetQx();
@@ -626,7 +621,7 @@ void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
// //
//calc qdd3 from: q3 & qd3 //calc qdd3 from: q3 & qd3
pCopyToVelocityVector(bod, scratch_qd3); pCopyToVelocityVector(bod, scratch_qd3);
bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(0., scratch_r, scratch_v, scratch_m); bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(0., m_scratch_r, m_scratch_v, m_scratch_m);
pCopy(output, scratch_qdd3, 0, numDofs); pCopy(output, scratch_qdd3, 0, numDofs);
// //
@@ -661,7 +656,7 @@ void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
{ {
for(int link = 0; link < bod->getNumLinks(); ++link) for(int link = 0; link < bod->getNumLinks(); ++link)
bod->getLink(link).updateCacheMultiDof(); bod->getLink(link).updateCacheMultiDof();
bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(0, scratch_r, scratch_v, scratch_m); bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(0, m_scratch_r, m_scratch_v, m_scratch_m);
} }
} }
@@ -701,16 +696,16 @@ void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
if (!isSleeping) if (!isSleeping)
{ {
//useless? they get resized in stepVelocities once again (AND DIFFERENTLY) //useless? they get resized in stepVelocities once again (AND DIFFERENTLY)
scratch_r.resize(bod->getNumLinks()+1); //multidof? ("Y"s use it and it is used to store qdd) m_scratch_r.resize(bod->getNumLinks()+1); //multidof? ("Y"s use it and it is used to store qdd)
scratch_v.resize(bod->getNumLinks()+1); m_scratch_v.resize(bod->getNumLinks()+1);
scratch_m.resize(bod->getNumLinks()+1); m_scratch_m.resize(bod->getNumLinks()+1);
{ {
if(!bod->isUsingRK4Integration()) if(!bod->isUsingRK4Integration())
{ {
bool isConstraintPass = true; bool isConstraintPass = true;
bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(solverInfo.m_timeStep, scratch_r, scratch_v, scratch_m, isConstraintPass); bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(solverInfo.m_timeStep, m_scratch_r, m_scratch_v, m_scratch_m, isConstraintPass);
} }
} }
} }
@@ -732,8 +727,6 @@ void btMultiBodyDynamicsWorld::integrateTransforms(btScalar timeStep)
{ {
BT_PROFILE("btMultiBody stepPositions"); BT_PROFILE("btMultiBody stepPositions");
//integrate and update the Featherstone hierarchies //integrate and update the Featherstone hierarchies
btAlignedObjectArray<btQuaternion> world_to_local;
btAlignedObjectArray<btVector3> local_origin;
for (int b=0;b<m_multiBodies.size();b++) for (int b=0;b<m_multiBodies.size();b++)
{ {
@@ -770,10 +763,10 @@ void btMultiBodyDynamicsWorld::integrateTransforms(btScalar timeStep)
} }
} }
world_to_local.resize(nLinks+1); m_scratch_world_to_local.resize(nLinks+1);
local_origin.resize(nLinks+1); m_scratch_local_origin.resize(nLinks+1);
bod->updateCollisionObjectWorldTransforms(world_to_local,local_origin); bod->updateCollisionObjectWorldTransforms(m_scratch_world_to_local,m_scratch_local_origin);
} else } else
{ {
@@ -818,8 +811,6 @@ void btMultiBodyDynamicsWorld::debugDrawWorld()
{ {
BT_PROFILE("btMultiBody debugDrawWorld"); BT_PROFILE("btMultiBody debugDrawWorld");
btAlignedObjectArray<btQuaternion> world_to_local1;
btAlignedObjectArray<btVector3> local_origin1;
for (int c=0;c<m_multiBodyConstraints.size();c++) for (int c=0;c<m_multiBodyConstraints.size();c++)
{ {
@@ -830,7 +821,7 @@ void btMultiBodyDynamicsWorld::debugDrawWorld()
for (int b = 0; b<m_multiBodies.size(); b++) for (int b = 0; b<m_multiBodies.size(); b++)
{ {
btMultiBody* bod = m_multiBodies[b]; btMultiBody* bod = m_multiBodies[b];
bod->forwardKinematics(world_to_local1,local_origin1); bod->forwardKinematics(m_scratch_world_to_local1,m_scratch_local_origin1);
getDebugDrawer()->drawTransform(bod->getBaseWorldTransform(), 0.1); getDebugDrawer()->drawTransform(bod->getBaseWorldTransform(), 0.1);

View File

@@ -36,6 +36,16 @@ protected:
btMultiBodyConstraintSolver* m_multiBodyConstraintSolver; btMultiBodyConstraintSolver* m_multiBodyConstraintSolver;
MultiBodyInplaceSolverIslandCallback* m_solverMultiBodyIslandCallback; MultiBodyInplaceSolverIslandCallback* m_solverMultiBodyIslandCallback;
//cached data to avoid memory allocations
btAlignedObjectArray<btQuaternion> m_scratch_world_to_local;
btAlignedObjectArray<btVector3> m_scratch_local_origin;
btAlignedObjectArray<btQuaternion> m_scratch_world_to_local1;
btAlignedObjectArray<btVector3> m_scratch_local_origin1;
btAlignedObjectArray<btScalar> m_scratch_r;
btAlignedObjectArray<btVector3> m_scratch_v;
btAlignedObjectArray<btMatrix3x3> m_scratch_m;
virtual void calculateSimulationIslands(); virtual void calculateSimulationIslands();
virtual void updateActivationState(btScalar timeStep); virtual void updateActivationState(btScalar timeStep);
virtual void solveConstraints(btContactSolverInfo& solverInfo); virtual void solveConstraints(btContactSolverInfo& solverInfo);

View File

@@ -105,29 +105,93 @@ void btAlignedAllocSetCustom(btAllocFunc *allocFunc, btFreeFunc *freeFunc)
} }
#ifdef BT_DEBUG_MEMORY_ALLOCATIONS #ifdef BT_DEBUG_MEMORY_ALLOCATIONS
static int allocations_id[10241024];
static int allocations_bytes[10241024];
static int mynumallocs = 0;
#include <stdio.h>
int btDumpMemoryLeaks()
{
int totalLeak = 0;
for (int i=0;i<mynumallocs;i++)
{
printf("Error: leaked memory of allocation #%d (%d bytes)\n", allocations_id[i], allocations_bytes[i]);
totalLeak+=allocations_bytes[i];
}
if (totalLeak)
{
printf("Error: memory leaks: %d allocations were not freed and leaked together %d bytes\n",mynumallocs,totalLeak);
}
return totalLeak;
}
//this generic allocator provides the total allocated number of bytes //this generic allocator provides the total allocated number of bytes
#include <stdio.h> #include <stdio.h>
struct btDebugPtrMagic
{
union
{
void** vptrptr;
void* vptr;
int* iptr;
char* cptr;
};
};
void* btAlignedAllocInternal (size_t size, int alignment,int line,char* filename) void* btAlignedAllocInternal (size_t size, int alignment,int line,char* filename)
{ {
if (size==0)
{
printf("Whaat? size==0");
return 0;
}
static int allocId = 0;
void *ret; void *ret;
char *real; char *real;
// to find some particular memory leak, you could do something like this:
// if (allocId==172)
// {
// printf("catch me!\n");
// }
// if (size>1024*1024)
// {
// printf("big alloc!%d\n", size);
// }
gTotalBytesAlignedAllocs += size; gTotalBytesAlignedAllocs += size;
gNumAlignedAllocs++; gNumAlignedAllocs++;
real = (char *)sAllocFunc(size + 2*sizeof(void *) + (alignment-1)); int sz4prt = 4*sizeof(void *);
real = (char *)sAllocFunc(size + sz4prt + (alignment-1));
if (real) { if (real) {
ret = (void*) btAlignPointer(real + 2*sizeof(void *), alignment);
*((void **)(ret)-1) = (void *)(real); ret = (void*) btAlignPointer(real + sz4prt, alignment);
*((int*)(ret)-2) = size; btDebugPtrMagic p;
p.vptr = ret;
p.cptr-=sizeof(void*);
*p.vptrptr = (void*)real;
p.cptr-=sizeof(void*);
*p.iptr = size;
p.cptr-=sizeof(void*);
*p.iptr = allocId;
allocations_id[mynumallocs] = allocId;
allocations_bytes[mynumallocs] = size;
mynumallocs++;
} else { } else {
ret = (void *)(real);//?? ret = (void *)(real);//??
} }
printf("allocation#%d at address %x, from %s,line %d, size %d\n",gNumAlignedAllocs,real, filename,line,size); printf("allocation %d at address %x, from %s,line %d, size %d (total allocated = %d)\n",allocId,real, filename,line,size,gTotalBytesAlignedAllocs);
allocId++;
int* ptr = (int*)ret; int* ptr = (int*)ret;
*ptr = 12; *ptr = 12;
@@ -138,19 +202,43 @@ void btAlignedFreeInternal (void* ptr,int line,char* filename)
{ {
void* real; void* real;
gNumAlignedFree++;
if (ptr) { if (ptr) {
real = *((void **)(ptr)-1); gNumAlignedFree++;
int size = *((int*)(ptr)-2);
gTotalBytesAlignedAllocs -= size;
printf("free #%d at address %x, from %s,line %d, size %d\n",gNumAlignedFree,real, filename,line,size); btDebugPtrMagic p;
p.vptr = ptr;
p.cptr-=sizeof(void*);
real = *p.vptrptr;
p.cptr-=sizeof(void*);
int size = *p.iptr;
p.cptr-=sizeof(void*);
int allocId = *p.iptr;
bool found = false;
for (int i=0;i<mynumallocs;i++)
{
if ( allocations_id[i] == allocId)
{
allocations_id[i] = allocations_id[mynumallocs-1];
allocations_bytes[i] = allocations_bytes[mynumallocs-1];
mynumallocs--;
found = true;
break;
}
}
gTotalBytesAlignedAllocs -= size;
int diff = gNumAlignedAllocs-gNumAlignedFree;
printf("free %d at address %x, from %s,line %d, size %d (total remain = %d in %d non-freed allocations)\n",allocId,real, filename,line,size, gTotalBytesAlignedAllocs, diff);
sFreeFunc(real); sFreeFunc(real);
} else } else
{ {
printf("NULL ptr\n"); //printf("deleting a NULL ptr, no effect\n");
} }
} }

View File

@@ -21,9 +21,15 @@ subject to the following restrictions:
///that is better portable and more predictable ///that is better portable and more predictable
#include "btScalar.h" #include "btScalar.h"
//#define BT_DEBUG_MEMORY_ALLOCATIONS 1
///BT_DEBUG_MEMORY_ALLOCATIONS preprocessor can be set in build system
///for regression tests to detect memory leaks
///#define BT_DEBUG_MEMORY_ALLOCATIONS 1
#ifdef BT_DEBUG_MEMORY_ALLOCATIONS #ifdef BT_DEBUG_MEMORY_ALLOCATIONS
int btDumpMemoryLeaks();
#define btAlignedAlloc(a,b) \ #define btAlignedAlloc(a,b) \
btAlignedAllocInternal(a,b,__LINE__,__FILE__) btAlignedAllocInternal(a,b,__LINE__,__FILE__)