3 Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include <IAnimatedMesh.h>
25 #include <SAnimatedMesh.h>
27 // In Irrlicht 1.8 the signature of ITexture::lock was changed from
28 // (bool, u32) to (E_TEXTURE_LOCK_MODE, u32).
29 #if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR <= 7
30 #define MY_ETLM_READ_ONLY true
32 #define MY_ETLM_READ_ONLY video::ETLM_READ_ONLY
35 scene::IAnimatedMesh* createCubeMesh(v3f scale)
37 video::SColor c(255,255,255,255);
38 video::S3DVertex vertices[24] =
41 video::S3DVertex(-0.5,+0.5,-0.5, 0,1,0, c, 0,1),
42 video::S3DVertex(-0.5,+0.5,+0.5, 0,1,0, c, 0,0),
43 video::S3DVertex(+0.5,+0.5,+0.5, 0,1,0, c, 1,0),
44 video::S3DVertex(+0.5,+0.5,-0.5, 0,1,0, c, 1,1),
46 video::S3DVertex(-0.5,-0.5,-0.5, 0,-1,0, c, 0,0),
47 video::S3DVertex(+0.5,-0.5,-0.5, 0,-1,0, c, 1,0),
48 video::S3DVertex(+0.5,-0.5,+0.5, 0,-1,0, c, 1,1),
49 video::S3DVertex(-0.5,-0.5,+0.5, 0,-1,0, c, 0,1),
51 video::S3DVertex(+0.5,-0.5,-0.5, 1,0,0, c, 0,1),
52 video::S3DVertex(+0.5,+0.5,-0.5, 1,0,0, c, 0,0),
53 video::S3DVertex(+0.5,+0.5,+0.5, 1,0,0, c, 1,0),
54 video::S3DVertex(+0.5,-0.5,+0.5, 1,0,0, c, 1,1),
56 video::S3DVertex(-0.5,-0.5,-0.5, -1,0,0, c, 1,1),
57 video::S3DVertex(-0.5,-0.5,+0.5, -1,0,0, c, 0,1),
58 video::S3DVertex(-0.5,+0.5,+0.5, -1,0,0, c, 0,0),
59 video::S3DVertex(-0.5,+0.5,-0.5, -1,0,0, c, 1,0),
61 video::S3DVertex(-0.5,-0.5,+0.5, 0,0,1, c, 1,1),
62 video::S3DVertex(+0.5,-0.5,+0.5, 0,0,1, c, 0,1),
63 video::S3DVertex(+0.5,+0.5,+0.5, 0,0,1, c, 0,0),
64 video::S3DVertex(-0.5,+0.5,+0.5, 0,0,1, c, 1,0),
66 video::S3DVertex(-0.5,-0.5,-0.5, 0,0,-1, c, 0,1),
67 video::S3DVertex(-0.5,+0.5,-0.5, 0,0,-1, c, 0,0),
68 video::S3DVertex(+0.5,+0.5,-0.5, 0,0,-1, c, 1,0),
69 video::S3DVertex(+0.5,-0.5,-0.5, 0,0,-1, c, 1,1),
72 u16 indices[6] = {0,1,2,2,3,0};
74 scene::SMesh *mesh = new scene::SMesh();
75 for (u32 i=0; i<6; ++i)
77 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
78 buf->append(vertices + 4 * i, 4, indices, 6);
79 // Set default material
80 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
81 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
82 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
83 // Add mesh buffer to mesh
84 mesh->addMeshBuffer(buf);
88 scene::SAnimatedMesh *anim_mesh = new scene::SAnimatedMesh(mesh);
90 scaleMesh(anim_mesh, scale); // also recalculates bounding box
94 void scaleMesh(scene::IMesh *mesh, v3f scale)
99 core::aabbox3d<f32> bbox;
102 u16 mc = mesh->getMeshBufferCount();
103 for(u16 j=0; j<mc; j++)
105 scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
106 video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
107 u16 vc = buf->getVertexCount();
108 for(u16 i=0; i<vc; i++)
110 vertices[i].Pos *= scale;
112 buf->recalculateBoundingBox();
114 // calculate total bounding box
116 bbox = buf->getBoundingBox();
118 bbox.addInternalBox(buf->getBoundingBox());
120 mesh->setBoundingBox(bbox);
123 void translateMesh(scene::IMesh *mesh, v3f vec)
128 core::aabbox3d<f32> bbox;
131 u16 mc = mesh->getMeshBufferCount();
132 for(u16 j=0; j<mc; j++)
134 scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
135 video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
136 u16 vc = buf->getVertexCount();
137 for(u16 i=0; i<vc; i++)
139 vertices[i].Pos += vec;
141 buf->recalculateBoundingBox();
143 // calculate total bounding box
145 bbox = buf->getBoundingBox();
147 bbox.addInternalBox(buf->getBoundingBox());
149 mesh->setBoundingBox(bbox);
152 void setMeshColor(scene::IMesh *mesh, const video::SColor &color)
157 u16 mc = mesh->getMeshBufferCount();
158 for(u16 j=0; j<mc; j++)
160 scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
161 video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
162 u16 vc = buf->getVertexCount();
163 for(u16 i=0; i<vc; i++)
165 vertices[i].Color = color;
170 void setMeshColorByNormalXYZ(scene::IMesh *mesh,
171 const video::SColor &colorX,
172 const video::SColor &colorY,
173 const video::SColor &colorZ)
178 u16 mc = mesh->getMeshBufferCount();
179 for(u16 j=0; j<mc; j++)
181 scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
182 video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
183 u16 vc = buf->getVertexCount();
184 for(u16 i=0; i<vc; i++)
186 f32 x = fabs(vertices[i].Normal.X);
187 f32 y = fabs(vertices[i].Normal.Y);
188 f32 z = fabs(vertices[i].Normal.Z);
190 vertices[i].Color = colorX;
192 vertices[i].Color = colorY;
194 vertices[i].Color = colorZ;
200 void rotateMeshBy6dFacedir(scene::IMesh *mesh, int facedir)
202 int axisdir = facedir>>2;
205 u16 mc = mesh->getMeshBufferCount();
206 for(u16 j = 0; j < mc; j++)
208 scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
209 video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
210 u16 vc = buf->getVertexCount();
211 for(u16 i=0; i<vc; i++)
217 vertices[i].Pos.rotateXZBy(-90);
218 else if(facedir == 2)
219 vertices[i].Pos.rotateXZBy(180);
220 else if(facedir == 3)
221 vertices[i].Pos.rotateXZBy(90);
224 vertices[i].Pos.rotateYZBy(90);
226 vertices[i].Pos.rotateXYBy(90);
227 else if(facedir == 2)
228 vertices[i].Pos.rotateXYBy(180);
229 else if(facedir == 3)
230 vertices[i].Pos.rotateXYBy(-90);
233 vertices[i].Pos.rotateYZBy(-90);
235 vertices[i].Pos.rotateXYBy(-90);
236 else if(facedir == 2)
237 vertices[i].Pos.rotateXYBy(180);
238 else if(facedir == 3)
239 vertices[i].Pos.rotateXYBy(90);
242 vertices[i].Pos.rotateXYBy(-90);
244 vertices[i].Pos.rotateYZBy(90);
245 else if(facedir == 2)
246 vertices[i].Pos.rotateYZBy(180);
247 else if(facedir == 3)
248 vertices[i].Pos.rotateYZBy(-90);
251 vertices[i].Pos.rotateXYBy(90);
253 vertices[i].Pos.rotateYZBy(-90);
254 else if(facedir == 2)
255 vertices[i].Pos.rotateYZBy(180);
256 else if(facedir == 3)
257 vertices[i].Pos.rotateYZBy(90);
260 vertices[i].Pos.rotateXYBy(-180);
262 vertices[i].Pos.rotateXZBy(90);
263 else if(facedir == 2)
264 vertices[i].Pos.rotateXZBy(180);
265 else if(facedir == 3)
266 vertices[i].Pos.rotateXZBy(-90);
275 void recalculateBoundingBox(scene::IMesh *src_mesh)
277 core::aabbox3d<f32> bbox;
279 for(u16 j = 0; j < src_mesh->getMeshBufferCount(); j++)
281 scene::IMeshBuffer *buf = src_mesh->getMeshBuffer(j);
282 buf->recalculateBoundingBox();
284 bbox = buf->getBoundingBox();
286 bbox.addInternalBox(buf->getBoundingBox());
288 src_mesh->setBoundingBox(bbox);
291 scene::IMesh* cloneMesh(scene::IMesh *src_mesh)
293 scene::SMesh* dst_mesh = new scene::SMesh();
294 for(u16 j = 0; j < src_mesh->getMeshBufferCount(); j++)
296 scene::IMeshBuffer *buf = src_mesh->getMeshBuffer(j);
297 video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
298 u16 *indices = (u16*)buf->getIndices();
299 scene::SMeshBuffer *temp_buf = new scene::SMeshBuffer();
300 temp_buf->append(vertices, buf->getVertexCount(),
301 indices, buf->getIndexCount());
302 dst_mesh->addMeshBuffer(temp_buf);
308 scene::IMesh* convertNodeboxNodeToMesh(ContentFeatures *f)
310 scene::SMesh* dst_mesh = new scene::SMesh();
311 for (u16 j = 0; j < 6; j++)
313 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
314 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
315 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
316 dst_mesh->addMeshBuffer(buf);
320 video::SColor c(255,255,255,255);
322 std::vector<aabb3f> boxes = f->node_box.fixed;
324 for(std::vector<aabb3f>::iterator
326 i != boxes.end(); i++)
331 if (box.MinEdge.X > box.MaxEdge.X)
334 box.MinEdge.X=box.MaxEdge.X;
337 if (box.MinEdge.Y > box.MaxEdge.Y)
340 box.MinEdge.Y=box.MaxEdge.Y;
343 if (box.MinEdge.Z > box.MaxEdge.Z)
346 box.MinEdge.Z=box.MaxEdge.Z;
349 // Compute texture coords
350 f32 tx1 = (box.MinEdge.X/BS)+0.5;
351 f32 ty1 = (box.MinEdge.Y/BS)+0.5;
352 f32 tz1 = (box.MinEdge.Z/BS)+0.5;
353 f32 tx2 = (box.MaxEdge.X/BS)+0.5;
354 f32 ty2 = (box.MaxEdge.Y/BS)+0.5;
355 f32 tz2 = (box.MaxEdge.Z/BS)+0.5;
358 tx1, 1-tz2, tx2, 1-tz1,
362 tz1, 1-ty2, tz2, 1-ty1,
364 1-tz2, 1-ty2, 1-tz1, 1-ty1,
366 1-tx2, 1-ty2, 1-tx1, 1-ty1,
368 tx1, 1-ty2, tx2, 1-ty1,
370 v3f min = box.MinEdge;
371 v3f max = box.MaxEdge;
373 video::S3DVertex vertices[24] =
376 video::S3DVertex(min.X,max.Y,max.Z, 0,1,0, c, txc[0],txc[1]),
377 video::S3DVertex(max.X,max.Y,max.Z, 0,1,0, c, txc[2],txc[1]),
378 video::S3DVertex(max.X,max.Y,min.Z, 0,1,0, c, txc[2],txc[3]),
379 video::S3DVertex(min.X,max.Y,min.Z, 0,1,0, c, txc[0],txc[3]),
381 video::S3DVertex(min.X,min.Y,min.Z, 0,-1,0, c, txc[4],txc[5]),
382 video::S3DVertex(max.X,min.Y,min.Z, 0,-1,0, c, txc[6],txc[5]),
383 video::S3DVertex(max.X,min.Y,max.Z, 0,-1,0, c, txc[6],txc[7]),
384 video::S3DVertex(min.X,min.Y,max.Z, 0,-1,0, c, txc[4],txc[7]),
386 video::S3DVertex(max.X,max.Y,min.Z, 1,0,0, c, txc[ 8],txc[9]),
387 video::S3DVertex(max.X,max.Y,max.Z, 1,0,0, c, txc[10],txc[9]),
388 video::S3DVertex(max.X,min.Y,max.Z, 1,0,0, c, txc[10],txc[11]),
389 video::S3DVertex(max.X,min.Y,min.Z, 1,0,0, c, txc[ 8],txc[11]),
391 video::S3DVertex(min.X,max.Y,max.Z, -1,0,0, c, txc[12],txc[13]),
392 video::S3DVertex(min.X,max.Y,min.Z, -1,0,0, c, txc[14],txc[13]),
393 video::S3DVertex(min.X,min.Y,min.Z, -1,0,0, c, txc[14],txc[15]),
394 video::S3DVertex(min.X,min.Y,max.Z, -1,0,0, c, txc[12],txc[15]),
396 video::S3DVertex(max.X,max.Y,max.Z, 0,0,1, c, txc[16],txc[17]),
397 video::S3DVertex(min.X,max.Y,max.Z, 0,0,1, c, txc[18],txc[17]),
398 video::S3DVertex(min.X,min.Y,max.Z, 0,0,1, c, txc[18],txc[19]),
399 video::S3DVertex(max.X,min.Y,max.Z, 0,0,1, c, txc[16],txc[19]),
401 video::S3DVertex(min.X,max.Y,min.Z, 0,0,-1, c, txc[20],txc[21]),
402 video::S3DVertex(max.X,max.Y,min.Z, 0,0,-1, c, txc[22],txc[21]),
403 video::S3DVertex(max.X,min.Y,min.Z, 0,0,-1, c, txc[22],txc[23]),
404 video::S3DVertex(min.X,min.Y,min.Z, 0,0,-1, c, txc[20],txc[23]),
407 u16 indices[] = {0,1,2,2,3,0};
409 for(u16 j = 0; j < 24; j += 4)
411 scene::IMeshBuffer *buf = dst_mesh->getMeshBuffer(j / 4);
412 buf->append(vertices + j, 4, indices, 6);