aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/source/Irrlicht/CTriangleSelector.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/CTriangleSelector.cpp')
-rw-r--r--src/others/irrlicht-1.8.1/source/Irrlicht/CTriangleSelector.cpp298
1 files changed, 298 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTriangleSelector.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTriangleSelector.cpp
new file mode 100644
index 0000000..7b30882
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTriangleSelector.cpp
@@ -0,0 +1,298 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt
2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h
4
5#include "CTriangleSelector.h"
6#include "ISceneNode.h"
7#include "IMeshBuffer.h"
8#include "IAnimatedMeshSceneNode.h"
9
10namespace irr
11{
12namespace scene
13{
14
15//! constructor
16CTriangleSelector::CTriangleSelector(ISceneNode* node)
17: SceneNode(node), AnimatedNode(0), LastMeshFrame(0)
18{
19 #ifdef _DEBUG
20 setDebugName("CTriangleSelector");
21 #endif
22
23 BoundingBox.reset(0.f, 0.f, 0.f);
24}
25
26
27//! constructor
28CTriangleSelector::CTriangleSelector(const core::aabbox3d<f32>& box, ISceneNode* node)
29: SceneNode(node), AnimatedNode(0), LastMeshFrame(0)
30{
31 #ifdef _DEBUG
32 setDebugName("CTriangleSelector");
33 #endif
34
35 BoundingBox=box;
36 // TODO
37}
38
39
40//! constructor
41CTriangleSelector::CTriangleSelector(const IMesh* mesh, ISceneNode* node)
42: SceneNode(node), AnimatedNode(0), LastMeshFrame(0)
43{
44 #ifdef _DEBUG
45 setDebugName("CTriangleSelector");
46 #endif
47
48 createFromMesh(mesh);
49}
50
51
52CTriangleSelector::CTriangleSelector(IAnimatedMeshSceneNode* node)
53: SceneNode(node), AnimatedNode(node), LastMeshFrame(0)
54{
55 #ifdef _DEBUG
56 setDebugName("CTriangleSelector");
57 #endif
58
59 if (!AnimatedNode)
60 return;
61
62 IAnimatedMesh* animatedMesh = AnimatedNode->getMesh();
63 if (!animatedMesh)
64 return;
65
66 LastMeshFrame = (u32)AnimatedNode->getFrameNr();
67 IMesh* mesh = animatedMesh->getMesh(LastMeshFrame);
68
69 if (mesh)
70 createFromMesh(mesh);
71}
72
73
74void CTriangleSelector::createFromMesh(const IMesh* mesh)
75{
76 const u32 cnt = mesh->getMeshBufferCount();
77 u32 totalFaceCount = 0;
78 for (u32 j=0; j<cnt; ++j)
79 totalFaceCount += mesh->getMeshBuffer(j)->getIndexCount();
80 totalFaceCount /= 3;
81 Triangles.reallocate(totalFaceCount);
82 BoundingBox.reset(0.f, 0.f, 0.f);
83
84 for (u32 i=0; i<cnt; ++i)
85 {
86 const IMeshBuffer* buf = mesh->getMeshBuffer(i);
87
88 const u32 idxCnt = buf->getIndexCount();
89 const u16* const indices = buf->getIndices();
90
91 for (u32 j=0; j<idxCnt; j+=3)
92 {
93 Triangles.push_back(core::triangle3df(
94 buf->getPosition(indices[j+0]),
95 buf->getPosition(indices[j+1]),
96 buf->getPosition(indices[j+2])));
97 const core::triangle3df& tri = Triangles.getLast();
98 BoundingBox.addInternalPoint(tri.pointA);
99 BoundingBox.addInternalPoint(tri.pointB);
100 BoundingBox.addInternalPoint(tri.pointC);
101 }
102 }
103}
104
105
106void CTriangleSelector::updateFromMesh(const IMesh* mesh) const
107{
108 if (!mesh)
109 return;
110
111 u32 meshBuffers = mesh->getMeshBufferCount();
112 u32 triangleCount = 0;
113
114 BoundingBox.reset(0.f, 0.f, 0.f);
115 for (u32 i = 0; i < meshBuffers; ++i)
116 {
117 IMeshBuffer* buf = mesh->getMeshBuffer(i);
118 u32 idxCnt = buf->getIndexCount();
119 const u16* indices = buf->getIndices();
120
121 for (u32 index = 0; index < idxCnt; index += 3)
122 {
123 core::triangle3df& tri = Triangles[triangleCount++];
124 tri.pointA = buf->getPosition(indices[index + 0]);
125 tri.pointB = buf->getPosition(indices[index + 1]);
126 tri.pointC = buf->getPosition(indices[index + 2]);
127 BoundingBox.addInternalPoint(tri.pointA);
128 BoundingBox.addInternalPoint(tri.pointB);
129 BoundingBox.addInternalPoint(tri.pointC);
130 }
131 }
132}
133
134
135void CTriangleSelector::update(void) const
136{
137 if (!AnimatedNode)
138 return; //< harmless no-op
139
140 const u32 currentFrame = (u32)AnimatedNode->getFrameNr();
141 if (currentFrame == LastMeshFrame)
142 return; //< Nothing to do
143
144 LastMeshFrame = currentFrame;
145 IAnimatedMesh * animatedMesh = AnimatedNode->getMesh();
146
147 if (animatedMesh)
148 {
149 IMesh * mesh = animatedMesh->getMesh(LastMeshFrame);
150
151 if (mesh)
152 updateFromMesh(mesh);
153 }
154}
155
156
157//! Gets all triangles.
158void CTriangleSelector::getTriangles(core::triangle3df* triangles,
159 s32 arraySize, s32& outTriangleCount,
160 const core::matrix4* transform) const
161{
162 // Update my triangles if necessary
163 update();
164
165 u32 cnt = Triangles.size();
166 if (cnt > (u32)arraySize)
167 cnt = (u32)arraySize;
168
169 core::matrix4 mat;
170 if (transform)
171 mat = *transform;
172 if (SceneNode)
173 mat *= SceneNode->getAbsoluteTransformation();
174
175 for (u32 i=0; i<cnt; ++i)
176 {
177 mat.transformVect( triangles[i].pointA, Triangles[i].pointA );
178 mat.transformVect( triangles[i].pointB, Triangles[i].pointB );
179 mat.transformVect( triangles[i].pointC, Triangles[i].pointC );
180 }
181
182 outTriangleCount = cnt;
183}
184
185
186//! Gets all triangles which lie within a specific bounding box.
187void CTriangleSelector::getTriangles(core::triangle3df* triangles,
188 s32 arraySize, s32& outTriangleCount,
189 const core::aabbox3d<f32>& box,
190 const core::matrix4* transform) const
191{
192 // Update my triangles if necessary
193 update();
194
195 core::matrix4 mat(core::matrix4::EM4CONST_NOTHING);
196 core::aabbox3df tBox(box);
197
198 if (SceneNode)
199 {
200 SceneNode->getAbsoluteTransformation().getInverse(mat);
201 mat.transformBoxEx(tBox);
202 }
203 if (transform)
204 mat = *transform;
205 else
206 mat.makeIdentity();
207 if (SceneNode)
208 mat *= SceneNode->getAbsoluteTransformation();
209
210 outTriangleCount = 0;
211
212 if (!tBox.intersectsWithBox(BoundingBox))
213 return;
214
215 s32 triangleCount = 0;
216 const u32 cnt = Triangles.size();
217 for (u32 i=0; i<cnt; ++i)
218 {
219 // This isn't an accurate test, but it's fast, and the
220 // API contract doesn't guarantee complete accuracy.
221 if (Triangles[i].isTotalOutsideBox(tBox))
222 continue;
223
224 triangles[triangleCount] = Triangles[i];
225 mat.transformVect(triangles[triangleCount].pointA);
226 mat.transformVect(triangles[triangleCount].pointB);
227 mat.transformVect(triangles[triangleCount].pointC);
228
229 ++triangleCount;
230
231 if (triangleCount == arraySize)
232 break;
233 }
234
235 outTriangleCount = triangleCount;
236}
237
238
239//! Gets all triangles which have or may have contact with a 3d line.
240void CTriangleSelector::getTriangles(core::triangle3df* triangles,
241 s32 arraySize, s32& outTriangleCount,
242 const core::line3d<f32>& line,
243 const core::matrix4* transform) const
244{
245 // Update my triangles if necessary
246 update();
247
248 core::aabbox3d<f32> box(line.start);
249 box.addInternalPoint(line.end);
250
251 // TODO: Could be optimized for line a little bit more.
252 getTriangles(triangles, arraySize, outTriangleCount,
253 box, transform);
254}
255
256
257//! Returns amount of all available triangles in this selector
258s32 CTriangleSelector::getTriangleCount() const
259{
260 return Triangles.size();
261}
262
263
264/* Get the number of TriangleSelectors that are part of this one.
265Only useful for MetaTriangleSelector others return 1
266*/
267u32 CTriangleSelector::getSelectorCount() const
268{
269 return 1;
270}
271
272
273/* Get the TriangleSelector based on index based on getSelectorCount.
274Only useful for MetaTriangleSelector others return 'this' or 0
275*/
276ITriangleSelector* CTriangleSelector::getSelector(u32 index)
277{
278 if (index)
279 return 0;
280 else
281 return this;
282}
283
284
285/* Get the TriangleSelector based on index based on getSelectorCount.
286Only useful for MetaTriangleSelector others return 'this' or 0
287*/
288const ITriangleSelector* CTriangleSelector::getSelector(u32 index) const
289{
290 if (index)
291 return 0;
292 else
293 return this;
294}
295
296
297} // end namespace scene
298} // end namespace irr