first commit
[blok] / Box2D / Source / Collision / Shapes / b2Shape.cpp
1 /*
2 * Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
3 *
4 * This software is provided 'as-is', without any express or implied
5 * warranty.  In no event will the authors be held liable for any damages
6 * arising from the use of this software.
7 * Permission is granted to anyone to use this software for any purpose,
8 * including commercial applications, and to alter it and redistribute it
9 * freely, subject to the following restrictions:
10 * 1. The origin of this software must not be misrepresented; you must not
11 * claim that you wrote the original software. If you use this software
12 * in a product, an acknowledgment in the product documentation would be
13 * appreciated but is not required.
14 * 2. Altered source versions must be plainly marked as such, and must not be
15 * misrepresented as being the original software.
16 * 3. This notice may not be removed or altered from any source distribution.
17 */
18
19 #include "b2Shape.h"
20 #include "b2CircleShape.h"
21 #include "b2PolygonShape.h"
22 #include "../b2Collision.h"
23 #include "../b2BroadPhase.h"
24 #include "../../Common/b2BlockAllocator.h"
25
26 #include <new>
27
28 b2Shape* b2Shape::Create(const b2ShapeDef* def, b2BlockAllocator* allocator)
29 {
30         switch (def->type)
31         {
32         case e_circleShape:
33                 {
34                         void* mem = allocator->Allocate(sizeof(b2CircleShape));
35                         return new (mem) b2CircleShape(def);
36                 }
37
38         case e_polygonShape:
39                 {
40                         void* mem = allocator->Allocate(sizeof(b2PolygonShape));
41                         return new (mem) b2PolygonShape(def);
42                 }
43
44         default:
45                 b2Assert(false);
46                 return NULL;
47         }
48 }
49
50 void b2Shape::Destroy(b2Shape* s, b2BlockAllocator* allocator)
51 {
52         switch (s->GetType())
53         {
54         case e_circleShape:
55                 s->~b2Shape();
56                 allocator->Free(s, sizeof(b2CircleShape));
57                 break;
58
59         case e_polygonShape:
60                 s->~b2Shape();
61                 allocator->Free(s, sizeof(b2PolygonShape));
62                 break;
63
64         default:
65                 b2Assert(false);
66         }
67 }
68
69 b2Shape::b2Shape(const b2ShapeDef* def)
70 {
71         m_userData = def->userData;
72         m_friction = def->friction;
73         m_restitution = def->restitution;
74         m_density = def->density;
75         m_body = NULL;
76         m_sweepRadius = 0.0f;
77
78         m_next = NULL;
79
80         m_proxyId = b2_nullProxy;
81
82         m_filter = def->filter;
83
84         m_isSensor = def->isSensor;
85 }
86
87 b2Shape::~b2Shape()
88 {
89         b2Assert(m_proxyId == b2_nullProxy);
90 }
91
92 void b2Shape::CreateProxy(b2BroadPhase* broadPhase, const b2XForm& transform)
93 {
94         b2Assert(m_proxyId == b2_nullProxy);
95
96         b2AABB aabb;
97         ComputeAABB(&aabb, transform);
98
99         bool inRange = broadPhase->InRange(aabb);
100
101         // You are creating a shape outside the world box.
102         b2Assert(inRange);
103
104         if (inRange)
105         {
106                 m_proxyId = broadPhase->CreateProxy(aabb, this);
107         }
108         else
109         {
110                 m_proxyId = b2_nullProxy;
111         }
112 }
113
114 void b2Shape::DestroyProxy(b2BroadPhase* broadPhase)
115 {
116         if (m_proxyId != b2_nullProxy)
117         {
118                 broadPhase->DestroyProxy(m_proxyId);
119                 m_proxyId = b2_nullProxy;
120         }
121 }
122
123 bool b2Shape::Synchronize(b2BroadPhase* broadPhase, const b2XForm& transform1, const b2XForm& transform2)
124 {
125         if (m_proxyId == b2_nullProxy)
126         {       
127                 return false;
128         }
129
130         // Compute an AABB that covers the swept shape (may miss some rotation effect).
131         b2AABB aabb;
132         ComputeSweptAABB(&aabb, transform1, transform2);
133
134         if (broadPhase->InRange(aabb))
135         {
136                 broadPhase->MoveProxy(m_proxyId, aabb);
137                 return true;
138         }
139         else
140         {
141                 return false;
142         }
143 }
144
145 void b2Shape::RefilterProxy(b2BroadPhase* broadPhase, const b2XForm& transform)
146 {
147         if (m_proxyId == b2_nullProxy)
148         {       
149                 return;
150         }
151
152         broadPhase->DestroyProxy(m_proxyId);
153
154         b2AABB aabb;
155         ComputeAABB(&aabb, transform);
156
157         bool inRange = broadPhase->InRange(aabb);
158
159         if (inRange)
160         {
161                 m_proxyId = broadPhase->CreateProxy(aabb, this);
162         }
163         else
164         {
165                 m_proxyId = b2_nullProxy;
166         }
167 }