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