diff options
Diffstat (limited to 'source/Irrlicht/COgreMeshFileLoader.cpp')
-rw-r--r-- | source/Irrlicht/COgreMeshFileLoader.cpp | 1607 |
1 files changed, 0 insertions, 1607 deletions
diff --git a/source/Irrlicht/COgreMeshFileLoader.cpp b/source/Irrlicht/COgreMeshFileLoader.cpp deleted file mode 100644 index 9df2087..0000000 --- a/source/Irrlicht/COgreMeshFileLoader.cpp +++ /dev/null @@ -1,1607 +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
-// Originally written by Christian Stehno, modified by Nikolaus Gebhardt
-
-#include "IrrCompileConfig.h"
-#ifdef _IRR_COMPILE_WITH_OGRE_LOADER_
-
-#include "COgreMeshFileLoader.h"
-#include "CMeshTextureLoader.h"
-#include "os.h"
-#include "SMeshBuffer.h"
-#include "SAnimatedMesh.h"
-#include "IReadFile.h"
-#include "fast_atof.h"
-#include "coreutil.h"
-
-#ifdef _DEBUG
-#define IRR_OGRE_LOADER_DEBUG
-#endif
-
-namespace irr
-{
-namespace scene
-{
-
-namespace
-{
- enum OGRE_CHUNKS
- {
- // Main Chunks
- COGRE_HEADER= 0x1000,
- COGRE_SKELETON= 0x2000,
- COGRE_MESH= 0x3000,
-
- // sub chunks of COGRE_MESH
- COGRE_SUBMESH= 0x4000,
- COGRE_GEOMETRY= 0x5000,
- COGRE_SKELETON_LINK= 0x6000,
- COGRE_BONE_ASSIGNMENT= 0x7000,
- COGRE_MESH_LOD= 0x8000,
- COGRE_MESH_BOUNDS= 0x9000,
- COGRE_MESH_SUBMESH_NAME_TABLE= 0xA000,
- COGRE_MESH_EDGE_LISTS= 0xB000,
-
- // sub chunks of COGRE_SKELETON
- COGRE_BONE_PARENT= 0x3000,
- COGRE_ANIMATION= 0x4000,
- COGRE_ANIMATION_TRACK= 0x4100,
- COGRE_ANIMATION_KEYFRAME= 0x4110,
- COGRE_ANIMATION_LINK= 0x5000,
-
- // sub chunks of COGRE_SUBMESH
- COGRE_SUBMESH_OPERATION= 0x4010,
- COGRE_SUBMESH_BONE_ASSIGNMENT= 0x4100,
- COGRE_SUBMESH_TEXTURE_ALIAS= 0x4200,
-
- // sub chunks of COGRE_GEOMETRY
- COGRE_GEOMETRY_VERTEX_DECLARATION= 0x5100,
- COGRE_GEOMETRY_VERTEX_ELEMENT= 0x5110,
- COGRE_GEOMETRY_VERTEX_BUFFER= 0x5200,
- COGRE_GEOMETRY_VERTEX_BUFFER_DATA= 0x5210
- };
-}
-
-//! Constructor
-COgreMeshFileLoader::COgreMeshFileLoader(io::IFileSystem* fs, video::IVideoDriver* driver)
-: FileSystem(fs), Driver(driver), SwapEndian(false), Mesh(0), NumUV(0)
-{
-
- #ifdef _DEBUG
- setDebugName("COgreMeshFileLoader");
- #endif
-
- if (FileSystem)
- FileSystem->grab();
-
- if (Driver)
- Driver->grab();
-
- TextureLoader = new CMeshTextureLoader( FileSystem, Driver );
-}
-
-
-//! destructor
-COgreMeshFileLoader::~COgreMeshFileLoader()
-{
- clearMeshes();
-
- if (FileSystem)
- FileSystem->drop();
-
- if (Driver)
- Driver->drop();
-
- if (Mesh)
- Mesh->drop();
-}
-
-
-//! returns true if the file maybe is able to be loaded by this class
-//! based on the file extension (e.g. ".bsp")
-bool COgreMeshFileLoader::isALoadableFileExtension(const io::path& filename) const
-{
- return core::hasFileExtension ( filename, "mesh" );
-}
-
-
-//! creates/loads an animated mesh from the file.
-//! \return Pointer to the created mesh. Returns 0 if loading failed.
-//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
-//! See IReferenceCounted::drop() for more information.
-IAnimatedMesh* COgreMeshFileLoader::createMesh(io::IReadFile* file)
-{
- if ( !file )
- return 0;
-
- if ( getMeshTextureLoader() )
- getMeshTextureLoader()->setMeshFile(file);
-
- s16 id;
-
- file->read(&id, 2);
-
- if (id == COGRE_HEADER)
- SwapEndian=false;
- else if (id == 0x0010)
- SwapEndian=true;
- else
- return 0;
- ChunkData data;
- readString(file, data, Version);
- if ((Version != "[MeshSerializer_v1.30]") && (Version != "[MeshSerializer_v1.40]") && (Version != "[MeshSerializer_v1.41]"))
- {
- os::Printer::log("Unsupported ogre mesh version", Version.c_str(), ELL_INFORMATION);
- return 0;
- }
-
- clearMeshes();
- if (Mesh)
- Mesh->drop();
-
- CurrentlyLoadingFromPath = FileSystem->getFileDir(file->getFileName());
- loadMaterials(file);
-
- if (readChunk(file))
- {
- // delete data loaded from file
- clearMeshes();
-
- if (Skeleton.Bones.size())
- {
- ISkinnedMesh* tmp = static_cast<CSkinnedMesh*>(Mesh);
- static_cast<CSkinnedMesh*>(Mesh)->updateBoundingBox();
- Skeleton.Animations.clear();
- Skeleton.Bones.clear();
- Mesh=0;
- return tmp;
- }
- else
- {
- for (u32 i=0; i<Mesh->getMeshBufferCount(); ++i)
- ((SMeshBuffer*)Mesh->getMeshBuffer(i))->recalculateBoundingBox();
-
- ((SMesh*)Mesh)->recalculateBoundingBox();
- SAnimatedMesh* am = new SAnimatedMesh();
- am->Type = EAMT_3DS;
- am->addMesh(Mesh);
- am->recalculateBoundingBox();
- Mesh->drop();
- Mesh = 0;
- return am;
- }
- }
-
- Mesh->drop();
- Mesh = 0;
-
- return 0;
-}
-
-
-bool COgreMeshFileLoader::readChunk(io::IReadFile* file)
-{
- while(file->getPos() < file->getSize())
- {
- ChunkData data;
- readChunkData(file, data);
-
- switch(data.header.id)
- {
- case COGRE_MESH:
- {
- Meshes.push_back(OgreMesh());
- readObjectChunk(file, data, Meshes.getLast());
- if (Skeleton.Bones.size())
- Mesh = new CSkinnedMesh();
- else
- Mesh = new SMesh();
- composeObject();
- }
- break;
- default:
- return true;
- }
- }
-
- return true;
-}
-
-
-bool COgreMeshFileLoader::readObjectChunk(io::IReadFile* file, ChunkData& parent, OgreMesh& mesh)
-{
-#ifdef IRR_OGRE_LOADER_DEBUG
- os::Printer::log("Read Object Chunk", ELL_DEBUG);
-#endif
- readBool(file, parent, mesh.SkeletalAnimation);
- bool skeleton_loaded=false;
- while ((parent.read < parent.header.length)&&(file->getPos() < file->getSize()))
- {
- ChunkData data;
- readChunkData(file, data);
-
- switch(data.header.id)
- {
- case COGRE_GEOMETRY:
- readGeometry(file, data, mesh.Geometry);
- break;
- case COGRE_SUBMESH:
- mesh.SubMeshes.push_back(OgreSubMesh());
- readSubMesh(file, data, mesh.SubMeshes.getLast());
- break;
- case COGRE_MESH_BOUNDS:
- {
-#ifdef IRR_OGRE_LOADER_DEBUG
- os::Printer::log("Read Mesh Bounds", ELL_DEBUG);
-#endif
- readVector(file, data, mesh.BBoxMinEdge);
- readVector(file, data, mesh.BBoxMaxEdge);
- readFloat(file, data, &mesh.BBoxRadius);
- }
- break;
- case COGRE_SKELETON_LINK:
- {
-#ifdef IRR_OGRE_LOADER_DEBUG
- os::Printer::log("Read Skeleton link", ELL_DEBUG);
-#endif
- core::stringc name;
- readString(file, data, name);
- loadSkeleton(file, name);
- skeleton_loaded=true;
- }
- break;
- case COGRE_BONE_ASSIGNMENT:
- {
- mesh.BoneAssignments.push_back(OgreBoneAssignment());
- readInt(file, data, &mesh.BoneAssignments.getLast().VertexID);
- readShort(file, data, &mesh.BoneAssignments.getLast().BoneID);
- readFloat(file, data, &mesh.BoneAssignments.getLast().Weight);
- }
- break;
- case COGRE_MESH_LOD:
- case COGRE_MESH_SUBMESH_NAME_TABLE:
- case COGRE_MESH_EDGE_LISTS:
- // ignore chunk
- file->seek(data.header.length-data.read, true);
- data.read += data.header.length-data.read;
- break;
- default:
-#ifdef IRR_OGRE_LOADER_DEBUG
- os::Printer::log("Skipping", core::stringc(data.header.id), ELL_DEBUG);
-#endif
- // ignore chunk
- file->seek(data.header.length-data.read, true);
- data.read += data.header.length-data.read;
- break;
- }
- parent.read += data.read;
- }
- if (!skeleton_loaded)
- loadSkeleton(file, FileSystem->getFileBasename(file->getFileName(), false));
- return true;
-}
-
-
-bool COgreMeshFileLoader::readGeometry(io::IReadFile* file, ChunkData& parent, OgreGeometry& geometry)
-{
-#ifdef IRR_OGRE_LOADER_DEBUG
- os::Printer::log("Read Geometry", ELL_DEBUG);
-#endif
- readInt(file, parent, &geometry.NumVertex);
- while(parent.read < parent.header.length)
- {
- ChunkData data;
- readChunkData(file, data);
-
- switch(data.header.id)
- {
- case COGRE_GEOMETRY_VERTEX_DECLARATION:
- readVertexDeclaration(file, data, geometry);
- break;
- case COGRE_GEOMETRY_VERTEX_BUFFER:
- readVertexBuffer(file, data, geometry);
- break;
- default:
- // ignore chunk
-#ifdef IRR_OGRE_LOADER_DEBUG
- os::Printer::log("Skipping", core::stringc(data.header.id), ELL_DEBUG);
-#endif
- file->seek(data.header.length-data.read, true);
- data.read += data.header.length-data.read;
- }
- parent.read += data.read;
- }
- if (parent.read != parent.header.length)
- os::Printer::log("Incorrect geometry length. File might be corrupted.");
- return true;
-}
-
-
-bool COgreMeshFileLoader::readVertexDeclaration(io::IReadFile* file, ChunkData& parent, OgreGeometry& geometry)
-{
-#ifdef IRR_OGRE_LOADER_DEBUG
- os::Printer::log("Read Vertex Declaration", ELL_DEBUG);
-#endif
- NumUV = 0;
- while(parent.read < parent.header.length)
- {
- ChunkData data;
- readChunkData(file, data);
-
- switch(data.header.id)
- {
- case COGRE_GEOMETRY_VERTEX_ELEMENT:
- {
- geometry.Elements.push_back(OgreVertexElement());
- OgreVertexElement& elem = geometry.Elements.getLast();
- readShort(file, data, &elem.Source);
- readShort(file, data, &elem.Type);
- readShort(file, data, &elem.Semantic);
- if (elem.Semantic == 7) //Tex coords
- {
- ++NumUV;
- }
- readShort(file, data, &elem.Offset);
- elem.Offset /= sizeof(f32);
- readShort(file, data, &elem.Index);
- }
- break;
- default:
- // ignore chunk
- file->seek(data.header.length-data.read, true);
- data.read += data.header.length-data.read;
- }
- parent.read += data.read;
- }
- if (parent.read != parent.header.length)
- os::Printer::log("Incorrect vertex declaration length. File might be corrupted.");
- return true;
-}
-
-
-bool COgreMeshFileLoader::readVertexBuffer(io::IReadFile* file, ChunkData& parent, OgreGeometry& geometry)
-{
-#ifdef IRR_OGRE_LOADER_DEBUG
- os::Printer::log("Read Vertex Buffer", ELL_DEBUG);
-#endif
- OgreVertexBuffer buf;
- readShort(file, parent, &buf.BindIndex);
- readShort(file, parent, &buf.VertexSize);
- buf.VertexSize /= sizeof(f32);
- ChunkData data;
- readChunkData(file, data);
-
- if (data.header.id == COGRE_GEOMETRY_VERTEX_BUFFER_DATA)
- {
- buf.Data.set_used(geometry.NumVertex*buf.VertexSize);
- readFloat(file, data, buf.Data.pointer(), geometry.NumVertex*buf.VertexSize);
- }
-
- geometry.Buffers.push_back(buf);
- parent.read += data.read;
- if (parent.read != parent.header.length)
- os::Printer::log("Incorrect vertex buffer length. File might be corrupted.");
- return true;
-}
-
-
-bool COgreMeshFileLoader::readSubMesh(io::IReadFile* file, ChunkData& parent, OgreSubMesh& subMesh)
-{
-#ifdef IRR_OGRE_LOADER_DEBUG
- os::Printer::log("Read Submesh", ELL_DEBUG);
-#endif
- readString(file, parent, subMesh.Material);
-#ifdef IRR_OGRE_LOADER_DEBUG
- os::Printer::log("using material", subMesh.Material, ELL_DEBUG);
-#endif
- readBool(file, parent, subMesh.SharedVertices);
-
- s32 numIndices;
- readInt(file, parent, &numIndices);
- subMesh.Indices.set_used(numIndices);
-
- readBool(file, parent, subMesh.Indices32Bit);
-
- if (subMesh.Indices32Bit)
- readInt(file, parent, subMesh.Indices.pointer(), numIndices);
- else
- {
- for (s32 i=0; i<numIndices; ++i)
- {
- u16 num;
- readShort(file, parent, &num);
- subMesh.Indices[i]=num;
- }
- }
-
- while(parent.read < parent.header.length)
- {
- ChunkData data;
- readChunkData(file, data);
-
- switch(data.header.id)
- {
- case COGRE_GEOMETRY:
- readGeometry(file, data, subMesh.Geometry);
- break;
- case COGRE_SUBMESH_OPERATION:
- readShort(file, data, &subMesh.Operation);
-#ifdef IRR_OGRE_LOADER_DEBUG
- os::Printer::log("Read Submesh Operation",core::stringc(subMesh.Operation), ELL_DEBUG);
-#endif
- if (subMesh.Operation != 4)
- os::Printer::log("Primitive type != trilist not yet implemented", ELL_WARNING);
- break;
- case COGRE_SUBMESH_TEXTURE_ALIAS:
- {
-#ifdef IRR_OGRE_LOADER_DEBUG
- os::Printer::log("Read Submesh Texture Alias", ELL_DEBUG);
-#endif
- core::stringc texture, alias;
- readString(file, data, texture);
- readString(file, data, alias);
- subMesh.TextureAliases.push_back(OgreTextureAlias(texture,alias));
- }
- break;
- case COGRE_SUBMESH_BONE_ASSIGNMENT:
- {
- subMesh.BoneAssignments.push_back(OgreBoneAssignment());
- readInt(file, data, &subMesh.BoneAssignments.getLast().VertexID);
- readShort(file, data, &subMesh.BoneAssignments.getLast().BoneID);
- readFloat(file, data, &subMesh.BoneAssignments.getLast().Weight);
- }
- break;
- default:
-#ifdef IRR_OGRE_LOADER_DEBUG
- os::Printer::log("Skipping", core::stringc(data.header.id), ELL_DEBUG);
-#endif
- parent.read=parent.header.length;
- file->seek(-(long)sizeof(ChunkHeader), true);
- return true;
- }
- parent.read += data.read;
- }
- if (parent.read != parent.header.length)
- os::Printer::log("Incorrect submesh length. File might be corrupted.");
-#ifdef IRR_OGRE_LOADER_DEBUG
- os::Printer::log("Done with submesh", ELL_DEBUG);
-#endif
- return true;
-}
-
-
-void COgreMeshFileLoader::composeMeshBufferMaterial(scene::IMeshBuffer* mb, const core::stringc& materialName)
-{
- video::SMaterial& material=mb->getMaterial();
- for (u32 k=0; k<Materials.size(); ++k)
- {
- if ((materialName==Materials[k].Name)&&(Materials[k].Techniques.size())&&(Materials[k].Techniques[0].Passes.size()))
- {
- material=Materials[k].Techniques[0].Passes[0].Material;
- for (u32 i=0; i<Materials[k].Techniques[0].Passes[0].Texture.Filename.size(); ++i)
- {
- video::ITexture * texture = NULL;
- if ( getMeshTextureLoader() )
- {
- texture = getMeshTextureLoader()->getTexture(Materials[k].Techniques[0].Passes[0].Texture.Filename[i]);
- if ( texture )
- material.setTexture(i, texture);
- }
- }
- break;
- }
- }
-}
-
-
-scene::SMeshBuffer* COgreMeshFileLoader::composeMeshBuffer(const core::array<s32>& indices, const OgreGeometry& geom)
-{
- scene::SMeshBuffer *mb=new scene::SMeshBuffer();
-
- u32 i;
- mb->Indices.set_used(indices.size());
- for (i=0; i<indices.size(); ++i)
- mb->Indices[i]=indices[i];
-
- mb->Vertices.set_used(geom.NumVertex);
- for (i=0; i<geom.Elements.size(); ++i)
- {
- if (geom.Elements[i].Semantic==1) //Pos
- {
- for (u32 j=0; j<geom.Buffers.size(); ++j)
- {
- if (geom.Elements[i].Source==geom.Buffers[j].BindIndex)
- {
- u32 eSize=geom.Buffers[j].VertexSize;
- u32 ePos=geom.Elements[i].Offset;
- for (s32 k=0; k<geom.NumVertex; ++k)
- {
- mb->Vertices[k].Color=mb->Material.DiffuseColor;
- mb->Vertices[k].Pos.set(geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]);
- ePos += eSize;
- }
- }
- }
- }
-
- if (geom.Elements[i].Semantic==4) //Normal
- {
- for (u32 j=0; j<geom.Buffers.size(); ++j)
- {
- if (geom.Elements[i].Source==geom.Buffers[j].BindIndex)
- {
- u32 eSize=geom.Buffers[j].VertexSize;
- u32 ePos=geom.Elements[i].Offset;
- for (s32 k=0; k<geom.NumVertex; ++k)
- {
- mb->Vertices[k].Normal.set(geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]);
- ePos += eSize;
- }
- }
- }
- }
-
- if (geom.Elements[i].Semantic==7) //TexCoord
- {
- for (u32 j=0; j<geom.Buffers.size(); ++j)
- {
- if (geom.Elements[i].Source==geom.Buffers[j].BindIndex)
- {
- u32 eSize=geom.Buffers[j].VertexSize;
- u32 ePos=geom.Elements[i].Offset;
- for (s32 k=0; k<geom.NumVertex; ++k)
- {
- mb->Vertices[k].TCoords.set(geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1]);
- ePos += eSize;
- }
- }
- }
- }
- }
- return mb;
-}
-
-
-scene::SMeshBufferLightMap* COgreMeshFileLoader::composeMeshBufferLightMap(const core::array<s32>& indices, const OgreGeometry& geom)
-{
- scene::SMeshBufferLightMap *mb=new scene::SMeshBufferLightMap();
-
- u32 i;
- mb->Indices.set_used(indices.size());
- for (i=0; i<indices.size(); ++i)
- mb->Indices[i]=indices[i];
-
- mb->Vertices.set_used(geom.NumVertex);
-
- for (i=0; i<geom.Elements.size(); ++i)
- {
- if (geom.Elements[i].Semantic==1) //Pos
- {
- for (u32 j=0; j<geom.Buffers.size(); ++j)
- {
- if (geom.Elements[i].Source==geom.Buffers[j].BindIndex)
- {
- u32 eSize=geom.Buffers[j].VertexSize;
- u32 ePos=geom.Elements[i].Offset;
- for (s32 k=0; k<geom.NumVertex; ++k)
- {
- mb->Vertices[k].Color=mb->Material.DiffuseColor;
- mb->Vertices[k].Pos.set(geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]);
- ePos += eSize;
- }
- }
- }
- }
-
- if (geom.Elements[i].Semantic==4) //Normal
- {
- for (u32 j=0; j<geom.Buffers.size(); ++j)
- {
- if (geom.Elements[i].Source==geom.Buffers[j].BindIndex)
- {
- u32 eSize=geom.Buffers[j].VertexSize;
- u32 ePos=geom.Elements[i].Offset;
- for (s32 k=0; k<geom.NumVertex; ++k)
- {
- mb->Vertices[k].Normal.set(geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]);
- ePos += eSize;
- }
- }
- }
- }
-
- if (geom.Elements[i].Semantic==7) //TexCoord
- {
- for (u32 j=0; j<geom.Buffers.size(); ++j)
- {
- if (geom.Elements[i].Source==geom.Buffers[j].BindIndex)
- {
- u32 eSize=geom.Buffers[j].VertexSize;
- u32 ePos=geom.Elements[i].Offset;
- // make sure we have data for a second texture coord
- const bool secondCoord = (eSize>ePos+3);
- for (s32 k=0; k<geom.NumVertex; ++k)
- {
- mb->Vertices[k].TCoords.set(geom.Buffers[j].Data[ePos], geom.Buffers[j].Data[ePos+1]);
- if (secondCoord)
- mb->Vertices[k].TCoords2.set(geom.Buffers[j].Data[ePos+2], geom.Buffers[j].Data[ePos+3]);
- else
- mb->Vertices[k].TCoords2.set(geom.Buffers[j].Data[ePos], geom.Buffers[j].Data[ePos+1]);
- ePos += eSize;
- }
- }
- }
- }
- }
-
- return mb;
-}
-
-
-scene::IMeshBuffer* COgreMeshFileLoader::composeMeshBufferSkinned(scene::CSkinnedMesh& mesh, const core::array<s32>& indices, const OgreGeometry& geom)
-{
- scene::SSkinMeshBuffer *mb=mesh.addMeshBuffer();
- if (NumUV>1)
- {
- mb->convertTo2TCoords();
- mb->Vertices_2TCoords.set_used(geom.NumVertex);
- }
- else
- mb->Vertices_Standard.set_used(geom.NumVertex);
-
- u32 i;
- mb->Indices.set_used(indices.size());
- for (i=0; i<indices.size(); i+=3)
- {
- mb->Indices[i+0]=indices[i+2];
- mb->Indices[i+1]=indices[i+1];
- mb->Indices[i+2]=indices[i+0];
- }
-
- for (i=0; i<geom.Elements.size(); ++i)
- {
- if (geom.Elements[i].Semantic==1) //Pos
- {
- for (u32 j=0; j<geom.Buffers.size(); ++j)
- {
- if (geom.Elements[i].Source==geom.Buffers[j].BindIndex)
- {
- u32 eSize=geom.Buffers[j].VertexSize;
- u32 ePos=geom.Elements[i].Offset;
- for (s32 k=0; k<geom.NumVertex; ++k)
- {
- if (NumUV>1)
- mb->Vertices_2TCoords[k].Color=mb->Material.DiffuseColor;
- else
- mb->Vertices_Standard[k].Color=mb->Material.DiffuseColor;
- mb->getPosition(k).set(-geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]);
- ePos += eSize;
- }
- }
- }
- }
-
- if (geom.Elements[i].Semantic==4) //Normal
- {
- for (u32 j=0; j<geom.Buffers.size(); ++j)
- {
- if (geom.Elements[i].Source==geom.Buffers[j].BindIndex)
- {
- u32 eSize=geom.Buffers[j].VertexSize;
- u32 ePos=geom.Elements[i].Offset;
- for (s32 k=0; k<geom.NumVertex; ++k)
- {
- mb->getNormal(k).set(-geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]);
- ePos += eSize;
- }
- }
- }
- }
-
- if (geom.Elements[i].Semantic==7) //TexCoord
- {
- for (u32 j=0; j<geom.Buffers.size(); ++j)
- {
- if (geom.Elements[i].Source==geom.Buffers[j].BindIndex)
- {
- u32 eSize=geom.Buffers[j].VertexSize;
- u32 ePos=geom.Elements[i].Offset;
- // make sure we have data for a second texture coord
- const bool secondCoord = (eSize>ePos+3);
- for (s32 k=0; k<geom.NumVertex; ++k)
- {
- mb->getTCoords(k).set(geom.Buffers[j].Data[ePos], geom.Buffers[j].Data[ePos+1]);
- if (NumUV>1)
- {
- if (secondCoord)
- mb->Vertices_2TCoords[k].TCoords2.set(geom.Buffers[j].Data[ePos+2], geom.Buffers[j].Data[ePos+3]);
- else
- mb->Vertices_2TCoords[k].TCoords2.set(geom.Buffers[j].Data[ePos], geom.Buffers[j].Data[ePos+1]);
- }
- ePos += eSize;
- }
- }
- }
- }
- }
-
- return mb;
-}
-
-
-void COgreMeshFileLoader::composeObject(void)
-{
- for (u32 i=0; i<Meshes.size(); ++i)
- {
- for (u32 j=0; j<Meshes[i].SubMeshes.size(); ++j)
- {
- IMeshBuffer* mb;
- if (Meshes[i].SubMeshes[j].SharedVertices)
- {
- if (Skeleton.Bones.size())
- {
- mb = composeMeshBufferSkinned(*(CSkinnedMesh*)Mesh, Meshes[i].SubMeshes[j].Indices, Meshes[i].Geometry);
- }
- else if (NumUV < 2)
- {
- mb = composeMeshBuffer(Meshes[i].SubMeshes[j].Indices, Meshes[i].Geometry);
- }
- else
- {
- mb = composeMeshBufferLightMap(Meshes[i].SubMeshes[j].Indices, Meshes[i].Geometry);
- }
- }
- else
- {
- if (Skeleton.Bones.size())
- {
- mb = composeMeshBufferSkinned(*(CSkinnedMesh*)Mesh, Meshes[i].SubMeshes[j].Indices, Meshes[i].SubMeshes[j].Geometry);
- }
- else if (NumUV < 2)
- {
- mb = composeMeshBuffer(Meshes[i].SubMeshes[j].Indices, Meshes[i].SubMeshes[j].Geometry);
- }
- else
- {
- mb = composeMeshBufferLightMap(Meshes[i].SubMeshes[j].Indices, Meshes[i].SubMeshes[j].Geometry);
- }
- }
-
- if (mb != 0)
- {
- composeMeshBufferMaterial(mb, Meshes[i].SubMeshes[j].Material);
- if (!Skeleton.Bones.size())
- {
- ((SMesh*)Mesh)->addMeshBuffer(mb);
- mb->drop();
- }
- }
- }
- }
- if (Skeleton.Bones.size())
- {
- CSkinnedMesh* m = (CSkinnedMesh*)Mesh;
- // Create Joints
- for (u32 i=0; i<Skeleton.Bones.size(); ++i)
- {
- ISkinnedMesh::SJoint* joint = m->addJoint();
- joint->Name=Skeleton.Bones[i].Name;
-
- // IRR_TEST_BROKEN_QUATERNION_USE: TODO - switched to getMatrix_transposed instead of getMatrix for downward compatibility.
- // Not tested so far if this was correct or wrong before quaternion fix!
- Skeleton.Bones[i].Orientation.getMatrix_transposed(joint->LocalMatrix);
-
- if (Skeleton.Bones[i].Scale != core::vector3df(1,1,1))
- {
- core::matrix4 scaleMatrix;
- scaleMatrix.setScale( Skeleton.Bones[i].Scale );
- joint->LocalMatrix *= scaleMatrix;
- }
- joint->LocalMatrix.setTranslation( Skeleton.Bones[i].Position );
- }
- // Joints hierarchy
- for (u32 i=0; i<Skeleton.Bones.size(); ++i)
- {
- if (Skeleton.Bones[i].Parent<m->getJointCount())
- {
- m->getAllJoints()[Skeleton.Bones[i].Parent]->Children.push_back(m->getAllJoints()[Skeleton.Bones[i].Handle]);
- }
- }
-
- // Weights
- u32 bufCount=0;
- for (u32 i=0; i<Meshes.size(); ++i)
- {
- for (u32 j=0; j<Meshes[i].SubMeshes.size(); ++j)
- {
- for (u32 k=0; k<Meshes[i].SubMeshes[j].BoneAssignments.size(); ++k)
- {
- const OgreBoneAssignment& ba = Meshes[i].SubMeshes[j].BoneAssignments[k];
- if (ba.BoneID<m->getJointCount())
- {
- ISkinnedMesh::SWeight* w = m->addWeight(m->getAllJoints()[ba.BoneID]);
- w->strength=ba.Weight;
- w->vertex_id=ba.VertexID;
- w->buffer_id=bufCount;
- }
- }
- ++bufCount;
- }
- }
-
- for (u32 i=0; i<Skeleton.Animations.size(); ++i)
- {
- for (u32 j=0; j<Skeleton.Animations[i].Keyframes.size(); ++j)
- {
- OgreKeyframe& frame = Skeleton.Animations[i].Keyframes[j];
- ISkinnedMesh::SJoint* keyjoint = m->getAllJoints()[frame.BoneID];
- ISkinnedMesh::SPositionKey* poskey = m->addPositionKey(keyjoint);
- poskey->frame=frame.Time*25;
- poskey->position=keyjoint->LocalMatrix.getTranslation()+frame.Position;
- ISkinnedMesh::SRotationKey* rotkey = m->addRotationKey(keyjoint);
- rotkey->frame=frame.Time*25;
-
- // IRR_TEST_BROKEN_QUATERNION_USE: TODO - switched from keyjoint->LocalMatrix to keyjoint->LocalMatrix.getTransposed() for downward compatibility.
- // Not tested so far if this was correct or wrong before quaternion fix!
- rotkey->rotation=core::quaternion(keyjoint->LocalMatrix.getTransposed())*frame.Orientation;
-
- ISkinnedMesh::SScaleKey* scalekey = m->addScaleKey(keyjoint);
- scalekey->frame=frame.Time*25;
- scalekey->scale=frame.Scale;
- }
- }
- m->finalize();
- }
-}
-
-
-void COgreMeshFileLoader::getMaterialToken(io::IReadFile* file, core::stringc& token, bool noNewLine)
-{
- bool parseString=false;
- c8 c=0;
- token = "";
-
- if (file->getPos() >= file->getSize())
- return;
-
- file->read(&c, sizeof(c8));
- // search for word beginning
- while ( core::isspace(c) && (file->getPos() < file->getSize()))
- {
- if (noNewLine && c=='\n')
- {
- file->seek(-1, true);
- return;
- }
- file->read(&c, sizeof(c8));
- }
- // check if we read a string
- if (c=='"')
- {
- parseString = true;
- file->read(&c, sizeof(c8));
- }
- do
- {
- if (c=='/')
- {
- file->read(&c, sizeof(c8));
- // check for comments, cannot be part of strings
- if (!parseString && (c=='/'))
- {
- // skip comments
- while(c!='\n')
- file->read(&c, sizeof(c8));
- if (!token.size())
- {
- // if we start with a comment we need to skip
- // following whitespaces, so restart
- getMaterialToken(file, token, noNewLine);
- return;
- }
- else
- {
- // else continue with next character
- file->read(&c, sizeof(c8));
- continue;
- }
- }
- else
- {
- // else append first slash and check if second char
- // ends this token
- token.append('/');
- if ((!parseString && core::isspace(c)) ||
- (parseString && (c=='"')))
- return;
- }
- }
- token.append(c);
- file->read(&c, sizeof(c8));
- // read until a token delimiter is found
- }
- while (((!parseString && !core::isspace(c)) || (parseString && (c!='"'))) &&
- (file->getPos() < file->getSize()));
- // we want to skip the last quotes of a string , but other chars might be the next
- // token already.
- if (!parseString)
- file->seek(-1, true);
-}
-
-
-bool COgreMeshFileLoader::readColor(io::IReadFile* file, video::SColor& col)
-{
- core::stringc token;
-
- getMaterialToken(file, token);
- if (token!="vertexcolour")
- {
- video::SColorf col_f;
- col_f.r=core::fast_atof(token.c_str());
- getMaterialToken(file, token);
- col_f.g=core::fast_atof(token.c_str());
- getMaterialToken(file, token);
- col_f.b=core::fast_atof(token.c_str());
- getMaterialToken(file, token, true);
- if (token.size())
- col_f.a=core::fast_atof(token.c_str());
- else
- col_f.a=1.0f;
- if ((col_f.r==0.0f)&&(col_f.g==0.0f)&&(col_f.b==0.0f))
- col.set(255,255,255,255);
- else
- col=col_f.toSColor();
- return false;
- }
- return true;
-}
-
-
-void COgreMeshFileLoader::readPass(io::IReadFile* file, OgreTechnique& technique)
-{
-#ifdef IRR_OGRE_LOADER_DEBUG
- os::Printer::log("Read Pass");
-#endif
- core::stringc token;
- technique.Passes.push_back(OgrePass());
- OgrePass& pass=technique.Passes.getLast();
-
- getMaterialToken(file, token); //open brace or name
- if (token != "{")
- getMaterialToken(file, token); //open brace
-
- getMaterialToken(file, token);
- if (token == "}")
- return;
- u32 inBlocks=1;
- u32 textureUnit=0;
- while(inBlocks)
- {
- if (token=="ambient")
- pass.AmbientTokenColor=readColor(file, pass.Material.AmbientColor);
- else if (token=="diffuse")
- pass.DiffuseTokenColor=readColor(file, pass.Material.DiffuseColor);
- else if (token=="specular")
- {
- pass.SpecularTokenColor=readColor(file, pass.Material.SpecularColor);
- getMaterialToken(file, token);
- pass.Material.Shininess=core::fast_atof(token.c_str());
- }
- else if (token=="emissive")
- pass.EmissiveTokenColor=readColor(file, pass.Material.EmissiveColor);
- else if (token=="scene_blend")
- { // TODO: Choose correct values
- getMaterialToken(file, token);
- if (token=="add")
- pass.Material.MaterialType=video::EMT_TRANSPARENT_ADD_COLOR;
- else if (token=="modulate")
- pass.Material.MaterialType=video::EMT_SOLID;
- else if (token=="alpha_blend")
- pass.Material.MaterialType=video::EMT_TRANSPARENT_ALPHA_CHANNEL;
- else if (token=="colour_blend")
- pass.Material.MaterialType=video::EMT_TRANSPARENT_VERTEX_ALPHA;
- else
- getMaterialToken(file, token);
- }
- else if (token=="depth_check")
- {
- getMaterialToken(file, token);
- if (token!="on")
- pass.Material.ZBuffer=video::ECFN_DISABLED;
- }
- else if (token=="depth_write")
- {
- getMaterialToken(file, token);
- pass.Material.ZWriteEnable=(token=="on") ? video::EZW_ON : video::EZW_OFF;
- }
- else if (token=="depth_func")
- {
- getMaterialToken(file, token); // Function name
- if (token=="always_fail")
- pass.Material.ZBuffer=video::ECFN_NEVER;
- else if (token=="always_pass")
- pass.Material.ZBuffer=video::ECFN_ALWAYS;
- else if (token=="equal")
- pass.Material.ZBuffer=video::ECFN_EQUAL;
- else if (token=="greater")
- pass.Material.ZBuffer=video::ECFN_GREATER;
- else if (token=="greater_equal")
- pass.Material.ZBuffer=video::ECFN_GREATEREQUAL;
- else if (token=="less")
- pass.Material.ZBuffer=video::ECFN_LESS;
- else if (token=="less_equal")
- pass.Material.ZBuffer=video::ECFN_LESSEQUAL;
- else if (token=="not_equal")
- pass.Material.ZBuffer=video::ECFN_NOTEQUAL;
- }
- else if (token=="normalise_normals")
- {
- getMaterialToken(file, token);
- pass.Material.NormalizeNormals=(token=="on");
- }
- else if (token=="depth_bias")
- {
- getMaterialToken(file, token); // bias value
- }
- else if (token=="alpha_rejection")
- {
- getMaterialToken(file, token); // function name
- getMaterialToken(file, token); // value
- pass.Material.MaterialTypeParam=core::fast_atof(token.c_str());
- }
- else if (token=="alpha_to_coverage")
- {
- getMaterialToken(file, token);
- if (token=="on")
- pass.Material.AntiAliasing |= video::EAAM_ALPHA_TO_COVERAGE;
- }
- else if (token=="colour_write")
- {
- getMaterialToken(file, token);
- pass.Material.ColorMask = (token=="on")?video::ECP_ALL:video::ECP_NONE;
- }
- else if (token=="cull_hardware")
- {
- getMaterialToken(file, token); // rotation name
- }
- else if (token=="cull_software")
- {
- getMaterialToken(file, token); // culling side
- }
- else if (token=="lighting")
- {
- getMaterialToken(file, token);
- pass.Material.Lighting=(token=="on");
- }
- else if (token=="shading")
- {
- getMaterialToken(file, token);
- // We take phong as gouraud
- pass.Material.GouraudShading=(token!="flat");
- }
- else if (token=="polygon_mode")
- {
- getMaterialToken(file, token);
- pass.Material.Wireframe=(token=="wireframe");
- pass.Material.PointCloud=(token=="points");
- }
- else if (token=="max_lights")
- {
- getMaterialToken(file, token);
- pass.MaxLights=core::strtoul10(token.c_str());
- }
- else if (token=="point_size")
- {
- getMaterialToken(file, token);
- pass.PointSize=core::fast_atof(token.c_str());
- }
- else if (token=="point_sprites")
- {
- getMaterialToken(file, token);
- pass.PointSprites=(token=="on");
- }
- else if (token=="point_size_min")
- {
- getMaterialToken(file, token);
- pass.PointSizeMin=core::strtoul10(token.c_str());
- }
- else if (token=="point_size_max")
- {
- getMaterialToken(file, token);
- pass.PointSizeMax=core::strtoul10(token.c_str());
- }
- else if (token=="texture_unit")
- {
-#ifdef IRR_OGRE_LOADER_DEBUG
- os::Printer::log("Read Texture unit", ELL_DEBUG);
-#endif
- getMaterialToken(file, token); //open brace
- getMaterialToken(file, token);
- while(token != "}")
- {
- if (token=="texture")
- {
- getMaterialToken(file, token);
- pass.Texture.Filename.push_back(token);
-#ifdef IRR_OGRE_LOADER_DEBUG
- os::Printer::log("Read Texture", token, ELL_DEBUG);
-#endif
- getMaterialToken(file, pass.Texture.CoordsType, true);
- getMaterialToken(file, pass.Texture.MipMaps, true);
- getMaterialToken(file, pass.Texture.Alpha, true);
- // Hmm, we might need more hints for other material types using two textures...
- if (textureUnit>0)
- pass.Material.MaterialType=video::EMT_LIGHTMAP;
- }
- else if (token=="filtering")
- {
- getMaterialToken(file, token);
- pass.Material.TextureLayer[textureUnit].AnisotropicFilter=0;
- if (token=="point")
- {
- pass.Material.TextureLayer[textureUnit].BilinearFilter=false;
- pass.Material.TextureLayer[textureUnit].TrilinearFilter=false;
- getMaterialToken(file, token);
- getMaterialToken(file, token);
- }
- else if (token=="linear")
- {
- getMaterialToken(file, token);
- if (token=="point")
- {
- pass.Material.TextureLayer[textureUnit].BilinearFilter=false;
- pass.Material.TextureLayer[textureUnit].TrilinearFilter=false;
- getMaterialToken(file, token);
- }
- else
- {
- pass.Material.TextureLayer[textureUnit].BilinearFilter=true;
- getMaterialToken(file, token);
- pass.Material.TextureLayer[textureUnit].TrilinearFilter=(token=="linear");
- }
- }
- else
- {
- pass.Material.TextureLayer[textureUnit].BilinearFilter=(token=="bilinear");
- pass.Material.TextureLayer[textureUnit].TrilinearFilter=(token=="trilinear");
- pass.Material.TextureLayer[textureUnit].AnisotropicFilter=(token=="anisotropic")?2:1;
- }
- }
- else if (token=="max_anisotropy")
- {
- getMaterialToken(file, token);
- pass.Material.TextureLayer[textureUnit].AnisotropicFilter=(u8)core::strtoul10(token.c_str());
- }
- else if (token=="texture_alias")
- {
- getMaterialToken(file, pass.Texture.Alias);
- }
- else if (token=="mipmap_bias")
- {
- getMaterialToken(file, token);
- pass.Material.TextureLayer[textureUnit].LODBias=(s8)core::fast_atof(token.c_str());
- }
- else if (token=="colour_op")
- { // TODO: Choose correct values
- getMaterialToken(file, token);
- if (token=="add")
- pass.Material.MaterialType=video::EMT_TRANSPARENT_ADD_COLOR;
- else if (token=="modulate")
- pass.Material.MaterialType=video::EMT_SOLID;
- else if (token=="alpha_blend")
- pass.Material.MaterialType=video::EMT_TRANSPARENT_ALPHA_CHANNEL;
- else if (token=="colour_blend")
- pass.Material.MaterialType=video::EMT_TRANSPARENT_VERTEX_ALPHA;
- else
- getMaterialToken(file, token);
- }
- getMaterialToken(file, token);
- }
- ++textureUnit;
- }
- else if (token=="shadow_caster_program_ref")
- {
- do
- {
- getMaterialToken(file, token);
- } while (token != "}");
- }
- else if (token=="shadow_caster_vertex_program_ref")
- {
- do
- {
- getMaterialToken(file, token);
- } while (token != "}");
- }
- else if (token=="vertex_program_ref")
- {
- do
- {
- getMaterialToken(file, token);
- } while (token != "}");
- }
- //fog_override, iteration, point_size_attenuation
- //not considered yet!
- getMaterialToken(file, token);
- if (token=="{")
- ++inBlocks;
- else if (token=="}")
- --inBlocks;
- }
-}
-
-
-void COgreMeshFileLoader::readTechnique(io::IReadFile* file, OgreMaterial& mat)
-{
-#ifdef IRR_OGRE_LOADER_DEBUG
- os::Printer::log("Read Technique");
-#endif
- core::stringc token;
- mat.Techniques.push_back(OgreTechnique());
- OgreTechnique& technique=mat.Techniques.getLast();
-
- getMaterialToken(file, technique.Name); //open brace or name
- if (technique.Name != "{")
- getMaterialToken(file, token); //open brace
- else
- technique.Name=core::stringc((int)mat.Techniques.size());
-
- getMaterialToken(file, token);
- while (token != "}")
- {
- if (token == "pass")
- readPass(file, technique);
- else if (token == "scheme")
- getMaterialToken(file, token);
- else if (token == "lod_index")
- getMaterialToken(file, token);
- getMaterialToken(file, token);
- }
-}
-
-
-void COgreMeshFileLoader::loadMaterials(io::IReadFile* meshFile)
-{
-#ifdef IRR_OGRE_LOADER_DEBUG
- os::Printer::log("Load Materials", ELL_DEBUG);
-#endif
- core::stringc token;
- io::IReadFile* file = 0;
- io::path filename = FileSystem->getFileBasename(meshFile->getFileName(), false) + ".material";
- if (FileSystem->existFile(filename))
- file = FileSystem->createAndOpenFile(filename);
- else
- file = FileSystem->createAndOpenFile(FileSystem->getFileDir(meshFile->getFileName())+"/"+filename);
-
- if (!file)
- {
- os::Printer::log("Could not load OGRE material", filename);
- return;
- }
-
- getMaterialToken(file, token);
-
- while (file->getPos() < file->getSize())
- {
- if ((token == "fragment_program") || (token == "vertex_program"))
- {
- // skip whole block
- u32 blocks=1;
- do
- {
- getMaterialToken(file, token);
- } while (token != "{");
- do
- {
- getMaterialToken(file, token);
- if (token == "{")
- ++blocks;
- else if (token == "}")
- --blocks;
- } while (blocks);
- getMaterialToken(file, token);
- continue;
- }
- if (token != "material")
- {
- if (token.trim().size())
- os::Printer::log("Unknown material group", token.c_str());
- break;
- }
-
- Materials.push_back(OgreMaterial());
- OgreMaterial& mat = Materials.getLast();
-
- getMaterialToken(file, mat.Name);
-#ifdef IRR_OGRE_LOADER_DEBUG
- os::Printer::log("Load Material", mat.Name.c_str(), ELL_DEBUG);
-#endif
- getMaterialToken(file, token); //open brace
- getMaterialToken(file, token);
- while(token != "}")
- {
- if (token=="lod_distances") // can have several items
- getMaterialToken(file, token);
- else if (token=="receive_shadows")
- {
- getMaterialToken(file, token);
- mat.ReceiveShadows=(token=="on");
- }
- else if (token=="transparency_casts_shadows")
- {
- getMaterialToken(file, token);
- mat.TransparencyCastsShadows=(token=="on");
- }
- else if (token=="set_texture_alias")
- {
- getMaterialToken(file, token);
- getMaterialToken(file, token);
- }
- else if (token=="technique")
- readTechnique(file, mat);
- getMaterialToken(file, token);
- }
- getMaterialToken(file, token);
- }
-
- file->drop();
-#ifdef IRR_OGRE_LOADER_DEBUG
- os::Printer::log("Finished loading Materials", ELL_DEBUG);
-#endif
-}
-
-
-bool COgreMeshFileLoader::loadSkeleton(io::IReadFile* meshFile, const core::stringc& name)
-{
-#ifdef IRR_OGRE_LOADER_DEBUG
- os::Printer::log("Load Skeleton", name, ELL_DEBUG);
-#endif
- io::IReadFile* file = 0;
- io::path filename;
- if (FileSystem->existFile(name))
- file = FileSystem->createAndOpenFile(name);
- else if (FileSystem->existFile(filename = FileSystem->getFileDir(meshFile->getFileName())+"/"+name))
- file = FileSystem->createAndOpenFile(filename);
- else if (FileSystem->existFile(filename = FileSystem->getFileBasename(meshFile->getFileName(), false) + ".skeleton"))
- file = FileSystem->createAndOpenFile(filename);
- else
- file = FileSystem->createAndOpenFile(FileSystem->getFileDir(meshFile->getFileName())+"/"+filename);
- if (!file)
- {
- os::Printer::log("Could not load matching skeleton", name);
- return false;
- }
-
- s16 id;
- file->read(&id, 2);
- if (SwapEndian)
- id = os::Byteswap::byteswap(id);
- if (id != COGRE_HEADER)
- {
- file->drop();
- return false;
- }
-
- core::stringc skeletonVersion;
- ChunkData head;
- readString(file, head, skeletonVersion);
- if (skeletonVersion != "[Serializer_v1.10]")
- {
- file->drop();
- return false;
- }
-
- u16 bone=0;
- f32 animationTotal=0.f;
- while(file->getPos() < file->getSize())
- {
- ChunkData data;
- readChunkData(file, data);
-
- switch(data.header.id)
- {
- case COGRE_SKELETON:
- {
- Skeleton.Bones.push_back(OgreBone());
- OgreBone& bone = Skeleton.Bones.getLast();
- readString(file, data, bone.Name);
- readShort(file, data, &bone.Handle);
- readVector(file, data, bone.Position);
- readQuaternion(file, data, bone.Orientation);
-#ifdef IRR_OGRE_LOADER_DEBUG
- os::Printer::log("Bone", bone.Name+" ("+core::stringc(bone.Handle)+")", ELL_DEBUG);
- os::Printer::log("Position", core::stringc(bone.Position.X)+" "+core::stringc(bone.Position.Y)+" "+core::stringc(bone.Position.Z), ELL_DEBUG);
- os::Printer::log("Rotation quat", core::stringc(bone.Orientation.W)+" "+core::stringc(bone.Orientation.X)+" "+core::stringc(bone.Orientation.Y)+" "+core::stringc(bone.Orientation.Z), ELL_DEBUG);
-// core::vector3df rot;
-// bone.Orientation.toEuler(rot);
-// rot *= core::RADTODEG;
-// os::Printer::log("Rotation", core::stringc(rot.X)+" "+core::stringc(rot.Y)+" "+core::stringc(rot.Z));
-#endif
- if (data.read<(data.header.length-bone.Name.size()))
- {
- readVector(file, data, bone.Scale);
- bone.Scale.X *= -1.f;
- }
- else
- bone.Scale=core::vector3df(1,1,1);
- bone.Parent=0xffff;
- }
- break;
- case COGRE_BONE_PARENT:
- {
- u16 parent;
- readShort(file, data, &bone);
- readShort(file, data, &parent);
- if (bone<Skeleton.Bones.size() && parent<Skeleton.Bones.size())
- Skeleton.Bones[bone].Parent=parent;
- }
- break;
- case COGRE_ANIMATION:
- {
- if (Skeleton.Animations.size())
- animationTotal+=Skeleton.Animations.getLast().Length;
- Skeleton.Animations.push_back(OgreAnimation());
- OgreAnimation& anim = Skeleton.Animations.getLast();
- readString(file, data, anim.Name);
- readFloat(file, data, &anim.Length);
-#ifdef IRR_OGRE_LOADER_DEBUG
- os::Printer::log("Animation", anim.Name, ELL_DEBUG);
- os::Printer::log("Length", core::stringc(anim.Length), ELL_DEBUG);
-#endif
- }
- break;
- case COGRE_ANIMATION_TRACK:
-#ifdef IRR_OGRE_LOADER_DEBUG
- os::Printer::log("for Bone ", core::stringc(bone), ELL_DEBUG);
-#endif
- readShort(file, data, &bone); // store current bone
- break;
- case COGRE_ANIMATION_KEYFRAME:
- {
- Skeleton.Animations.getLast().Keyframes.push_back(OgreKeyframe());
- OgreKeyframe& keyframe = Skeleton.Animations.getLast().Keyframes.getLast();
- readFloat(file, data, &keyframe.Time);
- keyframe.Time+=animationTotal;
- readQuaternion(file, data, keyframe.Orientation);
- readVector(file, data, keyframe.Position);
- if (data.read<data.header.length)
- {
- readVector(file, data, keyframe.Scale);
- keyframe.Scale.X *= -1.f;
- }
- else
- keyframe.Scale=core::vector3df(1,1,1);
- keyframe.BoneID=bone;
- }
- break;
- case COGRE_ANIMATION_LINK:
-#ifdef IRR_OGRE_LOADER_DEBUG
- os::Printer::log("Animation link", ELL_DEBUG);
-#endif
- break;
- default:
- break;
- }
- }
- file->drop();
- return true;
-}
-
-
-void COgreMeshFileLoader::readChunkData(io::IReadFile* file, ChunkData& data)
-{
- file->read(&data.header, sizeof(ChunkHeader));
- if (SwapEndian)
- {
- data.header.id = os::Byteswap::byteswap(data.header.id);
- data.header.length = os::Byteswap::byteswap(data.header.length);
- }
- data.read += sizeof(ChunkHeader);
-}
-
-
-void COgreMeshFileLoader::readString(io::IReadFile* file, ChunkData& data, core::stringc& out)
-{
- c8 c = 0;
- out = "";
-
- while (c!='\n')
- {
- file->read(&c, sizeof(c8));
- if (c!='\n')
- out.append(c);
-
- }
- data.read+=out.size()+1;
-}
-
-
-void COgreMeshFileLoader::readBool(io::IReadFile* file, ChunkData& data, bool& out)
-{
- // normal C type because we read a bit string
- char c = 0;
- file->read(&c, sizeof(char));
- out=(c!=0);
- ++data.read;
-}
-
-
-void COgreMeshFileLoader::readInt(io::IReadFile* file, ChunkData& data, s32* out, u32 num)
-{
- // normal C type because we read a bit string
- file->read(out, sizeof(int)*num);
- if (SwapEndian)
- {
- for (u32 i=0; i<num; ++i)
- out[i] = os::Byteswap::byteswap(out[i]);
- }
- data.read+=sizeof(int)*num;
-}
-
-
-void COgreMeshFileLoader::readShort(io::IReadFile* file, ChunkData& data, u16* out, u32 num)
-{
- // normal C type because we read a bit string
- file->read(out, sizeof(short)*num);
- if (SwapEndian)
- {
- for (u32 i=0; i<num; ++i)
- out[i] = os::Byteswap::byteswap(out[i]);
- }
- data.read+=sizeof(short)*num;
-}
-
-
-void COgreMeshFileLoader::readFloat(io::IReadFile* file, ChunkData& data, f32* out, u32 num)
-{
- // normal C type because we read a bit string
- file->read(out, sizeof(float)*num);
- if (SwapEndian)
- {
- for (u32 i=0; i<num; ++i)
- out[i] = os::Byteswap::byteswap(out[i]);
- }
- data.read+=sizeof(float)*num;
-}
-
-
-void COgreMeshFileLoader::readVector(io::IReadFile* file, ChunkData& data, core::vector3df& out)
-{
- readFloat(file, data, &out.X);
- readFloat(file, data, &out.Y);
- readFloat(file, data, &out.Z);
- out.X *= -1.f;
-}
-
-
-void COgreMeshFileLoader::readQuaternion(io::IReadFile* file, ChunkData& data, core::quaternion& out)
-{
- readVector(file, data, *((core::vector3df*)&out.X));
- readFloat(file, data, &out.W);
-}
-
-
-void COgreMeshFileLoader::clearMeshes()
-{
- for (u32 i=0; i<Meshes.size(); ++i)
- {
- for (int k=0; k<(int)Meshes[i].Geometry.Buffers.size(); ++k)
- Meshes[i].Geometry.Buffers[k].Data.clear();
-
- for (u32 j=0; j<Meshes[i].SubMeshes.size(); ++j)
- {
- for (int h=0; h<(int)Meshes[i].SubMeshes[j].Geometry.Buffers.size(); ++h)
- Meshes[i].SubMeshes[j].Geometry.Buffers[h].Data.clear();
- }
- }
-
- Meshes.clear();
-}
-
-
-} // end namespace scene
-} // end namespace irr
-
-#endif // _IRR_COMPILE_WITH_OGRE_LOADER_
-
|