Skip to content

Commit a14828e

Browse files
committed
Move solve functionality into a standalone function
1 parent d077e30 commit a14828e

File tree

3 files changed

+152
-150
lines changed

3 files changed

+152
-150
lines changed

Collision.cpp

+136-101
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,33 @@
22
#define TINYC2_IMPLEMENTATION
33
#include "tinyc2.h"
44

5-
void handleResult(const c2Manifold&, Manifold&);
6-
void handleResult(const c2Raycast&, const c2Ray&, Raycast&);
7-
c2AABB shapeToc2(const Aabb&, const sf::Vector2f);
8-
c2Circle shapeToc2(const Circle&, const sf::Vector2f);
9-
c2Ray rayToc2(const Ray&, const sf::Vector2f);
10-
c2v toc2v(const sf::Vector2f&);
11-
sf::Vector2f tosfv(const c2v&);
5+
namespace priv
6+
{
7+
template <typename T>
8+
struct Helper
9+
{
10+
Helper(const T& shape, sf::Vector2f position);
11+
12+
const T& shape;
13+
sf::Vector2f position;
14+
};
15+
16+
Manifold calculate(Helper<Aabb> a, Helper<Aabb> b);
17+
Manifold calculate(Helper<Circle> a, Helper<Circle> b);
18+
Manifold calculate(Helper<Aabb> a, Helper<Circle> b);
19+
Manifold calculate(Helper<Circle> a, Helper<Aabb> b);
20+
Raycast calculate(Helper<Ray> a, Helper<Aabb> b);
21+
Raycast calculate(Helper<Ray> a, Helper<Circle> b);
22+
23+
Manifold toManifold(const c2Manifold& m);
24+
Raycast toRaycast(const c2Raycast& r, const c2Ray& ray);
25+
26+
c2AABB toc2AABB(Helper<Aabb> aabb);
27+
c2Circle toc2Circle(Helper<Circle> circle);
28+
c2Ray toc2Ray(Helper<Ray> ray);
29+
c2v toc2v(const sf::Vector2f& v);
30+
sf::Vector2f tosfv(const c2v& v);
31+
}
1232

1333
Shape::Shape(Type type)
1434
: mType(type)
@@ -110,187 +130,202 @@ Manifold::Manifold()
110130
{
111131
}
112132

113-
void Manifold::solve(const Shape& a, const sf::Vector2f positionA,
114-
const Shape& b, const sf::Vector2f positionB)
133+
Raycast::Raycast()
134+
: hit(false)
135+
, normal(0, 0)
136+
, contact(0, 0)
137+
, t(0)
115138
{
116-
mPositionA = positionA;
117-
mPositionB = positionB;
139+
}
118140

119-
dispatch(a, b);
141+
template <typename T>
142+
priv::Helper<T>::Helper(const T& shape, sf::Vector2f position)
143+
: shape(shape)
144+
, position(position)
145+
{
120146
}
121147

122-
void Manifold::dispatch(const Shape& a, const Shape& b)
148+
Manifold solve(const Shape& a, sf::Vector2f posA, const Shape& b,
149+
sf::Vector2f posB)
123150
{
151+
Manifold m;
152+
124153
if (a.getType() == Type::Aabb)
125154
{
126-
const Aabb& aChild = castShape<Aabb>(a);
155+
priv::Helper<Aabb> ha(castShape<Aabb>(a), posA);
127156

128157
if (b.getType() == Type::Aabb)
129158
{
130-
const Aabb& bChild = castShape<Aabb>(b);
131-
collide(aChild, bChild);
159+
priv::Helper<Aabb> hb(castShape<Aabb>(b), posB);
160+
m = priv::calculate(ha, hb);
132161
}
133162
else if (b.getType() == Type::Circle)
134163
{
135-
const Circle& bChild = castShape<Circle>(b);
136-
collide(aChild, bChild);
164+
priv::Helper<Circle> hb(castShape<Circle>(b), posB);
165+
m = priv::calculate(ha, hb);
137166
}
138167
}
139168
else if (a.getType() == Type::Circle)
140169
{
141-
const Circle& aChild = castShape<Circle>(a);
170+
priv::Helper<Circle> ha(castShape<Circle>(a), posA);
142171

172+
// Could use a function castOther<T>() to avoid duplicating this
143173
if (b.getType() == Type::Aabb)
144174
{
145-
const Aabb& bChild = castShape<Aabb>(b);
146-
collide(aChild, bChild);
175+
priv::Helper<Aabb> hb(castShape<Aabb>(b), posB);
176+
m = priv::calculate(ha, hb);
147177
}
148178
else if (b.getType() == Type::Circle)
149179
{
150-
const Circle& bChild = castShape<Circle>(b);
151-
collide(aChild, bChild);
180+
priv::Helper<Circle> hb(castShape<Circle>(b), posB);
181+
m = priv::calculate(ha, hb);
152182
}
153183
}
154-
}
155184

