Merge remote-tracking branch 'official/collada_export_escape' into contrib

pull/546/head
Léo Terziman 2014-08-25 10:51:50 +02:00
commit e2d9512275
72 changed files with 3365 additions and 514 deletions

View File

@ -1,5 +1,5 @@
before_install:
- sudo apt-get install cmake
- sudo apt-get install cmake libcppunit-dev
env:
- TRAVIS_NO_EXPORT=YES
@ -13,7 +13,9 @@ compiler:
- gcc
- clang
script: cmake -G "Unix Makefiles" -DASSIMP_ENABLE_BOOST_WORKAROUND=YES -DASSIMP_NO_EXPORT=$TRAVIS_NO_EXPORT -STATIC_BUILD=$TRAVIS_STATIC_BUILD && make
script:
- cmake -G "Unix Makefiles" -DASSIMP_ENABLE_BOOST_WORKAROUND=YES -DASSIMP_NO_EXPORT=$TRAVIS_NO_EXPORT -STATIC_BUILD=$TRAVIS_STATIC_BUILD
- make
- cd test/unit
- ../../bin/unit

View File

@ -76,8 +76,7 @@ SET( ASSIMP_INCLUDE_INSTALL_DIR "include" CACHE PATH
"Path the header files are installed to." )
SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE PATH
"Path the tool executables are installed to." )
SET ( ASSIMP_BUILD_STATIC_LIB OFF CACHE BOOL
"Build a static (.a) version of the library" )
option (ASSIMP_BUILD_STATIC_LIB "Build a static (.a) version of the library" OFF)
SET(ASSIMP_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfitx for lib, samples and tools")
@ -102,8 +101,9 @@ ENDIF()
# Globally enable Boost resp. the Boost workaround it is also needed by the
# tools which include the Assimp headers.
SET ( ASSIMP_ENABLE_BOOST_WORKAROUND ON CACHE BOOL
option ( ASSIMP_ENABLE_BOOST_WORKAROUND
"If a simple implementation of the used Boost functions is used. Slightly reduces functionality, but enables builds without Boost available."
ON
)
IF ( ASSIMP_ENABLE_BOOST_WORKAROUND )
INCLUDE_DIRECTORIES( code/BoostWorkaround )
@ -129,8 +129,9 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config.cmake.in" "${C
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config-version.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" @ONLY IMMEDIATE)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" DESTINATION "${ASSIMP_LIB_INSTALL_DIR}/cmake/assimp-${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}" COMPONENT ${LIBASSIMP-DEV_COMPONENT})
SET ( ASSIMP_NO_EXPORT OFF CACHE BOOL
"Disable Assimp's export functionality."
option ( ASSIMP_NO_EXPORT
"Disable Assimp's export functionality."
OFF
)
# Search for external dependencies, and build them from source if not found
@ -186,8 +187,9 @@ ENDIF ( ASSIMP_BUILD_COMPILER STREQUAL "")
MARK_AS_ADVANCED ( ASSIMP_BUILD_ARCHITECTURE ASSIMP_BUILD_COMPILER )
ADD_SUBDIRECTORY( code/ )
SET ( ASSIMP_BUILD_ASSIMP_TOOLS ON CACHE BOOL
option ( ASSIMP_BUILD_ASSIMP_TOOLS
"If the supplementary tools for Assimp are built in addition to the library."
ON
)
IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
IF ( WIN32 )
@ -196,8 +198,9 @@ IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
ADD_SUBDIRECTORY( tools/assimp_cmd/ )
ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS )
SET ( ASSIMP_BUILD_SAMPLES OFF CACHE BOOL
option ( ASSIMP_BUILD_SAMPLES
"If the official samples are built as well (needs Glut)."
OFF
)
IF ( ASSIMP_BUILD_SAMPLES)
@ -207,19 +210,19 @@ IF ( ASSIMP_BUILD_SAMPLES)
ADD_SUBDIRECTORY( samples/SimpleOpenGL/ )
ENDIF ( ASSIMP_BUILD_SAMPLES )
IF ( WIN32 )
SET ( ASSIMP_BUILD_TESTS ON CACHE BOOL
"If the test suite for Assimp is built in addition to the library."
)
option ( ASSIMP_BUILD_TESTS
"If the test suite for Assimp is built in addition to the library."
ON
)
IF ( ASSIMP_BUILD_TESTS )
ADD_SUBDIRECTORY( test/ )
ENDIF ( ASSIMP_BUILD_TESTS )
ENDIF ( WIN32 )
IF ( ASSIMP_BUILD_TESTS )
ADD_SUBDIRECTORY( test/ )
ENDIF ( ASSIMP_BUILD_TESTS )
IF(MSVC)
SET ( ASSIMP_INSTALL_PDB ON CACHE BOOL
option ( ASSIMP_INSTALL_PDB
"Install MSVC debug files."
ON
)
ENDIF(MSVC)

View File

@ -1,7 +1,7 @@
Open Asset Import Library (assimp)
========
Open Asset Import Library is a Open Source library designed to load various __3d file formats and convert them into a shared, in-memory format__. It supports more than __30 file formats__ for import and a growing selection of file formats for export. Additionally, assimp features various __post processing tools__ to refine the imported data: _normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials_ and many more.
Open Asset Import Library is a Open Source library designed to load various __3d file formats and convert them into a shared, in-memory format__. It supports more than __40 file formats__ for import and a growing selection of file formats for export. Additionally, assimp features various __post processing tools__ to refine the imported data: _normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials_ and many more.
This is the development trunk of assimp containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [assimp.sf.net](http://assimp.sf.net) or from *nix package repositories. According to [Travis-CI] (https://travis-ci.org/), the current build status of the trunk is [![Build Status](https://travis-ci.org/assimp/assimp.png)](https://travis-ci.org/assimp/assimp)
@ -46,6 +46,7 @@ The library provides importers for a lot of file formats, including:
- Ogre Binary
- Ogre XML
- Q3D
- ASSBIN (Assimp scene serialization)
Additionally, the following formats are also supported, but not part of the core library as they depend on proprietary libraries.
@ -57,7 +58,10 @@ Exporters include:
- STL
- OBJ
- PLY
- X
- 3DS
- JSON (for WebGl, via https://github.com/acgessler/assimp2json)
- ASSBIN
See [the full list here](http://assimp.sourceforge.net/main_features_formats.html).

View File

@ -0,0 +1,560 @@
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2012, 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
following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
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
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
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
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
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
#include "AssimpPCH.h"
#ifndef ASSIMP_BUILD_NO_EXPORT
#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
#include "3DSExporter.h"
#include "3DSLoader.h"
#include "SceneCombiner.h"
#include "SplitLargeMeshes.h"
using namespace Assimp;
namespace Assimp {
namespace {
//////////////////////////////////////////////////////////////////////////////////////
// Scope utility to write a 3DS file chunk.
//
// Upon construction, the chunk header is written with the chunk type (flags)
// filled out, but the chunk size left empty. Upon destruction, the correct chunk
// size based on the then-position of the output stream cursor is filled in.
class ChunkWriter {
enum {
CHUNK_SIZE_NOT_SET = 0xdeadbeef
, SIZE_OFFSET = 2
};
public:
ChunkWriter(StreamWriterLE& writer, uint16_t chunk_type)
: writer(writer)
{
chunk_start_pos = writer.GetCurrentPos();
writer.PutU2(chunk_type);
writer.PutU4(CHUNK_SIZE_NOT_SET);
}
~ChunkWriter() {
std::size_t head_pos = writer.GetCurrentPos();
ai_assert(head_pos > chunk_start_pos);
const std::size_t chunk_size = head_pos - chunk_start_pos;
writer.SetCurrentPos(chunk_start_pos + SIZE_OFFSET);
writer.PutU4(chunk_size);
writer.SetCurrentPos(head_pos);
}
private:
StreamWriterLE& writer;
std::size_t chunk_start_pos;
};
// Return an unique name for a given |mesh| attached to |node| that
// preserves the mesh's given name if it has one. |index| is the index
// of the mesh in |aiScene::mMeshes|.
std::string GetMeshName(const aiMesh& mesh, unsigned int index, const aiNode& node) {
static const std::string underscore = "_";
char postfix[10] = {0};
ASSIMP_itoa10(postfix, index);
std::string result = node.mName.C_Str();
if (mesh.mName.length > 0) {
result += underscore + mesh.mName.C_Str();
}
return result + underscore + postfix;
}
// Return an unique name for a given |mat| with original position |index|
// in |aiScene::mMaterials|. The name preserves the original material
// name if possible.
std::string GetMaterialName(const aiMaterial& mat, unsigned int index) {
static const std::string underscore = "_";
char postfix[10] = {0};
ASSIMP_itoa10(postfix, index);
aiString mat_name;
if (AI_SUCCESS == mat.Get(AI_MATKEY_NAME, mat_name)) {
return mat_name.C_Str() + underscore + postfix;
}
return "Material" + underscore + postfix;
}
// Collect world transformations for each node
void CollectTrafos(const aiNode* node, std::map<const aiNode*, aiMatrix4x4>& trafos) {
const aiMatrix4x4& parent = node->mParent ? trafos[node->mParent] : aiMatrix4x4();
trafos[node] = parent * node->mTransformation;
for (unsigned int i = 0; i < node->mNumChildren; ++i) {
CollectTrafos(node->mChildren[i], trafos);
}
}
// Generate a flat list of the meshes (by index) assigned to each node
void CollectMeshes(const aiNode* node, std::multimap<const aiNode*, unsigned int>& meshes) {
for (unsigned int i = 0; i < node->mNumMeshes; ++i) {
meshes.insert(std::make_pair(node, node->mMeshes[i]));
}
for (unsigned int i = 0; i < node->mNumChildren; ++i) {
CollectMeshes(node->mChildren[i], meshes);
}
}
}
// ------------------------------------------------------------------------------------------------
// Worker function for exporting a scene to 3DS. Prototyped and registered in Exporter.cpp
void ExportScene3DS(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene)
{
boost::shared_ptr<IOStream> outfile (pIOSystem->Open(pFile, "wb"));
if(!outfile) {
throw DeadlyExportError("Could not open output .3ds file: " + std::string(pFile));
}
// TODO: This extra copy should be avoided and all of this made a preprocess
// requirement of the 3DS exporter.
//
// 3DS meshes can be max 0xffff (16 Bit) vertices and faces, respectively.
// SplitLargeMeshes can do this, but it requires the correct limit to be set
// which is not possible with the current way of specifying preprocess steps
// in |Exporter::ExportFormatEntry|.
aiScene* scenecopy_tmp;
SceneCombiner::CopyScene(&scenecopy_tmp,pScene);
std::auto_ptr<aiScene> scenecopy(scenecopy_tmp);
SplitLargeMeshesProcess_Triangle tri_splitter;
tri_splitter.SetLimit(0xffff);
tri_splitter.Execute(scenecopy.get());
SplitLargeMeshesProcess_Vertex vert_splitter;
vert_splitter.SetLimit(0xffff);
vert_splitter.Execute(scenecopy.get());
// Invoke the actual exporter
Discreet3DSExporter exporter(outfile, scenecopy.get());
}
} // end of namespace Assimp
// ------------------------------------------------------------------------------------------------
Discreet3DSExporter:: Discreet3DSExporter(boost::shared_ptr<IOStream> outfile, const aiScene* scene)
: scene(scene)
, writer(outfile)
{
CollectTrafos(scene->mRootNode, trafos);
CollectMeshes(scene->mRootNode, meshes);
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAIN);
{
ChunkWriter chunk(writer, Discreet3DS::CHUNK_OBJMESH);
WriteMeshes();
WriteMaterials();
{
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MASTER_SCALE);
writer.PutF4(1.0f);
}
}
{
ChunkWriter chunk(writer, Discreet3DS::CHUNK_KEYFRAMER);
WriteHierarchy(*scene->mRootNode, -1, -1);
}
}
// ------------------------------------------------------------------------------------------------
int Discreet3DSExporter::WriteHierarchy(const aiNode& node, int seq, int sibling_level)
{
// 3DS scene hierarchy is serialized as in http://www.martinreddy.net/gfx/3d/3DS.spec
{
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKINFO);
{
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKOBJNAME);
// Assimp node names are unique and distinct from all mesh-node
// names we generate; thus we can use them as-is
WriteString(node.mName);
// Two unknown int16 values - it is even unclear if 0 is a safe value
// but luckily importers do not know better either.
writer.PutI4(0);
int16_t hierarchy_pos = static_cast<int16_t>(seq);
if (sibling_level != -1) {
hierarchy_pos = sibling_level;
}
// Write the hierarchy position
writer.PutI2(hierarchy_pos);
}
}
// TODO: write transformation chunks
++seq;
sibling_level = seq;
// Write all children
for (unsigned int i = 0; i < node.mNumChildren; ++i) {
seq = WriteHierarchy(*node.mChildren[i], seq, i == 0 ? -1 : sibling_level);
}
// Write all meshes as separate nodes to be able to reference the meshes by name
for (unsigned int i = 0; i < node.mNumMeshes; ++i) {
const bool first_child = node.mNumChildren == 0 && i == 0;
const unsigned int mesh_idx = node.mMeshes[i];
const aiMesh& mesh = *scene->mMeshes[mesh_idx];
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKINFO);
{
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKOBJNAME);
WriteString(GetMeshName(mesh, mesh_idx, node));
writer.PutI4(0);
writer.PutI2(static_cast<int16_t>(first_child ? seq : sibling_level));
++seq;
}
}
return seq;
}
// ------------------------------------------------------------------------------------------------
void Discreet3DSExporter::WriteMaterials()
{
for (unsigned int i = 0; i < scene->mNumMaterials; ++i) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MATERIAL);
const aiMaterial& mat = *scene->mMaterials[i];
{
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MATNAME);
const std::string& name = GetMaterialName(mat, i);
WriteString(name);
}
aiColor3D color;
if (mat.Get(AI_MATKEY_COLOR_DIFFUSE, color) == AI_SUCCESS) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_DIFFUSE);
WriteColor(color);
}
if (mat.Get(AI_MATKEY_COLOR_SPECULAR, color) == AI_SUCCESS) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SPECULAR);
WriteColor(color);
}
if (mat.Get(AI_MATKEY_COLOR_AMBIENT, color) == AI_SUCCESS) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_AMBIENT);
WriteColor(color);
}
if (mat.Get(AI_MATKEY_COLOR_EMISSIVE, color) == AI_SUCCESS) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SELF_ILLUM);
WriteColor(color);
}
aiShadingMode shading_mode;
if (mat.Get(AI_MATKEY_SHADING_MODEL, shading_mode) == AI_SUCCESS) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHADING);
Discreet3DS::shadetype3ds shading_mode_out;
switch(shading_mode) {
case aiShadingMode_Flat:
case aiShadingMode_NoShading:
shading_mode_out = Discreet3DS::Flat;
break;
case aiShadingMode_Gouraud:
case aiShadingMode_Toon:
case aiShadingMode_OrenNayar:
case aiShadingMode_Minnaert:
shading_mode_out = Discreet3DS::Gouraud;
break;
case aiShadingMode_Phong:
case aiShadingMode_Blinn:
case aiShadingMode_CookTorrance:
case aiShadingMode_Fresnel:
shading_mode_out = Discreet3DS::Phong;
break;
default:
ai_assert(false);
};
writer.PutU2(static_cast<uint16_t>(shading_mode_out));
}
float f;
if (mat.Get(AI_MATKEY_SHININESS, f) == AI_SUCCESS) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHININESS);
WritePercentChunk(f);
}
if (mat.Get(AI_MATKEY_SHININESS_STRENGTH, f) == AI_SUCCESS) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHININESS_PERCENT);
WritePercentChunk(f);
}
int twosided;
if (mat.Get(AI_MATKEY_TWOSIDED, twosided) == AI_SUCCESS && twosided != 0) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_TWO_SIDE);
writer.PutI2(1);
}
WriteTexture(mat, aiTextureType_DIFFUSE, Discreet3DS::CHUNK_MAT_TEXTURE);
WriteTexture(mat, aiTextureType_HEIGHT, Discreet3DS::CHUNK_MAT_BUMPMAP);
WriteTexture(mat, aiTextureType_OPACITY, Discreet3DS::CHUNK_MAT_OPACMAP);
WriteTexture(mat, aiTextureType_SHININESS, Discreet3DS::CHUNK_MAT_MAT_SHINMAP);
WriteTexture(mat, aiTextureType_SPECULAR, Discreet3DS::CHUNK_MAT_SPECMAP);
WriteTexture(mat, aiTextureType_EMISSIVE, Discreet3DS::CHUNK_MAT_SELFIMAP);
WriteTexture(mat, aiTextureType_REFLECTION, Discreet3DS::CHUNK_MAT_REFLMAP);
}
}
// ------------------------------------------------------------------------------------------------
void Discreet3DSExporter::WriteTexture(const aiMaterial& mat, aiTextureType type, uint16_t chunk_flags)
{
aiString path;
aiTextureMapMode map_mode[2] = {
aiTextureMapMode_Wrap, aiTextureMapMode_Wrap
};
float blend = 1.0f;
if (mat.GetTexture(type, 0, &path, NULL, NULL, &blend, NULL, map_mode) != AI_SUCCESS || !path.length) {
return;
}
// TODO: handle embedded textures properly
if (path.data[0] == '*') {
DefaultLogger::get()->error("Ignoring embedded texture for export: " + std::string(path.C_Str()));
return;
}
ChunkWriter chunk(writer, chunk_flags);
{
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAPFILE);
WriteString(path);
}
WritePercentChunk(blend);
{
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MAP_TILING);
uint16_t val = 0; // WRAP
if (map_mode[0] == aiTextureMapMode_Mirror) {
val = 0x2;
}
else if (map_mode[0] == aiTextureMapMode_Decal) {
val = 0x10;
}
writer.PutU2(val);
}
// TODO: export texture transformation (i.e. UV offset, scale, rotation)
}
// ------------------------------------------------------------------------------------------------
void Discreet3DSExporter::WriteMeshes()
{
// NOTE: 3DS allows for instances. However:
// i) not all importers support reading them
// ii) instances are not as flexible as they are in assimp, in particular,
// nodes can carry (and instance) only one mesh.
//
// This exporter currently deep clones all instanced meshes, i.e. for each mesh
// attached to a node a full TRIMESH chunk is written to the file.
//
// Furthermore, the TRIMESH is transformed into world space so that it will
// appear correctly if importers don't read the scene hierarchy at all.
for (MeshesByNodeMap::const_iterator it = meshes.begin(); it != meshes.end(); ++it) {
const aiNode& node = *(*it).first;
const unsigned int mesh_idx = (*it).second;
const aiMesh& mesh = *scene->mMeshes[mesh_idx];
// This should not happen if the SLM step is correctly executed
// before the scene is handed to the exporter
ai_assert(mesh.mNumVertices <= 0xffff);
ai_assert(mesh.mNumFaces <= 0xffff);
const aiMatrix4x4& trafo = trafos[&node];
ChunkWriter chunk(writer, Discreet3DS::CHUNK_OBJBLOCK);
// Mesh name is tied to the node it is attached to so it can later be referenced
const std::string& name = GetMeshName(mesh, mesh_idx, node);
WriteString(name);
// TRIMESH chunk
ChunkWriter chunk2(writer, Discreet3DS::CHUNK_TRIMESH);
// Vertices in world space
{
ChunkWriter chunk(writer, Discreet3DS::CHUNK_VERTLIST);
const uint16_t count = static_cast<uint16_t>(mesh.mNumVertices);
writer.PutU2(count);
for (unsigned int i = 0; i < mesh.mNumVertices; ++i) {
const aiVector3D& v = trafo * mesh.mVertices[i];
writer.PutF4(v.x);
writer.PutF4(v.y);
writer.PutF4(v.z);
}
}
// UV coordinates
if (mesh.HasTextureCoords(0)) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAPLIST);
const uint16_t count = static_cast<uint16_t>(mesh.mNumVertices);
writer.PutU2(count);
for (unsigned int i = 0; i < mesh.mNumVertices; ++i) {
const aiVector3D& v = mesh.mTextureCoords[0][i];
writer.PutF4(v.x);
writer.PutF4(v.y);
}
}
// Faces (indices)
{
ChunkWriter chunk(writer, Discreet3DS::CHUNK_FACELIST);
ai_assert(mesh.mNumFaces <= 0xffff);
// Count triangles, discard lines and points
uint16_t count = 0;
for (unsigned int i = 0; i < mesh.mNumFaces; ++i) {
const aiFace& f = mesh.mFaces[i];
if (f.mNumIndices < 3) {
continue;
}
// TRIANGULATE step is a pre-requisite so we should not see polys here
ai_assert(f.mNumIndices == 3);
++count;
}
writer.PutU2(count);
for (unsigned int i = 0; i < mesh.mNumFaces; ++i) {
const aiFace& f = mesh.mFaces[i];
if (f.mNumIndices < 3) {
continue;
}
for (unsigned int j = 0; j < 3; ++j) {
ai_assert(f.mIndices[j] <= 0xffff);
writer.PutI2(static_cast<uint16_t>(f.mIndices[j]));
}
// Edge visibility flag
writer.PutI2(0x0);
}
// TODO: write smoothing groups (CHUNK_SMOOLIST)
WriteFaceMaterialChunk(mesh);
}
// Transformation matrix by which the mesh vertices have been pre-transformed with.
{
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRMATRIX);
for (unsigned int r = 0; r < 4; ++r) {
for (unsigned int c = 0; c < 3; ++c) {
writer.PutF4(trafo[r][c]);
}
}
}
}
}
// ------------------------------------------------------------------------------------------------
void Discreet3DSExporter::WriteFaceMaterialChunk(const aiMesh& mesh)
{
ChunkWriter chunk(writer, Discreet3DS::CHUNK_FACEMAT);
const std::string& name = GetMaterialName(*scene->mMaterials[mesh.mMaterialIndex], mesh.mMaterialIndex);
WriteString(name);
// Because assimp splits meshes by material, only a single
// FACEMAT chunk needs to be written
ai_assert(mesh.mNumFaces <= 0xffff);
const uint16_t count = static_cast<uint16_t>(mesh.mNumFaces);
writer.PutU2(count);
for (unsigned int i = 0; i < mesh.mNumFaces; ++i) {
writer.PutU2(static_cast<uint16_t>(i));
}
}
// ------------------------------------------------------------------------------------------------
void Discreet3DSExporter::WriteString(const std::string& s) {
for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) {
writer.PutI1(*it);
}
writer.PutI1('\0');
}
// ------------------------------------------------------------------------------------------------
void Discreet3DSExporter::WriteString(const aiString& s) {
for (std::size_t i = 0; i < s.length; ++i) {
writer.PutI1(s.data[i]);
}
writer.PutI1('\0');
}
// ------------------------------------------------------------------------------------------------
void Discreet3DSExporter::WriteColor(const aiColor3D& color) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_RGBF);
writer.PutF4(color.r);
writer.PutF4(color.g);
writer.PutF4(color.b);
}
// ------------------------------------------------------------------------------------------------
void Discreet3DSExporter::WritePercentChunk(float f) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_PERCENTF);
writer.PutF4(f);
}
#endif // ASSIMP_BUILD_NO_3DS_EXPORTER
#endif // ASSIMP_BUILD_NO_EXPORT

94
code/3DSExporter.h 100644
View File

