diff --git a/include/EMeshWriterEnums.h b/include/EMeshWriterEnums.h deleted file mode 100644 index d06e3416..00000000 --- a/include/EMeshWriterEnums.h +++ /dev/null @@ -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 diff --git a/include/IMeshWriter.h b/include/IMeshWriter.h deleted file mode 100644 index 8e98d965..00000000 --- a/include/IMeshWriter.h +++ /dev/null @@ -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 - - diff --git a/include/ISceneManager.h b/include/ISceneManager.h index 30b0c73e..46102c10 100644 --- a/include/ISceneManager.h +++ b/include/ISceneManager.h @@ -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; diff --git a/include/irrlicht.h b/include/irrlicht.h index 9bff3fb2..e8f091f7 100644 --- a/include/irrlicht.h +++ b/include/irrlicht.h @@ -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" diff --git a/source/Irrlicht/CB3DMeshWriter.cpp b/source/Irrlicht/CB3DMeshWriter.cpp deleted file mode 100644 index ea0399d9..00000000 --- a/source/Irrlicht/CB3DMeshWriter.cpp +++ /dev/null @@ -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 texs; - std::map 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(skinnedMesh->getFrameCount() * animationSpeedMultiplier); - - file->write(&flags, 4); - file->write(&frames, 4); - file->write(&fps, 4); - } - - // Write joints - core::array 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(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(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(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(mesh); - } - return 0; -} - -core::array CB3DMeshWriter::getRootJoints(const ISkinnedMesh* mesh) -{ - core::array roots; - - core::array 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 diff --git a/source/Irrlicht/CB3DMeshWriter.h b/source/Irrlicht/CB3DMeshWriter.h deleted file mode 100644 index 47065d78..00000000 --- a/source/Irrlicht/CB3DMeshWriter.h +++ /dev/null @@ -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 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 - diff --git a/source/Irrlicht/CSceneManager.cpp b/source/Irrlicht/CSceneManager.cpp index 71c8b866..2dbd3fe4 100644 --- a/source/Irrlicht/CSceneManager.cpp +++ b/source/Irrlicht/CSceneManager.cpp @@ -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) diff --git a/source/Irrlicht/CSceneManager.h b/source/Irrlicht/CSceneManager.h index 51cc6f90..db13bed9 100644 --- a/source/Irrlicht/CSceneManager.h +++ b/source/Irrlicht/CSceneManager.h @@ -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;