ruby-procedural 0.0.1-x86-linux

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. data/Gemfile +4 -0
  2. data/README.md +29 -0
  3. data/Rakefile +65 -0
  4. data/bindings/procedural/interface/ProceduralBoxGenerator.i +12 -0
  5. data/bindings/procedural/interface/ProceduralCapsuleGenerator.i +12 -0
  6. data/bindings/procedural/interface/ProceduralConeGenerator.i +12 -0
  7. data/bindings/procedural/interface/ProceduralCylinderGenerator.i +12 -0
  8. data/bindings/procedural/interface/ProceduralExtruder.i +8 -0
  9. data/bindings/procedural/interface/ProceduralGeometryHelpers.i +15 -0
  10. data/bindings/procedural/interface/ProceduralHeader.i +8 -0
  11. data/bindings/procedural/interface/ProceduralIcoSphereGenerator.i +12 -0
  12. data/bindings/procedural/interface/ProceduralLathe.i +8 -0
  13. data/bindings/procedural/interface/ProceduralMeshGenerator.i +9 -0
  14. data/bindings/procedural/interface/ProceduralMultiShape.i +8 -0
  15. data/bindings/procedural/interface/ProceduralPath.i +8 -0
  16. data/bindings/procedural/interface/ProceduralPathGenerators.i +10 -0
  17. data/bindings/procedural/interface/ProceduralPlaneGenerator.i +12 -0
  18. data/bindings/procedural/interface/ProceduralPlatform.i +8 -0
  19. data/bindings/procedural/interface/ProceduralRoot.i +23 -0
  20. data/bindings/procedural/interface/ProceduralRoundedBoxGenerator.i +12 -0
  21. data/bindings/procedural/interface/ProceduralShape.i +8 -0
  22. data/bindings/procedural/interface/ProceduralShapeGenerators.i +10 -0
  23. data/bindings/procedural/interface/ProceduralSphereGenerator.i +11 -0
  24. data/bindings/procedural/interface/ProceduralSplines.i +8 -0
  25. data/bindings/procedural/interface/ProceduralStableHeaders.i +8 -0
  26. data/bindings/procedural/interface/ProceduralTorusGenerator.i +12 -0
  27. data/bindings/procedural/interface/ProceduralTorusKnotGenerator.i +12 -0
  28. data/bindings/procedural/interface/ProceduralTrack.i +8 -0
  29. data/bindings/procedural/interface/ProceduralTriangleBuffer.i +13 -0
  30. data/bindings/procedural/interface/ProceduralTriangulator.i +8 -0
  31. data/bindings/procedural/interface/ProceduralTubeGenerator.i +12 -0
  32. data/bindings/procedural/interface/ProceduralUtils.i +8 -0
  33. data/bindings/procedural/interface/Rakefile +22 -0
  34. data/bindings/procedural/interface/procedural.i +41 -0
  35. data/bindings/procedural/interface/procedural_wrap.cpp +36079 -0
  36. data/bindings/procedural/interface/procedural_wrap.h +19 -0
  37. data/bindings/procedural/interface/procedural_wrap.o +0 -0
  38. data/deps/include/OgreProcedural/Procedural.h +54 -0
  39. data/deps/include/OgreProcedural/ProceduralBoxGenerator.h +110 -0
  40. data/deps/include/OgreProcedural/ProceduralCapsuleGenerator.h +103 -0
  41. data/deps/include/OgreProcedural/ProceduralConeGenerator.h +90 -0
  42. data/deps/include/OgreProcedural/ProceduralCylinderGenerator.h +99 -0
  43. data/deps/include/OgreProcedural/ProceduralExtruder.h +131 -0
  44. data/deps/include/OgreProcedural/ProceduralGeometryHelpers.h +171 -0
  45. data/deps/include/OgreProcedural/ProceduralIcoSphereGenerator.h +76 -0
  46. data/deps/include/OgreProcedural/ProceduralLathe.h +129 -0
  47. data/deps/include/OgreProcedural/ProceduralMeshGenerator.h +286 -0
  48. data/deps/include/OgreProcedural/ProceduralMultiShape.h +126 -0
  49. data/deps/include/OgreProcedural/ProceduralPath.h +322 -0
  50. data/deps/include/OgreProcedural/ProceduralPathGenerators.h +281 -0
  51. data/deps/include/OgreProcedural/ProceduralPlaneGenerator.h +93 -0
  52. data/deps/include/OgreProcedural/ProceduralPlatform.h +54 -0
  53. data/deps/include/OgreProcedural/ProceduralRoot.h +65 -0
  54. data/deps/include/OgreProcedural/ProceduralRoundedBoxGenerator.h +118 -0
  55. data/deps/include/OgreProcedural/ProceduralShape.h +532 -0
  56. data/deps/include/OgreProcedural/ProceduralShapeGenerators.h +362 -0
  57. data/deps/include/OgreProcedural/ProceduralSphereGenerator.h +80 -0
  58. data/deps/include/OgreProcedural/ProceduralSplines.h +168 -0
  59. data/deps/include/OgreProcedural/ProceduralStableHeaders.h +28 -0
  60. data/deps/include/OgreProcedural/ProceduralTorusGenerator.h +88 -0
  61. data/deps/include/OgreProcedural/ProceduralTorusKnotGenerator.h +106 -0
  62. data/deps/include/OgreProcedural/ProceduralTrack.h +122 -0
  63. data/deps/include/OgreProcedural/ProceduralTriangleBuffer.h +328 -0
  64. data/deps/include/OgreProcedural/ProceduralTriangulator.h +173 -0
  65. data/deps/include/OgreProcedural/ProceduralTubeGenerator.h +96 -0
  66. data/deps/include/OgreProcedural/ProceduralUtils.h +185 -0
  67. data/deps/lib/libOgreProcedural.so +0 -0
  68. data/lib/procedural.so +0 -0
  69. data/lib/ruby-procedural/version.rb +5 -0
  70. data/lib/ruby-procedural.rb +27 -0
  71. data/ruby-procedural.gemspec +33 -0
  72. metadata +138 -0
