From 797680a535f395cbe568d3612f216eb3dfe673fc Mon Sep 17 00:00:00 2001 From: erwin coumans Date: Thu, 14 Jul 2016 20:42:00 -0700 Subject: [PATCH 01/10] Remove memory leak in SimpleOpenGL3 example code --- examples/OpenGLWindow/SimpleOpenGL3App.cpp | 6 +++++- examples/SimpleOpenGL3/main.cpp | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/examples/OpenGLWindow/SimpleOpenGL3App.cpp b/examples/OpenGLWindow/SimpleOpenGL3App.cpp index 0ed1db2ea..ba7f1c076 100644 --- a/examples/OpenGLWindow/SimpleOpenGL3App.cpp +++ b/examples/OpenGLWindow/SimpleOpenGL3App.cpp @@ -650,9 +650,13 @@ void SimpleOpenGL3App::setBackgroundColor(float red, float green, float blue) SimpleOpenGL3App::~SimpleOpenGL3App() { + + delete m_instancingRenderer; delete m_primRenderer ; - + sth_delete(m_data->m_fontStash); + delete m_data->m_renderCallbacks; m_window->closeWindow(); + TwDeleteDefaultFonts(); delete m_window; delete m_data ; } diff --git a/examples/SimpleOpenGL3/main.cpp b/examples/SimpleOpenGL3/main.cpp index 726abf693..5a2752e73 100644 --- a/examples/SimpleOpenGL3/main.cpp +++ b/examples/SimpleOpenGL3/main.cpp @@ -1,3 +1,4 @@ + #include "OpenGLWindow/SimpleOpenGL3App.h" #include "Bullet3Common/b3Quaternion.h" #include "Bullet3Common/b3CommandLineArgs.h" @@ -78,7 +79,7 @@ int main(int argc, char* argv[]) app->m_window->setResizeCallback(MyResizeCallback); - myArgs.GetCmdLineArgument("mp4_file",gVideoFileName); + myArgs.GetCmdLineArgument("mp4_file",gVideoFileName); if (gVideoFileName) app->dumpFramesToVideo(gVideoFileName); @@ -150,6 +151,9 @@ int main(int argc, char* argv[]) } while (!app->m_window->requestedExit()); + delete app; + + delete[] image; return 0; } From f9762d63abb6730e2b3caff8d032d8aae67937db Mon Sep 17 00:00:00 2001 From: erwin coumans Date: Sat, 16 Jul 2016 00:55:56 -0700 Subject: [PATCH 02/10] Removed many memoryleaks in Example Browser, reducing some technical debt. When running the Example Browser with Basic Example, 'visual leak detector' show no leak. Many other individual examples still leak, so it is work-in-progress. Disabled the profiler window (too many leaks) --- .../GwenGUISupport/GwenProfileWindow.cpp | 16 +- .../GwenGUISupport/gwenInternalData.h | 5 +- .../GwenGUISupport/gwenUserInterface.cpp | 170 ++++++---- .../GwenGUISupport/gwenUserInterface.h | 1 + .../ExampleBrowser/OpenGLExampleBrowser.cpp | 302 ++++++++++++------ .../ExampleBrowser/OpenGLExampleBrowser.h | 3 + examples/ExampleBrowser/OpenGLGuiHelper.cpp | 1 + examples/ExampleBrowser/main.cpp | 52 +-- .../ImportURDFDemo/BulletUrdfImporter.cpp | 1 + .../Importers/ImportURDFDemo/UrdfParser.cpp | 8 +- .../ImportURDFDemo/urdfStringSplit.cpp | 9 +- .../ImportURDFDemo/urdfStringSplit.h | 4 +- .../InverseDynamicsExample.cpp | 11 + examples/OpenGLWindow/SimpleOpenGL3App.cpp | 3 +- examples/OpenGLWindow/TwFonts.cpp | 35 +- examples/SimpleOpenGL3/main.cpp | 188 +++++------ .../main_console_single_example.cpp | 28 +- 17 files changed, 521 insertions(+), 316 deletions(-) diff --git a/examples/ExampleBrowser/GwenGUISupport/GwenProfileWindow.cpp b/examples/ExampleBrowser/GwenGUISupport/GwenProfileWindow.cpp index d376246ec..597ff834d 100644 --- a/examples/ExampleBrowser/GwenGUISupport/GwenProfileWindow.cpp +++ b/examples/ExampleBrowser/GwenGUISupport/GwenProfileWindow.cpp @@ -44,7 +44,7 @@ public: CProfileIterator* profIter; - + class MyMenuItems* m_menuItems; MyProfileWindow ( Gwen::Controls::Base* pParent) : Gwen::Controls::WindowControl( pParent ), profIter(0) @@ -83,6 +83,12 @@ public: } + virtual ~MyProfileWindow() + { + + delete m_node; + delete m_ctrl; + } float dumpRecursive(CProfileIterator* profileIterator, Gwen::Controls::TreeNode* parentNode) { @@ -266,11 +272,16 @@ public: MyProfileWindow* setupProfileWindow(GwenInternalData* data) { MyMenuItems* menuItems = new MyMenuItems; + MyProfileWindow* profWindow = new MyProfileWindow(data->pCanvas); //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); + menuItems->m_profWindow = profWindow; + return profWindow; } @@ -290,5 +301,6 @@ void profileWindowSetVisible(MyProfileWindow* window, bool visible) } void destroyProfileWindow(MyProfileWindow* window) { + CProfileManager::Release_Iterator(window->profIter); delete window; } diff --git a/examples/ExampleBrowser/GwenGUISupport/gwenInternalData.h b/examples/ExampleBrowser/GwenGUISupport/gwenInternalData.h index ec0982571..3fc3bb4b4 100644 --- a/examples/ExampleBrowser/GwenGUISupport/gwenInternalData.h +++ b/examples/ExampleBrowser/GwenGUISupport/gwenInternalData.h @@ -45,7 +45,10 @@ struct GwenInternalData Gwen::Controls::ListBox* m_TextOutput; Gwen::Controls::Label* m_exampleInfoGroupBox; 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; diff --git a/examples/ExampleBrowser/GwenGUISupport/gwenUserInterface.cpp b/examples/ExampleBrowser/GwenGUISupport/gwenUserInterface.cpp index a70d9268a..fcff13968 100644 --- a/examples/ExampleBrowser/GwenGUISupport/gwenUserInterface.cpp +++ b/examples/ExampleBrowser/GwenGUISupport/gwenUserInterface.cpp @@ -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() { for (int i=0;im_handlers.size();i++) @@ -26,72 +103,15 @@ GwenUserInterface::~GwenUserInterface() m_data->m_handlers.clear(); - - delete m_data->pCanvas; - - + 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) { @@ -232,6 +252,7 @@ void GwenUserInterface::setStatusBarMessage(const char* message, bool isLeft) } } + void GwenUserInterface::registerFileOpenCallback(b3FileOpenCallback callback) { m_data->m_menuItems->m_fileOpenCallback = callback; @@ -249,35 +270,43 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere 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; - + m_data->m_menubar = menubar; + - 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->SetWidth(width/2); //m_data->m_rightStatusBar->SetText( L"Label Added to Right" ); bar->AddControl( m_data->m_rightStatusBar, true ); - + m_data->m_TextOutput = new Gwen::Controls::ListBox( m_data->pCanvas ); + m_data->m_TextOutput->Dock( Gwen::Pos::Bottom ); m_data->m_TextOutput->SetHeight( 100 ); - + m_data->m_leftStatusBar = new Gwen::Controls::Label( bar ); + //m_data->m_leftStatusBar->SetText( L"Label Added to Left" ); m_data->m_leftStatusBar->SetWidth(width/2); bar->AddControl( m_data->m_leftStatusBar,false); + //Gwen::KeyboardFocus /*Gwen::Controls::GroupBox* box = new Gwen::Controls::GroupBox(m_data->pCanvas); box->SetText("text"); @@ -289,11 +318,14 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere windowRight->SetWidth(250); windowRight->SetHeight(250); windowRight->SetScroll(false,true); - + m_data->m_windowRight = windowRight; //windowLeft->SetSkin( Gwen::Controls::TabControl* tab = new Gwen::Controls::TabControl(windowRight); + m_data->m_tab = tab; + + //tab->SetHeight(300); tab->SetWidth(240); @@ -304,7 +336,8 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere Gwen::UnicodeString str1(L"Params"); m_data->m_demoPage = tab->AddPage(str1); - + + @@ -348,7 +381,7 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere //windowLeft->SetClosable(false); // windowLeft->SetShouldDrawBackground(true); windowLeft->SetTabable(true); - + Gwen::Controls::TabControl* explorerTab = new Gwen::Controls::TabControl(windowLeft); //tab->SetHeight(300); @@ -388,7 +421,6 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere m_data->m_exampleInfoGroupBox->SetText("Example Description"); m_data->m_exampleInfoTextOutput = new Gwen::Controls::ListBox(m_data->m_explorerPage->GetPage()); - //m_data->m_exampleInfoTextOutput->Dock( Gwen::Pos::Bottom ); m_data->m_exampleInfoTextOutput->SetPos(2, 332); diff --git a/examples/ExampleBrowser/GwenGUISupport/gwenUserInterface.h b/examples/ExampleBrowser/GwenGUISupport/gwenUserInterface.h index c448e9fff..d66b59828 100644 --- a/examples/ExampleBrowser/GwenGUISupport/gwenUserInterface.h +++ b/examples/ExampleBrowser/GwenGUISupport/gwenUserInterface.h @@ -26,6 +26,7 @@ class GwenUserInterface virtual ~GwenUserInterface(); void init(int width, int height,Gwen::Renderer::Base* gwenRenderer,float retinaScale); + void exit(); void setFocus(); void forceUpdateScrollBars(); diff --git a/examples/ExampleBrowser/OpenGLExampleBrowser.cpp b/examples/ExampleBrowser/OpenGLExampleBrowser.cpp index 64eb707a9..18578c71a 100644 --- a/examples/ExampleBrowser/OpenGLExampleBrowser.cpp +++ b/examples/ExampleBrowser/OpenGLExampleBrowser.cpp @@ -42,19 +42,65 @@ #include "../Importers/ImportURDFDemo/ImportURDFSetup.h" #include "../Importers/ImportBullet/SerializeSetup.h" +#include "Bullet3Common/b3HashMap.h" + +struct GL3TexLoader : public MyTextureLoader +{ + b3HashMap 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 m_nodes; + GwenUserInterface* m_gui; + GL3TexLoader* m_myTexLoader; + struct MyMenuItemHander* m_handler2; + btAlignedObjectArray 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 CommonWindowInterface* s_window = 0; static CommonParameterInterface* s_parameterInterface=0; static CommonRenderInterface* s_instancingRenderer=0; static OpenGLGuiHelper* s_guiHelper=0; -static MyProfileWindow* s_profWindow =0; +//static MyProfileWindow* s_profWindow =0; static SharedMemoryInterface* sSharedMem = 0; #define DEMO_SELECTION_COMBOBOX 13 const char* startFileName = "0_Bullet3Demo.txt"; char staticPngFileName[1024]; -static GwenUserInterface* gui = 0; +//static GwenUserInterface* gui = 0; +static GwenUserInterface* gui2 = 0; static int sCurrentDemoIndex = -1; static int sCurrentHightlighted = 0; static CommonExampleInterface* sCurrentDemo = 0; @@ -123,9 +169,9 @@ void MyKeyboardCallback(int key, int state) //b3Printf("key=%d, state=%d", key, state); bool handled = false; - if (gui && !handled ) + if (gui2 && !handled ) { - handled = gui->keyboardCallback(key, state); + handled = gui2->keyboardCallback(key, state); } if (!handled && sCurrentDemo) @@ -226,8 +272,8 @@ 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 && gui2) + handled = gui2->mouseMoveCallback(x,y); if (!handled) { if (prevMouseMoveCallback) @@ -244,8 +290,8 @@ static void MyMouseButtonCallback(int button, int state, float x, float y) if (sCurrentDemo) handled = sCurrentDemo->mouseButtonCallback(button,state,x,y); - if (!handled && gui) - handled = gui->mouseButtonCallback(button,state,x,y); + if (!handled && gui2) + handled = gui2->mouseButtonCallback(button,state,x,y); if (!handled) { @@ -333,7 +379,10 @@ void selectDemo(int demoIndex) CommonExampleInterface::CreateFunc* func = gAllExamples->getExampleCreateFunc(demoIndex); if (func) { - s_parameterInterface->removeAllParameters(); + if (s_parameterInterface) + { + s_parameterInterface->removeAllParameters(); + } int option = gAllExamples->getExampleOption(demoIndex); s_guiHelper= new OpenGLGuiHelper(s_app, sUseOpenGL2); CommonExampleOptions options(s_guiHelper, option); @@ -341,12 +390,15 @@ void selectDemo(int demoIndex) sCurrentDemo = (*func)(options); if (sCurrentDemo) { - if (gui) + if (gui2) { - gui->setStatusBarMessage("Status: OK", false); + gui2->setStatusBarMessage("Status: OK", false); } b3Printf("Selected demo: %s",gAllExamples->getExampleName(demoIndex)); - gui->setExampleDescription(gAllExamples->getExampleDescription(demoIndex)); + if (gui2) + { + gui2->setExampleDescription(gAllExamples->getExampleDescription(demoIndex)); + } sCurrentDemo->initPhysics(); if(resetCamera) @@ -437,10 +489,10 @@ void MyComboBoxCallback(int comboId, const char* item) void MyGuiPrintf(const char* msg) { printf("b3Printf: %s\n",msg); - if (gui) + if (gui2) { - gui->textOutput(msg); - gui->forceUpdateScrollBars(); + gui2->textOutput(msg); + gui2->forceUpdateScrollBars(); } } @@ -449,10 +501,10 @@ void MyGuiPrintf(const char* msg) void MyStatusBarPrintf(const char* msg) { printf("b3Printf: %s\n", msg); - if (gui) + if (gui2) { 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) { printf("Warning: %s\n", msg); - if (gui) + if (gui2) { bool isLeft = false; - gui->setStatusBarMessage(msg,isLeft); - gui->textOutput(msg); - gui->forceUpdateScrollBars(); + gui2->setStatusBarMessage(msg,isLeft); + gui2->textOutput(msg); + gui2->forceUpdateScrollBars(); } } @@ -534,7 +586,7 @@ struct MyMenuItemHander :public Gwen::Event::Handler { // printf("select %d\n",m_buttonId); sCurrentHightlighted = m_buttonId; - gui->setExampleDescription(gAllExamples->getExampleDescription(sCurrentHightlighted)); + gui2->setExampleDescription(gAllExamples->getExampleDescription(sCurrentHightlighted)); } 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 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() @@ -623,7 +655,7 @@ struct QuickCanvas : public Common2dCanvasInterface m_curNumGraphWindows++; - MyGraphInput input(gui->getInternalData()); + MyGraphInput input(gui2->getInternalData()); input.m_width=width; input.m_height=height; input.m_xPos = 10000;//GUI will clamp it to the right//300; @@ -669,12 +701,50 @@ struct QuickCanvas : public Common2dCanvasInterface OpenGLExampleBrowser::OpenGLExampleBrowser(class ExampleEntries* examples) { + m_internalData = new OpenGLExampleBrowserInternalData; + gAllExamples = examples; } 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; + gAllExamples = 0; } @@ -732,11 +802,10 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[]) char title[1024]; sprintf(title,"%s using OpenGL3+. %s", appTitle,optMode); simpleApp = new SimpleOpenGL3App(title,width,height, gAllowRetina); - - s_app = simpleApp; } #endif + m_internalData->m_app = s_app; char* gVideoFileName = 0; args.GetCmdLineArgument("mp4",gVideoFileName); #ifndef NO_OPENGL3 @@ -792,43 +861,67 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[]) assert(glGetError()==GL_NO_ERROR); + { + GL3TexLoader* myTexLoader = new GL3TexLoader; + m_internalData->m_myTexLoader = myTexLoader; - gui = new GwenUserInterface; - GL3TexLoader* myTexLoader = new GL3TexLoader; - - Gwen::Renderer::Base* gwenRenderer = 0; - if (sUseOpenGL2 ) - { - gwenRenderer = new Gwen::Renderer::OpenGL_DebugFont(); - } + sth_stash* fontstash = simpleApp->getFontStash(); + + if (sUseOpenGL2) + { + m_internalData->m_gwenRenderer = new Gwen::Renderer::OpenGL_DebugFont(); + } #ifndef NO_OPENGL3 - else - { - sth_stash* fontstash=simpleApp->getFontStash(); - gwenRenderer = new GwenOpenGL3CoreRenderer(simpleApp->m_primRenderer,fontstash,width,height,s_window->getRetinaScale(),myTexLoader); - } + else + { + sth_stash* fontstash = simpleApp->getFontStash(); + m_internalData->m_gwenRenderer = new GwenOpenGL3CoreRenderer(simpleApp->m_primRenderer, fontstash, width, height, s_window->getRetinaScale(), myTexLoader); + } #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()); - - - - -// gui->getInternalData()->m_explorerPage - Gwen::Controls::TreeControl* tree = gui->getInternalData()->m_explorerTreeCtrl; + if (gui2) + { + + + + + // gui->getInternalData()->m_explorerPage + Gwen::Controls::TreeControl* tree = gui2->getInternalData()->m_explorerTreeCtrl; + + + //gui->getInternalData()->pRenderer->setTextureLoader(myTexLoader); + + +// s_profWindow= setupProfileWindow(gui2->getInternalData()); + //m_internalData->m_profWindow = s_profWindow; + // profileWindowSetVisible(s_profWindow,false); + gui2->setFocus(); + + s_parameterInterface = s_app->m_parameterInterface = new GwenParameterInterface(gui2->getInternalData()); + s_app->m_2dCanvasInterface = new QuickCanvas(myTexLoader); - //gui->getInternalData()->pRenderer->setTextureLoader(myTexLoader); - - - s_profWindow= setupProfileWindow(gui->getInternalData()); - profileWindowSetVisible(s_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 @@ -839,7 +932,7 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[]) //int curDemo = 0; int selectedDemo = 0; Gwen::Controls::TreeNode* curNode = tree; - MyMenuItemHander* handler2 = new MyMenuItemHander(-1); + m_internalData->m_handler2 = new MyMenuItemHander(-1); char* demoNameFromCommandOption = 0; args.GetCmdLineArgument("start_demo_name", demoNameFromCommandOption); @@ -847,7 +940,7 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[]) selectedDemo = -1; } - tree->onReturnKeyDown.Add(handler2, &MyMenuItemHander::onButtonD); + tree->onReturnKeyDown.Add(m_internalData->m_handler2, &MyMenuItemHander::onButtonD); int firstAvailableDemoIndex=-1; Gwen::Controls::TreeNode* firstNode=0; @@ -894,13 +987,18 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[]) } } +#if 1 MyMenuItemHander* handler = new MyMenuItemHander(d); + m_internalData->m_handlers.push_back(handler); + 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); + +#endif // pNode->onKeyReturn.Add(handler, &MyMenuItemHander::onButtonD); // pNode->GetButton()->onKeyboardReturn.Add(handler, &MyMenuItemHander::onButtonD); // pNode->onNamePress.Add(handler, &MyMenuItemHander::onButtonD); @@ -910,6 +1008,7 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[]) else { curNode = tree->AddNode(nodeUText); + m_internalData->m_nodes.push_back(curNode); } } @@ -928,6 +1027,9 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[]) } } + free(demoNameFromCommandOption); + demoNameFromCommandOption = 0; + btAssert(sCurrentDemo!=0); if (sCurrentDemo==0) { @@ -935,9 +1037,11 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[]) exit(0); } - gui->registerFileOpenCallback(fileOpenCallback); - gui->registerQuitCallback(quitCallback); - + gui2->registerFileOpenCallback(fileOpenCallback); + gui2->registerQuitCallback(quitCallback); + } + + return true; } @@ -1044,7 +1148,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]; float camDist = s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraDistance(); @@ -1053,7 +1157,7 @@ void OpenGLExampleBrowser::update(float deltaTime) float camTarget[3]; 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]); - gui->setStatusBarMessage(msg, true); + gui2->setStatusBarMessage(msg, true); } } @@ -1061,16 +1165,24 @@ void OpenGLExampleBrowser::update(float deltaTime) static int toggle = 1; if (renderGui) { - if (!pauseSimulation) - processProfileData(s_profWindow,false); + // if (!pauseSimulation) + // 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"); - gui->draw(s_instancingRenderer->getScreenWidth(),s_instancingRenderer->getScreenHeight()); + BT_PROFILE("Draw Gwen GUI"); + 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) { restoreOpenGLState(); @@ -1084,14 +1196,20 @@ void OpenGLExampleBrowser::update(float deltaTime) toggle=1-toggle; { BT_PROFILE("Sync Parameters"); - s_parameterInterface->syncParameters(); + if (s_parameterInterface) + { + s_parameterInterface->syncParameters(); + } } { BT_PROFILE("Swap Buffers"); s_app->swapBuffer(); } - gui->forceUpdateScrollBars(); + if (gui2) + { + gui2->forceUpdateScrollBars(); + } } diff --git a/examples/ExampleBrowser/OpenGLExampleBrowser.h b/examples/ExampleBrowser/OpenGLExampleBrowser.h index ac9acd2f6..1f68abedb 100644 --- a/examples/ExampleBrowser/OpenGLExampleBrowser.h +++ b/examples/ExampleBrowser/OpenGLExampleBrowser.h @@ -5,6 +5,9 @@ class OpenGLExampleBrowser : public ExampleBrowserInterface { + + struct OpenGLExampleBrowserInternalData* m_internalData; + public: OpenGLExampleBrowser(class ExampleEntries* examples); diff --git a/examples/ExampleBrowser/OpenGLGuiHelper.cpp b/examples/ExampleBrowser/OpenGLGuiHelper.cpp index 1ed1ffb19..a5d7e0c3d 100644 --- a/examples/ExampleBrowser/OpenGLGuiHelper.cpp +++ b/examples/ExampleBrowser/OpenGLGuiHelper.cpp @@ -167,6 +167,7 @@ OpenGLGuiHelper::OpenGLGuiHelper(CommonGraphicsApp* glApp, bool useOpenGL2) OpenGLGuiHelper::~OpenGLGuiHelper() { + delete m_data->m_debugDraw; delete m_data->m_gl2ShapeDrawer; delete m_data; } diff --git a/examples/ExampleBrowser/main.cpp b/examples/ExampleBrowser/main.cpp index b245cdecb..6a528bc24 100644 --- a/examples/ExampleBrowser/main.cpp +++ b/examples/ExampleBrowser/main.cpp @@ -1,3 +1,4 @@ +#include "C:\develop\visual_leak_detector\vld-2.5\vld-2.5\src\vld.h" #include "OpenGLExampleBrowser.h" @@ -19,33 +20,34 @@ 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 - { - float deltaTimeInSeconds = clock.getTimeMicroseconds()/1000000.f; - clock.reset(); - exampleBrowser->update(deltaTimeInSeconds); + 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 + { + float deltaTimeInSeconds = clock.getTimeMicroseconds() / 1000000.f; + clock.reset(); + exampleBrowser->update(deltaTimeInSeconds); + + } while (!exampleBrowser->requestedExit()); + } + delete exampleBrowser; - } while (!exampleBrowser->requestedExit()); } - delete exampleBrowser; - - return 0; } diff --git a/examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp b/examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp index 1c24c2eba..628d99bc2 100644 --- a/examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp +++ b/examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp @@ -1058,6 +1058,7 @@ btCollisionShape* BulletURDFImporter::getAllocatedCollisionShape(int index) { const UrdfCollision& col = link->m_collisionArray[v]; btCollisionShape* childShape = convertURDFToCollisionShape(&col ,pathPrefix); + m_data->m_allocatedCollisionShapes.push_back(childShape); if (childShape) { diff --git a/examples/Importers/ImportURDFDemo/UrdfParser.cpp b/examples/Importers/ImportURDFDemo/UrdfParser.cpp index 64be1573b..6ed9ac2c8 100644 --- a/examples/Importers/ImportURDFDemo/UrdfParser.cpp +++ b/examples/Importers/ImportURDFDemo/UrdfParser.cpp @@ -61,7 +61,9 @@ static bool parseVector4(btVector4& vec4, const std::string& vector_str) vec4.setZero(); btArray pieces; btArray rgba; - urdfStringSplit(pieces, vector_str, urdfIsAnyOf(" ")); + btAlignedObjectArray strArray; + urdfIsAnyOf(" ", strArray); + urdfStringSplit(pieces, vector_str, strArray); for (int i = 0; i < pieces.size(); ++i) { if (!pieces[i].empty()) @@ -82,7 +84,9 @@ static bool parseVector3(btVector3& vec3, const std::string& vector_str, ErrorLo vec3.setZero(); btArray pieces; btArray rgba; - urdfStringSplit(pieces, vector_str, urdfIsAnyOf(" ")); + btAlignedObjectArray strArray; + urdfIsAnyOf(" ", strArray); + urdfStringSplit(pieces, vector_str, strArray); for (int i = 0; i < pieces.size(); ++i) { if (!pieces[i].empty()) diff --git a/examples/Importers/ImportURDFDemo/urdfStringSplit.cpp b/examples/Importers/ImportURDFDemo/urdfStringSplit.cpp index a5a1adf83..9ed88e7f4 100644 --- a/examples/Importers/ImportURDFDemo/urdfStringSplit.cpp +++ b/examples/Importers/ImportURDFDemo/urdfStringSplit.cpp @@ -8,7 +8,7 @@ #include "urdfStringSplit.h" -void urdfStringSplit( btAlignedObjectArray&pieces, const std::string& vector_str, btAlignedObjectArray separators) +void urdfStringSplit( btAlignedObjectArray&pieces, const std::string& vector_str, const btAlignedObjectArray& separators) { assert(separators.size()==1); if (separators.size()==1) @@ -20,10 +20,9 @@ void urdfStringSplit( btAlignedObjectArray&pieces, const std::strin urdfStrArrayFree(strArray); } } - btAlignedObjectArray urdfIsAnyOf(const char* seps) + void urdfIsAnyOf(const char* seps, btAlignedObjectArray& strArray) { - btAlignedObjectArray strArray; - + int numSeps = strlen(seps); for (int i=0;i&pieces, const std::strin sep2[0] = seps[i]; strArray.push_back(sep2); } - return strArray; - } diff --git a/examples/Importers/ImportURDFDemo/urdfStringSplit.h b/examples/Importers/ImportURDFDemo/urdfStringSplit.h index 6eaa42b6d..dd7af9158 100644 --- a/examples/Importers/ImportURDFDemo/urdfStringSplit.h +++ b/examples/Importers/ImportURDFDemo/urdfStringSplit.h @@ -7,9 +7,9 @@ #include "LinearMath/btAlignedObjectArray.h" -void urdfStringSplit( btAlignedObjectArray&pieces, const std::string& vector_str, btAlignedObjectArray separators); +void urdfStringSplit( btAlignedObjectArray&pieces, const std::string& vector_str, const btAlignedObjectArray& separators); -btAlignedObjectArray urdfIsAnyOf(const char* seps); +void urdfIsAnyOf(const char* seps, btAlignedObjectArray& strArray); ///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 diff --git a/examples/InverseDynamics/InverseDynamicsExample.cpp b/examples/InverseDynamics/InverseDynamicsExample.cpp index 20cff9204..986f9024b 100644 --- a/examples/InverseDynamics/InverseDynamicsExample.cpp +++ b/examples/InverseDynamics/InverseDynamicsExample.cpp @@ -73,6 +73,7 @@ class InverseDynamicsExample : public CommonMultiBodyBase { btInverseDynamicsExampleOptions m_option; btMultiBody* m_multiBody; + btAlignedObjectArray m_allocatedShapes; btInverseDynamics::MultiBodyTree *m_inverseModel; TimeSeriesCanvas* m_timeSeriesCanvas; public: @@ -105,7 +106,13 @@ InverseDynamicsExample::InverseDynamicsExample(struct GUIHelperInterface* helper InverseDynamicsExample::~InverseDynamicsExample() { + delete m_multiBody; + for (int i = 0; i < m_allocatedShapes.size(); i++) + { + delete m_allocatedShapes[i]; + } + m_allocatedShapes.resize(0); delete m_inverseModel; delete m_timeSeriesCanvas; } @@ -166,6 +173,10 @@ void InverseDynamicsExample::initPhysics() btTransform identityTrans; identityTrans.setIdentity(); ConvertURDF2Bullet(u2b,creation, identityTrans,m_dynamicsWorld,true,u2b.getPathPrefix()); + for (int i = 0; i < u2b.getNumAllocatedCollisionShapes(); i++) + { + m_allocatedShapes.push_back(u2b.getAllocatedCollisionShape(i)); + } m_multiBody = creation.getBulletMultiBody(); if (m_multiBody) { diff --git a/examples/OpenGLWindow/SimpleOpenGL3App.cpp b/examples/OpenGLWindow/SimpleOpenGL3App.cpp index ba7f1c076..1423f2841 100644 --- a/examples/OpenGLWindow/SimpleOpenGL3App.cpp +++ b/examples/OpenGLWindow/SimpleOpenGL3App.cpp @@ -655,8 +655,9 @@ SimpleOpenGL3App::~SimpleOpenGL3App() delete m_primRenderer ; sth_delete(m_data->m_fontStash); delete m_data->m_renderCallbacks; - m_window->closeWindow(); TwDeleteDefaultFonts(); + m_window->closeWindow(); + delete m_window; delete m_data ; } diff --git a/examples/OpenGLWindow/TwFonts.cpp b/examples/OpenGLWindow/TwFonts.cpp index e5cd37595..eaf351eec 100644 --- a/examples/OpenGLWindow/TwFonts.cpp +++ b/examples/OpenGLWindow/TwFonts.cpp @@ -4883,18 +4883,33 @@ static const unsigned char s_FontFixed1[] = { void TwGenerateDefaultFonts() { - g_DefaultSmallFont = TwGenerateFont(s_Font0, FONT0_BM_W, FONT0_BM_H); - assert(g_DefaultSmallFont && g_DefaultSmallFont->m_NbCharRead==224); + if (g_DefaultSmallFont == 0) + { + 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); - assert(g_DefaultNormalFont && g_DefaultNormalFont->m_NbCharRead==224); + if (g_DefaultNormalFont == 0) + { + 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); - assert(g_DefaultNormalFontAA && g_DefaultNormalFontAA->m_NbCharRead==224); - g_DefaultLargeFont = TwGenerateFont(s_Font2AA, FONT2AA_BM_W, FONT2AA_BM_H); - assert(g_DefaultLargeFont && g_DefaultLargeFont->m_NbCharRead==224); - g_DefaultFixed1Font = TwGenerateFont(s_FontFixed1, FONTFIXED1_BM_W, FONTFIXED1_BM_H); - assert(g_DefaultFixed1Font && g_DefaultFixed1Font->m_NbCharRead==224); + if (g_DefaultNormalFontAA == 0) + { + g_DefaultNormalFontAA = TwGenerateFont(s_Font1AA, FONT1AA_BM_W, FONT1AA_BM_H); + assert(g_DefaultNormalFontAA && g_DefaultNormalFontAA->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); + } } // --------------------------------------------------------------------------- diff --git a/examples/SimpleOpenGL3/main.cpp b/examples/SimpleOpenGL3/main.cpp index 5a2752e73..fe637778f 100644 --- a/examples/SimpleOpenGL3/main.cpp +++ b/examples/SimpleOpenGL3/main.cpp @@ -1,4 +1,6 @@ + + #include "OpenGLWindow/SimpleOpenGL3App.h" #include "Bullet3Common/b3Quaternion.h" #include "Bullet3Common/b3CommandLineArgs.h" @@ -59,101 +61,103 @@ void MyKeyboardCallback(int keycode, int state) 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; - 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 - for(int y=0;y>4; - unsigned char* pi=image+y*textureWidth*3; - for(int x=0;x>4; - const unsigned char b=180; - unsigned char c=b+((s+(t&1))&1)*(255-b); - pi[0]=pi[1]=pi[2]=pi[3]=c;pi+=3; - } - } - - app->m_renderer->activateTexture(textureHandle); - app->m_renderer->updateTexture(textureHandle,image); - - 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_instancingRenderer->init(); - app->m_instancingRenderer->updateCamera(); - - app->m_renderer->renderScene(); - app->drawGrid(); - char bla[1024]; - sprintf(bla,"Simple test frame %d", frameCount); - - app->drawText(bla,10,10); - app->swapBuffer(); - } while (!app->m_window->requestedExit()); + b3CommandLineArgs myArgs(argc, argv); - - delete app; + SimpleOpenGL3App* app = new SimpleOpenGL3App("SimpleOpenGL3App", gWidth, gHeight, true); - delete[] image; + 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 + for (int y = 0; y < textureHeight; ++y) + { + const int t = (y + frameCount) >> 4; + unsigned char* pi = image + y*textureWidth * 3; + for (int x = 0; x < textureWidth; ++x) + { + const int s = x >> 4; + const unsigned char b = 180; + unsigned char c = b + ((s + (t & 1)) & 1)*(255 - b); + pi[0] = pi[1] = pi[2] = pi[3] = c; pi += 3; + } + } + + app->m_renderer->activateTexture(textureHandle); + app->m_renderer->updateTexture(textureHandle, image); + + 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_instancingRenderer->init(); + app->m_instancingRenderer->updateCamera(); + + app->m_renderer->renderScene(); + app->drawGrid(); + char bla[1024]; + sprintf(bla, "Simple test frame %d", frameCount); + + app->drawText(bla, 10, 10); + app->swapBuffer(); + } while (!app->m_window->requestedExit()); + + + + delete app; + + delete[] image; + } return 0; } diff --git a/examples/StandaloneMain/main_console_single_example.cpp b/examples/StandaloneMain/main_console_single_example.cpp index c29ebcd79..5764e28fb 100644 --- a/examples/StandaloneMain/main_console_single_example.cpp +++ b/examples/StandaloneMain/main_console_single_example.cpp @@ -28,22 +28,22 @@ subject to the following restrictions: 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); - example->stepSimulation(1.f/60.f); + DummyGUIHelper noGfx; + + 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; } From a12d25e6cea8e441e781a9f422811764fe18e2df Mon Sep 17 00:00:00 2001 From: erwin coumans Date: Sat, 16 Jul 2016 00:58:09 -0700 Subject: [PATCH 03/10] remove #include of visual leak detector (used to find memory leaks in ExampleBrowser/main.cpp) --- examples/ExampleBrowser/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ExampleBrowser/main.cpp b/examples/ExampleBrowser/main.cpp index 6a528bc24..7a155d6c0 100644 --- a/examples/ExampleBrowser/main.cpp +++ b/examples/ExampleBrowser/main.cpp @@ -1,4 +1,4 @@ -#include "C:\develop\visual_leak_detector\vld-2.5\vld-2.5\src\vld.h" + #include "OpenGLExampleBrowser.h" From bbefc6b1088d3b2ac2b598091d917d61547854c6 Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Sat, 16 Jul 2016 01:11:53 -0700 Subject: [PATCH 04/10] fix an issue in previous commit --- examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp b/examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp index 628d99bc2..c1ae57c4d 100644 --- a/examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp +++ b/examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp @@ -1058,7 +1058,7 @@ btCollisionShape* BulletURDFImporter::getAllocatedCollisionShape(int index) { const UrdfCollision& col = link->m_collisionArray[v]; btCollisionShape* childShape = convertURDFToCollisionShape(&col ,pathPrefix); - m_data->m_allocatedCollisionShapes.push_back(childShape); + //m_data->m_allocatedCollisionShapes.push_back(childShape); if (childShape) { From 2caa2b7ff407921eb84a459087fd71d8c1df84ce Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Sat, 16 Jul 2016 14:58:11 -0700 Subject: [PATCH 05/10] removed more memory leaks and improve btAlignedAllocator memory-leak debugging --- data/multibody.bullet | Bin 14584 -> 14584 bytes .../ImportURDFDemo/ImportURDFSetup.cpp | 8 +++- src/LinearMath/btAlignedAllocator.cpp | 44 ++++++++++++++---- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/data/multibody.bullet b/data/multibody.bullet index 1074b55dc5e60dafd11b59406edb7842bdfc57dd..31800308cedc7804a8642a0343c167373049f94b 100644 GIT binary patch delta 899 zcmb`GO=uHA6vt=cCYy#9p&zlDRBPRuR?XUKO>4|-x1NO7LJ?BLODc*WB8?X*u@>sV zOF`>gJt%tcRFEj1CIP{Z$_BgzPoBJZ^57xRLjAwV#E-iRznS^H_jYD>cDGS%6d%5_ zYC#}m!OF_-c5HonaV5?e+XH&RUa$`&KoazU{onxT2M56bI0PIp2o8f37y`qfbv<8H z6&kzXI2Zw=-~>1c#=t2GWiS{A6W}z+f-@io1n|Hl`27B?_u5%jG8xL9yN#!~GGAAS zvs)QguXJs`PW9|ejoY#9~W>BuIs;zc6(F#`jnV81qf6S zP;gzaksj9@+etSkgzJUjI&U_pWCLS~We{*?0dV$+=v#pfGg9&`i9{oAA3|tvk@`v3`1r(_K SRnWSD3gR*!oh|>2S?(`W)WyaC delta 743 zcmZ9K%S#(k7{%`-<0OvefoKF3i4sVaAOS%TjEUe%0xGy_wNA9HZ=KmG3g!=RQTe(R zM$E>?F1it-S(XyPZ8rtGsoG5t1Q%jFcdipP7k+c+JLlZ*-g!J2561W7s&2+uJEi1a zx^=1BkGkyN2{`FW4%HS*UMEbJxPB2bdhU!1eqW=N253yiX`9iFF!kyBDAJ6H$-U@ckN`=T@AKoF9^Q%!Fp&TT6b4XBer_&3{6_ z^t^vpMdY$UIVwrb+0iPWB(+gW3Cm~|r!6H!nyk{P(ke0ft%ToH9jX~U_=mkH6k?WIzVN=~Osq0P zraDF$_bTl>y!6N25-{_KbIRlJpfiR)sYwwhq>bt%6;+uE)vFU9k@^J2!36jWCV>W0 pU`*0W5+gunbm!4h-5=haH~H?47D~Jp&6(j}HI< diff --git a/examples/Importers/ImportURDFDemo/ImportURDFSetup.cpp b/examples/Importers/ImportURDFDemo/ImportURDFSetup.cpp index 33bc35d32..ebe8334a5 100644 --- a/examples/Importers/ImportURDFDemo/ImportURDFSetup.cpp +++ b/examples/Importers/ImportURDFDemo/ImportURDFSetup.cpp @@ -207,7 +207,7 @@ void ImportUrdfSetup::initPhysics() BulletURDFImporter u2b(m_guiHelper, 0); - bool loadOk = u2b.loadURDF(m_fileName); + bool loadOk = u2b.loadURDF(m_fileName); #ifdef TEST_MULTIBODY_SERIALIZATION //test to serialize a multibody to disk or shared memory, with base, link and joint names @@ -238,7 +238,11 @@ void ImportUrdfSetup::initPhysics() m_data->m_rb = creation.getRigidBody(); m_data->m_mb = creation.getBulletMultiBody(); 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 ) { std::string* name = new std::string(u2b.getLinkName(u2b.getRootLinkIndex())); diff --git a/src/LinearMath/btAlignedAllocator.cpp b/src/LinearMath/btAlignedAllocator.cpp index a65296c6a..3209b86ee 100644 --- a/src/LinearMath/btAlignedAllocator.cpp +++ b/src/LinearMath/btAlignedAllocator.cpp @@ -108,6 +108,18 @@ void btAlignedAllocSetCustom(btAllocFunc *allocFunc, btFreeFunc *freeFunc) //this generic allocator provides the total allocated number of bytes #include +struct btDebugPtrMagic +{ + union + { + void** vptrptr; + void* vptr; + int* iptr; + char* cptr; + }; +}; + + void* btAlignedAllocInternal (size_t size, int alignment,int line,char* filename) { void *ret; @@ -117,17 +129,24 @@ void* btAlignedAllocInternal (size_t size, int alignment,int line,char* filen gNumAlignedAllocs++; - real = (char *)sAllocFunc(size + 2*sizeof(void *) + (alignment-1)); +int sz2prt = 2*sizeof(void *); + + real = (char *)sAllocFunc(size + sz2prt + (alignment-1)); if (real) { - ret = (void*) btAlignPointer(real + 2*sizeof(void *), alignment); - *((void **)(ret)-1) = (void *)(real); - *((int*)(ret)-2) = size; + + ret = (void*) btAlignPointer(real + sz2prt, alignment); + btDebugPtrMagic p; + p.vptr = ret; + p.cptr-=sizeof(void*); + *p.vptrptr = (void*)real; + p.cptr-=sizeof(void*); + *p.iptr = size; } else { 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",gNumAlignedAllocs,real, filename,line,size,gTotalBytesAlignedAllocs); int* ptr = (int*)ret; *ptr = 12; @@ -141,16 +160,21 @@ void btAlignedFreeInternal (void* ptr,int line,char* filename) gNumAlignedFree++; if (ptr) { - real = *((void **)(ptr)-1); - int size = *((int*)(ptr)-2); - gTotalBytesAlignedAllocs -= size; + btDebugPtrMagic p; + p.vptr = ptr; + p.cptr-=sizeof(void*); + real = *p.vptrptr; + p.cptr-=sizeof(void*); + int size = *p.iptr; + + gTotalBytesAlignedAllocs -= size; - printf("free #%d at address %x, from %s,line %d, size %d\n",gNumAlignedFree,real, filename,line,size); + printf("free #%d at address %x, from %s,line %d, size %d (total remain = %d\n",gNumAlignedFree,real, filename,line,size, gTotalBytesAlignedAllocs); sFreeFunc(real); } else { - printf("NULL ptr\n"); + //printf("deleting a NULL ptr, no effect\n"); } } From e2bdd7dbb11b292b5f9fa1d8967993d13d2976fb Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Sat, 16 Jul 2016 17:40:44 -0700 Subject: [PATCH 06/10] fix more memory leaks, ImportURDFExample is now leak-free eliminate all run-time memory allocation (except for mouse-pick/ray-intersection) in ImportURDFExample --- .../CommonInterfaces/CommonMultiBodyBase.h | 16 +++- .../ImportURDFDemo/BulletUrdfImporter.cpp | 2 +- .../ImportURDFDemo/ImportURDFSetup.cpp | 1 + .../BroadphaseCollision/btDbvt.h | 93 ++++++++++++++----- .../btCompoundCollisionAlgorithm.cpp | 6 +- .../btCompoundCollisionAlgorithm.h | 4 + .../btConvexConvexAlgorithm.cpp | 7 +- .../btConvexConvexAlgorithm.h | 3 + .../btPolyhedralContactClipping.cpp | 10 +- .../btPolyhedralContactClipping.h | 7 +- .../Featherstone/btMultiBodyDynamicsWorld.cpp | 55 +++++------ .../Featherstone/btMultiBodyDynamicsWorld.h | 10 ++ src/LinearMath/btAlignedAllocator.h | 2 +- 13 files changed, 146 insertions(+), 70 deletions(-) diff --git a/examples/CommonInterfaces/CommonMultiBodyBase.h b/examples/CommonInterfaces/CommonMultiBodyBase.h index 3219f8294..48130b2d1 100644 --- a/examples/CommonInterfaces/CommonMultiBodyBase.h +++ b/examples/CommonInterfaces/CommonMultiBodyBase.h @@ -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) m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); - m_broadphase = new btDbvtBroadphase(); + m_broadphase = new btDbvtBroadphase();//btSimpleBroadphase(); m_solver = new btMultiBodyConstraintSolver; @@ -97,6 +97,20 @@ struct CommonMultiBodyBase : public CommonExampleInterface { 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--) { btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; diff --git a/examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp b/examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp index c1ae57c4d..628d99bc2 100644 --- a/examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp +++ b/examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp @@ -1058,7 +1058,7 @@ btCollisionShape* BulletURDFImporter::getAllocatedCollisionShape(int index) { const UrdfCollision& col = link->m_collisionArray[v]; btCollisionShape* childShape = convertURDFToCollisionShape(&col ,pathPrefix); - //m_data->m_allocatedCollisionShapes.push_back(childShape); + m_data->m_allocatedCollisionShapes.push_back(childShape); if (childShape) { diff --git a/examples/Importers/ImportURDFDemo/ImportURDFSetup.cpp b/examples/Importers/ImportURDFDemo/ImportURDFSetup.cpp index ebe8334a5..46b69cc08 100644 --- a/examples/Importers/ImportURDFDemo/ImportURDFSetup.cpp +++ b/examples/Importers/ImportURDFDemo/ImportURDFSetup.cpp @@ -352,6 +352,7 @@ void ImportUrdfSetup::initPhysics() btVector3 groundHalfExtents(20,20,20); groundHalfExtents[upAxis]=1.f; btBoxShape* box = new btBoxShape(groundHalfExtents); + m_collisionShapes.push_back(box); box->initializePolyhedralFeatures(); m_guiHelper->createCollisionShapeGraphicsObject(box); diff --git a/src/BulletCollision/BroadphaseCollision/btDbvt.h b/src/BulletCollision/BroadphaseCollision/btDbvt.h index db4e482f2..bee17e5c8 100644 --- a/src/BulletCollision/BroadphaseCollision/btDbvt.h +++ b/src/BulletCollision/BroadphaseCollision/btDbvt.h @@ -122,6 +122,7 @@ subject to the following restrictions: #error "DBVT_INT0_IMPL undefined" #endif + // // Defaults volumes // @@ -188,6 +189,9 @@ struct btDbvtNode }; }; +typedef btAlignedObjectArray btNodeStack; + + ///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. ///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, const btDbvtVolume& volume, 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 slower than rayTestInternal, because it builds a local stack, using memory allocations, and it recomputes signs/rayDirectionInverses each time DBVT_PREFIX @@ -917,39 +931,72 @@ inline void btDbvt::collideTT( const btDbvtNode* root0, } #endif -// DBVT_PREFIX inline void btDbvt::collideTV( const btDbvtNode* root, const btDbvtVolume& vol, DBVT_IPOLICY) const { DBVT_CHECKTYPE - if(root) - { - ATTRIBUTE_ALIGNED16(btDbvtVolume) volume(vol); - btAlignedObjectArray stack; - 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(root) + { + ATTRIBUTE_ALIGNED16(btDbvtVolume) volume(vol); + btAlignedObjectArray stack; + 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()) { - if(n->isinternal()) - { - stack.push_back(n->childs[0]); - stack.push_back(n->childs[1]); - } - else - { - policy.Process(n); - } + stack.push_back(n->childs[0]); + stack.push_back(n->childs[1]); } - } 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 inline void btDbvt::rayTestInternal( const btDbvtNode* root, const btVector3& rayFrom, diff --git a/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp index a80c438d1..13cddc11a 100644 --- a/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp +++ b/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp @@ -244,7 +244,7 @@ void btCompoundCollisionAlgorithm::processCollision (const btCollisionObjectWrap ///so we should add a 'refreshManifolds' in the btCollisionAlgorithm { int i; - btManifoldArray manifoldArray; + manifoldArray.resize(0); for (i=0;icollideTV(tree->m_root,bounds,callback); + tree->collideTVNoStackAlloc(tree->m_root,bounds,stack2,callback); } else { @@ -291,7 +291,7 @@ void btCompoundCollisionAlgorithm::processCollision (const btCollisionObjectWrap //iterate over all children, perform an AABB check inside ProcessChildShape int numChildren = m_childCollisionAlgorithms.size(); int i; - btManifoldArray manifoldArray; + manifoldArray.resize(0); const btCollisionShape* childShape = 0; btTransform orgTrans; diff --git a/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h b/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h index 7d792c18d..ea469e7ca 100644 --- a/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h +++ b/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h @@ -26,6 +26,7 @@ class btDispatcher; #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" #include "btCollisionCreateFunc.h" #include "LinearMath/btAlignedObjectArray.h" +#include "BulletCollision/BroadPhaseCollision/btDbvt.h" class btDispatcher; class btCollisionObject; @@ -36,6 +37,9 @@ extern btShapePairCallback gCompoundChildShapePairCallback; /// btCompoundCollisionAlgorithm supports collision between CompoundCollisionShapes and other collision shapes class btCompoundCollisionAlgorithm : public btActivatingCollisionAlgorithm { + btNodeStack stack2; + btManifoldArray manifoldArray; + protected: btAlignedObjectArray m_childCollisionAlgorithms; bool m_isSwapped; diff --git a/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp index 7f2722aa4..b9cc04186 100644 --- a/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp +++ b/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp @@ -503,9 +503,11 @@ void btConvexConvexAlgorithm ::processCollision (const btCollisionObjectWrapper* // printf("sepNormalWorldSpace=%f,%f,%f\n",sepNormalWorldSpace.getX(),sepNormalWorldSpace.getY(),sepNormalWorldSpace.getZ()); + worldVertsB1.resize(0); btPolyhedralContactClipping::clipHullAgainstHull(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(), body0Wrap->getWorldTransform(), - body1Wrap->getWorldTransform(), minDist-threshold, threshold, *resultOut); + body1Wrap->getWorldTransform(), minDist-threshold, threshold, worldVertsB1,worldVertsB2, + *resultOut); } if (m_ownManifold) @@ -568,8 +570,9 @@ void btConvexConvexAlgorithm ::processCollision (const btCollisionObjectWrapper* if (foundSepAxis) { + worldVertsB2.resize(0); btPolyhedralContactClipping::clipFaceAgainstHull(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(), - body0Wrap->getWorldTransform(), vertices, minDist-threshold, maxDist, *resultOut); + body0Wrap->getWorldTransform(), vertices, worldVertsB2,minDist-threshold, maxDist, *resultOut); } diff --git a/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h b/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h index 51db0c654..d0ff3b3c1 100644 --- a/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h +++ b/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h @@ -24,6 +24,7 @@ subject to the following restrictions: #include "btCollisionCreateFunc.h" #include "btCollisionDispatcher.h" #include "LinearMath/btTransformUtil.h" //for btConvexSeparatingDistanceUtil +#include "BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h" class btConvexPenetrationDepthSolver; @@ -45,6 +46,8 @@ class btConvexConvexAlgorithm : public btActivatingCollisionAlgorithm btSimplexSolverInterface* m_simplexSolver; btConvexPenetrationDepthSolver* m_pdSolver; + btVertexArray worldVertsB1; + btVertexArray worldVertsB2; bool m_ownManifold; btPersistentManifold* m_manifoldPtr; diff --git a/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp b/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp index d5f4a964b..ea380bc5f 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp +++ b/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp @@ -411,9 +411,9 @@ bool btPolyhedralContactClipping::findSeparatingAxis( const btConvexPolyhedron& 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* pVtxOut = &worldVertsB2; 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(); @@ -552,7 +552,7 @@ void btPolyhedralContactClipping::clipHullAgainstHull(const btVector3& separatin } } } - btVertexArray worldVertsB1; + worldVertsB1.resize(0); { const btFace& polyB = hullB.m_faces[closestFaceB]; const int numVertices = polyB.m_indices.size(); @@ -565,6 +565,6 @@ void btPolyhedralContactClipping::clipHullAgainstHull(const btVector3& separatin if (closestFaceB>=0) - clipFaceAgainstHull(separatingNormal, hullA, transA,worldVertsB1, minDist, maxDist,resultOut); + clipFaceAgainstHull(separatingNormal, hullA, transA,worldVertsB1, worldVertsB2,minDist, maxDist,resultOut); } diff --git a/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h b/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h index b87bd4f32..30e3db687 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h +++ b/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h @@ -32,8 +32,11 @@ typedef btAlignedObjectArray btVertexArray; // Clips a face to the back of a plane 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); diff --git a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp index a9c0b33b3..d94d1d4ea 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp +++ b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp @@ -396,22 +396,17 @@ btMultiBodyDynamicsWorld::~btMultiBodyDynamicsWorld () void btMultiBodyDynamicsWorld::forwardKinematics() { - btAlignedObjectArray world_to_local; - btAlignedObjectArray local_origin; for (int b=0;bforwardKinematics(world_to_local,local_origin); + bod->forwardKinematics(m_scratch_world_to_local,m_scratch_local_origin); } } void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) { forwardKinematics(); - btAlignedObjectArray scratch_r; - btAlignedObjectArray scratch_v; - btAlignedObjectArray scratch_m; BT_PROFILE("solveConstraints"); @@ -463,9 +458,9 @@ void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) if (!isSleeping) { //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) - scratch_v.resize(bod->getNumLinks()+1); - scratch_m.resize(bod->getNumLinks()+1); + m_scratch_r.resize(bod->getNumLinks()+1); //multidof? ("Y"s use it and it is used to store qdd) + m_scratch_v.resize(bod->getNumLinks()+1); + m_scratch_m.resize(bod->getNumLinks()+1); bod->addBaseForce(m_gravity * bod->getBaseMass()); @@ -500,15 +495,15 @@ void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) if (!isSleeping) { //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) - scratch_v.resize(bod->getNumLinks()+1); - scratch_m.resize(bod->getNumLinks()+1); + m_scratch_r.resize(bod->getNumLinks()+1); //multidof? ("Y"s use it and it is used to store qdd) + m_scratch_v.resize(bod->getNumLinks()+1); + m_scratch_m.resize(bod->getNumLinks()+1); bool doNotUpdatePos = false; { 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 { @@ -594,9 +589,9 @@ void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) // btScalar h = solverInfo.m_timeStep; - #define output &scratch_r[bod->getNumDofs()] + #define output &m_scratch_r[bod->getNumDofs()] //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); //calc q1 = q0 + h/2 * qd0 pResetQx(); @@ -606,7 +601,7 @@ void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) // //calc qdd1 from: q1 & 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); //calc q2 = q0 + h/2 * qd1 pResetQx(); @@ -616,7 +611,7 @@ void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) // //calc qdd2 from: q2 & 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); //calc q3 = q0 + h * qd2 pResetQx(); @@ -626,7 +621,7 @@ void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) // //calc qdd3 from: q3 & 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); // @@ -661,7 +656,7 @@ void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) { for(int link = 0; link < bod->getNumLinks(); ++link) 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) { //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) - scratch_v.resize(bod->getNumLinks()+1); - scratch_m.resize(bod->getNumLinks()+1); + m_scratch_r.resize(bod->getNumLinks()+1); //multidof? ("Y"s use it and it is used to store qdd) + m_scratch_v.resize(bod->getNumLinks()+1); + m_scratch_m.resize(bod->getNumLinks()+1); { if(!bod->isUsingRK4Integration()) { 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,9 +727,7 @@ void btMultiBodyDynamicsWorld::integrateTransforms(btScalar timeStep) { BT_PROFILE("btMultiBody stepPositions"); //integrate and update the Featherstone hierarchies - btAlignedObjectArray world_to_local; - btAlignedObjectArray local_origin; - + for (int b=0;bupdateCollisionObjectWorldTransforms(world_to_local,local_origin); + bod->updateCollisionObjectWorldTransforms(m_scratch_world_to_local,m_scratch_local_origin); } else { @@ -818,8 +811,6 @@ void btMultiBodyDynamicsWorld::debugDrawWorld() { BT_PROFILE("btMultiBody debugDrawWorld"); - btAlignedObjectArray world_to_local1; - btAlignedObjectArray local_origin1; for (int c=0;cforwardKinematics(world_to_local1,local_origin1); + bod->forwardKinematics(m_scratch_world_to_local1,m_scratch_local_origin1); getDebugDrawer()->drawTransform(bod->getBaseWorldTransform(), 0.1); diff --git a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h index 03ef3335c..2c912da5c 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h +++ b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h @@ -36,6 +36,16 @@ protected: btMultiBodyConstraintSolver* m_multiBodyConstraintSolver; MultiBodyInplaceSolverIslandCallback* m_solverMultiBodyIslandCallback; + //cached data to avoid memory allocations + btAlignedObjectArray m_scratch_world_to_local; + btAlignedObjectArray m_scratch_local_origin; + btAlignedObjectArray m_scratch_world_to_local1; + btAlignedObjectArray m_scratch_local_origin1; + btAlignedObjectArray m_scratch_r; + btAlignedObjectArray m_scratch_v; + btAlignedObjectArray m_scratch_m; + + virtual void calculateSimulationIslands(); virtual void updateActivationState(btScalar timeStep); virtual void solveConstraints(btContactSolverInfo& solverInfo); diff --git a/src/LinearMath/btAlignedAllocator.h b/src/LinearMath/btAlignedAllocator.h index f168f3c66..3cc6140de 100644 --- a/src/LinearMath/btAlignedAllocator.h +++ b/src/LinearMath/btAlignedAllocator.h @@ -21,7 +21,7 @@ subject to the following restrictions: ///that is better portable and more predictable #include "btScalar.h" -//#define BT_DEBUG_MEMORY_ALLOCATIONS 1 +///#define BT_DEBUG_MEMORY_ALLOCATIONS 1 #ifdef BT_DEBUG_MEMORY_ALLOCATIONS #define btAlignedAlloc(a,b) \ From 589fa376b3a0075b970a9376891e8e4a4ac76fc4 Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Sat, 16 Jul 2016 17:58:06 -0700 Subject: [PATCH 07/10] only add compound child shapes to 'allocated' list once --- .../ImportURDFDemo/BulletUrdfImporter.cpp | 2 +- .../PhysicsServerCommandProcessor.cpp | 18 ------------------ 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp b/examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp index 628d99bc2..f081325b3 100644 --- a/examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp +++ b/examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp @@ -1065,7 +1065,7 @@ btCollisionShape* BulletURDFImporter::getAllocatedCollisionShape(int index) btTransform childTrans = col.m_linkLocalFrame; compoundShape->addChildShape(localInertiaFrame.inverse()*childTrans,childShape); - } + } } } diff --git a/examples/SharedMemory/PhysicsServerCommandProcessor.cpp b/examples/SharedMemory/PhysicsServerCommandProcessor.cpp index cce14de16..3f08f88e2 100644 --- a/examples/SharedMemory/PhysicsServerCommandProcessor.cpp +++ b/examples/SharedMemory/PhysicsServerCommandProcessor.cpp @@ -701,15 +701,6 @@ bool PhysicsServerCommandProcessor::loadSdf(const char* fileName, char* bufferSe { btCollisionShape* shape =u2b.getAllocatedCollisionShape(i); m_data->m_collisionShapes.push_back(shape); - if (shape->isCompound()) - { - btCompoundShape* compound = (btCompoundShape*) shape; - for (int childIndex=0;childIndexgetNumChildShapes();childIndex++) - { - m_data->m_collisionShapes.push_back(compound->getChildShape(childIndex)); - } - } - } btTransform rootTrans; @@ -851,15 +842,6 @@ bool PhysicsServerCommandProcessor::loadUrdf(const char* fileName, const btVecto { btCollisionShape* shape =u2b.getAllocatedCollisionShape(i); m_data->m_collisionShapes.push_back(shape); - if (shape->isCompound()) - { - btCompoundShape* compound = (btCompoundShape*) shape; - for (int childIndex=0;childIndexgetNumChildShapes();childIndex++) - { - m_data->m_collisionShapes.push_back(compound->getChildShape(childIndex)); - } - } - } btMultiBody* mb = creation.getBulletMultiBody(); From c54a61b97a98e770cf95752c00008a7eec933a1a Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Sat, 16 Jul 2016 21:29:31 -0700 Subject: [PATCH 08/10] More example code is memory-leak free now, in particular PhysicsServerExample. /PhysicsServerCommandProcessor also fixed some memory issue in InverseDynamicsExample (the base class is supposed to delete collision shape memory) --- .../GwenGUISupport/GraphingTexture.cpp | 1 + .../ExampleBrowser/OpenGLExampleBrowser.cpp | 4 + examples/ExampleBrowser/main.cpp | 8 +- .../InverseDynamicsExample.cpp | 9 +-- .../PhysicsServerCommandProcessor.cpp | 4 + .../PhysicsServerSharedMemory.cpp | 1 - .../TinyRendererVisualShapeConverter.cpp | 11 ++- src/LinearMath/btAlignedAllocator.cpp | 78 +++++++++++++++++-- src/LinearMath/btAlignedAllocator.h | 6 ++ 9 files changed, 104 insertions(+), 18 deletions(-) diff --git a/examples/ExampleBrowser/GwenGUISupport/GraphingTexture.cpp b/examples/ExampleBrowser/GwenGUISupport/GraphingTexture.cpp index 4cfcc8f10..7a87be819 100644 --- a/examples/ExampleBrowser/GwenGUISupport/GraphingTexture.cpp +++ b/examples/ExampleBrowser/GwenGUISupport/GraphingTexture.cpp @@ -21,6 +21,7 @@ void GraphingTexture::destroy() m_height=0; glDeleteTextures(1,(GLuint*)&m_textureId); m_textureId=0; + } bool GraphingTexture::create(int texWidth, int texHeight) diff --git a/examples/ExampleBrowser/OpenGLExampleBrowser.cpp b/examples/ExampleBrowser/OpenGLExampleBrowser.cpp index 18578c71a..e06d5f205 100644 --- a/examples/ExampleBrowser/OpenGLExampleBrowser.cpp +++ b/examples/ExampleBrowser/OpenGLExampleBrowser.cpp @@ -675,7 +675,10 @@ struct QuickCanvas : public Common2dCanvasInterface virtual void destroyCanvas(int canvasId) { btAssert(canvasId>=0); + delete m_gt[canvasId]; + m_gt[canvasId] = 0; destroyTextureWindow(m_gw[canvasId]); + m_gw[canvasId] = 0; m_curNumGraphWindows--; } virtual void setPixel(int canvasId, int x, int y, unsigned char red, unsigned char green,unsigned char blue, unsigned char alpha) @@ -745,6 +748,7 @@ OpenGLExampleBrowser::~OpenGLExampleBrowser() delete m_internalData; + gFileImporterByExtension.clear(); gAllExamples = 0; } diff --git a/examples/ExampleBrowser/main.cpp b/examples/ExampleBrowser/main.cpp index 7a155d6c0..f5b05211c 100644 --- a/examples/ExampleBrowser/main.cpp +++ b/examples/ExampleBrowser/main.cpp @@ -15,7 +15,7 @@ #include "../Importers/ImportURDFDemo/ImportURDFSetup.h" #include "../Importers/ImportSDFDemo/ImportSDFSetup.h" #include "../Importers/ImportSTLDemo/ImportSTLSetup.h" - +#include "LinearMath/btAlignedAllocator.h" int main(int argc, char* argv[]) @@ -49,5 +49,11 @@ int main(int argc, char* argv[]) delete exampleBrowser; } + +//#ifdef BT_DEBUG_MEMORY_ALLOCATIONS + int numBytesLeaked = btDumpMemoryLeaks(); + btAssert(numBytesLeaked==0); +//#endif//BT_DEBUG_MEMORY_ALLOCATIONS + return 0; } diff --git a/examples/InverseDynamics/InverseDynamicsExample.cpp b/examples/InverseDynamics/InverseDynamicsExample.cpp index 986f9024b..ebf7efb0d 100644 --- a/examples/InverseDynamics/InverseDynamicsExample.cpp +++ b/examples/InverseDynamics/InverseDynamicsExample.cpp @@ -73,7 +73,6 @@ class InverseDynamicsExample : public CommonMultiBodyBase { btInverseDynamicsExampleOptions m_option; btMultiBody* m_multiBody; - btAlignedObjectArray m_allocatedShapes; btInverseDynamics::MultiBodyTree *m_inverseModel; TimeSeriesCanvas* m_timeSeriesCanvas; public: @@ -107,12 +106,6 @@ InverseDynamicsExample::InverseDynamicsExample(struct GUIHelperInterface* helper InverseDynamicsExample::~InverseDynamicsExample() { - delete m_multiBody; - for (int i = 0; i < m_allocatedShapes.size(); i++) - { - delete m_allocatedShapes[i]; - } - m_allocatedShapes.resize(0); delete m_inverseModel; delete m_timeSeriesCanvas; } @@ -175,7 +168,7 @@ void InverseDynamicsExample::initPhysics() ConvertURDF2Bullet(u2b,creation, identityTrans,m_dynamicsWorld,true,u2b.getPathPrefix()); for (int i = 0; i < u2b.getNumAllocatedCollisionShapes(); i++) { - m_allocatedShapes.push_back(u2b.getAllocatedCollisionShape(i)); + m_collisionShapes.push_back(u2b.getAllocatedCollisionShape(i)); } m_multiBody = creation.getBulletMultiBody(); if (m_multiBody) diff --git a/examples/SharedMemory/PhysicsServerCommandProcessor.cpp b/examples/SharedMemory/PhysicsServerCommandProcessor.cpp index 3f08f88e2..5c82e3381 100644 --- a/examples/SharedMemory/PhysicsServerCommandProcessor.cpp +++ b/examples/SharedMemory/PhysicsServerCommandProcessor.cpp @@ -31,6 +31,10 @@ struct UrdfLinkNameMapUtil UrdfLinkNameMapUtil():m_mb(0),m_memSerializer(0) { } + virtual ~UrdfLinkNameMapUtil() + { + delete m_memSerializer; + } }; diff --git a/examples/SharedMemory/PhysicsServerSharedMemory.cpp b/examples/SharedMemory/PhysicsServerSharedMemory.cpp index 0d29fae1e..d0b583969 100644 --- a/examples/SharedMemory/PhysicsServerSharedMemory.cpp +++ b/examples/SharedMemory/PhysicsServerSharedMemory.cpp @@ -78,7 +78,6 @@ PhysicsServerSharedMemory::PhysicsServerSharedMemory(SharedMemoryInterface* shar } m_data->m_commandProcessor = new PhysicsServerCommandProcessor; - m_data->m_commandProcessor ->createEmptyDynamicsWorld(); } diff --git a/examples/SharedMemory/TinyRendererVisualShapeConverter.cpp b/examples/SharedMemory/TinyRendererVisualShapeConverter.cpp index 92bca7498..9457652a6 100644 --- a/examples/SharedMemory/TinyRendererVisualShapeConverter.cpp +++ b/examples/SharedMemory/TinyRendererVisualShapeConverter.cpp @@ -701,7 +701,16 @@ void TinyRendererVisualShapeConverter::copyCameraImageData(unsigned char* pixels void TinyRendererVisualShapeConverter::resetAll() { - //todo: free memory + for (int i=0;im_swRenderInstances.size();i++) + { + TinyRendererObjectArray** ptrptr = m_data->m_swRenderInstances.getAtIndex(i); + if (ptrptr && *ptrptr) + { + TinyRendererObjectArray* ptr = *ptrptr; + delete ptr; + } + } + m_data->m_swRenderInstances.clear(); } diff --git a/src/LinearMath/btAlignedAllocator.cpp b/src/LinearMath/btAlignedAllocator.cpp index 3209b86ee..e5f6040c4 100644 --- a/src/LinearMath/btAlignedAllocator.cpp +++ b/src/LinearMath/btAlignedAllocator.cpp @@ -105,6 +105,27 @@ void btAlignedAllocSetCustom(btAllocFunc *allocFunc, btFreeFunc *freeFunc) } #ifdef BT_DEBUG_MEMORY_ALLOCATIONS + +static int allocations_id[10241024]; +static int allocations_bytes[10241024]; +static int mynumallocs = 0; +#include + +int btDumpMemoryLeaks() +{ + int totalLeak = 0; + + for (int i=0;i @@ -122,32 +143,56 @@ struct btDebugPtrMagic 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; 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; gNumAlignedAllocs++; -int sz2prt = 2*sizeof(void *); +int sz4prt = 4*sizeof(void *); - real = (char *)sAllocFunc(size + sz2prt + (alignment-1)); + real = (char *)sAllocFunc(size + sz4prt + (alignment-1)); if (real) { - ret = (void*) btAlignPointer(real + sz2prt, alignment); + ret = (void*) btAlignPointer(real + sz4prt, alignment); 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 { ret = (void *)(real);//?? } - printf("allocation#%d at address %x, from %s,line %d, size %d (total allocated = %d)\n",gNumAlignedAllocs,real, filename,line,size,gTotalBytesAlignedAllocs); - + 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; *ptr = 12; return (ret); @@ -157,19 +202,38 @@ void btAlignedFreeInternal (void* ptr,int line,char* filename) { void* real; - gNumAlignedFree++; if (ptr) { + gNumAlignedFree++; + 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 Date: Sat, 16 Jul 2016 21:36:40 -0700 Subject: [PATCH 09/10] fix: accidently enable memory-leak debug test --- examples/ExampleBrowser/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/ExampleBrowser/main.cpp b/examples/ExampleBrowser/main.cpp index f5b05211c..d0f132c1a 100644 --- a/examples/ExampleBrowser/main.cpp +++ b/examples/ExampleBrowser/main.cpp @@ -50,10 +50,10 @@ int main(int argc, char* argv[]) } -//#ifdef BT_DEBUG_MEMORY_ALLOCATIONS +#ifdef BT_DEBUG_MEMORY_ALLOCATIONS int numBytesLeaked = btDumpMemoryLeaks(); btAssert(numBytesLeaked==0); -//#endif//BT_DEBUG_MEMORY_ALLOCATIONS +#endif//BT_DEBUG_MEMORY_ALLOCATIONS return 0; } From f9096c2e30bbcbcac8954c1a9f19c36872e97ac6 Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Sat, 16 Jul 2016 21:47:07 -0700 Subject: [PATCH 10/10] typo/case sensitivity BroadphaseCollision vs NarrowPhaseCollision, aargh --- .../CollisionDispatch/btCompoundCollisionAlgorithm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h b/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h index ea469e7ca..d2086fbc0 100644 --- a/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h +++ b/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h @@ -26,7 +26,7 @@ class btDispatcher; #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" #include "btCollisionCreateFunc.h" #include "LinearMath/btAlignedObjectArray.h" -#include "BulletCollision/BroadPhaseCollision/btDbvt.h" +#include "BulletCollision/BroadphaseCollision/btDbvt.h" class btDispatcher; class btCollisionObject;