Merge pull request #701 from erwincoumans/master
Remove many memory leaks/technical debt in example code.
This commit is contained in:
Binary file not shown.
@@ -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];
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;i<m_data->m_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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -42,19 +42,65 @@
|
||||
#include "../Importers/ImportURDFDemo/ImportURDFSetup.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 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<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()
|
||||
@@ -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;
|
||||
@@ -643,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)
|
||||
@@ -669,12 +704,51 @@ 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;
|
||||
|
||||
gFileImporterByExtension.clear();
|
||||
gAllExamples = 0;
|
||||
}
|
||||
|
||||
@@ -732,11 +806,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 +865,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 +936,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 +944,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 +991,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 +1012,7 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
|
||||
else
|
||||
{
|
||||
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);
|
||||
if (sCurrentDemo==0)
|
||||
{
|
||||
@@ -935,9 +1041,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 +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];
|
||||
float camDist = s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraDistance();
|
||||
@@ -1053,7 +1161,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 +1169,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 +1200,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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
|
||||
class OpenGLExampleBrowser : public ExampleBrowserInterface
|
||||
{
|
||||
|
||||
struct OpenGLExampleBrowserInternalData* m_internalData;
|
||||
|
||||
public:
|
||||
|
||||
OpenGLExampleBrowser(class ExampleEntries* examples);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
|
||||
|
||||
#include "OpenGLExampleBrowser.h"
|
||||
|
||||
#include "Bullet3Common/b3CommandLineArgs.h"
|
||||
@@ -14,38 +15,45 @@
|
||||
#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[])
|
||||
{
|
||||
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;
|
||||
|
||||
#ifdef BT_DEBUG_MEMORY_ALLOCATIONS
|
||||
int numBytesLeaked = btDumpMemoryLeaks();
|
||||
btAssert(numBytesLeaked==0);
|
||||
#endif//BT_DEBUG_MEMORY_ALLOCATIONS
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1058,13 +1058,14 @@ 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)
|
||||
{
|
||||
btTransform childTrans = col.m_linkLocalFrame;
|
||||
|
||||
compoundShape->addChildShape(localInertiaFrame.inverse()*childTrans,childShape);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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()));
|
||||
@@ -348,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);
|
||||
|
||||
@@ -61,7 +61,9 @@ static bool parseVector4(btVector4& vec4, const std::string& vector_str)
|
||||
vec4.setZero();
|
||||
btArray<std::string> pieces;
|
||||
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)
|
||||
{
|
||||
if (!pieces[i].empty())
|
||||
@@ -82,7 +84,9 @@ static bool parseVector3(btVector3& vec3, const std::string& vector_str, ErrorLo
|
||||
vec3.setZero();
|
||||
btArray<std::string> pieces;
|
||||
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)
|
||||
{
|
||||
if (!pieces[i].empty())
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#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);
|
||||
if (separators.size()==1)
|
||||
@@ -20,10 +20,9 @@ void urdfStringSplit( btAlignedObjectArray<std::string>&pieces, const std::strin
|
||||
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);
|
||||
for (int i=0;i<numSeps;i++)
|
||||
{
|
||||
@@ -32,8 +31,6 @@ void urdfStringSplit( btAlignedObjectArray<std::string>&pieces, const std::strin
|
||||
sep2[0] = seps[i];
|
||||
strArray.push_back(sep2);
|
||||
}
|
||||
return strArray;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
#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
|
||||
///See http://stackoverflow.com/questions/2531605/how-to-split-a-string-with-a-delimiter-larger-than-one-single-char
|
||||
|
||||
@@ -105,7 +105,7 @@ InverseDynamicsExample::InverseDynamicsExample(struct GUIHelperInterface* helper
|
||||
|
||||
InverseDynamicsExample::~InverseDynamicsExample()
|
||||
{
|
||||
delete m_multiBody;
|
||||
|
||||
delete m_inverseModel;
|
||||
delete m_timeSeriesCanvas;
|
||||
}
|
||||
@@ -166,6 +166,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_collisionShapes.push_back(u2b.getAllocatedCollisionShape(i));
|
||||
}
|
||||
m_multiBody = creation.getBulletMultiBody();
|
||||
if (m_multiBody)
|
||||
{
|
||||
|
||||
@@ -650,9 +650,14 @@ 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;
|
||||
TwDeleteDefaultFonts();
|
||||
m_window->closeWindow();
|
||||
|
||||
delete m_window;
|
||||
delete m_data ;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -31,6 +31,10 @@ struct UrdfLinkNameMapUtil
|
||||
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);
|
||||
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;
|
||||
@@ -851,15 +846,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;childIndex<compound->getNumChildShapes();childIndex++)
|
||||
{
|
||||
m_data->m_collisionShapes.push_back(compound->getChildShape(childIndex));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
btMultiBody* mb = creation.getBulletMultiBody();
|
||||
|
||||
@@ -78,7 +78,6 @@ PhysicsServerSharedMemory::PhysicsServerSharedMemory(SharedMemoryInterface* shar
|
||||
}
|
||||
|
||||
m_data->m_commandProcessor = new PhysicsServerCommandProcessor;
|
||||
m_data->m_commandProcessor ->createEmptyDynamicsWorld();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -701,7 +701,16 @@ void TinyRendererVisualShapeConverter::copyCameraImageData(unsigned char* pixels
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
|
||||
|
||||
|
||||
#include "OpenGLWindow/SimpleOpenGL3App.h"
|
||||
#include "Bullet3Common/b3Quaternion.h"
|
||||
#include "Bullet3Common/b3CommandLineArgs.h"
|
||||
@@ -58,98 +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<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());
|
||||
b3CommandLineArgs myArgs(argc, argv);
|
||||
|
||||
|
||||
delete app;
|
||||
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 < 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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<const btDbvtNode*> 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<const btDbvtNode*> 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<const btDbvtNode*> 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,
|
||||
|
||||
@@ -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;i<m_childCollisionAlgorithms.size();i++)
|
||||
{
|
||||
if (m_childCollisionAlgorithms[i])
|
||||
@@ -274,7 +274,7 @@ void btCompoundCollisionAlgorithm::processCollision (const btCollisionObjectWrap
|
||||
|
||||
const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax);
|
||||
//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
|
||||
{
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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<btCollisionAlgorithm*> m_childCollisionAlgorithms;
|
||||
bool m_isSwapped;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -32,8 +32,11 @@ typedef btAlignedObjectArray<btVector3> 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);
|
||||
|
||||
|
||||
@@ -396,22 +396,17 @@ btMultiBodyDynamicsWorld::~btMultiBodyDynamicsWorld ()
|
||||
|
||||
void btMultiBodyDynamicsWorld::forwardKinematics()
|
||||
{
|
||||
btAlignedObjectArray<btQuaternion> world_to_local;
|
||||
btAlignedObjectArray<btVector3> local_origin;
|
||||
|
||||
for (int b=0;b<m_multiBodies.size();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)
|
||||
{
|
||||
forwardKinematics();
|
||||
|
||||
btAlignedObjectArray<btScalar> scratch_r;
|
||||
btAlignedObjectArray<btVector3> scratch_v;
|
||||
btAlignedObjectArray<btMatrix3x3> 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<btQuaternion> world_to_local;
|
||||
btAlignedObjectArray<btVector3> local_origin;
|
||||
|
||||
|
||||
for (int b=0;b<m_multiBodies.size();b++)
|
||||
{
|
||||
btMultiBody* bod = m_multiBodies[b];
|
||||
@@ -770,10 +763,10 @@ void btMultiBodyDynamicsWorld::integrateTransforms(btScalar timeStep)
|
||||
}
|
||||
}
|
||||
|
||||
world_to_local.resize(nLinks+1);
|
||||
local_origin.resize(nLinks+1);
|
||||
m_scratch_world_to_local.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
|
||||
{
|
||||
@@ -818,8 +811,6 @@ void btMultiBodyDynamicsWorld::debugDrawWorld()
|
||||
{
|
||||
BT_PROFILE("btMultiBody debugDrawWorld");
|
||||
|
||||
btAlignedObjectArray<btQuaternion> world_to_local1;
|
||||
btAlignedObjectArray<btVector3> local_origin1;
|
||||
|
||||
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++)
|
||||
{
|
||||
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);
|
||||
|
||||
|
||||
@@ -36,6 +36,16 @@ protected:
|
||||
btMultiBodyConstraintSolver* m_multiBodyConstraintSolver;
|
||||
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 updateActivationState(btScalar timeStep);
|
||||
virtual void solveConstraints(btContactSolverInfo& solverInfo);
|
||||
|
||||
@@ -105,30 +105,94 @@ 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 <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
|
||||
#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)
|
||||
{
|
||||
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++;
|
||||
|
||||
|
||||
real = (char *)sAllocFunc(size + 2*sizeof(void *) + (alignment-1));
|
||||
int sz4prt = 4*sizeof(void *);
|
||||
|
||||
real = (char *)sAllocFunc(size + sz4prt + (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 + 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\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;
|
||||
*ptr = 12;
|
||||
return (ret);
|
||||
@@ -138,19 +202,43 @@ void btAlignedFreeInternal (void* ptr,int line,char* filename)
|
||||
{
|
||||
|
||||
void* real;
|
||||
gNumAlignedFree++;
|
||||
|
||||
if (ptr) {
|
||||
real = *((void **)(ptr)-1);
|
||||
int size = *((int*)(ptr)-2);
|
||||
gTotalBytesAlignedAllocs -= size;
|
||||
gNumAlignedFree++;
|
||||
|
||||
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);
|
||||
} else
|
||||
{
|
||||
printf("NULL ptr\n");
|
||||
//printf("deleting a NULL ptr, no effect\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,9 +21,15 @@ subject to the following restrictions:
|
||||
///that is better portable and more predictable
|
||||
|
||||
#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
|
||||
|
||||
int btDumpMemoryLeaks();
|
||||
|
||||
#define btAlignedAlloc(a,b) \
|
||||
btAlignedAllocInternal(a,b,__LINE__,__FILE__)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user