generate convex hull/cluster using 'G' while the tests are running

This commit is contained in:
Irlan 2018-04-20 03:13:16 -03:00
parent c413f4d8aa
commit 43f59409de
3 changed files with 125 additions and 59 deletions

View File

@ -17,8 +17,8 @@
*/ */
#include <testbed/framework/test.h> #include <testbed/framework/test.h>
#include <testbed/tests/quickhull_test.h> #include <testbed/tests/convex_hull.h>
#include <testbed/tests/cluster_test.h> #include <testbed/tests/cluster.h>
#include <testbed/tests/distance_test.h> #include <testbed/tests/distance_test.h>
#include <testbed/tests/collide_test.h> #include <testbed/tests/collide_test.h>
#include <testbed/tests/capsule_collision.h> #include <testbed/tests/capsule_collision.h>
@ -69,9 +69,9 @@
TestEntry g_tests[] = TestEntry g_tests[] =
{ {
{ "Quickhull Test", &QuickhullTest::Create }, { "Convex Hull", &ConvexHull::Create },
{ "Cluster Test", &Cluster::Create }, { "Cluster", &Cluster::Create },
{ "Distance Test", &Distance::Create }, { "Distance", &Distance::Create },
{ "Capsule Collision", &CapsuleCollision::Create }, { "Capsule Collision", &CapsuleCollision::Create },
{ "Deep Capsule", &DeepCapsule::Create }, { "Deep Capsule", &DeepCapsule::Create },
{ "Degenerate Capsule", &DegenerateCapsule::Create }, { "Degenerate Capsule", &DegenerateCapsule::Create },

View File

@ -24,45 +24,77 @@
class Cluster : public Test class Cluster : public Test
{ {
public: public:
enum
{
e_count = 64
};
Cluster() Cluster()
{ {
// Initialize observations Generate();
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;
m_solver.AddObservation(obs);
} }
// Initialize clusters void Generate()
m_solver.Solve();
const b3Array<b3Cluster>& clusters = m_solver.GetClusters();
m_colors.Resize(clusters.Count());
for (u32 i = 0; i < clusters.Count(); ++i)
{ {
m_colors[i] = b3Color(RandomFloat(0.0f, 1.0f), RandomFloat(0.0f, 1.0f), RandomFloat(0.0f, 1.0f)); 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;
}
for (u32 i = 0; i < B3_MAX_MANIFOLDS; ++i)
{
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() void Step()
{ {
const b3Array<b3Observation>& observations = m_solver.GetObservations(); b3ClusterSolver cluster;
const b3Array<b3Cluster>& clusters = m_solver.GetClusters();
// 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<b3Observation>& observations = cluster.GetObservations();
const b3Array<b3Cluster>& clusters = cluster.GetClusters();
B3_ASSERT(clusters.Count() <= B3_MAX_MANIFOLDS);
for (u32 i = 0; i < clusters.Count(); ++i) for (u32 i = 0; i < clusters.Count(); ++i)
{ {
g_draw->DrawSegment(b3Vec3(0, 0, 0), clusters[i].centroid, b3Color(1, 1, 1)); b3Vec3 centroid = clusters[i].centroid;
g_draw->DrawPoint(clusters[i].centroid, 4.0f, m_colors[i]);
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) 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() static Test* Create()
@ -80,9 +115,8 @@ public:
return new Cluster(); return new Cluster();
} }
b3ClusterSolver m_solver; b3Vec3 m_points[e_count];
b3Color m_colors[B3_MAX_MANIFOLDS];
b3StackArray<b3Color, 32> m_colors;
}; };
#endif #endif

View File

@ -16,65 +16,97 @@
* 3. This notice may not be removed or altered from any source distribution. * 3. This notice may not be removed or altered from any source distribution.
*/ */
#ifndef QHULL_H #ifndef CONVEX_HULL_H
#define QHULL_H #define CONVEX_HULL_H
#include <bounce/quickhull/qh_hull.h> class ConvexHull : public Test
class QuickhullTest : public Test
{ {
public: public:
QuickhullTest() enum
{
// Half to avoid generation failure due to many vertices
e_count = B3_MAX_HULL_VERTICES / 2
};
ConvexHull()
{ {
b3BoxHull box; b3BoxHull box;
box.SetIdentity(); box.SetIdentity();
b3StackArray<b3Vec3, 256> tetra; b3Vec3 tetra[4];
b3Vec3 v1(-1.0f, 0.0f, 0.0f); b3Vec3 v1(-1.0f, 0.0f, 0.0f);
b3Vec3 v2(1.0f, 0.0f, 0.0f); b3Vec3 v2(1.0f, 0.0f, 0.0f);
b3Vec3 v3(0.0f, 0.0f, -1.0f); b3Vec3 v3(0.0f, 0.0f, -1.0f);
b3Vec3 v4 = 0.5f * (v1 + v2 + v3); b3Vec3 v4 = 0.5f * (v1 + v2 + v3);
v4.y += 2.0f; v4.y += 2.0f;
tetra.PushBack(v1); tetra[0] = v1;
tetra.PushBack(v2); tetra[1] = v2;
tetra.PushBack(v3); tetra[2] = v3;
tetra.PushBack(v4); tetra[3] = v4;
// Minkowski sum of box and tetrahedron // Minkowski sum of box and tetrahedron
b3StackArray<b3Vec3, 256> points; m_count = 0;
for (u32 i = 0; i < box.vertexCount; ++i) 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]; b3Vec3 p = box.vertices[i] - tetra[j];
points.PushBack(p);
m_points[m_count++] = p;
}
} }
} }
u32 size = qhGetMemorySize(points.Count()); ~ConvexHull()
m_memory = b3Alloc(size);
m_qhull.Construct(m_memory, points);
}
~QuickhullTest()
{ {
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() void Step()
{ {
g_draw->DrawString(b3Color_white, "Iterations = %d", m_qhull.GetIterations()); b3QHull hull;
m_qhull.Draw(); 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() static Test* Create()
{ {
return new QuickhullTest(); return new ConvexHull();
} }
void* m_memory; u32 m_count;
qhHull m_qhull; b3Vec3 m_points[e_count];
}; };
#endif #endif