Delete mesh writing support entirely

CB3DMeshWriter.cpp was not even being compiled
This commit is contained in:
sfan5 2024-03-09 22:37:22 +01:00
parent d26c0aeaaf
commit 9d07f906a7
8 changed files with 0 additions and 709 deletions

@ -1,60 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "irrTypes.h"
namespace irr
{
namespace scene
{
//! An enumeration for all supported types of built-in mesh writers
/** A scene mesh writers is represented by a four character code
such as 'irrm' or 'coll' instead of simple numbers, to avoid
name clashes with external mesh writers.*/
enum EMESH_WRITER_TYPE
{
//! Irrlicht native mesh writer, for static .irrmesh files.
EMWT_IRR_MESH = MAKE_IRR_ID('i','r','r','m'),
//! COLLADA mesh writer for .dae and .xml files
EMWT_COLLADA = MAKE_IRR_ID('c','o','l','l'),
//! STL mesh writer for .stl files
EMWT_STL = MAKE_IRR_ID('s','t','l',0),
//! OBJ mesh writer for .obj files
EMWT_OBJ = MAKE_IRR_ID('o','b','j',0),
//! PLY mesh writer for .ply files
EMWT_PLY = MAKE_IRR_ID('p','l','y',0),
//! B3D mesh writer, for static .b3d files
EMWT_B3D = MAKE_IRR_ID('b', '3', 'd', 0)
};
//! flags configuring mesh writing
enum E_MESH_WRITER_FLAGS
{
//! no writer flags
EMWF_NONE = 0,
//! write lightmap textures out if possible
//! Currently not used by any Irrlicht mesh-writer
// (Note: User meshwriters can still use it)
EMWF_WRITE_LIGHTMAPS = 0x1,
//! write in a way that consumes less disk space
// (Note: Mainly there for user meshwriters)
EMWF_WRITE_COMPRESSED = 0x2,
//! write in binary format rather than text
EMWF_WRITE_BINARY = 0x4
};
} // end namespace scene
} // end namespace irr

@ -1,55 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IReferenceCounted.h"
#include "EMeshWriterEnums.h"
namespace irr
{
namespace io
{
class IWriteFile;
} // end namespace io
namespace scene
{
class IMesh;
//! Interface for writing meshes
class IMeshWriter : public virtual IReferenceCounted
{
public:
//! Destructor
virtual ~IMeshWriter() {}
//! Get the type of the mesh writer
/** For own implementations, use MAKE_IRR_ID as shown in the
EMESH_WRITER_TYPE enumeration to return your own unique mesh
type id.
\return Type of the mesh writer. */
virtual EMESH_WRITER_TYPE getType() const = 0;
//! Write a static mesh.
/** \param file File handle to write the mesh to.
\param mesh Pointer to mesh to be written.
\param flags Optional flags to set properties of the writer.
\return True if successful */
virtual bool writeMesh(io::IWriteFile* file, scene::IMesh* mesh,
s32 flags=EMWF_NONE) = 0;
// Writes an animated mesh
// for future use, only b3d writer is able to write animated meshes currently and that was implemented using the writeMesh above.
/* \return Returns true if successful */
//virtual bool writeAnimatedMesh(io::IWriteFile* file,
// scene::IAnimatedMesh* mesh,
// s32 flags=EMWF_NONE) = 0;
};
} // end namespace
} // end namespace

@ -12,7 +12,6 @@
#include "dimension2d.h"
#include "SColor.h"
#include "ESceneNodeTypes.h"
#include "EMeshWriterEnums.h"
#include "SceneParameters.h"
#include "ISkinnedMesh.h"
@ -108,7 +107,6 @@ namespace scene
class IMeshLoader;
class IMeshManipulator;
class IMeshSceneNode;
class IMeshWriter;
class ISceneNode;
class ISceneNodeFactory;

@ -41,7 +41,6 @@
#include "EHardwareBufferFlags.h"
#include "EMaterialProps.h"
#include "EMaterialTypes.h"
#include "EMeshWriterEnums.h"
#include "ESceneNodeTypes.h"
#include "fast_atof.h"
#include "IAnimatedMesh.h"
@ -87,7 +86,6 @@
#include "IMeshLoader.h"
#include "IMeshManipulator.h"
#include "IMeshSceneNode.h"
#include "IMeshWriter.h"
#include "IOSOperator.h"
#include "IReadFile.h"
#include "IReferenceCounted.h"

@ -1,530 +0,0 @@
// Copyright (C) 2014 Lauri Kasanen
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
// TODO: replace printf's by logging messages
#include "CB3DMeshWriter.h"
#include "os.h"
#include "ISkinnedMesh.h"
#include "IMeshBuffer.h"
#include "IWriteFile.h"
#include "ITexture.h"
namespace irr
{
namespace scene
{
using namespace core;
using namespace video;
CB3DMeshWriter::CB3DMeshWriter()
{
#ifdef _DEBUG
setDebugName("CB3DMeshWriter");
#endif
}
//! Returns the type of the mesh writer
EMESH_WRITER_TYPE CB3DMeshWriter::getType() const
{
return EMWT_B3D;
}
//! writes a mesh
bool CB3DMeshWriter::writeMesh(io::IWriteFile* file, IMesh* const mesh, s32 flags)
{
if (!file || !mesh)
return false;
#ifdef __BIG_ENDIAN__
os::Printer::log("B3D export does not support big-endian systems.", ELL_ERROR);
return false;
#endif
file->write("BB3D", 4);
file->write("size", 4); // BB3D chunk size, updated later
const u32 version = 1;
file->write(&version, 4);
//
const u32 numMeshBuffers = mesh->getMeshBufferCount();
array<SB3dTexture> texs;
std::map<ITexture *, u32> tex2id; // TODO: texture pointer as key not sufficient as same texture can have several id's
u32 texsizes = 0;
for (u32 i = 0; i < numMeshBuffers; i++)
{
const IMeshBuffer * const mb = mesh->getMeshBuffer(i);
const SMaterial &mat = mb->getMaterial();
for (u32 j = 0; j < MATERIAL_MAX_TEXTURES; j++)
{
if (mat.getTexture(j))
{
SB3dTexture t;
t.TextureName = core::stringc(mat.getTexture(j)->getName().getPath());
// TODO: need some description of Blitz3D texture-flags to figure this out. But Blend should likely depend on material-type.
t.Flags = j == 2 ? 65536 : 1;
t.Blend = 2;
// TODO: evaluate texture matrix
t.Xpos = 0;
t.Ypos = 0;
t.Xscale = 1;
t.Yscale = 1;
t.Angle = 0;
texs.push_back(t);
texsizes += 7*4 + t.TextureName.size() + 1;
tex2id[mat.getTexture(j)] = texs.size() - 1;
}
}
}
file->write("TEXS", 4);
file->write(&texsizes, 4);
u32 numTexture = texs.size();
for (u32 i = 0; i < numTexture; i++)
{
file->write(texs[i].TextureName.c_str(), (size_t)texs[i].TextureName.size() + 1);
file->write(&texs[i].Flags, 7*4);
}
//
file->write("BRUS", 4);
const u32 brushSizeAdress = file->getPos();
file->write(&brushSizeAdress, 4); // BRUSH chunk size, updated later
const u32 usedtex = MATERIAL_MAX_TEXTURES;
file->write(&usedtex, 4);
for (u32 i = 0; i < numMeshBuffers; i++)
{
const IMeshBuffer * const mb = mesh->getMeshBuffer(i);
const SMaterial &mat = mb->getMaterial();
file->write("", 1);
float f = 1;
file->write(&f, 4);
file->write(&f, 4);
file->write(&f, 4);
file->write(&f, 4);
f = 0;
file->write(&f, 4);
u32 tmp = 1;
file->write(&tmp, 4);
tmp = 0;
file->write(&tmp, 4);
for (u32 j = 0; j < MATERIAL_MAX_TEXTURES; j++)
{
s32 id = -1;
if (mat.getTexture(j))
{
id = tex2id[mat.getTexture(j)];
}
file->write(&id, 4);
}
}
writeSizeFrom(file, brushSizeAdress+4, brushSizeAdress); // BRUSH chunk size
file->write("NODE", 4);
u32 nodeSizeAdress = file->getPos();
file->write(&nodeSizeAdress, 4); // NODE chunk size, updated later
// Node
file->write("", 1);
// position
writeVector3(file, core::vector3df(0.f, 0.f, 0.f));
// scale
writeVector3(file, core::vector3df(1.f, 1.f, 1.f));
// rotation
writeQuaternion(file, core::quaternion(0.f, 0.f, 0.f, 1.f));
// Mesh
file->write("MESH", 4);
const u32 meshSizeAdress = file->getPos();
file->write(&meshSizeAdress, 4); // MESH chunk size, updated later
s32 brushID = -1;
file->write(&brushID, 4);
// Verts
file->write("VRTS", 4);
const u32 verticesSizeAdress = file->getPos();
file->write(&verticesSizeAdress, 4);
u32 flagsB3D = 3; // 1=normal values present, 2=rgba values present
file->write(&flagsB3D, 4);
const u32 texcoordsCount = getUVlayerCount(mesh);
file->write(&texcoordsCount, 4);
flagsB3D = 2;
file->write(&flagsB3D, 4);
for (u32 i = 0; i < numMeshBuffers; i++)
{
const IMeshBuffer * const mb = mesh->getMeshBuffer(i);
const u32 numVertices = mb->getVertexCount();
for (u32 j = 0; j < numVertices; j++)
{
const vector3df &pos = mb->getPosition(j);
writeVector3(file, pos);
const vector3df &n = mb->getNormal(j);
writeVector3(file, n);
switch (mb->getVertexType())
{
case EVT_STANDARD:
{
S3DVertex *v = (S3DVertex *) mb->getVertices();
const SColorf col(v[j].Color);
writeColor(file, col);
const core::vector2df uv1 = v[j].TCoords;
writeVector2(file, uv1);
if (texcoordsCount == 2)
{
writeVector2(file, core::vector2df(0.f, 0.f));
}
}
break;
case EVT_2TCOORDS:
{
S3DVertex2TCoords *v = (S3DVertex2TCoords *) mb->getVertices();
const SColorf col(v[j].Color);
writeColor(file, col);
const core::vector2df uv1 = v[j].TCoords;
writeVector2(file, uv1);
const core::vector2df uv2 = v[j].TCoords;
writeVector2(file, uv2);
}
break;
case EVT_TANGENTS:
{
S3DVertexTangents *v = (S3DVertexTangents *) mb->getVertices();
const SColorf col(v[j].Color);
writeColor(file, col);
const core::vector2df uv1 = v[j].TCoords;
writeVector2(file, uv1);
if (texcoordsCount == 2)
{
writeVector2(file, core::vector2df(0.f, 0.f));
}
}
break;
}
}
}
writeSizeFrom(file, verticesSizeAdress+4, verticesSizeAdress); // VERT chunk size
u32 currentMeshBufferIndex = 0;
// Tris
for (u32 i = 0; i < numMeshBuffers; i++)
{
const IMeshBuffer * const mb = mesh->getMeshBuffer(i);
file->write("TRIS", 4);
const u32 trisSizeAdress = file->getPos();
file->write(&trisSizeAdress, 4); // TRIS chunk size, updated later
file->write(&i, 4);
u32 numIndices = mb->getIndexCount();
const u16 * const idx = (u16 *) mb->getIndices();
for (u32 j = 0; j < numIndices; j += 3)
{
u32 tmp = idx[j] + currentMeshBufferIndex;
file->write(&tmp, sizeof(u32));
tmp = idx[j + 1] + currentMeshBufferIndex;
file->write(&tmp, sizeof(u32));
tmp = idx[j + 2] + currentMeshBufferIndex;
file->write(&tmp, sizeof(u32));
}
writeSizeFrom(file, trisSizeAdress+4, trisSizeAdress); // TRIS chunk size
currentMeshBufferIndex += mb->getVertexCount();
}
writeSizeFrom(file, meshSizeAdress+4, meshSizeAdress); // MESH chunk size
if(ISkinnedMesh *skinnedMesh = getSkinned(mesh))
{
// Write animation data
f32 animationSpeedMultiplier = 1.f;
if (!skinnedMesh->isStatic())
{
file->write("ANIM", 4);
const u32 animsize = 12;
file->write(&animsize, 4);
const u32 flags = 0;
f32 fps = skinnedMesh->getAnimationSpeed();
/* B3D file format use integer as keyframe, so there is some potential issues if the model use float as keyframe (Irrlicht use float) with a low animation FPS value
So we define a minimum animation FPS value to multiply the frame and FPS value if the FPS of the animation is too low to store the keyframe with integers */
const int minimumAnimationFPS = 60;
if (fps < minimumAnimationFPS)
{
animationSpeedMultiplier = minimumAnimationFPS / fps;
fps = minimumAnimationFPS;
}
const u32 frames = static_cast<u32>(skinnedMesh->getFrameCount() * animationSpeedMultiplier);
file->write(&flags, 4);
file->write(&frames, 4);
file->write(&fps, 4);
}
// Write joints
core::array<ISkinnedMesh::SJoint*> rootJoints = getRootJoints(skinnedMesh);
for (u32 i = 0; i < rootJoints.size(); i++)
{
writeJointChunk(file, skinnedMesh, rootJoints[i], animationSpeedMultiplier);
}
}
writeSizeFrom(file, nodeSizeAdress+4, nodeSizeAdress); // Node chunk size
writeSizeFrom(file, 8, 4); // BB3D chunk size
return true;
}
void CB3DMeshWriter::writeJointChunk(io::IWriteFile* file, ISkinnedMesh* mesh, ISkinnedMesh::SJoint* joint, f32 animationSpeedMultiplier)
{
// Node
file->write("NODE", 4);
const u32 nodeSizeAdress = file->getPos();
file->write(&nodeSizeAdress, 4);
core::stringc name = joint->Name;
file->write(name.c_str(), name.size());
file->write("", 1);
// Position
const core::vector3df pos = joint->Animatedposition;
writeVector3(file, pos);
// Scale
core::vector3df scale = joint->Animatedscale;
if (scale == core::vector3df(0, 0, 0))
scale = core::vector3df(1, 1, 1);
writeVector3(file, scale);
// Rotation
const core::quaternion quat = joint->Animatedrotation;
writeQuaternion(file, quat);
// Bone
file->write("BONE", 4);
u32 bonesize = 8 * joint->Weights.size();
file->write(&bonesize, 4);
// Skinning ------------------
for (u32 i = 0; i < joint->Weights.size(); i++)
{
const u32 vertexID = joint->Weights[i].vertex_id;
const u32 bufferID = joint->Weights[i].buffer_id;
const f32 weight = joint->Weights[i].strength;
u32 b3dVertexID = vertexID;
for (u32 j = 0; j < bufferID; j++)
{
b3dVertexID += mesh->getMeshBuffer(j)->getVertexCount();
}
file->write(&b3dVertexID, 4);
file->write(&weight, 4);
}
// ---------------------------
f32 floatBuffer[5];
// Animation keys
if (joint->PositionKeys.size())
{
file->write("KEYS", 4);
u32 keysSize = 4 * joint->PositionKeys.size() * 4; // X, Y and Z pos + frame
keysSize += 4; // Flag to define the type of the key
file->write(&keysSize, 4);
u32 flag = 1; // 1 = flag for position keys
file->write(&flag, 4);
for (u32 i = 0; i < joint->PositionKeys.size(); i++)
{
const s32 frame = static_cast<s32>(joint->PositionKeys[i].frame * animationSpeedMultiplier);
file->write(&frame, 4);
const core::vector3df pos = joint->PositionKeys[i].position;
pos.getAs3Values(floatBuffer);
file->write(floatBuffer, 12);
}
}
if (joint->RotationKeys.size())
{
file->write("KEYS", 4);
u32 keysSize = 4 * joint->RotationKeys.size() * 5; // W, X, Y and Z rot + frame
keysSize += 4; // Flag
file->write(&keysSize, 4);
u32 flag = 4;
file->write(&flag, 4);
for (u32 i = 0; i < joint->RotationKeys.size(); i++)
{
const s32 frame = static_cast<s32>(joint->RotationKeys[i].frame * animationSpeedMultiplier);
const core::quaternion rot = joint->RotationKeys[i].rotation;
memcpy(floatBuffer, &frame, 4);
floatBuffer[1] = rot.W;
floatBuffer[2] = rot.X;
floatBuffer[3] = rot.Y;
floatBuffer[4] = rot.Z;
file->write(floatBuffer, 20);
}
}
if (joint->ScaleKeys.size())
{
file->write("KEYS", 4);
u32 keysSize = 4 * joint->ScaleKeys.size() * 4; // X, Y and Z scale + frame
keysSize += 4; // Flag
file->write(&keysSize, 4);
u32 flag = 2;
file->write(&flag, 4);
for (u32 i = 0; i < joint->ScaleKeys.size(); i++)
{
const s32 frame = static_cast<s32>(joint->ScaleKeys[i].frame * animationSpeedMultiplier);
file->write(&frame, 4);
const core::vector3df scale = joint->ScaleKeys[i].scale;
scale.getAs3Values(floatBuffer);
file->write(floatBuffer, 12);
}
}
for (u32 i = 0; i < joint->Children.size(); i++)
{
writeJointChunk(file, mesh, joint->Children[i], animationSpeedMultiplier);
}
writeSizeFrom(file, nodeSizeAdress+4, nodeSizeAdress); // NODE chunk size
}
ISkinnedMesh* CB3DMeshWriter::getSkinned (IMesh *mesh)
{
if (mesh->getMeshType() == EAMT_SKINNED)
{
return static_cast<ISkinnedMesh*>(mesh);
}
return 0;
}
core::array<ISkinnedMesh::SJoint*> CB3DMeshWriter::getRootJoints(const ISkinnedMesh* mesh)
{
core::array<ISkinnedMesh::SJoint*> roots;
core::array<ISkinnedMesh::SJoint*> allJoints = mesh->getAllJoints();
for (u32 i = 0; i < allJoints.size(); i++)
{
bool isRoot = true;
ISkinnedMesh::SJoint* testedJoint = allJoints[i];
for (u32 j = 0; j < allJoints.size(); j++)
{
ISkinnedMesh::SJoint* testedJoint2 = allJoints[j];
for (u32 k = 0; k < testedJoint2->Children.size(); k++)
{
if (testedJoint == testedJoint2->Children[k])
isRoot = false;
}
}
if (isRoot)
roots.push_back(testedJoint);
}
return roots;
}
u32 CB3DMeshWriter::getUVlayerCount(const IMesh* mesh)
{
const u32 numBeshBuffers = mesh->getMeshBufferCount();
for (u32 i = 0; i < numBeshBuffers; i++)
{
const IMeshBuffer * const mb = mesh->getMeshBuffer(i);
if (mb->getVertexType() == EVT_2TCOORDS)
{
return 2;
}
}
return 1;
}
void CB3DMeshWriter::writeVector2(io::IWriteFile* file, const core::vector2df& vec2)
{
f32 buffer[2] = {vec2.X, vec2.Y};
file->write(buffer, 8);
}
void CB3DMeshWriter::writeVector3(io::IWriteFile* file, const core::vector3df& vec3)
{
f32 buffer[3];
vec3.getAs3Values(buffer);
file->write(buffer, 12);
}
void CB3DMeshWriter::writeQuaternion(io::IWriteFile* file, const core::quaternion& quat)
{
f32 buffer[4] = {quat.W, quat.X, quat.Y, quat.Z};
file->write(buffer, 16);
}
void CB3DMeshWriter::writeColor(io::IWriteFile* file, const video::SColorf& color)
{
f32 buffer[4] = {color.r, color.g, color.b, color.a};
file->write(buffer, 16);
}
// Write the size from a given position to current position at a specific position in the file
void CB3DMeshWriter::writeSizeFrom(io::IWriteFile* file, const u32 from, const u32 adressToWrite)
{
const long back = file->getPos();
file->seek(adressToWrite);
const u32 sizeToWrite = back - from;
file->write(&sizeToWrite, 4);
file->seek(back);
}
} // end namespace
} // end namespace

