Add b3d mesh-writer.
- Interface getMeshType moved from IAnimatedMesh up to IMesh. - Static b3d mesh-writer written by Hendu, support for animated meshes added by JLouisB, testing and bugfixes by CuteAlien. git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@5095 dfc29bdd-3216-0410-991c-e03cc46cb475master
parent
c6eec21cec
commit
e6c197fa87
|
@ -1,6 +1,8 @@
|
|||
--------------------------
|
||||
Changes in 1.9 (not yet released)
|
||||
|
||||
- Interface getMeshType moved from IAnimatedMesh up to IMesh.
|
||||
- Add b3d mesh-writer. Static writer written by Hendu, support for animated meshes added by JLouisB, testing and bugfixes by CuteAlien.
|
||||
- Node-collision functions of SceneCollisionManager like getSceneNodeFromScreenCoordinatesBB will now ignore collisions against empty boundingboxes.
|
||||
- Cameras return again an empty boundingbox (at 0,0,0) instead of returning the frustum boundingbox (was changed in very old Irrlicht version).
|
||||
You can access the frustum boundingbox through the frustum itself.
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<Project filename="01.HelloWorld/HelloWorld.cbp" />
|
||||
<Project filename="02.Quake3Map/Quake3Map.cbp" />
|
||||
<Project filename="03.CustomSceneNode/CustomSceneNode.cbp" />
|
||||
<Project filename="04.Movement/Movement.cbp" />
|
||||
<Project filename="04.Movement/Movement.cbp" active="1" />
|
||||
<Project filename="05.UserInterface/UserInterface.cbp" />
|
||||
<Project filename="06.2DGraphics/2DGraphics.cbp" />
|
||||
<Project filename="07.Collision/Collision.cbp" />
|
||||
|
@ -27,7 +27,7 @@
|
|||
<Project filename="24.CursorControl/CursorControl.cbp" />
|
||||
<Project filename="25.XmlHandling/XmlHandling.cbp" />
|
||||
<Project filename="26.OcclusionQuery/OcclusionQuery.cbp" />
|
||||
<Project filename="30.Profiling/Profiling.cbp" active="1" />
|
||||
<Project filename="30.Profiling/Profiling.cbp" />
|
||||
<Project filename="Demo/demo.cbp" />
|
||||
<Project filename="../tools/GUIEditor/GUIEditor_gcc.cbp" />
|
||||
<Project filename="../tools/MeshConverter/MeshConverter.cbp" />
|
||||
|
|
|
@ -31,7 +31,10 @@ namespace scene
|
|||
EMWT_OBJ = MAKE_IRR_ID('o','b','j',0),
|
||||
|
||||
//! PLY mesh writer for .ply files
|
||||
EMWT_PLY = MAKE_IRR_ID('p','l','y',0)
|
||||
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)
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -12,48 +12,6 @@ namespace irr
|
|||
{
|
||||
namespace scene
|
||||
{
|
||||
//! Possible types of (animated) meshes.
|
||||
enum E_ANIMATED_MESH_TYPE
|
||||
{
|
||||
//! Unknown animated mesh type.
|
||||
EAMT_UNKNOWN = 0,
|
||||
|
||||
//! Quake 2 MD2 model file
|
||||
EAMT_MD2,
|
||||
|
||||
//! Quake 3 MD3 model file
|
||||
EAMT_MD3,
|
||||
|
||||
//! Maya .obj static model
|
||||
EAMT_OBJ,
|
||||
|
||||
//! Quake 3 .bsp static Map
|
||||
EAMT_BSP,
|
||||
|
||||
//! 3D Studio .3ds file
|
||||
EAMT_3DS,
|
||||
|
||||
//! My3D Mesh, the file format by Zhuck Dimitry
|
||||
EAMT_MY3D,
|
||||
|
||||
//! Pulsar LMTools .lmts file. This Irrlicht loader was written by Jonas Petersen
|
||||
EAMT_LMTS,
|
||||
|
||||
//! Cartography Shop .csm file. This loader was created by Saurav Mohapatra.
|
||||
EAMT_CSM,
|
||||
|
||||
//! .oct file for Paul Nette's FSRad or from Murphy McCauley's Blender .oct exporter.
|
||||
/** The oct file format contains 3D geometry and lightmaps and
|
||||
can be loaded directly by Irrlicht */
|
||||
EAMT_OCT,
|
||||
|
||||
//! Halflife MDL model file
|
||||
EAMT_MDL_HALFLIFE,
|
||||
|
||||
//! generic skinned mesh
|
||||
EAMT_SKINNED
|
||||
};
|
||||
|
||||
//! Interface for an animated mesh.
|
||||
/** There are already simple implementations of this interface available so
|
||||
you don't have to implement this interface on your own if you need to:
|
||||
|
|
|
@ -13,6 +13,54 @@ namespace irr
|
|||
{
|
||||
namespace scene
|
||||
{
|
||||
//! Possible types of meshes.
|
||||
// Note: Was previously only used in IAnimatedMesh so it still has the "animated" in the name.
|
||||
// But can now be used for all mesh-types as we need those casts as well.
|
||||
enum E_ANIMATED_MESH_TYPE
|
||||
{
|
||||
//! Unknown animated mesh type.
|
||||
EAMT_UNKNOWN = 0,
|
||||
|
||||
//! Quake 2 MD2 model file
|
||||
EAMT_MD2,
|
||||
|
||||
//! Quake 3 MD3 model file
|
||||
EAMT_MD3,
|
||||
|
||||
//! Maya .obj static model
|
||||
EAMT_OBJ,
|
||||
|
||||
//! Quake 3 .bsp static Map
|
||||
EAMT_BSP,
|
||||
|
||||
//! 3D Studio .3ds file
|
||||
EAMT_3DS,
|
||||
|
||||
//! My3D Mesh, the file format by Zhuck Dimitry
|
||||
EAMT_MY3D,
|
||||
|
||||
//! Pulsar LMTools .lmts file. This Irrlicht loader was written by Jonas Petersen
|
||||
EAMT_LMTS,
|
||||
|
||||
//! Cartography Shop .csm file. This loader was created by Saurav Mohapatra.
|
||||
EAMT_CSM,
|
||||
|
||||
//! .oct file for Paul Nette's FSRad or from Murphy McCauley's Blender .oct exporter.
|
||||
/** The oct file format contains 3D geometry and lightmaps and
|
||||
can be loaded directly by Irrlicht */
|
||||
EAMT_OCT,
|
||||
|
||||
//! Halflife MDL model file
|
||||
EAMT_MDL_HALFLIFE,
|
||||
|
||||
//! generic skinned mesh
|
||||
EAMT_SKINNED,
|
||||
|
||||
//! generig non-animated mesh
|
||||
EAMT_STATIC
|
||||
};
|
||||
|
||||
|
||||
class IMeshBuffer;
|
||||
|
||||
//! Class which holds the geometry of an object.
|
||||
|
@ -66,6 +114,17 @@ namespace scene
|
|||
indices have changed. Otherwise, changes won't be updated
|
||||
on the GPU in the next render cycle. */
|
||||
virtual void setDirty(E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX) = 0;
|
||||
|
||||
//! Returns the type of the meshes.
|
||||
/** This is useful for making a safe downcast. For example,
|
||||
if getMeshType() returns EAMT_MD2 it's safe to cast the
|
||||
IMesh to IAnimatedMeshMD2.
|
||||
Note: It's no longer just about animated meshes, that name has just historical reasons.
|
||||
\returns Type of the mesh */
|
||||
virtual E_ANIMATED_MESH_TYPE getMeshType() const
|
||||
{
|
||||
return EAMT_STATIC;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace scene
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace scene
|
|||
s32 flags=EMWF_NONE) = 0;
|
||||
|
||||
// Writes an animated mesh
|
||||
// for future use, no writer is able to write animated meshes currently
|
||||
// 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 sucessful */
|
||||
//virtual bool writeAnimatedMesh(io::IWriteFile* file,
|
||||
// scene::IAnimatedMesh* mesh,
|
||||
|
|
|
@ -482,6 +482,11 @@ B3D, MS3D or X meshes */
|
|||
#ifdef NO_IRR_COMPILE_WITH_PLY_WRITER_
|
||||
#undef _IRR_COMPILE_WITH_PLY_WRITER_
|
||||
#endif
|
||||
//! Define _IRR_COMPILE_WITH_B3D_WRITER_ if you want to write .b3d files
|
||||
#define _IRR_COMPILE_WITH_B3D_WRITER_
|
||||
#ifdef NO_IRR_COMPILE_WITH_B3D_WRITER_
|
||||
#undef _IRR_COMPILE_WITH_B3D_WRITER_
|
||||
#endif
|
||||
|
||||
//! Define _IRR_COMPILE_WITH_BMP_LOADER_ if you want to load .bmp files
|
||||
//! Disabling this loader will also disable the built-in font
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "IMeshLoader.h"
|
||||
#include "ISceneManager.h"
|
||||
#include "CSkinnedMesh.h"
|
||||
#include "SB3DStructs.h"
|
||||
#include "IReadFile.h"
|
||||
|
||||
namespace irr
|
||||
|
@ -42,56 +43,6 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
struct SB3dChunkHeader
|
||||
{
|
||||
c8 name[4];
|
||||
s32 size;
|
||||
};
|
||||
|
||||
struct SB3dChunk
|
||||
{
|
||||
SB3dChunk(const SB3dChunkHeader& header, long sp)
|
||||
: length(header.size+8), startposition(sp)
|
||||
{
|
||||
name[0]=header.name[0];
|
||||
name[1]=header.name[1];
|
||||
name[2]=header.name[2];
|
||||
name[3]=header.name[3];
|
||||
}
|
||||
|
||||
c8 name[4];
|
||||
s32 length;
|
||||
long startposition;
|
||||
};
|
||||
|
||||
struct SB3dTexture
|
||||
{
|
||||
core::stringc TextureName;
|
||||
s32 Flags;
|
||||
s32 Blend;
|
||||
f32 Xpos;
|
||||
f32 Ypos;
|
||||
f32 Xscale;
|
||||
f32 Yscale;
|
||||
f32 Angle;
|
||||
};
|
||||
|
||||
struct SB3dMaterial
|
||||
{
|
||||
SB3dMaterial() : red(1.0f), green(1.0f),
|
||||
blue(1.0f), alpha(1.0f), shininess(0.0f), blend(1),
|
||||
fx(0)
|
||||
{
|
||||
for (u32 i=0; i<video::MATERIAL_MAX_TEXTURES; ++i)
|
||||
Textures[i]=0;
|
||||
}
|
||||
video::SMaterial Material;
|
||||
f32 red, green, blue, alpha;
|
||||
f32 shininess;
|
||||
s32 blend,fx;
|
||||
SB3dTexture *Textures[video::MATERIAL_MAX_TEXTURES];
|
||||
};
|
||||
|
||||
bool load();
|
||||
bool readChunkNODE(CSkinnedMesh::SJoint* InJoint);
|
||||
bool readChunkMESH(CSkinnedMesh::SJoint* InJoint);
|
||||
|
|
|
@ -0,0 +1,649 @@
|
|||
// 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 "IrrCompileConfig.h"
|
||||
|
||||
#define _IRR_COMPILE_WITH_B3D_WRITER_
|
||||
#ifdef _IRR_COMPILE_WITH_B3D_WRITER_
|
||||
|
||||
#include "CB3DMeshWriter.h"
|
||||
#include "os.h"
|
||||
#include "ISkinnedMesh.h"
|
||||
#include "IMeshBuffer.h"
|
||||
#include "IWriteFile.h"
|
||||
#include "ITexture.h"
|
||||
#include "irrMap.h"
|
||||
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace scene
|
||||
{
|
||||
|
||||
using namespace core;
|
||||
using namespace video;
|
||||
|
||||
CB3DMeshWriter::CB3DMeshWriter(io::IFileSystem *fs): FileSystem(fs)
|
||||
{
|
||||
#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
|
||||
|
||||
Size = 0;
|
||||
file->write("BB3D", 4);
|
||||
file->write(&Size, sizeof(u32)); // Updated later once known.
|
||||
|
||||
int version = 1;
|
||||
write(file, &version, sizeof(int));
|
||||
|
||||
//
|
||||
|
||||
const u32 numBeshBuffers = mesh->getMeshBufferCount();
|
||||
array<SB3dTexture> texs;
|
||||
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 < numBeshBuffers; 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
write(file, "TEXS", 4);
|
||||
write(file, &texsizes, 4);
|
||||
|
||||
u32 numTexture = texs.size();
|
||||
for (u32 i = 0; i < numTexture; i++)
|
||||
{
|
||||
write(file, texs[i].TextureName.c_str(), texs[i].TextureName.size() + 1);
|
||||
write(file, &texs[i].Flags, 7*4);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
const u32 brushsize = (7 * 4 + 1) * numBeshBuffers + numBeshBuffers * 4 * MATERIAL_MAX_TEXTURES + 4;
|
||||
write(file, "BRUS", 4);
|
||||
write(file, &brushsize, 4);
|
||||
u32 brushcheck = Size;
|
||||
const u32 usedtex = MATERIAL_MAX_TEXTURES;
|
||||
write(file, &usedtex, 4);
|
||||
|
||||
for (u32 i = 0; i < numBeshBuffers; i++)
|
||||
{
|
||||
const IMeshBuffer * const mb = mesh->getMeshBuffer(i);
|
||||
const SMaterial &mat = mb->getMaterial();
|
||||
|
||||
write(file, "", 1);
|
||||
|
||||
float f = 1;
|
||||
write(file, &f, 4);
|
||||
write(file, &f, 4);
|
||||
write(file, &f, 4);
|
||||
write(file, &f, 4);
|
||||
|
||||
f = 0;
|
||||
write(file, &f, 4);
|
||||
|
||||
u32 tmp = 1;
|
||||
write(file, &tmp, 4);
|
||||
tmp = 0;
|
||||
write(file, &tmp, 4);
|
||||
|
||||
for (u32 j = 0; j < MATERIAL_MAX_TEXTURES; j++)
|
||||
{
|
||||
if (mat.getTexture(j))
|
||||
{
|
||||
const u32 id = tex2id[mat.getTexture(j)];
|
||||
write(file, &id, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
const int id = -1;
|
||||
write(file, &id, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check brushsize
|
||||
brushcheck = Size - brushcheck;
|
||||
if (brushcheck != brushsize)
|
||||
{
|
||||
printf("Failed in brush size calculation, size %u advanced %u\n",
|
||||
brushsize, brushcheck);
|
||||
}
|
||||
|
||||
write(file, "NODE", 4);
|
||||
|
||||
// Calculate node size
|
||||
u32 nodesize = 41 + 8 + 4 + 8;
|
||||
u32 bonesSize = 0;
|
||||
|
||||
if(ISkinnedMesh *skinnedMesh = getSkinned(mesh))
|
||||
{
|
||||
if (!skinnedMesh->isStatic())
|
||||
{
|
||||
bonesSize += 20;
|
||||
}
|
||||
|
||||
const core::array<ISkinnedMesh::SJoint*> rootJoints = getRootJoints(skinnedMesh);
|
||||
for (u32 i = 0; i < rootJoints.size(); i++)
|
||||
{
|
||||
bonesSize += getJointChunkSize(skinnedMesh, rootJoints[i]);
|
||||
}
|
||||
nodesize += bonesSize;
|
||||
|
||||
// -------------------
|
||||
|
||||
}
|
||||
|
||||
// VERT data
|
||||
nodesize += 12;
|
||||
|
||||
const u32 texcoords = getUVlayerCount(mesh);
|
||||
for (u32 i = 0; i < numBeshBuffers; i++)
|
||||
{
|
||||
nodesize += 8 + 4;
|
||||
const IMeshBuffer * const mb = mesh->getMeshBuffer(i);
|
||||
|
||||
nodesize += mb->getVertexCount() * 10 * 4;
|
||||
|
||||
nodesize += mb->getVertexCount() * texcoords * 2 * 4;
|
||||
nodesize += mb->getIndexCount() * 4;
|
||||
}
|
||||
write(file, &nodesize, 4);
|
||||
u32 nodecheck = Size;
|
||||
|
||||
// Node
|
||||
write(file, "", 1);
|
||||
float f = 0;
|
||||
write(file, &f, 4);
|
||||
write(file, &f, 4);
|
||||
write(file, &f, 4);
|
||||
|
||||
f = 1;
|
||||
write(file, &f, 4);
|
||||
write(file, &f, 4);
|
||||
write(file, &f, 4);
|
||||
|
||||
write(file, &f, 4);
|
||||
f = 0;
|
||||
write(file, &f, 4);
|
||||
write(file, &f, 4);
|
||||
write(file, &f, 4);
|
||||
|
||||
// Mesh
|
||||
write(file, "MESH", 4);
|
||||
const u32 meshsize = nodesize - 41 - 8 - bonesSize;
|
||||
write(file, &meshsize, 4);
|
||||
s32 brushID = -1;
|
||||
write(file, &brushID, 4);
|
||||
|
||||
|
||||
|
||||
// Verts
|
||||
write(file, "VRTS", 4);
|
||||
u32 vertsize = 12;
|
||||
|
||||
for (u32 i = 0; i < numBeshBuffers; i++)
|
||||
{
|
||||
const IMeshBuffer * const mb = mesh->getMeshBuffer(i);
|
||||
|
||||
vertsize += mb->getVertexCount() * 10 * 4 +
|
||||
mb->getVertexCount() * texcoords * 2 * 4;
|
||||
}
|
||||
write(file, &vertsize, 4);
|
||||
u32 vertcheck = Size;
|
||||
|
||||
int flagsB3D = 3;
|
||||
write(file, &flagsB3D, 4);
|
||||
|
||||
write(file, &texcoords, 4);
|
||||
flagsB3D = 2;
|
||||
write(file, &flagsB3D, 4);
|
||||
|
||||
for (u32 i = 0; i < numBeshBuffers; i++)
|
||||
{
|
||||
const IMeshBuffer * const mb = mesh->getMeshBuffer(i);
|
||||
irr::u32 numVertices = mb->getVertexCount();
|
||||
for (u32 j = 0; j < numVertices; j++)
|
||||
{
|
||||
const vector3df &pos = mb->getPosition(j);
|
||||
write(file, &pos.X, 4);
|
||||
write(file, &pos.Y, 4);
|
||||
write(file, &pos.Z, 4);
|
||||
|
||||
const vector3df &n = mb->getNormal(j);
|
||||
write(file, &n.X, 4);
|
||||
write(file, &n.Y, 4);
|
||||
write(file, &n.Z, 4);
|
||||
|
||||
const u32 zero = 0;
|
||||
switch (mb->getVertexType())
|
||||
{
|
||||
case EVT_STANDARD:
|
||||
{
|
||||
S3DVertex *v = (S3DVertex *) mb->getVertices();
|
||||
const SColorf col(v[j].Color);
|
||||
write(file, &col.r, 4);
|
||||
write(file, &col.g, 4);
|
||||
write(file, &col.b, 4);
|
||||
write(file, &col.a, 4);
|
||||
|
||||
write(file, &v[j].TCoords.X, 4);
|
||||
write(file, &v[j].TCoords.Y, 4);
|
||||
if (texcoords == 2)
|
||||
{
|
||||
write(file, &zero, 4);
|
||||
write(file, &zero, 4);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EVT_2TCOORDS:
|
||||
{
|
||||
S3DVertex2TCoords *v = (S3DVertex2TCoords *) mb->getVertices();
|
||||
const SColorf col(v[j].Color);
|
||||
write(file, &col.r, 4);
|
||||
write(file, &col.g, 4);
|
||||
write(file, &col.b, 4);
|
||||
write(file, &col.a, 4);
|
||||
|
||||
write(file, &v[j].TCoords.X, 4);
|
||||
write(file, &v[j].TCoords.Y, 4);
|
||||
write(file, &v[j].TCoords2.X, 4);
|
||||
write(file, &v[j].TCoords2.Y, 4);
|
||||
}
|
||||
break;
|
||||
case EVT_TANGENTS:
|
||||
{
|
||||
S3DVertexTangents *v = (S3DVertexTangents *) mb->getVertices();
|
||||
const SColorf col(v[j].Color);
|
||||
write(file, &col.r, 4);
|
||||
write(file, &col.g, 4);
|
||||
write(file, &col.b, 4);
|
||||
write(file, &col.a, 4);
|
||||
|
||||
write(file, &v[j].TCoords.X, 4);
|
||||
write(file, &v[j].TCoords.Y, 4);
|
||||
if (texcoords == 2)
|
||||
{
|
||||
write(file, &zero, 4);
|
||||
write(file, &zero, 4);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check vertsize
|
||||
vertcheck = Size - vertcheck;
|
||||
if (vertcheck != vertsize)
|
||||
{
|
||||
printf("Failed in vertex size calculation, size %u advanced %u\n",
|
||||
vertsize, vertcheck);
|
||||
}
|
||||
|
||||
u32 currentMeshBufferIndex = 0;
|
||||
// Tris
|
||||
for (u32 i = 0; i < numBeshBuffers; i++)
|
||||
{
|
||||
const IMeshBuffer * const mb = mesh->getMeshBuffer(i);
|
||||
write(file, "TRIS", 4);
|
||||
const u32 trisize = 4 + mb->getIndexCount() * 4;
|
||||
write(file, &trisize, 4);
|
||||
|
||||
u32 tricheck = Size;
|
||||
|
||||
write(file, &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;
|
||||
write(file, &tmp, sizeof(u32));
|
||||
|
||||
tmp = idx[j + 1] + currentMeshBufferIndex;
|
||||
write(file, &tmp, sizeof(u32));
|
||||
|
||||
tmp = idx[j + 2] + currentMeshBufferIndex;
|
||||
write(file, &tmp, sizeof(u32));
|
||||
}
|
||||
|
||||
// Check that tris calculation was ok
|
||||
tricheck = Size - tricheck;
|
||||
if (tricheck != trisize)
|
||||
{
|
||||
printf("Failed in tris size calculation, size %u advanced %u\n",
|
||||
trisize, tricheck);
|
||||
}
|
||||
|
||||
currentMeshBufferIndex += mb->getVertexCount();
|
||||
}
|
||||
|
||||
if(ISkinnedMesh *skinnedMesh = getSkinned(mesh))
|
||||
{
|
||||
// Write animation data
|
||||
if (!skinnedMesh->isStatic())
|
||||
{
|
||||
write(file, "ANIM", 4);
|
||||
|
||||
const u32 animsize = 12;
|
||||
write(file, &animsize, 4);
|
||||
|
||||
const u32 flags = 0;
|
||||
const u32 frames = skinnedMesh->getFrameCount();
|
||||
const f32 fps = skinnedMesh->getAnimationSpeed();
|
||||
|
||||
write(file, &flags, 4);
|
||||
write(file, &frames, 4);
|
||||
write(file, &fps, 4);
|
||||
}
|
||||
|
||||
// Write joints
|
||||
core::array<ISkinnedMesh::SJoint*> rootJoints = getRootJoints(skinnedMesh);
|
||||
|
||||
for (u32 i = 0; i < rootJoints.size(); i++)
|
||||
{
|
||||
writeJointChunk(file, skinnedMesh, rootJoints[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Check that node calculation was ok
|
||||
nodecheck = Size - nodecheck;
|
||||
if (nodecheck != nodesize)
|
||||
{
|
||||
printf("Failed in node size calculation, size %u advanced %u\n",
|
||||
nodesize, nodecheck);
|
||||
}
|
||||
file->seek(4);
|
||||
file->write(&Size, 4);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CB3DMeshWriter::writeJointChunk(io::IWriteFile* file, ISkinnedMesh* mesh , ISkinnedMesh::SJoint* joint)
|
||||
{
|
||||
// Node
|
||||
write(file, "NODE", 4);
|
||||
|
||||
// Calculate node size
|
||||
u32 nodesize = getJointChunkSize(mesh, joint);
|
||||
nodesize -= 8; // The declaration + size of THIS chunk shouldn't be added to the size
|
||||
|
||||
write(file, &nodesize, 4);
|
||||
|
||||
|
||||
core::stringc name = joint->Name;
|
||||
write(file, name.c_str(), name.size());
|
||||
write(file, "", 1);
|
||||
|
||||
core::vector3df pos = joint->Animatedposition;
|
||||
// Position
|
||||
write(file, &pos.X, 4);
|
||||
write(file, &pos.Y, 4);
|
||||
write(file, &pos.Z, 4);
|
||||
|
||||
// Scale
|
||||
core::vector3df scale = joint->Animatedscale;
|
||||
if (scale == core::vector3df(0, 0, 0))
|
||||
scale = core::vector3df(1, 1, 1);
|
||||
|
||||
write(file, &scale.X, 4);
|
||||
write(file, &scale.Y, 4);
|
||||
write(file, &scale.Z, 4);
|
||||
|
||||
// Rotation
|
||||
core::quaternion quat = joint->Animatedrotation;
|
||||
write(file, &quat.W, 4);
|
||||
write(file, &quat.X, 4);
|
||||
write(file, &quat.Y, 4);
|
||||
write(file, &quat.Z, 4);
|
||||
|
||||
// Bone
|
||||
write(file, "BONE", 4);
|
||||
u32 bonesize = 8 * joint->Weights.size();
|
||||
write(file, &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();
|
||||
}
|
||||
|
||||
write(file, &b3dVertexID, 4);
|
||||
write(file, &weight, 4);
|
||||
}
|
||||
// ---------------------------
|
||||
|
||||
// Animation keys
|
||||
if (joint->PositionKeys.size())
|
||||
{
|
||||
write(file, "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
|
||||
write(file, &keysSize, 4);
|
||||
|
||||
u32 flag = 1; // 1 = flag for position keys
|
||||
write(file, &flag, 4);
|
||||
|
||||
for (u32 i = 0; i < joint->PositionKeys.size(); i++)
|
||||
{
|
||||
const s32 frame = static_cast<s32>(joint->PositionKeys[i].frame);
|
||||
const core::vector3df pos = joint->PositionKeys[i].position;
|
||||
|
||||
write (file, &frame, 4);
|
||||
|
||||
write (file, &pos.X, 4);
|
||||
write (file, &pos.Y, 4);
|
||||
write (file, &pos.Z, 4);
|
||||
|
||||
}
|
||||
}
|
||||
if (joint->RotationKeys.size())
|
||||
{
|
||||
write(file, "KEYS", 4);
|
||||
u32 keysSize = 4 * joint->RotationKeys.size() * 5; // W, X, Y and Z rot + frame
|
||||
keysSize += 4; // Flag
|
||||
write(file, &keysSize, 4);
|
||||
|
||||
u32 flag = 4;
|
||||
write(file, &flag, 4);
|
||||
|
||||
for (u32 i = 0; i < joint->RotationKeys.size(); i++)
|
||||
{
|
||||
const s32 frame = static_cast<s32>(joint->RotationKeys[i].frame);
|
||||
const core::quaternion rot = joint->RotationKeys[i].rotation;
|
||||
|
||||
write (file, &frame, 4);
|
||||
|
||||
write (file, &rot.W, 4);
|
||||
write (file, &rot.X, 4);
|
||||
write (file, &rot.Y, 4);
|
||||
write (file, &rot.Z, 4);
|
||||
}
|
||||
}
|
||||
if (joint->ScaleKeys.size())
|
||||
{
|
||||
write(file, "KEYS", 4);
|
||||
u32 keysSize = 4 * joint->ScaleKeys.size() * 4; // X, Y and Z scale + frame
|
||||
keysSize += 4; // Flag
|
||||
write(file, &keysSize, 4);
|
||||
|
||||
u32 flag = 2;
|
||||
write(file, &flag, 4);
|
||||
|
||||
for (u32 i = 0; i < joint->ScaleKeys.size(); i++)
|
||||
{
|
||||
const s32 frame = static_cast<s32>(joint->ScaleKeys[i].frame);
|
||||
const core::vector3df scale = joint->ScaleKeys[i].scale;
|
||||
|
||||
write (file, &frame, 4);
|
||||
|
||||
write (file, &scale.X, 4);
|
||||
write (file, &scale.Y, 4);
|
||||
write (file, &scale.Z, 4);
|
||||
}
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < joint->Children.size(); i++)
|
||||
{
|
||||
writeJointChunk(file, mesh, joint->Children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ISkinnedMesh* CB3DMeshWriter::getSkinned (IMesh *mesh)
|
||||
{
|
||||
if (mesh->getMeshType() == EAMT_SKINNED)
|
||||
{
|
||||
return static_cast<ISkinnedMesh*>(mesh);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 CB3DMeshWriter::getJointChunkSize(const ISkinnedMesh* mesh, ISkinnedMesh::SJoint* joint)
|
||||
{
|
||||
u32 chunkSize = 8 + 40; // Chunk declaration + chunk data
|
||||
chunkSize += joint->Name.size() + 1; // the NULL character at the end of the string
|
||||
|
||||
u32 boneSize = joint->Weights.size() * 8; // vertex_id + weight = 8 bits per weight block
|
||||
boneSize += 8; // declaration + size of he BONE chunk
|
||||
|
||||
u32 keysSize = 0;
|
||||
if (joint->PositionKeys.size() != 0)
|
||||
{
|
||||
keysSize += 8; // KEYS + chunk size
|
||||
keysSize += 4; // flags
|
||||
|
||||
keysSize += (joint->PositionKeys.size() * 16);
|
||||
}
|
||||
if (joint->RotationKeys.size() != 0)
|
||||
{
|
||||
keysSize += 8; // KEYS + chunk size
|
||||
keysSize += 4; // flags
|
||||
|
||||
keysSize += (joint->RotationKeys.size() * 20);
|
||||
}
|
||||
if (joint->ScaleKeys.size() != 0)
|
||||
{
|
||||
keysSize += 8; // KEYS + chunk size
|
||||
keysSize += 4; // flags
|
||||
|
||||
keysSize += (joint->ScaleKeys.size() * 16);
|
||||
}
|
||||
|
||||
chunkSize += boneSize;
|
||||
chunkSize += keysSize;
|
||||
|
||||
for (u32 i = 0; i < joint->Children.size(); ++i)
|
||||
{
|
||||
chunkSize += (getJointChunkSize(mesh, joint->Children[i]));
|
||||
}
|
||||
return chunkSize;
|
||||
}
|
||||
|
||||
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(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::write(io::IWriteFile* file, const void *ptr, const u32 bytes)
|
||||
{
|
||||
file->write(ptr, bytes);
|
||||
Size += bytes;
|
||||
}
|
||||
|
||||
} // end namespace
|
||||
} // end namespace
|
||||
|
||||
#endif // _IRR_COMPILE_WITH_B3D_WRITER_
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
// 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
|
||||
|
||||
#ifndef __IRR_B3D_MESH_WRITER_H_INCLUDED__
|
||||
#define __IRR_B3D_MESH_WRITER_H_INCLUDED__
|
||||
|
||||
#include "IMeshWriter.h"
|
||||
#include "IFileSystem.h"
|
||||
#include "SB3DStructs.h"
|
||||
#include "ISkinnedMesh.h"
|
||||
|
||||
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace scene
|
||||
{
|
||||
|
||||
//! class to write B3D mesh files
|
||||
class CB3DMeshWriter : public IMeshWriter
|
||||
{
|
||||
public:
|
||||
|
||||
CB3DMeshWriter(io::IFileSystem *fs);
|
||||
|
||||
//! Returns the type of the mesh writer
|
||||
virtual EMESH_WRITER_TYPE getType() const;
|
||||
|
||||
//! writes a mesh
|
||||
virtual bool writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags=EMWF_NONE);
|
||||
|
||||
private:
|
||||
io::IFileSystem *FileSystem;
|
||||
u32 Size;
|
||||
|
||||
void writeJointChunk(io::IWriteFile* file, ISkinnedMesh* mesh , ISkinnedMesh::SJoint* joint);
|
||||
u32 getJointChunkSize(const ISkinnedMesh* mesh, ISkinnedMesh::SJoint* joint);
|
||||
core::array<ISkinnedMesh::SJoint*> getRootJoints(const ISkinnedMesh* mesh);
|
||||
|
||||
u32 getUVlayerCount(IMesh *mesh);
|
||||
ISkinnedMesh* getSkinned (IMesh *mesh);
|
||||
|
||||
void write(io::IWriteFile* file, const void *ptr, const u32 bytes);
|
||||
|
||||
};
|
||||
|
||||
} // end namespace
|
||||
} // end namespace
|
||||
|
||||
#endif
|
|
@ -134,6 +134,10 @@
|
|||
#include "CPLYMeshWriter.h"
|
||||
#endif
|
||||
|
||||
#ifdef _IRR_COMPILE_WITH_B3D_WRITER_
|
||||
#include "CB3DMeshWriter.h"
|
||||
#endif
|
||||
|
||||
#include "CCubeSceneNode.h"
|
||||
#include "CSphereSceneNode.h"
|
||||
#include "CAnimatedMeshSceneNode.h"
|
||||
|
@ -2545,6 +2549,13 @@ IMeshWriter* CSceneManager::createMeshWriter(EMESH_WRITER_TYPE type)
|
|||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
case EMWT_B3D:
|
||||
#ifdef _IRR_COMPILE_WITH_B3D_WRITER_
|
||||
return new CB3DMeshWriter(FileSystem);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -614,6 +614,8 @@
|
|||
<Unit filename="CAttributes.h" />
|
||||
<Unit filename="CB3DMeshFileLoader.cpp" />
|
||||
<Unit filename="CB3DMeshFileLoader.h" />
|
||||
<Unit filename="CB3DMeshWriter.cpp" />
|
||||
<Unit filename="CB3DMeshWriter.h" />
|
||||
<Unit filename="CBSPMeshFileLoader.cpp" />
|
||||
<Unit filename="CBSPMeshFileLoader.h" />
|
||||
<Unit filename="CBillboardSceneNode.cpp" />
|
||||
|
@ -1013,6 +1015,7 @@
|
|||
<Unit filename="Octree.h" />
|
||||
<Unit filename="S2DVertex.h" />
|
||||
<Unit filename="S4DVertex.h" />
|
||||
<Unit filename="SB3DStructs.h" />
|
||||
<Unit filename="SoftwareDriver2_compile_config.h" />
|
||||
<Unit filename="SoftwareDriver2_helper.h" />
|
||||
<Unit filename="aesGladman\aes.h" />
|
||||
|
|
|
@ -994,6 +994,7 @@
|
|||
<ClInclude Include="..\..\include\IGUIToolbar.h" />
|
||||
<ClInclude Include="..\..\include\IGUITreeView.h" />
|
||||
<ClInclude Include="..\..\include\IGUIWindow.h" />
|
||||
<ClInclude Include="CB3DMeshWriter.h" />
|
||||
<ClInclude Include="CD3D9RenderTarget.h" />
|
||||
<ClInclude Include="CDefaultSceneNodeAnimatorFactory.h" />
|
||||
<ClInclude Include="CDefaultSceneNodeFactory.h" />
|
||||
|
@ -1103,6 +1104,7 @@
|
|||
<ClInclude Include="COpenGLSLMaterialRenderer.h" />
|
||||
<ClInclude Include="COpenGLTexture.h" />
|
||||
<ClInclude Include="glext.h" />
|
||||
<ClInclude Include="SB3DStructs.h" />
|
||||
<ClInclude Include="wglext.h" />
|
||||
<ClInclude Include="CColorConverter.h" />
|
||||
<ClInclude Include="CFPSCounter.h" />
|
||||
|
@ -1240,6 +1242,7 @@
|
|||
<None Include="..\..\readme.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CB3DMeshWriter.cpp" />
|
||||
<ClCompile Include="CD3D9RenderTarget.cpp" />
|
||||
<ClCompile Include="CDefaultSceneNodeAnimatorFactory.cpp" />
|
||||
<ClCompile Include="CDefaultSceneNodeFactory.cpp" />
|
||||
|
|
|
@ -1309,6 +1309,12 @@
|
|||
<ClInclude Include="COpenGLRenderTarget.h">
|
||||
<Filter>Irrlicht\video\OpenGL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CB3DMeshWriter.h">
|
||||
<Filter>Irrlicht\scene\writers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SB3DStructs.h">
|
||||
<Filter>Irrlicht\scene</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\changes.txt">
|
||||
|
@ -2237,6 +2243,9 @@
|
|||
<ClCompile Include="COpenGLRenderTarget.cpp">
|
||||
<Filter>Irrlicht\video\OpenGL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CB3DMeshWriter.cpp">
|
||||
<Filter>Irrlicht\scene\writers</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="Irrlicht.rc" />
|
||||
|
|
|
@ -1001,6 +1001,7 @@
|
|||
<ClInclude Include="..\..\include\IGUIToolbar.h" />
|
||||
<ClInclude Include="..\..\include\IGUITreeView.h" />
|
||||
<ClInclude Include="..\..\include\IGUIWindow.h" />
|
||||
<ClInclude Include="CB3DMeshWriter.h" />
|
||||
<ClInclude Include="CD3D9RenderTarget.h" />
|
||||
<ClInclude Include="CDefaultSceneNodeAnimatorFactory.h" />
|
||||
<ClInclude Include="CDefaultSceneNodeFactory.h" />
|
||||
|
@ -1109,6 +1110,7 @@
|
|||
<ClInclude Include="COpenGLSLMaterialRenderer.h" />
|
||||
<ClInclude Include="COpenGLTexture.h" />
|
||||
<ClInclude Include="glext.h" />
|
||||
<ClInclude Include="SB3DStructs.h" />
|
||||
<ClInclude Include="wglext.h" />
|
||||
<ClInclude Include="CColorConverter.h" />
|
||||
<ClInclude Include="CFPSCounter.h" />
|
||||
|
@ -1247,6 +1249,7 @@
|
|||
<None Include="..\..\readme.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CB3DMeshWriter.cpp" />
|
||||
<ClCompile Include="CD3D9RenderTarget.cpp" />
|
||||
<ClCompile Include="CDefaultSceneNodeAnimatorFactory.cpp" />
|
||||
<ClCompile Include="CDefaultSceneNodeFactory.cpp" />
|
||||
|
|
|
@ -1308,6 +1308,12 @@
|
|||
</ClInclude>
|
||||
<ClInclude Include="COpenGLRenderTarget.h">
|
||||
<Filter>Irrlicht\video\OpenGL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CB3DMeshWriter.h">
|
||||
<Filter>Irrlicht\scene\writers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SB3DStructs.h">
|
||||
<Filter>Irrlicht\scene</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -2236,6 +2242,9 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="COpenGLRenderTarget.cpp">
|
||||
<Filter>Irrlicht\video\OpenGL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CB3DMeshWriter.cpp">
|
||||
<Filter>Irrlicht\scene\writers</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -1001,6 +1001,7 @@
|
|||
<ClInclude Include="..\..\include\IGUIToolbar.h" />
|
||||
<ClInclude Include="..\..\include\IGUITreeView.h" />
|
||||
<ClInclude Include="..\..\include\IGUIWindow.h" />
|
||||
<ClInclude Include="CB3DMeshWriter.h" />
|
||||
<ClInclude Include="CD3D9RenderTarget.h" />
|
||||
<ClInclude Include="CDefaultSceneNodeAnimatorFactory.h" />
|
||||
<ClInclude Include="CDefaultSceneNodeFactory.h" />
|
||||
|
@ -1109,6 +1110,7 @@
|
|||
<ClInclude Include="COpenGLSLMaterialRenderer.h" />
|
||||
<ClInclude Include="COpenGLTexture.h" />
|
||||
<ClInclude Include="glext.h" />
|
||||
<ClInclude Include="SB3DStructs.h" />
|
||||
<ClInclude Include="wglext.h" />
|
||||
<ClInclude Include="CColorConverter.h" />
|
||||
<ClInclude Include="CFPSCounter.h" />
|
||||
|
@ -1247,6 +1249,7 @@
|
|||
<None Include="..\..\readme.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CB3DMeshWriter.cpp" />
|
||||
<ClCompile Include="CD3D9RenderTarget.cpp" />
|
||||
<ClCompile Include="CDefaultSceneNodeAnimatorFactory.cpp" />
|
||||
<ClCompile Include="CDefaultSceneNodeFactory.cpp" />
|
||||
|
|
|
@ -1308,6 +1308,12 @@
|
|||
</ClInclude>
|
||||
<ClInclude Include="COpenGLRenderTarget.h">
|
||||
<Filter>Irrlicht\video\OpenGL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CB3DMeshWriter.h">
|
||||
<Filter>Irrlicht\scene\writers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SB3DStructs.h">
|
||||
<Filter>Irrlicht\scene</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -2236,6 +2242,9 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="COpenGLRenderTarget.cpp">
|
||||
<Filter>Irrlicht\video\OpenGL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CB3DMeshWriter.cpp">
|
||||
<Filter>Irrlicht\scene\writers</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -2079,6 +2079,14 @@
|
|||
RelativePath="CSTLMeshWriter.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CB3DMeshWriter.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CB3DMeshWriter.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
|
|
|
@ -30,7 +30,7 @@ VERSION_RELEASE = 0
|
|||
|
||||
#List of object files, separated based on engine architecture
|
||||
IRRMESHLOADER = CBSPMeshFileLoader.o CMD2MeshFileLoader.o CMD3MeshFileLoader.o CMS3DMeshFileLoader.o CB3DMeshFileLoader.o C3DSMeshFileLoader.o COgreMeshFileLoader.o COBJMeshFileLoader.o CColladaFileLoader.o CCSMLoader.o CDMFLoader.o CLMTSMeshFileLoader.o CMY3DMeshFileLoader.o COCTLoader.o CXMeshFileLoader.o CIrrMeshFileLoader.o CSTLMeshFileLoader.o CLWOMeshFileLoader.o CPLYMeshFileLoader.o CSMFMeshFileLoader.o CMeshTextureLoader.o
|
||||
IRRMESHWRITER = CColladaMeshWriter.o CIrrMeshWriter.o CSTLMeshWriter.o COBJMeshWriter.o CPLYMeshWriter.o
|
||||
IRRMESHWRITER = CColladaMeshWriter.o CIrrMeshWriter.o CSTLMeshWriter.o COBJMeshWriter.o CPLYMeshWriter.o CB3DMeshWriter.o
|
||||
IRRMESHOBJ = $(IRRMESHLOADER) $(IRRMESHWRITER) \
|
||||
CSkinnedMesh.o CBoneSceneNode.o CMeshSceneNode.o \
|
||||
CAnimatedMeshSceneNode.o CAnimatedMeshMD2.o CAnimatedMeshMD3.o \
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
// Copyright (C) 2006-2012 Luke Hoschke
|
||||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||
|
||||
// B3D Mesh loader
|
||||
// File format designed by Mark Sibly for the Blitz3D engine and has been
|
||||
// declared public domain
|
||||
|
||||
#include "IrrCompileConfig.h"
|
||||
|
||||
#ifndef SB3DSTRUCTS_H
|
||||
#define SB3DSTRUCTS_H
|
||||
|
||||
#include "SMaterial.h"
|
||||
|
||||
namespace irr {
|
||||
namespace scene {
|
||||
|
||||
struct SB3dChunkHeader
|
||||
{
|
||||
c8 name[4];
|
||||
s32 size;
|
||||
};
|
||||
|
||||
struct SB3dChunk
|
||||
{
|
||||
SB3dChunk(const SB3dChunkHeader& header, long sp)
|
||||
: length(header.size+8), startposition(sp)
|
||||
{
|
||||
name[0]=header.name[0];
|
||||
name[1]=header.name[1];
|
||||
name[2]=header.name[2];
|
||||
name[3]=header.name[3];
|
||||
}
|
||||
c8 name[4];
|
||||
s32 length;
|
||||
long startposition;
|
||||
};
|
||||
|
||||
struct SB3dTexture
|
||||
{
|
||||
core::stringc TextureName;
|
||||
s32 Flags;
|
||||
s32 Blend;
|
||||
f32 Xpos;
|
||||
f32 Ypos;
|
||||
f32 Xscale;
|
||||
f32 Yscale;
|
||||
f32 Angle;
|
||||
};
|
||||
|
||||
struct SB3dMaterial
|
||||
{
|
||||
SB3dMaterial() : red(1.0f), green(1.0f),
|
||||
blue(1.0f), alpha(1.0f), shininess(0.0f), blend(1),
|
||||
fx(0)
|
||||
{
|
||||
for (u32 i=0; i<video::MATERIAL_MAX_TEXTURES; ++i)
|
||||
Textures[i]=0;
|
||||
}
|
||||
video::SMaterial Material;
|
||||
f32 red, green, blue, alpha;
|
||||
f32 shininess;
|
||||
s32 blend,fx;
|
||||
SB3dTexture *Textures[video::MATERIAL_MAX_TEXTURES];
|
||||
};
|
||||
|
||||
} // end namespace scene
|
||||
} // end namespace irr
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue