ruby-procedural 0.0.1-x86-linux
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.
- 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
|