diff --git a/examples/testbed/framework/test_entries.cpp b/examples/testbed/framework/test_entries.cpp index 55ca991..9255b2d 100644 --- a/examples/testbed/framework/test_entries.cpp +++ b/examples/testbed/framework/test_entries.cpp @@ -17,8 +17,8 @@ */ #include -#include -#include +#include +#include #include #include #include @@ -69,9 +69,9 @@ TestEntry g_tests[] = { - { "Quickhull Test", &QuickhullTest::Create }, - { "Cluster Test", &Cluster::Create }, - { "Distance Test", &Distance::Create }, + { "Convex Hull", &ConvexHull::Create }, + { "Cluster", &Cluster::Create }, + { "Distance", &Distance::Create }, { "Capsule Collision", &CapsuleCollision::Create }, { "Deep Capsule", &DeepCapsule::Create }, { "Degenerate Capsule", &DegenerateCapsule::Create }, diff --git a/examples/testbed/tests/cluster_test.h b/examples/testbed/tests/cluster.h similarity index 53% rename from examples/testbed/tests/cluster_test.h rename to examples/testbed/tests/cluster.h index 5829e2e..bd7b0b2 100644 --- a/examples/testbed/tests/cluster_test.h +++ b/examples/testbed/tests/cluster.h @@ -24,45 +24,77 @@ class Cluster : public Test { public: + enum + { + e_count = 64 + }; + Cluster() { - // Initialize observations - for (u32 i = 0; i < 90; ++i) - { - float32 x = RandomFloat(-1.0f, 1.0f); - float32 y = RandomFloat(-1.0f, 1.0f); - float32 z = RandomFloat(-1.0f, 1.0f); - - b3Observation obs; - obs.point.Set(x, y, z); - obs.point = b3Normalize(obs.point); - obs.cluster = B3_NULL_CLUSTER; + Generate(); + } - m_solver.AddObservation(obs); + void Generate() + { + for (u32 i = 0; i < e_count; ++i) + { + float32 x = 3.0f * RandomFloat(-1.0f, 1.0f); + float32 y = 3.0f * RandomFloat(-1.0f, 1.0f); + float32 z = 3.0f * RandomFloat(-1.0f, 1.0f); + + b3Vec3 p(x, y, z); + m_points[i] = p; } - - // Initialize clusters - m_solver.Solve(); - const b3Array& clusters = m_solver.GetClusters(); - - m_colors.Resize(clusters.Count()); - - for (u32 i = 0; i < clusters.Count(); ++i) + for (u32 i = 0; i < B3_MAX_MANIFOLDS; ++i) { - m_colors[i] = b3Color(RandomFloat(0.0f, 1.0f), RandomFloat(0.0f, 1.0f), RandomFloat(0.0f, 1.0f)); + float32 r = RandomFloat(0.0f, 1.0f); + float32 g = RandomFloat(0.0f, 1.0f); + float32 b = RandomFloat(0.0f, 1.0f); + + b3Color c(r, g, b); + m_colors[i] = c; + } + } + + void KeyDown(int button) + { + if (button == GLFW_KEY_G) + { + Generate(); } } void Step() { - const b3Array& observations = m_solver.GetObservations(); - const b3Array& clusters = m_solver.GetClusters(); + b3ClusterSolver cluster; + + // Initialize observations + for (u32 i = 0; i < e_count; ++i) + { + b3Observation obs; + obs.point = m_points[i]; + obs.point = b3Normalize(obs.point); + obs.cluster = B3_NULL_CLUSTER; + + cluster.AddObservation(obs); + } + + // Run cluster + cluster.Solve(); + + // Draw + const b3Array& observations = cluster.GetObservations(); + const b3Array& clusters = cluster.GetClusters(); + B3_ASSERT(clusters.Count() <= B3_MAX_MANIFOLDS); + for (u32 i = 0; i < clusters.Count(); ++i) { - g_draw->DrawSegment(b3Vec3(0, 0, 0), clusters[i].centroid, b3Color(1, 1, 1)); - g_draw->DrawPoint(clusters[i].centroid, 4.0f, m_colors[i]); + b3Vec3 centroid = clusters[i].centroid; + + g_draw->DrawSegment(b3Vec3_zero, centroid, b3Color_white); + g_draw->DrawPoint(centroid, 4.0f, m_colors[i]); for (u32 j = 0; j < observations.Count(); ++j) { @@ -73,6 +105,9 @@ public: } } } + + g_draw->DrawString(b3Color_white, "G - Generate a random cluster"); + g_draw->DrawString(b3Color_white, "Iterations = %d", cluster.GetIterations()); } static Test* Create() @@ -80,9 +115,8 @@ public: return new Cluster(); } - b3ClusterSolver m_solver; - - b3StackArray m_colors; + b3Vec3 m_points[e_count]; + b3Color m_colors[B3_MAX_MANIFOLDS]; }; -#endif +#endif \ No newline at end of file diff --git a/examples/testbed/tests/quickhull_test.h b/examples/testbed/tests/convex_hull.h similarity index 53% rename from examples/testbed/tests/quickhull_test.h rename to examples/testbed/tests/convex_hull.h index fec246a..389fc35 100644 --- a/examples/testbed/tests/quickhull_test.h +++ b/examples/testbed/tests/convex_hull.h @@ -16,65 +16,97 @@ * 3. This notice may not be removed or altered from any source distribution. */ -#ifndef QHULL_H -#define QHULL_H +#ifndef CONVEX_HULL_H +#define CONVEX_HULL_H -#include - -class QuickhullTest : public Test +class ConvexHull : public Test { public: - QuickhullTest() + enum + { + // Half to avoid generation failure due to many vertices + e_count = B3_MAX_HULL_VERTICES / 2 + }; + + ConvexHull() { b3BoxHull box; box.SetIdentity(); - b3StackArray tetra; + b3Vec3 tetra[4]; b3Vec3 v1(-1.0f, 0.0f, 0.0f); b3Vec3 v2(1.0f, 0.0f, 0.0f); b3Vec3 v3(0.0f, 0.0f, -1.0f); b3Vec3 v4 = 0.5f * (v1 + v2 + v3); v4.y += 2.0f; - tetra.PushBack(v1); - tetra.PushBack(v2); - tetra.PushBack(v3); - tetra.PushBack(v4); + tetra[0] = v1; + tetra[1] = v2; + tetra[2] = v3; + tetra[3] = v4; // Minkowski sum of box and tetrahedron - b3StackArray points; + m_count = 0; for (u32 i = 0; i < box.vertexCount; ++i) { - for (u32 j = 0; j < tetra.Count(); ++j) + for (u32 j = 0; j < 4; ++j) { b3Vec3 p = box.vertices[i] - tetra[j]; - points.PushBack(p); + + m_points[m_count++] = p; } } - - u32 size = qhGetMemorySize(points.Count()); - m_memory = b3Alloc(size); - m_qhull.Construct(m_memory, points); } - ~QuickhullTest() + ~ConvexHull() { - b3Free(m_memory); + + } + + void KeyDown(int button) + { + if (button == GLFW_KEY_G) + { + Generate(); + } + } + + void Generate() + { + m_count = 0; + for (u32 i = 0; i < e_count; ++i) + { + // Clamp to force coplanarities. + // This will stress the generation code. + float32 x = 3.0f * RandomFloat(-1.0f, 1.0f); + float32 y = 3.0f * RandomFloat(-1.0f, 1.0f); + float32 z = 3.0f * RandomFloat(-1.0f, 1.0f); + + b3Vec3 p(x, y, z); + m_points[m_count++] = p; + } } void Step() { - g_draw->DrawString(b3Color_white, "Iterations = %d", m_qhull.GetIterations()); - m_qhull.Draw(); + b3QHull hull; + hull.Set(m_points, m_count); + + b3HullShape shape; + shape.m_hull = &hull; + + g_draw->DrawSolidShape(&shape, b3Color_white, b3Transform_identity); + + g_draw->DrawString(b3Color_white, "G - Generate a random convex hull"); } static Test* Create() { - return new QuickhullTest(); + return new ConvexHull(); } - void* m_memory; - qhHull m_qhull; + u32 m_count; + b3Vec3 m_points[e_count]; }; #endif \ No newline at end of file