ruby-procedural 0.0.1-x86-linux
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +4 -0
- data/README.md +29 -0
- data/Rakefile +65 -0
- data/bindings/procedural/interface/ProceduralBoxGenerator.i +12 -0
- data/bindings/procedural/interface/ProceduralCapsuleGenerator.i +12 -0
- data/bindings/procedural/interface/ProceduralConeGenerator.i +12 -0
- data/bindings/procedural/interface/ProceduralCylinderGenerator.i +12 -0
- data/bindings/procedural/interface/ProceduralExtruder.i +8 -0
- data/bindings/procedural/interface/ProceduralGeometryHelpers.i +15 -0
- data/bindings/procedural/interface/ProceduralHeader.i +8 -0
- data/bindings/procedural/interface/ProceduralIcoSphereGenerator.i +12 -0
- data/bindings/procedural/interface/ProceduralLathe.i +8 -0
- data/bindings/procedural/interface/ProceduralMeshGenerator.i +9 -0
- data/bindings/procedural/interface/ProceduralMultiShape.i +8 -0
- data/bindings/procedural/interface/ProceduralPath.i +8 -0
- data/bindings/procedural/interface/ProceduralPathGenerators.i +10 -0
- data/bindings/procedural/interface/ProceduralPlaneGenerator.i +12 -0
- data/bindings/procedural/interface/ProceduralPlatform.i +8 -0
- data/bindings/procedural/interface/ProceduralRoot.i +23 -0
- data/bindings/procedural/interface/ProceduralRoundedBoxGenerator.i +12 -0
- data/bindings/procedural/interface/ProceduralShape.i +8 -0
- data/bindings/procedural/interface/ProceduralShapeGenerators.i +10 -0
- data/bindings/procedural/interface/ProceduralSphereGenerator.i +11 -0
- data/bindings/procedural/interface/ProceduralSplines.i +8 -0
- data/bindings/procedural/interface/ProceduralStableHeaders.i +8 -0
- data/bindings/procedural/interface/ProceduralTorusGenerator.i +12 -0
- data/bindings/procedural/interface/ProceduralTorusKnotGenerator.i +12 -0
- data/bindings/procedural/interface/ProceduralTrack.i +8 -0
- data/bindings/procedural/interface/ProceduralTriangleBuffer.i +13 -0
- data/bindings/procedural/interface/ProceduralTriangulator.i +8 -0
- data/bindings/procedural/interface/ProceduralTubeGenerator.i +12 -0
- data/bindings/procedural/interface/ProceduralUtils.i +8 -0
- data/bindings/procedural/interface/Rakefile +22 -0
- data/bindings/procedural/interface/procedural.i +41 -0
- data/bindings/procedural/interface/procedural_wrap.cpp +36079 -0
- data/bindings/procedural/interface/procedural_wrap.h +19 -0
- data/bindings/procedural/interface/procedural_wrap.o +0 -0
- data/deps/include/OgreProcedural/Procedural.h +54 -0
- data/deps/include/OgreProcedural/ProceduralBoxGenerator.h +110 -0
- data/deps/include/OgreProcedural/ProceduralCapsuleGenerator.h +103 -0
- data/deps/include/OgreProcedural/ProceduralConeGenerator.h +90 -0
- data/deps/include/OgreProcedural/ProceduralCylinderGenerator.h +99 -0
- data/deps/include/OgreProcedural/ProceduralExtruder.h +131 -0
- data/deps/include/OgreProcedural/ProceduralGeometryHelpers.h +171 -0
- data/deps/include/OgreProcedural/ProceduralIcoSphereGenerator.h +76 -0
- data/deps/include/OgreProcedural/ProceduralLathe.h +129 -0
- data/deps/include/OgreProcedural/ProceduralMeshGenerator.h +286 -0
- data/deps/include/OgreProcedural/ProceduralMultiShape.h +126 -0
- data/deps/include/OgreProcedural/ProceduralPath.h +322 -0
- data/deps/include/OgreProcedural/ProceduralPathGenerators.h +281 -0
- data/deps/include/OgreProcedural/ProceduralPlaneGenerator.h +93 -0
- data/deps/include/OgreProcedural/ProceduralPlatform.h +54 -0
- data/deps/include/OgreProcedural/ProceduralRoot.h +65 -0
- data/deps/include/OgreProcedural/ProceduralRoundedBoxGenerator.h +118 -0
- data/deps/include/OgreProcedural/ProceduralShape.h +532 -0
- data/deps/include/OgreProcedural/ProceduralShapeGenerators.h +362 -0
- data/deps/include/OgreProcedural/ProceduralSphereGenerator.h +80 -0
- data/deps/include/OgreProcedural/ProceduralSplines.h +168 -0
- data/deps/include/OgreProcedural/ProceduralStableHeaders.h +28 -0
- data/deps/include/OgreProcedural/ProceduralTorusGenerator.h +88 -0
- data/deps/include/OgreProcedural/ProceduralTorusKnotGenerator.h +106 -0
- data/deps/include/OgreProcedural/ProceduralTrack.h +122 -0
- data/deps/include/OgreProcedural/ProceduralTriangleBuffer.h +328 -0
- data/deps/include/OgreProcedural/ProceduralTriangulator.h +173 -0
- data/deps/include/OgreProcedural/ProceduralTubeGenerator.h +96 -0
- data/deps/include/OgreProcedural/ProceduralUtils.h +185 -0
- data/deps/lib/libOgreProcedural.so +0 -0
- data/lib/procedural.so +0 -0
- data/lib/ruby-procedural/version.rb +5 -0
- data/lib/ruby-procedural.rb +27 -0
- data/ruby-procedural.gemspec +33 -0
- 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
|