From c062bfc2d5f844162e3dd1d0e70827e8ebd04488 Mon Sep 17 00:00:00 2001 From: Tigran Gasparian Date: Fri, 31 Aug 2018 15:12:28 +0200 Subject: [PATCH 1/2] Removes visual shape data when a body gets removed. Problem description: When you add a body, remove it and then add a new body, the body id may be reused by Bullet. Because the visual shape data was not being removed when a body was removed, requesting the visual shape data for a 'recycled' body id results in both the visual shape data of the new body as well as the old one. Removing the visual shape data when the body gets removed fixes this. Changes the btAlignedObjectArray for visual shapes to a hashmap, so that removing is faster. Additionally, functions like getNumVisualShape don't perform a linear search anymore. --- .../TinyRendererVisualShapeConverter.cpp | 88 +++++++------------ 1 file changed, 32 insertions(+), 56 deletions(-) diff --git a/examples/SharedMemory/plugins/tinyRendererPlugin/TinyRendererVisualShapeConverter.cpp b/examples/SharedMemory/plugins/tinyRendererPlugin/TinyRendererVisualShapeConverter.cpp index 132cc2def..26a7bf831 100644 --- a/examples/SharedMemory/plugins/tinyRendererPlugin/TinyRendererVisualShapeConverter.cpp +++ b/examples/SharedMemory/plugins/tinyRendererPlugin/TinyRendererVisualShapeConverter.cpp @@ -67,7 +67,8 @@ struct TinyRendererVisualShapeConverterInternalData btHashMap m_swRenderInstances; - btAlignedObjectArray m_visualShapes; + // Maps bodyUniqueId to a list of visual shapes belonging to the body. + btHashMap> m_visualShapesMap; int m_upAxis; int m_swWidth; @@ -710,82 +711,56 @@ void TinyRendererVisualShapeConverter::convertVisualShapes( visualShape.m_tinyRendererTextureId = m_data->m_textures.size(); m_data->m_textures.push_back(textures[i]); } - m_data->m_visualShapes.push_back(visualShape); - + btAlignedObjectArray* shapes = m_data->m_visualShapesMap[visualShape.m_objectUniqueId]; + if (!shapes) { + m_data->m_visualShapesMap.insert(visualShape.m_objectUniqueId, btAlignedObjectArray()); + shapes = m_data->m_visualShapesMap[visualShape.m_objectUniqueId]; + + } + shapes->push_back(visualShape); } } } int TinyRendererVisualShapeConverter::getNumVisualShapes(int bodyUniqueId) { - int start = -1; - //find first one, then count how many - for (int i = 0; i < m_data->m_visualShapes.size(); i++) - { - if (m_data->m_visualShapes[i].m_objectUniqueId == bodyUniqueId) - { - start = i; - break; - } + btAlignedObjectArray* shapes = m_data->m_visualShapesMap[bodyUniqueId]; + if (shapes) { + return shapes->size(); } - int count = 0; - - if (start >= 0) - { - for (int i = start; i < m_data->m_visualShapes.size(); i++) - { - if (m_data->m_visualShapes[i].m_objectUniqueId == bodyUniqueId) - { - count++; - } - else - { - //storage of each visual shape for a given body unique id assumed to be contiguous - break; - } - } - } - return count; + return 0; } int TinyRendererVisualShapeConverter::getVisualShapesData(int bodyUniqueId, int shapeIndex, struct b3VisualShapeData* shapeData) { - int start = -1; - //find first one, then count how many - for (int i = 0; i < m_data->m_visualShapes.size(); i++) - { - if (m_data->m_visualShapes[i].m_objectUniqueId == bodyUniqueId) - { - start = i; - break; - } + btAlignedObjectArray* shapes = m_data->m_visualShapesMap[bodyUniqueId]; + if (!shapes) { + return 0; } - //int count = 0; - - if (start >= 0) - { - if (start + shapeIndex < m_data->m_visualShapes.size()) - { - *shapeData = m_data->m_visualShapes[start + shapeIndex]; - return 1; - } + if (shapes->size() <= shapeIndex) { + return 0; } - return 0; + *shapeData = shapes->at(shapeIndex); + return 1; } void TinyRendererVisualShapeConverter::changeRGBAColor(int bodyUniqueId, int linkIndex, int shapeIndex, const double rgbaColor[4]) { + btAlignedObjectArray* shapes = m_data->m_visualShapesMap[bodyUniqueId]; + if (!shapes) { + return; + } int start = -1; - for (int i = 0; i < m_data->m_visualShapes.size(); i++) + for (int i = 0; i < shapes->size(); i++) { - if (m_data->m_visualShapes[i].m_objectUniqueId == bodyUniqueId && m_data->m_visualShapes[i].m_linkIndex == linkIndex) + if (shapes->at(i).m_linkIndex == linkIndex) { - m_data->m_visualShapes[i].m_rgbaColor[0] = rgbaColor[0]; - m_data->m_visualShapes[i].m_rgbaColor[1] = rgbaColor[1]; - m_data->m_visualShapes[i].m_rgbaColor[2] = rgbaColor[2]; - m_data->m_visualShapes[i].m_rgbaColor[3] = rgbaColor[3]; + shapes->at(i).m_rgbaColor[0] = rgbaColor[0]; + shapes->at(i).m_rgbaColor[1] = rgbaColor[1]; + shapes->at(i).m_rgbaColor[2] = rgbaColor[2]; + shapes->at(i).m_rgbaColor[3] = rgbaColor[3]; } } @@ -1143,6 +1118,7 @@ void TinyRendererVisualShapeConverter::removeVisualShape(int collisionObjectUniq TinyRendererObjectArray* ptr = *ptrptr; if (ptr) { + m_data->m_visualShapesMap.remove(ptr->m_objectUniqueId); for (int o=0;om_renderObjects.size();o++) { delete ptr->m_renderObjects[o]; @@ -1182,7 +1158,7 @@ void TinyRendererVisualShapeConverter::resetAll() } m_data->m_textures.clear(); m_data->m_swRenderInstances.clear(); - m_data->m_visualShapes.clear(); + m_data->m_visualShapesMap.clear(); } From 93145f3979931d9a2e2282d9145ee5e4d5c4b463 Mon Sep 17 00:00:00 2001 From: Tigran Gasparian Date: Mon, 3 Sep 2018 10:37:22 +0200 Subject: [PATCH 2/2] Adding space to make compiler happy. --- .../tinyRendererPlugin/TinyRendererVisualShapeConverter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/SharedMemory/plugins/tinyRendererPlugin/TinyRendererVisualShapeConverter.cpp b/examples/SharedMemory/plugins/tinyRendererPlugin/TinyRendererVisualShapeConverter.cpp index 26a7bf831..d1403f2fc 100644 --- a/examples/SharedMemory/plugins/tinyRendererPlugin/TinyRendererVisualShapeConverter.cpp +++ b/examples/SharedMemory/plugins/tinyRendererPlugin/TinyRendererVisualShapeConverter.cpp @@ -68,7 +68,7 @@ struct TinyRendererVisualShapeConverterInternalData btHashMap m_swRenderInstances; // Maps bodyUniqueId to a list of visual shapes belonging to the body. - btHashMap> m_visualShapesMap; + btHashMap > m_visualShapesMap; int m_upAxis; int m_swWidth;