@ -1,51 +0,0 @@
// Copyright (C) 2014 Lauri Kasanen
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
// Modified version with rigging/skinning support
#pragma once
#include "IMeshWriter.h"
#include "IWriteFile.h"
#include "SB3DStructs.h"
#include "ISkinnedMesh.h"
namespace irr
{
namespace scene
{
//! class to write B3D mesh files
class CB3DMeshWriter : public IMeshWriter
{
public:
CB3DMeshWriter();
//! Returns the type of the mesh writer
EMESH_WRITER_TYPE getType() const override;
//! writes a mesh
bool writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags=EMWF_NONE) override;
private:
void writeJointChunk(io::IWriteFile* file, ISkinnedMesh* mesh , ISkinnedMesh::SJoint* joint, f32 animationSpeedMultiplier);
u32 getJointChunkSize(const ISkinnedMesh* mesh, ISkinnedMesh::SJoint* joint);
core::array<ISkinnedMesh::SJoint*> getRootJoints(const ISkinnedMesh* mesh);
u32 getUVlayerCount(const IMesh *mesh);
ISkinnedMesh* getSkinned (IMesh *mesh);
inline void writeVector2(io::IWriteFile* file, const core::vector2df& vec);
inline void writeVector3(io::IWriteFile* file, const core::vector3df& vec);
inline void writeQuaternion(io::IWriteFile* file, const core::quaternion& quat);
inline void writeColor(io::IWriteFile* file, const video::SColorf& color);
void writeSizeFrom(io::IWriteFile* file, const u32 from, const u32 adressToWrite);
};
} // end namespace
} // end namespace

@ -867,12 +867,6 @@ ISkinnedMesh* CSceneManager::createSkinnedMesh()
return new CSkinnedMesh();
}
//! Returns a mesh writer implementation if available
IMeshWriter* CSceneManager::createMeshWriter(EMESH_WRITER_TYPE type)
{
return 0;
}
// creates a scenemanager
ISceneManager* createSceneManager(video::IVideoDriver* driver, gui::ICursorControl* cursorcontrol)

@ -168,9 +168,6 @@ namespace scene
//! Returns type of the scene node
ESCENE_NODE_TYPE getType() const override { return ESNT_SCENE_MANAGER; }
//! Returns a mesh writer implementation if available
IMeshWriter* createMeshWriter(EMESH_WRITER_TYPE type) override;
//! Get a skinned mesh, which is not available as header-only code
ISkinnedMesh* createSkinnedMesh() override;