@ -0,0 +1,94 @@
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2012, 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
following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
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
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
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
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
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** @file 3DSExporter.h
* 3DS Exporter Main Header
*/
#ifndef AI_3DSEXPORTER_H_INC
#define AI_3DSEXPORTER_H_INC
#include <map>
#include "StreamWriter.h"
struct aiScene;
struct aiNode;
namespace Assimp
{
// ------------------------------------------------------------------------------------------------
/** Helper class to export a given scene to a 3DS file. */
// ------------------------------------------------------------------------------------------------
class Discreet3DSExporter
{
public:
Discreet3DSExporter(boost::shared_ptr<IOStream> outfile, const aiScene* pScene);
private:
void WriteMeshes();
void WriteMaterials();
void WriteTexture(const aiMaterial& mat, aiTextureType type, uint16_t chunk_flags);
void WriteFaceMaterialChunk(const aiMesh& mesh);
int WriteHierarchy(const aiNode& node, int level, int sibling_level);
void WriteString(const std::string& s);
void WriteString(const aiString& s);
void WriteColor(const aiColor3D& color);
void WritePercentChunk(float f);
private:
const aiScene* const scene;
StreamWriterLE writer;
std::map<const aiNode*, aiMatrix4x4> trafos;
typedef std::multimap<const aiNode*, unsigned int> MeshesByNodeMap;
MeshesByNodeMap meshes;
};
}
#endif

View File

@ -273,8 +273,8 @@ protected:
bool bIsPrj;
};
#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER
} // end of namespace Assimp
#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER
#endif // AI_3DSIMPORTER_H_INC

View File

@ -0,0 +1,762 @@
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2012, 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
following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
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
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
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
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
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** @file AssbinExporter.cpp
* ASSBIN exporter main code
*/
#include "AssimpPCH.h"
#include "assbin_chunks.h"
#include "./../include/assimp/version.h"
#include "ProcessHelper.h"
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
# include <zlib.h>
#else
# include "../contrib/zlib/zlib.h"
#endif
#ifndef ASSIMP_BUILD_NO_EXPORT
#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
using namespace Assimp;
namespace Assimp {
template <typename T>
size_t Write(IOStream * stream, const T& v)
{
return stream->Write( &v, sizeof(T), 1 );
}
// -----------------------------------------------------------------------------------
// Serialize an aiString
template <>
inline size_t Write<aiString>(IOStream * stream, const aiString& s)
{
const size_t s2 = (uint32_t)s.length;
stream->Write(&s,4,1);
stream->Write(s.data,s2,1);
return s2+4;
}
// -----------------------------------------------------------------------------------
// Serialize an unsigned int as uint32_t
template <>
inline size_t Write<unsigned int>(IOStream * stream, const unsigned int& w)
{
const uint32_t t = (uint32_t)w;
if (w > t) {
// this shouldn't happen, integers in Assimp data structures never exceed 2^32
throw new DeadlyExportError("loss of data due to 64 -> 32 bit integer conversion");
}
stream->Write(&t,4,1);
return 4;
}
// -----------------------------------------------------------------------------------
// Serialize an unsigned int as uint16_t
template <>
inline size_t Write<uint16_t>(IOStream * stream, const uint16_t& w)
{
BOOST_STATIC_ASSERT(sizeof(uint16_t)==2);
stream->Write(&w,2,1);
return 2;
}
// -----------------------------------------------------------------------------------
// Serialize a float
template <>
inline size_t Write<float>(IOStream * stream, const float& f)
{
BOOST_STATIC_ASSERT(sizeof(float)==4);
stream->Write(&f,4,1);
return 4;
}
// -----------------------------------------------------------------------------------
// Serialize a double
template <>
inline size_t Write<double>(IOStream * stream, const double& f)
{
BOOST_STATIC_ASSERT(sizeof(double)==8);
stream->Write(&f,8,1);
return 8;
}
// -----------------------------------------------------------------------------------
// Serialize a vec3
template <>
inline size_t Write<aiVector3D>(IOStream * stream, const aiVector3D& v)
{
size_t t = Write<float>(stream,v.x);
t += Write<float>(stream,v.y);
t += Write<float>(stream,v.z);
return t;
}
// -----------------------------------------------------------------------------------
// Serialize a color value
template <>
inline size_t Write<aiColor4D>(IOStream * stream, const aiColor4D& v)
{
size_t t = Write<float>(stream,v.r);
t += Write<float>(stream,v.g);
t += Write<float>(stream,v.b);
t += Write<float>(stream,v.a);
return t;
}
// -----------------------------------------------------------------------------------
// Serialize a quaternion
template <>
inline size_t Write<aiQuaternion>(IOStream * stream, const aiQuaternion& v)
{
size_t t = Write<float>(stream,v.w);
t += Write<float>(stream,v.x);
t += Write<float>(stream,v.y);
t += Write<float>(stream,v.z);
return 16;
}
// -----------------------------------------------------------------------------------
// Serialize a vertex weight
template <>
inline size_t Write<aiVertexWeight>(IOStream * stream, const aiVertexWeight& v)
{
size_t t = Write<unsigned int>(stream,v.mVertexId);
return t+Write<float>(stream,v.mWeight);
}
// -----------------------------------------------------------------------------------
// Serialize a mat4x4
template <>
inline size_t Write<aiMatrix4x4>(IOStream * stream, const aiMatrix4x4& m)
{
for (unsigned int i = 0; i < 4;++i) {
for (unsigned int i2 = 0; i2 < 4;++i2) {
Write<float>(stream,m[i][i2]);
}
}
return 64;
}
// -----------------------------------------------------------------------------------
// Serialize an aiVectorKey
template <>
inline size_t Write<aiVectorKey>(IOStream * stream, const aiVectorKey& v)
{
const size_t t = Write<double>(stream,v.mTime);
return t + Write<aiVector3D>(stream,v.mValue);
}
// -----------------------------------------------------------------------------------
// Serialize an aiQuatKey
template <>
inline size_t Write<aiQuatKey>(IOStream * stream, const aiQuatKey& v)
{
const size_t t = Write<double>(stream,v.mTime);
return t + Write<aiQuaternion>(stream,v.mValue);
}
template <typename T>
inline size_t WriteBounds(IOStream * stream, const T* in, unsigned int size)
{
T minc,maxc;
ArrayBounds(in,size,minc,maxc);
const size_t t = Write<T>(stream,minc);
return t + Write<T>(stream,maxc);
}
// We use this to write out non-byte arrays so that we write using the specializations.
// This way we avoid writing out extra bytes that potentially come from struct alignment.
template <typename T>
inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
{
size_t n = 0;
for (unsigned int i=0; i<size; i++) n += Write<T>(stream,in[i]);
return n;
}
// ----------------------------------------------------------------------------------
/** @class AssbinChunkWriter
* @brief Chunk writer mechanism for the .assbin file structure
*
* This is a standard in-memory IOStream (most of the code is based on BlobIOStream),
* the difference being that this takes another IOStream as a "container" in the
* constructor, and when it is destroyed, it appends the magic number, the chunk size,
* and the chunk contents to the container stream. This allows relatively easy chunk
* chunk construction, even recursively.
*/
class AssbinChunkWriter : public IOStream
{
private:
uint8_t* buffer;
uint32_t magic;
IOStream * container;
size_t cur_size, cursor, initial;
private:
// -------------------------------------------------------------------
void Grow(size_t need = 0)
{
size_t new_size = std::max(initial, std::max( need, cur_size+(cur_size>>1) ));
const uint8_t* const old = buffer;
buffer = new uint8_t[new_size];
if (old) {
memcpy(buffer,old,cur_size);
delete[] old;
}
cur_size = new_size;
}
public:
AssbinChunkWriter( IOStream * container, uint32_t magic, size_t initial = 4096)
: buffer(NULL), magic(magic), container(container), cur_size(0), cursor(0), initial(initial)
{
}
virtual ~AssbinChunkWriter()
{
if (container) {
container->Write( &magic, sizeof(uint32_t), 1 );
container->Write( &cursor, sizeof(uint32_t), 1 );
container->Write( buffer, 1, cursor );
}
if (buffer) delete[] buffer;
}
void * GetBufferPointer() { return buffer; };
// -------------------------------------------------------------------
virtual size_t Read(void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) { return 0; };
virtual aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) { return aiReturn_FAILURE; };
virtual size_t Tell() const { return cursor; };
virtual void Flush() { };
virtual size_t FileSize() const
{
return cursor;
}
// -------------------------------------------------------------------
virtual size_t Write(const void* pvBuffer, size_t pSize, size_t pCount)
{
pSize *= pCount;
if (cursor + pSize > cur_size) {
Grow(cursor + pSize);
}
memcpy(buffer+cursor, pvBuffer, pSize);
cursor += pSize;
return pCount;
}
};
// ----------------------------------------------------------------------------------
/** @class AssbinExport
* @brief Assbin exporter class
*
* This class performs the .assbin exporting, and is responsible for the file layout.
*/
class AssbinExport
{
private:
bool shortened;
bool compressed;
protected:
// -----------------------------------------------------------------------------------
void WriteBinaryNode( IOStream * container, const aiNode* node)
{
AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODE );
Write<aiString>(&chunk,node->mName);
Write<aiMatrix4x4>(&chunk,node->mTransformation);
Write<unsigned int>(&chunk,node->mNumChildren);
Write<unsigned int>(&chunk,node->mNumMeshes);
for (unsigned int i = 0; i < node->mNumMeshes;++i) {
Write<unsigned int>(&chunk,node->mMeshes[i]);
}
for (unsigned int i = 0; i < node->mNumChildren;++i) {
WriteBinaryNode( &chunk, node->mChildren[i] );
}
}
// -----------------------------------------------------------------------------------
void WriteBinaryTexture(IOStream * container, const aiTexture* tex)
{
AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AITEXTURE );
Write<unsigned int>(&chunk,tex->mWidth);
Write<unsigned int>(&chunk,tex->mHeight);
chunk.Write( tex->achFormatHint, sizeof(char), 4 );
if(!shortened) {
if (!tex->mHeight) {
chunk.Write(tex->pcData,1,tex->mWidth);
}
else {
chunk.Write(tex->pcData,1,tex->mWidth*tex->mHeight*4);
}
}
}
// -----------------------------------------------------------------------------------
void WriteBinaryBone(IOStream * container, const aiBone* b)
{
AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIBONE );
Write<aiString>(&chunk,b->mName);
Write<unsigned int>(&chunk,b->mNumWeights);
Write<aiMatrix4x4>(&chunk,b->mOffsetMatrix);
// for the moment we write dumb min/max values for the bones, too.
// maybe I'll add a better, hash-like solution later
if (shortened) {
WriteBounds(&chunk,b->mWeights,b->mNumWeights);
} // else write as usual
else WriteArray<aiVertexWeight>(&chunk,b->mWeights,b->mNumWeights);
}
// -----------------------------------------------------------------------------------
void WriteBinaryMesh(IOStream * container, const aiMesh* mesh)
{
AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMESH );
Write<unsigned int>(&chunk,mesh->mPrimitiveTypes);
Write<unsigned int>(&chunk,mesh->mNumVertices);
Write<unsigned int>(&chunk,mesh->mNumFaces);
Write<unsigned int>(&chunk,mesh->mNumBones);
Write<unsigned int>(&chunk,mesh->mMaterialIndex);
// first of all, write bits for all existent vertex components
unsigned int c = 0;
if (mesh->mVertices) {
c |= ASSBIN_MESH_HAS_POSITIONS;
}
if (mesh->mNormals) {
c |= ASSBIN_MESH_HAS_NORMALS;
}
if (mesh->mTangents && mesh->mBitangents) {
c |= ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS;
}
for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) {
if (!mesh->mTextureCoords[n]) {
break;
}
c |= ASSBIN_MESH_HAS_TEXCOORD(n);
}
for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) {
if (!mesh->mColors[n]) {
break;
}
c |= ASSBIN_MESH_HAS_COLOR(n);
}
Write<unsigned int>(&chunk,c);
aiVector3D minVec, maxVec;
if (mesh->mVertices) {
if (shortened) {
WriteBounds(&chunk,mesh->mVertices,mesh->mNumVertices);
} // else write as usual
else WriteArray<aiVector3D>(&chunk,mesh->mVertices,mesh->mNumVertices);
}
if (mesh->mNormals) {
if (shortened) {
WriteBounds(&chunk,mesh->mNormals,mesh->mNumVertices);
} // else write as usual
else WriteArray<aiVector3D>(&chunk,mesh->mNormals,mesh->mNumVertices);
}
if (mesh->mTangents && mesh->mBitangents) {
if (shortened) {
WriteBounds(&chunk,mesh->mTangents,mesh->mNumVertices);
WriteBounds(&chunk,mesh->mBitangents,mesh->mNumVertices);
} // else write as usual
else {
WriteArray<aiVector3D>(&chunk,mesh->mTangents,mesh->mNumVertices);
WriteArray<aiVector3D>(&chunk,mesh->mBitangents,mesh->mNumVertices);
}
}
for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) {
if (!mesh->mColors[n])
break;
if (shortened) {
WriteBounds(&chunk,mesh->mColors[n],mesh->mNumVertices);
} // else write as usual
else WriteArray<aiColor4D>(&chunk,mesh->mColors[n],mesh->mNumVertices);
}
for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) {
if (!mesh->mTextureCoords[n])
break;
// write number of UV components
Write<unsigned int>(&chunk,mesh->mNumUVComponents[n]);
if (shortened) {
WriteBounds(&chunk,mesh->mTextureCoords[n],mesh->mNumVertices);
} // else write as usual
else WriteArray<aiVector3D>(&chunk,mesh->mTextureCoords[n],mesh->mNumVertices);
}
// write faces. There are no floating-point calculations involved
// in these, so we can write a simple hash over the face data
// to the dump file. We generate a single 32 Bit hash for 512 faces
// using Assimp's standard hashing function.
if (shortened) {
unsigned int processed = 0;
for (unsigned int job;(job = std::min(mesh->mNumFaces-processed,512u));processed += job) {
uint32_t hash = 0;
for (unsigned int a = 0; a < job;++a) {
const aiFace& f = mesh->mFaces[processed+a];
uint32_t tmp = f.mNumIndices;
hash = SuperFastHash(reinterpret_cast<const char*>(&tmp),sizeof tmp,hash);
for (unsigned int i = 0; i < f.mNumIndices; ++i) {
BOOST_STATIC_ASSERT(AI_MAX_VERTICES <= 0xffffffff);
tmp = static_cast<uint32_t>( f.mIndices[i] );
hash = SuperFastHash(reinterpret_cast<const char*>(&tmp),sizeof tmp,hash);
}
}
Write<unsigned int>(&chunk,hash);
}
}
else // else write as usual
{
// if there are less than 2^16 vertices, we can simply use 16 bit integers ...
for (unsigned int i = 0; i < mesh->mNumFaces;++i) {
const aiFace& f = mesh->mFaces[i];
BOOST_STATIC_ASSERT(AI_MAX_FACE_INDICES <= 0xffff);
Write<uint16_t>(&chunk,f.mNumIndices);
for (unsigned int a = 0; a < f.mNumIndices;++a) {
if (mesh->mNumVertices < (1u<<16)) {
Write<uint16_t>(&chunk,f.mIndices[a]);
}
else Write<unsigned int>(&chunk,f.mIndices[a]);
}
}
}
// write bones
if (mesh->mNumBones) {
for (unsigned int a = 0; a < mesh->mNumBones;++a) {
const aiBone* b = mesh->mBones[a];
WriteBinaryBone(&chunk,b);
}
}
}
// -----------------------------------------------------------------------------------
void WriteBinaryMaterialProperty(IOStream * container, const aiMaterialProperty* prop)
{
AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIALPROPERTY );
Write<aiString>(&chunk,prop->mKey);
Write<unsigned int>(&chunk,prop->mSemantic);
Write<unsigned int>(&chunk,prop->mIndex);
Write<unsigned int>(&chunk,prop->mDataLength);
Write<unsigned int>(&chunk,(unsigned int)prop->mType);
chunk.Write(prop->mData,1,prop->mDataLength);
}
// -----------------------------------------------------------------------------------
void WriteBinaryMaterial(IOStream * container, const aiMaterial* mat)
{
AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIAL);
Write<unsigned int>(&chunk,mat->mNumProperties);
for (unsigned int i = 0; i < mat->mNumProperties;++i) {
WriteBinaryMaterialProperty( &chunk, mat->mProperties[i]);
}
}
// -----------------------------------------------------------------------------------
void WriteBinaryNodeAnim(IOStream * container, const aiNodeAnim* nd)
{
AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODEANIM );
Write<aiString>(&chunk,nd->mNodeName);
Write<unsigned int>(&chunk,nd->mNumPositionKeys);
Write<unsigned int>(&chunk,nd->mNumRotationKeys);
Write<unsigned int>(&chunk,nd->mNumScalingKeys);
Write<unsigned int>(&chunk,nd->mPreState);
Write<unsigned int>(&chunk,nd->mPostState);
if (nd->mPositionKeys) {
if (shortened) {
WriteBounds(&chunk,nd->mPositionKeys,nd->mNumPositionKeys);
} // else write as usual
else WriteArray<aiVectorKey>(&chunk,nd->mPositionKeys,nd->mNumPositionKeys);
}
if (nd->mRotationKeys) {
if (shortened) {
WriteBounds(&chunk,nd->mRotationKeys,nd->mNumRotationKeys);
} // else write as usual
else WriteArray<aiQuatKey>(&chunk,nd->mRotationKeys,nd->mNumRotationKeys);
}
if (nd->mScalingKeys) {
if (shortened) {
WriteBounds(&chunk,nd->mScalingKeys,nd->mNumScalingKeys);
} // else write as usual
else WriteArray<aiVectorKey>(&chunk,nd->mScalingKeys,nd->mNumScalingKeys);
}
}
// -----------------------------------------------------------------------------------
void WriteBinaryAnim( IOStream * container, const aiAnimation* anim )
{
AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIANIMATION );
Write<aiString>(&chunk,anim->mName);
Write<double>(&chunk,anim->mDuration);
Write<double>(&chunk,anim->mTicksPerSecond);
Write<unsigned int>(&chunk,anim->mNumChannels);
for (unsigned int a = 0; a < anim->mNumChannels;++a) {
const aiNodeAnim* nd = anim->mChannels[a];
WriteBinaryNodeAnim(&chunk,nd);
}
}
// -----------------------------------------------------------------------------------
void WriteBinaryLight( IOStream * container, const aiLight* l )
{
AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AILIGHT );
Write<aiString>(&chunk,l->mName);
Write<unsigned int>(&chunk,l->mType);
if (l->mType != aiLightSource_DIRECTIONAL) {
Write<float>(&chunk,l->mAttenuationConstant);
Write<float>(&chunk,l->mAttenuationLinear);
Write<float>(&chunk,l->mAttenuationQuadratic);
}
Write<aiVector3D>(&chunk,(const aiVector3D&)l->mColorDiffuse);
Write<aiVector3D>(&chunk,(const aiVector3D&)l->mColorSpecular);
Write<aiVector3D>(&chunk,(const aiVector3D&)l->mColorAmbient);
if (l->mType == aiLightSource_SPOT) {
Write<float>(&chunk,l->mAngleInnerCone);
Write<float>(&chunk,l->mAngleOuterCone);
}
}
// -----------------------------------------------------------------------------------
void WriteBinaryCamera( IOStream * container, const aiCamera* cam )
{
AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AICAMERA );
Write<aiString>(&chunk,cam->mName);
Write<aiVector3D>(&chunk,cam->mPosition);
Write<aiVector3D>(&chunk,cam->mLookAt);
Write<aiVector3D>(&chunk,cam->mUp);
Write<float>(&chunk,cam->mHorizontalFOV);
Write<float>(&chunk,cam->mClipPlaneNear);
Write<float>(&chunk,cam->mClipPlaneFar);
Write<float>(&chunk,cam->mAspect);
}
// -----------------------------------------------------------------------------------
void WriteBinaryScene( IOStream * container, const aiScene* scene)
{
AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AISCENE );
// basic scene information
Write<unsigned int>(&chunk,scene->mFlags);
Write<unsigned int>(&chunk,scene->mNumMeshes);
Write<unsigned int>(&chunk,scene->mNumMaterials);
Write<unsigned int>(&chunk,scene->mNumAnimations);
Write<unsigned int>(&chunk,scene->mNumTextures);
Write<unsigned int>(&chunk,scene->mNumLights);
Write<unsigned int>(&chunk,scene->mNumCameras);
// write node graph
WriteBinaryNode( &chunk, scene->mRootNode );
// write all meshes
for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
const aiMesh* mesh = scene->mMeshes[i];
WriteBinaryMesh( &chunk,mesh);
}
// write materials
for (unsigned int i = 0; i< scene->mNumMaterials; ++i) {
const aiMaterial* mat = scene->mMaterials[i];
WriteBinaryMaterial(&chunk,mat);
}
// write all animations
for (unsigned int i = 0; i < scene->mNumAnimations;++i) {
const aiAnimation* anim = scene->mAnimations[i];
WriteBinaryAnim(&chunk,anim);
}
// write all textures
for (unsigned int i = 0; i < scene->mNumTextures;++i) {
const aiTexture* mesh = scene->mTextures[i];
WriteBinaryTexture(&chunk,mesh);
}
// write lights
for (unsigned int i = 0; i < scene->mNumLights;++i) {
const aiLight* l = scene->mLights[i];
WriteBinaryLight(&chunk,l);
}
// write cameras
for (unsigned int i = 0; i < scene->mNumCameras;++i) {
const aiCamera* cam = scene->mCameras[i];
WriteBinaryCamera(&chunk,cam);
}
}
public:
AssbinExport()
: shortened(false), compressed(false) // temporary settings until properties are introduced for exporters
{
}
// -----------------------------------------------------------------------------------
// Write a binary model dump
void WriteBinaryDump(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene)
{
IOStream * out = pIOSystem->Open( pFile, "wb" );
if (!out) return;
time_t tt = time(NULL);
tm* p = gmtime(&tt);
// header
char s[64];
memset( s, 0, 64 );
#if _MSC_VER >= 1400
sprintf_s(s,"ASSIMP.binary-dump.%s",asctime(p));
#else
snprintf(s,64,"ASSIMP.binary-dump.%s",asctime(p));
#endif
out->Write( s, 44, 1 );
// == 44 bytes
Write<unsigned int>( out, ASSBIN_VERSION_MAJOR );
Write<unsigned int>( out, ASSBIN_VERSION_MINOR );
Write<unsigned int>( out, aiGetVersionRevision() );
Write<unsigned int>( out, aiGetCompileFlags() );
Write<uint16_t>( out, shortened );
Write<uint16_t>( out, compressed );
// == 20 bytes
char buff[256];
strncpy(buff,pFile,256);
out->Write(buff,sizeof(char),256);
char cmd[] = "\0";
strncpy(buff,cmd,128);
out->Write(buff,sizeof(char),128);
// leave 64 bytes free for future extensions
memset(buff,0xcd,64);
out->Write(buff,sizeof(char),64);
// == 435 bytes
// ==== total header size: 512 bytes
ai_assert( out->Tell() == ASSBIN_HEADER_LENGTH );
// Up to here the data is uncompressed. For compressed files, the rest
// is compressed using standard DEFLATE from zlib.
if (compressed)
{
AssbinChunkWriter uncompressedStream( NULL, 0 );
WriteBinaryScene( &uncompressedStream, pScene );
uLongf uncompressedSize = uncompressedStream.Tell();
uLongf compressedSize = (uLongf)(uncompressedStream.Tell() * 1.001 + 12.);
uint8_t* compressedBuffer = new uint8_t[ compressedSize ];
compress2( compressedBuffer, &compressedSize, (const Bytef*)uncompressedStream.GetBufferPointer(), uncompressedSize, 9 );
out->Write( &uncompressedSize, sizeof(uint32_t), 1 );
out->Write( compressedBuffer, sizeof(char), compressedSize );
delete[] compressedBuffer;
}
else
{
WriteBinaryScene( out, pScene );
}
pIOSystem->Close( out );
}
};
void ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene)
{
AssbinExport exporter;
exporter.WriteBinaryDump( pFile, pIOSystem, pScene );
}
} // end of namespace Assimp
#endif // ASSIMP_BUILD_NO_ASSBIN_EXPORTER
#endif // ASSIMP_BUILD_NO_EXPORT

View File

@ -0,0 +1,49 @@
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2012, 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
following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
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
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
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
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
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** @file AssbinExporter.h
* ASSBIN Exporter Main Header
*/
#ifndef AI_ASSBINEXPORTER_H_INC
#define AI_ASSBINEXPORTER_H_INC
// nothing really needed here - reserved for future use like properties
#endif

