123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2013 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #include "graphics/dgl.h"
- #include "2d/scene/DebugDraw.h"
- // Debug Profiling.
- #include "debug/profiler.h"
- //-----------------------------------------------------------------------------
- void DebugDraw::DrawAABB( const b2AABB& aabb, const ColorF& color )
- {
- // Debug Profiling.
- PROFILE_SCOPE(DebugDraw_DrawAABB);
- // Calculate AABB vertices.
- b2Vec2 aabbVertex[4];
- aabbVertex[0].Set(aabb.lowerBound.x, aabb.lowerBound.y);
- aabbVertex[1].Set(aabb.upperBound.x, aabb.lowerBound.y);
- aabbVertex[2].Set(aabb.upperBound.x, aabb.upperBound.y);
- aabbVertex[3].Set(aabb.lowerBound.x, aabb.upperBound.y);
- DrawPolygon( aabbVertex, 4, color );
- }
- //-----------------------------------------------------------------------------
- void DebugDraw::DrawOOBB( const b2Vec2* pOOBB, const ColorF& color )
- {
- // Debug Profiling.
- PROFILE_SCOPE(DebugDraw_DrawOOBB);
- DrawPolygon( pOOBB, 4, color );
- }
- //-----------------------------------------------------------------------------
- void DebugDraw::DrawAsleep( const b2Vec2* pOOBB, const ColorF& color )
- {
- // Debug Profiling.
- PROFILE_SCOPE(DebugDraw_DrawAsleep);
- DrawSegment( pOOBB[0], pOOBB[2], color );
- DrawSegment( pOOBB[1], pOOBB[3], color );
- }
- //-----------------------------------------------------------------------------
- void DebugDraw::DrawCollisionShapes( const b2Transform& xf, b2Body* pBody )
- {
- // Debug Profiling.
- PROFILE_SCOPE(DebugDraw_DrawCollisionShapes);
- // Iterate fixtures.
- for ( b2Fixture* pFixture = pBody->GetFixtureList(); pFixture; pFixture = pFixture->GetNext() )
- {
- // Inactive fixture.
- if ( pBody->IsActive() == false )
- {
- DrawShape(pFixture, xf, ColorF(0.5f, 0.5f, 0.5f));
- }
- // Active static fixture.
- else if ( pBody->GetType() == b2_staticBody )
- {
- DrawShape(pFixture, xf, ColorF(0.5f, 0.9f, 0.5f));
- }
- // Active kinematic fixture.
- else if ( pBody->GetType() == b2_kinematicBody )
- {
- DrawShape(pFixture, xf, ColorF(0.5f, 0.5f, 0.9f));
- }
- // Active, asleep dynamic fixture.
- else if ( pBody->IsAwake() == false )
- {
- DrawShape(pFixture, xf, ColorF(0.6f, 0.6f, 0.2f));
- }
- // Active, awake dynamic fixture.
- else
- {
- DrawShape(pFixture, xf, ColorF(0.9f, 0.9f, 0.2f));
- }
- }
- }
- //-----------------------------------------------------------------------------
- void DebugDraw::DrawSortPoint( const b2Vec2& worldPosition, const b2Vec2& size, const b2Vec2& localSortPoint )
- {
- // Debug Profiling.
- PROFILE_SCOPE(DebugDraw_DrawSortPoint);
- // Calculate sort point marker size based upon the object size.
- const b2Vec2 halfSize( size.x * 0.5f, size.y * 0.5f );
- const b2Vec2 objectSize( size.x * 0.2f, size.y * 0.2f );
- const F32 markerSize = getMin(objectSize.x, objectSize.y);
- // Calculate world sort point.
- b2Vec2 worldPoint( worldPosition.x + (localSortPoint.x * halfSize.x), worldPosition.y + (localSortPoint.y * halfSize.y) );
- // Calculate The Sort Point "X".
- b2Vec2 worldSortPoint[4];
- worldSortPoint[0].Set( worldPoint.x - markerSize, worldPoint.y - markerSize );
- worldSortPoint[1].Set( worldPoint.x + markerSize, worldPoint.y + markerSize );
- worldSortPoint[2].Set( worldPoint.x - markerSize, worldPoint.y + markerSize );
- worldSortPoint[3].Set( worldPoint.x + markerSize, worldPoint.y - markerSize );
- DrawSegment( worldSortPoint[0], worldSortPoint[1], ColorF( 0.0f, 1.0f, 0.8f ) );
- DrawSegment( worldSortPoint[2], worldSortPoint[3], ColorF( 0.0f, 1.0f, 0.8f ) );
- }
- //-----------------------------------------------------------------------------
- void DebugDraw::DrawShape( b2Fixture* fixture, const b2Transform& xf, const ColorF& color )
- {
- // Debug Profiling.
- PROFILE_SCOPE(DebugDraw_DrawShape);
- switch (fixture->GetType())
- {
- case b2Shape::e_circle:
- {
- b2CircleShape* circle = (b2CircleShape*)fixture->GetShape();
- b2Vec2 center = b2Mul(xf, circle->m_p);
- float32 radius = circle->m_radius;
- b2Vec2 axis = b2Mul(xf.q, b2Vec2(0.0f, 1.0f));
- DrawSolidCircle(center, radius, axis, color);
- }
- break;
- case b2Shape::e_edge:
- {
- b2EdgeShape* edge = (b2EdgeShape*)fixture->GetShape();
- b2Vec2 v1 = b2Mul(xf, edge->m_vertex1);
- b2Vec2 v2 = b2Mul(xf, edge->m_vertex2);
- DrawSegment(v1, v2, color);
- }
- break;
- case b2Shape::e_chain:
- {
- b2ChainShape* chain = (b2ChainShape*)fixture->GetShape();
- int32 count = chain->m_count;
- const b2Vec2* vertices = chain->m_vertices;
- b2Vec2 v1 = b2Mul(xf, vertices[0]);
- for (int32 i = 1; i < count; ++i)
- {
- b2Vec2 v2 = b2Mul(xf, vertices[i]);
- DrawSegment(v1, v2, color);
- DrawCircle(v1, 0.05f, color);
- v1 = v2;
- }
- }
- break;
- case b2Shape::e_polygon:
- {
- b2PolygonShape* poly = (b2PolygonShape*)fixture->GetShape();
- int32 vertexCount = poly->m_count;
- b2Assert(vertexCount <= b2_maxPolygonVertices);
- b2Vec2 vertices[b2_maxPolygonVertices];
- for (int32 i = 0; i < vertexCount; ++i)
- {
- vertices[i] = b2Mul(xf, poly->m_vertices[i]);
- }
- DrawSolidPolygon(vertices, vertexCount, color);
- }
- break;
-
- default:
- break;
- }
- }
- //-----------------------------------------------------------------------------
- void DebugDraw::DrawJoints( b2World* pWorld )
- {
- // Debug Profiling.
- PROFILE_SCOPE(DebugDraw_Joints);
- // Draw all joints in world.
- for ( b2Joint* pJoint = pWorld->GetJointList(); pJoint; pJoint = pJoint->GetNext() )
- {
- // Fetch joint configuration.
- b2Body* pBodyA = pJoint->GetBodyA();
- b2Body* pBodyB = pJoint->GetBodyB();
- const b2Transform& xf1 = pBodyA->GetTransform();
- const b2Transform& xf2 = pBodyB->GetTransform();
- b2Vec2 x1 = xf1.p;
- b2Vec2 x2 = xf2.p;
- b2Vec2 p1 = pJoint->GetAnchorA();
- b2Vec2 p2 = pJoint->GetAnchorB();
- ColorF color( 0.5f, 0.8f, 0.8f );
- switch ( pJoint->GetType() )
- {
- // Distance joint.
- case e_distanceJoint:
- DrawSegment(p1, p2, color);
- break;
- // Pullet joint.
- case e_pulleyJoint:
- {
- b2PulleyJoint* pPulley = (b2PulleyJoint*)pJoint;
- b2Vec2 s1 = pPulley->GetGroundAnchorA();
- b2Vec2 s2 = pPulley->GetGroundAnchorB();
- DrawSegment( s1, p1, color );
- DrawSegment( s2, p2, color );
- DrawSegment( s1, s2, color );
- }
- break;
-
- case e_mouseJoint:
- {
- b2MouseJoint* pMouseJoint = (b2MouseJoint*)pJoint;
-
- b2Vec2 p1 = pBodyB->GetPosition();
- p1 = pMouseJoint->GetAnchorB();
- b2Vec2 p2 = pMouseJoint->GetTarget();
- DrawSegment( p1, p2, color );
- }
- break;
- // All other joints.
- default:
- DrawSegment( x1, p1, color );
- DrawSegment( p1, p2, color );
- DrawSegment( x2, p2, color );
- }
- }
- }
- //-----------------------------------------------------------------------------
- void DebugDraw::DrawPolygon( const b2Vec2* vertices, int32 vertexCount, const ColorF& color )
- {
- // Debug Profiling.
- PROFILE_SCOPE(DebugDraw_DrawPolygon);
- glColor3f(color.red, color.green, color.blue);
- glBegin(GL_LINE_LOOP);
- for (int32 i = 0; i < vertexCount; ++i)
- {
- glVertex2f(vertices[i].x, vertices[i].y);
- }
- glEnd();
- }
- //-----------------------------------------------------------------------------
- void DebugDraw::DrawSolidPolygon( const b2Vec2* vertices, int32 vertexCount, const ColorF& color )
- {
- // Debug Profiling.
- PROFILE_SCOPE(DebugDraw_DrawSolidPolygon);
- glEnable(GL_BLEND);
- glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glColor4f(0.5f * color.red, 0.5f * color.green, 0.5f * color.blue, 0.15f);
- glBegin(GL_TRIANGLE_FAN);
- for (int32 i = 0; i < vertexCount; ++i)
- {
- glVertex2f(vertices[i].x, vertices[i].y);
- }
- glEnd();
- glDisable(GL_BLEND);
- glColor4f(color.red, color.green, color.blue, 1.0f);
- glBegin(GL_LINE_LOOP);
- for (int32 i = 0; i < vertexCount; ++i)
- {
- glVertex2f(vertices[i].x, vertices[i].y);
- }
- glEnd();
- }
- //-----------------------------------------------------------------------------
- void DebugDraw::DrawCircle( const b2Vec2& center, float32 radius, const ColorF& color )
- {
- // Debug Profiling.
- PROFILE_SCOPE(DebugDraw_DrawCircle);
- const float32 k_segments = 16.0f;
- const float32 k_increment = 2.0f * b2_pi / k_segments;
- float32 theta = 0.0f;
- glColor3f(color.red, color.green, color.blue);
- glBegin(GL_LINE_LOOP);
- for (int32 i = 0; i < k_segments; ++i)
- {
- b2Vec2 v = center + radius * b2Vec2(cosf(theta), sinf(theta));
- glVertex2f(v.x, v.y);
- theta += k_increment;
- }
- glEnd();
- }
-
- //-----------------------------------------------------------------------------
- void DebugDraw::DrawSolidCircle( const b2Vec2& center, float32 radius, const b2Vec2& axis, const ColorF& color )
- {
- // Debug Profiling.
- PROFILE_SCOPE(DebugDraw_DrawSolidCircle);
- const float32 k_segments = 12.0f;
- const float32 k_increment = 2.0f * b2_pi / k_segments;
- float32 theta = 0.0f;
- glEnable(GL_BLEND);
- glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glColor4f(0.5f * color.red, 0.5f * color.green, 0.5f * color.blue, 0.15f);
- glBegin(GL_TRIANGLE_FAN);
- for (int32 i = 0; i < k_segments; ++i)
- {
- b2Vec2 v = center + radius * b2Vec2(cosf(theta), sinf(theta));
- glVertex2f(v.x, v.y);
- theta += k_increment;
- }
- glEnd();
- glDisable(GL_BLEND);
- theta = 0.0f;
- glColor4f(color.red, color.green, color.blue, 1.0f);
- glBegin(GL_LINE_LOOP);
- for (int32 i = 0; i < k_segments; ++i)
- {
- b2Vec2 v = center + radius * b2Vec2(cosf(theta), sinf(theta));
- glVertex2f(v.x, v.y);
- theta += k_increment;
- }
- glEnd();
- b2Vec2 p = center + radius * axis;
- glBegin(GL_LINES);
- glVertex2f(center.x, center.y);
- glVertex2f(p.x, p.y);
- glEnd();
- }
-
- //-----------------------------------------------------------------------------
- void DebugDraw::DrawSegment( const b2Vec2& p1, const b2Vec2& p2, const ColorF& color )
- {
- glColor3f(color.red, color.green, color.blue);
- glBegin(GL_LINES);
- glVertex2f(p1.x, p1.y);
- glVertex2f(p2.x, p2.y);
- glEnd();
- }
- //-----------------------------------------------------------------------------
- void DebugDraw::DrawTransform( const b2Transform& xf )
- {
- b2Vec2 p1 = xf.p, p2;
- const float32 k_axisScale = 0.4f;
- glBegin(GL_LINES);
-
- glColor3f(1.0f, 0.0f, 0.0f);
- glVertex2f(p1.x, p1.y);
- p2 = p1 + k_axisScale * xf.q.GetXAxis();
- glVertex2f(p2.x, p2.y);
- glColor3f(0.0f, 1.0f, 0.0f);
- glVertex2f(p1.x, p1.y);
- p2 = p1 + k_axisScale * xf.q.GetYAxis();
- glVertex2f(p2.x, p2.y);
- glEnd();
- }
- //-----------------------------------------------------------------------------
- void DebugDraw::DrawPoint( const b2Vec2& p, float32 size, const ColorF& color )
- {
- glPointSize(size);
- glBegin(GL_POINTS);
- glColor3f(color.red, color.green, color.blue);
- glVertex2f(p.x, p.y);
- glEnd();
- glPointSize(1.0f);
- }
|