@@ -0,0 +1,118 @@
1
+ /*
2
+ -----------------------------------------------------------------------------
3
+ This source file is part of ogre-procedural
4
+
5
+ For the latest info, see http://code.google.com/p/ogre-procedural/
6
+
7
+ Copyright (c) 2010 Michael Broutin
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ of this software and associated documentation files (the "Software"), to deal
11
+ in the Software without restriction, including without limitation the rights
12
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the Software is
14
+ furnished to do so, subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in
17
+ all copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25
+ THE SOFTWARE.
26
+ -----------------------------------------------------------------------------
27
+ */
28
+ #ifndef PROCEDURAL_ROUNDED_BOX_GENERATOR_INCLUDED
29
+ #define PROCEDURAL_ROUNDED_BOX_GENERATOR_INCLUDED
30
+
31
+ #include "ProceduralMeshGenerator.h"
32
+ #include "ProceduralPlatform.h"
33
+
34
+ namespace Procedural
35
+ {
36
+ /**
37
+ * Builds a rounded box.
38
+ * You can choose the size of the rounded borders to get a sharper or smoother look.
39
+ */
40
+ class _ProceduralExport RoundedBoxGenerator : public MeshGenerator<RoundedBoxGenerator>
41
+ {
42
+ Ogre::Real mSizeX,mSizeY,mSizeZ;
43
+ unsigned short mNumSegX,mNumSegY,mNumSegZ;
44
+ Ogre::Real mChamferSize;
45
+ unsigned short mChamferNumSeg;
46
+
47
+ public:
48
+ RoundedBoxGenerator() : mSizeX(1.f), mSizeY(1.f), mSizeZ(1.f),
49
+ mNumSegX(1), mNumSegY(1), mNumSegZ(1), mChamferSize(.1f), mChamferNumSeg(8) {}
50
+
51
+ /** Sets the size of the box along X axis */
52
+ RoundedBoxGenerator& setSizeX(Ogre::Real sizeX)
53
+ {
54
+ mSizeX = sizeX;
55
+ return *this;
56
+ }
57
+
58
+ /** Sets the size of the box along Y axis */
59
+ RoundedBoxGenerator& setSizeY(Ogre::Real sizeY)
60
+ {
61
+ mSizeY = sizeY;
62
+ return *this;
63
+ }
64
+
65
+ /** Sets the size of the box along Z axis */
66
+ RoundedBoxGenerator& setSizeZ(Ogre::Real sizeZ)
67
+ {
68
+ mSizeZ = sizeZ;
69
+ return *this;
70
+ }
71
+
72
+ /** Sets the number of segments along X axis */
73
+ RoundedBoxGenerator& setNumSegX(unsigned short numSegX)
74
+ {
75
+ mNumSegX = numSegX;
76
+ return *this;
77
+ }
78
+
79
+ /** Sets the number of segments along Y axis */
80
+ RoundedBoxGenerator& setNumSegY(unsigned short numSegY)
81
+ {
82
+ mNumSegY = numSegY;
83
+ return *this;
84
+ }
85
+
86
+ /** Sets the number of segments along Z axis */
87
+ RoundedBoxGenerator& setNumSegZ(unsigned short numSegZ)
88
+ {
89
+ mNumSegZ = numSegZ;
90
+ return *this;
91
+ }
92
+
93
+ /** Sets the size of the chamfer, ie the radius of the rounded part */
94
+ RoundedBoxGenerator& setChamferSize(Ogre::Real chamferSize)
95
+ {
96
+ mChamferSize = chamferSize;
97
+ return *this;
98
+ }
99
+
100
+ /**
101
+ * Builds the mesh into the given TriangleBuffer
102
+ * @param buffer The TriangleBuffer on where to append the mesh.
103
+ */
104
+ void addToTriangleBuffer(TriangleBuffer& buffer) const;
105
+
106
+ private:
107
+
108
+ /// Internal. Builds an "edge" of the rounded box, ie a quarter cylinder
109
+ void _addEdge(TriangleBuffer& buffer, short xPos, short yPos, short zPos) const;
110
+
111
+ /// Internal. Builds a "corner" of the rounded box, ie a 1/8th of a sphere
112
+ void _addCorner(TriangleBuffer& buffer, bool isXPositive, bool isYPositive, bool isZPositive) const;
113
+
114
+ };
115
+
116
+
117
+ }
118
+ #endif
@@ -0,0 +1,532 @@
1
+ /*
2
+ -----------------------------------------------------------------------------
3
+ This source file is part of ogre-procedural
4
+
5
+ For the latest info, see http://code.google.com/p/ogre-procedural/
6
+
7
+ Copyright (c) 2010 Michael Broutin
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ of this software and associated documentation files (the "Software"), to deal
11
+ in the Software without restriction, including without limitation the rights
12
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the Software is
14
+ furnished to do so, subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in
17
+ all copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25
+ THE SOFTWARE.
26
+ -----------------------------------------------------------------------------
27
+ */
28
+ #ifndef PROCEDURAL_SHAPE_INCLUDED
29
+ #define PROCEDURAL_SHAPE_INCLUDED
30
+
31
+ #include "OgreVector2.h"
32
+ #include "ProceduralPlatform.h"
33
+ #include "ProceduralUtils.h"
34
+ #include "OgreMesh.h"
35
+ #include "OgreManualObject.h"
36
+ #include "ProceduralRoot.h"
37
+ #include "ProceduralMultiShape.h"
38
+ #include "ProceduralTrack.h"
39
+
40
+ namespace Procedural
41
+ {
42
+ class Path;
43
+
44
+ enum Side {SIDE_LEFT, SIDE_RIGHT};
45
+
46
+ /** Describes a succession of interconnected 2D points.
47
+ * It can be closed or not, and there's always an outside and an inside
48
+ */
49
+ class _ProceduralExport Shape
50
+ {
51
+ std::vector<Ogre::Vector2> mPoints;
52
+ bool mClosed;
53
+ Side mOutSide;
54
+
55
+ public:
56
+ /// Default constructor
57
+ Shape() : mClosed(false), mOutSide(SIDE_RIGHT) {}
58
+
59
+ /// Adds a point to the shape
60
+ inline Shape& addPoint(const Ogre::Vector2& pt)
61
+ {
62
+ mPoints.push_back(pt);
63
+ return *this;
64
+ }
65
+
66
+ /// Adds a point to the shape
67
+ inline Shape& addPoint(Ogre::Real x, Ogre::Real y)
68
+ {
69
+ mPoints.push_back(Ogre::Vector2(x, y));
70
+ return *this;
71
+ }
72
+
73
+ /// Inserts a point to the shape
74
+ /// @arg index the index before the inserted point
75
+ /// @arg x new point's x coordinate
76
+ /// @arg y new point's y coordinate
77
+ inline Shape& insertPoint(size_t index, Ogre::Real x, Ogre::Real y)
78
+ {
79
+ mPoints.insert(mPoints.begin()+index, Ogre::Vector2(x, y));
80
+ return *this;
81
+ }
82
+
83
+ /// Inserts a point to the shape
84
+ /// @arg index the index before the inserted point
85
+ /// @arg pt new point's position
86
+ inline Shape& insertPoint(size_t index, const Ogre::Vector2& pt)
87
+ {
88
+ mPoints.insert(mPoints.begin()+index, pt);
89
+ return *this;
90
+ }
91
+
92
+ /// Adds a point to the shape, relative to the last point added
93
+ inline Shape& addPointRel(const Ogre::Vector2& pt)
94
+ {
95
+ if (mPoints.empty())
96
+ mPoints.push_back(pt);
97
+ else
98
+ mPoints.push_back(pt + *(mPoints.end()-1));
99
+ return *this;
100
+ }
101
+
102
+ /// Adds a point to the shape, relative to the last point added
103
+ inline Shape& addPointRel(Ogre::Real x, Ogre::Real y)
104
+ {
105
+ if (mPoints.empty())
106
+ mPoints.push_back(Ogre::Vector2(x, y));
107
+ else
108
+ mPoints.push_back(Ogre::Vector2(x, y) + *(mPoints.end()-1));
109
+ return *this;
110
+ }
111
+
112
+ /// Appends another shape at the end of this one
113
+ inline Shape& appendShape(const Shape& other)
114
+ {
115
+ mPoints.insert(mPoints.end(), other.mPoints.begin(), other.mPoints.end());
116
+ return *this;
117
+ }
118
+
119
+ /// Appends another shape at the end of this one, relative to the last point of this shape
120
+ inline Shape& appendShapeRel(const Shape& other)
121
+ {
122
+ if (mPoints.empty())
123
+ appendShape(other);
124
+ else
125
+ {
126
+ Ogre::Vector2 refVector = *(mPoints.end()-1);
127
+ std::vector<Ogre::Vector2> pointList(other.mPoints.begin(), other.mPoints.end());
128
+ for (std::vector<Ogre::Vector2>::iterator it = pointList.begin(); it!=pointList.end(); it++)
129
+ *it +=refVector;
130
+ mPoints.insert(mPoints.end(), pointList.begin(), pointList.end());
131
+ }
132
+ return *this;
133
+ }
134
+
135
+ /// Extracts a part of the shape as a new shape
136
+ /// @arg first first index to be in the new shape
137
+ /// @arg last last index to be in the new shape
138
+ inline Shape extractSubShape(unsigned int first, unsigned int last)
139
+ {
140
+ Shape s;
141
+ for (unsigned int i=first;i<=last;i++)
142
+ s.addPoint(mPoints[i]);
143
+ s.setOutSide(mOutSide);
144
+ if (mClosed)
145
+ s.close();
146
+ return s;
147
+ }
148
+
149
+ /// Reverses direction of the shape
150
+ /// The outside is preserved
151
+ inline Shape& reverse()
152
+ {
153
+ std::reverse(mPoints.begin(), mPoints.end());
154
+ switchSide();
155
+ return *this;
156
+ }
157
+
158
+ /// Clears the content of the shape
159
+ inline Shape& reset()
160
+ {
161
+ mPoints.clear();
162
+ return *this;
163
+ }
164
+
165
+ /// Converts the shape to a path, with Y=0
166
+ Path convertToPath() const;
167
+
168
+ /// Outputs a track, with Key=X and Value=Y
169
+ Track convertToTrack(Track::AddressingMode addressingMode=Track::AM_RELATIVE_LINEIC) const;
170
+
171
+ /// Gets raw vector data of this shape
172
+ inline std::vector<Ogre::Vector2> getPoints() const
173
+ {
174
+ return mPoints;
175
+ }
176
+
177
+ /// Gets raw vector data of this shape as a non-const reference
178
+ inline std::vector<Ogre::Vector2>& getPointsReference()
179
+ {
180
+ return mPoints;
181
+ }
182
+
183
+ /// Gets raw vector data of this shape as a non-const reference
184
+ inline const std::vector<Ogre::Vector2>& getPointsReference() const
185
+ {
186
+ return mPoints;
187
+ }
188
+
189
+ /**
190
+ * Bounds-safe method to get a point : it will allow you to go beyond the bounds
191
+ */
192
+ inline const Ogre::Vector2& getPoint(unsigned int i) const
193
+ {
194
+ if (mClosed)
195
+ return mPoints[Utils::modulo(i,mPoints.size())];
196
+ return mPoints[Utils::cap(i,0,mPoints.size()-1)];
197
+ }
198
+
199
+ /**
200
+ * Makes the shape a closed shape, ie it will automatically connect
201
+ * the last point to the first point.
202
+ */
203
+ inline Shape& close()
204
+ {
205
+ mClosed = true;
206
+ return *this;
207
+ }
208
+
209
+ /**
210
+ * Sets which side (left or right) is on the outside of the shape.
211
+ * It is used for such things as normal generation
212
+ * Default is right, which corresponds to placing points anti-clockwise.
213
+ */
214
+ inline Shape& setOutSide(Side side)
215
+ {
216
+ mOutSide = side;
217
+ return *this;
218
+ }
219
+
220
+ /// Gets which side is out
221
+ inline Side getOutSide() const
222
+ {
223
+ return mOutSide;
224
+ }
225
+
226
+ /// Switches the inside and the outside
227
+ inline Shape& switchSide()
228
+ {
229
+ mOutSide = (mOutSide == SIDE_LEFT)? SIDE_RIGHT: SIDE_LEFT;
230
+ return *this;
231
+ }
232
+
233
+ /// Gets the number of segments in that shape
234
+ inline size_t getSegCount() const
235
+ {
236
+ return (mPoints.size()-1) + (mClosed?1:0);
237
+ }
238
+
239
+ /// Gets whether the shape is closed or not
240
+ inline bool isClosed() const
241
+ {
242
+ return mClosed;
243
+ }
244
+
245
+ /**
246
+ * Returns local direction after the current point
247
+ */
248
+ inline Ogre::Vector2 getDirectionAfter(unsigned int i) const
249
+ {
250
+ // If the path isn't closed, we get a different calculation at the end, because
251
+ // the tangent shall not be null
252
+ if (! mClosed && i == mPoints.size() - 1 && i > 0)
253
+ return (mPoints[i] - mPoints[i-1]).normalisedCopy();
254
+ else
255
+ return (getPoint(i+1) - getPoint(i)).normalisedCopy();
256
+ }
257
+
258
+ /**
259
+ * Returns local direction after the current point
260
+ */
261
+ inline Ogre::Vector2 getDirectionBefore(unsigned int i) const
262
+ {
263
+ // If the path isn't closed, we get a different calculation at the end, because
264
+ // the tangent shall not be null
265
+ if (!mClosed && i == 1)
266
+ return (mPoints[1] - mPoints[0]).normalisedCopy();
267
+ else
268
+ return (getPoint(i) - getPoint(i-1)).normalisedCopy();
269
+ }
270
+
271
+ /// Gets the average between before direction and after direction
272
+ inline Ogre::Vector2 getAvgDirection(unsigned int i) const
273
+ {
274
+ return (getDirectionAfter(i) + getDirectionBefore(i)).normalisedCopy();
275
+ }
276
+
277
+ /// Gets the shape normal just after that point
278
+ inline Ogre::Vector2 getNormalAfter(unsigned int i) const
279
+ {
280
+ if (mOutSide==SIDE_RIGHT)
281
+ return -getDirectionAfter(i).perpendicular();
282
+ return getDirectionAfter(i).perpendicular();
283
+ }
284
+
285
+ /// Gets the shape normal just before that point
286
+ inline Ogre::Vector2 getNormalBefore(unsigned int i) const
287
+ {
288
+ if (mOutSide==SIDE_RIGHT)
289
+ return -getDirectionBefore(i).perpendicular();
290
+ return getDirectionBefore(i).perpendicular();
291
+ }
292
+
293
+ /// Gets the "normal" of that point ie an average between before and after normals
294
+ inline Ogre::Vector2 getAvgNormal(unsigned int i) const
295
+ {
296
+ if (mOutSide==SIDE_RIGHT)
297
+ return -getAvgDirection(i).perpendicular();
298
+ return getAvgDirection(i).perpendicular();
299
+ }
300
+
301
+ /**
302
+ * Outputs a mesh representing the shape.
303
+ * Mostly for debugging purposes
304
+ */
305
+ Ogre::MeshPtr realizeMesh(const std::string& name="");
306
+
307
+ /**
308
+ * Appends the shape vertices to a manual object being edited
309
+ */
310
+ void _appendToManualObject(Ogre::ManualObject* manual);
311
+
312
+ /**
313
+ * Tells whether a point is inside a shape or not
314
+ * @arg point The point to check
315
+ * @return true if the point is inside this shape, false otherwise
316
+ */
317
+ bool isPointInside(const Ogre::Vector2& point) const;
318
+
319
+ /**
320
+ * Computes the intersection between this shape and another one.
321
+ * Both shapes must be closed.
322
+ * @arg other The shape against which the intersection is computed
323
+ * @return The intersection of two shapes, as a new shape
324
+ */
325
+ MultiShape booleanIntersect(const Shape& other) const;
326
+
327
+ /**
328
+ * Computes the union between this shape and another one.
329
+ * Both shapes must be closed.
330
+ */
331
+ MultiShape booleanUnion(const Shape& other) const;
332
+
333
+ /**
334
+ * Computes the difference between this shape and another one.
335
+ * Both shapes must be closed.
336
+ */
337
+ MultiShape booleanDifference(const Shape& other) const;
338
+
339
+ /**
340
+ * On a closed shape, find if the outside is located on the right
341
+ * or on the left. If the outside can easily be guessed in your context,
342
+ * you'd rather use setOutside(), which doesn't need any computation.
343
+ */
344
+ Side findRealOutSide() const;
345
+
346
+ /**
347
+ * Determines whether the outside as defined by user equals "real" outside
348
+ */
349
+ bool isOutsideRealOutside() const;
350
+
351
+ /// Creates a shape with the keys of this shape and extra keys coming from a track
352
+ /// @arg track the track to merge keys with
353
+ /// @return a new Shape coming from the merge between original shape and the track
354
+ Shape mergeKeysWithTrack(const Track& track) const;
355
+
356
+ /**
357
+ * Applies the given translation to all the points already defined.
358
+ * Has strictly no effect on the points defined after that
359
+ * @param translation the translation vector
360
+ */
361
+ Shape& translate(const Ogre::Vector2& translation)
362
+ {
363
+ for (std::vector<Ogre::Vector2>::iterator it = mPoints.begin(); it!=mPoints.end(); it++)
364
+ *it+=translation;
365
+ return *this;
366
+ }
367
+
368
+ /**
369
+ * Applies the given translation to all the points already defined.
370
+ * Has strictly no effect on the points defined after that
371
+ * @param translationX X component of the translation vector
372
+ * @param translationY Y component of the translation vector
373
+ */
374
+ Shape& translate(Ogre::Real translationX, Ogre::Real translationY)
375
+ {
376
+ return translate(Ogre::Vector2(translationX, translationY));
377
+ }
378
+
379
+ /**
380
+ * Applies the given rotation to all the points already defined.
381
+ * Has strictly no effect on the points defined after that
382
+ * @param angle angle of rotation
383
+ */
384
+ Shape& rotate(Ogre::Radian angle)
385
+ {
386
+ Ogre::Real c = Ogre::Math::Cos(angle.valueRadians());
387
+ Ogre::Real s = Ogre::Math::Sin(angle.valueRadians());
388
+ for (std::vector<Ogre::Vector2>::iterator it = mPoints.begin(); it!=mPoints.end(); it++)
389
+ {
390
+ Ogre::Real x = it->x;
391
+ Ogre::Real y = it->y;
392
+ it->x = c * x - s * y;
393
+ it->y = s * x + c * y;
394
+ }
395
+ return *this;
396
+ }
397
+
398
+ /**
399
+ * Applies the given scale to all the points already defined.
400
+ * Has strictly no effect on the points defined after that
401
+ * @param amount amount of scale
402
+ */
403
+ Shape& scale(Ogre::Real amount)
404
+ {
405
+ return scale(amount, amount);
406
+ }
407
+
408
+ /**
409
+ * Applies the given scale to all the points already defined.
410
+ * Has strictly no effect on the points defined after that
411
+ * @param scaleX amount of scale in the X direction
412
+ * @param scaleY amount of scale in the Y direction
413
+ */
414
+ Shape& scale(Ogre::Real scaleX, Ogre::Real scaleY)
415
+ {
416
+ for (std::vector<Ogre::Vector2>::iterator it = mPoints.begin(); it!=mPoints.end(); it++)
417
+ {
418
+ it->x *= scaleX;
419
+ it->y *= scaleY;
420
+ }
421
+ return *this;
422
+ }
423
+
424
+ /**
425
+ * Applies the given scale to all the points already defined.
426
+ * Has strictly no effect on the points defined after that
427
+ * @param amount of scale
428
+ */
429
+ Shape& scale(const Ogre::Vector2& amount)
430
+ {
431
+ return scale(amount.x, amount.y);
432
+ }
433
+
434
+ /**
435
+ * Reflect all points in this shape against a zero-origined line with a given normal
436
+ * @param the normal
437
+ */
438
+ Shape& reflect(const Ogre::Vector2& normal)
439
+ {
440
+ for (std::vector<Ogre::Vector2>::iterator it = mPoints.begin(); it!=mPoints.end(); it++)
441
+ {
442
+ *it = it->reflect(normal);
443
+ }
444
+ return *this;
445
+ }
446
+
447
+ /// Returns the total lineic length of that shape
448
+ Ogre::Real getTotalLength() const
449
+ {
450
+ Ogre::Real length = 0;
451
+ for (unsigned int i=0;i<mPoints.size()-1;i++)
452
+ length+=(mPoints[i+1]-mPoints[i]).length();
453
+ if (mClosed)
454
+ length+=(mPoints.back()-*mPoints.begin()).length();
455
+ return length;
456
+ }
457
+
458
+ /// Gets a position on the shape with index of the point and a percentage of position on the segment
459
+ /// @arg i index of the segment
460
+ /// @arg coord a number between 0 and 1 meaning the percentage of position on the segment
461
+ inline Ogre::Vector2 getPosition(unsigned int i, Ogre::Real coord) const
462
+ {
463
+ assert(mClosed || (i < mPoints.size() - 1 && "Out of Bounds"));
464
+ assert(coord>=0. && coord<=1. && "Coord must be comprised between 0 and 1");
465
+ Ogre::Vector2 A = getPoint(i);
466
+ Ogre::Vector2 B = getPoint(i+1);
467
+ return A + coord*(B-A);
468
+ }
469
+
470
+ /// Gets a position on the shape from lineic coordinate
471
+ /// @arg coord lineic coordinate
472
+ inline Ogre::Vector2 getPosition(Ogre::Real coord) const
473
+ {
474
+ assert(mPoints.size()>=2 && "The shape must at least contain 2 points");
475
+ unsigned int i=0;
476
+ while(true)
477
+ {
478
+ Ogre::Real nextLen = (getPoint(i+1) - getPoint(i)).length();
479
+ if (coord>nextLen)
480
+ coord-=nextLen;
481
+ else
482
+ return getPosition(i, coord);
483
+ if (!mClosed && i>= mPoints.size()-2)
484
+ return mPoints.back();
485
+ i++;
486
+ }
487
+ }
488
+
489
+ /// Computes the radius of a bounding circle centered on the origin
490
+ Ogre::Real findBoundingRadius() const
491
+ {
492
+ Ogre::Real sqRadius=0.f;
493
+ for (unsigned int i=0;i<mPoints.size();i++)
494
+ sqRadius=std::max(sqRadius,mPoints[i].squaredLength());
495
+ return Ogre::Math::Sqrt(sqRadius);
496
+ }
497
+
498
+ /// Applies a "thickness" to a shape, ie a bit like the extruder, but in 2D
499
+ MultiShape thicken(Ogre::Real amount);
500
+
501
+ private:
502
+
503
+ enum BooleanOperationType { BOT_UNION, BOT_INTERSECTION, BOT_DIFFERENCE};
504
+
505
+ MultiShape _booleanOperation(const Shape& other, BooleanOperationType opType) const;
506
+
507
+ struct IntersectionInShape
508
+ {
509
+ unsigned int index[2];
510
+ bool onVertex[2];
511
+ Ogre::Vector2 position;
512
+ IntersectionInShape(unsigned int i, unsigned int j, Ogre::Vector2 intersect) : position(intersect)
513
+ {
514
+ index[0] = i;
515
+ index[1] = j;
516
+ onVertex[0] = false;
517
+ onVertex[1] = false;
518
+ }
519
+ };
520
+
521
+ bool _isLookingForOutside(BooleanOperationType opType, char shapeSelector) const;
522
+
523
+ char _isIncreasing(Ogre::Real d, BooleanOperationType opType, char shapeSelector) const;
524
+
525
+ bool _findWhereToGo(const Shape* inputShapes[], BooleanOperationType opType, IntersectionInShape intersection, Ogre::uint8& shapeSelector, char& isIncreasing, unsigned int& currentSegment) const;
526
+
527
+ void _findAllIntersections(const Shape& other, std::vector<IntersectionInShape>& intersections) const;
528
+
529
+ };
530
+ }
531
+
532
+ #endif