View File

@ -0,0 +1,671 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2012, 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 following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
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
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
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
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
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
/** @file AssbinLoader.cpp
* @brief Implementation of the .assbin importer class
*
* see assbin_chunks.h
*/
#include "AssimpPCH.h"
#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER
// internal headers
#include "AssbinLoader.h"
#include "assbin_chunks.h"
#include "MemoryIOWrapper.h"
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
# include <zlib.h>
#else
# include "../contrib/zlib/zlib.h"
#endif
using namespace Assimp;
static const aiImporterDesc desc = {
".assbin Importer",
"Gargaj / Conspiracy",
"",
"",
aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportCompressedFlavour,
0,
0,
0,
0,
"assbin"
};
const aiImporterDesc* AssbinImporter::GetInfo() const
{
return &desc;
}
bool AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/ ) const
{
IOStream * in = pIOHandler->Open(pFile);
if (!in)
return false;
char s[32];
in->Read( s, sizeof(char), 32 );
pIOHandler->Close(in);
return strncmp( s, "ASSIMP.binary-dump.", 19 ) == 0;
}
template <typename T>
T Read(IOStream * stream)
{
T t;
stream->Read( &t, sizeof(T), 1 );
return t;
}
template <>
aiVector3D Read<aiVector3D>(IOStream * stream)
{
aiVector3D v;
v.x = Read<float>(stream);
v.y = Read<float>(stream);
v.z = Read<float>(stream);
return v;
}
template <>
aiColor4D Read<aiColor4D>(IOStream * stream)
{
aiColor4D c;
c.r = Read<float>(stream);
c.g = Read<float>(stream);
c.b = Read<float>(stream);
c.a = Read<float>(stream);
return c;
}
template <>
aiQuaternion Read<aiQuaternion>(IOStream * stream)
{
aiQuaternion v;
v.w = Read<float>(stream);
v.x = Read<float>(stream);
v.y = Read<float>(stream);
v.z = Read<float>(stream);
return v;
}
template <>
aiString Read<aiString>(IOStream * stream)
{
aiString s;
stream->Read(&s.length,4,1);
stream->Read(s.data,s.length,1);
return s;
}
template <>
aiVertexWeight Read<aiVertexWeight>(IOStream * stream)
{
aiVertexWeight w;
w.mVertexId = Read<unsigned int>(stream);
w.mWeight = Read<float>(stream);
return w;
}
template <>
aiMatrix4x4 Read<aiMatrix4x4>(IOStream * stream)
{
aiMatrix4x4 m;
for (unsigned int i = 0; i < 4;++i) {
for (unsigned int i2 = 0; i2 < 4;++i2) {
m[i][i2] = Read<float>(stream);
}
}
return m;
}
template <>
aiVectorKey Read<aiVectorKey>(IOStream * stream)
{
aiVectorKey v;
v.mTime = Read<double>(stream);
v.mValue = Read<aiVector3D>(stream);
return v;
}
template <>
aiQuatKey Read<aiQuatKey>(IOStream * stream)
{
aiQuatKey v;
v.mTime = Read<double>(stream);
v.mValue = Read<aiQuaternion>(stream);
return v;
}
template <typename T>
void ReadArray(IOStream * stream, T * out, unsigned int size)
{
for (unsigned int i=0; i<size; i++) out[i] = Read<T>(stream);
}
template <typename T> void ReadBounds( IOStream * stream, T* /*p*/, unsigned int n )
{
// not sure what to do here, the data isn't really useful.
stream->Seek( sizeof(T) * n, aiOrigin_CUR );
}
void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node )
{
ai_assert( Read<uint32_t>(stream) == ASSBIN_CHUNK_AINODE);
/*uint32_t size =*/ Read<uint32_t>(stream);
*node = new aiNode();
(*node)->mName = Read<aiString>(stream);
(*node)->mTransformation = Read<aiMatrix4x4>(stream);
(*node)->mNumChildren = Read<unsigned int>(stream);
(*node)->mNumMeshes = Read<unsigned int>(stream);
if ((*node)->mNumMeshes)
{
(*node)->mMeshes = new unsigned int[(*node)->mNumMeshes];
for (unsigned int i = 0; i < (*node)->mNumMeshes; ++i) {
(*node)->mMeshes[i] = Read<unsigned int>(stream);
}
}
if ((*node)->mNumChildren)
{
(*node)->mChildren = new aiNode*[(*node)->mNumChildren];
for (unsigned int i = 0; i < (*node)->mNumChildren; ++i) {
ReadBinaryNode( stream, &(*node)->mChildren[i] );
}
}
}
// -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b )
{
ai_assert( Read<uint32_t>(stream) == ASSBIN_CHUNK_AIBONE );
/*uint32_t size =*/ Read<uint32_t>(stream);
b->mName = Read<aiString>(stream);
b->mNumWeights = Read<unsigned int>(stream);
b->mOffsetMatrix = Read<aiMatrix4x4>(stream);
// for the moment we write dumb min/max values for the bones, too.
// maybe I'll add a better, hash-like solution later
if (shortened)
{
ReadBounds(stream,b->mWeights,b->mNumWeights);
} // else write as usual
else
{
b->mWeights = new aiVertexWeight[b->mNumWeights];
ReadArray<aiVertexWeight>(stream,b->mWeights,b->mNumWeights);
}
}
void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
{
ai_assert( Read<uint32_t>(stream) == ASSBIN_CHUNK_AIMESH);
/*uint32_t size =*/ Read<uint32_t>(stream);
mesh->mPrimitiveTypes = Read<unsigned int>(stream);
mesh->mNumVertices = Read<unsigned int>(stream);
mesh->mNumFaces = Read<unsigned int>(stream);
mesh->mNumBones = Read<unsigned int>(stream);
mesh->mMaterialIndex = Read<unsigned int>(stream);
// first of all, write bits for all existent vertex components
unsigned int c = Read<unsigned int>(stream);
if (c & ASSBIN_MESH_HAS_POSITIONS)
{
if (shortened) {
ReadBounds(stream,mesh->mVertices,mesh->mNumVertices);
} // else write as usual
else
{
mesh->mVertices = new aiVector3D[mesh->mNumVertices];
ReadArray<aiVector3D>(stream,mesh->mVertices,mesh->mNumVertices);
}
}
if (c & ASSBIN_MESH_HAS_NORMALS)
{
if (shortened) {
ReadBounds(stream,mesh->mNormals,mesh->mNumVertices);
} // else write as usual
else
{
mesh->mNormals = new aiVector3D[mesh->mNumVertices];
ReadArray<aiVector3D>(stream,mesh->mNormals,mesh->mNumVertices);
}
}
if (c & ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS)
{
if (shortened) {
ReadBounds(stream,mesh->mTangents,mesh->mNumVertices);
ReadBounds(stream,mesh->mBitangents,mesh->mNumVertices);
} // else write as usual
else
{
mesh->mTangents = new aiVector3D[mesh->mNumVertices];
ReadArray<aiVector3D>(stream,mesh->mTangents,mesh->mNumVertices);
mesh->mBitangents = new aiVector3D[mesh->mNumVertices];
ReadArray<aiVector3D>(stream,mesh->mBitangents,mesh->mNumVertices);
}
}
for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n)
{
if (!(c & ASSBIN_MESH_HAS_COLOR(n)))
break;
if (shortened)
{
ReadBounds(stream,mesh->mColors[n],mesh->mNumVertices);
} // else write as usual
else
{
mesh->mColors[n] = new aiColor4D[mesh->mNumVertices];
ReadArray<aiColor4D>(stream,mesh->mColors[n],mesh->mNumVertices);
}
}
for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n)
{
if (!(c & ASSBIN_MESH_HAS_TEXCOORD(n)))
break;
// write number of UV components
mesh->mNumUVComponents[n] = Read<unsigned int>(stream);
if (shortened) {
ReadBounds(stream,mesh->mTextureCoords[n],mesh->mNumVertices);
} // else write as usual
else
{
mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices];
ReadArray<aiVector3D>(stream,mesh->mTextureCoords[n],mesh->mNumVertices);
}
}
// write faces. There are no floating-point calculations involved
// in these, so we can write a simple hash over the face data
// to the dump file. We generate a single 32 Bit hash for 512 faces
// using Assimp's standard hashing function.
if (shortened) {
Read<unsigned int>(stream);
}
else // else write as usual
{
// if there are less than 2^16 vertices, we can simply use 16 bit integers ...
mesh->mFaces = new aiFace[mesh->mNumFaces];
for (unsigned int i = 0; i < mesh->mNumFaces;++i) {
aiFace& f = mesh->mFaces[i];
BOOST_STATIC_ASSERT(AI_MAX_FACE_INDICES <= 0xffff);
f.mNumIndices = Read<uint16_t>(stream);
f.mIndices = new unsigned int[f.mNumIndices];
for (unsigned int a = 0; a < f.mNumIndices;++a) {
if (mesh->mNumVertices < (1u<<16))
{
f.mIndices[a] = Read<uint16_t>(stream);
}
else
{
f.mIndices[a] = Read<unsigned int>(stream);
}
}
}
}
// write bones
if (mesh->mNumBones) {
mesh->mBones = new C_STRUCT aiBone*[mesh->mNumBones];
for (unsigned int a = 0; a < mesh->mNumBones;++a) {
mesh->mBones[a] = new aiBone();
ReadBinaryBone(stream,mesh->mBones[a]);
}
}
}
void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop)
{
ai_assert( Read<uint32_t>(stream) == ASSBIN_CHUNK_AIMATERIALPROPERTY);
/*uint32_t size =*/ Read<uint32_t>(stream);
prop->mKey = Read<aiString>(stream);
prop->mSemantic = Read<unsigned int>(stream);
prop->mIndex = Read<unsigned int>(stream);
prop->mDataLength = Read<unsigned int>(stream);
prop->mType = (aiPropertyTypeInfo)Read<unsigned int>(stream);
prop->mData = new char [ prop->mDataLength ];
stream->Read(prop->mData,1,prop->mDataLength);
}
// -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat)
{
ai_assert( Read<uint32_t>(stream) == ASSBIN_CHUNK_AIMATERIAL);
/*uint32_t size =*/ Read<uint32_t>(stream);
mat->mNumAllocated = mat->mNumProperties = Read<unsigned int>(stream);
if (mat->mNumProperties)
{
if (mat->mProperties)
{
delete[] mat->mProperties;
}
mat->mProperties = new aiMaterialProperty*[mat->mNumProperties];
for (unsigned int i = 0; i < mat->mNumProperties;++i) {
mat->mProperties[i] = new aiMaterialProperty();
ReadBinaryMaterialProperty( stream, mat->mProperties[i]);
}
}
}
// -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd)
{
ai_assert( Read<uint32_t>(stream) == ASSBIN_CHUNK_AINODEANIM);
/*uint32_t size =*/ Read<uint32_t>(stream);
nd->mNodeName = Read<aiString>(stream);
nd->mNumPositionKeys = Read<unsigned int>(stream);
nd->mNumRotationKeys = Read<unsigned int>(stream);
nd->mNumScalingKeys = Read<unsigned int>(stream);
nd->mPreState = (aiAnimBehaviour)Read<unsigned int>(stream);
nd->mPostState = (aiAnimBehaviour)Read<unsigned int>(stream);
if (nd->mNumPositionKeys) {
if (shortened) {
ReadBounds(stream,nd->mPositionKeys,nd->mNumPositionKeys);
} // else write as usual
else {
nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys];
ReadArray<aiVectorKey>(stream,nd->mPositionKeys,nd->mNumPositionKeys);
}
}
if (nd->mNumRotationKeys) {
if (shortened) {
ReadBounds(stream,nd->mRotationKeys,nd->mNumRotationKeys);
} // else write as usual
else
{
nd->mRotationKeys = new aiQuatKey[nd->mNumRotationKeys];
ReadArray<aiQuatKey>(stream,nd->mRotationKeys,nd->mNumRotationKeys);
}
}
if (nd->mNumScalingKeys) {
if (shortened) {
ReadBounds(stream,nd->mScalingKeys,nd->mNumScalingKeys);
} // else write as usual
else
{
nd->mScalingKeys = new aiVectorKey[nd->mNumScalingKeys];
ReadArray<aiVectorKey>(stream,nd->mScalingKeys,nd->mNumScalingKeys);
}
}
}
// -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim )
{
ai_assert( Read<uint32_t>(stream) == ASSBIN_CHUNK_AIANIMATION);
/*uint32_t size =*/ Read<uint32_t>(stream);
anim->mName = Read<aiString> (stream);
anim->mDuration = Read<double> (stream);
anim->mTicksPerSecond = Read<double> (stream);
anim->mNumChannels = Read<unsigned int>(stream);
if (anim->mNumChannels)
{
anim->mChannels = new aiNodeAnim*[ anim->mNumChannels ];
for (unsigned int a = 0; a < anim->mNumChannels;++a) {
anim->mChannels[a] = new aiNodeAnim();
ReadBinaryNodeAnim(stream,anim->mChannels[a]);
}
}
}
void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex)
{
ai_assert( Read<uint32_t>(stream) == ASSBIN_CHUNK_AITEXTURE);
/*uint32_t size =*/ Read<uint32_t>(stream);
tex->mWidth = Read<unsigned int>(stream);
tex->mHeight = Read<unsigned int>(stream);
stream->Read( tex->achFormatHint, sizeof(char), 4 );
if(!shortened) {
if (!tex->mHeight) {
tex->pcData = new aiTexel[ tex->mWidth ];
stream->Read(tex->pcData,1,tex->mWidth);
}
else {
tex->pcData = new aiTexel[ tex->mWidth*tex->mHeight ];
stream->Read(tex->pcData,1,tex->mWidth*tex->mHeight*4);
}
}
}
// -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l )
{
ai_assert( Read<uint32_t>(stream) == ASSBIN_CHUNK_AILIGHT);
/*uint32_t size =*/ Read<uint32_t>(stream);
l->mName = Read<aiString>(stream);
l->mType = (aiLightSourceType)Read<unsigned int>(stream);
if (l->mType != aiLightSource_DIRECTIONAL) {
l->mAttenuationConstant = Read<float>(stream);
l->mAttenuationLinear = Read<float>(stream);
l->mAttenuationQuadratic = Read<float>(stream);
}
l->mColorDiffuse = Read<aiColor3D>(stream);
l->mColorSpecular = Read<aiColor3D>(stream);
l->mColorAmbient = Read<aiColor3D>(stream);
if (l->mType == aiLightSource_SPOT) {
l->mAngleInnerCone = Read<float>(stream);
l->mAngleOuterCone = Read<float>(stream);
}
}
// -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam )
{
ai_assert( Read<uint32_t>(stream) == ASSBIN_CHUNK_AICAMERA);
/*uint32_t size =*/ Read<uint32_t>(stream);
cam->mName = Read<aiString>(stream);
cam->mPosition = Read<aiVector3D>(stream);
cam->mLookAt = Read<aiVector3D>(stream);
cam->mUp = Read<aiVector3D>(stream);
cam->mHorizontalFOV = Read<float>(stream);
cam->mClipPlaneNear = Read<float>(stream);
cam->mClipPlaneFar = Read<float>(stream);
cam->mAspect = Read<float>(stream);
}
void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
{
ai_assert( Read<uint32_t>(stream) == ASSBIN_CHUNK_AISCENE);
/*uint32_t size =*/ Read<uint32_t>(stream);
scene->mFlags = Read<unsigned int>(stream);
scene->mNumMeshes = Read<unsigned int>(stream);
scene->mNumMaterials = Read<unsigned int>(stream);
scene->mNumAnimations = Read<unsigned int>(stream);
scene->mNumTextures = Read<unsigned int>(stream);
scene->mNumLights = Read<unsigned int>(stream);
scene->mNumCameras = Read<unsigned int>(stream);
// Read node graph
scene->mRootNode = new aiNode[1];
ReadBinaryNode( stream, &scene->mRootNode );
// Read all meshes
if (scene->mNumMeshes)
{
scene->mMeshes = new aiMesh*[scene->mNumMeshes];
for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
scene->mMeshes[i] = new aiMesh();
ReadBinaryMesh( stream,scene->mMeshes[i]);
}
}
// Read materials
if (scene->mNumMaterials)
{
scene->mMaterials = new aiMaterial*[scene->mNumMaterials];
for (unsigned int i = 0; i< scene->mNumMaterials; ++i) {
scene->mMaterials[i] = new aiMaterial();
ReadBinaryMaterial(stream,scene->mMaterials[i]);
}
}
// Read all animations
if (scene->mNumAnimations)
{
scene->mAnimations = new aiAnimation*[scene->mNumAnimations];
for (unsigned int i = 0; i < scene->mNumAnimations;++i) {
scene->mAnimations[i] = new aiAnimation();
ReadBinaryAnim(stream,scene->mAnimations[i]);
}
}
// Read all textures
if (scene->mNumTextures)
{
scene->mTextures = new aiTexture*[scene->mNumTextures];
for (unsigned int i = 0; i < scene->mNumTextures;++i) {
scene->mTextures[i] = new aiTexture();
ReadBinaryTexture(stream,scene->mTextures[i]);
}
}
// Read lights
if (scene->mNumLights)
{
scene->mLights = new aiLight*[scene->mNumLights];
for (unsigned int i = 0; i < scene->mNumLights;++i) {
scene->mLights[i] = new aiLight();
ReadBinaryLight(stream,scene->mLights[i]);
}
}
// Read cameras
if (scene->mNumCameras)
{
scene->mCameras = new aiCamera*[scene->mNumCameras];
for (unsigned int i = 0; i < scene->mNumCameras;++i) {
scene->mCameras[i] = new aiCamera();
ReadBinaryCamera(stream,scene->mCameras[i]);
}
}
}
void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler )
{
IOStream * stream = pIOHandler->Open(pFile,"rb");
if (!stream)
return;
stream->Seek( 44, aiOrigin_CUR ); // signature
/*unsigned int versionMajor =*/ Read<unsigned int>(stream);
/*unsigned int versionMinor =*/ Read<unsigned int>(stream);
/*unsigned int versionRevision =*/ Read<unsigned int>(stream);
/*unsigned int compileFlags =*/ Read<unsigned int>(stream);
shortened = Read<uint16_t>(stream) > 0;
compressed = Read<uint16_t>(stream) > 0;
if (shortened)
throw DeadlyImportError( "Shortened binaries are not supported!" );
stream->Seek( 256, aiOrigin_CUR ); // original filename
stream->Seek( 128, aiOrigin_CUR ); // options
stream->Seek( 64, aiOrigin_CUR ); // padding
if (compressed)
{
uLongf uncompressedSize = Read<uint32_t>(stream);
uLongf compressedSize = stream->FileSize() - stream->Tell();
unsigned char * compressedData = new unsigned char[ compressedSize ];
stream->Read( compressedData, 1, compressedSize );
unsigned char * uncompressedData = new unsigned char[ uncompressedSize ];
uncompress( uncompressedData, &uncompressedSize, compressedData, compressedSize );
MemoryIOStream io( uncompressedData, uncompressedSize );
ReadBinaryScene(&io,pScene);
delete[] uncompressedData;
delete[] compressedData;
}
else
{
ReadBinaryScene(stream,pScene);
}
pIOHandler->Close(stream);
}
#endif // !! ASSIMP_BUILD_NO_ASSBIN_IMPORTER

View File

@ -0,0 +1,94 @@
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2012, 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
following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
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
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
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
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
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** @file AssbinLoader.h
* @brief .assbin File format loader
*/
#ifndef AI_ASSBINIMPORTER_H_INC
#define AI_ASSBINIMPORTER_H_INC
#include "BaseImporter.h"
#include "../include/assimp/types.h"
#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER
namespace Assimp {
// ---------------------------------------------------------------------------------
/** Importer class for 3D Studio r3 and r4 3DS files
*/
class AssbinImporter : public BaseImporter
{
private:
bool shortened;
bool compressed;
protected:
public:
virtual bool CanRead(
const std::string& pFile,
IOSystem* pIOHandler,
bool checkSig
) const;
virtual const aiImporterDesc* GetInfo() const;
virtual void InternReadFile(
const std::string& pFile,
aiScene* pScene,
IOSystem* pIOHandler
);
void ReadBinaryScene( IOStream * stream, aiScene* pScene );
void ReadBinaryNode( IOStream * stream, aiNode** mRootNode );
void ReadBinaryMesh( IOStream * stream, aiMesh* mesh );
void ReadBinaryBone( IOStream * stream, aiBone* bone );
void ReadBinaryMaterial(IOStream * stream, aiMaterial* mat);
void ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop);
void ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd);
void ReadBinaryAnim( IOStream * stream, aiAnimation* anim );
void ReadBinaryTexture(IOStream * stream, aiTexture* tex);
void ReadBinaryLight( IOStream * stream, aiLight* l );
void ReadBinaryCamera( IOStream * stream, aiCamera* cam );
};
} // end of namespace Assimp
#endif // !! ASSIMP_BUILD_NO_ASSBIN_IMPORTER
#endif // AI_ASSBINIMPORTER_H_INC

View File

@ -999,7 +999,7 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
}
// ------------------------------------------------------------------------------------------------
aiCamera* BlenderImporter::ConvertCamera(const Scene& /*in*/, const Object* obj, const Camera* camera, ConversionData& /*conv_data*/)
aiCamera* BlenderImporter::ConvertCamera(const Scene& /*in*/, const Object* obj, const Camera* /*camera*/, ConversionData& /*conv_data*/)
{
ScopeGuard<aiCamera> out(new aiCamera());
out->mName = obj->id.name+2;
@ -1010,7 +1010,7 @@ aiCamera* BlenderImporter::ConvertCamera(const Scene& /*in*/, const Object* obj,
}
// ------------------------------------------------------------------------------------------------
aiLight* BlenderImporter::ConvertLight(const Scene& in, const Object* obj, const Lamp* lamp, ConversionData& conv_data)
aiLight* BlenderImporter::ConvertLight(const Scene& /*in*/, const Object* obj, const Lamp* lamp, ConversionData& /*conv_data*/)
{
ScopeGuard<aiLight> out(new aiLight());
out->mName = obj->id.name+2;

View File

@ -100,7 +100,7 @@ namespace boost {
};
// dummy
list_elem& operator = (const list_elem& other) {
list_elem& operator = (const list_elem& /*other*/) {
return *this;
}
@ -142,7 +142,7 @@ namespace boost {
return me.me;
}
};
};
}
// A very minimal implementation for up to 5 elements
template <typename T0 = detail::nulltype,
@ -278,6 +278,6 @@ namespace boost {
tuple <> t;
return t;
}
};
}
#endif // !! BOOST_TUPLE_INCLUDED

View File

@ -111,6 +111,7 @@ SET( Common_SRCS
MemoryIOWrapper.h
ParsingUtils.h
StreamReader.h
StreamWriter.h
StringComparison.h
SGSpatialSort.cpp
SGSpatialSort.h
@ -143,6 +144,7 @@ SET( Common_SRCS
LogAux.h
Bitmap.cpp
Bitmap.h
XMLTools.h
)
SOURCE_GROUP(Common FILES ${Common_SRCS})
@ -151,6 +153,8 @@ SET( 3DS_SRCS
3DSHelper.h
3DSLoader.cpp
3DSLoader.h
3DSExporter.h
3DSExporter.cpp
)
SOURCE_GROUP(3DS FILES ${3DS_SRCS})
@ -168,6 +172,14 @@ SET( ASE_SRCS
)
SOURCE_GROUP( ASE FILES ${ASE_SRCS})
SET( ASSBIN_SRCS
AssbinExporter.h
AssbinExporter.cpp
AssbinLoader.h
AssbinLoader.cpp
)
SOURCE_GROUP( Assbin FILES ${ASSBIN_SRCS})
SET( B3D_SRCS
B3DImporter.cpp
B3DImporter.h
@ -612,7 +624,7 @@ SOURCE_GROUP( unzip FILES ${unzip_SRCS})
# VC2010 fixes
if(MSVC10)
OPTION( VC10_STDINT_FIX "Fix for VC10 Compiler regarding pstdint.h redefinition errors" OFF )
option( VC10_STDINT_FIX "Fix for VC10 Compiler regarding pstdint.h redefinition errors" OFF )
if( VC10_STDINT_FIX )
ADD_DEFINITIONS( -D_STDINT )
endif( VC10_STDINT_FIX )
@ -643,6 +655,7 @@ SET( assimp_src
${3DS_SRCS}
${AC_SRCS}
${ASE_SRCS}
${ASSBIN_SRCS}
${B3D_SRCS}
${BVH_SRCS}
${Collada_SRCS}

View File

@ -115,9 +115,9 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
// we assume that the mesh is still in the verbose vertex format where each face has its own set
// of vertices and no vertices are shared between faces. Sadly I don't know any quick test to
// assert() it here.
//assert( must be verbose, dammit);
// assert( must be verbose, dammit);
if (pMesh->mTangents) // thisimplies that mBitangents is also there
if (pMesh->mTangents) // this implies that mBitangents is also there
return false;
// If the mesh consists of lines and/or points but not of
@ -271,7 +271,7 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
const aiVector3D& origNorm = pMesh->mNormals[a];
const aiVector3D& origTang = pMesh->mTangents[a];
const aiVector3D& origBitang = pMesh->mBitangents[a];
closeVertices.clear();
closeVertices.resize( 0 );
// find all vertices close to that position
vertexFinder->FindPositions( origPos, posEpsilon, verticesFound);

View File

@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "Bitmap.h"
#include "fast_atof.h"
#include "SceneCombiner.h"
#include "XMLTools.h"
#include <ctime>
#include <set>
@ -93,6 +94,7 @@ void ExportSceneCollada(const char* pFile, IOSystem* pIOSystem, const aiScene* p
} // end of namespace Assimp
// ------------------------------------------------------------------------------------------------
// Constructor for a specific scene to export
ColladaExporter::ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file) : mIOSystem(pIOSystem), mPath(path), mFile(file)
@ -140,7 +142,7 @@ void ColladaExporter::WriteFile()
// useless Collada fu at the end, just in case we haven't had enough indirections, yet.
mOutput << startstr << "<scene>" << endstr;
PushTag();
mOutput << startstr << "<instance_visual_scene url=\"#" + std::string(mScene->mRootNode->mName.C_Str()) + "\" />" << endstr;
mOutput << startstr << "<instance_visual_scene url=\"#" + XMLEscape(mScene->mRootNode->mName.C_Str()) + "\" />" << endstr;
PopTag();
mOutput << startstr << "</scene>" << endstr;
PopTag();
@ -236,12 +238,12 @@ void ColladaExporter::WriteHeader()
if (!meta || !meta->Get("Author", value))
mOutput << startstr << "<author>" << "Assimp" << "</author>" << endstr;
else
mOutput << startstr << "<author>" << value.C_Str() << "</author>" << endstr;
mOutput << startstr << "<author>" << XMLEscape(value.C_Str()) << "</author>" << endstr;
if (!meta || !meta->Get("AuthoringTool", value))
mOutput << startstr << "<authoring_tool>" << "Assimp Exporter" << "</authoring_tool>" << endstr;
else
mOutput << startstr << "<authoring_tool>" << value.C_Str() << "</authoring_tool>" << endstr;
mOutput << startstr << "<authoring_tool>" << XMLEscape(value.C_Str()) << "</authoring_tool>" << endstr;
//mOutput << startstr << "<author>" << mScene->author.C_Str() << "</author>" << endstr;
//mOutput << startstr << "<authoring_tool>" << mScene->authoringTool.C_Str() << "</authoring_tool>" << endstr;
@ -342,16 +344,20 @@ void ColladaExporter::WriteImageEntry( const Surface& pSurface, const std::strin
{
if( !pSurface.texture.empty() )
{
mOutput << startstr << "<image id=\"" << pNameAdd << "\">" << endstr;
mOutput << startstr << "<image id=\"" << XMLEscape(pNameAdd) << "\">" << endstr;
PushTag();
mOutput << startstr << "<init_from>";
// URL encode image file name first, then XML encode on top
std::stringstream imageUrlEncoded;
for( std::string::const_iterator it = pSurface.texture.begin(); it != pSurface.texture.end(); ++it )
{
if( isalnum( *it) || *it == '_' || *it == '.' || *it == '/' || *it == '\\' )
mOutput << *it;
imageUrlEncoded << *it;
else
mOutput << '%' << std::hex << size_t( (unsigned char) *it) << std::dec;
imageUrlEncoded << '%' << std::hex << size_t( (unsigned char) *it) << std::dec;
}
mOutput << XMLEscape(imageUrlEncoded.str());
mOutput << "</init_from>" << endstr;
PopTag();
mOutput << startstr << "</image>" << endstr;
@ -371,7 +377,7 @@ void ColladaExporter::WriteTextureColorEntry( const Surface& pSurface, const std
}
else
{
mOutput << startstr << "<texture texture=\"" << pImageName << "\" texcoord=\"CHANNEL" << pSurface.channel << "\" />" << endstr;
mOutput << startstr << "<texture texture=\"" << XMLEscape(pImageName) << "\" texcoord=\"CHANNEL" << pSurface.channel << "\" />" << endstr;
}
PopTag();
mOutput << startstr << "</" << pTypeName << ">" << endstr;
@ -385,21 +391,21 @@ void ColladaExporter::WriteTextureParamEntry( const Surface& pSurface, const std
// if surface is a texture, write out the sampler and the surface parameters necessary to reference the texture
if( !pSurface.texture.empty() )
{
mOutput << startstr << "<newparam sid=\"" << pMatName << "-" << pTypeName << "-surface\">" << endstr;
mOutput << startstr << "<newparam sid=\"" << XMLEscape(pMatName) << "-" << pTypeName << "-surface\">" << endstr;
PushTag();
mOutput << startstr << "<surface type=\"2D\">" << endstr;
PushTag();
mOutput << startstr << "<init_from>" << pMatName << "-" << pTypeName << "-image</init_from>" << endstr;
mOutput << startstr << "<init_from>" << XMLEscape(pMatName) << "-" << pTypeName << "-image</init_from>" << endstr;
PopTag();
mOutput << startstr << "</surface>" << endstr;
PopTag();
mOutput << startstr << "</newparam>" << endstr;
mOutput << startstr << "<newparam sid=\"" << pMatName << "-" << pTypeName << "-sampler\">" << endstr;
mOutput << startstr << "<newparam sid=\"" << XMLEscape(pMatName) << "-" << pTypeName << "-sampler\">" << endstr;
PushTag();
mOutput << startstr << "<sampler2D>" << endstr;
PushTag();
mOutput << startstr << "<source>" << pMatName << "-" << pTypeName << "-surface</source>" << endstr;
mOutput << startstr << "<source>" << XMLEscape(pMatName) << "-" << pTypeName << "-surface</source>" << endstr;
PopTag();
mOutput << startstr << "</sampler2D>" << endstr;
PopTag();
@ -439,7 +445,7 @@ void ColladaExporter::WriteMaterials()
name = "mat";
materials[a].name = std::string( "m") + boost::lexical_cast<std::string> (a) + name.C_Str();
for( std::string::iterator it = materials[a].name.begin(); it != materials[a].name.end(); ++it ) {
// isalnum on MSVC asserts for code points in [0,255]. Thus prevent unwanted promotion
// isalnum on MSVC asserts for code points outside [0,255]. Thus prevent unwanted promotion
// of char to signed int and take the unsigned char value.
if( !isalnum( static_cast<uint8_t>(*it) ) ) {
*it = '_';
@ -510,7 +516,7 @@ void ColladaExporter::WriteMaterials()
{
const Material& mat = *it;
// this is so ridiculous it must be right
mOutput << startstr << "<effect id=\"" << mat.name << "-fx\" name=\"" << mat.name << "\">" << endstr;
mOutput << startstr << "<effect id=\"" << XMLEscape(mat.name) << "-fx\" name=\"" << XMLEscape(mat.name) << "\">" << endstr;
PushTag();
mOutput << startstr << "<profile_COMMON>" << endstr;
PushTag();
@ -561,9 +567,9 @@ void ColladaExporter::WriteMaterials()
for( std::vector<Material>::const_iterator it = materials.begin(); it != materials.end(); ++it )
{
const Material& mat = *it;
mOutput << startstr << "<material id=\"" << mat.name << "\" name=\"" << mat.name << "\">" << endstr;
mOutput << startstr << "<material id=\"" << XMLEscape(mat.name) << "\" name=\"" << mat.name << "\">" << endstr;
PushTag();
mOutput << startstr << "<instance_effect url=\"#" << mat.name << "-fx\"/>" << endstr;
mOutput << startstr << "<instance_effect url=\"#" << XMLEscape(mat.name) << "-fx\"/>" << endstr;
PopTag();
mOutput << startstr << "</material>" << endstr;
}
@ -591,13 +597,14 @@ void ColladaExporter::WriteGeometryLibrary()
void ColladaExporter::WriteGeometry( size_t pIndex)
{
const aiMesh* mesh = mScene->mMeshes[pIndex];
std::string idstr = GetMeshId( pIndex);
const std::string idstr = GetMeshId( pIndex);
const std::string idstrEscaped = XMLEscape(idstr);
if( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 )
return;
// opening tag
mOutput << startstr << "<geometry id=\"" << idstr << "\" name=\"" << idstr << "_name\" >" << endstr;
mOutput << startstr << "<geometry id=\"" << idstrEscaped << "\" name=\"" << idstrEscaped << "_name\" >" << endstr;
PushTag();
mOutput << startstr << "<mesh>" << endstr;
@ -627,20 +634,20 @@ void ColladaExporter::WriteGeometry( size_t pIndex)
}
// assemble vertex structure
mOutput << startstr << "<vertices id=\"" << idstr << "-vertices" << "\">" << endstr;
mOutput << startstr << "<vertices id=\"" << idstrEscaped << "-vertices" << "\">" << endstr;
PushTag();
mOutput << startstr << "<input semantic=\"POSITION\" source=\"#" << idstr << "-positions\" />" << endstr;
mOutput << startstr << "<input semantic=\"POSITION\" source=\"#" << idstrEscaped << "-positions\" />" << endstr;
if( mesh->HasNormals() )
mOutput << startstr << "<input semantic=\"NORMAL\" source=\"#" << idstr << "-normals\" />" << endstr;
mOutput << startstr << "<input semantic=\"NORMAL\" source=\"#" << idstrEscaped << "-normals\" />" << endstr;
for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a )
{
if( mesh->HasTextureCoords( a) )
mOutput << startstr << "<input semantic=\"TEXCOORD\" source=\"#" << idstr << "-tex" << a << "\" " /*<< "set=\"" << a << "\"" */ << " />" << endstr;
mOutput << startstr << "<input semantic=\"TEXCOORD\" source=\"#" << idstrEscaped << "-tex" << a << "\" " /*<< "set=\"" << a << "\"" */ << " />" << endstr;
}
for( size_t a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a )
{
if( mesh->HasVertexColors( a) )
mOutput << startstr << "<input semantic=\"COLOR\" source=\"#" << idstr << "-color" << a << "\" " /*<< set=\"" << a << "\"" */ << " />" << endstr;
mOutput << startstr << "<input semantic=\"COLOR\" source=\"#" << idstrEscaped << "-color" << a << "\" " /*<< set=\"" << a << "\"" */ << " />" << endstr;
}
PopTag();
@ -660,7 +667,7 @@ void ColladaExporter::WriteGeometry( size_t pIndex)
{
mOutput << startstr << "<lines count=\"" << countLines << "\" material=\"defaultMaterial\">" << endstr;
PushTag();
mOutput << startstr << "<input offset=\"0\" semantic=\"VERTEX\" source=\"#" << idstr << "-vertices\" />" << endstr;
mOutput << startstr << "<input offset=\"0\" semantic=\"VERTEX\" source=\"#" << idstrEscaped << "-vertices\" />" << endstr;
mOutput << startstr << "<p>";
for( size_t a = 0; a < mesh->mNumFaces; ++a )
{
@ -681,7 +688,7 @@ void ColladaExporter::WriteGeometry( size_t pIndex)
{
mOutput << startstr << "<polylist count=\"" << countPoly << "\" material=\"defaultMaterial\">" << endstr;
PushTag();
mOutput << startstr << "<input offset=\"0\" semantic=\"VERTEX\" source=\"#" << idstr << "-vertices\" />" << endstr;
mOutput << startstr << "<input offset=\"0\" semantic=\"VERTEX\" source=\"#" << idstrEscaped << "-vertices\" />" << endstr;
mOutput << startstr << "<vcount>";
for( size_t a = 0; a < mesh->mNumFaces; ++a )
@ -728,11 +735,11 @@ void ColladaExporter::WriteFloatArray( const std::string& pIdString, FloatDataTy
std::string arrayId = pIdString + "-array";
mOutput << startstr << "<source id=\"" << pIdString << "\" name=\"" << pIdString << "\">" << endstr;
mOutput << startstr << "<source id=\"" << XMLEscape(pIdString) << "\" name=\"" << XMLEscape(pIdString) << "\">" << endstr;
PushTag();
// source array
mOutput << startstr << "<float_array id=\"" << arrayId << "\" count=\"" << pElementCount * floatsPerElement << "\"> ";
mOutput << startstr << "<float_array id=\"" << XMLEscape(arrayId) << "\" count=\"" << pElementCount * floatsPerElement << "\"> ";
PushTag();
if( pType == FloatType_TexCoord2 )
@ -804,11 +811,11 @@ void ColladaExporter::WriteFloatArray( const std::string& pIdString, FloatDataTy
// Writes the scene library
void ColladaExporter::WriteSceneLibrary()
{
std::string scene_name = mScene->mRootNode->mName.C_Str();
const std::string scene_name_escaped = XMLEscape(mScene->mRootNode->mName.C_Str());
mOutput << startstr << "<library_visual_scenes>" << endstr;
PushTag();
mOutput << startstr << "<visual_scene id=\"" + scene_name + "\" name=\"" + scene_name + "\">" << endstr;
mOutput << startstr << "<visual_scene id=\"" + scene_name_escaped + "\" name=\"" + scene_name_escaped + "\">" << endstr;
PushTag();
// start recursive write at the root node
@ -833,7 +840,8 @@ void ColladaExporter::WriteNode(aiNode* pNode)
pNode->mName.Set(ss.str());
}
mOutput << startstr << "<node id=\"" << pNode->mName.data << "\" name=\"" << pNode->mName.data << "\">" << endstr;
const std::string node_name_escaped = XMLEscape(pNode->mName.data);
mOutput << startstr << "<node id=\"" << node_name_escaped << "\" name=\"" << node_name_escaped << "\">" << endstr;
PushTag();
// write transformation - we can directly put the matrix there
@ -854,13 +862,13 @@ void ColladaExporter::WriteNode(aiNode* pNode)
if( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 )
continue;
mOutput << startstr << "<instance_geometry url=\"#" << GetMeshId( pNode->mMeshes[a]) << "\">" << endstr;
mOutput << startstr << "<instance_geometry url=\"#" << XMLEscape(GetMeshId( pNode->mMeshes[a])) << "\">" << endstr;
PushTag();
mOutput << startstr << "<bind_material>" << endstr;
PushTag();
mOutput << startstr << "<technique_common>" << endstr;
PushTag();
mOutput << startstr << "<instance_material symbol=\"defaultMaterial\" target=\"#" << materials[mesh->mMaterialIndex].name << "\" />" << endstr;
mOutput << startstr << "<instance_material symbol=\"defaultMaterial\" target=\"#" << XMLEscape(materials[mesh->mMaterialIndex].name) << "\" />" << endstr;
PopTag();
mOutput << startstr << "</technique_common>" << endstr;
PopTag();

View File

@ -57,12 +57,15 @@ using namespace Assimp;
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
MakeLeftHandedProcess::MakeLeftHandedProcess()
{}
: BaseProcess() {
// empty
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
MakeLeftHandedProcess::~MakeLeftHandedProcess()
{}
MakeLeftHandedProcess::~MakeLeftHandedProcess() {
// empty
}
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
@ -121,8 +124,9 @@ void MakeLeftHandedProcess::ProcessNode( aiNode* pNode, const aiMatrix4x4& pPare
pNode->mTransformation.d3 = -pNode->mTransformation.d3; // useless, but anyways...
// continue for all children
for( size_t a = 0; a < pNode->mNumChildren; ++a)
ProcessNode( pNode->mChildren[a], pParentGlobalRotation * pNode->mTransformation);
for( size_t a = 0; a < pNode->mNumChildren; ++a ) {
ProcessNode( pNode->mChildren[ a ], pParentGlobalRotation * pNode->mTransformation );
}
}
// ------------------------------------------------------------------------------------------------
@ -244,6 +248,10 @@ void FlipUVsProcess::ProcessMaterial (aiMaterial* _mat)
aiMaterial* mat = (aiMaterial*)_mat;
for (unsigned int a = 0; a < mat->mNumProperties;++a) {
aiMaterialProperty* prop = mat->mProperties[a];
if( !prop ) {
DefaultLogger::get()->debug( "Property is null" );
continue;
}
// UV transformation key?
if (!::strcmp( prop->mKey.data, "$tex.uvtrafo")) {
@ -263,11 +271,13 @@ void FlipUVsProcess::ProcessMesh( aiMesh* pMesh)
{
// mirror texture y coordinate
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
if( !pMesh->HasTextureCoords( a))
break;
if( !pMesh->HasTextureCoords( a ) ) {
break;
}
for( unsigned int b = 0; b < pMesh->mNumVertices; b++)
pMesh->mTextureCoords[a][b].y = 1.0f - pMesh->mTextureCoords[a][b].y;
for( unsigned int b = 0; b < pMesh->mNumVertices; b++ ) {
pMesh->mTextureCoords[ a ][ b ].y = 1.0f - pMesh->mTextureCoords[ a ][ b ].y;
}
}
}

View File

@ -111,8 +111,8 @@ void DeboneProcess::Execute( aiScene* pScene)
if(numSplits) {
// we need to do something. Let's go.
mSubMeshIndices.clear();
mSubMeshIndices.resize(pScene->mNumMeshes);
//mSubMeshIndices.clear(); // really needed?
mSubMeshIndices.resize(pScene->mNumMeshes); // because we're doing it here anyway
// build a new array of meshes for the scene
std::vector<aiMesh*> meshes;

View File

@ -78,7 +78,8 @@ void ExportSceneObj(const char*,IOSystem*, const aiScene*);
void ExportSceneSTL(const char*,IOSystem*, const aiScene*);
void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*);
void ExportScenePly(const char*,IOSystem*, const aiScene*);
void ExportScene3DS(const char*, IOSystem*, const aiScene*) {}
void ExportScene3DS(const char*, IOSystem*, const aiScene*);
void ExportSceneAssbin(const char*, IOSystem*, const aiScene*);
// ------------------------------------------------------------------------------------------------
// global array of all export formats which Assimp supports in its current build
@ -90,7 +91,7 @@ Exporter::ExportFormatEntry gExporters[] =
#ifndef ASSIMP_BUILD_NO_FXILE_EXPORTER
Exporter::ExportFormatEntry( "x", "X Files", "x", &ExportSceneXFile,
aiProcess_MakeLeftHanded | aiProcess_FlipWindingOrder | aiProcess_FlipUVs),
aiProcess_MakeLeftHanded | aiProcess_FlipWindingOrder | aiProcess_FlipUVs),
#endif
#ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER
@ -113,9 +114,14 @@ Exporter::ExportFormatEntry gExporters[] =
),
#endif
//#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
// ExportFormatEntry( "3ds", "Autodesk 3DS (legacy format)", "3ds" , &ExportScene3DS),
//#endif
#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
Exporter::ExportFormatEntry( "3ds", "Autodesk 3DS (legacy)", "3ds" , &ExportScene3DS,
aiProcess_Triangulate | aiProcess_SortByPType | aiProcess_JoinIdenticalVertices),
#endif
#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
Exporter::ExportFormatEntry( "assbin", "Assimp Binary", "assbin" , &ExportSceneAssbin, 0),
#endif
};
#define ASSIMP_NUM_EXPORTERS (sizeof(gExporters)/sizeof(gExporters[0]))

View File

@ -59,7 +59,7 @@ namespace FBX {
using namespace Util;
// ------------------------------------------------------------------------------------------------
AnimationCurve::AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& doc)
AnimationCurve::AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& /*doc*/)
: Object(id, element, name)
{
const Scope& sc = GetRequiredScope(element);

View File

@ -1319,7 +1319,7 @@ private:
// ------------------------------------------------------------------------------------------------
void ConvertCluster(std::vector<aiBone*>& bones, const Model& model, const Cluster& cl,
void ConvertCluster(std::vector<aiBone*>& bones, const Model& /*model*/, const Cluster& cl,
std::vector<size_t>& out_indices,
std::vector<size_t>& index_out_indices,
std::vector<size_t>& count_out_indices,
@ -2347,7 +2347,7 @@ private:
// ------------------------------------------------------------------------------------------------
aiNodeAnim* GenerateScalingNodeAnim(const std::string& name,
const Model& target,
const Model& /*target*/,
const std::vector<const AnimationCurveNode*>& curves,
const LayerMap& layer_map,
double& max_time,
@ -2378,7 +2378,7 @@ private:
// ------------------------------------------------------------------------------------------------
aiNodeAnim* GenerateTranslationNodeAnim(const std::string& name,
const Model& target,
const Model& /*target*/,
const std::vector<const AnimationCurveNode*>& curves,
const LayerMap& layer_map,
double& max_time,
@ -2830,7 +2830,7 @@ private:
// ------------------------------------------------------------------------------------------------
void ConvertScaleKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& layers,
void ConvertScaleKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& /*layers*/,
double& maxTime,
double& minTime)
{
@ -2851,7 +2851,7 @@ private:
// ------------------------------------------------------------------------------------------------
void ConvertTranslationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
const LayerMap& layers,
const LayerMap& /*layers*/,
double& maxTime,
double& minTime)
{
@ -2869,7 +2869,7 @@ private:
// ------------------------------------------------------------------------------------------------
void ConvertRotationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
const LayerMap& layers,
const LayerMap& /*layers*/,
double& maxTime,
double& minTime,
Model::RotOrder order)

View File

@ -253,8 +253,8 @@ Document::Document(const Parser& parser, const ImportSettings& settings)
: settings(settings)
, parser(parser)
{
// cannot use array default initialization syntax because vc8 fails on it
for (unsigned int i = 0; i < 7; ++i) {
// Cannot use array default initialization syntax because vc8 fails on it
for (unsigned int i = 0; i < sizeof(creationTimeStamp) / sizeof(creationTimeStamp[0]); ++i) {
creationTimeStamp[i] = 0;
}
@ -263,7 +263,7 @@ Document::Document(const Parser& parser, const ImportSettings& settings)
ReadGlobalSettings();
// this order is important, connections need parsed objects to check
// This order is important, connections need parsed objects to check
// whether connections are ok or not. Objects may not be evaluated yet,
// though, since this may require valid connections.
ReadObjects();
@ -277,13 +277,18 @@ Document::~Document()
BOOST_FOREACH(ObjectMap::value_type& v, objects) {
delete v.second;
}
BOOST_FOREACH(ConnectionMap::value_type& v, src_connections) {
delete v.second;
}
// |dest_connections| contain the same Connection objects as the |src_connections|
}
// ------------------------------------------------------------------------------------------------
void Document::ReadHeader()
{
// read ID objects from "Objects" section
// Read ID objects from "Objects" section
const Scope& sc = parser.GetRootScope();
const Element* const ehead = sc["FBXHeaderExtension"];
if(!ehead || !ehead->Compound()) {
@ -293,7 +298,7 @@ void Document::ReadHeader()
const Scope& shead = *ehead->Compound();
fbxVersion = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(shead,"FBXVersion",ehead),0));
// while we maye have some success with newer files, we don't support
// While we maye have some success with newer files, we don't support
// the older 6.n fbx format
if(fbxVersion < 7100) {
DOMError("unsupported, old format version, supported are only FBX 2011, FBX 2012 and FBX 2013");

View File

@ -696,7 +696,7 @@ public:
public:
/** Get the Skin attached to this geometry or NULL */
const Skin* const DeformerSkin() const {
const Skin* DeformerSkin() const {
return skin;
}
@ -1096,7 +1096,7 @@ public:
return transformLink;
}
const Model* const TargetNode() const {
const Model* TargetNode() const {
return node;
}

View File

@ -179,6 +179,8 @@ void FBXImporter::InternReadFile( const std::string& pFile,
// convert the FBX DOM to aiScene
ConvertToAssimpScene(pScene,doc);
std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>());
}
catch(std::exception&) {
std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>());

View File

@ -207,7 +207,7 @@ Texture::~Texture()
}
LayeredTexture::LayeredTexture(uint64_t id, const Element& element, const Document& doc, const std::string& name)
LayeredTexture::LayeredTexture(uint64_t id, const Element& element, const Document& /*doc*/, const std::string& name)
: Object(id,element,name)
,texture(0)
,blendMode(BlendMode_Modulate)

View File

@ -466,8 +466,9 @@ void MeshGeometry::ReadVertexDataTangents(std::vector<aiVector3D>& tangents_out,
const std::string& MappingInformationType,
const std::string& ReferenceInformationType)
{
const char * str = source.Elements().count( "Tangents" ) > 0 ? "Tangents" : "Tangent";
ResolveVertexDataArray(tangents_out,source,MappingInformationType,ReferenceInformationType,
"Tangent",
str,
"TangentIndex",
vertices.size(),
mapping_counts,
@ -481,8 +482,9 @@ void MeshGeometry::ReadVertexDataBinormals(std::vector<aiVector3D>& binormals_ou
const std::string& MappingInformationType,
const std::string& ReferenceInformationType)
{
const char * str = source.Elements().count( "Binormals" ) > 0 ? "Binormals" : "Binormal";
ResolveVertexDataArray(binormals_out,source,MappingInformationType,ReferenceInformationType,
"Binormal",
str,
"BinormalIndex",
vertices.size(),
mapping_counts,

View File

@ -93,7 +93,7 @@ namespace {
}
// ------------------------------------------------------------------------------------------------
void ParseWarning(const std::string& message, const Element* element = NULL)
/* void ParseWarning(const std::string& message, const Element* element = NULL)
{
if(element) {
ParseWarning(message,element->KeyToken());
@ -103,7 +103,7 @@ namespace {
DefaultLogger::get()->warn("FBX-Parser: " + message);
}
}
*/
// ------------------------------------------------------------------------------------------------
void ParseError(const std::string& message, TokenPtr token)
{
@ -113,6 +113,18 @@ namespace {
ParseError(message);
}
// Initially, we did reinterpret_cast, breaking strict aliasing rules.
// This actually caused trouble on Android, so let's be safe this time.
// https://github.com/assimp/assimp/issues/24
template <typename T>
T SafeParse(const char* data, const char* end) {
// Actual size validation happens during Tokenization so
// this is valid as an assertion.
ai_assert(static_cast<size_t>(end - data) >= sizeof(T));
T result = static_cast<T>(0);
::memcpy(&result, data, sizeof(T));
return result;
}
}
namespace Assimp {
@ -275,9 +287,7 @@ uint64_t ParseTokenAsID(const Token& t, const char*& err_out)
return 0L;
}
ai_assert(t.end() - data == 9);
BE_NCONST uint64_t id = *reinterpret_cast<const uint64_t*>(data+1);
BE_NCONST uint64_t id = SafeParse<uint64_t>(data+1, t.end());
AI_SWAP8(id);
return id;
}
@ -316,8 +326,7 @@ size_t ParseTokenAsDim(const Token& t, const char*& err_out)
return 0;
}
ai_assert(t.end() - data == 9);
BE_NCONST uint64_t id = *reinterpret_cast<const uint64_t*>(data+1);
BE_NCONST uint64_t id = SafeParse<uint64_t>(data+1, t.end());
AI_SWAP8(id);
return static_cast<size_t>(id);
}
@ -364,24 +373,10 @@ float ParseTokenAsFloat(const Token& t, const char*& err_out)
}
if (data[0] == 'F') {
// Actual size validation happens during Tokenization so
// this is valid as an assertion.
ai_assert(t.end() - data == sizeof(float) + 1);
// Initially, we did reinterpret_cast, breaking strict aliasing rules.
// This actually caused trouble on Android, so let's be safe this time.
// https://github.com/assimp/assimp/issues/24
float out_float;
::memcpy(&out_float, data+1, sizeof(float));
return out_float;
return SafeParse<float>(data+1, t.end());
}
else {
ai_assert(t.end() - data == sizeof(double) + 1);
// Same
double out_double;
::memcpy(&out_double, data+1, sizeof(double));
return static_cast<float>(out_double);
return SafeParse<double>(data+1, t.end());
}
}
@ -416,8 +411,7 @@ int ParseTokenAsInt(const Token& t, const char*& err_out)
return 0;
}
ai_assert(t.end() - data == 5);
BE_NCONST int32_t ival = *reinterpret_cast<const int32_t*>(data+1);
BE_NCONST int32_t ival = SafeParse<int32_t>(data+1, t.end());
AI_SWAP4(ival);
return static_cast<int>(ival);
}
@ -453,10 +447,8 @@ std::string ParseTokenAsString(const Token& t, const char*& err_out)
return "";
}
ai_assert(t.end() - data >= 5);
// read string length
BE_NCONST int32_t len = *reinterpret_cast<const int32_t*>(data+1);
BE_NCONST int32_t len = SafeParse<int32_t>(data+1, t.end());
AI_SWAP4(len);
ai_assert(t.end() - data == 5 + len);
@ -494,7 +486,7 @@ void ReadBinaryDataArrayHead(const char*& data, const char* end, char& type, uin
type = *data;
// read number of elements
BE_NCONST uint32_t len = *reinterpret_cast<const uint32_t*>(data+1);
BE_NCONST uint32_t len = SafeParse<uint32_t>(data+1, end);
AI_SWAP4(len);
count = len;
@ -506,16 +498,14 @@ void ReadBinaryDataArrayHead(const char*& data, const char* end, char& type, uin
// read binary data array, assume cursor points to the 'compression mode' field (i.e. behind the header)
void ReadBinaryDataArray(char type, uint32_t count, const char*& data, const char* end,
std::vector<char>& buff,
const Element& el)
const Element& /*el*/)
{
ai_assert(static_cast<size_t>(end-data) >= 4); // runtime check for this happens at tokenization stage
BE_NCONST uint32_t encmode = *reinterpret_cast<const uint32_t*>(data);
BE_NCONST uint32_t encmode = SafeParse<uint32_t>(data, end);
AI_SWAP4(encmode);
data += 4;
// next comes the compressed length
BE_NCONST uint32_t comp_len = *reinterpret_cast<const uint32_t*>(data);
BE_NCONST uint32_t comp_len = SafeParse<uint32_t>(data, end);
AI_SWAP4(comp_len);
data += 4;

View File

@ -105,7 +105,7 @@ Property* ReadTypedProperty(const Element& element)
ParseTokenAsFloat(*tok[6]))
);
}
else if (!strcmp(cs,"double") || !strcmp(cs,"Number") || !strcmp(cs,"KTime") || !strcmp(cs,"Float")) {
else if (!strcmp(cs,"double") || !strcmp(cs,"Number") || !strcmp(cs,"KTime") || !strcmp(cs,"Float") || !strcmp(cs,"FieldOfView")) {
return new TypedProperty<float>(ParseTokenAsFloat(*tok[4]));
}
return NULL;

View File

@ -143,8 +143,7 @@ private:
// ------------------------------------------------------------------------------------------------
template <typename T>
inline T PropertyGet(const PropertyTable& in, const std::string& name,
const T& defaultValue,
bool ignoreTemplate = false)
const T& defaultValue)
{
const Property* const prop = in.Get(name);
if(!prop) {
@ -164,8 +163,7 @@ inline T PropertyGet(const PropertyTable& in, const std::string& name,
// ------------------------------------------------------------------------------------------------
template <typename T>
inline T PropertyGet(const PropertyTable& in, const std::string& name,
bool& result,
bool ignoreTemplate = false)
bool& result)
{
const Property* const prop = in.Get(name);
if(!prop) {

View File

@ -174,7 +174,6 @@ void FindInstancesProcess::Execute( aiScene* pScene)
// use a constant epsilon for colors and UV coordinates
static const float uvEpsilon = 10e-4f;
{
unsigned int i, end = orig->GetNumUVChannels();
for(i = 0; i < end; ++i) {
@ -260,7 +259,7 @@ void FindInstancesProcess::Execute( aiScene* pScene)
pScene->mMeshes[real++] = pScene->mMeshes[i];
}
// And update the nodegraph with our nice lookup table
// And update the node graph with our nice lookup table
UpdateMeshIndices(pScene->mRootNode,remapping.get());
// write to log

View File

@ -93,7 +93,7 @@ void GenVertexNormalsProcess::Execute( aiScene* pScene)
bool bHas = false;
for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
{
if(GenMeshVertexNormals( pScene->mMeshes[a],a))
if(GenMeshVertexNormals( pScene->mMeshes[a],a))
bHas = true;
}

View File

@ -53,7 +53,7 @@ namespace Assimp {
// ---------------------------------------------------------------------------
/** The GenFaceNormalsProcess computes vertex normals for all vertizes
*/
class ASSIMP_API_WINONLY GenVertexNormalsProcess : public BaseProcess
class ASSIMP_API GenVertexNormalsProcess : public BaseProcess
{
public:

View File

@ -85,7 +85,7 @@ Intersect IntersectSegmentPlane(const IfcVector3& p,const IfcVector3& n, const I
// ------------------------------------------------------------------------------------------------
void ProcessBooleanHalfSpaceDifference(const IfcHalfSpaceSolid* hs, TempMesh& result,
const TempMesh& first_operand,
ConversionData& conv)
ConversionData& /*conv*/)
{
ai_assert(hs != NULL);

View File

@ -259,7 +259,7 @@ BoundingBox GetBoundingBox(const ClipperLib::Polygon& poly)
// ------------------------------------------------------------------------------------------------
void InsertWindowContours(const ContourVector& contours,
const std::vector<TempOpening>& openings,
const std::vector<TempOpening>& /*openings*/,
TempMesh& curmesh)
{
// fix windows - we need to insert the real, polygonal shapes into the quadratic holes that we have now
@ -1741,4 +1741,4 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
#undef from_int64
#undef one_vec
#endif
#endif

View File

@ -101,7 +101,7 @@ void ProcessOpenProfile(const IfcArbitraryOpenProfileDef& def, TempMesh& meshout
}
// ------------------------------------------------------------------------------------------------
void ProcessParametrizedProfile(const IfcParameterizedProfileDef& def, TempMesh& meshout, ConversionData& conv)
void ProcessParametrizedProfile(const IfcParameterizedProfileDef& def, TempMesh& meshout, ConversionData& /*conv*/)
{
if(const IfcRectangleProfileDef* const cprofile = def.ToPtr<IfcRectangleProfileDef>()) {
const IfcFloat x = cprofile->XDim*0.5f, y = cprofile->YDim*0.5f;

View File

@ -1045,7 +1045,7 @@ void IFC::GetSchema(EXPRESS::ConversionSchema& out)
namespace STEP {
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<NotImplemented>(const STEP::DB& db, const LIST& params, NotImplemented* in)
template <> size_t GenericFill<NotImplemented>(const STEP::DB& /*db*/, const LIST& /*params*/, NotImplemented* /*in*/)
{
return 0;
}
@ -1253,7 +1253,7 @@ template <> size_t GenericFill<IfcPerformanceHistory>(const DB& db, const LIST&
return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<IfcRepresentationItem>(const DB& db, const LIST& params, IfcRepresentationItem* in)
template <> size_t GenericFill<IfcRepresentationItem>(const DB& /*db*/, const LIST& /*params*/, IfcRepresentationItem* /*in*/)
{
size_t base = 0;
return base;
@ -1715,7 +1715,7 @@ template <> size_t GenericFill<IfcPlateType>(const DB& db, const LIST& params, I
return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<IfcObjectPlacement>(const DB& db, const LIST& params, IfcObjectPlacement* in)
template <> size_t GenericFill<IfcObjectPlacement>(const DB& /*db*/, const LIST& /*params*/, IfcObjectPlacement* /*in*/)
{
size_t base = 0;
return base;

View File

@ -640,16 +640,25 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags)
}
}
// Get file size for progress handler
IOStream * fileIO = pimpl->mIOHandler->Open( pFile );
uint32_t fileSize = 0;
if (fileIO)
{
fileSize = fileIO->FileSize();
pimpl->mIOHandler->Close( fileIO );
}
// Dispatch the reading to the worker class for this format
DefaultLogger::get()->info("Found a matching importer for this file format");
pimpl->mProgressHandler->Update();
pimpl->mProgressHandler->UpdateFileRead( 0, fileSize );
if (profiler) {
profiler->BeginRegion("import");
}
pimpl->mScene = imp->ReadFile( this, pFile, pimpl->mIOHandler);
pimpl->mProgressHandler->Update();
pimpl->mProgressHandler->UpdateFileRead( fileSize, fileSize );
if (profiler) {
profiler->EndRegion("import");
@ -678,7 +687,6 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags)
ScenePreprocessor pre(pimpl->mScene);
pre.ProcessScene();
pimpl->mProgressHandler->Update();
if (profiler) {
profiler->EndRegion("preprocess");
}
@ -768,6 +776,7 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags)
for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) {
BaseProcess* process = pimpl->mPostProcessingSteps[a];
pimpl->mProgressHandler->UpdatePostProcess( a, pimpl->mPostProcessingSteps.size() );
if( process->IsActive( pFlags)) {
if (profiler) {
@ -775,7 +784,6 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags)
}
process->ExecuteOnScene ( this );
pimpl->mProgressHandler->Update();
if (profiler) {
profiler->EndRegion("postprocess");
@ -803,6 +811,7 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags)
}
#endif // ! DEBUG
}
pimpl->mProgressHandler->UpdatePostProcess( pimpl->mPostProcessingSteps.size(), pimpl->mPostProcessingSteps.size() );
// update private scene flags
if( pimpl->mScene )

View File

@ -166,6 +166,9 @@ corresponding preprocessor flag to selectively disable formats.
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
# include "FBXImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER
# include "AssbinLoader.h"
#endif
namespace Assimp {
@ -291,6 +294,9 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out)
#if ( !defined ASSIMP_BUILD_NO_FBX_IMPORTER )
out.push_back( new FBXImporter() );
#endif
#if ( !defined ASSIMP_BUILD_NO_ASSBIN_IMPORTER )
out.push_back( new AssbinImporter() );
#endif
}
}

View File

@ -59,7 +59,7 @@ class JoinVerticesTest;
* erases all but one of the copies. This usually reduces the number of vertices
* in a mesh by a serious amount and is the standard form to render a mesh.
*/
class ASSIMP_API_WINONLY JoinVerticesProcess : public BaseProcess
class ASSIMP_API JoinVerticesProcess : public BaseProcess
{
public:

View File

@ -131,10 +131,15 @@ void LimitBoneWeightsProcess::ProcessMesh( aiMesh* pMesh)
// and renormalize the weights
float sum = 0.0f;
for( std::vector<Weight>::const_iterator it = vit->begin(); it != vit->end(); ++it)
sum += it->mWeight;
for( std::vector<Weight>::iterator it = vit->begin(); it != vit->end(); ++it)
it->mWeight /= sum;
for( std::vector<Weight>::const_iterator it = vit->begin(); it != vit->end(); ++it ) {
sum += it->mWeight;
}
if( 0.0f != sum ) {
const float invSum = 1.0f / sum;
for( std::vector<Weight>::iterator it = vit->begin(); it != vit->end(); ++it ) {
it->mWeight *= invSum;
}
}
}
if (bChanged) {
@ -157,18 +162,6 @@ void LimitBoneWeightsProcess::ProcessMesh( aiMesh* pMesh)
const std::vector<aiVertexWeight>& bw = boneWeights[a];
aiBone* bone = pMesh->mBones[a];
// ignore the bone if no vertex weights were removed there
// FIX (Aramis, 07|22|08)
// NO! we can't ignore it in this case ... it is possible that
// the number of weights did not change, but the weight values did.
// if( bw.size() == bone->mNumWeights)
// continue;
// FIX (Aramis, 07|21|08)
// It is possible that all weights of a bone have been removed.
// This would naturally cause an exception in &bw[0].
if ( bw.empty() )
{
abNoNeed[a] = bChanged = true;
@ -177,7 +170,7 @@ void LimitBoneWeightsProcess::ProcessMesh( aiMesh* pMesh)
// copy the weight list. should always be less weights than before, so we don't need a new allocation
ai_assert( bw.size() <= bone->mNumWeights);
bone->mNumWeights = (unsigned int) bw.size();
bone->mNumWeights = static_cast<unsigned int>( bw.size() );
::memcpy( bone->mWeights, &bw[0], bw.size() * sizeof( aiVertexWeight));
}

View File

@ -75,6 +75,7 @@ void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
} // end of namespace Assimp
static const std::string MaterialExt = ".mtl";
// ------------------------------------------------------------------------------------------------
ObjExporter :: ObjExporter(const char* _filename, const aiScene* pScene)
@ -107,7 +108,7 @@ std::string ObjExporter :: GetMaterialLibName()
// ------------------------------------------------------------------------------------------------
std::string ObjExporter :: GetMaterialLibFileName()
{
return filename + ".mtl";
return filename + MaterialExt;
}
// ------------------------------------------------------------------------------------------------
@ -132,7 +133,7 @@ std::string ObjExporter :: GetMaterialName(unsigned int index)
}
// ------------------------------------------------------------------------------------------------
void ObjExporter :: WriteMaterialFile()
void ObjExporter::WriteMaterialFile()
{
WriteHeader(mOutputMat);
@ -144,16 +145,16 @@ void ObjExporter :: WriteMaterialFile()
aiColor4D c;
if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_DIFFUSE,c)) {
mOutputMat << "kd " << c.r << " " << c.g << " " << c.b << endl;
mOutputMat << "Kd " << c.r << " " << c.g << " " << c.b << endl;
}
if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_AMBIENT,c)) {
mOutputMat << "ka " << c.r << " " << c.g << " " << c.b << endl;
mOutputMat << "Ka " << c.r << " " << c.g << " " << c.b << endl;
}
if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_SPECULAR,c)) {
mOutputMat << "ks " << c.r << " " << c.g << " " << c.b << endl;
mOutputMat << "Ks " << c.r << " " << c.g << " " << c.b << endl;
}
if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_EMISSIVE,c)) {
mOutputMat << "ke " << c.r << " " << c.g << " " << c.b << endl;
mOutputMat << "Ke " << c.r << " " << c.g << " " << c.b << endl;
}
float o;
@ -170,16 +171,19 @@ void ObjExporter :: WriteMaterialFile()
aiString s;
if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_DIFFUSE(0),s)) {
mOutputMat << "map_kd " << s.data << endl;
mOutputMat << "map_Kd " << s.data << endl;
}
if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_AMBIENT(0),s)) {
mOutputMat << "map_ka " << s.data << endl;
mOutputMat << "map_Ka " << s.data << endl;
}
if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_SPECULAR(0),s)) {
mOutputMat << "map_ks " << s.data << endl;
mOutputMat << "map_Ks " << s.data << endl;
}
if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_SHININESS(0),s)) {
mOutputMat << "map_ns " << s.data << endl;
mOutputMat << "map_Ns " << s.data << endl;
}
if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_OPACITY(0),s)) {
mOutputMat << "map_d " << s.data << endl;
}
if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_HEIGHT(0),s) || AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_NORMALS(0),s)) {
// implementations seem to vary here, so write both variants
@ -281,7 +285,7 @@ void ObjExporter::vecIndexMap::getVectors( std::vector<aiVector3D>& vecs )
}
// ------------------------------------------------------------------------------------------------
void ObjExporter :: AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat)
void ObjExporter::AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat)
{
meshes.push_back(MeshInstance());
MeshInstance& mesh = meshes.back();
@ -332,7 +336,7 @@ void ObjExporter :: AddMesh(const aiString& name, const aiMesh* m, const aiMatri
}
// ------------------------------------------------------------------------------------------------
void ObjExporter :: AddNode(const aiNode* nd, const aiMatrix4x4& mParent)
void ObjExporter::AddNode(const aiNode* nd, const aiMatrix4x4& mParent)
{
const aiMatrix4x4& mAbs = mParent * nd->mTransformation;
@ -345,5 +349,7 @@ void ObjExporter :: AddNode(const aiNode* nd, const aiMatrix4x4& mParent)
}
}
#endif
#endif
// ------------------------------------------------------------------------------------------------
#endif // ASSIMP_BUILD_NO_OBJ_EXPORTER
#endif // ASSIMP_BUILD_NO_EXPORT

View File

@ -54,6 +54,7 @@ static const std::string DiffuseTexture = "map_kd";
static const std::string AmbientTexture = "map_ka";
static const std::string SpecularTexture = "map_ks";
static const std::string OpacityTexture = "map_d";
static const std::string EmmissiveTexture = "map_emissive";
static const std::string BumpTexture1 = "map_bump";
static const std::string BumpTexture2 = "map_Bump";
static const std::string BumpTexture3 = "bump";
@ -128,6 +129,7 @@ void ObjFileMtlImporter::load()
{
switch (*m_DataIt)
{
case 'k':
case 'K':
{
++m_DataIt;
@ -221,15 +223,17 @@ void ObjFileMtlImporter::getColorRGBA( aiColor3D *pColor )
{
ai_assert( NULL != pColor );
float r, g, b;
float r( 0.0f ), g( 0.0f ), b( 0.0f );
m_DataIt = getFloat<DataArrayIt>( m_DataIt, m_DataItEnd, r );
pColor->r = r;
m_DataIt = getFloat<DataArrayIt>( m_DataIt, m_DataItEnd, g );
pColor->g = g;
m_DataIt = getFloat<DataArrayIt>( m_DataIt, m_DataItEnd, b );
pColor->b = b;
// we have to check if color is default 0 with only one token
if( !isNewLine( *m_DataIt ) ) {
m_DataIt = getFloat<DataArrayIt>( m_DataIt, m_DataItEnd, g );
m_DataIt = getFloat<DataArrayIt>( m_DataIt, m_DataItEnd, b );
}
pColor->g = g;
pColor->b = b;
}
// -------------------------------------------------------------------
@ -303,11 +307,7 @@ void ObjFileMtlImporter::getTexture() {
// Opacity texture
out = & m_pModel->m_pCurrentMaterial->textureOpacity;
clampIndex = ObjFile::Material::TextureOpacityType;
} else if (!ASSIMP_strincmp( pPtr,"map_ka",6)) {
// Ambient texture
out = & m_pModel->m_pCurrentMaterial->textureAmbient;
clampIndex = ObjFile::Material::TextureAmbientType;
} else if (!ASSIMP_strincmp(&(*m_DataIt),"map_emissive",6)) {
} else if (!ASSIMP_strincmp( pPtr, EmmissiveTexture.c_str(), EmmissiveTexture.size())) {
// Emissive texture
out = & m_pModel->m_pCurrentMaterial->textureEmissive;
clampIndex = ObjFile::Material::TextureEmissiveType;

View File

@ -113,8 +113,8 @@ void ObjFileParser::parseFile()
getVector3(m_pModel->m_Vertices);
} else if (*m_DataIt == 't') {
// read in texture coordinate ( 2D or 3D )
++m_DataIt;
getVector( m_pModel->m_TextureCoord );
++m_DataIt;
getVector( m_pModel->m_TextureCoord );
} else if (*m_DataIt == 'n') {
// Read in normal vector definition
++m_DataIt;
@ -233,12 +233,13 @@ void ObjFileParser::copyNextLine(char *pBuffer, size_t length)
// -------------------------------------------------------------------
void ObjFileParser::getVector( std::vector<aiVector3D> &point3d_array ) {
size_t numComponents( 0 );
DataArrayIt tmp( m_DataIt );
const char* tmp( &m_DataIt[0] );
while( !IsLineEnd( *tmp ) ) {
if( *tmp == ' ' ) {
++numComponents;
if ( !SkipSpaces( &tmp ) ) {
break;
}
tmp++;
SkipToken( tmp );
++numComponents;
}
float x, y, z;
if( 2 == numComponents ) {
@ -550,13 +551,15 @@ void ObjFileParser::getNewMaterial()
{
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
if ( m_DataIt == m_DataItEnd )
return;
if( m_DataIt == m_DataItEnd ) {
return;
}
char *pStart = &(*m_DataIt);
std::string strMat( pStart, *m_DataIt );
while ( m_DataIt != m_DataItEnd && isSeparator( *m_DataIt ) )
m_DataIt++;
while( m_DataIt != m_DataItEnd && isSeparator( *m_DataIt ) ) {
++m_DataIt;
}
std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( strMat );
if ( it == m_pModel->m_MaterialMap.end() )
{
@ -581,8 +584,9 @@ void ObjFileParser::getNewMaterial()
int ObjFileParser::getMaterialIndex( const std::string &strMaterialName )
{
int mat_index = -1;
if ( strMaterialName.empty() )
return mat_index;
if( strMaterialName.empty() ) {
return mat_index;
}
for (size_t index = 0; index < m_pModel->m_MaterialLib.size(); ++index)
{
if ( strMaterialName == m_pModel->m_MaterialLib[ index ])
@ -601,8 +605,9 @@ void ObjFileParser::getGroupName()
std::string strGroupName;
m_DataIt = getName<DataArrayIt>(m_DataIt, m_DataItEnd, strGroupName);
if ( isEndOfBuffer( m_DataIt, m_DataItEnd ) )
return;
if( isEndOfBuffer( m_DataIt, m_DataItEnd ) ) {
return;
}
// Change active group, if necessary
if ( m_pModel->m_strActiveGroup != strGroupName )
@ -653,11 +658,13 @@ void ObjFileParser::getGroupNumberAndResolution()
void ObjFileParser::getObjectName()
{
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
if (m_DataIt == m_DataItEnd)
return;
if( m_DataIt == m_DataItEnd ) {
return;
}
char *pStart = &(*m_DataIt);
while ( m_DataIt != m_DataItEnd && !isSeparator( *m_DataIt ) )
++m_DataIt;
while( m_DataIt != m_DataItEnd && !isSeparator( *m_DataIt ) ) {
++m_DataIt;
}
std::string strObjectName(pStart, &(*m_DataIt));
if (!strObjectName.empty())
@ -678,8 +685,9 @@ void ObjFileParser::getObjectName()
}
// Allocate a new object, if current one was not found before
if ( NULL == m_pModel->m_pCurrent )
createObject(strObjectName);
if( NULL == m_pModel->m_pCurrent ) {
createObject( strObjectName );
}
}
m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
}
@ -694,7 +702,6 @@ void ObjFileParser::createObject(const std::string &strObjectName)
m_pModel->m_pCurrent->m_strObjName = strObjectName;
m_pModel->m_Objects.push_back( m_pModel->m_pCurrent );
createMesh();
if( m_pModel->m_pCurrentMaterial )

View File

@ -259,4 +259,4 @@ unsigned int tokenize( const string_type& str, std::vector<string_type>& tokens,
} // Namespace Assimp
#endif
#endif // OBJ_TOOLS_H_INC

View File

@ -376,14 +376,14 @@ void OgreBinarySerializer::ReadMeshSkeletonLink(Mesh *mesh)
mesh->skeletonRef = ReadLine();
}
void OgreBinarySerializer::ReadMeshBounds(Mesh *mesh)
void OgreBinarySerializer::ReadMeshBounds(Mesh * /*mesh*/)
{
// Skip bounds, not compatible with Assimp.
// 2x float vec3 + 1x float sphere radius
SkipBytes(sizeof(float) * 7);
}
void OgreBinarySerializer::ReadMeshExtremes(Mesh *mesh)
void OgreBinarySerializer::ReadMeshExtremes(Mesh * /*mesh*/)
{
// Skip extremes, not compatible with Assimp.
size_t numBytes = m_currentLen - MSTREAM_OVERHEAD_SIZE;
@ -534,7 +534,6 @@ void OgreBinarySerializer::ReadSubMeshTextureAlias(SubMesh *submesh)
void OgreBinarySerializer::ReadSubMeshNames(Mesh *mesh)
{
uint16_t id = 0;
uint16_t submeshIndex = 0;
if (!AtEnd())
{
@ -644,7 +643,7 @@ void OgreBinarySerializer::ReadGeometryVertexBuffer(VertexData *dest)
DefaultLogger::get()->debug(Formatter::format() << " - Read vertex buffer for source " << bindIndex << " of " << numBytes << " bytes");
}
void OgreBinarySerializer::ReadEdgeList(Mesh *mesh)
void OgreBinarySerializer::ReadEdgeList(Mesh * /*mesh*/)
{
// Assimp does not acknowledge LOD levels as far as I can see it. This info is just skipped.
@ -1055,7 +1054,7 @@ void OgreBinarySerializer::ReadSkeletonAnimation(Skeleton *skeleton)
DefaultLogger::get()->debug(Formatter::format() << " " << anim->name << " (" << anim->length << " sec, " << anim->tracks.size() << " tracks)");
}
void OgreBinarySerializer::ReadSkeletonAnimationTrack(Skeleton *skeleton, Animation *dest)
void OgreBinarySerializer::ReadSkeletonAnimationTrack(Skeleton * /*skeleton*/, Animation *dest)
{
uint16_t boneId = Read<uint16_t>();
Bone *bone = dest->parentSkeleton->BoneById(boneId);
@ -1097,7 +1096,7 @@ void OgreBinarySerializer::ReadSkeletonAnimationKeyFrame(VertexAnimationTrack *d
dest->transformKeyFrames.push_back(keyframe);
}
void OgreBinarySerializer::ReadSkeletonAnimationLink(Skeleton *skeleton)
void OgreBinarySerializer::ReadSkeletonAnimationLink(Skeleton * /*skeleton*/)
{
// Skip bounds, not compatible with Assimp.
ReadLine(); // skeleton name

View File

@ -75,8 +75,8 @@ private:
};
OgreBinarySerializer(MemoryStreamReader *reader, AssetMode mode) :
m_reader(reader),
m_currentLen(0),
m_reader(reader),
assetMode(mode)
{
}
@ -301,11 +301,12 @@ enum MeshChunkId
// unsigned short poseIndex
// float influence
// Optional submesh extreme vertex list chink
M_TABLE_EXTREMES = 0xE000,
M_TABLE_EXTREMES = 0xE000
// unsigned short submesh_index;
// float extremes [n_extremes][3];
};
/*
static std::string MeshHeaderToString(MeshChunkId id)
{
switch(id)
@ -347,6 +348,7 @@ static std::string MeshHeaderToString(MeshChunkId id)
}
return "Unknown_MeshChunkId";
}
*/
enum SkeletonChunkId
{
@ -393,6 +395,7 @@ enum SkeletonChunkId
// float scale : scale to apply to trans/scale keys
};
/*
static std::string SkeletonHeaderToString(SkeletonChunkId id)
{
switch(id)
@ -409,6 +412,7 @@ static std::string SkeletonHeaderToString(SkeletonChunkId id)
}
return "Unknown_SkeletonChunkId";
}
*/
} // Ogre
} // Assimp

View File

@ -404,9 +404,9 @@ size_t IndexData::FaceSize() const
// Mesh
Mesh::Mesh() :
sharedVertexData(0),
skeleton(0),
hasSkeletalAnimations(false)
hasSkeletalAnimations(false),
skeleton(NULL),
sharedVertexData(NULL)
{
}
@ -712,8 +712,8 @@ aiMesh *SubMesh::ConvertToAssimpMesh(Mesh *parent)
// MeshXml
MeshXml::MeshXml() :
sharedVertexData(0),
skeleton(0)
skeleton(0),
sharedVertexData(0)
{
}
@ -797,8 +797,8 @@ void MeshXml::ConvertToAssimpScene(aiScene* dest)
// SubMeshXml
SubMeshXml::SubMeshXml() :
vertexData(0),
indexData(new IndexDataXml())
indexData(new IndexDataXml()),
vertexData(0)
{
}
@ -912,8 +912,8 @@ aiMesh *SubMeshXml::ConvertToAssimpMesh(MeshXml *parent)
// Animation
Animation::Animation(Skeleton *parent) :
parentMesh(NULL),
parentSkeleton(parent),
parentMesh(0),
length(0.0f),
baseTime(-1.0f)
{
@ -963,6 +963,8 @@ aiAnimation *Animation::ConvertToAssimpAnimation()
// Skeleton
Skeleton::Skeleton() :
bones(),
animations(),
blendMode(ANIMBLEND_AVERAGE)
{
}
@ -1103,7 +1105,7 @@ aiNode *Bone::ConvertToAssimpNode(Skeleton *skeleton, aiNode *parentNode)
return node;
}
aiBone *Bone::ConvertToAssimpBone(Skeleton *parent, const std::vector<aiVertexWeight> &boneWeights)
aiBone *Bone::ConvertToAssimpBone(Skeleton * /*parent*/, const std::vector<aiVertexWeight> &boneWeights)
{
aiBone *bone = new aiBone();
bone->mName = name;
@ -1122,8 +1124,8 @@ aiBone *Bone::ConvertToAssimpBone(Skeleton *parent, const std::vector<aiVertexWe
// VertexAnimationTrack
VertexAnimationTrack::VertexAnimationTrack() :
target(0),
type(VAT_NONE)
type(VAT_NONE),
target(0)
{
}

View File

@ -46,16 +46,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_PARSING_UTILS_H_INC
#include "StringComparison.h"
namespace Assimp {
// NOTE: the functions below are mostly intended as replacement for
// std::upper, std::lower, std::isupper, std::islower, std::isspace.
// we don't bother of locales. We don't want them. We want reliable
// (i.e. identical) results across all locales.
// NOTE: the functions below are mostly intended as replacement for
// std::upper, std::lower, std::isupper, std::islower, std::isspace.
// we don't bother of locales. We don't want them. We want reliable
// (i.e. identical) results across all locales.
// The functions below accept any character type, but know only
// about ASCII. However, UTF-32 is the only safe ASCII superset to
// use since it doesn't have multibyte sequences.
// The functions below accept any character type, but know only
// about ASCII. However, UTF-32 is the only safe ASCII superset to
// use since it doesn't have multi-byte sequences.
static const unsigned int BufferSize = 4096;
// ---------------------------------------------------------------------------------
template <class char_t>
@ -63,118 +66,145 @@ AI_FORCE_INLINE char_t ToLower( char_t in)
{
return (in >= (char_t)'A' && in <= (char_t)'Z') ? (char_t)(in+0x20) : in;
}
// ---------------------------------------------------------------------------------
template <class char_t>
AI_FORCE_INLINE char_t ToUpper( char_t in)
{
return (in >= (char_t)'a' && in <= (char_t)'z') ? (char_t)(in-0x20) : in;
AI_FORCE_INLINE char_t ToUpper( char_t in) {
return (in >= (char_t)'a' && in <= (char_t)'z') ? (char_t)(in-0x20) : in;
}
// ---------------------------------------------------------------------------------
template <class char_t>
AI_FORCE_INLINE bool IsUpper( char_t in)
{
return (in >= (char_t)'A' && in <= (char_t)'Z');
}
// ---------------------------------------------------------------------------------
template <class char_t>
AI_FORCE_INLINE bool IsLower( char_t in)
{
return (in >= (char_t)'a' && in <= (char_t)'z');
}
// ---------------------------------------------------------------------------------
template <class char_t>
AI_FORCE_INLINE bool IsSpace( char_t in)
{
return (in == (char_t)' ' || in == (char_t)'\t');
}
// ---------------------------------------------------------------------------------
template <class char_t>
AI_FORCE_INLINE bool IsLineEnd( char_t in)
{
return (in == (char_t)'\r' || in == (char_t)'\n' || in == (char_t)'\0');
}
// ---------------------------------------------------------------------------------
template <class char_t>
AI_FORCE_INLINE bool IsSpaceOrNewLine( char_t in)
{
return IsSpace<char_t>(in) || IsLineEnd<char_t>(in);
}
// ---------------------------------------------------------------------------------
template <class char_t>
AI_FORCE_INLINE bool SkipSpaces( const char_t* in, const char_t** out)
{
while (*in == (char_t)' ' || *in == (char_t)'\t')in++;
while( *in == ( char_t )' ' || *in == ( char_t )'\t' ) {
++in;
}
*out = in;
return !IsLineEnd<char_t>(*in);
}
// ---------------------------------------------------------------------------------
template <class char_t>
AI_FORCE_INLINE bool SkipSpaces( const char_t** inout)
{
return SkipSpaces<char_t>(*inout,inout);
}
// ---------------------------------------------------------------------------------
template <class char_t>
AI_FORCE_INLINE bool SkipLine( const char_t* in, const char_t** out)
{
while (*in != (char_t)'\r' && *in != (char_t)'\n' && *in != (char_t)'\0')in++;
while( *in != ( char_t )'\r' && *in != ( char_t )'\n' && *in != ( char_t )'\0' ) {
++in;
}
// files are opened in binary mode. Ergo there are both NL and CR
while (*in == (char_t)'\r' || *in == (char_t)'\n')in++;
while( *in == ( char_t )'\r' || *in == ( char_t )'\n' ) {
++in;
}
*out = in;
return *in != (char_t)'\0';
}
// ---------------------------------------------------------------------------------
template <class char_t>
AI_FORCE_INLINE bool SkipLine( const char_t** inout)
{
return SkipLine<char_t>(*inout,inout);
}
// ---------------------------------------------------------------------------------
template <class char_t>
AI_FORCE_INLINE bool SkipSpacesAndLineEnd( const char_t* in, const char_t** out)
{
while (*in == (char_t)' ' || *in == (char_t)'\t' ||
*in == (char_t)'\r' || *in == (char_t)'\n')in++;
while( *in == ( char_t )' ' || *in == ( char_t )'\t' || *in == ( char_t )'\r' || *in == ( char_t )'\n' ) {
++in;
}
*out = in;
return *in != '\0';
}
// ---------------------------------------------------------------------------------
template <class char_t>
AI_FORCE_INLINE bool SkipSpacesAndLineEnd( const char_t** inout)
{
return SkipSpacesAndLineEnd<char_t>(*inout,inout);
}
// ---------------------------------------------------------------------------------
template <class char_t>
AI_FORCE_INLINE bool GetNextLine(const char_t*& buffer, char_t out[4096])
AI_FORCE_INLINE bool GetNextLine( const char_t*& buffer, char_t out[ BufferSize ] )
{
if ((char_t)'\0' == *buffer)return false;
if( ( char_t )'\0' == *buffer ) {
return false;
}
char* _out = out;
char* const end = _out+4096;
while (!IsLineEnd( *buffer ) && _out < end)
*_out++ = *buffer++;
char* const end = _out + BufferSize;
while( !IsLineEnd( *buffer ) && _out < end ) {
*_out++ = *buffer++;
}
*_out = (char_t)'\0';
while (IsLineEnd( *buffer ) && '\0' != *buffer)++buffer;
return true;
while( IsLineEnd( *buffer ) && '\0' != *buffer ) {
++buffer;
}
return true;
}
// ---------------------------------------------------------------------------------
template <class char_t>
AI_FORCE_INLINE bool IsNumeric( char_t in)
{
return ( in >= '0' && in <= '9' ) || '-' == in || '+' == in;
}
// ---------------------------------------------------------------------------------
template <class char_t>
AI_FORCE_INLINE bool TokenMatch(char_t*& in, const char* token, unsigned int len)
{
if (!::strncmp(token,in,len) && IsSpaceOrNewLine(in[len]))
{
if (!::strncmp(token,in,len) && IsSpaceOrNewLine(in[len])) {
in += len+1;
return true;
}
return false;
}
// ---------------------------------------------------------------------------------
@ -185,8 +215,7 @@ AI_FORCE_INLINE bool TokenMatch(char_t*& in, const char* token, unsigned int len
*/
AI_FORCE_INLINE bool TokenMatchI(const char*& in, const char* token, unsigned int len)
{
if (!ASSIMP_strincmp(token,in,len) && IsSpaceOrNewLine(in[len]))
{
if (!ASSIMP_strincmp(token,in,len) && IsSpaceOrNewLine(in[len])) {
in += len+1;
return true;
}
@ -206,5 +235,9 @@ AI_FORCE_INLINE std::string GetNextToken(const char*& in)
while (!IsSpaceOrNewLine(*in))++in;
return std::string(cur,(size_t)(in-cur));
}
// ---------------------------------------------------------------------------------
} // ! namespace Assimp
#endif // ! AI_PARSING_UTILS_H_INC

View File

@ -73,11 +73,13 @@ static const aiImporterDesc desc = {
namespace Assimp {
/*
static void getSupportedExtensions(std::vector<std::string> &supportedExtensions) {
supportedExtensions.push_back( ".jpg" );
supportedExtensions.push_back( ".png" );
supportedExtensions.push_back( ".tga" );
}
*/
using namespace Q3BSP;

View File

@ -68,25 +68,25 @@ voidpf IOSystem2Unzip::open(voidpf opaque, const char* filename, int mode) {
return (voidpf) io_system->Open(filename, mode_fopen);
}
uLong IOSystem2Unzip::read(voidpf opaque, voidpf stream, void* buf, uLong size) {
uLong IOSystem2Unzip::read(voidpf /*opaque*/, voidpf stream, void* buf, uLong size) {
IOStream* io_stream = (IOStream*) stream;
return io_stream->Read(buf, 1, size);
}
uLong IOSystem2Unzip::write(voidpf opaque, voidpf stream, const void* buf, uLong size) {
uLong IOSystem2Unzip::write(voidpf /*opaque*/, voidpf stream, const void* buf, uLong size) {
IOStream* io_stream = (IOStream*) stream;
return io_stream->Write(buf, 1, size);
}
long IOSystem2Unzip::tell(voidpf opaque, voidpf stream) {
long IOSystem2Unzip::tell(voidpf /*opaque*/, voidpf stream) {
IOStream* io_stream = (IOStream*) stream;
return io_stream->Tell();
}
long IOSystem2Unzip::seek(voidpf opaque, voidpf stream, uLong offset, int origin) {
long IOSystem2Unzip::seek(voidpf /*opaque*/, voidpf stream, uLong offset, int origin) {
IOStream* io_stream = (IOStream*) stream;
aiOrigin assimp_origin;
@ -115,7 +115,7 @@ int IOSystem2Unzip::close(voidpf opaque, voidpf stream) {
return 0;
}
int IOSystem2Unzip::testerror(voidpf opaque, voidpf stream) {
int IOSystem2Unzip::testerror(voidpf /*opaque*/, voidpf /*stream*/) {
return 0;
}

View File

@ -348,8 +348,8 @@ bool STLImporter::LoadBinaryFile()
bool bIsMaterialise = false;
// search for an occurence of "COLOR=" in the header
const char* sz2 = (const char*)mBuffer;
const char* const szEnd = sz2+80;
const unsigned char* sz2 = (const unsigned char*)mBuffer;
const unsigned char* const szEnd = sz2+80;
while (sz2 < szEnd) {
if ('C' == *sz2++ && 'O' == *sz2++ && 'L' == *sz2++ &&

235
code/StreamWriter.h 100644
View File

@ -0,0 +1,235 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2012, 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 following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
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
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
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
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
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
/** @file Defines the StreamWriter class which writes data to
* a binary stream with a well-defined endianess. */
#ifndef AI_STREAMWRITER_H_INCLUDED
#define AI_STREAMWRITER_H_INCLUDED
#include "ByteSwap.h"
namespace Assimp {
// --------------------------------------------------------------------------------------------
/** Wrapper class around IOStream to allow for consistent writing of binary data in both
* little and big endian format. Don't attempt to instance the template directly. Use
* StreamWriterLE to read from a little-endian stream and StreamWriterBE to read from a
* BE stream. Alternatively, there is StreamWriterAny if the endianess of the output
* stream is to be determined at runtime.
*/
// --------------------------------------------------------------------------------------------
template <bool SwapEndianess = false, bool RuntimeSwitch = false>
class StreamWriter
{
enum {
INITIAL_CAPACITY = 1024
};
public:
// ---------------------------------------------------------------------
/** Construction from a given stream with a well-defined endianess.
*
* The StreamReader holds a permanent strong reference to the
* stream, which is released upon destruction.
* @param stream Input stream. The stream is not re-seeked and writing
continues at the current position of the stream cursor.
* @param le If @c RuntimeSwitch is true: specifies whether the
* stream is in little endian byte order. Otherwise the
* endianess information is defined by the @c SwapEndianess
* template parameter and this parameter is meaningless. */
StreamWriter(boost::shared_ptr<IOStream> stream, bool le = false)
: stream(stream)
, le(le)
, cursor()
{
ai_assert(stream);
buffer.reserve(INITIAL_CAPACITY);
}
// ---------------------------------------------------------------------
StreamWriter(IOStream* stream, bool le = false)
: stream(boost::shared_ptr<IOStream>(stream))
, le(le)
, cursor()
{
ai_assert(stream);
buffer.reserve(INITIAL_CAPACITY);
}
// ---------------------------------------------------------------------
~StreamWriter() {
stream->Write(&buffer[0], 1, buffer.size());
stream->Flush();
}
public:
// ---------------------------------------------------------------------
/** Write a float to the stream */
void PutF4(float f)
{
Put(f);
}
// ---------------------------------------------------------------------
/** Write a double to the stream */
void PutF8(double d) {
Put(d);
}
// ---------------------------------------------------------------------
/** Write a signed 16 bit integer to the stream */
void PutI2(int16_t n) {
Put(n);
}
// ---------------------------------------------------------------------
/** Write a signed 8 bit integer to the stream */
void PutI1(int8_t n) {
Put(n);
}
// ---------------------------------------------------------------------
/** Write an signed 32 bit integer to the stream */
void PutI4(int32_t n) {
Put(n);
}
// ---------------------------------------------------------------------
/** Write a signed 64 bit integer to the stream */
void PutI8(int64_t n) {
Put(n);
}
// ---------------------------------------------------------------------
/** Write a unsigned 16 bit integer to the stream */
void PutU2(uint16_t n) {
Put(n);
}
// ---------------------------------------------------------------------
/** Write a unsigned 8 bit integer to the stream */
void PutU1(uint8_t n) {
Put(n);
}
// ---------------------------------------------------------------------
/** Write an unsigned 32 bit integer to the stream */
void PutU4(uint32_t n) {
Put(n);
}
// ---------------------------------------------------------------------
/** Write a unsigned 64 bit integer to the stream */
void PutU8(uint64_t n) {
Put(n);
}
public:
// ---------------------------------------------------------------------
/** overload operator<< and allow chaining of MM ops. */
template <typename T>
StreamWriter& operator << (T f) {
Put(f);
return *this;
}
// ---------------------------------------------------------------------
std::size_t GetCurrentPos() const {
return cursor;
}
// ---------------------------------------------------------------------
void SetCurrentPos(std::size_t new_cursor) {
cursor = new_cursor;
}
private:
// ---------------------------------------------------------------------
/** Generic write method. ByteSwap::Swap(T*) *must* be defined */
template <typename T>
void Put(T f) {
Intern :: Getter<SwapEndianess,T,RuntimeSwitch>() (&f, le);
if (cursor + sizeof(T) >= buffer.size()) {
buffer.resize(cursor + sizeof(T));
}
void* dest = &buffer[cursor];
// reinterpret_cast + assignment breaks strict aliasing rules
// and generally causes trouble on platforms such as ARM that
// do not silently ignore alignment faults.
::memcpy(dest, &f, sizeof(T));
cursor += sizeof(T);
}
private:
boost::shared_ptr<IOStream> stream;
bool le;
std::vector<uint8_t> buffer;
std::size_t cursor;
};
// --------------------------------------------------------------------------------------------
// `static` StreamWriter. Their byte order is fixed and they might be a little bit faster.
#ifdef AI_BUILD_BIG_ENDIAN
typedef StreamWriter<true> StreamWriterLE;
typedef StreamWriter<false> StreamWriterBE;
#else
typedef StreamWriter<true> StreamWriterBE;
typedef StreamWriter<false> StreamWriterLE;
#endif
// `dynamic` StreamWriter. The byte order of the input data is specified in the
// c'tor. This involves runtime branching and might be a little bit slower.
typedef StreamWriter<true,true> StreamWriterAny;
} // end namespace Assimp
#endif // !! AI_STREAMWriter_H_INCLUDED

81
code/XMLTools.h 100644
View File

@ -0,0 +1,81 @@
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2012, 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
following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
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
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
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
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
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
#ifndef INCLUDED_ASSIMP_XML_TOOLS_H
#define INCLUDED_ASSIMP_XML_TOOLS_H
#include <string>
namespace Assimp {
// XML escape the 5 XML special characters (",',<,> and &) in |data|
// Based on http://stackoverflow.com/questions/5665231
std::string XMLEscape(const std::string& data) {
std::string buffer;
const size_t size = data.size();
buffer.reserve(size + size / 8);
for(size_t i = 0; i < size; ++i) {
const char c = data[i];
switch(c) {
case '&' :
buffer.append("&amp;");
break;
case '\"':
buffer.append("&quot;");
break;
case '\'':
buffer.append("&apos;");
break;
case '<' :
buffer.append("&lt;");
break;
case '>' :
buffer.append("&gt;");
break;
default:
buffer.append(&c, 1);
break;
}
}
return buffer;
}
}
#endif // INCLUDED_ASSIMP_XML_TOOLS_H

View File

@ -16,7 +16,9 @@
#define __FAST_A_TO_F_H_INCLUDED__
#include <math.h>
#include <limits.h>
#include <limits>
#include "StringComparison.h"
namespace Assimp
{
@ -229,15 +231,45 @@ inline uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int*
template <typename Real>
inline const char* fast_atoreal_move(const char* c, Real& out, bool check_comma = true)
{
Real f;
Real f = 0;
bool inv = (*c=='-');
if (inv || *c=='+') {
bool inv = (*c == '-');
if (inv || *c == '+') {
++c;
}
f = static_cast<Real>( strtoul10_64 ( c, &c) );
if (*c == '.' || (check_comma && c[0] == ',' && c[1] >= '0' && c[1] <= '9')) // allow for commas, too
if ((c[0] == 'N' || c[0] == 'n') && ASSIMP_strincmp(c, "nan", 3) == 0)
{
out = std::numeric_limits<Real>::quiet_NaN();
c += 3;
return c;
}
if ((c[0] == 'I' || c[0] == 'i') && ASSIMP_strincmp(c, "inf", 3) == 0)
{
out = std::numeric_limits<Real>::infinity();
c += 3;
if ((c[0] == 'I' || c[0] == 'i') && ASSIMP_strincmp(c, "inity", 5) == 0)
{
c += 5;
}
return c;
}
if (!(c[0] >= '0' && c[0] <= '9') &&
!(c[0] == '.' && c[1] >= '0' && c[1] <= '9'))
{
throw std::invalid_argument("Cannot parse string "
"as real number: does not start with digit "
"or decimal point followed by digit.");
}
if (*c != '.')
{
f = static_cast<Real>( strtoul10_64 ( c, &c) );
}
if ((*c == '.' || (check_comma && c[0] == ',')) && c[1] >= '0' && c[1] <= '9')
{
++c;
@ -255,6 +287,10 @@ inline const char* fast_atoreal_move(const char* c, Real& out, bool check_comma
pl *= fast_atof_table[diff];
f += static_cast<Real>( pl );
}
// For backwards compatibility: eat trailing dots, but not trailing commas.
else if (*c == '.') {
++c;
}
// A major 'E' must be allowed. Necessary for proper reading of some DXF files.
// Thanks to Zhao Lei to point out that this if() must be outside the if (*c == '.' ..)

View File

@ -2124,11 +2124,13 @@ void Clipper::AddOutPt(TEdge *e, const IntPoint &pt)
{
//check for 'rounding' artefacts ...
if (outRec->sides == esNeither && pt.Y == op->pt.Y)
{
if (ToFront)
{
if (pt.X == op->pt.X +1) return; //ie wrong side of bottomPt
}
else if (pt.X == op->pt.X -1) return; //ie wrong side of bottomPt
}
outRec->sides = (EdgeSide)(outRec->sides | e->side);
if (outRec->sides == esBoth)

View File

@ -1246,7 +1246,7 @@ extern int ZEXPORT unzReadCurrentFile (file, buf, len)
return UNZ_PARAMERROR;
if ((pfile_in_zip_read_info->read_buffer == NULL))
if (pfile_in_zip_read_info->read_buffer == NULL)
return UNZ_END_OF_LIST_OF_FILE;
if (len==0)
return 0;

View File

@ -81,13 +81,39 @@ public:
* all needed cleanup tasks prior to returning control to the
* caller). If the loading is aborted, #Importer::ReadFile()
* returns always NULL.
*
* @note Currently, percentage is always -1.f because there is
* no reliable way to compute it.
* */
virtual bool Update(float percentage = -1.f) = 0;
// -------------------------------------------------------------------
/** @brief Progress callback for file loading steps
* @param numberOfSteps The number of total post-processing
* steps
* @param currentStep The index of the current post-processing
* step that will run, or equal to numberOfSteps if all of
* them has finished. This number is always strictly monotone
* increasing, although not necessarily linearly.
*
* @note This is currently only used at the start and the end
* of the file parsing.
* */
virtual void UpdateFileRead(int currentStep /*= 0*/, int numberOfSteps /*= 0*/) {
float f = numberOfSteps ? currentStep / (float)numberOfSteps : 1.0f;
Update( f * 0.5f );
};
// -------------------------------------------------------------------
/** @brief Progress callback for post-processing steps
* @param numberOfSteps The number of total post-processing
* steps
* @param currentStep The index of the current post-processing
* step that will run, or equal to numberOfSteps if all of
* them has finished. This number is always strictly monotone
* increasing, although not necessarily linearly.
* */
virtual void UpdatePostProcess(int currentStep /*= 0*/, int numberOfSteps /*= 0*/) {
float f = numberOfSteps ? currentStep / (float)numberOfSteps : 1.0f;
Update( f * 0.5f + 0.5f );
};
}; // !class ProgressHandler
// ------------------------------------------------------------------------------------

View File

@ -72,7 +72,7 @@ enum aiImporterFlags
* should be used with care. This only happens for trunk
* (i.e. SVN) versions, experimental code is not included
* in releases. */
aiImporterFlags_Experimental = 0x10,
aiImporterFlags_Experimental = 0x10
};

View File

@ -1,5 +1,6 @@
FIND_PACKAGE(OpenGL)
FIND_PACKAGE(GLUT)
find_library(M_LIB m)
IF ( NOT GLUT_FOUND )
IF ( MSVC )
@ -29,7 +30,7 @@ ADD_EXECUTABLE( assimp_simpleogl
SET_PROPERTY(TARGET assimp_simpleogl PROPERTY DEBUG_POSTFIX ${ASSIMP_DEBUG_POSTFIX})
TARGET_LINK_LIBRARIES( assimp_simpleogl assimp ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} )
TARGET_LINK_LIBRARIES( assimp_simpleogl assimp ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${M_LIB} )
SET_TARGET_PROPERTIES( assimp_simpleogl PROPERTIES
OUTPUT_NAME assimp_simpleogl
)

View File

@ -1,4 +1,4 @@
// ----------------------------------------------------------------------------
/* ----------------------------------------------------------------------------
// Simple sample to prove that Assimp is easy to use with OpenGL.
// It takes a file name as command line parameter, loads it using standard
// settings and displays it.
@ -9,29 +9,30 @@
// The vc8 solution links against assimp-release-dll_win32 - be sure to
// have this configuration built.
// ----------------------------------------------------------------------------
*/
#include <stdlib.h>
#include <stdio.h>
#include <GL/glut.h>
// assimp include files. These three are usually needed.
/* assimp include files. These three are usually needed. */
#include <assimp/cimport.h>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
// the global Assimp scene object
/* the global Assimp scene object */
const struct aiScene* scene = NULL;
GLuint scene_list = 0;
struct aiVector3D scene_min, scene_max, scene_center;
// current rotation angle
/* current rotation angle */
static float angle = 0.f;
#define aisgl_min(x,y) (x<y?x:y)
#define aisgl_max(x,y) (y>x?y:x)
// ----------------------------------------------------------------------------
/* ---------------------------------------------------------------------------- */
void reshape(int width, int height)
{
const double aspectRatio = (float) width / height, fieldOfView = 45.0;
@ -43,7 +44,7 @@ void reshape(int width, int height)
glViewport(0, 0, width, height);
}
// ----------------------------------------------------------------------------
/* ---------------------------------------------------------------------------- */
void get_bounding_box_for_node (const struct aiNode* nd,
struct aiVector3D* min,
struct aiVector3D* max,
@ -78,7 +79,7 @@ void get_bounding_box_for_node (const struct aiNode* nd,
*trafo = prev;
}
// ----------------------------------------------------------------------------
/* ---------------------------------------------------------------------------- */
void get_bounding_box (struct aiVector3D* min, struct aiVector3D* max)
{
struct aiMatrix4x4 trafo;
@ -89,7 +90,7 @@ void get_bounding_box (struct aiVector3D* min, struct aiVector3D* max)
get_bounding_box_for_node(scene->mRootNode,min,max,&trafo);
}
// ----------------------------------------------------------------------------
/* ---------------------------------------------------------------------------- */
void color4_to_float4(const struct aiColor4D *c, float f[4])
{
f[0] = c->r;
@ -98,7 +99,7 @@ void color4_to_float4(const struct aiColor4D *c, float f[4])
f[3] = c->a;
}
// ----------------------------------------------------------------------------
/* ---------------------------------------------------------------------------- */
void set_float4(float f[4], float a, float b, float c, float d)
{
f[0] = a;
@ -107,7 +108,7 @@ void set_float4(float f[4], float a, float b, float c, float d)
f[3] = d;
}
// ----------------------------------------------------------------------------
/* ---------------------------------------------------------------------------- */
void apply_material(const struct aiMaterial *mtl)
{
float c[4];
@ -173,19 +174,19 @@ void apply_material(const struct aiMaterial *mtl)
glEnable(GL_CULL_FACE);
}
// ----------------------------------------------------------------------------
/* ---------------------------------------------------------------------------- */
void recursive_render (const struct aiScene *sc, const struct aiNode* nd)
{
unsigned int i;
unsigned int n = 0, t;
struct aiMatrix4x4 m = nd->mTransformation;
// update transform
/* update transform */
aiTransposeMatrix4(&m);
glPushMatrix();
glMultMatrixf((float*)&m);
// draw all meshes assigned to this node
/* draw all meshes assigned to this node */
for (; n < nd->mNumMeshes; ++n) {
const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]];
@ -224,7 +225,7 @@ void recursive_render (const struct aiScene *sc, const struct aiNode* nd)
}
// draw all children
/* draw all children */
for (n = 0; n < nd->mNumChildren; ++n) {
recursive_render(sc, nd->mChildren[n]);
}
@ -232,7 +233,7 @@ void recursive_render (const struct aiScene *sc, const struct aiNode* nd)
glPopMatrix();
}
// ----------------------------------------------------------------------------
/* ---------------------------------------------------------------------------- */
void do_motion (void)
{
static GLint prev_time = 0;
@ -244,7 +245,7 @@ void do_motion (void)
prev_time = time;
frames += 1;
if ((time - prev_fps_time) > 1000) // update every seconds
if ((time - prev_fps_time) > 1000) /* update every seconds */
{
int current_fps = frames * 1000 / (time - prev_fps_time);
printf("%d fps\n", current_fps);
@ -256,7 +257,7 @@ void do_motion (void)
glutPostRedisplay ();
}
// ----------------------------------------------------------------------------
/* ---------------------------------------------------------------------------- */
void display(void)
{
float tmp;
@ -267,27 +268,27 @@ void display(void)
glLoadIdentity();
gluLookAt(0.f,0.f,3.f,0.f,0.f,-5.f,0.f,1.f,0.f);
// rotate it around the y axis
/* rotate it around the y axis */
glRotatef(angle,0.f,1.f,0.f);
// scale the whole asset to fit into our view frustum
/* scale the whole asset to fit into our view frustum */
tmp = scene_max.x-scene_min.x;
tmp = aisgl_max(scene_max.y - scene_min.y,tmp);
tmp = aisgl_max(scene_max.z - scene_min.z,tmp);
tmp = 1.f / tmp;
glScalef(tmp, tmp, tmp);
// center the model
/* center the model */
glTranslatef( -scene_center.x, -scene_center.y, -scene_center.z );
// if the display list has not been made yet, create a new one and
// fill it with scene contents
/* if the display list has not been made yet, create a new one and
fill it with scene contents */
if(scene_list == 0) {
scene_list = glGenLists(1);
glNewList(scene_list, GL_COMPILE);
// now begin at the root node of the imported data and traverse
// the scenegraph by multiplying subsequent local transforms
// together on GL's matrix stack.
/* now begin at the root node of the imported data and traverse
the scenegraph by multiplying subsequent local transforms
together on GL's matrix stack. */
recursive_render(scene, scene->mRootNode);
glEndList();
}
@ -299,11 +300,11 @@ void display(void)
do_motion();
}
// ----------------------------------------------------------------------------
/* ---------------------------------------------------------------------------- */
int loadasset (const char* path)
{
// we are taking one of the postprocessing presets to avoid
// spelling out 20+ single postprocessing flags here.
/* we are taking one of the postprocessing presets to avoid
spelling out 20+ single postprocessing flags here. */
scene = aiImportFile(path,aiProcessPreset_TargetRealtime_MaxQuality);
if (scene) {
@ -316,7 +317,7 @@ int loadasset (const char* path)
return 1;
}
// ----------------------------------------------------------------------------
/* ---------------------------------------------------------------------------- */
int main(int argc, char **argv)
{
struct aiLogStream stream;
@ -330,21 +331,21 @@ int main(int argc, char **argv)
glutDisplayFunc(display);
glutReshapeFunc(reshape);
// get a handle to the predefined STDOUT log stream and attach
// it to the logging system. It remains active for all further
// calls to aiImportFile(Ex) and aiApplyPostProcessing.
/* get a handle to the predefined STDOUT log stream and attach
it to the logging system. It remains active for all further
calls to aiImportFile(Ex) and aiApplyPostProcessing. */
stream = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT,NULL);
aiAttachLogStream(&stream);
// ... same procedure, but this stream now writes the
// log messages to assimp_log.txt
/* ... same procedure, but this stream now writes the
log messages to assimp_log.txt */
stream = aiGetPredefinedLogStream(aiDefaultLogStream_FILE,"assimp_log.txt");
aiAttachLogStream(&stream);
// the model name can be specified on the command line. If none
// is specified, we try to locate one of the more expressive test
// models from the repository (/models-nonbsd may be missing in
// some distributions so we need a fallback from /models!).
/* the model name can be specified on the command line. If none
is specified, we try to locate one of the more expressive test
models from the repository (/models-nonbsd may be missing in
some distributions so we need a fallback from /models!). */
if( 0 != loadasset( argc >= 2 ? argv[1] : "../../test/models-nonbsd/X/dwarf.x")) {
if( argc != 1 || (0 != loadasset( "../../../../test/models-nonbsd/X/dwarf.x") && 0 != loadasset( "../../test/models/X/Testwuson.X"))) {
return -1;
@ -354,14 +355,14 @@ int main(int argc, char **argv)
glClearColor(0.1f,0.1f,0.1f,1.f);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0); // Uses default lighting parameters
glEnable(GL_LIGHT0); /* Uses default lighting parameters */
glEnable(GL_DEPTH_TEST);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
glEnable(GL_NORMALIZE);
// XXX docs say all polygons are emitted CCW, but tests show that some aren't.
/* XXX docs say all polygons are emitted CCW, but tests show that some aren't. */
if(getenv("MODEL_IS_BROKEN"))
glFrontFace(GL_CW);
@ -370,14 +371,15 @@ int main(int argc, char **argv)
glutGet(GLUT_ELAPSED_TIME);
glutMainLoop();
// cleanup - calling 'aiReleaseImport' is important, as the library
// keeps internal resources until the scene is freed again. Not
// doing so can cause severe resource leaking.
/* cleanup - calling 'aiReleaseImport' is important, as the library
keeps internal resources until the scene is freed again. Not
doing so can cause severe resource leaking. */
aiReleaseImport(scene);
// We added a log stream to the library, it's our job to disable it
// again. This will definitely release the last resources allocated
// by Assimp.
/* We added a log stream to the library, it's our job to disable it
again. This will definitely release the last resources allocated
by Assimp.*/
aiDetachAllLogStreams();
return 0;
}

View File

@ -12,9 +12,6 @@
// Thanks to NeHe on whose OpenGL tutorials this one's based on! :)
// http://nehe.gamedev.net/
// ----------------------------------------------------------------------------
#include <windows.h>
#include <stdio.h>
#include <GL/gl.h>
@ -36,7 +33,7 @@
#include "assimp/LogStream.hpp"
// The default hardcoded path. Can be overridden by supplying a path through the commandline.
// The default hard-coded path. Can be overridden by supplying a path through the command line.
static std::string modelpath = "../../test/models/OBJ/spider.obj";
@ -47,7 +44,7 @@ HINSTANCE hInstance; // Holds The Instance Of The Application
bool keys[256]; // Array used for Keyboard Routine;
bool active=TRUE; // Window Active Flag Set To TRUE by Default
bool fullscreen=TRUE; // Fullscreen Flag Set To Fullscreen By Default
bool fullscreen=TRUE; // full-screen Flag Set To full-screen By Default
GLfloat xrot;
GLfloat yrot;
@ -80,6 +77,7 @@ Assimp::Importer importer;
void createAILogger()
{
// Change this line to normal if you not want to analyse the import process
//Assimp::Logger::LogSeverity severity = Assimp::Logger::NORMAL;
Assimp::Logger::LogSeverity severity = Assimp::Logger::VERBOSE;
@ -101,20 +99,20 @@ void destroyAILogger()
void logInfo(std::string logString)
{
//Will add message to File with "info" Tag
// Will add message to File with "info" Tag
Assimp::DefaultLogger::get()->info(logString.c_str());
}
void logDebug(const char* logString)
{
//Will add message to File with "debug" Tag
// Will add message to File with "debug" Tag
Assimp::DefaultLogger::get()->debug(logString);
}
bool Import3DFromFile( const std::string& pFile)
{
//check if file exists
// Check if file exists
std::ifstream fin(pFile.c_str());
if(!fin.fail())
{
@ -143,12 +141,14 @@ bool Import3DFromFile( const std::string& pFile)
return true;
}
void ReSizeGLScene(GLsizei width, GLsizei height) // Resize And Initialize The GL Window
// Resize And Initialize The GL Window
void ReSizeGLScene(GLsizei width, GLsizei height)
{
if (height==0) // Prevent A Divide By Zero By
// Prevent A Divide By Zero By
if (height==0)
{
height=1; // Making Height Equal One
// Making Height Equal One
height=1;
}
glViewport(0, 0, width, height); // Reset The Current Viewport
@ -217,9 +217,6 @@ int LoadGLTextures(const aiScene* scene)
textureIds = new GLuint[numTextures];
glGenTextures(numTextures, textureIds); /* Texture name generation */
/* define texture path */
//std::string texturepath = "../../../test/models/Obj/";
/* get iterator */
std::map<std::string, GLuint*>::iterator itr = textureIdMap.begin();
@ -239,48 +236,50 @@ int LoadGLTextures(const aiScene* scene)
if (success) /* If no error occured: */
{
success = ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE); /* Convert every colour component into
unsigned byte. If your image contains alpha channel you can replace IL_RGB with IL_RGBA */
// Convert every colour component into unsigned byte.If your image contains
// alpha channel you can replace IL_RGB with IL_RGBA
success = ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE);
if (!success)
{
/* Error occured */
abortGLInit("Couldn't convert image");
return -1;
}
//glGenTextures(numTextures, &textureIds[i]); /* Texture name generation */
glBindTexture(GL_TEXTURE_2D, textureIds[i]); /* Binding of texture name */
//redefine standard texture values
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); /* We will use linear
interpolation for magnification filter */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); /* We will use linear
interpolation for minifying filter */
glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH),
// Binding of texture name
glBindTexture(GL_TEXTURE_2D, textureIds[i]);
// redefine standard texture values
// We will use linear interpolation for magnification filter
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
// We will use linear interpolation for minifying filter
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
// Texture specification
glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH),
ilGetInteger(IL_IMAGE_HEIGHT), 0, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE,
ilGetData()); /* Texture specification */
ilGetData());
// we also want to be able to deal with odd texture dimensions
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );
glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0 );
glPixelStorei( GL_UNPACK_SKIP_ROWS, 0 );
}
else
{
/* Error occured */
MessageBox(NULL, ("Couldn't load Image: " + fileloc).c_str() , "ERROR", MB_OK | MB_ICONEXCLAMATION);
}
}
// Because we have already copied image data into texture data we can release memory used by image.
ilDeleteImages(numTextures, imageIds);
ilDeleteImages(numTextures, imageIds); /* Because we have already copied image data into texture data
we can release memory used by image. */
//Cleanup
// Cleanup
delete [] imageIds;
imageIds = NULL;
//return success;
return TRUE;
}
int InitGL() // All Setup For OpenGL goes here
// All Setup For OpenGL goes here
int InitGL()
{
if (!LoadGLTextures(scene))
{
@ -307,9 +306,6 @@ int InitGL() // All Setup For OpenGL goes here
glLightfv(GL_LIGHT1, GL_POSITION, LightPosition);
glEnable(GL_LIGHT1);
//glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
return TRUE; // Initialization Went OK
}
@ -449,8 +445,6 @@ void recursive_render (const struct aiScene *sc, const struct aiNode* nd, float
glDisable(GL_COLOR_MATERIAL);
}
for (t = 0; t < mesh->mNumFaces; ++t) {
const struct aiFace* face = &mesh->mFaces[t];
GLenum face_mode;
@ -480,14 +474,10 @@ void recursive_render (const struct aiScene *sc, const struct aiNode* nd, float
glNormal3fv(&mesh->mNormals[vertexIndex].x);
glVertex3fv(&mesh->mVertices[vertexIndex].x);
}
glEnd();
}
}
// draw all children
for (n = 0; n < nd->mNumChildren; ++n)
{
@ -521,12 +511,11 @@ int DrawGLScene() //Here's where we do all the drawing
drawAiScene(scene);
//xrot+=0.3f;
yrot+=0.2f;
//zrot+=0.4f;
return TRUE; // Ewwrissing okay
return TRUE; // okay
}
@ -667,11 +656,6 @@ BOOL CreateGLWindow(const char* title, int width, int height, int bits, bool ful
{
abortGLInit("Window Creation Error.");
return FALSE;
/*
KillGLWindow(); // Reset The Display
MessageBox(NULL, "Window Creation Error.", "ERROR", MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return False
*/
}
static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be
@ -767,8 +751,8 @@ LRESULT CALLBACK WndProc(HWND hWnd, // Handles for this Window
{
switch (wParam)
{
case SC_SCREENSAVE: // Screensaver trying to start
case SC_MONITORPOWER: // Monitor tryig to enter powersafe
case SC_SCREENSAVE: // Screen-saver trying to start
case SC_MONITORPOWER: // Monitor trying to enter power-safe
return 0;
}
break;
@ -799,12 +783,12 @@ LRESULT CALLBACK WndProc(HWND hWnd, // Handles for this Window
}
}
// Pass All Unhandled Messaged To DefWindowProc
// Pass All unhandled Messaged To DefWindowProc
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
int WINAPI WinMain( HINSTANCE hInstance, // Instance
HINSTANCE hPrevInstance, // Previous Instance
int WINAPI WinMain( HINSTANCE hInstance, // The instance
HINSTANCE hPrevInstance, // Previous instance
LPSTR lpCmdLine, // Command Line Parameters
int nShowCmd ) // Window Show State
{

View File

@ -15,7 +15,8 @@ SOURCE_GROUP( unit FILES
unit/BoostWorkaround/tupletest.cpp
)
SOURCE_GROUP( cppunit FILES
if(WIN32)
SET( CPPUNIT_SRCS
../contrib/cppunit-1.12.1/src/cppunit/AdditionalMessage.cpp
../contrib/cppunit-1.12.1/src/cppunit/Asserter.cpp
../contrib/cppunit-1.12.1/src/cppunit/BeOsDynamicLibraryManager.cpp
@ -70,59 +71,12 @@ SOURCE_GROUP( cppunit FILES
../contrib/cppunit-1.12.1/src/cppunit/XmlOutputter.cpp
../contrib/cppunit-1.12.1/src/cppunit/XmlOutputterHook.cpp
)
SOURCE_GROUP(cppunit FILES ${CPPUNIT_SRCS})
else()
find_library(CPPUNIT_LIBRARY cppunit)
endif()
SOURCE_GROUP( tests FILES
unit/Main.cpp
unit/UnitTestPCH.cpp
unit/UnitTestPCH.h
unit/utFindDegenerates.cpp
unit/utFindDegenerates.h
unit/utFindInvalidData.cpp
unit/utFindInvalidData.h
unit/utFixInfacingNormals.cpp
unit/utGenNormals.cpp
unit/utGenNormals.h
unit/utImporter.cpp
unit/utImporter.h
unit/utImproveCacheLocality.cpp
unit/utJoinVertices.cpp
unit/utJoinVertices.h
unit/utLimitBoneWeights.cpp
unit/utLimitBoneWeights.h
unit/utMaterialSystem.cpp
unit/utMaterialSystem.h
unit/utPretransformVertices.cpp
unit/utPretransformVertices.h
unit/utRemoveComments.cpp
unit/utRemoveComments.h
unit/utRemoveComponent.cpp
unit/utRemoveComponent.h
unit/utRemoveRedundantMaterials.cpp
unit/utRemoveRedundantMaterials.h
unit/utScenePreprocessor.cpp
unit/utScenePreprocessor.h
unit/utSharedPPData.cpp
unit/utSharedPPData.h
unit/utSortByPType.cpp
unit/utSortByPType.h
unit/utSplitLargeMeshes.cpp
unit/utSplitLargeMeshes.h
unit/utTargetAnimation.cpp
unit/utTargetAnimation.h
unit/utTextureTransform.cpp
unit/utTriangulate.cpp
unit/utTriangulate.h
unit/utVertexTriangleAdjacency.cpp
unit/utVertexTriangleAdjacency.h
unit/utNoBoostTest.cpp
unit/utNoBoostTest.h
)
add_executable( unit
unit/CCompilerTest.c
unit/Main.cpp
unit/UnitTestPCH.cpp
unit/UnitTestPCH.h
SET( TEST_SRCS
unit/utFindDegenerates.cpp
unit/utFindDegenerates.h
unit/utFindInvalidData.cpp
@ -165,65 +119,20 @@ add_executable( unit
unit/utNoBoostTest.cpp
unit/utNoBoostTest.h
unit/BoostWorkaround/tupletest.cpp
../contrib/cppunit-1.12.1/src/cppunit/AdditionalMessage.cpp
../contrib/cppunit-1.12.1/src/cppunit/Asserter.cpp
../contrib/cppunit-1.12.1/src/cppunit/BeOsDynamicLibraryManager.cpp
../contrib/cppunit-1.12.1/src/cppunit/BriefTestProgressListener.cpp
../contrib/cppunit-1.12.1/src/cppunit/CompilerOutputter.cpp
../contrib/cppunit-1.12.1/src/cppunit/DefaultProtector.cpp
../contrib/cppunit-1.12.1/src/cppunit/DefaultProtector.h
../contrib/cppunit-1.12.1/src/cppunit/DllMain.cpp
../contrib/cppunit-1.12.1/src/cppunit/DynamicLibraryManager.cpp
../contrib/cppunit-1.12.1/src/cppunit/DynamicLibraryManagerException.cpp
../contrib/cppunit-1.12.1/src/cppunit/Exception.cpp
../contrib/cppunit-1.12.1/src/cppunit/Message.cpp
../contrib/cppunit-1.12.1/src/cppunit/PlugInManager.cpp
../contrib/cppunit-1.12.1/src/cppunit/PlugInParameters.cpp
../contrib/cppunit-1.12.1/src/cppunit/Protector.cpp
../contrib/cppunit-1.12.1/src/cppunit/ProtectorChain.cpp
../contrib/cppunit-1.12.1/src/cppunit/ProtectorChain.h
../contrib/cppunit-1.12.1/src/cppunit/ProtectorContext.h
../contrib/cppunit-1.12.1/src/cppunit/RepeatedTest.cpp
../contrib/cppunit-1.12.1/src/cppunit/ShlDynamicLibraryManager.cpp
../contrib/cppunit-1.12.1/src/cppunit/SourceLine.cpp
../contrib/cppunit-1.12.1/src/cppunit/StringTools.cpp
../contrib/cppunit-1.12.1/src/cppunit/SynchronizedObject.cpp
../contrib/cppunit-1.12.1/src/cppunit/Test.cpp
../contrib/cppunit-1.12.1/src/cppunit/TestAssert.cpp
../contrib/cppunit-1.12.1/src/cppunit/TestCase.cpp
../contrib/cppunit-1.12.1/src/cppunit/TestCaseDecorator.cpp
../contrib/cppunit-1.12.1/src/cppunit/TestComposite.cpp
../contrib/cppunit-1.12.1/src/cppunit/TestDecorator.cpp
../contrib/cppunit-1.12.1/src/cppunit/TestFactoryRegistry.cpp
../contrib/cppunit-1.12.1/src/cppunit/TestFailure.cpp
../contrib/cppunit-1.12.1/src/cppunit/TestLeaf.cpp
../contrib/cppunit-1.12.1/src/cppunit/TestNamer.cpp
../contrib/cppunit-1.12.1/src/cppunit/TestPath.cpp
../contrib/cppunit-1.12.1/src/cppunit/TestPlugInDefaultImpl.cpp
../contrib/cppunit-1.12.1/src/cppunit/TestResult.cpp
../contrib/cppunit-1.12.1/src/cppunit/TestResultCollector.cpp
../contrib/cppunit-1.12.1/src/cppunit/TestRunner.cpp
../contrib/cppunit-1.12.1/src/cppunit/TestSetUp.cpp
../contrib/cppunit-1.12.1/src/cppunit/TestSuccessListener.cpp
../contrib/cppunit-1.12.1/src/cppunit/TestSuite.cpp
../contrib/cppunit-1.12.1/src/cppunit/TestSuiteBuilderContext.cpp
../contrib/cppunit-1.12.1/src/cppunit/TextOutputter.cpp
../contrib/cppunit-1.12.1/src/cppunit/TextTestProgressListener.cpp
../contrib/cppunit-1.12.1/src/cppunit/TextTestResult.cpp
../contrib/cppunit-1.12.1/src/cppunit/TextTestRunner.cpp
../contrib/cppunit-1.12.1/src/cppunit/TypeInfoHelper.cpp
../contrib/cppunit-1.12.1/src/cppunit/UnixDynamicLibraryManager.cpp
../contrib/cppunit-1.12.1/src/cppunit/Win32DynamicLibraryManager.cpp
../contrib/cppunit-1.12.1/src/cppunit/XmlDocument.cpp
../contrib/cppunit-1.12.1/src/cppunit/XmlElement.cpp
../contrib/cppunit-1.12.1/src/cppunit/XmlOutputter.cpp
../contrib/cppunit-1.12.1/src/cppunit/XmlOutputterHook.cpp
)
IF( WIN32 )
FIND_PACKAGE(DirectX REQUIRED)
ENDIF( WIN32 )
SOURCE_GROUP(tests FILES ${TEST_SRCS})
add_executable( unit
unit/CCompilerTest.c
unit/Main.cpp
unit/UnitTestPCH.cpp
unit/UnitTestPCH.h
${TEST_SRCS}
${CPPUNIT_SRCS}
)
SET_PROPERTY(TARGET assimp PROPERTY DEBUG_POSTFIX ${ASSIMP_DEBUG_POSTFIX})
# TODO: Port to non-Windows platforms.
target_link_libraries ( unit assimp ${DirectX_LIBRARY} ${DirectX_D3DX9_LIBRARY} comctl32.lib Winmm.lib )
target_link_libraries ( unit assimp ${CPPUNIT_LIBRARY} )

View File

@ -0,0 +1,210 @@
<?xml version="1.0"?>
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
<asset>
<contributor>
<author>alorino</author>
<authoring_tool>Maya 7.0 | ColladaMaya v2.01 Jun 9 2006 at 16:08:19 | FCollada v1.11</authoring_tool>
<comments>Collada Maya Export Options: bakeTransforms=0;exportPolygonMeshes=1;bakeLighting=0;isSampling=0;
curveConstrainSampling=0;exportCameraAsLookat=0;
exportLights=1;exportCameras=1;exportJointsAndSkin=1;
exportAnimations=1;exportTriangles=0;exportInvisibleNodes=0;
exportNormals=1;exportTexCoords=1;exportVertexColors=1;exportTangents=0;
exportTexTangents=0;exportConstraints=0;exportPhysics=0;exportXRefs=1;
dereferenceXRefs=0;cameraXFov=0;cameraYFov=1</comments>
<copyright>
Copyright 2006 Sony Computer Entertainment Inc.
Licensed under the SCEA Shared Source License, Version 1.0 (the
&quot;License&quot;); you may not use this file except in compliance with the
License. You may obtain a copy of the License at:
http://research.scea.com/scea_shared_source_license.html
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
</copyright>
</contributor>
<created>2006-06-21T21:23:22Z</created>
<modified>2006-06-21T21:23:22Z</modified>
<unit meter="0.01" name="centimeter"/>
<up_axis>Y_UP</up_axis>
</asset>
<library_cameras>
<camera id="PerspCamera" name="PerspCamera">
<optics>
<technique_common>
<perspective>
<yfov>37.8493</yfov>
<aspect_ratio>1</aspect_ratio>
<znear>10</znear>
<zfar>1000</zfar>
</perspective>
</technique_common>
</optics>
</camera>
<camera id="testCameraShape" name="testCameraShape">
<optics>
<technique_common>
<perspective>
<yfov>37.8501</yfov>
<aspect_ratio>1</aspect_ratio>
<znear>0.01</znear>
<zfar>1000</zfar>
</perspective>
</technique_common>
</optics>
</camera>
</library_cameras>
<library_lights>
<light id="light-lib" name="light">
<technique_common>
<point>
<color>1 1 1</color>
<constant_attenuation>1</constant_attenuation>
<linear_attenuation>0</linear_attenuation>
<quadratic_attenuation>0</quadratic_attenuation>
</point>
</technique_common>
<technique profile="MAX3D">
<intensity>1.000000</intensity>
</technique>
</light>
<light id="pointLightShape1-lib" name="pointLightShape1">
<technique_common>
<point>
<color>1 1 1</color>
<constant_attenuation>1</constant_attenuation>
<linear_attenuation>0</linear_attenuation>
<quadratic_attenuation>0</quadratic_attenuation>
</point>
</technique_common>
</light>
</library_lights>
<library_materials>
<material id="Blue" name="Blue">
<instance_effect url="#Blue-fx"/>
</material>
</library_materials>
<library_effects>
<effect id="Blue-fx">
<profile_COMMON>
<technique sid="common">
<phong>
<emission>
<color>0 0 0 1</color>
</emission>
<ambient>
<color>0 0 0 1</color>
</ambient>
<diffuse>
<color>0.137255 0.403922 0.870588 1</color>
</diffuse>
<specular>
<color>0.5 0.5 0.5 1</color>
</specular>
<shininess>
<float>16</float>
</shininess>
<reflective>
<color>0 0 0 1</color>
</reflective>
<reflectivity>
<float>0.5</float>
</reflectivity>
<transparent>
<color>0 0 0 1</color>
</transparent>
<transparency>
<float>1</float>
</transparency>
<index_of_refraction>
<float>0</float>
</index_of_refraction>
</phong>
</technique>
</profile_COMMON>
</effect>
</library_effects>
<library_geometries>
<geometry id="&quot;&amp;&lt;box-lib&gt;&amp;&quot;" name="&quot;&amp;&lt;box&gt;&amp;&quot;">
<mesh>
<source id="&quot;&amp;&lt;box-lib-positions&gt;&amp;&quot;" name="position">
<float_array id="box-lib-positions-array" count="24">-50 50 50 50 50 50 -50 -50 50 50 -50 50 -50 50 -50 50 50 -50 -50 -50 -50 50 -50 -50</float_array>
<technique_common>
<accessor count="8" offset="0" source="#box-lib-positions-array" stride="3">
<param name="X" type="float"></param>
<param name="Y" type="float"></param>
<param name="Z" type="float"></param>
</accessor>
</technique_common>
</source>
<source id="&quot;&amp;&lt;box-lib-normals&gt;&amp;&quot;" name="normal">
<float_array id="box-lib-normals-array" count="72">0 0 1 0 0 1 0 0 1 0 0 1 0 1 0 0 1 0 0 1 0 0 1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1</float_array>
<technique_common>
<accessor count="24" offset="0" source="#box-lib-normals-array" stride="3">
<param name="X" type="float"></param>
<param name="Y" type="float"></param>
<param name="Z" type="float"></param>
</accessor>
</technique_common>
</source>
<vertices id="&quot;&amp;&lt;box-lib-vertices&gt;&amp;&quot;">
<input semantic="POSITION" source="#&quot;&amp;&lt;box-lib-positions&gt;&amp;&quot;"/>
</vertices>
<polylist count="6" material="BlueSG">
<input offset="0" semantic="VERTEX" source="#&quot;&amp;&lt;box-lib-vertices&gt;&amp;&quot;"/>
<input offset="1" semantic="NORMAL" source="#&quot;&amp;&lt;box-lib-normals&gt;&amp;&quot;"/>
<vcount>4 4 4 4 4 4</vcount>
<p>0 0 2 1 3 2 1 3 0 4 1 5 5 6 4 7 6 8 7 9 3 10 2 11 0 12 4 13 6 14 2 15 3 16 7 17 5 18 1 19 5 20 7 21 6 22 4 23</p>
</polylist>
</mesh>
</geometry>
</library_geometries>
<library_visual_scenes>
<visual_scene id="&quot;&amp;&lt;VisualSceneNode&gt;&amp;&quot;" name="untitled">
<node id="Camera" name="Camera">
<translate sid="translate">-427.749 333.855 655.017</translate>
<rotate sid="rotateY">0 1 0 -33</rotate>
<rotate sid="rotateX">1 0 0 -22.1954</rotate>
<rotate sid="rotateZ">0 0 1 0</rotate>
<instance_camera url="#PerspCamera"/>
</node>
<node id="Light" name="Light">
<translate sid="translate">-500 1000 400</translate>
<rotate sid="rotateZ">0 0 1 0</rotate>
<rotate sid="rotateY">0 1 0 0</rotate>
<rotate sid="rotateX">1 0 0 0</rotate>
<instance_light url="#light-lib"/>
</node>
<node id="Box" name="&quot;&amp;&lt;Box&gt;&amp;&quot;">
<rotate sid="rotateZ">0 0 1 0</rotate>
<rotate sid="rotateY">0 1 0 0</rotate>
<rotate sid="rotateX">1 0 0 0</rotate>
<instance_geometry url="#&quot;&amp;&lt;box-lib&gt;&amp;&quot;">
<bind_material>
<technique_common>
<instance_material symbol="BlueSG" target="#Blue"/>
</technique_common>
</bind_material>
</instance_geometry>
</node>
<node id="testCamera" name="testCamera">
<translate sid="translate">-427.749 333.855 655.017</translate>
<rotate sid="rotateY">0 1 0 -33</rotate>
<rotate sid="rotateX">1 0 0 -22.1954</rotate>
<rotate sid="rotateZ">0 0 1 0</rotate>
<instance_camera url="#testCameraShape"/>
</node>
<node id="pointLight1" name="pointLight1">
<translate sid="translate">3 4 10</translate>
<rotate sid="rotateZ">0 0 1 0</rotate>
<rotate sid="rotateY">0 1 0 0</rotate>
<rotate sid="rotateX">1 0 0 0</rotate>
<instance_light url="#pointLightShape1-lib"/>
</node>
</visual_scene>
</library_visual_scenes>
<scene>
<instance_visual_scene url="#&quot;&amp;&lt;VisualSceneNode&gt;&amp;&quot;"/>
</scene>
</COLLADA>

View File

@ -4,7 +4,7 @@ newmtl
Ns 0
Ka 0.000000 0.000000 0.000000
Kd 0.8 0.8 0.8
Ks 0.8 0.8 0.8
Ks 0
d 1
illum 2

View File

@ -0,0 +1,11 @@
v 1.0 2.0 3.0
v 2.0 3.0 1.0
v 3.0 1.0 2.0
v 1.0 2.0 3.0
vt 1.0 2.0 3.0
vt 2.0 3.0 1.0
vt 3.0 1.0 2.0
vt 1.0 2.0 3.0
f 1 2 3

View File

@ -0,0 +1,23 @@
v 0 0 0
v 1 2. 3.0
v +1 +2. +3.0
v -1 -2. -3.0
v 1e2 2.e1 3.1e2
v +1e2 +2.e1 +3.1e2
v -1e2 -2.e1 -3.1e2
v 1e+2 2.e+1 3.1+e2
v +1e+2 +2.e+1 +3.1+e2
v -1e+2 -2.e+1 -3.1+e2
v 1e-2 2.e-1 3.1-e2
v +1e-2 +2.e-1 +3.1-e2
v -1e-2 -2.e-1 -3.1-e2
v 1e10 2.e01 3.1e10
v 1E2 2.E1 3.1E2
f 1 2 4

View File

@ -1,5 +1,5 @@
// This is just a small test to check whether Assimp's API compiles from C
/* This is just a small test to check whether Assimp's API compiles from C */
#include <assimp/postprocess.h>
#include <assimp/scene.h>

View File

@ -26,9 +26,8 @@ int main (int argc, char* argv[])
// .. and C. They should smoothly work together
aiEnableVerboseLogging(AI_TRUE);
aiAttachLogStream(&aiGetPredefinedLogStream(
aiDefaultLogStream_FILE,
"AssimpLog_C.txt"));
aiLogStream logstream= aiGetPredefinedLogStream(aiDefaultLogStream_FILE, "AssimpLog_C.txt");
aiAttachLogStream(&logstream);
// ............................................................................
@ -66,4 +65,4 @@ int main (int argc, char* argv[])
// Rueckmeldung, ob Tests erfolgreich waren
return collectedresults.wasSuccessful () ? 0 : 1;
}
}

View File

@ -72,7 +72,7 @@ static const aiImporterDesc desc = {
bool TestPlugin :: CanRead( const std::string& pFile,
IOSystem* pIOHandler, bool test) const
IOSystem* /*pIOHandler*/, bool /*test*/) const
{
std::string::size_type pos = pFile.find_last_of('.');
// no file extension - can't read
@ -90,8 +90,8 @@ const aiImporterDesc* TestPlugin :: GetInfo() const
return & desc;
}
void TestPlugin :: InternReadFile( const std::string& pFile,
aiScene* pScene, IOSystem* pIOHandler)
void TestPlugin :: InternReadFile( const std::string& /*pFile*/,
aiScene* /*pScene*/, IOSystem* /*pIOHandler*/)
{
throw DeadlyImportError(AIUT_DEF_ERROR_TEXT);
}
@ -208,11 +208,11 @@ void ImporterTest :: testMultipleReads (void)
CPPUNIT_ASSERT(pImp->ReadFile("../../test/models/X/test.x",flags));
//CPPUNIT_ASSERT(pImp->ReadFile("../../test/models/X/dwarf.x",flags)); # is in nonbsd
CPPUNIT_ASSERT(pImp->ReadFile("../../test/models/X/Testwuson.x",flags));
CPPUNIT_ASSERT(pImp->ReadFile("../../test/models/X/Testwuson.X",flags));
CPPUNIT_ASSERT(pImp->ReadFile("../../test/models/X/anim_test.x",flags));
//CPPUNIT_ASSERT(pImp->ReadFile("../../test/models/X/dwarf.x",flags)); # is in nonbsd
CPPUNIT_ASSERT(pImp->ReadFile("../../test/models/X/anim_test.x",flags));
CPPUNIT_ASSERT(pImp->ReadFile("../../test/models/X/bcn_epileptic.x",flags));
CPPUNIT_ASSERT(pImp->ReadFile("../../test/models/X/BCN_Epileptic.X",flags));
//CPPUNIT_ASSERT(pImp->ReadFile("../../test/models/X/dwarf.x",flags)); # is in nonbsd
}

View File

@ -4,7 +4,7 @@
namespace noboost {
#define ASSIMP_FORCE_NOBOOST
#include "..\..\code\BoostWorkaround\boost\format.hpp"
#include "../../code/BoostWorkaround/boost/format.hpp"
using boost::format;
using boost::str;
@ -34,4 +34,4 @@ class NoBoostTest : public CPPUNIT_NS :: TestFixture
};
#endif
#endif

View File

@ -43,7 +43,7 @@ void RemoveCommentsTest :: testSingleLineComments (void)
// ------------------------------------------------------------------------------------------------
void RemoveCommentsTest :: testMultiLineComments (void)
{
char* szTest =
const char* szTest =
"/* comment to be removed */\n"
"valid text /* \n "
" comment across multiple lines */"
@ -62,4 +62,4 @@ void RemoveCommentsTest :: testMultiLineComments (void)
CPPUNIT_ASSERT(0 == ::strcmp(szTest2,szTestResult));
delete[] szTest2;
}
}

View File

@ -656,7 +656,7 @@ uint32_t WriteBinaryScene(const aiScene* scene)
// -----------------------------------------------------------------------------------
// Write a binary model dump
void WriteBinaryDump(const aiScene* scene, FILE* _out, const char* src, const char* cmd,
bool _shortened, bool compressed, ImportData& imp)
bool _shortened, bool compressed, ImportData& /*imp*/)
{
out = _out;
shortened = _shortened;

View File

@ -1030,18 +1030,17 @@ void PopulateExportMenu()
//-------------------------------------------------------------------------------
void DoExport(size_t formatId)
{
if (!g_szFileName) {
if (!g_szFileName[0]) {
MessageBox(g_hDlg, "No model loaded", "Export", MB_ICONERROR);
return;
}
Exporter exp;
const aiExportFormatDesc* const e = exp.GetExportFormatDescription(formatId);
ai_assert(e);
char szFileName[MAX_PATH*2];
DWORD dwTemp;
if(ERROR_SUCCESS == RegQueryValueEx(g_hRegistry,"ModelExportDest",NULL,NULL,(BYTE*)szFileName,&dwTemp)) {
ai_assert(dwTemp == MAX_PATH + 1);
DWORD dwTemp = sizeof(szFileName);
if(ERROR_SUCCESS == RegQueryValueEx(g_hRegistry,"ModelExportDest",NULL,NULL,(BYTE*)szFileName, &dwTemp)) {
ai_assert(strlen(szFileName) <= MAX_PATH);
// invent a nice default file name