156-
void Manifold::collide(const Aabb& a, const Aabb& b)
157-
{
158-
c2AABB shapeA = shapeToc2(a, mPositionA);
159-
c2AABB shapeB = shapeToc2(b, mPositionB);
160-
c2Manifold m;
161-
c2AABBtoAABBManifold(shapeA, shapeB, &m);
162-
163-
handleResult(m, *this);
185+
return m;
164186
}
165187

166-
void Manifold::collide(const Circle& a, const Circle& b)
188+
Raycast solve(const Ray& a, sf::Vector2f posA, const Shape& b,
189+
sf::Vector2f posB)
167190
{
168-
c2Circle shapeA = shapeToc2(a, mPositionA);
169-
c2Circle shapeB = shapeToc2(b, mPositionB);
170-
c2Manifold m;
171-
c2CircletoCircleManifold(shapeA, shapeB, &m);
191+
Raycast r;
192+
priv::Helper<Ray> ha(a, posA);
172193

173-
handleResult(m, *this);
174-
}
194+
if (b.getType() == Type::Aabb)
195+
{
196+
priv::Helper<Aabb> hb(castShape<Aabb>(b), posB);
197+
r = priv::calculate(ha, hb);
198+
}
199+
else if (b.getType() == Type::Circle)
200+
{
201+
priv::Helper<Circle> hb(castShape<Circle>(b), posB);
202+
r = priv::calculate(ha, hb);
203+
}
175204

176-
void Manifold::collide(const Aabb& a, const Circle& b)
177-
{
178-
collide(b, a);
179-
normal = -normal;
205+
return r;
180206
}
181207

182-
void Manifold::collide(const Circle& a, const Aabb& b)
208+
Manifold priv::calculate(Helper<Aabb> a, Helper<Aabb> b)
183209
{
184-
c2Circle shapeA = shapeToc2(a, mPositionA);
185-
c2AABB shapeB = shapeToc2(b, mPositionB);
210+
c2AABB shapeA = priv::toc2AABB(a);
211+
c2AABB shapeB = priv::toc2AABB(b);
186212
c2Manifold m;
187-
c2CircletoAABBManifold(shapeA, shapeB, &m);
213+
c2AABBtoAABBManifold(shapeA, shapeB, &m);
188214

189-
handleResult(m, *this);
215+
return priv::toManifold(m);
190216
}
191217

192-
Raycast::Raycast()
193-
: hit(false)
194-
, normal(0, 0)
195-
, t(0)
218+
Manifold priv::calculate(Helper<Circle> a, Helper<Circle> b)
196219
{
220+
c2Circle shapeA = priv::toc2Circle(a);
221+
c2Circle shapeB = priv::toc2Circle(b);
222+
c2Manifold m;
223+
c2CircletoCircleManifold(shapeA, shapeB, &m);
224+
225+
return priv::toManifold(m);
197226
}
198227

199-
void Raycast::solve(const Ray& a, const sf::Vector2f positionA,
200-
const Shape& b, const sf::Vector2f positionB)
228+
Manifold priv::calculate(Helper<Aabb> a, Helper<Circle> b)
201229
{
202-
mPositionA = positionA;
203-
mPositionB = positionB;
230+
Manifold m = priv::calculate(b, a);
231+
m.normal = -m.normal;
204232

205-
dispatch(a, b);
233+
return m;
206234
}
207235

208-
void Raycast::dispatch(const Ray& a, const Shape& b)
236+
Manifold priv::calculate(Helper<Circle> a, Helper<Aabb> b)
209237
{
210-
if (b.getType() == Type::Aabb)
211-
{
212-
const Aabb& bChild = castShape<Aabb>(b);
213-
calculate(a, bChild);
214-
}
215-
else if (b.getType() == Type::Circle)
216-
{
217-
const Circle& bChild = castShape<Circle>(b);
218-
calculate(a, bChild);
219-
}
238+
c2Circle shapeA = priv::toc2Circle(a);
239+
c2AABB shapeB = priv::toc2AABB(b);
240+
c2Manifold m;
241+
c2CircletoAABBManifold(shapeA, shapeB, &m);
242+
243+
return priv::toManifold(m);
220244
}
221245

