| 
							- /*
 - * Copyright (c) 2009 Erin Catto http://www.box2d.org
 - *
 - * This software is provided 'as-is', without any express or implied
 - * warranty.  In no event will the authors be held liable for any damages
 - * arising from the use of this software.
 - * Permission is granted to anyone to use this software for any purpose,
 - * including commercial applications, and to alter it and redistribute it
 - * freely, subject to the following restrictions:
 - * 1. The origin of this software must not be misrepresented; you must not
 - * claim that you wrote the original software. If you use this software
 - * in a product, an acknowledgment in the product documentation would be
 - * appreciated but is not required.
 - * 2. Altered source versions must be plainly marked as such, and must not be
 - * misrepresented as being the original software.
 - * 3. This notice may not be removed or altered from any source distribution.
 - */
 - 
 - #ifndef DYNAMIC_TREE_TEST_H
 - #define DYNAMIC_TREE_TEST_H
 - 
 - class DynamicTreeTest : public Test
 - {
 - public:
 - 
 -     enum
 -     {
 -         e_actorCount = 128
 -     };
 - 
 -     DynamicTreeTest()
 -     {
 -         m_worldExtent = 15.0f;
 -         m_proxyExtent = 0.5f;
 - 
 -         srand(888);
 - 
 -         for (int32 i = 0; i < e_actorCount; ++i)
 -         {
 -             Actor* actor = m_actors + i;
 -             GetRandomAABB(&actor->aabb);
 -             actor->proxyId = m_tree.CreateProxy(actor->aabb, actor);
 -         }
 - 
 -         m_stepCount = 0;
 - 
 -         float32 h = m_worldExtent;
 -         m_queryAABB.lowerBound.Set(-3.0f, -4.0f + h);
 -         m_queryAABB.upperBound.Set(5.0f, 6.0f + h);
 - 
 -         m_rayCastInput.p1.Set(-5.0, 5.0f + h);
 -         m_rayCastInput.p2.Set(7.0f, -4.0f + h);
 -         //m_rayCastInput.p1.Set(0.0f, 2.0f + h);
 -         //m_rayCastInput.p2.Set(0.0f, -2.0f + h);
 -         m_rayCastInput.maxFraction = 1.0f;
 - 
 -         m_automated = false;
 -     }
 - 
 -     static Test* Create()
 -     {
 -         return new DynamicTreeTest;
 -     }
 - 
 -     void Step(Settings* settings)
 -     {
 -         B2_NOT_USED(settings);
 - 
 -         m_rayActor = NULL;
 -         for (int32 i = 0; i < e_actorCount; ++i)
 -         {
 -             m_actors[i].fraction = 1.0f;
 -             m_actors[i].overlap = false;
 -         }
 - 
 -         if (m_automated == true)
 -         {
 -             int32 actionCount = b2Max(1, e_actorCount >> 2);
 - 
 -             for (int32 i = 0; i < actionCount; ++i)
 -             {
 -                 Action();
 -             }
 -         }
 - 
 -         Query();
 -         RayCast();
 - 
 -         for (int32 i = 0; i < e_actorCount; ++i)
 -         {
 -             Actor* actor = m_actors + i;
 -             if (actor->proxyId == b2_nullNode)
 -                 continue;
 - 
 -             b2Color c(0.9f, 0.9f, 0.9f);
 -             if (actor == m_rayActor && actor->overlap)
 -             {
 -                 c.Set(0.9f, 0.6f, 0.6f);
 -             }
 -             else if (actor == m_rayActor)
 -             {
 -                 c.Set(0.6f, 0.9f, 0.6f);
 -             }
 -             else if (actor->overlap)
 -             {
 -                 c.Set(0.6f, 0.6f, 0.9f);
 -             }
 - 
 -             m_debugDraw.DrawAABB(&actor->aabb, c);
 -         }
 - 
 -         b2Color c(0.7f, 0.7f, 0.7f);
 -         m_debugDraw.DrawAABB(&m_queryAABB, c);
 - 
 -         m_debugDraw.DrawSegment(m_rayCastInput.p1, m_rayCastInput.p2, c);
 - 
 -         b2Color c1(0.2f, 0.9f, 0.2f);
 -         b2Color c2(0.9f, 0.2f, 0.2f);
 -         m_debugDraw.DrawPoint(m_rayCastInput.p1, 6.0f, c1);
 -         m_debugDraw.DrawPoint(m_rayCastInput.p2, 6.0f, c2);
 - 
 -         if (m_rayActor)
 -         {
 -             b2Color cr(0.2f, 0.2f, 0.9f);
 -             b2Vec2 p = m_rayCastInput.p1 + m_rayActor->fraction * (m_rayCastInput.p2 - m_rayCastInput.p1);
 -             m_debugDraw.DrawPoint(p, 6.0f, cr);
 -         }
 - 
 -         {
 -             int32 height = m_tree.GetHeight();
 -             m_debugDraw.DrawString(5, m_textLine, "dynamic tree height = %d", height);
 -             m_textLine += 15;
 -         }
 - 
 -         ++m_stepCount;
 -     }
 - 
 -     void Keyboard(unsigned char key)
 -     {
 -         switch (key)
 -         {
 -         case 'a':
 -             m_automated = !m_automated;
 -             break;
 - 
 -         case 'c':
 -             CreateProxy();
 -             break;
 - 
 -         case 'd':
 -             DestroyProxy();
 -             break;
 - 
 -         case 'm':
 -             MoveProxy();
 -             break;
 -         }
 -     }
 - 
 -     bool QueryCallback(int32 proxyId)
 -     {
 -         Actor* actor = (Actor*)m_tree.GetUserData(proxyId);
 -         actor->overlap = b2TestOverlap(m_queryAABB, actor->aabb);
 -         return true;
 -     }
 - 
 -     float32 RayCastCallback(const b2RayCastInput& input, int32 proxyId)
 -     {
 -         Actor* actor = (Actor*)m_tree.GetUserData(proxyId);
 - 
 -         b2RayCastOutput output;
 -         bool hit = actor->aabb.RayCast(&output, input);
 - 
 -         if (hit)
 -         {
 -             m_rayCastOutput = output;
 -             m_rayActor = actor;
 -             m_rayActor->fraction = output.fraction;
 -             return output.fraction;
 -         }
 - 
 -         return input.maxFraction;
 -     }
 - 
 - private:
 - 
 -     struct Actor
 -     {
 -         b2AABB aabb;
 -         float32 fraction;
 -         bool overlap;
 -         int32 proxyId;
 -     };
 - 
 -     void GetRandomAABB(b2AABB* aabb)
 -     {
 -         b2Vec2 w; w.Set(2.0f * m_proxyExtent, 2.0f * m_proxyExtent);
 -         //aabb->lowerBound.x = -m_proxyExtent;
 -         //aabb->lowerBound.y = -m_proxyExtent + m_worldExtent;
 -         aabb->lowerBound.x = RandomFloat(-m_worldExtent, m_worldExtent);
 -         aabb->lowerBound.y = RandomFloat(0.0f, 2.0f * m_worldExtent);
 -         aabb->upperBound = aabb->lowerBound + w;
 -     }
 - 
 -     void MoveAABB(b2AABB* aabb)
 -     {
 -         b2Vec2 d;
 -         d.x = RandomFloat(-0.5f, 0.5f);
 -         d.y = RandomFloat(-0.5f, 0.5f);
 -         //d.x = 2.0f;
 -         //d.y = 0.0f;
 -         aabb->lowerBound += d;
 -         aabb->upperBound += d;
 - 
 -         b2Vec2 c0 = 0.5f * (aabb->lowerBound + aabb->upperBound);
 -         b2Vec2 min; min.Set(-m_worldExtent, 0.0f);
 -         b2Vec2 max; max.Set(m_worldExtent, 2.0f * m_worldExtent);
 -         b2Vec2 c = b2Clamp(c0, min, max);
 - 
 -         aabb->lowerBound += c - c0;
 -         aabb->upperBound += c - c0;
 -     }
 - 
 -     void CreateProxy()
 -     {
 -         for (int32 i = 0; i < e_actorCount; ++i)
 -         {
 -             int32 j = rand() % e_actorCount;
 -             Actor* actor = m_actors + j;
 -             if (actor->proxyId == b2_nullNode)
 -             {
 -                 GetRandomAABB(&actor->aabb);
 -                 actor->proxyId = m_tree.CreateProxy(actor->aabb, actor);
 -                 return;
 -             }
 -         }
 -     }
 - 
 -     void DestroyProxy()
 -     {
 -         for (int32 i = 0; i < e_actorCount; ++i)
 -         {
 -             int32 j = rand() % e_actorCount;
 -             Actor* actor = m_actors + j;
 -             if (actor->proxyId != b2_nullNode)
 -             {
 -                 m_tree.DestroyProxy(actor->proxyId);
 -                 actor->proxyId = b2_nullNode;
 -                 return;
 -             }
 -         }
 -     }
 - 
 -     void MoveProxy()
 -     {
 -         for (int32 i = 0; i < e_actorCount; ++i)
 -         {
 -             int32 j = rand() % e_actorCount;
 -             Actor* actor = m_actors + j;
 -             if (actor->proxyId == b2_nullNode)
 -             {
 -                 continue;
 -             }
 - 
 -             b2AABB aabb0 = actor->aabb;
 -             MoveAABB(&actor->aabb);
 -             b2Vec2 displacement = actor->aabb.GetCenter() - aabb0.GetCenter();
 -             m_tree.MoveProxy(actor->proxyId, actor->aabb, displacement);
 -             return;
 -         }
 -     }
 - 
 -     void Action()
 -     {
 -         int32 choice = rand() % 20;
 - 
 -         switch (choice)
 -         {
 -         case 0:
 -             CreateProxy();
 -             break;
 - 
 -         case 1:
 -             DestroyProxy();
 -             break;
 - 
 -         default:
 -             MoveProxy();
 -         }
 -     }
 - 
 -     void Query()
 -     {
 -         m_tree.Query(this, m_queryAABB);
 - 
 -         for (int32 i = 0; i < e_actorCount; ++i)
 -         {
 -             if (m_actors[i].proxyId == b2_nullNode)
 -             {
 -                 continue;
 -             }
 - 
 -             bool overlap = b2TestOverlap(m_queryAABB, m_actors[i].aabb);
 -             B2_NOT_USED(overlap);
 -             b2Assert(overlap == m_actors[i].overlap);
 -         }
 -     }
 - 
 -     void RayCast()
 -     {
 -         m_rayActor = NULL;
 - 
 -         b2RayCastInput input = m_rayCastInput;
 - 
 -         // Ray cast against the dynamic tree.
 -         m_tree.RayCast(this, input);
 - 
 -         // Brute force ray cast.
 -         Actor* bruteActor = NULL;
 -         b2RayCastOutput bruteOutput;
 -         for (int32 i = 0; i < e_actorCount; ++i)
 -         {
 -             if (m_actors[i].proxyId == b2_nullNode)
 -             {
 -                 continue;
 -             }
 - 
 -             b2RayCastOutput output;
 -             bool hit = m_actors[i].aabb.RayCast(&output, input);
 -             if (hit)
 -             {
 -                 bruteActor = m_actors + i;
 -                 bruteOutput = output;
 -                 input.maxFraction = output.fraction;
 -             }
 -         }
 - 
 -         if (bruteActor != NULL)
 -         {
 -             b2Assert(bruteOutput.fraction == m_rayCastOutput.fraction);
 -         }
 -     }
 - 
 -     float32 m_worldExtent;
 -     float32 m_proxyExtent;
 - 
 -     b2DynamicTree m_tree;
 -     b2AABB m_queryAABB;
 -     b2RayCastInput m_rayCastInput;
 -     b2RayCastOutput m_rayCastOutput;
 -     Actor* m_rayActor;
 -     Actor m_actors[e_actorCount];
 -     int32 m_stepCount;
 -     bool m_automated;
 - };
 - 
 - #endif
 
 
  |