
Exact convex hull:
Polyhedron method:
- Code: Select all
Leadwerks::Shape* ShapeShrinkWrap(Leadwerks::Model* model,float* matf)
{
Leadwerks::Mat4 mat = Leadwerks::Mat4(matf);
Leadwerks::Vec3 p;
Leadwerks::PhysicsDriver* driver = Leadwerks::PhysicsDriver::GetCurrent();
Leadwerks::Shape* shape = NULL;
std::vector<Leadwerks::Vec3> points;
float mindist,d;
Leadwerks::Surface* hulldata = Leadwerks::Surface::Create();
//Collect vertices
for (int i = 0; i < model->CountSurfaces(); i++)
{
model->surfaces[i]->Transform(mat);
for (int v = 0; v < model->surfaces[i]->CountVertices(); v++)
{
p = model->surfaces[i]->GetVertexPosition(v);
points.push_back(p);
}
}
//Create planes
std::vector < Leadwerks::Plane > planes;
//Top
planes.push_back(Leadwerks::Plane(0, 1, 0, 0));
//Top ring
planes.push_back(Leadwerks::Plane(-1, 1, 0, 0));
planes.push_back(Leadwerks::Plane(1, 1, 0, 0));
planes.push_back(Leadwerks::Plane(0, 1, -1, 0));
planes.push_back(Leadwerks::Plane(0, 1, 1, 0));
planes.push_back(Leadwerks::Plane(-1, 1, -1, 0));
planes.push_back(Leadwerks::Plane(-1, 1, 1, 0));
planes.push_back(Leadwerks::Plane(1, 1, -1, 0));
planes.push_back(Leadwerks::Plane(1, 1, 1, 0));
//Middle ring
planes.push_back(Leadwerks::Plane(-1, 0, 0, 0));
planes.push_back(Leadwerks::Plane(1, 0, 0, 0));
planes.push_back(Leadwerks::Plane(0, 0, -1, 0));
planes.push_back(Leadwerks::Plane(0, 0, 1, 0));
planes.push_back(Leadwerks::Plane(-1, 0, -1, 0));
planes.push_back(Leadwerks::Plane(-1, 0, 1, 0));
planes.push_back(Leadwerks::Plane(1, 0, -1, 0));
planes.push_back(Leadwerks::Plane(1, 0, 1, 0));
//Bottom ring
planes.push_back(Leadwerks::Plane(-1, -1, 0, 0));
planes.push_back(Leadwerks::Plane(1, -1, 0, 0));
planes.push_back(Leadwerks::Plane(0, -1, -1, 0));
planes.push_back(Leadwerks::Plane(0, -1, 1, 0));
planes.push_back(Leadwerks::Plane(-1, -1, -1, 0));
planes.push_back(Leadwerks::Plane(-1, -1, 1, 0));
planes.push_back(Leadwerks::Plane(1, -1, -1, 0));
planes.push_back(Leadwerks::Plane(1, -1, 1, 0));
//Bottom
planes.push_back(Leadwerks::Plane(0, -1, 0, 0));
//Adjust planes
for (int i = 0; i < planes.size(); i++)
{
planes[i].Normalize();
for (int v = 0; v < points.size(); v++)
{
d = planes[i].DistanceToPoint(points[v]);
if (v == 0)
{
mindist = d;
}
else
{
mindist = min(mindist, d);
}
}
planes[i].d = mindist;
}
//Build shape
Leadwerks::Vec3 na, nb, nc;
for (int a = 0; a < planes.size(); a++)
{
na = planes[a].GetNormal();
for (int b = 0; b < planes.size(); b++)
{
if (b != a)
{
nb = planes[b].GetNormal();
for (int c = 0; c < planes.size(); c++)
{
if (c != a && c != b)
{
nc = planes[c].GetNormal();
if( planes[a].IntersectsPlanes(planes[b], planes[c],p))
{
bool ok = true;
for (int n = 0; n < planes.size(); n++)
{
if (n != a && n != b && n != c)
{
if (planes[n].DistanceToPoint(p) > 0.0)
{
ok = false;
exit;
}
}
}
if (ok) hulldata->AddVertex(-p);
}
}
}
}
}
}
if (hulldata->CountVertices() < 4)
{
hulldata->Release();
return NULL;
}
shape = Leadwerks::Shape::ConvexHull(hulldata);
hulldata->Release();
return shape;
}