222-
void Raycast::calculate(const Ray& a, const Aabb& b)
246+
Raycast priv::calculate(Helper<Ray> a, Helper<Aabb> b)
223247
{
224-
c2Ray ray = rayToc2(a, mPositionA);
225-
c2AABB shape = shapeToc2(b, mPositionB);
248+
Raycast tmp;
249+
c2Ray ray = priv::toc2Ray(a);
250+
c2AABB shape = priv::toc2AABB(b);
226251
c2Raycast r;
227-
hit = false;
228252

229253
if (c2RaytoAABB(ray, shape, &r))
230-
handleResult(r, ray, *this);
254+
tmp = priv::toRaycast(r, ray);
255+
256+
return tmp;
231257
}
232258

233-
void Raycast::calculate(const Ray& a, const Circle& b)
259+
Raycast priv::calculate(Helper<Ray> a, Helper<Circle> b)
234260
{
235-
c2Ray ray = rayToc2(a, mPositionA);
236-
c2Circle shape = shapeToc2(b, mPositionB);
261+
Raycast tmp;
262+
c2Ray ray = priv::toc2Ray(a);
263+
c2Circle shape = priv::toc2Circle(b);
237264
c2Raycast r;
238-
hit = false;
239265

240266
if (c2RaytoCircle(ray, shape, &r))
241-
handleResult(r, ray, *this);
267+
tmp = priv::toRaycast(r, ray);
268+
269+
return tmp;
242270
}
243271

244-
void handleResult(const c2Manifold& manifold, Manifold& m)
272+
Manifold priv::toManifold(const c2Manifold& m)
245273
{
246-
m.colliding = manifold.count > 0;
247-
if (m.colliding)
274+
Manifold tmp;
275+
tmp.colliding = m.count > 0;
276+
277+
if (tmp.colliding)
248278
{
249-
m.normal = tosfv(manifold.normal);
250-
m.contact = tosfv(manifold.contact_points[0]);
251-
m.depth = manifold.depths[0];
279+
tmp.normal = tosfv(m.normal);
280+
tmp.contact = tosfv(m.contact_points[0]);
281+
tmp.depth = m.depths[0];
252282
}
283+
284+
return tmp;
253285
}
254286

255-
void handleResult(const c2Raycast& raycast, const c2Ray& ray, Raycast& r)
287+
Raycast priv::toRaycast(const c2Raycast& r, const c2Ray& ray)
256288
{
257-
r.hit = true;
258-
r.normal = tosfv(raycast.n);
259-
r.contact = tosfv(c2Impact(ray, raycast.t));
260-
r.t = raycast.t;
289+
Raycast tmp;
290+
tmp.hit = true;
291+
tmp.normal = tosfv(r.n);
292+
tmp.contact = tosfv(c2Impact(ray, r.t));
293+
tmp.t = r.t;
294+
295+
return tmp;
261296
}
262297

263-
c2AABB shapeToc2(const Aabb& aabb, const sf::Vector2f position)
298+
c2AABB priv::toc2AABB(Helper<Aabb> aabb)
264299
{
265300
c2AABB tmp;
266-
tmp.min = toc2v(position);
267-
tmp.max = toc2v(position + aabb.getSize());
301+
tmp.min = toc2v(aabb.position);
302+
tmp.max = toc2v(aabb.position + aabb.shape.getSize());
268303
return tmp;
269304
}
270305

271-
c2Circle shapeToc2(const Circle& circle, const sf::Vector2f position)
306+
c2Circle priv::toc2Circle(Helper<Circle> circle)
272307
{
273308
c2Circle tmp;
274-
tmp.p = toc2v(position);
275-
tmp.r = circle.getRadius();
309+
tmp.p = toc2v(circle.position);
310+
tmp.r = circle.shape.getRadius();
276311
return tmp;
277312
}
278313

279-
c2Ray rayToc2(const Ray& ray, const sf::Vector2f position)
314+
c2Ray priv::toc2Ray(Helper<Ray> ray)
280315
{
281316
c2Ray tmp;
282-
tmp.p = toc2v(position);
283-
tmp.d = toc2v(ray.getDirection());
284-
tmp.t = ray.getLength();
317+
tmp.p = toc2v(ray.position);
318+
tmp.d = toc2v(ray.shape.getDirection());
319+
tmp.t = ray.shape.getLength();
285320
return tmp;
286321
}
287322

288-
c2v toc2v(const sf::Vector2f& v)
323+
c2v priv::toc2v(const sf::Vector2f& v)
289324
{
290325
return c2V(v.x, v.y);
291326
}
292327

293-
sf::Vector2f tosfv(const c2v& v)
328+
sf::Vector2f priv::tosfv(const c2v& v)
294329
{
295330
return sf::Vector2f(v.x, v.y);
296331
}

0 commit comments

Comments
 (0)