#include <iostream>
#include <IAnimatedMesh.h>
#include <SAnimatedMesh.h>
+#include <IAnimatedMeshSceneNode.h>
// In Irrlicht 1.8 the signature of ITexture::lock was changed from
// (bool, u32) to (E_TEXTURE_LOCK_MODE, u32).
#define MY_ETLM_READ_ONLY video::ETLM_READ_ONLY
#endif
-static void applyFacesShading(video::SColor& color, float factor)
+inline static void applyShadeFactor(video::SColor& color, float factor)
{
color.setRed(core::clamp(core::round32(color.getRed()*factor), 0, 255));
color.setGreen(core::clamp(core::round32(color.getGreen()*factor), 0, 255));
color.setBlue(core::clamp(core::round32(color.getBlue()*factor), 0, 255));
}
+void applyFacesShading(video::SColor &color, const v3f &normal)
+{
+ /*
+ Some drawtypes have normals set to (0, 0, 0), this must result in
+ maximum brightness: shade factor 1.0.
+ Shade factors for aligned cube faces are:
+ +Y 1.000000 sqrt(1.0)
+ -Y 0.447213 sqrt(0.2)
+ +-X 0.670820 sqrt(0.45)
+ +-Z 0.836660 sqrt(0.7)
+ */
+ float x2 = normal.X * normal.X;
+ float y2 = normal.Y * normal.Y;
+ float z2 = normal.Z * normal.Z;
+ if (normal.Y < 0)
+ applyShadeFactor(color, 0.670820f * x2 + 0.447213f * y2 + 0.836660f * z2);
+ else if ((x2 > 1e-3) || (z2 > 1e-3))
+ applyShadeFactor(color, 0.670820f * x2 + 1.000000f * y2 + 0.836660f * z2);
+}
+
scene::IAnimatedMesh* createCubeMesh(v3f scale)
{
video::SColor c(255,255,255,255);
mesh->setBoundingBox(bbox);
}
-
-void setMeshColor(scene::IMesh *mesh, const video::SColor &color)
+void setMeshBufferColor(scene::IMeshBuffer *buf, const video::SColor &color)
{
- if (mesh == NULL)
- return;
+ const u32 stride = getVertexPitchFromType(buf->getVertexType());
+ u32 vertex_count = buf->getVertexCount();
+ u8 *vertices = (u8 *) buf->getVertices();
+ for (u32 i = 0; i < vertex_count; i++)
+ ((video::S3DVertex *) (vertices + i * stride))->Color = color;
+}
- u32 mc = mesh->getMeshBufferCount();
- for (u32 j = 0; j < mc; j++) {
- scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
- const u32 stride = getVertexPitchFromType(buf->getVertexType());
- u32 vertex_count = buf->getVertexCount();
- u8 *vertices = (u8 *)buf->getVertices();
- for (u32 i = 0; i < vertex_count; i++)
- ((video::S3DVertex *)(vertices + i * stride))->Color = color;
+void setAnimatedMeshColor(scene::IAnimatedMeshSceneNode *node, const video::SColor &color)
+{
+ for (u32 i = 0; i < node->getMaterialCount(); ++i) {
+ node->getMaterial(i).EmissiveColor = color;
}
}
-void shadeMeshFaces(scene::IMesh *mesh)
+void setMeshColor(scene::IMesh *mesh, const video::SColor &color)
{
if (mesh == NULL)
return;
u32 mc = mesh->getMeshBufferCount();
- for (u32 j = 0; j < mc; j++) {
- scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
- const u32 stride = getVertexPitchFromType(buf->getVertexType());
- u32 vertex_count = buf->getVertexCount();
- u8 *vertices = (u8 *)buf->getVertices();
- for (u32 i = 0; i < vertex_count; i++) {
- video::S3DVertex *vertex = (video::S3DVertex *)(vertices + i * stride);
- video::SColor &vc = vertex->Color;
- // Many special drawtypes have normals set to 0,0,0 and this
- // must result in maximum brightness (no face shadng).
- if (vertex->Normal.Y < -0.5f)
- applyFacesShading (vc, 0.447213f);
- else if (vertex->Normal.X > 0.5f || vertex->Normal.X < -0.5f)
- applyFacesShading (vc, 0.670820f);
- else if (vertex->Normal.Z > 0.5f || vertex->Normal.Z < -0.5f)
- applyFacesShading (vc, 0.836660f);
- }
+ for (u32 j = 0; j < mc; j++)
+ setMeshBufferColor(mesh->getMeshBuffer(j), color);
+}
+
+void colorizeMeshBuffer(scene::IMeshBuffer *buf, const video::SColor *buffercolor)
+{
+ const u32 stride = getVertexPitchFromType(buf->getVertexType());
+ u32 vertex_count = buf->getVertexCount();
+ u8 *vertices = (u8 *) buf->getVertices();
+ for (u32 i = 0; i < vertex_count; i++) {
+ video::S3DVertex *vertex = (video::S3DVertex *) (vertices + i * stride);
+ video::SColor *vc = &(vertex->Color);
+ // Reset color
+ *vc = *buffercolor;
+ // Apply shading
+ applyFacesShading(*vc, vertex->Normal);
}
}
src_mesh->setBoundingBox(bbox);
}
-scene::IMesh* cloneMesh(scene::IMesh *src_mesh)
+scene::IMeshBuffer* cloneMeshBuffer(scene::IMeshBuffer *mesh_buffer)
+{
+ switch (mesh_buffer->getVertexType()) {
+ case video::EVT_STANDARD: {
+ video::S3DVertex *v = (video::S3DVertex *) mesh_buffer->getVertices();
+ u16 *indices = mesh_buffer->getIndices();
+ scene::SMeshBuffer *cloned_buffer = new scene::SMeshBuffer();
+ cloned_buffer->append(v, mesh_buffer->getVertexCount(), indices,
+ mesh_buffer->getIndexCount());
+ return cloned_buffer;
+ }
+ case video::EVT_2TCOORDS: {
+ video::S3DVertex2TCoords *v =
+ (video::S3DVertex2TCoords *) mesh_buffer->getVertices();
+ u16 *indices = mesh_buffer->getIndices();
+ scene::SMeshBufferTangents *cloned_buffer =
+ new scene::SMeshBufferTangents();
+ cloned_buffer->append(v, mesh_buffer->getVertexCount(), indices,
+ mesh_buffer->getIndexCount());
+ return cloned_buffer;
+ }
+ case video::EVT_TANGENTS: {
+ video::S3DVertexTangents *v =
+ (video::S3DVertexTangents *) mesh_buffer->getVertices();
+ u16 *indices = mesh_buffer->getIndices();
+ scene::SMeshBufferTangents *cloned_buffer =
+ new scene::SMeshBufferTangents();
+ cloned_buffer->append(v, mesh_buffer->getVertexCount(), indices,
+ mesh_buffer->getIndexCount());
+ return cloned_buffer;
+ }
+ }
+ // This should not happen.
+ sanity_check(false);
+ return NULL;
+}
+
+scene::SMesh* cloneMesh(scene::IMesh *src_mesh)
{
scene::SMesh* dst_mesh = new scene::SMesh();
for (u16 j = 0; j < src_mesh->getMeshBufferCount(); j++) {
- scene::IMeshBuffer *buf = src_mesh->getMeshBuffer(j);
- switch (buf->getVertexType()) {
- case video::EVT_STANDARD: {
- video::S3DVertex *v =
- (video::S3DVertex *) buf->getVertices();
- u16 *indices = (u16*)buf->getIndices();
- scene::SMeshBuffer *temp_buf = new scene::SMeshBuffer();
- temp_buf->append(v, buf->getVertexCount(),
- indices, buf->getIndexCount());
- dst_mesh->addMeshBuffer(temp_buf);
- temp_buf->drop();
- break;
- }
- case video::EVT_2TCOORDS: {
- video::S3DVertex2TCoords *v =
- (video::S3DVertex2TCoords *) buf->getVertices();
- u16 *indices = (u16*)buf->getIndices();
- scene::SMeshBufferTangents *temp_buf =
- new scene::SMeshBufferTangents();
- temp_buf->append(v, buf->getVertexCount(),
- indices, buf->getIndexCount());
- dst_mesh->addMeshBuffer(temp_buf);
- temp_buf->drop();
- break;
- }
- case video::EVT_TANGENTS: {
- video::S3DVertexTangents *v =
- (video::S3DVertexTangents *) buf->getVertices();
- u16 *indices = (u16*)buf->getIndices();
- scene::SMeshBufferTangents *temp_buf =
- new scene::SMeshBufferTangents();
- temp_buf->append(v, buf->getVertexCount(),
- indices, buf->getIndexCount());
- dst_mesh->addMeshBuffer(temp_buf);
- temp_buf->drop();
- break;
- }
- }
+ scene::IMeshBuffer *temp_buf = cloneMeshBuffer(
+ src_mesh->getMeshBuffer(j));
+ dst_mesh->addMeshBuffer(temp_buf);
+ temp_buf->drop();
+
}
return dst_mesh;
}
buf->drop();
}
- video::SColor c(255,255,255,255);
+ video::SColor c(255,255,255,255);
- for (std::vector<aabb3f>::const_iterator
- i = boxes.begin();
- i != boxes.end(); ++i)
- {
- aabb3f box = *i;
+ for (aabb3f box : boxes) {
box.repair();
box.MinEdge.X -= expand;
buf->append(vertices + j, 4, indices, 6);
}
}
- return dst_mesh;
+ return dst_mesh;
}
struct vcache
public:
f_lru(vcache *v, tcache *t): vc(v), tc(t)
{
- for (u16 i = 0; i < cachesize; i++)
- {
- cache[i] = -1;
+ for (int &i : cache) {
+ i = -1;
}
}
}
// Update triangle scores
- for (u16 i = 0; i < cachesize; i++)
- {
- if (cache[i] == -1)
+ for (int i : cache) {
+ if (i == -1)
break;
- const u16 trisize = vc[cache[i]].tris.size();
+ const u16 trisize = vc[i].tris.size();
for (u16 t = 0; t < trisize; t++)
{
- tcache *tri = &tc[vc[cache[i]].tris[t]];
+ tcache *tri = &tc[vc[i].tris[t]];
tri->score =
vc[tri->ind[0]].score +
if (tri->score > hiscore)
{
hiscore = tri->score;
- highest = vc[cache[i]].tris[t];
+ highest = vc[i].tris[t];
}
}
}
tc[highest].drawn = true;
- for (u16 j = 0; j < 3; j++)
- {
- vcache *vert = &vc[tc[highest].ind[j]];
+ for (u16 j : tc[highest].ind) {
+ vcache *vert = &vc[j];
for (u16 t = 0; t < vert->tris.size(); t++)
{
if (highest == vert->tris[t])
tc[highest].drawn = true;
- for (u16 j = 0; j < 3; j++)
- {
- vcache *vert = &vc[tc[highest].ind[j]];
+ for (u16 j : tc[highest].ind) {
+ vcache *vert = &vc[j];
for (u16 t = 0; t < vert->tris.size(); t++)
{
if (highest == vert->tris[t])
tc[highest].drawn = true;
- for (u16 j = 0; j < 3; j++)
- {
- vcache *vert = &vc[tc[highest].ind[j]];
+ for (u16 j : tc[highest].ind) {
+ vcache *vert = &vc[j];
for (u16 t = 0; t < vert->tris.size(); t++)
{
if (highest == vert->tris[t])