Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Top down tree rebuild #41

Merged
merged 5 commits into from
Jul 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion include/box2d/dynamic_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ typedef struct b2DynamicTree
int32_t nodeCount;
int32_t nodeCapacity;
int32_t freeList;
int32_t insertionCount;
int32_t proxyCount;
} b2DynamicTree;

/// Constructing the tree initializes the node pool.
Expand Down Expand Up @@ -99,6 +99,19 @@ float b2DynamicTree_GetAreaRatio(const b2DynamicTree* tree);
/// Build an optimal tree. Very expensive. For testing.
void b2DynamicTree_RebuildBottomUp(b2DynamicTree* tree);

struct b2ProxyMap
{
void* userData;
};

/// Get the number of proxies created
int32_t b2DynamicTree_GetProxyCount(const b2DynamicTree* tree);

/// Rebuild a the tree top down using the surface area heuristic. The provide map array must have length equal
/// to the proxy count. This map allows you to update your proxy indices since this operation invalidates the original indices.
/// See b2DynamicTree_GetProxyCount.
void b2DynamicTree_RebuildTopDownSAH(b2DynamicTree* tree, struct b2ProxyMap* mapArray, int32_t mapCount);

/// Shift the world origin. Useful for large worlds.
/// The shift formula is: position -= newOrigin
/// @param newOrigin the new origin with respect to the old origin
Expand Down
39 changes: 35 additions & 4 deletions samples/collection/sample_dynamic_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,14 @@ class DynamicTree : public Sample
m_moveFraction = 0.0f;
m_moveDelta = 0.1f;
m_proxies = nullptr;
m_mapArray = nullptr;
m_proxyCount = 0;
m_proxyCapacity = 0;
m_wx = 0.5f;
m_wy = 0.5f;

m_rowCount = 10;
m_columnCount = 10;
m_rowCount = 20;
m_columnCount = 20;
memset(&m_tree, 0, sizeof(m_tree));
BuildTree();
m_timeStamp = 0;
Expand All @@ -47,23 +48,26 @@ class DynamicTree : public Sample
m_endPoint = {0.0f, 0.0f};
m_queryDrag = false;
m_rayDrag = false;

m_topDown = false;
m_validate = true;
}

~DynamicTree()
{
free(m_proxies);
free(m_mapArray);
b2DynamicTree_Destroy(&m_tree);
}

void BuildTree()
{
b2DynamicTree_Destroy(&m_tree);
free(m_proxies);
free(m_mapArray);

m_proxyCapacity = m_rowCount * m_columnCount;
m_proxies = static_cast<Proxy*>(malloc(m_proxyCapacity * sizeof(Proxy)));
m_mapArray = static_cast<struct b2ProxyMap*>(malloc(m_proxyCapacity * sizeof(struct b2ProxyMap)));
m_proxyCount = 0;

float y = -4.0f;
Expand Down Expand Up @@ -95,12 +99,14 @@ class DynamicTree : public Sample

y += m_wy;
}

m_topDown = false;
}

void UpdateUI() override
{
ImGui::SetNextWindowPos(ImVec2(10.0f, 100.0f));
ImGui::SetNextWindowSize(ImVec2(230.0f, 220.0f));
ImGui::SetNextWindowSize(ImVec2(240.0f, 250.0f));
ImGui::Begin("Tree Controls", nullptr, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize);

bool changed = false;
Expand Down Expand Up @@ -131,6 +137,18 @@ class DynamicTree : public Sample
{
}

if (ImGui::Button("Rebuild Top Down"))
{
assert(m_proxyCount == b2DynamicTree_GetProxyCount(&m_tree));
b2DynamicTree_RebuildTopDownSAH(&m_tree, m_mapArray, m_proxyCount);
for (int32_t i = 0; i < m_proxyCount; ++i)
{
Proxy* proxy = static_cast<Proxy*>(m_mapArray[i].userData);
proxy->proxyId = i;
}
m_topDown = true;
}

ImGui::Separator();

ImGui::Text("mouse button 1: ray cast");
Expand Down Expand Up @@ -245,6 +263,17 @@ class DynamicTree : public Sample
b2DynamicTree_Validate(&m_tree);
}

if (m_topDown)
{
g_draw.DrawString(5, m_textLine, "top down");
m_textLine += m_textIncrement;
}
else
{
g_draw.DrawString(5, m_textLine, "incremental");
m_textLine += m_textIncrement;
}

m_timeStamp += 1;
}

Expand All @@ -256,6 +285,7 @@ class DynamicTree : public Sample
b2DynamicTree m_tree;
int m_rowCount, m_columnCount;
Proxy* m_proxies;
struct b2ProxyMap* m_mapArray;
int m_proxyCapacity;
int m_proxyCount;
int m_timeStamp;
Expand All @@ -270,6 +300,7 @@ class DynamicTree : public Sample
bool m_rayDrag;
bool m_queryDrag;
bool m_validate;
bool m_topDown;
};

static bool QueryCallback(int32_t proxyId, void* userData, void* context)
Expand Down
27 changes: 20 additions & 7 deletions samples/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -498,13 +498,26 @@ int main(int, char**)
{
#if defined(_WIN32)
// Enable memory-leak reports
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT);
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDOUT);
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT);
_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
//_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
//_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDOUT);
//_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
//_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT);
{
// Get the current bits
//int tmp = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);

// Clear the upper 16 bits and OR in the desired frequency
//tmp = (tmp & 0x0000FFFF) | _CRTDBG_CHECK_EVERY_16_DF;

// Set the new bits
//_CrtSetDbgFlag(tmp);

//_CrtSetDbgFlag(_CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_CHECK_CRT_DF | _CRTDBG_LEAK_CHECK_DF);
//_CrtSetDbgFlag(_CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG));
//_CrtSetDbgFlag(_CRTDBG_DELAY_FREE_MEM_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG));
}
_CrtSetAllocHook(MyAllocHook);
//_CrtSetBreakAlloc(196);
#endif
Expand Down
Loading