summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/assimp/code/COBLoader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/assimp/code/COBLoader.cpp')
-rw-r--r--src/3rdparty/assimp/code/COBLoader.cpp2007
1 files changed, 1007 insertions, 1000 deletions
diff --git a/src/3rdparty/assimp/code/COBLoader.cpp b/src/3rdparty/assimp/code/COBLoader.cpp
index 49a45be7a..4f0ad3980 100644
--- a/src/3rdparty/assimp/code/COBLoader.cpp
+++ b/src/3rdparty/assimp/code/COBLoader.cpp
@@ -2,11 +2,11 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
-Copyright (c) 2006-2012, assimp team
+Copyright (c) 2006-2016, assimp team
All rights reserved.
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
following conditions are met:
* Redistributions of source code must retain the above
@@ -23,16 +23,16 @@ following conditions are met:
derived from this software without specific prior
written permission of the assimp team.
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
@@ -41,7 +41,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file COBLoader.cpp
* @brief Implementation of the TrueSpace COB/SCN importer class.
*/
-#include "AssimpPCH.h"
+
#ifndef ASSIMP_BUILD_NO_COB_IMPORTER
#include "COBLoader.h"
@@ -53,36 +53,39 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "LineSplitter.h"
#include "TinyFormatter.h"
+#include <memory>
+#include <assimp/IOSystem.hpp>
+#include <assimp/DefaultLogger.hpp>
+#include <assimp/scene.h>
+
using namespace Assimp;
using namespace Assimp::COB;
using namespace Assimp::Formatter;
-#define for_each BOOST_FOREACH
-
static const float units[] = {
- 1000.f,
- 100.f,
- 1.f,
- 0.001f,
- 1.f/0.0254f,
- 1.f/0.3048f,
- 1.f/0.9144f,
- 1.f/1609.344f
-};
+ 1000.f,
+ 100.f,
+ 1.f,
+ 0.001f,
+ 1.f/0.0254f,
+ 1.f/0.3048f,
+ 1.f/0.9144f,
+ 1.f/1609.344f
+};
static const aiImporterDesc desc = {
- "TrueSpace Object Importer",
- "",
- "",
- "little-endian files only",
- aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour,
- 0,
- 0,
- 0,
- 0,
- "cob scn"
+ "TrueSpace Object Importer",
+ "",
+ "",
+ "little-endian files only",
+ aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour,
+ 0,
+ 0,
+ 0,
+ 0,
+ "cob scn"
};
@@ -92,843 +95,847 @@ COBImporter::COBImporter()
{}
// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
+// Destructor, private as well
COBImporter::~COBImporter()
{}
// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
+// Returns whether the class can handle the format of the given file.
bool COBImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
{
- const std::string& extension = GetExtension(pFile);
- if (extension == "cob" || extension == "scn") {
- return true;
- }
-
- else if ((!extension.length() || checkSig) && pIOHandler) {
- const char* tokens[] = {"Caligary"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
+ const std::string& extension = GetExtension(pFile);
+ if (extension == "cob" || extension == "scn") {
+ return true;
+ }
+
+ else if ((!extension.length() || checkSig) && pIOHandler) {
+ const char* tokens[] = {"Caligary"};
+ return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
+ }
+ return false;
}
// ------------------------------------------------------------------------------------------------
// Loader meta information
const aiImporterDesc* COBImporter::GetInfo () const
{
- return &desc;
+ return &desc;
}
// ------------------------------------------------------------------------------------------------
// Setup configuration properties for the loader
void COBImporter::SetupProperties(const Importer* /*pImp*/)
{
- // nothing to be done for the moment
+ // nothing to be done for the moment
}
// ------------------------------------------------------------------------------------------------
-/*static*/ void COBImporter::ThrowException(const std::string& msg)
+/*static*/ AI_WONT_RETURN void COBImporter::ThrowException(const std::string& msg)
{
- throw DeadlyImportError("COB: "+msg);
+ throw DeadlyImportError("COB: "+msg);
}
// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void COBImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
+// Imports the given file into the given scene structure.
+void COBImporter::InternReadFile( const std::string& pFile,
+ aiScene* pScene, IOSystem* pIOHandler)
{
- COB::Scene scene;
- boost::scoped_ptr<StreamReaderLE> stream(new StreamReaderLE( pIOHandler->Open(pFile,"rb")) );
-
- // check header
- char head[32];
- stream->CopyAndAdvance(head,32);
- if (strncmp(head,"Caligari ",9)) {
- ThrowException("Could not found magic id: `Caligari`");
- }
-
- DefaultLogger::get()->info("File format tag: "+std::string(head+9,6));
- void (COBImporter::* load)(Scene&,StreamReaderLE*)= head[15]=='A'?&COBImporter::ReadAsciiFile:&COBImporter::ReadBinaryFile;
- if (head[16]!='L') {
- ThrowException("File is big-endian, which is not supported");
- }
-
- // load data into intermediate structures
- (this->*load)(scene,stream.get());
- if(scene.nodes.empty()) {
- ThrowException("No nodes loaded");
- }
-
- // sort faces by material indices
- for_each(boost::shared_ptr< Node >& n,scene.nodes) {
- if (n->type == Node::TYPE_MESH) {
- Mesh& mesh = (Mesh&)(*n.get());
- for_each(Face& f,mesh.faces) {
- mesh.temp_map[f.material].push_back(&f);
- }
- }
- }
-
- // count meshes
- for_each(boost::shared_ptr< Node >& n,scene.nodes) {
- if (n->type == Node::TYPE_MESH) {
- Mesh& mesh = (Mesh&)(*n.get());
- if (mesh.vertex_positions.size() && mesh.texture_coords.size()) {
- pScene->mNumMeshes += mesh.temp_map.size();
- }
- }
- }
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]();
- pScene->mMaterials = new aiMaterial*[pScene->mNumMeshes]();
- pScene->mNumMeshes = 0;
-
- // count lights and cameras
- for_each(boost::shared_ptr< Node >& n,scene.nodes) {
- if (n->type == Node::TYPE_LIGHT) {
- ++pScene->mNumLights;
- }
- else if (n->type == Node::TYPE_CAMERA) {
- ++pScene->mNumCameras;
- }
- }
-
- if (pScene->mNumLights) {
- pScene->mLights = new aiLight*[pScene->mNumLights]();
- }
- if (pScene->mNumCameras) {
- pScene->mCameras = new aiCamera*[pScene->mNumCameras]();
- }
- pScene->mNumLights = pScene->mNumCameras = 0;
-
- // resolve parents by their IDs and build the output graph
- boost::scoped_ptr<Node> root(new Group());
- for(size_t n = 0; n < scene.nodes.size(); ++n) {
- const Node& nn = *scene.nodes[n].get();
- if(nn.parent_id==0) {
- root->temp_children.push_back(&nn);
- }
-
- for(size_t m = n; m < scene.nodes.size(); ++m) {
- const Node& mm = *scene.nodes[m].get();
- if (mm.parent_id == nn.id) {
- nn.temp_children.push_back(&mm);
- }
- }
- }
-
- pScene->mRootNode = BuildNodes(*root.get(),scene,pScene);
+ COB::Scene scene;
+ std::unique_ptr<StreamReaderLE> stream(new StreamReaderLE( pIOHandler->Open(pFile,"rb")) );
+
+ // check header
+ char head[32];
+ stream->CopyAndAdvance(head,32);
+ if (strncmp(head,"Caligari ",9)) {
+ ThrowException("Could not found magic id: `Caligari`");
+ }
+
+ DefaultLogger::get()->info("File format tag: "+std::string(head+9,6));
+ if (head[16]!='L') {
+ ThrowException("File is big-endian, which is not supported");
+ }
+
+ // load data into intermediate structures
+ if (head[15]=='A') {
+ ReadAsciiFile(scene, stream.get());
+ }
+ else {
+ ReadBinaryFile(scene, stream.get());
+ }
+ if(scene.nodes.empty()) {
+ ThrowException("No nodes loaded");
+ }
+
+ // sort faces by material indices
+ for(std::shared_ptr< Node >& n : scene.nodes) {
+ if (n->type == Node::TYPE_MESH) {
+ Mesh& mesh = (Mesh&)(*n.get());
+ for(Face& f : mesh.faces) {
+ mesh.temp_map[f.material].push_back(&f);
+ }
+ }
+ }
+
+ // count meshes
+ for(std::shared_ptr< Node >& n : scene.nodes) {
+ if (n->type == Node::TYPE_MESH) {
+ Mesh& mesh = (Mesh&)(*n.get());
+ if (mesh.vertex_positions.size() && mesh.texture_coords.size()) {
+ pScene->mNumMeshes += mesh.temp_map.size();
+ }
+ }
+ }
+ pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]();
+ pScene->mMaterials = new aiMaterial*[pScene->mNumMeshes]();
+ pScene->mNumMeshes = 0;
+
+ // count lights and cameras
+ for(std::shared_ptr< Node >& n : scene.nodes) {
+ if (n->type == Node::TYPE_LIGHT) {
+ ++pScene->mNumLights;
+ }
+ else if (n->type == Node::TYPE_CAMERA) {
+ ++pScene->mNumCameras;
+ }
+ }
+
+ if (pScene->mNumLights) {
+ pScene->mLights = new aiLight*[pScene->mNumLights]();
+ }
+ if (pScene->mNumCameras) {
+ pScene->mCameras = new aiCamera*[pScene->mNumCameras]();
+ }
+ pScene->mNumLights = pScene->mNumCameras = 0;
+
+ // resolve parents by their IDs and build the output graph
+ std::unique_ptr<Node> root(new Group());
+ for(size_t n = 0; n < scene.nodes.size(); ++n) {
+ const Node& nn = *scene.nodes[n].get();
+ if(nn.parent_id==0) {
+ root->temp_children.push_back(&nn);
+ }
+
+ for(size_t m = n; m < scene.nodes.size(); ++m) {
+ const Node& mm = *scene.nodes[m].get();
+ if (mm.parent_id == nn.id) {
+ nn.temp_children.push_back(&mm);
+ }
+ }
+ }
+
+ pScene->mRootNode = BuildNodes(*root.get(),scene,pScene);
}
// ------------------------------------------------------------------------------------------------
-void ConvertTexture(boost::shared_ptr< Texture > tex, aiMaterial* out, aiTextureType type)
+void ConvertTexture(std::shared_ptr< Texture > tex, aiMaterial* out, aiTextureType type)
{
- const aiString path( tex->path );
- out->AddProperty(&path,AI_MATKEY_TEXTURE(type,0));
- out->AddProperty(&tex->transform,1,AI_MATKEY_UVTRANSFORM(type,0));
+ const aiString path( tex->path );
+ out->AddProperty(&path,AI_MATKEY_TEXTURE(type,0));
+ out->AddProperty(&tex->transform,1,AI_MATKEY_UVTRANSFORM(type,0));
}
// ------------------------------------------------------------------------------------------------
aiNode* COBImporter::BuildNodes(const Node& root,const Scene& scin,aiScene* fill)
{
- aiNode* nd = new aiNode();
- nd->mName.Set(root.name);
- nd->mTransformation = root.transform;
-
- // Note to everybody believing Voodoo is appropriate here:
- // I know polymorphism, run as fast as you can ;-)
- if (Node::TYPE_MESH == root.type) {
- const Mesh& ndmesh = (const Mesh&)(root);
- if (ndmesh.vertex_positions.size() && ndmesh.texture_coords.size()) {
-
- typedef std::pair<unsigned int,Mesh::FaceRefList> Entry;
- for_each(const Entry& reflist,ndmesh.temp_map) {
- { // create mesh
- size_t n = 0;
- for_each(Face* f, reflist.second) {
- n += f->indices.size();
- }
- if (!n) {
- continue;
- }
- aiMesh* outmesh = fill->mMeshes[fill->mNumMeshes++] = new aiMesh();
- ++nd->mNumMeshes;
-
- outmesh->mVertices = new aiVector3D[n];
- outmesh->mTextureCoords[0] = new aiVector3D[n];
-
- outmesh->mFaces = new aiFace[reflist.second.size()]();
- for_each(Face* f, reflist.second) {
- if (f->indices.empty()) {
- continue;
- }
-
- aiFace& fout = outmesh->mFaces[outmesh->mNumFaces++];
- fout.mIndices = new unsigned int[f->indices.size()];
-
- for_each(VertexIndex& v, f->indices) {
- if (v.pos_idx >= ndmesh.vertex_positions.size()) {
- ThrowException("Position index out of range");
- }
- if (v.uv_idx >= ndmesh.texture_coords.size()) {
- ThrowException("UV index out of range");
- }
- outmesh->mVertices[outmesh->mNumVertices] = ndmesh.vertex_positions[ v.pos_idx ];
- outmesh->mTextureCoords[0][outmesh->mNumVertices] = aiVector3D(
- ndmesh.texture_coords[ v.uv_idx ].x,
- ndmesh.texture_coords[ v.uv_idx ].y,
- 0.f
- );
-
- fout.mIndices[fout.mNumIndices++] = outmesh->mNumVertices++;
- }
- }
- outmesh->mMaterialIndex = fill->mNumMaterials;
- }{ // create material
- const Material* min = NULL;
- for_each(const Material& m, scin.materials) {
- if (m.parent_id == ndmesh.id && m.matnum == reflist.first) {
- min = &m;
- break;
- }
- }
- boost::scoped_ptr<const Material> defmat;
- if(!min) {
- DefaultLogger::get()->debug(format()<<"Could not resolve material index "
- <<reflist.first<<" - creating default material for this slot");
-
- defmat.reset(min=new Material());
- }
-
- aiMaterial* mat = new aiMaterial();
- fill->mMaterials[fill->mNumMaterials++] = mat;
-
- const aiString s(format("#mat_")<<fill->mNumMeshes<<"_"<<min->matnum);
- mat->AddProperty(&s,AI_MATKEY_NAME);
-
- if(int tmp = ndmesh.draw_flags & Mesh::WIRED ? 1 : 0) {
- mat->AddProperty(&tmp,1,AI_MATKEY_ENABLE_WIREFRAME);
- }
-
- { int shader;
- switch(min->shader)
- {
- case Material::FLAT:
- shader = aiShadingMode_Gouraud;
- break;
-
- case Material::PHONG:
- shader = aiShadingMode_Phong;
- break;
-
- case Material::METAL:
- shader = aiShadingMode_CookTorrance;
- break;
-
- default:
- ai_assert(false); // shouldn't be here
- }
- mat->AddProperty(&shader,1,AI_MATKEY_SHADING_MODEL);
- if(shader != aiShadingMode_Gouraud) {
- mat->AddProperty(&min->exp,1,AI_MATKEY_SHININESS);
- }
- }
-
- mat->AddProperty(&min->ior,1,AI_MATKEY_REFRACTI);
- mat->AddProperty(&min->rgb,1,AI_MATKEY_COLOR_DIFFUSE);
-
- aiColor3D c = aiColor3D(min->rgb)*min->ks;
- mat->AddProperty(&c,1,AI_MATKEY_COLOR_SPECULAR);
-
- c = aiColor3D(min->rgb)*min->ka;
- mat->AddProperty(&c,1,AI_MATKEY_COLOR_AMBIENT);
-
- // convert textures if some exist.
- if(min->tex_color) {
- ConvertTexture(min->tex_color,mat,aiTextureType_DIFFUSE);
- }
- if(min->tex_env) {
- ConvertTexture(min->tex_env ,mat,aiTextureType_UNKNOWN);
- }
- if(min->tex_bump) {
- ConvertTexture(min->tex_bump ,mat,aiTextureType_HEIGHT);
- }
- }
- }
- }
- }
- else if (Node::TYPE_LIGHT == root.type) {
- const Light& ndlight = (const Light&)(root);
- aiLight* outlight = fill->mLights[fill->mNumLights++] = new aiLight();
-
- outlight->mName.Set(ndlight.name);
- outlight->mColorDiffuse = outlight->mColorAmbient = outlight->mColorSpecular = ndlight.color;
-
- outlight->mAngleOuterCone = AI_DEG_TO_RAD(ndlight.angle);
- outlight->mAngleInnerCone = AI_DEG_TO_RAD(ndlight.inner_angle);
-
- // XXX
- outlight->mType = ndlight.ltype==Light::SPOT ? aiLightSource_SPOT : aiLightSource_DIRECTIONAL;
- }
- else if (Node::TYPE_CAMERA == root.type) {
- const Camera& ndcam = (const Camera&)(root);
- aiCamera* outcam = fill->mCameras[fill->mNumCameras++] = new aiCamera();
-
- outcam->mName.Set(ndcam.name);
- }
-
- // add meshes
- if (nd->mNumMeshes) { // mMeshes must be NULL if count is 0
- nd->mMeshes = new unsigned int[nd->mNumMeshes];
- for(unsigned int i = 0; i < nd->mNumMeshes;++i) {
- nd->mMeshes[i] = fill->mNumMeshes-i-1;
- }
- }
-
- // add children recursively
- nd->mChildren = new aiNode*[root.temp_children.size()]();
- for_each(const Node* n, root.temp_children) {
- (nd->mChildren[nd->mNumChildren++] = BuildNodes(*n,scin,fill))->mParent = nd;
- }
-
- return nd;
+ aiNode* nd = new aiNode();
+ nd->mName.Set(root.name);
+ nd->mTransformation = root.transform;
+
+ // Note to everybody believing Voodoo is appropriate here:
+ // I know polymorphism, run as fast as you can ;-)
+ if (Node::TYPE_MESH == root.type) {
+ const Mesh& ndmesh = (const Mesh&)(root);
+ if (ndmesh.vertex_positions.size() && ndmesh.texture_coords.size()) {
+
+ typedef std::pair<unsigned int,Mesh::FaceRefList> Entry;
+ for(const Entry& reflist : ndmesh.temp_map) {
+ { // create mesh
+ size_t n = 0;
+ for(Face* f : reflist.second) {
+ n += f->indices.size();
+ }
+ if (!n) {
+ continue;
+ }
+ aiMesh* outmesh = fill->mMeshes[fill->mNumMeshes++] = new aiMesh();
+ ++nd->mNumMeshes;
+
+ outmesh->mVertices = new aiVector3D[n];
+ outmesh->mTextureCoords[0] = new aiVector3D[n];
+
+ outmesh->mFaces = new aiFace[reflist.second.size()]();
+ for(Face* f : reflist.second) {
+ if (f->indices.empty()) {
+ continue;
+ }
+
+ aiFace& fout = outmesh->mFaces[outmesh->mNumFaces++];
+ fout.mIndices = new unsigned int[f->indices.size()];
+
+ for(VertexIndex& v : f->indices) {
+ if (v.pos_idx >= ndmesh.vertex_positions.size()) {
+ ThrowException("Position index out of range");
+ }
+ if (v.uv_idx >= ndmesh.texture_coords.size()) {
+ ThrowException("UV index out of range");
+ }
+ outmesh->mVertices[outmesh->mNumVertices] = ndmesh.vertex_positions[ v.pos_idx ];
+ outmesh->mTextureCoords[0][outmesh->mNumVertices] = aiVector3D(
+ ndmesh.texture_coords[ v.uv_idx ].x,
+ ndmesh.texture_coords[ v.uv_idx ].y,
+ 0.f
+ );
+
+ fout.mIndices[fout.mNumIndices++] = outmesh->mNumVertices++;
+ }
+ }
+ outmesh->mMaterialIndex = fill->mNumMaterials;
+ }{ // create material
+ const Material* min = NULL;
+ for(const Material& m : scin.materials) {
+ if (m.parent_id == ndmesh.id && m.matnum == reflist.first) {
+ min = &m;
+ break;
+ }
+ }
+ std::unique_ptr<const Material> defmat;
+ if(!min) {
+ DefaultLogger::get()->debug(format()<<"Could not resolve material index "
+ <<reflist.first<<" - creating default material for this slot");
+
+ defmat.reset(min=new Material());
+ }
+
+ aiMaterial* mat = new aiMaterial();
+ fill->mMaterials[fill->mNumMaterials++] = mat;
+
+ const aiString s(format("#mat_")<<fill->mNumMeshes<<"_"<<min->matnum);
+ mat->AddProperty(&s,AI_MATKEY_NAME);
+
+ if(int tmp = ndmesh.draw_flags & Mesh::WIRED ? 1 : 0) {
+ mat->AddProperty(&tmp,1,AI_MATKEY_ENABLE_WIREFRAME);
+ }
+
+ { int shader;
+ switch(min->shader)
+ {
+ case Material::FLAT:
+ shader = aiShadingMode_Gouraud;
+ break;
+
+ case Material::PHONG:
+ shader = aiShadingMode_Phong;
+ break;
+
+ case Material::METAL:
+ shader = aiShadingMode_CookTorrance;
+ break;
+
+ default:
+ ai_assert(false); // shouldn't be here
+ }
+ mat->AddProperty(&shader,1,AI_MATKEY_SHADING_MODEL);
+ if(shader != aiShadingMode_Gouraud) {
+ mat->AddProperty(&min->exp,1,AI_MATKEY_SHININESS);
+ }
+ }
+
+ mat->AddProperty(&min->ior,1,AI_MATKEY_REFRACTI);
+ mat->AddProperty(&min->rgb,1,AI_MATKEY_COLOR_DIFFUSE);
+
+ aiColor3D c = aiColor3D(min->rgb)*min->ks;
+ mat->AddProperty(&c,1,AI_MATKEY_COLOR_SPECULAR);
+
+ c = aiColor3D(min->rgb)*min->ka;
+ mat->AddProperty(&c,1,AI_MATKEY_COLOR_AMBIENT);
+
+ // convert textures if some exist.
+ if(min->tex_color) {
+ ConvertTexture(min->tex_color,mat,aiTextureType_DIFFUSE);
+ }
+ if(min->tex_env) {
+ ConvertTexture(min->tex_env ,mat,aiTextureType_UNKNOWN);
+ }
+ if(min->tex_bump) {
+ ConvertTexture(min->tex_bump ,mat,aiTextureType_HEIGHT);
+ }
+ }
+ }
+ }
+ }
+ else if (Node::TYPE_LIGHT == root.type) {
+ const Light& ndlight = (const Light&)(root);
+ aiLight* outlight = fill->mLights[fill->mNumLights++] = new aiLight();
+
+ outlight->mName.Set(ndlight.name);
+ outlight->mColorDiffuse = outlight->mColorAmbient = outlight->mColorSpecular = ndlight.color;
+
+ outlight->mAngleOuterCone = AI_DEG_TO_RAD(ndlight.angle);
+ outlight->mAngleInnerCone = AI_DEG_TO_RAD(ndlight.inner_angle);
+
+ // XXX
+ outlight->mType = ndlight.ltype==Light::SPOT ? aiLightSource_SPOT : aiLightSource_DIRECTIONAL;
+ }
+ else if (Node::TYPE_CAMERA == root.type) {
+ const Camera& ndcam = (const Camera&)(root);
+ aiCamera* outcam = fill->mCameras[fill->mNumCameras++] = new aiCamera();
+
+ outcam->mName.Set(ndcam.name);
+ }
+
+ // add meshes
+ if (nd->mNumMeshes) { // mMeshes must be NULL if count is 0
+ nd->mMeshes = new unsigned int[nd->mNumMeshes];
+ for(unsigned int i = 0; i < nd->mNumMeshes;++i) {
+ nd->mMeshes[i] = fill->mNumMeshes-i-1;
+ }
+ }
+
+ // add children recursively
+ nd->mChildren = new aiNode*[root.temp_children.size()]();
+ for(const Node* n : root.temp_children) {
+ (nd->mChildren[nd->mNumChildren++] = BuildNodes(*n,scin,fill))->mParent = nd;
+ }
+
+ return nd;
}
// ------------------------------------------------------------------------------------------------
// Read an ASCII file into the given scene data structure
void COBImporter::ReadAsciiFile(Scene& out, StreamReaderLE* stream)
{
- ChunkInfo ci;
- for(LineSplitter splitter(*stream);splitter;++splitter) {
-
- // add all chunks to be recognized here. /else ../ omitted intentionally.
- if (splitter.match_start("PolH ")) {
- ReadChunkInfo_Ascii(ci,splitter);
- ReadPolH_Ascii(out,splitter,ci);
- }
- if (splitter.match_start("BitM ")) {
- ReadChunkInfo_Ascii(ci,splitter);
- ReadBitM_Ascii(out,splitter,ci);
- }
- if (splitter.match_start("Mat1 ")) {
- ReadChunkInfo_Ascii(ci,splitter);
- ReadMat1_Ascii(out,splitter,ci);
- }
- if (splitter.match_start("Grou ")) {
- ReadChunkInfo_Ascii(ci,splitter);
- ReadGrou_Ascii(out,splitter,ci);
- }
- if (splitter.match_start("Lght ")) {
- ReadChunkInfo_Ascii(ci,splitter);
- ReadLght_Ascii(out,splitter,ci);
- }
- if (splitter.match_start("Came ")) {
- ReadChunkInfo_Ascii(ci,splitter);
- ReadCame_Ascii(out,splitter,ci);
- }
- if (splitter.match_start("Bone ")) {
- ReadChunkInfo_Ascii(ci,splitter);
- ReadBone_Ascii(out,splitter,ci);
- }
- if (splitter.match_start("Chan ")) {
- ReadChunkInfo_Ascii(ci,splitter);
- ReadChan_Ascii(out,splitter,ci);
- }
- if (splitter.match_start("Unit ")) {
- ReadChunkInfo_Ascii(ci,splitter);
- ReadUnit_Ascii(out,splitter,ci);
- }
- if (splitter.match_start("END ")) {
- // we don't need this, but I guess there is a reason this
- // chunk has been implemented into COB for.
- return;
- }
- }
+ ChunkInfo ci;
+ for(LineSplitter splitter(*stream);splitter;++splitter) {
+
+ // add all chunks to be recognized here. /else ../ omitted intentionally.
+ if (splitter.match_start("PolH ")) {
+ ReadChunkInfo_Ascii(ci,splitter);
+ ReadPolH_Ascii(out,splitter,ci);
+ }
+ if (splitter.match_start("BitM ")) {
+ ReadChunkInfo_Ascii(ci,splitter);
+ ReadBitM_Ascii(out,splitter,ci);
+ }
+ if (splitter.match_start("Mat1 ")) {
+ ReadChunkInfo_Ascii(ci,splitter);
+ ReadMat1_Ascii(out,splitter,ci);
+ }
+ if (splitter.match_start("Grou ")) {
+ ReadChunkInfo_Ascii(ci,splitter);
+ ReadGrou_Ascii(out,splitter,ci);
+ }
+ if (splitter.match_start("Lght ")) {
+ ReadChunkInfo_Ascii(ci,splitter);
+ ReadLght_Ascii(out,splitter,ci);
+ }
+ if (splitter.match_start("Came ")) {
+ ReadChunkInfo_Ascii(ci,splitter);
+ ReadCame_Ascii(out,splitter,ci);
+ }
+ if (splitter.match_start("Bone ")) {
+ ReadChunkInfo_Ascii(ci,splitter);
+ ReadBone_Ascii(out,splitter,ci);
+ }
+ if (splitter.match_start("Chan ")) {
+ ReadChunkInfo_Ascii(ci,splitter);
+ ReadChan_Ascii(out,splitter,ci);
+ }
+ if (splitter.match_start("Unit ")) {
+ ReadChunkInfo_Ascii(ci,splitter);
+ ReadUnit_Ascii(out,splitter,ci);
+ }
+ if (splitter.match_start("END ")) {
+ // we don't need this, but I guess there is a reason this
+ // chunk has been implemented into COB for.
+ return;
+ }
+ }
}
// ------------------------------------------------------------------------------------------------
void COBImporter::ReadChunkInfo_Ascii(ChunkInfo& out, const LineSplitter& splitter)
{
- const char* all_tokens[8];
- splitter.get_tokens(all_tokens);
+ const char* all_tokens[8];
+ splitter.get_tokens(all_tokens);
- out.version = (all_tokens[1][1]-'0')*100+(all_tokens[1][3]-'0')*10+(all_tokens[1][4]-'0');
- out.id = strtoul10(all_tokens[3]);
- out.parent_id = strtoul10(all_tokens[5]);
- out.size = strtol10(all_tokens[7]);
+ out.version = (all_tokens[1][1]-'0')*100+(all_tokens[1][3]-'0')*10+(all_tokens[1][4]-'0');
+ out.id = strtoul10(all_tokens[3]);
+ out.parent_id = strtoul10(all_tokens[5]);
+ out.size = strtol10(all_tokens[7]);
}
// ------------------------------------------------------------------------------------------------
void COBImporter::UnsupportedChunk_Ascii(LineSplitter& splitter, const ChunkInfo& nfo, const char* name)
{
- const std::string error = format("Encountered unsupported chunk: ") << name <<
- " [version: "<<nfo.version<<", size: "<<nfo.size<<"]";
-
- // we can recover if the chunk size was specified.
- if(nfo.size != static_cast<unsigned int>(-1)) {
- DefaultLogger::get()->error(error);
-
- // (HACK) - our current position in the stream is the beginning of the
- // head line of the next chunk. That's fine, but the caller is going
- // to call ++ on `splitter`, which we need to swallow to avoid
- // missing the next line.
- splitter.get_stream().IncPtr(nfo.size);
- splitter.swallow_next_increment();
- }
- else ThrowException(error);
+ const std::string error = format("Encountered unsupported chunk: ") << name <<
+ " [version: "<<nfo.version<<", size: "<<nfo.size<<"]";
+
+ // we can recover if the chunk size was specified.
+ if(nfo.size != static_cast<unsigned int>(-1)) {
+ DefaultLogger::get()->error(error);
+
+ // (HACK) - our current position in the stream is the beginning of the
+ // head line of the next chunk. That's fine, but the caller is going
+ // to call ++ on `splitter`, which we need to swallow to avoid
+ // missing the next line.
+ splitter.get_stream().IncPtr(nfo.size);
+ splitter.swallow_next_increment();
+ }
+ else ThrowException(error);
}
// ------------------------------------------------------------------------------------------------
-void COBImporter::LogWarn_Ascii(const LineSplitter& splitter, const format& message) {
- LogWarn_Ascii(message << " [at line "<< splitter.get_index()<<"]");
+void COBImporter::LogWarn_Ascii(const LineSplitter& splitter, const format& message) {
+ LogWarn_Ascii(message << " [at line "<< splitter.get_index()<<"]");
}
// ------------------------------------------------------------------------------------------------
-void COBImporter::LogError_Ascii(const LineSplitter& splitter, const format& message) {
- LogError_Ascii(message << " [at line "<< splitter.get_index()<<"]");
+void COBImporter::LogError_Ascii(const LineSplitter& splitter, const format& message) {
+ LogError_Ascii(message << " [at line "<< splitter.get_index()<<"]");
}
// ------------------------------------------------------------------------------------------------
-void COBImporter::LogInfo_Ascii(const LineSplitter& splitter, const format& message) {
- LogInfo_Ascii(message << " [at line "<< splitter.get_index()<<"]");
+void COBImporter::LogInfo_Ascii(const LineSplitter& splitter, const format& message) {
+ LogInfo_Ascii(message << " [at line "<< splitter.get_index()<<"]");
}
// ------------------------------------------------------------------------------------------------
-void COBImporter::LogDebug_Ascii(const LineSplitter& splitter, const format& message) {
- LogDebug_Ascii(message << " [at line "<< splitter.get_index()<<"]");
+void COBImporter::LogDebug_Ascii(const LineSplitter& splitter, const format& message) {
+ LogDebug_Ascii(message << " [at line "<< splitter.get_index()<<"]");
}
// ------------------------------------------------------------------------------------------------
-void COBImporter::LogWarn_Ascii(const Formatter::format& message) {
- DefaultLogger::get()->warn(std::string("COB: ")+=message);
+void COBImporter::LogWarn_Ascii(const Formatter::format& message) {
+ DefaultLogger::get()->warn(std::string("COB: ")+=message);
}
// ------------------------------------------------------------------------------------------------
-void COBImporter::LogError_Ascii(const Formatter::format& message) {
- DefaultLogger::get()->error(std::string("COB: ")+=message);
+void COBImporter::LogError_Ascii(const Formatter::format& message) {
+ DefaultLogger::get()->error(std::string("COB: ")+=message);
}
// ------------------------------------------------------------------------------------------------
-void COBImporter::LogInfo_Ascii(const Formatter::format& message) {
- DefaultLogger::get()->info(std::string("COB: ")+=message);
+void COBImporter::LogInfo_Ascii(const Formatter::format& message) {
+ DefaultLogger::get()->info(std::string("COB: ")+=message);
}
// ------------------------------------------------------------------------------------------------
-void COBImporter::LogDebug_Ascii(const Formatter::format& message) {
- DefaultLogger::get()->debug(std::string("COB: ")+=message);
+void COBImporter::LogDebug_Ascii(const Formatter::format& message) {
+ DefaultLogger::get()->debug(std::string("COB: ")+=message);
}
// ------------------------------------------------------------------------------------------------
void COBImporter::ReadBasicNodeInfo_Ascii(Node& msh, LineSplitter& splitter, const ChunkInfo& /*nfo*/)
{
- for(;splitter;++splitter) {
- if (splitter.match_start("Name")) {
- msh.name = std::string(splitter[1]);
-
- // make nice names by merging the dupe count
- std::replace(msh.name.begin(),msh.name.end(),
- ',','_');
- }
- else if (splitter.match_start("Transform")) {
- for(unsigned int y = 0; y < 4 && ++splitter; ++y) {
- const char* s = splitter->c_str();
- for(unsigned int x = 0; x < 4; ++x) {
- SkipSpaces(&s);
- msh.transform[y][x] = fast_atof(&s);
- }
- }
- // we need the transform chunk, so we won't return until we have it.
- return;
- }
- }
+ for(;splitter;++splitter) {
+ if (splitter.match_start("Name")) {
+ msh.name = std::string(splitter[1]);
+
+ // make nice names by merging the dupe count
+ std::replace(msh.name.begin(),msh.name.end(),
+ ',','_');
+ }
+ else if (splitter.match_start("Transform")) {
+ for(unsigned int y = 0; y < 4 && ++splitter; ++y) {
+ const char* s = splitter->c_str();
+ for(unsigned int x = 0; x < 4; ++x) {
+ SkipSpaces(&s);
+ msh.transform[y][x] = fast_atof(&s);
+ }
+ }
+ // we need the transform chunk, so we won't return until we have it.
+ return;
+ }
+ }
}
// ------------------------------------------------------------------------------------------------
template <typename T>
-void COBImporter::ReadFloat3Tuple_Ascii(T& fill, const char** in)
+void COBImporter::ReadFloat3Tuple_Ascii(T& fill, const char** in)
{
- const char* rgb = *in;
- for(unsigned int i = 0; i < 3; ++i) {
- SkipSpaces(&rgb);
- if (*rgb == ',')++rgb;
- SkipSpaces(&rgb);
-
- fill[i] = fast_atof(&rgb);
- }
- *in = rgb;
+ const char* rgb = *in;
+ for(unsigned int i = 0; i < 3; ++i) {
+ SkipSpaces(&rgb);
+ if (*rgb == ',')++rgb;
+ SkipSpaces(&rgb);
+
+ fill[i] = fast_atof(&rgb);
+ }
+ *in = rgb;
}
// ------------------------------------------------------------------------------------------------
void COBImporter::ReadMat1_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
{
- if(nfo.version > 8) {
- return UnsupportedChunk_Ascii(splitter,nfo,"Mat1");
- }
-
- ++splitter;
- if (!splitter.match_start("mat# ")) {
- LogWarn_Ascii(splitter,format()<<
- "Expected `mat#` line in `Mat1` chunk "<<nfo.id);
- return;
- }
-
- out.materials.push_back(Material());
- Material& mat = out.materials.back();
- mat = nfo;
-
- mat.matnum = strtoul10(splitter[1]);
- ++splitter;
-
- if (!splitter.match_start("shader: ")) {
- LogWarn_Ascii(splitter,format()<<
- "Expected `mat#` line in `Mat1` chunk "<<nfo.id);
- return;
- }
- std::string shader = std::string(splitter[1]);
- shader = shader.substr(0,shader.find_first_of(" \t"));
-
- if (shader == "metal") {
- mat.shader = Material::METAL;
- }
- else if (shader == "phong") {
- mat.shader = Material::PHONG;
- }
- else if (shader != "flat") {
- LogWarn_Ascii(splitter,format()<<
- "Unknown value for `shader` in `Mat1` chunk "<<nfo.id);
- }
-
- ++splitter;
- if (!splitter.match_start("rgb ")) {
- LogWarn_Ascii(splitter,format()<<
- "Expected `rgb` line in `Mat1` chunk "<<nfo.id);
- }
-
- const char* rgb = splitter[1];
- ReadFloat3Tuple_Ascii(mat.rgb,&rgb);
-
- ++splitter;
- if (!splitter.match_start("alpha ")) {
- LogWarn_Ascii(splitter,format()<<
- "Expected `alpha` line in `Mat1` chunk "<<nfo.id);
- }
-
- const char* tokens[10];
- splitter.get_tokens(tokens);
-
- mat.alpha = fast_atof( tokens[1] );
- mat.ka = fast_atof( tokens[3] );
- mat.ks = fast_atof( tokens[5] );
- mat.exp = fast_atof( tokens[7] );
- mat.ior = fast_atof( tokens[9] );
+ if(nfo.version > 8) {
+ return UnsupportedChunk_Ascii(splitter,nfo,"Mat1");
+ }
+
+ ++splitter;
+ if (!splitter.match_start("mat# ")) {
+ LogWarn_Ascii(splitter,format()<<
+ "Expected `mat#` line in `Mat1` chunk "<<nfo.id);
+ return;
+ }
+
+ out.materials.push_back(Material());
+ Material& mat = out.materials.back();
+ mat = nfo;
+
+ mat.matnum = strtoul10(splitter[1]);
+ ++splitter;
+
+ if (!splitter.match_start("shader: ")) {
+ LogWarn_Ascii(splitter,format()<<
+ "Expected `mat#` line in `Mat1` chunk "<<nfo.id);
+ return;
+ }
+ std::string shader = std::string(splitter[1]);
+ shader = shader.substr(0,shader.find_first_of(" \t"));
+
+ if (shader == "metal") {
+ mat.shader = Material::METAL;
+ }
+ else if (shader == "phong") {
+ mat.shader = Material::PHONG;
+ }
+ else if (shader != "flat") {
+ LogWarn_Ascii(splitter,format()<<
+ "Unknown value for `shader` in `Mat1` chunk "<<nfo.id);
+ }
+
+ ++splitter;
+ if (!splitter.match_start("rgb ")) {
+ LogWarn_Ascii(splitter,format()<<
+ "Expected `rgb` line in `Mat1` chunk "<<nfo.id);
+ }
+
+ const char* rgb = splitter[1];
+ ReadFloat3Tuple_Ascii(mat.rgb,&rgb);
+
+ ++splitter;
+ if (!splitter.match_start("alpha ")) {
+ LogWarn_Ascii(splitter,format()<<
+ "Expected `alpha` line in `Mat1` chunk "<<nfo.id);
+ }
+
+ const char* tokens[10];
+ splitter.get_tokens(tokens);
+
+ mat.alpha = fast_atof( tokens[1] );
+ mat.ka = fast_atof( tokens[3] );
+ mat.ks = fast_atof( tokens[5] );
+ mat.exp = fast_atof( tokens[7] );
+ mat.ior = fast_atof( tokens[9] );
}
// ------------------------------------------------------------------------------------------------
void COBImporter::ReadUnit_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
{
- if(nfo.version > 1) {
- return UnsupportedChunk_Ascii(splitter,nfo,"Unit");
- }
- ++splitter;
- if (!splitter.match_start("Units ")) {
- LogWarn_Ascii(splitter,format()<<
- "Expected `Units` line in `Unit` chunk "<<nfo.id);
- return;
- }
-
- // parent chunks preceede their childs, so we should have the
- // corresponding chunk already.
- for_each(boost::shared_ptr< Node >& nd, out.nodes) {
- if (nd->id == nfo.parent_id) {
- const unsigned int t=strtoul10(splitter[1]);
-
- nd->unit_scale = t>=sizeof(units)/sizeof(units[0])?(
- LogWarn_Ascii(splitter,format()<<t<<" is not a valid value for `Units` attribute in `Unit chunk` "<<nfo.id)
- ,1.f):units[t];
- return;
- }
- }
- LogWarn_Ascii(splitter,format()<<"`Unit` chunk "<<nfo.id<<" is a child of "
- <<nfo.parent_id<<" which does not exist");
+ if(nfo.version > 1) {
+ return UnsupportedChunk_Ascii(splitter,nfo,"Unit");
+ }
+ ++splitter;
+ if (!splitter.match_start("Units ")) {
+ LogWarn_Ascii(splitter,format()<<
+ "Expected `Units` line in `Unit` chunk "<<nfo.id);
+ return;
+ }
+
+ // parent chunks preceede their childs, so we should have the
+ // corresponding chunk already.
+ for(std::shared_ptr< Node >& nd : out.nodes) {
+ if (nd->id == nfo.parent_id) {
+ const unsigned int t=strtoul10(splitter[1]);
+
+ nd->unit_scale = t>=sizeof(units)/sizeof(units[0])?(
+ LogWarn_Ascii(splitter,format()<<t<<" is not a valid value for `Units` attribute in `Unit chunk` "<<nfo.id)
+ ,1.f):units[t];
+ return;
+ }
+ }
+ LogWarn_Ascii(splitter,format()<<"`Unit` chunk "<<nfo.id<<" is a child of "
+ <<nfo.parent_id<<" which does not exist");
}
// ------------------------------------------------------------------------------------------------
void COBImporter::ReadChan_Ascii(Scene& /*out*/, LineSplitter& splitter, const ChunkInfo& nfo)
{
- if(nfo.version > 8) {
- return UnsupportedChunk_Ascii(splitter,nfo,"Chan");
- }
+ if(nfo.version > 8) {
+ return UnsupportedChunk_Ascii(splitter,nfo,"Chan");
+ }
}
// ------------------------------------------------------------------------------------------------
void COBImporter::ReadLght_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
{
- if(nfo.version > 8) {
- return UnsupportedChunk_Ascii(splitter,nfo,"Lght");
- }
-
- out.nodes.push_back(boost::shared_ptr<Light>(new Light()));
- Light& msh = (Light&)(*out.nodes.back().get());
- msh = nfo;
-
- ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);
-
- if (splitter.match_start("Infinite ")) {
- msh.ltype = Light::INFINITE;
- }
- else if (splitter.match_start("Local ")) {
- msh.ltype = Light::LOCAL;
- }
- else if (splitter.match_start("Spot ")) {
- msh.ltype = Light::SPOT;
- }
- else {
- LogWarn_Ascii(splitter,format()<<
- "Unknown kind of light source in `Lght` chunk "<<nfo.id<<" : "<<*splitter);
- msh.ltype = Light::SPOT;
- }
-
- ++splitter;
- if (!splitter.match_start("color ")) {
- LogWarn_Ascii(splitter,format()<<
- "Expected `color` line in `Lght` chunk "<<nfo.id);
- }
-
- const char* rgb = splitter[1];
- ReadFloat3Tuple_Ascii(msh.color ,&rgb);
-
- SkipSpaces(&rgb);
- if (strncmp(rgb,"cone angle",10)) {
- LogWarn_Ascii(splitter,format()<<
- "Expected `cone angle` entity in `color` line in `Lght` chunk "<<nfo.id);
- }
- SkipSpaces(rgb+10,&rgb);
- msh.angle = fast_atof(&rgb);
-
- SkipSpaces(&rgb);
- if (strncmp(rgb,"inner angle",11)) {
- LogWarn_Ascii(splitter,format()<<
- "Expected `inner angle` entity in `color` line in `Lght` chunk "<<nfo.id);
- }
- SkipSpaces(rgb+11,&rgb);
- msh.inner_angle = fast_atof(&rgb);
-
- // skip the rest for we can't handle this kind of physically-based lighting information.
+ if(nfo.version > 8) {
+ return UnsupportedChunk_Ascii(splitter,nfo,"Lght");
+ }
+
+ out.nodes.push_back(std::shared_ptr<Light>(new Light()));
+ Light& msh = (Light&)(*out.nodes.back().get());
+ msh = nfo;
+
+ ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);
+
+ if (splitter.match_start("Infinite ")) {
+ msh.ltype = Light::INFINITE;
+ }
+ else if (splitter.match_start("Local ")) {
+ msh.ltype = Light::LOCAL;
+ }
+ else if (splitter.match_start("Spot ")) {
+ msh.ltype = Light::SPOT;
+ }
+ else {
+ LogWarn_Ascii(splitter,format()<<
+ "Unknown kind of light source in `Lght` chunk "<<nfo.id<<" : "<<*splitter);
+ msh.ltype = Light::SPOT;
+ }
+
+ ++splitter;
+ if (!splitter.match_start("color ")) {
+ LogWarn_Ascii(splitter,format()<<
+ "Expected `color` line in `Lght` chunk "<<nfo.id);
+ }
+
+ const char* rgb = splitter[1];
+ ReadFloat3Tuple_Ascii(msh.color ,&rgb);
+
+ SkipSpaces(&rgb);
+ if (strncmp(rgb,"cone angle",10)) {
+ LogWarn_Ascii(splitter,format()<<
+ "Expected `cone angle` entity in `color` line in `Lght` chunk "<<nfo.id);
+ }
+ SkipSpaces(rgb+10,&rgb);
+ msh.angle = fast_atof(&rgb);
+
+ SkipSpaces(&rgb);
+ if (strncmp(rgb,"inner angle",11)) {
+ LogWarn_Ascii(splitter,format()<<
+ "Expected `inner angle` entity in `color` line in `Lght` chunk "<<nfo.id);
+ }
+ SkipSpaces(rgb+11,&rgb);
+ msh.inner_angle = fast_atof(&rgb);
+
+ // skip the rest for we can't handle this kind of physically-based lighting information.
}
// ------------------------------------------------------------------------------------------------
void COBImporter::ReadCame_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
{
- if(nfo.version > 2) {
- return UnsupportedChunk_Ascii(splitter,nfo,"Came");
- }
+ if(nfo.version > 2) {
+ return UnsupportedChunk_Ascii(splitter,nfo,"Came");
+ }
- out.nodes.push_back(boost::shared_ptr<Camera>(new Camera()));
- Camera& msh = (Camera&)(*out.nodes.back().get());
- msh = nfo;
+ out.nodes.push_back(std::shared_ptr<Camera>(new Camera()));
+ Camera& msh = (Camera&)(*out.nodes.back().get());
+ msh = nfo;
- ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);
+ ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);
- // skip the next line, we don't know this differenciation between a
- // standard camera and a panoramic camera.
- ++splitter;
+ // skip the next line, we don't know this differenciation between a
+ // standard camera and a panoramic camera.
+ ++splitter;
}
// ------------------------------------------------------------------------------------------------
void COBImporter::ReadBone_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
{
- if(nfo.version > 5) {
- return UnsupportedChunk_Ascii(splitter,nfo,"Bone");
- }
+ if(nfo.version > 5) {
+ return UnsupportedChunk_Ascii(splitter,nfo,"Bone");
+ }
- out.nodes.push_back(boost::shared_ptr<Bone>(new Bone()));
- Bone& msh = (Bone&)(*out.nodes.back().get());
- msh = nfo;
+ out.nodes.push_back(std::shared_ptr<Bone>(new Bone()));
+ Bone& msh = (Bone&)(*out.nodes.back().get());
+ msh = nfo;
- ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);
+ ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);
- // TODO
+ // TODO
}
// ------------------------------------------------------------------------------------------------
void COBImporter::ReadGrou_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
{
- if(nfo.version > 1) {
- return UnsupportedChunk_Ascii(splitter,nfo,"Grou");
- }
+ if(nfo.version > 1) {
+ return UnsupportedChunk_Ascii(splitter,nfo,"Grou");
+ }
- out.nodes.push_back(boost::shared_ptr<Group>(new Group()));
- Group& msh = (Group&)(*out.nodes.back().get());
- msh = nfo;
+ out.nodes.push_back(std::shared_ptr<Group>(new Group()));
+ Group& msh = (Group&)(*out.nodes.back().get());
+ msh = nfo;
- ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);
+ ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);
}
// ------------------------------------------------------------------------------------------------
void COBImporter::ReadPolH_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
{
- if(nfo.version > 8) {
- return UnsupportedChunk_Ascii(splitter,nfo,"PolH");
- }
-
- out.nodes.push_back(boost::shared_ptr<Mesh>(new Mesh()));
- Mesh& msh = (Mesh&)(*out.nodes.back().get());
- msh = nfo;
-
- ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);
-
- // the chunk has a fixed order of components, but some are not interesting of us so
- // we're just looking for keywords in arbitrary order. The end of the chunk is
- // either the last `Face` or the `DrawFlags` attribute, depending on the format ver.
- for(;splitter;++splitter) {
- if (splitter.match_start("World Vertices")) {
- const unsigned int cnt = strtoul10(splitter[2]);
- msh.vertex_positions.resize(cnt);
-
- for(unsigned int cur = 0;cur < cnt && ++splitter;++cur) {
- const char* s = splitter->c_str();
-
- aiVector3D& v = msh.vertex_positions[cur];
-
- SkipSpaces(&s);
- v.x = fast_atof(&s);
- SkipSpaces(&s);
- v.y = fast_atof(&s);
- SkipSpaces(&s);
- v.z = fast_atof(&s);
- }
- }
- else if (splitter.match_start("Texture Vertices")) {
- const unsigned int cnt = strtoul10(splitter[2]);
- msh.texture_coords.resize(cnt);
-
- for(unsigned int cur = 0;cur < cnt && ++splitter;++cur) {
- const char* s = splitter->c_str();
-
- aiVector2D& v = msh.texture_coords[cur];
-
- SkipSpaces(&s);
- v.x = fast_atof(&s);
- SkipSpaces(&s);
- v.y = fast_atof(&s);
- }
- }
- else if (splitter.match_start("Faces")) {
- const unsigned int cnt = strtoul10(splitter[1]);
- msh.faces.reserve(cnt);
-
- for(unsigned int cur = 0; cur < cnt && ++splitter ;++cur) {
- if (splitter.match_start("Hole")) {
- LogWarn_Ascii(splitter,"Skipping unsupported `Hole` line");
- continue;
- }
-
- if (!splitter.match_start("Face")) {
- ThrowException("Expected Face line");
- }
-
- msh.faces.push_back(Face());
- Face& face = msh.faces.back();
-
- face.indices.resize(strtoul10(splitter[2]));
- face.flags = strtoul10(splitter[4]);
- face.material = strtoul10(splitter[6]);
-
- const char* s = (++splitter)->c_str();
- for(size_t i = 0; i < face.indices.size(); ++i) {
- if(!SkipSpaces(&s)) {
- ThrowException("Expected EOL token in Face entry");
- }
- if ('<' != *s++) {
- ThrowException("Expected < token in Face entry");
- }
- face.indices[i].pos_idx = strtoul10(s,&s);
- if (',' != *s++) {
- ThrowException("Expected , token in Face entry");
- }
- face.indices[i].uv_idx = strtoul10(s,&s);
- if ('>' != *s++) {
- ThrowException("Expected < token in Face entry");
- }
- }
- }
- if (nfo.version <= 4) {
- break;
- }
- }
- else if (splitter.match_start("DrawFlags")) {
- msh.draw_flags = strtoul10(splitter[1]);
- break;
- }
- }
+ if(nfo.version > 8) {
+ return UnsupportedChunk_Ascii(splitter,nfo,"PolH");
+ }
+
+ out.nodes.push_back(std::shared_ptr<Mesh>(new Mesh()));
+ Mesh& msh = (Mesh&)(*out.nodes.back().get());
+ msh = nfo;
+
+ ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);
+
+ // the chunk has a fixed order of components, but some are not interesting of us so
+ // we're just looking for keywords in arbitrary order. The end of the chunk is
+ // either the last `Face` or the `DrawFlags` attribute, depending on the format ver.
+ for(;splitter;++splitter) {
+ if (splitter.match_start("World Vertices")) {
+ const unsigned int cnt = strtoul10(splitter[2]);
+ msh.vertex_positions.resize(cnt);
+
+ for(unsigned int cur = 0;cur < cnt && ++splitter;++cur) {
+ const char* s = splitter->c_str();
+
+ aiVector3D& v = msh.vertex_positions[cur];
+
+ SkipSpaces(&s);
+ v.x = fast_atof(&s);
+ SkipSpaces(&s);
+ v.y = fast_atof(&s);
+ SkipSpaces(&s);
+ v.z = fast_atof(&s);
+ }
+ }
+ else if (splitter.match_start("Texture Vertices")) {
+ const unsigned int cnt = strtoul10(splitter[2]);
+ msh.texture_coords.resize(cnt);
+
+ for(unsigned int cur = 0;cur < cnt && ++splitter;++cur) {
+ const char* s = splitter->c_str();
+
+ aiVector2D& v = msh.texture_coords[cur];
+
+ SkipSpaces(&s);
+ v.x = fast_atof(&s);
+ SkipSpaces(&s);
+ v.y = fast_atof(&s);
+ }
+ }
+ else if (splitter.match_start("Faces")) {
+ const unsigned int cnt = strtoul10(splitter[1]);
+ msh.faces.reserve(cnt);
+
+ for(unsigned int cur = 0; cur < cnt && ++splitter ;++cur) {
+ if (splitter.match_start("Hole")) {
+ LogWarn_Ascii(splitter,"Skipping unsupported `Hole` line");
+ continue;
+ }
+
+ if (!splitter.match_start("Face")) {
+ ThrowException("Expected Face line");
+ }
+
+ msh.faces.push_back(Face());
+ Face& face = msh.faces.back();
+
+ face.indices.resize(strtoul10(splitter[2]));
+ face.flags = strtoul10(splitter[4]);
+ face.material = strtoul10(splitter[6]);
+
+ const char* s = (++splitter)->c_str();
+ for(size_t i = 0; i < face.indices.size(); ++i) {
+ if(!SkipSpaces(&s)) {
+ ThrowException("Expected EOL token in Face entry");
+ }
+ if ('<' != *s++) {
+ ThrowException("Expected < token in Face entry");
+ }
+ face.indices[i].pos_idx = strtoul10(s,&s);
+ if (',' != *s++) {
+ ThrowException("Expected , token in Face entry");
+ }
+ face.indices[i].uv_idx = strtoul10(s,&s);
+ if ('>' != *s++) {
+ ThrowException("Expected < token in Face entry");
+ }
+ }
+ }
+ if (nfo.version <= 4) {
+ break;
+ }
+ }
+ else if (splitter.match_start("DrawFlags")) {
+ msh.draw_flags = strtoul10(splitter[1]);
+ break;
+ }
+ }
}
// ------------------------------------------------------------------------------------------------
void COBImporter::ReadBitM_Ascii(Scene& /*out*/, LineSplitter& splitter, const ChunkInfo& nfo)
{
- if(nfo.version > 1) {
- return UnsupportedChunk_Ascii(splitter,nfo,"BitM");
- }
+ if(nfo.version > 1) {
+ return UnsupportedChunk_Ascii(splitter,nfo,"BitM");
+ }
/*
- "\nThumbNailHdrSize %ld"
- "\nThumbHeader: %02hx 02hx %02hx "
- "\nColorBufSize %ld"
- "\nColorBufZipSize %ld"
- "\nZippedThumbnail: %02hx 02hx %02hx "
+ "\nThumbNailHdrSize %ld"
+ "\nThumbHeader: %02hx 02hx %02hx "
+ "\nColorBufSize %ld"
+ "\nColorBufZipSize %ld"
+ "\nZippedThumbnail: %02hx 02hx %02hx "
*/
- const unsigned int head = strtoul10((++splitter)[1]);
- if (head != sizeof(Bitmap::BitmapHeader)) {
- LogWarn_Ascii(splitter,"Unexpected ThumbNailHdrSize, skipping this chunk");
- return;
- }
-
- /*union {
- Bitmap::BitmapHeader data;
- char opaq[sizeof Bitmap::BitmapHeader()];
- };*/
-// ReadHexOctets(opaq,head,(++splitter)[1]);
+ const unsigned int head = strtoul10((++splitter)[1]);
+ if (head != sizeof(Bitmap::BitmapHeader)) {
+ LogWarn_Ascii(splitter,"Unexpected ThumbNailHdrSize, skipping this chunk");
+ return;
+ }
+
+ /*union {
+ Bitmap::BitmapHeader data;
+ char opaq[sizeof Bitmap::BitmapHeader()];
+ };*/
+// ReadHexOctets(opaq,head,(++splitter)[1]);
}
// ------------------------------------------------------------------------------------------------
void COBImporter::ReadString_Binary(std::string& out, StreamReaderLE& reader)
{
- out.resize( reader.GetI2());
- for_each(char& c,out) {
- c = reader.GetI1();
- }
+ out.resize( reader.GetI2());
+ for(char& c : out) {
+ c = reader.GetI1();
+ }
}
// ------------------------------------------------------------------------------------------------
void COBImporter::ReadBasicNodeInfo_Binary(Node& msh, StreamReaderLE& reader, const ChunkInfo& /*nfo*/)
{
- const unsigned int dupes = reader.GetI2();
- ReadString_Binary(msh.name,reader);
+ const unsigned int dupes = reader.GetI2();
+ ReadString_Binary(msh.name,reader);
- msh.name = format(msh.name)<<'_'<<dupes;
+ msh.name = format(msh.name)<<'_'<<dupes;
- // skip local axes for the moment
- reader.IncPtr(48);
+ // skip local axes for the moment
+ reader.IncPtr(48);
- msh.transform = aiMatrix4x4();
- for(unsigned int y = 0; y < 3; ++y) {
- for(unsigned int x =0; x < 4; ++x) {
- msh.transform[y][x] = reader.GetF4();
- }
- }
+ msh.transform = aiMatrix4x4();
+ for(unsigned int y = 0; y < 3; ++y) {
+ for(unsigned int x =0; x < 4; ++x) {
+ msh.transform[y][x] = reader.GetF4();
+ }
+ }
}
// ------------------------------------------------------------------------------------------------
void COBImporter::UnsupportedChunk_Binary( StreamReaderLE& reader, const ChunkInfo& nfo, const char* name)
{
- const std::string error = format("Encountered unsupported chunk: ") << name <<
- " [version: "<<nfo.version<<", size: "<<nfo.size<<"]";
-
- // we can recover if the chunk size was specified.
- if(nfo.size != static_cast<unsigned int>(-1)) {
- DefaultLogger::get()->error(error);
- reader.IncPtr(nfo.size);
- }
- else ThrowException(error);
+ const std::string error = format("Encountered unsupported chunk: ") << name <<
+ " [version: "<<nfo.version<<", size: "<<nfo.size<<"]";
+
+ // we can recover if the chunk size was specified.
+ if(nfo.size != static_cast<unsigned int>(-1)) {
+ DefaultLogger::get()->error(error);
+ reader.IncPtr(nfo.size);
+ }
+ else ThrowException(error);
}
// ------------------------------------------------------------------------------------------------
@@ -937,354 +944,354 @@ class chunk_guard {
public:
- chunk_guard(const COB::ChunkInfo& nfo, StreamReaderLE& reader)
- : nfo(nfo)
- , reader(reader)
- , cur(reader.GetCurrentPos())
- {
- }
+ chunk_guard(const COB::ChunkInfo& nfo, StreamReaderLE& reader)
+ : nfo(nfo)
+ , reader(reader)
+ , cur(reader.GetCurrentPos())
+ {
+ }
- ~chunk_guard() {
- // don't do anything if the size is not given
- if(nfo.size != static_cast<unsigned int>(-1)) {
- reader.IncPtr(static_cast<int>(nfo.size)-reader.GetCurrentPos()+cur);
- }
- }
+ ~chunk_guard() {
+ // don't do anything if the size is not given
+ if(nfo.size != static_cast<unsigned int>(-1)) {
+ reader.IncPtr(static_cast<int>(nfo.size)-reader.GetCurrentPos()+cur);
+ }
+ }
private:
- const COB::ChunkInfo& nfo;
- StreamReaderLE& reader;
- long cur;
+ const COB::ChunkInfo& nfo;
+ StreamReaderLE& reader;
+ long cur;
};
// ------------------------------------------------------------------------------------------------
void COBImporter::ReadBinaryFile(Scene& out, StreamReaderLE* reader)
{
- while(1) {
- std::string type;
- type += reader -> GetI1()
- ,type += reader -> GetI1()
- ,type += reader -> GetI1()
- ,type += reader -> GetI1()
- ;
-
- ChunkInfo nfo;
- nfo.version = reader -> GetI2()*10;
- nfo.version += reader -> GetI2();
-
- nfo.id = reader->GetI4();
- nfo.parent_id = reader->GetI4();
- nfo.size = reader->GetI4();
-
- if (type == "PolH") {
- ReadPolH_Binary(out,*reader,nfo);
- }
- else if (type == "BitM") {
- ReadBitM_Binary(out,*reader,nfo);
- }
- else if (type == "Grou") {
- ReadGrou_Binary(out,*reader,nfo);
- }
- else if (type == "Lght") {
- ReadLght_Binary(out,*reader,nfo);
- }
- else if (type == "Came") {
- ReadCame_Binary(out,*reader,nfo);
- }
- else if (type == "Mat1") {
- ReadMat1_Binary(out,*reader,nfo);
- }
- /* else if (type == "Bone") {
- ReadBone_Binary(out,*reader,nfo);
- }
- else if (type == "Chan") {
- ReadChan_Binary(out,*reader,nfo);
- }*/
- else if (type == "Unit") {
- ReadUnit_Binary(out,*reader,nfo);
- }
- else if (type == "OLay") {
- // ignore layer index silently.
- if(nfo.size != static_cast<unsigned int>(-1) ) {
- reader->IncPtr(nfo.size);
- }
- else return UnsupportedChunk_Binary(*reader,nfo,type.c_str());
- }
- else if (type == "END ") {
- return;
- }
- else UnsupportedChunk_Binary(*reader,nfo,type.c_str());
- }
+ while(1) {
+ std::string type;
+ type += reader -> GetI1()
+ ,type += reader -> GetI1()
+ ,type += reader -> GetI1()
+ ,type += reader -> GetI1()
+ ;
+
+ ChunkInfo nfo;
+ nfo.version = reader -> GetI2()*10;
+ nfo.version += reader -> GetI2();
+
+ nfo.id = reader->GetI4();
+ nfo.parent_id = reader->GetI4();
+ nfo.size = reader->GetI4();
+
+ if (type == "PolH") {
+ ReadPolH_Binary(out,*reader,nfo);
+ }
+ else if (type == "BitM") {
+ ReadBitM_Binary(out,*reader,nfo);
+ }
+ else if (type == "Grou") {
+ ReadGrou_Binary(out,*reader,nfo);
+ }
+ else if (type == "Lght") {
+ ReadLght_Binary(out,*reader,nfo);
+ }
+ else if (type == "Came") {
+ ReadCame_Binary(out,*reader,nfo);
+ }
+ else if (type == "Mat1") {
+ ReadMat1_Binary(out,*reader,nfo);
+ }
+ /* else if (type == "Bone") {
+ ReadBone_Binary(out,*reader,nfo);
+ }
+ else if (type == "Chan") {
+ ReadChan_Binary(out,*reader,nfo);
+ }*/
+ else if (type == "Unit") {
+ ReadUnit_Binary(out,*reader,nfo);
+ }
+ else if (type == "OLay") {
+ // ignore layer index silently.
+ if(nfo.size != static_cast<unsigned int>(-1) ) {
+ reader->IncPtr(nfo.size);
+ }
+ else return UnsupportedChunk_Binary(*reader,nfo,type.c_str());
+ }
+ else if (type == "END ") {
+ return;
+ }
+ else UnsupportedChunk_Binary(*reader,nfo,type.c_str());
+ }
}
// ------------------------------------------------------------------------------------------------
void COBImporter::ReadPolH_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
{
- if(nfo.version > 8) {
- return UnsupportedChunk_Binary(reader,nfo,"PolH");
- }
- const chunk_guard cn(nfo,reader);
-
- out.nodes.push_back(boost::shared_ptr<Mesh>(new Mesh()));
- Mesh& msh = (Mesh&)(*out.nodes.back().get());
- msh = nfo;
-
- ReadBasicNodeInfo_Binary(msh,reader,nfo);
-
- msh.vertex_positions.resize(reader.GetI4());
- for_each(aiVector3D& v,msh.vertex_positions) {
- v.x = reader.GetF4();
- v.y = reader.GetF4();
- v.z = reader.GetF4();
- }
-
- msh.texture_coords.resize(reader.GetI4());
- for_each(aiVector2D& v,msh.texture_coords) {
- v.x = reader.GetF4();
- v.y = reader.GetF4();
- }
-
- const size_t numf = reader.GetI4();
- msh.faces.reserve(numf);
- for(size_t i = 0; i < numf; ++i) {
- // XXX backface culling flag is 0x10 in flags
-
- // hole?
- bool hole;
- if ((hole = (reader.GetI1() & 0x08) != 0)) {
- // XXX Basically this should just work fine - then triangulator
- // should output properly triangulated data even for polygons
- // with holes. Test data specific to COB is needed to confirm it.
- if (msh.faces.empty()) {
- ThrowException(format("A hole is the first entity in the `PolH` chunk with id ") << nfo.id);
- }
- }
- else msh.faces.push_back(Face());
- Face& f = msh.faces.back();
-
- const size_t num = reader.GetI2();
- f.indices.reserve(f.indices.size() + num);
-
- if(!hole) {
- f.material = reader.GetI2();
- f.flags = 0;
- }
-
- for(size_t x = 0; x < num; ++x) {
- f.indices.push_back(VertexIndex());
-
- VertexIndex& v = f.indices.back();
- v.pos_idx = reader.GetI4();
- v.uv_idx = reader.GetI4();
- }
-
- if(hole) {
- std::reverse(f.indices.rbegin(),f.indices.rbegin()+num);
- }
- }
- if (nfo.version>4) {
- msh.draw_flags = reader.GetI4();
- }
- nfo.version>5 && nfo.version<8 ? reader.GetI4() : 0;
+ if(nfo.version > 8) {
+ return UnsupportedChunk_Binary(reader,nfo,"PolH");
+ }
+ const chunk_guard cn(nfo,reader);
+
+ out.nodes.push_back(std::shared_ptr<Mesh>(new Mesh()));
+ Mesh& msh = (Mesh&)(*out.nodes.back().get());
+ msh = nfo;
+
+ ReadBasicNodeInfo_Binary(msh,reader,nfo);
+
+ msh.vertex_positions.resize(reader.GetI4());
+ for(aiVector3D& v : msh.vertex_positions) {
+ v.x = reader.GetF4();
+ v.y = reader.GetF4();
+ v.z = reader.GetF4();
+ }
+
+ msh.texture_coords.resize(reader.GetI4());
+ for(aiVector2D& v : msh.texture_coords) {
+ v.x = reader.GetF4();
+ v.y = reader.GetF4();
+ }
+
+ const size_t numf = reader.GetI4();
+ msh.faces.reserve(numf);
+ for(size_t i = 0; i < numf; ++i) {
+ // XXX backface culling flag is 0x10 in flags
+
+ // hole?
+ bool hole;
+ if ((hole = (reader.GetI1() & 0x08) != 0)) {
+ // XXX Basically this should just work fine - then triangulator
+ // should output properly triangulated data even for polygons
+ // with holes. Test data specific to COB is needed to confirm it.
+ if (msh.faces.empty()) {
+ ThrowException(format("A hole is the first entity in the `PolH` chunk with id ") << nfo.id);
+ }
+ }
+ else msh.faces.push_back(Face());
+ Face& f = msh.faces.back();
+
+ const size_t num = reader.GetI2();
+ f.indices.reserve(f.indices.size() + num);
+
+ if(!hole) {
+ f.material = reader.GetI2();
+ f.flags = 0;
+ }
+
+ for(size_t x = 0; x < num; ++x) {
+ f.indices.push_back(VertexIndex());
+
+ VertexIndex& v = f.indices.back();
+ v.pos_idx = reader.GetI4();
+ v.uv_idx = reader.GetI4();
+ }
+
+ if(hole) {
+ std::reverse(f.indices.rbegin(),f.indices.rbegin()+num);
+ }
+ }
+ if (nfo.version>4) {
+ msh.draw_flags = reader.GetI4();
+ }
+ nfo.version>5 && nfo.version<8 ? reader.GetI4() : 0;
}
// ------------------------------------------------------------------------------------------------
void COBImporter::ReadBitM_Binary(COB::Scene& /*out*/, StreamReaderLE& reader, const ChunkInfo& nfo)
{
- if(nfo.version > 1) {
- return UnsupportedChunk_Binary(reader,nfo,"BitM");
- }
+ if(nfo.version > 1) {
+ return UnsupportedChunk_Binary(reader,nfo,"BitM");
+ }
- const chunk_guard cn(nfo,reader);
+ const chunk_guard cn(nfo,reader);
- const uint32_t len = reader.GetI4();
- reader.IncPtr(len);
+ const uint32_t len = reader.GetI4();
+ reader.IncPtr(len);
- reader.GetI4();
- reader.IncPtr(reader.GetI4());
+ reader.GetI4();
+ reader.IncPtr(reader.GetI4());
}
// ------------------------------------------------------------------------------------------------
void COBImporter::ReadMat1_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
{
- if(nfo.version > 8) {
- return UnsupportedChunk_Binary(reader,nfo,"Mat1");
- }
-
- const chunk_guard cn(nfo,reader);
-
- out.materials.push_back(Material());
- Material& mat = out.materials.back();
- mat = nfo;
-
- mat.matnum = reader.GetI2();
- switch(reader.GetI1()) {
- case 'f':
- mat.type = Material::FLAT;
- break;
- case 'p':
- mat.type = Material::PHONG;
- break;
- case 'm':
- mat.type = Material::METAL;
- break;
- default:
- LogError_Ascii(format("Unrecognized shader type in `Mat1` chunk with id ")<<nfo.id);
- mat.type = Material::FLAT;
- }
-
- switch(reader.GetI1()) {
- case 'f':
- mat.autofacet = Material::FACETED;
- break;
- case 'a':
- mat.autofacet = Material::AUTOFACETED;
- break;
- case 's':
- mat.autofacet = Material::SMOOTH;
- break;
- default:
- LogError_Ascii(format("Unrecognized faceting mode in `Mat1` chunk with id ")<<nfo.id);
- mat.autofacet = Material::FACETED;
- }
- mat.autofacet_angle = static_cast<float>(reader.GetI1());
-
- mat.rgb.r = reader.GetF4();
- mat.rgb.g = reader.GetF4();
- mat.rgb.b = reader.GetF4();
-
- mat.alpha = reader.GetF4();
- mat.ka = reader.GetF4();
- mat.ks = reader.GetF4();
- mat.exp = reader.GetF4();
- mat.ior = reader.GetF4();
-
- char id[2];
- id[0] = reader.GetI1(),id[1] = reader.GetI1();
-
- if (id[0] == 'e' && id[1] == ':') {
- mat.tex_env.reset(new Texture());
-
- reader.GetI1();
- ReadString_Binary(mat.tex_env->path,reader);
-
- // advance to next texture-id
- id[0] = reader.GetI1(),id[1] = reader.GetI1();
- }
-
- if (id[0] == 't' && id[1] == ':') {
- mat.tex_color.reset(new Texture());
-
- reader.GetI1();
- ReadString_Binary(mat.tex_color->path,reader);
-
- mat.tex_color->transform.mTranslation.x = reader.GetF4();
- mat.tex_color->transform.mTranslation.y = reader.GetF4();
-
- mat.tex_color->transform.mScaling.x = reader.GetF4();
- mat.tex_color->transform.mScaling.y = reader.GetF4();
-
- // advance to next texture-id
- id[0] = reader.GetI1(),id[1] = reader.GetI1();
- }
-
- if (id[0] == 'b' && id[1] == ':') {
- mat.tex_bump.reset(new Texture());
-
- reader.GetI1();
- ReadString_Binary(mat.tex_bump->path,reader);
-
- mat.tex_bump->transform.mTranslation.x = reader.GetF4();
- mat.tex_bump->transform.mTranslation.y = reader.GetF4();
-
- mat.tex_bump->transform.mScaling.x = reader.GetF4();
- mat.tex_bump->transform.mScaling.y = reader.GetF4();
-
- // skip amplitude for I don't know its purpose.
- reader.GetF4();
- }
- reader.IncPtr(-2);
+ if(nfo.version > 8) {
+ return UnsupportedChunk_Binary(reader,nfo,"Mat1");
+ }
+
+ const chunk_guard cn(nfo,reader);
+
+ out.materials.push_back(Material());
+ Material& mat = out.materials.back();
+ mat = nfo;
+
+ mat.matnum = reader.GetI2();
+ switch(reader.GetI1()) {
+ case 'f':
+ mat.type = Material::FLAT;
+ break;
+ case 'p':
+ mat.type = Material::PHONG;
+ break;
+ case 'm':
+ mat.type = Material::METAL;
+ break;
+ default:
+ LogError_Ascii(format("Unrecognized shader type in `Mat1` chunk with id ")<<nfo.id);
+ mat.type = Material::FLAT;
+ }
+
+ switch(reader.GetI1()) {
+ case 'f':
+ mat.autofacet = Material::FACETED;
+ break;
+ case 'a':
+ mat.autofacet = Material::AUTOFACETED;
+ break;
+ case 's':
+ mat.autofacet = Material::SMOOTH;
+ break;
+ default:
+ LogError_Ascii(format("Unrecognized faceting mode in `Mat1` chunk with id ")<<nfo.id);
+ mat.autofacet = Material::FACETED;
+ }
+ mat.autofacet_angle = static_cast<float>(reader.GetI1());
+
+ mat.rgb.r = reader.GetF4();
+ mat.rgb.g = reader.GetF4();
+ mat.rgb.b = reader.GetF4();
+
+ mat.alpha = reader.GetF4();
+ mat.ka = reader.GetF4();
+ mat.ks = reader.GetF4();
+ mat.exp = reader.GetF4();
+ mat.ior = reader.GetF4();
+
+ char id[2];
+ id[0] = reader.GetI1(),id[1] = reader.GetI1();
+
+ if (id[0] == 'e' && id[1] == ':') {
+ mat.tex_env.reset(new Texture());
+
+ reader.GetI1();
+ ReadString_Binary(mat.tex_env->path,reader);
+
+ // advance to next texture-id
+ id[0] = reader.GetI1(),id[1] = reader.GetI1();
+ }
+
+ if (id[0] == 't' && id[1] == ':') {
+ mat.tex_color.reset(new Texture());
+
+ reader.GetI1();
+ ReadString_Binary(mat.tex_color->path,reader);
+
+ mat.tex_color->transform.mTranslation.x = reader.GetF4();
+ mat.tex_color->transform.mTranslation.y = reader.GetF4();
+
+ mat.tex_color->transform.mScaling.x = reader.GetF4();
+ mat.tex_color->transform.mScaling.y = reader.GetF4();
+
+ // advance to next texture-id
+ id[0] = reader.GetI1(),id[1] = reader.GetI1();
+ }
+
+ if (id[0] == 'b' && id[1] == ':') {
+ mat.tex_bump.reset(new Texture());
+
+ reader.GetI1();
+ ReadString_Binary(mat.tex_bump->path,reader);
+
+ mat.tex_bump->transform.mTranslation.x = reader.GetF4();
+ mat.tex_bump->transform.mTranslation.y = reader.GetF4();
+
+ mat.tex_bump->transform.mScaling.x = reader.GetF4();
+ mat.tex_bump->transform.mScaling.y = reader.GetF4();
+
+ // skip amplitude for I don't know its purpose.
+ reader.GetF4();
+ }
+ reader.IncPtr(-2);
}
// ------------------------------------------------------------------------------------------------
void COBImporter::ReadCame_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
{
- if(nfo.version > 2) {
- return UnsupportedChunk_Binary(reader,nfo,"Came");
- }
+ if(nfo.version > 2) {
+ return UnsupportedChunk_Binary(reader,nfo,"Came");
+ }
- const chunk_guard cn(nfo,reader);
+ const chunk_guard cn(nfo,reader);
- out.nodes.push_back(boost::shared_ptr<Camera>(new Camera()));
- Camera& msh = (Camera&)(*out.nodes.back().get());
- msh = nfo;
+ out.nodes.push_back(std::shared_ptr<Camera>(new Camera()));
+ Camera& msh = (Camera&)(*out.nodes.back().get());
+ msh = nfo;
- ReadBasicNodeInfo_Binary(msh,reader,nfo);
+ ReadBasicNodeInfo_Binary(msh,reader,nfo);
- // the rest is not interesting for us, so we skip over it.
- if(nfo.version > 1) {
- if (reader.GetI2()==512) {
- reader.IncPtr(42);
- }
- }
+ // the rest is not interesting for us, so we skip over it.
+ if(nfo.version > 1) {
+ if (reader.GetI2()==512) {
+ reader.IncPtr(42);
+ }
+ }
}
// ------------------------------------------------------------------------------------------------
void COBImporter::ReadLght_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
{
- if(nfo.version > 2) {
- return UnsupportedChunk_Binary(reader,nfo,"Lght");
- }
+ if(nfo.version > 2) {
+ return UnsupportedChunk_Binary(reader,nfo,"Lght");
+ }
- const chunk_guard cn(nfo,reader);
+ const chunk_guard cn(nfo,reader);
- out.nodes.push_back(boost::shared_ptr<Light>(new Light()));
- Light& msh = (Light&)(*out.nodes.back().get());
- msh = nfo;
+ out.nodes.push_back(std::shared_ptr<Light>(new Light()));
+ Light& msh = (Light&)(*out.nodes.back().get());
+ msh = nfo;
- ReadBasicNodeInfo_Binary(msh,reader,nfo);
+ ReadBasicNodeInfo_Binary(msh,reader,nfo);
}
// ------------------------------------------------------------------------------------------------
void COBImporter::ReadGrou_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
{
- if(nfo.version > 2) {
- return UnsupportedChunk_Binary(reader,nfo,"Grou");
- }
+ if(nfo.version > 2) {
+ return UnsupportedChunk_Binary(reader,nfo,"Grou");
+ }
- const chunk_guard cn(nfo,reader);
+ const chunk_guard cn(nfo,reader);
- out.nodes.push_back(boost::shared_ptr<Group>(new Group()));
- Group& msh = (Group&)(*out.nodes.back().get());
- msh = nfo;
+ out.nodes.push_back(std::shared_ptr<Group>(new Group()));
+ Group& msh = (Group&)(*out.nodes.back().get());
+ msh = nfo;
- ReadBasicNodeInfo_Binary(msh,reader,nfo);
+ ReadBasicNodeInfo_Binary(msh,reader,nfo);
}
// ------------------------------------------------------------------------------------------------
void COBImporter::ReadUnit_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
{
- if(nfo.version > 1) {
- return UnsupportedChunk_Binary(reader,nfo,"Unit");
- }
-
- const chunk_guard cn(nfo,reader);
-
- // parent chunks preceede their childs, so we should have the
- // corresponding chunk already.
- for_each(boost::shared_ptr< Node >& nd, out.nodes) {
- if (nd->id == nfo.parent_id) {
- const unsigned int t=reader.GetI2();
- nd->unit_scale = t>=sizeof(units)/sizeof(units[0])?(
- LogWarn_Ascii(format()<<t<<" is not a valid value for `Units` attribute in `Unit chunk` "<<nfo.id)
- ,1.f):units[t];
-
- return;
- }
- }
- LogWarn_Ascii(format()<<"`Unit` chunk "<<nfo.id<<" is a child of "
- <<nfo.parent_id<<" which does not exist");
+ if(nfo.version > 1) {
+ return UnsupportedChunk_Binary(reader,nfo,"Unit");
+ }
+
+ const chunk_guard cn(nfo,reader);
+
+ // parent chunks preceede their childs, so we should have the
+ // corresponding chunk already.
+ for(std::shared_ptr< Node >& nd : out.nodes) {
+ if (nd->id == nfo.parent_id) {
+ const unsigned int t=reader.GetI2();
+ nd->unit_scale = t>=sizeof(units)/sizeof(units[0])?(
+ LogWarn_Ascii(format()<<t<<" is not a valid value for `Units` attribute in `Unit chunk` "<<nfo.id)
+ ,1.f):units[t];
+
+ return;
+ }
+ }
+ LogWarn_Ascii(format()<<"`Unit` chunk "<<nfo.id<<" is a child of "
+ <<nfo.parent_id<<" which does not exist");
}