-
Notifications
You must be signed in to change notification settings - Fork 98
Open
Description
in Shape.h
void SetBox( real hw, real hh )
{
m_vertexCount = 4;
m_vertices[0].Set( -hw, -hh );
m_vertices[1].Set( hw, -hh );
m_vertices[2].Set( hw, hh );
m_vertices[3].Set( -hw, hh );
m_normals[0].Set( 0.0f, -1.0f );
m_normals[1].Set( 1.0f, 0.0f );
m_normals[2].Set( 0.0f, 1.0f );
m_normals[3].Set( -1.0f, 0.0f );
}
for (;;)
{
hull[outCount] = indexHull;
// Search for next index that wraps around the hull
// by computing cross products to find the most counter-clockwise
// vertex in the set, given the previos hull index
int32 nextHullIndex = 0;
for(int32 i = 1; i < (int32)count; ++i)
{
// Skip if same coordinate as we need three unique
// points in the set to perform a cross product
if(nextHullIndex == indexHull)
{
nextHullIndex = i;
continue;
}
// Cross every set of three unique vertices
// Record each counter clockwise third vertex and add
// to the output hull
// See : http://www.oocities.org/pcgpe/math2d.html
Vec2 e1 = vertices[nextHullIndex] - vertices[hull[outCount]];
Vec2 e2 = vertices[i] - vertices[hull[outCount]];
real c = Cross( e1, e2 );
if(c > 0.0f)
nextHullIndex = i;
// Cross product is zero then e vectors are on same line
// therefor want to record vertex farthest along that line
if(c == 0.0f && e2.LenSqr( ) > e1.LenSqr( ))
nextHullIndex = i;
}
++outCount;
indexHull = nextHullIndex;
// Conclude algorithm upon wrap-around
if(nextHullIndex == rightMost)
{
m_vertexCount = outCount;
break;
}
}
// Copy vertices into shape's vertices
for(uint32 i = 0; i < m_vertexCount; ++i)
m_vertices[i] = vertices[hull[i]];
// Compute face normals
for(uint32 i1 = 0; i1 < m_vertexCount; ++i1)
{
uint32 i2 = i1 + 1 < m_vertexCount ? i1 + 1 : 0;
Vec2 face = m_vertices[i2] - m_vertices[i1];
// Ensure no zero-length edges, because that's bad
assert( face.LenSqr( ) > EPSILON * EPSILON );
// Calculate normal with 2D cross product between vector and scalar
m_normals[i1] = Vec2( face.y, -face.x );
m_normals[i1].Normalize( );
}
}
in Collision.cpp
void CircletoPolygon( Manifold *m, Body *a, Body *b )
{
Circle *A = reinterpret_cast<Circle *> (a->shape);
PolygonShape *B = reinterpret_cast<PolygonShape *>(b->shape);
m->contact_count = 0;
// Transform circle center to Polygon model space
Vec2 center = a->position;
center = B->u.Transpose( ) * (center - b->position);
// Find edge with minimum penetration
// Exact concept as using support points in Polygon vs Polygon
real separation = -FLT_MAX;
uint32 faceNormal = 0;
for(uint32 i = 0; i < B->m_vertexCount; ++i)
{
real s = Dot( B->m_normals[i], center - B->m_vertices[i] );
if(s > A->radius)
return;
if(s > separation)
{
separation = s;
faceNormal = i;
}
}
// Grab face's vertices
Vec2 v1 = B->m_vertices[faceNormal];
uint32 i2 = faceNormal + 1 < B->m_vertexCount ? faceNormal + 1 : 0;
Vec2 v2 = B->m_vertices[i2];
// Check to see if center is within polygon
if(separation < EPSILON)
{
m->contact_count = 1;
m->normal = -(B->u * B->m_normals[faceNormal]);
m->contacts[0] = m->normal * A->radius + a->position;
m->penetration = A->radius;
return;
}
// Determine which voronoi region of the edge center of circle lies within
real dot1 = Dot( center - v1, v2 - v1 );
real dot2 = Dot( center - v2, v1 - v2 );
m->penetration = A->radius - separation;
// Closest to v1
if(dot1 <= 0.0f)
{
if(DistSqr( center, v1 ) > A->radius * A->radius)
return;
m->contact_count = 1;
Vec2 n = v1 - center;
n = B->u * n;
n.Normalize( );
m->normal = n;
v1 = B->u * v1 + b->position;
m->contacts[0] = v1;
}
// Closest to v2
else if(dot2 <= 0.0f)
{
if(DistSqr( center, v2 ) > A->radius * A->radius)
return;
m->contact_count = 1;
Vec2 n = v2 - center;
v2 = B->u * v2 + b->position;
m->contacts[0] = v2;
n = B->u * n;
n.Normalize( );
m->normal = n;
}
// Closest to face
else
{
Vec2 n = B->m_normals[faceNormal];
if(Dot( center - v1, n ) > A->radius)
return;
n = B->u * n;
m->normal = -n;
m->contacts[0] = m->normal * A->radius + a->position;
m->contact_count = 1;
}
}
The order of finding the vertices in void Set() in Shape.h is anti-clockwise. in void SetBox() as well the order in which the vertices of the rectangle are declared and the normals are calculated is anti-clockwise, but in Collision.cpp, when visualizing the function CircleToPolygon(), it works only when the vertices are arranged in a clockwise manner. I changed the order in which the vertices are declared in SetBox() but that broke the program. can you please explain why this is happening?
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels