Merge remote-tracking branch 'official/collada_export_escape' into contrib
commit
e2d9512275
10
.travis.yml
10
.travis.yml
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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).
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]))
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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>());
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -259,4 +259,4 @@ unsigned int tokenize( const string_type& str, std::vector<string_type>& tokens,
|
|||
|
||||
} // Namespace Assimp
|
||||
|
||||
#endif
|
||||
#endif // OBJ_TOOLS_H_INC
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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++ &&
|
||||
|
|
|
@ -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
|
|
@ -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("&");
|
||||
break;
|
||||
case '\"':
|
||||
buffer.append(""");
|
||||
break;
|
||||
case '\'':
|
||||
buffer.append("'");
|
||||
break;
|
||||
case '<' :
|
||||
buffer.append("<");
|
||||
break;
|
||||
case '>' :
|
||||
buffer.append(">");
|
||||
break;
|
||||
default:
|
||||
buffer.append(&c, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // INCLUDED_ASSIMP_XML_TOOLS_H
|
|
@ -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 == '.' ..)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
// ------------------------------------------------------------------------------------
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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} )
|
||||
|
|
|
@ -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
|
||||
"License"); 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 "AS IS" 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=""&<box-lib>&"" name=""&<box>&"">
|
||||
<mesh>
|
||||
<source id=""&<box-lib-positions>&"" 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=""&<box-lib-normals>&"" 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=""&<box-lib-vertices>&"">
|
||||
<input semantic="POSITION" source="#"&<box-lib-positions>&""/>
|
||||
</vertices>
|
||||
<polylist count="6" material="BlueSG">
|
||||
<input offset="0" semantic="VERTEX" source="#"&<box-lib-vertices>&""/>
|
||||
<input offset="1" semantic="NORMAL" source="#"&<box-lib-normals>&""/>
|
||||
<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=""&<VisualSceneNode>&"" 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=""&<Box>&"">
|
||||
<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="#"&<box-lib>&"">
|
||||
<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="#"&<VisualSceneNode>&""/>
|
||||
</scene>
|
||||
</COLLADA>
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue