reflexion 0.1.7 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.doc/ext/reflex/application.cpp +5 -5
- data/.doc/ext/reflex/body.cpp +167 -0
- data/.doc/ext/reflex/capture_event.cpp +4 -4
- data/.doc/ext/reflex/draw_event.cpp +4 -4
- data/.doc/ext/reflex/event.cpp +4 -4
- data/.doc/ext/reflex/fixture.cpp +101 -0
- data/.doc/ext/reflex/focus_event.cpp +4 -4
- data/.doc/ext/reflex/frame_event.cpp +4 -4
- data/.doc/ext/reflex/image_view.cpp +22 -5
- data/.doc/ext/reflex/key_event.cpp +4 -4
- data/.doc/ext/reflex/native.cpp +6 -0
- data/.doc/ext/reflex/pointer_event.cpp +4 -4
- data/.doc/ext/reflex/reflex.cpp +2 -3
- data/.doc/ext/reflex/scroll_event.cpp +4 -4
- data/.doc/ext/reflex/selector.cpp +4 -4
- data/.doc/ext/reflex/style.cpp +4 -4
- data/.doc/ext/reflex/style_length.cpp +4 -4
- data/.doc/ext/reflex/style_length2.cpp +4 -4
- data/.doc/ext/reflex/style_length4.cpp +4 -4
- data/.doc/ext/reflex/update_event.cpp +4 -4
- data/.doc/ext/reflex/view.cpp +110 -8
- data/.doc/ext/reflex/wheel_event.cpp +4 -4
- data/.doc/ext/reflex/window.cpp +36 -12
- data/README.md +2 -2
- data/Rakefile +2 -1
- data/VERSION +1 -1
- data/ext/reflex/application.cpp +8 -8
- data/ext/reflex/body.cpp +181 -0
- data/ext/reflex/capture_event.cpp +4 -4
- data/ext/reflex/draw_event.cpp +4 -4
- data/ext/reflex/event.cpp +4 -4
- data/ext/reflex/fixture.cpp +108 -0
- data/ext/reflex/focus_event.cpp +4 -4
- data/ext/reflex/frame_event.cpp +4 -4
- data/ext/reflex/image_view.cpp +24 -5
- data/ext/reflex/key_event.cpp +4 -4
- data/ext/reflex/native.cpp +6 -0
- data/ext/reflex/pointer_event.cpp +4 -4
- data/ext/reflex/reflex.cpp +2 -3
- data/ext/reflex/scroll_event.cpp +4 -4
- data/ext/reflex/selector.cpp +4 -4
- data/ext/reflex/style.cpp +4 -4
- data/ext/reflex/style_length.cpp +4 -4
- data/ext/reflex/style_length2.cpp +4 -4
- data/ext/reflex/style_length4.cpp +4 -4
- data/ext/reflex/update_event.cpp +4 -4
- data/ext/reflex/view.cpp +126 -12
- data/ext/reflex/wheel_event.cpp +4 -4
- data/ext/reflex/window.cpp +39 -12
- data/include/reflex/bitmap.h +20 -0
- data/include/reflex/body.h +82 -0
- data/include/reflex/bounds.h +20 -0
- data/include/reflex/color.h +20 -0
- data/include/reflex/color_space.h +20 -0
- data/include/reflex/defs.h +5 -1
- data/include/reflex/event.h +16 -25
- data/include/reflex/fixture.h +116 -0
- data/include/reflex/font.h +20 -0
- data/include/reflex/image.h +20 -0
- data/include/reflex/image_view.h +1 -1
- data/include/reflex/matrix.h +20 -0
- data/include/reflex/painter.h +20 -0
- data/include/reflex/point.h +24 -0
- data/include/reflex/ruby/application.h +6 -0
- data/include/reflex/ruby/body.h +41 -0
- data/include/reflex/ruby/event.h +68 -0
- data/include/reflex/ruby/fixture.h +41 -0
- data/include/reflex/ruby/image_view.h +14 -0
- data/include/reflex/ruby/selector.h +14 -0
- data/include/reflex/ruby/style.h +14 -0
- data/include/reflex/ruby/style_length.h +26 -0
- data/include/reflex/ruby/view.h +43 -39
- data/include/reflex/ruby/window.h +27 -21
- data/include/reflex/ruby.h +2 -0
- data/include/reflex/shader.h +20 -0
- data/include/reflex/style.h +2 -3
- data/include/reflex/texture.h +20 -0
- data/include/reflex/view.h +45 -24
- data/include/reflex/window.h +11 -14
- data/include/reflex.h +3 -0
- data/lib/reflex/application.rb +6 -2
- data/lib/reflex/body.rb +17 -0
- data/lib/reflex/fixture.rb +17 -0
- data/lib/reflex/view.rb +16 -1
- data/lib/reflex/window.rb +13 -1
- data/lib/reflex.rb +2 -0
- data/reflex.gemspec +1 -1
- data/samples/bats.rb +4 -3
- data/samples/checker.rb +4 -3
- data/samples/fans.rb +4 -3
- data/samples/fps.rb +5 -3
- data/samples/grid.rb +5 -4
- data/samples/hello.rb +1 -1
- data/samples/image.rb +3 -2
- data/samples/ios/hello/hello/main.cpp +12 -3
- data/samples/ios/hello/hello.xcodeproj/project.pbxproj +376 -123
- data/samples/key.rb +5 -4
- data/samples/layout.rb +3 -2
- data/samples/model.rb +3 -2
- data/samples/osx/hello/hello/main.cpp +12 -3
- data/samples/osx/hello/hello.xcodeproj/project.pbxproj +375 -120
- data/samples/physics.rb +37 -0
- data/samples/repl.rb +3 -2
- data/samples/shader.rb +4 -4
- data/samples/shapes.rb +4 -4
- data/samples/text.rb +6 -4
- data/samples/tree.rb +5 -4
- data/samples/views.rb +3 -2
- data/samples/visuals.rb +1 -2
- data/src/body.cpp +244 -0
- data/src/event.cpp +18 -18
- data/src/fixture.cpp +108 -0
- data/src/image_view.cpp +1 -1
- data/src/ios/native_window.h +2 -0
- data/src/ios/native_window.mm +18 -1
- data/src/ios/opengl_view.mm +8 -0
- data/src/ios/window.mm +24 -3
- data/src/ios/window_data.h +3 -3
- data/src/osx/native_window.mm +17 -1
- data/src/osx/window.mm +24 -3
- data/src/osx/window_data.h +3 -3
- data/src/physics/Box2D/Box2D.h +68 -0
- data/src/physics/Box2D/Collision/Shapes/b2ChainShape.cpp +193 -0
- data/src/physics/Box2D/Collision/Shapes/b2ChainShape.h +105 -0
- data/src/physics/Box2D/Collision/Shapes/b2CircleShape.cpp +99 -0
- data/src/physics/Box2D/Collision/Shapes/b2CircleShape.h +91 -0
- data/src/physics/Box2D/Collision/Shapes/b2EdgeShape.cpp +138 -0
- data/src/physics/Box2D/Collision/Shapes/b2EdgeShape.h +74 -0
- data/src/physics/Box2D/Collision/Shapes/b2PolygonShape.cpp +467 -0
- data/src/physics/Box2D/Collision/Shapes/b2PolygonShape.h +101 -0
- data/src/physics/Box2D/Collision/Shapes/b2Shape.h +101 -0
- data/src/physics/Box2D/Collision/b2BroadPhase.cpp +119 -0
- data/src/physics/Box2D/Collision/b2BroadPhase.h +257 -0
- data/src/physics/Box2D/Collision/b2CollideCircle.cpp +154 -0
- data/src/physics/Box2D/Collision/b2CollideEdge.cpp +698 -0
- data/src/physics/Box2D/Collision/b2CollidePolygon.cpp +239 -0
- data/src/physics/Box2D/Collision/b2Collision.cpp +252 -0
- data/src/physics/Box2D/Collision/b2Collision.h +277 -0
- data/src/physics/Box2D/Collision/b2Distance.cpp +603 -0
- data/src/physics/Box2D/Collision/b2Distance.h +141 -0
- data/src/physics/Box2D/Collision/b2DynamicTree.cpp +778 -0
- data/src/physics/Box2D/Collision/b2DynamicTree.h +289 -0
- data/src/physics/Box2D/Collision/b2TimeOfImpact.cpp +486 -0
- data/src/physics/Box2D/Collision/b2TimeOfImpact.h +58 -0
- data/src/physics/Box2D/Common/b2BlockAllocator.cpp +215 -0
- data/src/physics/Box2D/Common/b2BlockAllocator.h +62 -0
- data/src/physics/Box2D/Common/b2Draw.cpp +44 -0
- data/src/physics/Box2D/Common/b2Draw.h +86 -0
- data/src/physics/Box2D/Common/b2GrowableStack.h +85 -0
- data/src/physics/Box2D/Common/b2Math.cpp +94 -0
- data/src/physics/Box2D/Common/b2Math.h +720 -0
- data/src/physics/Box2D/Common/b2Settings.cpp +44 -0
- data/src/physics/Box2D/Common/b2Settings.h +151 -0
- data/src/physics/Box2D/Common/b2StackAllocator.cpp +83 -0
- data/src/physics/Box2D/Common/b2StackAllocator.h +60 -0
- data/src/physics/Box2D/Common/b2Timer.cpp +101 -0
- data/src/physics/Box2D/Common/b2Timer.h +50 -0
- data/src/physics/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.cpp +53 -0
- data/src/physics/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.h +39 -0
- data/src/physics/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.cpp +53 -0
- data/src/physics/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.h +39 -0
- data/src/physics/Box2D/Dynamics/Contacts/b2CircleContact.cpp +52 -0
- data/src/physics/Box2D/Dynamics/Contacts/b2CircleContact.h +39 -0
- data/src/physics/Box2D/Dynamics/Contacts/b2Contact.cpp +247 -0
- data/src/physics/Box2D/Dynamics/Contacts/b2Contact.h +349 -0
- data/src/physics/Box2D/Dynamics/Contacts/b2ContactSolver.cpp +838 -0
- data/src/physics/Box2D/Dynamics/Contacts/b2ContactSolver.h +95 -0
- data/src/physics/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.cpp +49 -0
- data/src/physics/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.h +39 -0
- data/src/physics/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.cpp +49 -0
- data/src/physics/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.h +39 -0
- data/src/physics/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp +49 -0
- data/src/physics/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.h +38 -0
- data/src/physics/Box2D/Dynamics/Contacts/b2PolygonContact.cpp +52 -0
- data/src/physics/Box2D/Dynamics/Contacts/b2PolygonContact.h +39 -0
- data/src/physics/Box2D/Dynamics/Joints/b2DistanceJoint.cpp +260 -0
- data/src/physics/Box2D/Dynamics/Joints/b2DistanceJoint.h +169 -0
- data/src/physics/Box2D/Dynamics/Joints/b2FrictionJoint.cpp +251 -0
- data/src/physics/Box2D/Dynamics/Joints/b2FrictionJoint.h +119 -0
- data/src/physics/Box2D/Dynamics/Joints/b2GearJoint.cpp +419 -0
- data/src/physics/Box2D/Dynamics/Joints/b2GearJoint.h +125 -0
- data/src/physics/Box2D/Dynamics/Joints/b2Joint.cpp +211 -0
- data/src/physics/Box2D/Dynamics/Joints/b2Joint.h +226 -0
- data/src/physics/Box2D/Dynamics/Joints/b2MotorJoint.cpp +304 -0
- data/src/physics/Box2D/Dynamics/Joints/b2MotorJoint.h +133 -0
- data/src/physics/Box2D/Dynamics/Joints/b2MouseJoint.cpp +222 -0
- data/src/physics/Box2D/Dynamics/Joints/b2MouseJoint.h +129 -0
- data/src/physics/Box2D/Dynamics/Joints/b2PrismaticJoint.cpp +629 -0
- data/src/physics/Box2D/Dynamics/Joints/b2PrismaticJoint.h +196 -0
- data/src/physics/Box2D/Dynamics/Joints/b2PulleyJoint.cpp +348 -0
- data/src/physics/Box2D/Dynamics/Joints/b2PulleyJoint.h +152 -0
- data/src/physics/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp +502 -0
- data/src/physics/Box2D/Dynamics/Joints/b2RevoluteJoint.h +204 -0
- data/src/physics/Box2D/Dynamics/Joints/b2RopeJoint.cpp +241 -0
- data/src/physics/Box2D/Dynamics/Joints/b2RopeJoint.h +114 -0
- data/src/physics/Box2D/Dynamics/Joints/b2WeldJoint.cpp +344 -0
- data/src/physics/Box2D/Dynamics/Joints/b2WeldJoint.h +126 -0
- data/src/physics/Box2D/Dynamics/Joints/b2WheelJoint.cpp +419 -0
- data/src/physics/Box2D/Dynamics/Joints/b2WheelJoint.h +210 -0
- data/src/physics/Box2D/Dynamics/b2Body.cpp +549 -0
- data/src/physics/Box2D/Dynamics/b2Body.h +860 -0
- data/src/physics/Box2D/Dynamics/b2ContactManager.cpp +296 -0
- data/src/physics/Box2D/Dynamics/b2ContactManager.h +52 -0
- data/src/physics/Box2D/Dynamics/b2Fixture.cpp +303 -0
- data/src/physics/Box2D/Dynamics/b2Fixture.h +345 -0
- data/src/physics/Box2D/Dynamics/b2Island.cpp +539 -0
- data/src/physics/Box2D/Dynamics/b2Island.h +93 -0
- data/src/physics/Box2D/Dynamics/b2TimeStep.h +70 -0
- data/src/physics/Box2D/Dynamics/b2World.cpp +1339 -0
- data/src/physics/Box2D/Dynamics/b2World.h +354 -0
- data/src/physics/Box2D/Dynamics/b2WorldCallbacks.cpp +36 -0
- data/src/physics/Box2D/Dynamics/b2WorldCallbacks.h +155 -0
- data/src/physics/Box2D/Rope/b2Rope.cpp +259 -0
- data/src/physics/Box2D/Rope/b2Rope.h +115 -0
- data/src/style.cpp +2 -2
- data/src/view.cpp +217 -17
- data/src/window.cpp +25 -15
- data/src/world.cpp +206 -0
- data/src/world.h +96 -0
- data/task/box2d.rake +25 -0
- data/test/test_view.rb +5 -5
- metadata +125 -3
@@ -0,0 +1,467 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
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 <Box2D/Collision/Shapes/b2PolygonShape.h>
|
20
|
+
#include <new>
|
21
|
+
|
22
|
+
b2Shape* b2PolygonShape::Clone(b2BlockAllocator* allocator) const
|
23
|
+
{
|
24
|
+
void* mem = allocator->Allocate(sizeof(b2PolygonShape));
|
25
|
+
b2PolygonShape* clone = new (mem) b2PolygonShape;
|
26
|
+
*clone = *this;
|
27
|
+
return clone;
|
28
|
+
}
|
29
|
+
|
30
|
+
void b2PolygonShape::SetAsBox(float32 hx, float32 hy)
|
31
|
+
{
|
32
|
+
m_count = 4;
|
33
|
+
m_vertices[0].Set(-hx, -hy);
|
34
|
+
m_vertices[1].Set( hx, -hy);
|
35
|
+
m_vertices[2].Set( hx, hy);
|
36
|
+
m_vertices[3].Set(-hx, hy);
|
37
|
+
m_normals[0].Set(0.0f, -1.0f);
|
38
|
+
m_normals[1].Set(1.0f, 0.0f);
|
39
|
+
m_normals[2].Set(0.0f, 1.0f);
|
40
|
+
m_normals[3].Set(-1.0f, 0.0f);
|
41
|
+
m_centroid.SetZero();
|
42
|
+
}
|
43
|
+
|
44
|
+
void b2PolygonShape::SetAsBox(float32 hx, float32 hy, const b2Vec2& center, float32 angle)
|
45
|
+
{
|
46
|
+
m_count = 4;
|
47
|
+
m_vertices[0].Set(-hx, -hy);
|
48
|
+
m_vertices[1].Set( hx, -hy);
|
49
|
+
m_vertices[2].Set( hx, hy);
|
50
|
+
m_vertices[3].Set(-hx, hy);
|
51
|
+
m_normals[0].Set(0.0f, -1.0f);
|
52
|
+
m_normals[1].Set(1.0f, 0.0f);
|
53
|
+
m_normals[2].Set(0.0f, 1.0f);
|
54
|
+
m_normals[3].Set(-1.0f, 0.0f);
|
55
|
+
m_centroid = center;
|
56
|
+
|
57
|
+
b2Transform xf;
|
58
|
+
xf.p = center;
|
59
|
+
xf.q.Set(angle);
|
60
|
+
|
61
|
+
// Transform vertices and normals.
|
62
|
+
for (int32 i = 0; i < m_count; ++i)
|
63
|
+
{
|
64
|
+
m_vertices[i] = b2Mul(xf, m_vertices[i]);
|
65
|
+
m_normals[i] = b2Mul(xf.q, m_normals[i]);
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
69
|
+
int32 b2PolygonShape::GetChildCount() const
|
70
|
+
{
|
71
|
+
return 1;
|
72
|
+
}
|
73
|
+
|
74
|
+
static b2Vec2 ComputeCentroid(const b2Vec2* vs, int32 count)
|
75
|
+
{
|
76
|
+
b2Assert(count >= 3);
|
77
|
+
|
78
|
+
b2Vec2 c; c.Set(0.0f, 0.0f);
|
79
|
+
float32 area = 0.0f;
|
80
|
+
|
81
|
+
// pRef is the reference point for forming triangles.
|
82
|
+
// It's location doesn't change the result (except for rounding error).
|
83
|
+
b2Vec2 pRef(0.0f, 0.0f);
|
84
|
+
#if 0
|
85
|
+
// This code would put the reference point inside the polygon.
|
86
|
+
for (int32 i = 0; i < count; ++i)
|
87
|
+
{
|
88
|
+
pRef += vs[i];
|
89
|
+
}
|
90
|
+
pRef *= 1.0f / count;
|
91
|
+
#endif
|
92
|
+
|
93
|
+
const float32 inv3 = 1.0f / 3.0f;
|
94
|
+
|
95
|
+
for (int32 i = 0; i < count; ++i)
|
96
|
+
{
|
97
|
+
// Triangle vertices.
|
98
|
+
b2Vec2 p1 = pRef;
|
99
|
+
b2Vec2 p2 = vs[i];
|
100
|
+
b2Vec2 p3 = i + 1 < count ? vs[i+1] : vs[0];
|
101
|
+
|
102
|
+
b2Vec2 e1 = p2 - p1;
|
103
|
+
b2Vec2 e2 = p3 - p1;
|
104
|
+
|
105
|
+
float32 D = b2Cross(e1, e2);
|
106
|
+
|
107
|
+
float32 triangleArea = 0.5f * D;
|
108
|
+
area += triangleArea;
|
109
|
+
|
110
|
+
// Area weighted centroid
|
111
|
+
c += triangleArea * inv3 * (p1 + p2 + p3);
|
112
|
+
}
|
113
|
+
|
114
|
+
// Centroid
|
115
|
+
b2Assert(area > b2_epsilon);
|
116
|
+
c *= 1.0f / area;
|
117
|
+
return c;
|
118
|
+
}
|
119
|
+
|
120
|
+
void b2PolygonShape::Set(const b2Vec2* vertices, int32 count)
|
121
|
+
{
|
122
|
+
b2Assert(3 <= count && count <= b2_maxPolygonVertices);
|
123
|
+
if (count < 3)
|
124
|
+
{
|
125
|
+
SetAsBox(1.0f, 1.0f);
|
126
|
+
return;
|
127
|
+
}
|
128
|
+
|
129
|
+
int32 n = b2Min(count, b2_maxPolygonVertices);
|
130
|
+
|
131
|
+
// Perform welding and copy vertices into local buffer.
|
132
|
+
b2Vec2 ps[b2_maxPolygonVertices];
|
133
|
+
int32 tempCount = 0;
|
134
|
+
for (int32 i = 0; i < n; ++i)
|
135
|
+
{
|
136
|
+
b2Vec2 v = vertices[i];
|
137
|
+
|
138
|
+
bool unique = true;
|
139
|
+
for (int32 j = 0; j < tempCount; ++j)
|
140
|
+
{
|
141
|
+
if (b2DistanceSquared(v, ps[j]) < 0.5f * b2_linearSlop)
|
142
|
+
{
|
143
|
+
unique = false;
|
144
|
+
break;
|
145
|
+
}
|
146
|
+
}
|
147
|
+
|
148
|
+
if (unique)
|
149
|
+
{
|
150
|
+
ps[tempCount++] = v;
|
151
|
+
}
|
152
|
+
}
|
153
|
+
|
154
|
+
n = tempCount;
|
155
|
+
if (n < 3)
|
156
|
+
{
|
157
|
+
// Polygon is degenerate.
|
158
|
+
b2Assert(false);
|
159
|
+
SetAsBox(1.0f, 1.0f);
|
160
|
+
return;
|
161
|
+
}
|
162
|
+
|
163
|
+
// Create the convex hull using the Gift wrapping algorithm
|
164
|
+
// http://en.wikipedia.org/wiki/Gift_wrapping_algorithm
|
165
|
+
|
166
|
+
// Find the right most point on the hull
|
167
|
+
int32 i0 = 0;
|
168
|
+
float32 x0 = ps[0].x;
|
169
|
+
for (int32 i = 1; i < n; ++i)
|
170
|
+
{
|
171
|
+
float32 x = ps[i].x;
|
172
|
+
if (x > x0 || (x == x0 && ps[i].y < ps[i0].y))
|
173
|
+
{
|
174
|
+
i0 = i;
|
175
|
+
x0 = x;
|
176
|
+
}
|
177
|
+
}
|
178
|
+
|
179
|
+
int32 hull[b2_maxPolygonVertices];
|
180
|
+
int32 m = 0;
|
181
|
+
int32 ih = i0;
|
182
|
+
|
183
|
+
for (;;)
|
184
|
+
{
|
185
|
+
hull[m] = ih;
|
186
|
+
|
187
|
+
int32 ie = 0;
|
188
|
+
for (int32 j = 1; j < n; ++j)
|
189
|
+
{
|
190
|
+
if (ie == ih)
|
191
|
+
{
|
192
|
+
ie = j;
|
193
|
+
continue;
|
194
|
+
}
|
195
|
+
|
196
|
+
b2Vec2 r = ps[ie] - ps[hull[m]];
|
197
|
+
b2Vec2 v = ps[j] - ps[hull[m]];
|
198
|
+
float32 c = b2Cross(r, v);
|
199
|
+
if (c < 0.0f)
|
200
|
+
{
|
201
|
+
ie = j;
|
202
|
+
}
|
203
|
+
|
204
|
+
// Collinearity check
|
205
|
+
if (c == 0.0f && v.LengthSquared() > r.LengthSquared())
|
206
|
+
{
|
207
|
+
ie = j;
|
208
|
+
}
|
209
|
+
}
|
210
|
+
|
211
|
+
++m;
|
212
|
+
ih = ie;
|
213
|
+
|
214
|
+
if (ie == i0)
|
215
|
+
{
|
216
|
+
break;
|
217
|
+
}
|
218
|
+
}
|
219
|
+
|
220
|
+
if (m < 3)
|
221
|
+
{
|
222
|
+
// Polygon is degenerate.
|
223
|
+
b2Assert(false);
|
224
|
+
SetAsBox(1.0f, 1.0f);
|
225
|
+
return;
|
226
|
+
}
|
227
|
+
|
228
|
+
m_count = m;
|
229
|
+
|
230
|
+
// Copy vertices.
|
231
|
+
for (int32 i = 0; i < m; ++i)
|
232
|
+
{
|
233
|
+
m_vertices[i] = ps[hull[i]];
|
234
|
+
}
|
235
|
+
|
236
|
+
// Compute normals. Ensure the edges have non-zero length.
|
237
|
+
for (int32 i = 0; i < m; ++i)
|
238
|
+
{
|
239
|
+
int32 i1 = i;
|
240
|
+
int32 i2 = i + 1 < m ? i + 1 : 0;
|
241
|
+
b2Vec2 edge = m_vertices[i2] - m_vertices[i1];
|
242
|
+
b2Assert(edge.LengthSquared() > b2_epsilon * b2_epsilon);
|
243
|
+
m_normals[i] = b2Cross(edge, 1.0f);
|
244
|
+
m_normals[i].Normalize();
|
245
|
+
}
|
246
|
+
|
247
|
+
// Compute the polygon centroid.
|
248
|
+
m_centroid = ComputeCentroid(m_vertices, m);
|
249
|
+
}
|
250
|
+
|
251
|
+
bool b2PolygonShape::TestPoint(const b2Transform& xf, const b2Vec2& p) const
|
252
|
+
{
|
253
|
+
b2Vec2 pLocal = b2MulT(xf.q, p - xf.p);
|
254
|
+
|
255
|
+
for (int32 i = 0; i < m_count; ++i)
|
256
|
+
{
|
257
|
+
float32 dot = b2Dot(m_normals[i], pLocal - m_vertices[i]);
|
258
|
+
if (dot > 0.0f)
|
259
|
+
{
|
260
|
+
return false;
|
261
|
+
}
|
262
|
+
}
|
263
|
+
|
264
|
+
return true;
|
265
|
+
}
|
266
|
+
|
267
|
+
bool b2PolygonShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
|
268
|
+
const b2Transform& xf, int32 childIndex) const
|
269
|
+
{
|
270
|
+
B2_NOT_USED(childIndex);
|
271
|
+
|
272
|
+
// Put the ray into the polygon's frame of reference.
|
273
|
+
b2Vec2 p1 = b2MulT(xf.q, input.p1 - xf.p);
|
274
|
+
b2Vec2 p2 = b2MulT(xf.q, input.p2 - xf.p);
|
275
|
+
b2Vec2 d = p2 - p1;
|
276
|
+
|
277
|
+
float32 lower = 0.0f, upper = input.maxFraction;
|
278
|
+
|
279
|
+
int32 index = -1;
|
280
|
+
|
281
|
+
for (int32 i = 0; i < m_count; ++i)
|
282
|
+
{
|
283
|
+
// p = p1 + a * d
|
284
|
+
// dot(normal, p - v) = 0
|
285
|
+
// dot(normal, p1 - v) + a * dot(normal, d) = 0
|
286
|
+
float32 numerator = b2Dot(m_normals[i], m_vertices[i] - p1);
|
287
|
+
float32 denominator = b2Dot(m_normals[i], d);
|
288
|
+
|
289
|
+
if (denominator == 0.0f)
|
290
|
+
{
|
291
|
+
if (numerator < 0.0f)
|
292
|
+
{
|
293
|
+
return false;
|
294
|
+
}
|
295
|
+
}
|
296
|
+
else
|
297
|
+
{
|
298
|
+
// Note: we want this predicate without division:
|
299
|
+
// lower < numerator / denominator, where denominator < 0
|
300
|
+
// Since denominator < 0, we have to flip the inequality:
|
301
|
+
// lower < numerator / denominator <==> denominator * lower > numerator.
|
302
|
+
if (denominator < 0.0f && numerator < lower * denominator)
|
303
|
+
{
|
304
|
+
// Increase lower.
|
305
|
+
// The segment enters this half-space.
|
306
|
+
lower = numerator / denominator;
|
307
|
+
index = i;
|
308
|
+
}
|
309
|
+
else if (denominator > 0.0f && numerator < upper * denominator)
|
310
|
+
{
|
311
|
+
// Decrease upper.
|
312
|
+
// The segment exits this half-space.
|
313
|
+
upper = numerator / denominator;
|
314
|
+
}
|
315
|
+
}
|
316
|
+
|
317
|
+
// The use of epsilon here causes the assert on lower to trip
|
318
|
+
// in some cases. Apparently the use of epsilon was to make edge
|
319
|
+
// shapes work, but now those are handled separately.
|
320
|
+
//if (upper < lower - b2_epsilon)
|
321
|
+
if (upper < lower)
|
322
|
+
{
|
323
|
+
return false;
|
324
|
+
}
|
325
|
+
}
|
326
|
+
|
327
|
+
b2Assert(0.0f <= lower && lower <= input.maxFraction);
|
328
|
+
|
329
|
+
if (index >= 0)
|
330
|
+
{
|
331
|
+
output->fraction = lower;
|
332
|
+
output->normal = b2Mul(xf.q, m_normals[index]);
|
333
|
+
return true;
|
334
|
+
}
|
335
|
+
|
336
|
+
return false;
|
337
|
+
}
|
338
|
+
|
339
|
+
void b2PolygonShape::ComputeAABB(b2AABB* aabb, const b2Transform& xf, int32 childIndex) const
|
340
|
+
{
|
341
|
+
B2_NOT_USED(childIndex);
|
342
|
+
|
343
|
+
b2Vec2 lower = b2Mul(xf, m_vertices[0]);
|
344
|
+
b2Vec2 upper = lower;
|
345
|
+
|
346
|
+
for (int32 i = 1; i < m_count; ++i)
|
347
|
+
{
|
348
|
+
b2Vec2 v = b2Mul(xf, m_vertices[i]);
|
349
|
+
lower = b2Min(lower, v);
|
350
|
+
upper = b2Max(upper, v);
|
351
|
+
}
|
352
|
+
|
353
|
+
b2Vec2 r(m_radius, m_radius);
|
354
|
+
aabb->lowerBound = lower - r;
|
355
|
+
aabb->upperBound = upper + r;
|
356
|
+
}
|
357
|
+
|
358
|
+
void b2PolygonShape::ComputeMass(b2MassData* massData, float32 density) const
|
359
|
+
{
|
360
|
+
// Polygon mass, centroid, and inertia.
|
361
|
+
// Let rho be the polygon density in mass per unit area.
|
362
|
+
// Then:
|
363
|
+
// mass = rho * int(dA)
|
364
|
+
// centroid.x = (1/mass) * rho * int(x * dA)
|
365
|
+
// centroid.y = (1/mass) * rho * int(y * dA)
|
366
|
+
// I = rho * int((x*x + y*y) * dA)
|
367
|
+
//
|
368
|
+
// We can compute these integrals by summing all the integrals
|
369
|
+
// for each triangle of the polygon. To evaluate the integral
|
370
|
+
// for a single triangle, we make a change of variables to
|
371
|
+
// the (u,v) coordinates of the triangle:
|
372
|
+
// x = x0 + e1x * u + e2x * v
|
373
|
+
// y = y0 + e1y * u + e2y * v
|
374
|
+
// where 0 <= u && 0 <= v && u + v <= 1.
|
375
|
+
//
|
376
|
+
// We integrate u from [0,1-v] and then v from [0,1].
|
377
|
+
// We also need to use the Jacobian of the transformation:
|
378
|
+
// D = cross(e1, e2)
|
379
|
+
//
|
380
|
+
// Simplification: triangle centroid = (1/3) * (p1 + p2 + p3)
|
381
|
+
//
|
382
|
+
// The rest of the derivation is handled by computer algebra.
|
383
|
+
|
384
|
+
b2Assert(m_count >= 3);
|
385
|
+
|
386
|
+
b2Vec2 center; center.Set(0.0f, 0.0f);
|
387
|
+
float32 area = 0.0f;
|
388
|
+
float32 I = 0.0f;
|
389
|
+
|
390
|
+
// s is the reference point for forming triangles.
|
391
|
+
// It's location doesn't change the result (except for rounding error).
|
392
|
+
b2Vec2 s(0.0f, 0.0f);
|
393
|
+
|
394
|
+
// This code would put the reference point inside the polygon.
|
395
|
+
for (int32 i = 0; i < m_count; ++i)
|
396
|
+
{
|
397
|
+
s += m_vertices[i];
|
398
|
+
}
|
399
|
+
s *= 1.0f / m_count;
|
400
|
+
|
401
|
+
const float32 k_inv3 = 1.0f / 3.0f;
|
402
|
+
|
403
|
+
for (int32 i = 0; i < m_count; ++i)
|
404
|
+
{
|
405
|
+
// Triangle vertices.
|
406
|
+
b2Vec2 e1 = m_vertices[i] - s;
|
407
|
+
b2Vec2 e2 = i + 1 < m_count ? m_vertices[i+1] - s : m_vertices[0] - s;
|
408
|
+
|
409
|
+
float32 D = b2Cross(e1, e2);
|
410
|
+
|
411
|
+
float32 triangleArea = 0.5f * D;
|
412
|
+
area += triangleArea;
|
413
|
+
|
414
|
+
// Area weighted centroid
|
415
|
+
center += triangleArea * k_inv3 * (e1 + e2);
|
416
|
+
|
417
|
+
float32 ex1 = e1.x, ey1 = e1.y;
|
418
|
+
float32 ex2 = e2.x, ey2 = e2.y;
|
419
|
+
|
420
|
+
float32 intx2 = ex1*ex1 + ex2*ex1 + ex2*ex2;
|
421
|
+
float32 inty2 = ey1*ey1 + ey2*ey1 + ey2*ey2;
|
422
|
+
|
423
|
+
I += (0.25f * k_inv3 * D) * (intx2 + inty2);
|
424
|
+
}
|
425
|
+
|
426
|
+
// Total mass
|
427
|
+
massData->mass = density * area;
|
428
|
+
|
429
|
+
// Center of mass
|
430
|
+
b2Assert(area > b2_epsilon);
|
431
|
+
center *= 1.0f / area;
|
432
|
+
massData->center = center + s;
|
433
|
+
|
434
|
+
// Inertia tensor relative to the local origin (point s).
|
435
|
+
massData->I = density * I;
|
436
|
+
|
437
|
+
// Shift to center of mass then to original body origin.
|
438
|
+
massData->I += massData->mass * (b2Dot(massData->center, massData->center) - b2Dot(center, center));
|
439
|
+
}
|
440
|
+
|
441
|
+
bool b2PolygonShape::Validate() const
|
442
|
+
{
|
443
|
+
for (int32 i = 0; i < m_count; ++i)
|
444
|
+
{
|
445
|
+
int32 i1 = i;
|
446
|
+
int32 i2 = i < m_count - 1 ? i1 + 1 : 0;
|
447
|
+
b2Vec2 p = m_vertices[i1];
|
448
|
+
b2Vec2 e = m_vertices[i2] - p;
|
449
|
+
|
450
|
+
for (int32 j = 0; j < m_count; ++j)
|
451
|
+
{
|
452
|
+
if (j == i1 || j == i2)
|
453
|
+
{
|
454
|
+
continue;
|
455
|
+
}
|
456
|
+
|
457
|
+
b2Vec2 v = m_vertices[j] - p;
|
458
|
+
float32 c = b2Cross(e, v);
|
459
|
+
if (c < 0.0f)
|
460
|
+
{
|
461
|
+
return false;
|
462
|
+
}
|
463
|
+
}
|
464
|
+
}
|
465
|
+
|
466
|
+
return true;
|
467
|
+
}
|
@@ -0,0 +1,101 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
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
|
+
#ifndef B2_POLYGON_SHAPE_H
|
20
|
+
#define B2_POLYGON_SHAPE_H
|
21
|
+
|
22
|
+
#include <Box2D/Collision/Shapes/b2Shape.h>
|
23
|
+
|
24
|
+
/// A convex polygon. It is assumed that the interior of the polygon is to
|
25
|
+
/// the left of each edge.
|
26
|
+
/// Polygons have a maximum number of vertices equal to b2_maxPolygonVertices.
|
27
|
+
/// In most cases you should not need many vertices for a convex polygon.
|
28
|
+
class b2PolygonShape : public b2Shape
|
29
|
+
{
|
30
|
+
public:
|
31
|
+
b2PolygonShape();
|
32
|
+
|
33
|
+
/// Implement b2Shape.
|
34
|
+
b2Shape* Clone(b2BlockAllocator* allocator) const;
|
35
|
+
|
36
|
+
/// @see b2Shape::GetChildCount
|
37
|
+
int32 GetChildCount() const;
|
38
|
+
|
39
|
+
/// Create a convex hull from the given array of local points.
|
40
|
+
/// The count must be in the range [3, b2_maxPolygonVertices].
|
41
|
+
/// @warning the points may be re-ordered, even if they form a convex polygon
|
42
|
+
/// @warning collinear points are handled but not removed. Collinear points
|
43
|
+
/// may lead to poor stacking behavior.
|
44
|
+
void Set(const b2Vec2* points, int32 count);
|
45
|
+
|
46
|
+
/// Build vertices to represent an axis-aligned box centered on the local origin.
|
47
|
+
/// @param hx the half-width.
|
48
|
+
/// @param hy the half-height.
|
49
|
+
void SetAsBox(float32 hx, float32 hy);
|
50
|
+
|
51
|
+
/// Build vertices to represent an oriented box.
|
52
|
+
/// @param hx the half-width.
|
53
|
+
/// @param hy the half-height.
|
54
|
+
/// @param center the center of the box in local coordinates.
|
55
|
+
/// @param angle the rotation of the box in local coordinates.
|
56
|
+
void SetAsBox(float32 hx, float32 hy, const b2Vec2& center, float32 angle);
|
57
|
+
|
58
|
+
/// @see b2Shape::TestPoint
|
59
|
+
bool TestPoint(const b2Transform& transform, const b2Vec2& p) const;
|
60
|
+
|
61
|
+
/// Implement b2Shape.
|
62
|
+
bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
|
63
|
+
const b2Transform& transform, int32 childIndex) const;
|
64
|
+
|
65
|
+
/// @see b2Shape::ComputeAABB
|
66
|
+
void ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const;
|
67
|
+
|
68
|
+
/// @see b2Shape::ComputeMass
|
69
|
+
void ComputeMass(b2MassData* massData, float32 density) const;
|
70
|
+
|
71
|
+
/// Get the vertex count.
|
72
|
+
int32 GetVertexCount() const { return m_count; }
|
73
|
+
|
74
|
+
/// Get a vertex by index.
|
75
|
+
const b2Vec2& GetVertex(int32 index) const;
|
76
|
+
|
77
|
+
/// Validate convexity. This is a very time consuming operation.
|
78
|
+
/// @returns true if valid
|
79
|
+
bool Validate() const;
|
80
|
+
|
81
|
+
b2Vec2 m_centroid;
|
82
|
+
b2Vec2 m_vertices[b2_maxPolygonVertices];
|
83
|
+
b2Vec2 m_normals[b2_maxPolygonVertices];
|
84
|
+
int32 m_count;
|
85
|
+
};
|
86
|
+
|
87
|
+
inline b2PolygonShape::b2PolygonShape()
|
88
|
+
{
|
89
|
+
m_type = e_polygon;
|
90
|
+
m_radius = b2_polygonRadius;
|
91
|
+
m_count = 0;
|
92
|
+
m_centroid.SetZero();
|
93
|
+
}
|
94
|
+
|
95
|
+
inline const b2Vec2& b2PolygonShape::GetVertex(int32 index) const
|
96
|
+
{
|
97
|
+
b2Assert(0 <= index && index < m_count);
|
98
|
+
return m_vertices[index];
|
99
|
+
}
|
100
|
+
|
101
|
+
#endif
|
@@ -0,0 +1,101 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
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
|
+
#ifndef B2_SHAPE_H
|
20
|
+
#define B2_SHAPE_H
|
21
|
+
|
22
|
+
#include <Box2D/Common/b2BlockAllocator.h>
|
23
|
+
#include <Box2D/Common/b2Math.h>
|
24
|
+
#include <Box2D/Collision/b2Collision.h>
|
25
|
+
|
26
|
+
/// This holds the mass data computed for a shape.
|
27
|
+
struct b2MassData
|
28
|
+
{
|
29
|
+
/// The mass of the shape, usually in kilograms.
|
30
|
+
float32 mass;
|
31
|
+
|
32
|
+
/// The position of the shape's centroid relative to the shape's origin.
|
33
|
+
b2Vec2 center;
|
34
|
+
|
35
|
+
/// The rotational inertia of the shape about the local origin.
|
36
|
+
float32 I;
|
37
|
+
};
|
38
|
+
|
39
|
+
/// A shape is used for collision detection. You can create a shape however you like.
|
40
|
+
/// Shapes used for simulation in b2World are created automatically when a b2Fixture
|
41
|
+
/// is created. Shapes may encapsulate a one or more child shapes.
|
42
|
+
class b2Shape
|
43
|
+
{
|
44
|
+
public:
|
45
|
+
|
46
|
+
enum Type
|
47
|
+
{
|
48
|
+
e_circle = 0,
|
49
|
+
e_edge = 1,
|
50
|
+
e_polygon = 2,
|
51
|
+
e_chain = 3,
|
52
|
+
e_typeCount = 4
|
53
|
+
};
|
54
|
+
|
55
|
+
virtual ~b2Shape() {}
|
56
|
+
|
57
|
+
/// Clone the concrete shape using the provided allocator.
|
58
|
+
virtual b2Shape* Clone(b2BlockAllocator* allocator) const = 0;
|
59
|
+
|
60
|
+
/// Get the type of this shape. You can use this to down cast to the concrete shape.
|
61
|
+
/// @return the shape type.
|
62
|
+
Type GetType() const;
|
63
|
+
|
64
|
+
/// Get the number of child primitives.
|
65
|
+
virtual int32 GetChildCount() const = 0;
|
66
|
+
|
67
|
+
/// Test a point for containment in this shape. This only works for convex shapes.
|
68
|
+
/// @param xf the shape world transform.
|
69
|
+
/// @param p a point in world coordinates.
|
70
|
+
virtual bool TestPoint(const b2Transform& xf, const b2Vec2& p) const = 0;
|
71
|
+
|
72
|
+
/// Cast a ray against a child shape.
|
73
|
+
/// @param output the ray-cast results.
|
74
|
+
/// @param input the ray-cast input parameters.
|
75
|
+
/// @param transform the transform to be applied to the shape.
|
76
|
+
/// @param childIndex the child shape index
|
77
|
+
virtual bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
|
78
|
+
const b2Transform& transform, int32 childIndex) const = 0;
|
79
|
+
|
80
|
+
/// Given a transform, compute the associated axis aligned bounding box for a child shape.
|
81
|
+
/// @param aabb returns the axis aligned box.
|
82
|
+
/// @param xf the world transform of the shape.
|
83
|
+
/// @param childIndex the child shape
|
84
|
+
virtual void ComputeAABB(b2AABB* aabb, const b2Transform& xf, int32 childIndex) const = 0;
|
85
|
+
|
86
|
+
/// Compute the mass properties of this shape using its dimensions and density.
|
87
|
+
/// The inertia tensor is computed about the local origin.
|
88
|
+
/// @param massData returns the mass data for this shape.
|
89
|
+
/// @param density the density in kilograms per meter squared.
|
90
|
+
virtual void ComputeMass(b2MassData* massData, float32 density) const = 0;
|
91
|
+
|
92
|
+
Type m_type;
|
93
|
+
float32 m_radius;
|
94
|
+
};
|
95
|
+
|
96
|
+
inline b2Shape::Type b2Shape::GetType() const
|
97
|
+
{
|
98
|
+
return m_type;
|
99
|
+
}
|
100
|
+
|
101
|
+
#endif
|