Merge remote-tracking branch 'official/collada_export_escape' into contrib
commit
e2d9512275
10
.travis.yml
10
.travis.yml
|
@ -1,5 +1,5 @@
|
||||||
before_install:
|
before_install:
|
||||||
- sudo apt-get install cmake
|
- sudo apt-get install cmake libcppunit-dev
|
||||||
|
|
||||||
env:
|
env:
|
||||||
- TRAVIS_NO_EXPORT=YES
|
- TRAVIS_NO_EXPORT=YES
|
||||||
|
@ -13,7 +13,9 @@ compiler:
|
||||||
- gcc
|
- gcc
|
||||||
- clang
|
- 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." )
|
"Path the header files are installed to." )
|
||||||
SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE PATH
|
SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE PATH
|
||||||
"Path the tool executables are installed to." )
|
"Path the tool executables are installed to." )
|
||||||
SET ( ASSIMP_BUILD_STATIC_LIB OFF CACHE BOOL
|
option (ASSIMP_BUILD_STATIC_LIB "Build a static (.a) version of the library" OFF)
|
||||||
"Build a static (.a) version of the library" )
|
|
||||||
|
|
||||||
SET(ASSIMP_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfitx for lib, samples and tools")
|
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
|
# Globally enable Boost resp. the Boost workaround – it is also needed by the
|
||||||
# tools which include the Assimp headers.
|
# 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."
|
"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 )
|
IF ( ASSIMP_ENABLE_BOOST_WORKAROUND )
|
||||||
INCLUDE_DIRECTORIES( code/BoostWorkaround )
|
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)
|
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})
|
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
|
option ( ASSIMP_NO_EXPORT
|
||||||
"Disable Assimp's export functionality."
|
"Disable Assimp's export functionality."
|
||||||
|
OFF
|
||||||
)
|
)
|
||||||
|
|
||||||
# Search for external dependencies, and build them from source if not found
|
# 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 )
|
MARK_AS_ADVANCED ( ASSIMP_BUILD_ARCHITECTURE ASSIMP_BUILD_COMPILER )
|
||||||
|
|
||||||
ADD_SUBDIRECTORY( code/ )
|
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."
|
"If the supplementary tools for Assimp are built in addition to the library."
|
||||||
|
ON
|
||||||
)
|
)
|
||||||
IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
||||||
IF ( WIN32 )
|
IF ( WIN32 )
|
||||||
|
@ -196,8 +198,9 @@ IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
||||||
ADD_SUBDIRECTORY( tools/assimp_cmd/ )
|
ADD_SUBDIRECTORY( tools/assimp_cmd/ )
|
||||||
ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
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)."
|
"If the official samples are built as well (needs Glut)."
|
||||||
|
OFF
|
||||||
)
|
)
|
||||||
|
|
||||||
IF ( ASSIMP_BUILD_SAMPLES)
|
IF ( ASSIMP_BUILD_SAMPLES)
|
||||||
|
@ -207,19 +210,19 @@ IF ( ASSIMP_BUILD_SAMPLES)
|
||||||
ADD_SUBDIRECTORY( samples/SimpleOpenGL/ )
|
ADD_SUBDIRECTORY( samples/SimpleOpenGL/ )
|
||||||
ENDIF ( ASSIMP_BUILD_SAMPLES )
|
ENDIF ( ASSIMP_BUILD_SAMPLES )
|
||||||
|
|
||||||
IF ( WIN32 )
|
option ( ASSIMP_BUILD_TESTS
|
||||||
SET ( ASSIMP_BUILD_TESTS ON CACHE BOOL
|
|
||||||
"If the test suite for Assimp is built in addition to the library."
|
"If the test suite for Assimp is built in addition to the library."
|
||||||
|
ON
|
||||||
)
|
)
|
||||||
|
|
||||||
IF ( ASSIMP_BUILD_TESTS )
|
IF ( ASSIMP_BUILD_TESTS )
|
||||||
ADD_SUBDIRECTORY( test/ )
|
ADD_SUBDIRECTORY( test/ )
|
||||||
ENDIF ( ASSIMP_BUILD_TESTS )
|
ENDIF ( ASSIMP_BUILD_TESTS )
|
||||||
ENDIF ( WIN32 )
|
|
||||||
|
|
||||||
IF(MSVC)
|
IF(MSVC)
|
||||||
SET ( ASSIMP_INSTALL_PDB ON CACHE BOOL
|
option ( ASSIMP_INSTALL_PDB
|
||||||
"Install MSVC debug files."
|
"Install MSVC debug files."
|
||||||
|
ON
|
||||||
)
|
)
|
||||||
ENDIF(MSVC)
|
ENDIF(MSVC)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
Open Asset Import Library (assimp)
|
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)
|
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 Binary
|
||||||
- Ogre XML
|
- Ogre XML
|
||||||
- Q3D
|
- 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.
|
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
|
- STL
|
||||||
- OBJ
|
- OBJ
|
||||||
- PLY
|
- PLY
|
||||||
|
- X
|
||||||
|
- 3DS
|
||||||
- JSON (for WebGl, via https://github.com/acgessler/assimp2json)
|
- JSON (for WebGl, via https://github.com/acgessler/assimp2json)
|
||||||
|
- ASSBIN
|
||||||
|
|
||||||
See [the full list here](http://assimp.sourceforge.net/main_features_formats.html).
|
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;
|
bool bIsPrj;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER
|
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
||||||
|
#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER
|
||||||
|
|
||||||
#endif // AI_3DSIMPORTER_H_INC
|
#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());
|
ScopeGuard<aiCamera> out(new aiCamera());
|
||||||
out->mName = obj->id.name+2;
|
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());
|
ScopeGuard<aiLight> out(new aiLight());
|
||||||
out->mName = obj->id.name+2;
|
out->mName = obj->id.name+2;
|
||||||
|
|
|
@ -100,7 +100,7 @@ namespace boost {
|
||||||
};
|
};
|
||||||
|
|
||||||
// dummy
|
// dummy
|
||||||
list_elem& operator = (const list_elem& other) {
|
list_elem& operator = (const list_elem& /*other*/) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ namespace boost {
|
||||||
return me.me;
|
return me.me;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
// A very minimal implementation for up to 5 elements
|
// A very minimal implementation for up to 5 elements
|
||||||
template <typename T0 = detail::nulltype,
|
template <typename T0 = detail::nulltype,
|
||||||
|
@ -278,6 +278,6 @@ namespace boost {
|
||||||
tuple <> t;
|
tuple <> t;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
#endif // !! BOOST_TUPLE_INCLUDED
|
#endif // !! BOOST_TUPLE_INCLUDED
|
||||||
|
|
|
@ -111,6 +111,7 @@ SET( Common_SRCS
|
||||||
MemoryIOWrapper.h
|
MemoryIOWrapper.h
|
||||||
ParsingUtils.h
|
ParsingUtils.h
|
||||||
StreamReader.h
|
StreamReader.h
|
||||||
|
StreamWriter.h
|
||||||
StringComparison.h
|
StringComparison.h
|
||||||
SGSpatialSort.cpp
|
SGSpatialSort.cpp
|
||||||
SGSpatialSort.h
|
SGSpatialSort.h
|
||||||
|
@ -143,6 +144,7 @@ SET( Common_SRCS
|
||||||
LogAux.h
|
LogAux.h
|
||||||
Bitmap.cpp
|
Bitmap.cpp
|
||||||
Bitmap.h
|
Bitmap.h
|
||||||
|
XMLTools.h
|
||||||
)
|
)
|
||||||
SOURCE_GROUP(Common FILES ${Common_SRCS})
|
SOURCE_GROUP(Common FILES ${Common_SRCS})
|
||||||
|
|
||||||
|
@ -151,6 +153,8 @@ SET( 3DS_SRCS
|
||||||
3DSHelper.h
|
3DSHelper.h
|
||||||
3DSLoader.cpp
|
3DSLoader.cpp
|
||||||
3DSLoader.h
|
3DSLoader.h
|
||||||
|
3DSExporter.h
|
||||||
|
3DSExporter.cpp
|
||||||
)
|
)
|
||||||
SOURCE_GROUP(3DS FILES ${3DS_SRCS})
|
SOURCE_GROUP(3DS FILES ${3DS_SRCS})
|
||||||
|
|
||||||
|
@ -168,6 +172,14 @@ SET( ASE_SRCS
|
||||||
)
|
)
|
||||||
SOURCE_GROUP( ASE FILES ${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
|
SET( B3D_SRCS
|
||||||
B3DImporter.cpp
|
B3DImporter.cpp
|
||||||
B3DImporter.h
|
B3DImporter.h
|
||||||
|
@ -612,7 +624,7 @@ SOURCE_GROUP( unzip FILES ${unzip_SRCS})
|
||||||
|
|
||||||
# VC2010 fixes
|
# VC2010 fixes
|
||||||
if(MSVC10)
|
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 )
|
if( VC10_STDINT_FIX )
|
||||||
ADD_DEFINITIONS( -D_STDINT )
|
ADD_DEFINITIONS( -D_STDINT )
|
||||||
endif( VC10_STDINT_FIX )
|
endif( VC10_STDINT_FIX )
|
||||||
|
@ -643,6 +655,7 @@ SET( assimp_src
|
||||||
${3DS_SRCS}
|
${3DS_SRCS}
|
||||||
${AC_SRCS}
|
${AC_SRCS}
|
||||||
${ASE_SRCS}
|
${ASE_SRCS}
|
||||||
|
${ASSBIN_SRCS}
|
||||||
${B3D_SRCS}
|
${B3D_SRCS}
|
||||||
${BVH_SRCS}
|
${BVH_SRCS}
|
||||||
${Collada_SRCS}
|
${Collada_SRCS}
|
||||||
|
|
|
@ -271,7 +271,7 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
|
||||||
const aiVector3D& origNorm = pMesh->mNormals[a];
|
const aiVector3D& origNorm = pMesh->mNormals[a];
|
||||||
const aiVector3D& origTang = pMesh->mTangents[a];
|
const aiVector3D& origTang = pMesh->mTangents[a];
|
||||||
const aiVector3D& origBitang = pMesh->mBitangents[a];
|
const aiVector3D& origBitang = pMesh->mBitangents[a];
|
||||||
closeVertices.clear();
|
closeVertices.resize( 0 );
|
||||||
|
|
||||||
// find all vertices close to that position
|
// find all vertices close to that position
|
||||||
vertexFinder->FindPositions( origPos, posEpsilon, verticesFound);
|
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 "Bitmap.h"
|
||||||
#include "fast_atof.h"
|
#include "fast_atof.h"
|
||||||
#include "SceneCombiner.h"
|
#include "SceneCombiner.h"
|
||||||
|
#include "XMLTools.h"
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
@ -93,6 +94,7 @@ void ExportSceneCollada(const char* pFile, IOSystem* pIOSystem, const aiScene* p
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor for a specific scene to export
|
// 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)
|
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.
|
// useless Collada fu at the end, just in case we haven't had enough indirections, yet.
|
||||||
mOutput << startstr << "<scene>" << endstr;
|
mOutput << startstr << "<scene>" << endstr;
|
||||||
PushTag();
|
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();
|
PopTag();
|
||||||
mOutput << startstr << "</scene>" << endstr;
|
mOutput << startstr << "</scene>" << endstr;
|
||||||
PopTag();
|
PopTag();
|
||||||
|
@ -236,12 +238,12 @@ void ColladaExporter::WriteHeader()
|
||||||
if (!meta || !meta->Get("Author", value))
|
if (!meta || !meta->Get("Author", value))
|
||||||
mOutput << startstr << "<author>" << "Assimp" << "</author>" << endstr;
|
mOutput << startstr << "<author>" << "Assimp" << "</author>" << endstr;
|
||||||
else
|
else
|
||||||
mOutput << startstr << "<author>" << value.C_Str() << "</author>" << endstr;
|
mOutput << startstr << "<author>" << XMLEscape(value.C_Str()) << "</author>" << endstr;
|
||||||
|
|
||||||
if (!meta || !meta->Get("AuthoringTool", value))
|
if (!meta || !meta->Get("AuthoringTool", value))
|
||||||
mOutput << startstr << "<authoring_tool>" << "Assimp Exporter" << "</authoring_tool>" << endstr;
|
mOutput << startstr << "<authoring_tool>" << "Assimp Exporter" << "</authoring_tool>" << endstr;
|
||||||
else
|
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 << "<author>" << mScene->author.C_Str() << "</author>" << endstr;
|
||||||
//mOutput << startstr << "<authoring_tool>" << mScene->authoringTool.C_Str() << "</authoring_tool>" << 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() )
|
if( !pSurface.texture.empty() )
|
||||||
{
|
{
|
||||||
mOutput << startstr << "<image id=\"" << pNameAdd << "\">" << endstr;
|
mOutput << startstr << "<image id=\"" << XMLEscape(pNameAdd) << "\">" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<init_from>";
|
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 )
|
for( std::string::const_iterator it = pSurface.texture.begin(); it != pSurface.texture.end(); ++it )
|
||||||
{
|
{
|
||||||
if( isalnum( *it) || *it == '_' || *it == '.' || *it == '/' || *it == '\\' )
|
if( isalnum( *it) || *it == '_' || *it == '.' || *it == '/' || *it == '\\' )
|
||||||
mOutput << *it;
|
imageUrlEncoded << *it;
|
||||||
else
|
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;
|
mOutput << "</init_from>" << endstr;
|
||||||
PopTag();
|
PopTag();
|
||||||
mOutput << startstr << "</image>" << endstr;
|
mOutput << startstr << "</image>" << endstr;
|
||||||
|
@ -371,7 +377,7 @@ void ColladaExporter::WriteTextureColorEntry( const Surface& pSurface, const std
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mOutput << startstr << "<texture texture=\"" << pImageName << "\" texcoord=\"CHANNEL" << pSurface.channel << "\" />" << endstr;
|
mOutput << startstr << "<texture texture=\"" << XMLEscape(pImageName) << "\" texcoord=\"CHANNEL" << pSurface.channel << "\" />" << endstr;
|
||||||
}
|
}
|
||||||
PopTag();
|
PopTag();
|
||||||
mOutput << startstr << "</" << pTypeName << ">" << endstr;
|
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 surface is a texture, write out the sampler and the surface parameters necessary to reference the texture
|
||||||
if( !pSurface.texture.empty() )
|
if( !pSurface.texture.empty() )
|
||||||
{
|
{
|
||||||
mOutput << startstr << "<newparam sid=\"" << pMatName << "-" << pTypeName << "-surface\">" << endstr;
|
mOutput << startstr << "<newparam sid=\"" << XMLEscape(pMatName) << "-" << pTypeName << "-surface\">" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<surface type=\"2D\">" << endstr;
|
mOutput << startstr << "<surface type=\"2D\">" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<init_from>" << pMatName << "-" << pTypeName << "-image</init_from>" << endstr;
|
mOutput << startstr << "<init_from>" << XMLEscape(pMatName) << "-" << pTypeName << "-image</init_from>" << endstr;
|
||||||
PopTag();
|
PopTag();
|
||||||
mOutput << startstr << "</surface>" << endstr;
|
mOutput << startstr << "</surface>" << endstr;
|
||||||
PopTag();
|
PopTag();
|
||||||
mOutput << startstr << "</newparam>" << endstr;
|
mOutput << startstr << "</newparam>" << endstr;
|
||||||
|
|
||||||
mOutput << startstr << "<newparam sid=\"" << pMatName << "-" << pTypeName << "-sampler\">" << endstr;
|
mOutput << startstr << "<newparam sid=\"" << XMLEscape(pMatName) << "-" << pTypeName << "-sampler\">" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<sampler2D>" << endstr;
|
mOutput << startstr << "<sampler2D>" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<source>" << pMatName << "-" << pTypeName << "-surface</source>" << endstr;
|
mOutput << startstr << "<source>" << XMLEscape(pMatName) << "-" << pTypeName << "-surface</source>" << endstr;
|
||||||
PopTag();
|
PopTag();
|
||||||
mOutput << startstr << "</sampler2D>" << endstr;
|
mOutput << startstr << "</sampler2D>" << endstr;
|
||||||
PopTag();
|
PopTag();
|
||||||
|
@ -439,7 +445,7 @@ void ColladaExporter::WriteMaterials()
|
||||||
name = "mat";
|
name = "mat";
|
||||||
materials[a].name = std::string( "m") + boost::lexical_cast<std::string> (a) + name.C_Str();
|
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 ) {
|
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.
|
// of char to signed int and take the unsigned char value.
|
||||||
if( !isalnum( static_cast<uint8_t>(*it) ) ) {
|
if( !isalnum( static_cast<uint8_t>(*it) ) ) {
|
||||||
*it = '_';
|
*it = '_';
|
||||||
|
@ -510,7 +516,7 @@ void ColladaExporter::WriteMaterials()
|
||||||
{
|
{
|
||||||
const Material& mat = *it;
|
const Material& mat = *it;
|
||||||
// this is so ridiculous it must be right
|
// 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();
|
PushTag();
|
||||||
mOutput << startstr << "<profile_COMMON>" << endstr;
|
mOutput << startstr << "<profile_COMMON>" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
|
@ -561,9 +567,9 @@ void ColladaExporter::WriteMaterials()
|
||||||
for( std::vector<Material>::const_iterator it = materials.begin(); it != materials.end(); ++it )
|
for( std::vector<Material>::const_iterator it = materials.begin(); it != materials.end(); ++it )
|
||||||
{
|
{
|
||||||
const Material& mat = *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();
|
PushTag();
|
||||||
mOutput << startstr << "<instance_effect url=\"#" << mat.name << "-fx\"/>" << endstr;
|
mOutput << startstr << "<instance_effect url=\"#" << XMLEscape(mat.name) << "-fx\"/>" << endstr;
|
||||||
PopTag();
|
PopTag();
|
||||||
mOutput << startstr << "</material>" << endstr;
|
mOutput << startstr << "</material>" << endstr;
|
||||||
}
|
}
|
||||||
|
@ -591,13 +597,14 @@ void ColladaExporter::WriteGeometryLibrary()
|
||||||
void ColladaExporter::WriteGeometry( size_t pIndex)
|
void ColladaExporter::WriteGeometry( size_t pIndex)
|
||||||
{
|
{
|
||||||
const aiMesh* mesh = mScene->mMeshes[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 )
|
if( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// opening tag
|
// opening tag
|
||||||
mOutput << startstr << "<geometry id=\"" << idstr << "\" name=\"" << idstr << "_name\" >" << endstr;
|
mOutput << startstr << "<geometry id=\"" << idstrEscaped << "\" name=\"" << idstrEscaped << "_name\" >" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
|
|
||||||
mOutput << startstr << "<mesh>" << endstr;
|
mOutput << startstr << "<mesh>" << endstr;
|
||||||
|
@ -627,20 +634,20 @@ void ColladaExporter::WriteGeometry( size_t pIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
// assemble vertex structure
|
// assemble vertex structure
|
||||||
mOutput << startstr << "<vertices id=\"" << idstr << "-vertices" << "\">" << endstr;
|
mOutput << startstr << "<vertices id=\"" << idstrEscaped << "-vertices" << "\">" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<input semantic=\"POSITION\" source=\"#" << idstr << "-positions\" />" << endstr;
|
mOutput << startstr << "<input semantic=\"POSITION\" source=\"#" << idstrEscaped << "-positions\" />" << endstr;
|
||||||
if( mesh->HasNormals() )
|
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 )
|
for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a )
|
||||||
{
|
{
|
||||||
if( mesh->HasTextureCoords( 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 )
|
for( size_t a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a )
|
||||||
{
|
{
|
||||||
if( mesh->HasVertexColors( 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();
|
PopTag();
|
||||||
|
@ -660,7 +667,7 @@ void ColladaExporter::WriteGeometry( size_t pIndex)
|
||||||
{
|
{
|
||||||
mOutput << startstr << "<lines count=\"" << countLines << "\" material=\"defaultMaterial\">" << endstr;
|
mOutput << startstr << "<lines count=\"" << countLines << "\" material=\"defaultMaterial\">" << endstr;
|
||||||
PushTag();
|
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>";
|
mOutput << startstr << "<p>";
|
||||||
for( size_t a = 0; a < mesh->mNumFaces; ++a )
|
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;
|
mOutput << startstr << "<polylist count=\"" << countPoly << "\" material=\"defaultMaterial\">" << endstr;
|
||||||
PushTag();
|
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>";
|
mOutput << startstr << "<vcount>";
|
||||||
for( size_t a = 0; a < mesh->mNumFaces; ++a )
|
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";
|
std::string arrayId = pIdString + "-array";
|
||||||
|
|
||||||
mOutput << startstr << "<source id=\"" << pIdString << "\" name=\"" << pIdString << "\">" << endstr;
|
mOutput << startstr << "<source id=\"" << XMLEscape(pIdString) << "\" name=\"" << XMLEscape(pIdString) << "\">" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
|
|
||||||
// source array
|
// source array
|
||||||
mOutput << startstr << "<float_array id=\"" << arrayId << "\" count=\"" << pElementCount * floatsPerElement << "\"> ";
|
mOutput << startstr << "<float_array id=\"" << XMLEscape(arrayId) << "\" count=\"" << pElementCount * floatsPerElement << "\"> ";
|
||||||
PushTag();
|
PushTag();
|
||||||
|
|
||||||
if( pType == FloatType_TexCoord2 )
|
if( pType == FloatType_TexCoord2 )
|
||||||
|
@ -804,11 +811,11 @@ void ColladaExporter::WriteFloatArray( const std::string& pIdString, FloatDataTy
|
||||||
// Writes the scene library
|
// Writes the scene library
|
||||||
void ColladaExporter::WriteSceneLibrary()
|
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;
|
mOutput << startstr << "<library_visual_scenes>" << endstr;
|
||||||
PushTag();
|
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();
|
PushTag();
|
||||||
|
|
||||||
// start recursive write at the root node
|
// start recursive write at the root node
|
||||||
|
@ -833,7 +840,8 @@ void ColladaExporter::WriteNode(aiNode* pNode)
|
||||||
pNode->mName.Set(ss.str());
|
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();
|
PushTag();
|
||||||
|
|
||||||
// write transformation - we can directly put the matrix there
|
// 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 )
|
if( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
mOutput << startstr << "<instance_geometry url=\"#" << GetMeshId( pNode->mMeshes[a]) << "\">" << endstr;
|
mOutput << startstr << "<instance_geometry url=\"#" << XMLEscape(GetMeshId( pNode->mMeshes[a])) << "\">" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<bind_material>" << endstr;
|
mOutput << startstr << "<bind_material>" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<technique_common>" << endstr;
|
mOutput << startstr << "<technique_common>" << endstr;
|
||||||
PushTag();
|
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();
|
PopTag();
|
||||||
mOutput << startstr << "</technique_common>" << endstr;
|
mOutput << startstr << "</technique_common>" << endstr;
|
||||||
PopTag();
|
PopTag();
|
||||||
|
|
|
@ -57,12 +57,15 @@ using namespace Assimp;
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
MakeLeftHandedProcess::MakeLeftHandedProcess()
|
MakeLeftHandedProcess::MakeLeftHandedProcess()
|
||||||
{}
|
: BaseProcess() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Destructor, private as well
|
// Destructor, private as well
|
||||||
MakeLeftHandedProcess::~MakeLeftHandedProcess()
|
MakeLeftHandedProcess::~MakeLeftHandedProcess() {
|
||||||
{}
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
|
@ -121,9 +124,10 @@ void MakeLeftHandedProcess::ProcessNode( aiNode* pNode, const aiMatrix4x4& pPare
|
||||||
pNode->mTransformation.d3 = -pNode->mTransformation.d3; // useless, but anyways...
|
pNode->mTransformation.d3 = -pNode->mTransformation.d3; // useless, but anyways...
|
||||||
|
|
||||||
// continue for all children
|
// continue for all children
|
||||||
for( size_t a = 0; a < pNode->mNumChildren; ++a)
|
for( size_t a = 0; a < pNode->mNumChildren; ++a ) {
|
||||||
ProcessNode( pNode->mChildren[ a ], pParentGlobalRotation * pNode->mTransformation );
|
ProcessNode( pNode->mChildren[ a ], pParentGlobalRotation * pNode->mTransformation );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Converts a single mesh to left handed coordinates.
|
// Converts a single mesh to left handed coordinates.
|
||||||
|
@ -244,6 +248,10 @@ void FlipUVsProcess::ProcessMaterial (aiMaterial* _mat)
|
||||||
aiMaterial* mat = (aiMaterial*)_mat;
|
aiMaterial* mat = (aiMaterial*)_mat;
|
||||||
for (unsigned int a = 0; a < mat->mNumProperties;++a) {
|
for (unsigned int a = 0; a < mat->mNumProperties;++a) {
|
||||||
aiMaterialProperty* prop = mat->mProperties[a];
|
aiMaterialProperty* prop = mat->mProperties[a];
|
||||||
|
if( !prop ) {
|
||||||
|
DefaultLogger::get()->debug( "Property is null" );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// UV transformation key?
|
// UV transformation key?
|
||||||
if (!::strcmp( prop->mKey.data, "$tex.uvtrafo")) {
|
if (!::strcmp( prop->mKey.data, "$tex.uvtrafo")) {
|
||||||
|
@ -263,13 +271,15 @@ void FlipUVsProcess::ProcessMesh( aiMesh* pMesh)
|
||||||
{
|
{
|
||||||
// mirror texture y coordinate
|
// mirror texture y coordinate
|
||||||
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
|
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
|
||||||
if( !pMesh->HasTextureCoords( a))
|
if( !pMesh->HasTextureCoords( a ) ) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
for( unsigned int b = 0; b < pMesh->mNumVertices; b++)
|
for( unsigned int b = 0; b < pMesh->mNumVertices; b++ ) {
|
||||||
pMesh->mTextureCoords[ a ][ b ].y = 1.0f - pMesh->mTextureCoords[ a ][ b ].y;
|
pMesh->mTextureCoords[ a ][ b ].y = 1.0f - pMesh->mTextureCoords[ a ][ b ].y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif // !ASSIMP_BUILD_NO_FLIPUVS_PROCESS
|
#endif // !ASSIMP_BUILD_NO_FLIPUVS_PROCESS
|
||||||
#ifndef ASSIMP_BUILD_NO_FLIPWINDING_PROCESS
|
#ifndef ASSIMP_BUILD_NO_FLIPWINDING_PROCESS
|
||||||
|
|
|
@ -111,8 +111,8 @@ void DeboneProcess::Execute( aiScene* pScene)
|
||||||
|
|
||||||
if(numSplits) {
|
if(numSplits) {
|
||||||
// we need to do something. Let's go.
|
// we need to do something. Let's go.
|
||||||
mSubMeshIndices.clear();
|
//mSubMeshIndices.clear(); // really needed?
|
||||||
mSubMeshIndices.resize(pScene->mNumMeshes);
|
mSubMeshIndices.resize(pScene->mNumMeshes); // because we're doing it here anyway
|
||||||
|
|
||||||
// build a new array of meshes for the scene
|
// build a new array of meshes for the scene
|
||||||
std::vector<aiMesh*> meshes;
|
std::vector<aiMesh*> meshes;
|
||||||
|
|
|
@ -78,7 +78,8 @@ void ExportSceneObj(const char*,IOSystem*, const aiScene*);
|
||||||
void ExportSceneSTL(const char*,IOSystem*, const aiScene*);
|
void ExportSceneSTL(const char*,IOSystem*, const aiScene*);
|
||||||
void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*);
|
void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*);
|
||||||
void ExportScenePly(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
|
// global array of all export formats which Assimp supports in its current build
|
||||||
|
@ -113,9 +114,14 @@ Exporter::ExportFormatEntry gExporters[] =
|
||||||
),
|
),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
|
||||||
// ExportFormatEntry( "3ds", "Autodesk 3DS (legacy format)", "3ds" , &ExportScene3DS),
|
Exporter::ExportFormatEntry( "3ds", "Autodesk 3DS (legacy)", "3ds" , &ExportScene3DS,
|
||||||
//#endif
|
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]))
|
#define ASSIMP_NUM_EXPORTERS (sizeof(gExporters)/sizeof(gExporters[0]))
|
||||||
|
|
|
@ -59,7 +59,7 @@ namespace FBX {
|
||||||
using namespace Util;
|
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)
|
: Object(id, element, name)
|
||||||
{
|
{
|
||||||
const Scope& sc = GetRequiredScope(element);
|
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>& out_indices,
|
||||||
std::vector<size_t>& index_out_indices,
|
std::vector<size_t>& index_out_indices,
|
||||||
std::vector<size_t>& count_out_indices,
|
std::vector<size_t>& count_out_indices,
|
||||||
|
@ -2347,7 +2347,7 @@ private:
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
aiNodeAnim* GenerateScalingNodeAnim(const std::string& name,
|
aiNodeAnim* GenerateScalingNodeAnim(const std::string& name,
|
||||||
const Model& target,
|
const Model& /*target*/,
|
||||||
const std::vector<const AnimationCurveNode*>& curves,
|
const std::vector<const AnimationCurveNode*>& curves,
|
||||||
const LayerMap& layer_map,
|
const LayerMap& layer_map,
|
||||||
double& max_time,
|
double& max_time,
|
||||||
|
@ -2378,7 +2378,7 @@ private:
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
aiNodeAnim* GenerateTranslationNodeAnim(const std::string& name,
|
aiNodeAnim* GenerateTranslationNodeAnim(const std::string& name,
|
||||||
const Model& target,
|
const Model& /*target*/,
|
||||||
const std::vector<const AnimationCurveNode*>& curves,
|
const std::vector<const AnimationCurveNode*>& curves,
|
||||||
const LayerMap& layer_map,
|
const LayerMap& layer_map,
|
||||||
double& max_time,
|
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& maxTime,
|
||||||
double& minTime)
|
double& minTime)
|
||||||
{
|
{
|
||||||
|
@ -2851,7 +2851,7 @@ private:
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ConvertTranslationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
void ConvertTranslationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
||||||
const LayerMap& layers,
|
const LayerMap& /*layers*/,
|
||||||
double& maxTime,
|
double& maxTime,
|
||||||
double& minTime)
|
double& minTime)
|
||||||
{
|
{
|
||||||
|
@ -2869,7 +2869,7 @@ private:
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ConvertRotationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
void ConvertRotationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
||||||
const LayerMap& layers,
|
const LayerMap& /*layers*/,
|
||||||
double& maxTime,
|
double& maxTime,
|
||||||
double& minTime,
|
double& minTime,
|
||||||
Model::RotOrder order)
|
Model::RotOrder order)
|
||||||
|
|
|
@ -253,8 +253,8 @@ Document::Document(const Parser& parser, const ImportSettings& settings)
|
||||||
: settings(settings)
|
: settings(settings)
|
||||||
, parser(parser)
|
, parser(parser)
|
||||||
{
|
{
|
||||||
// cannot use array default initialization syntax because vc8 fails on it
|
// Cannot use array default initialization syntax because vc8 fails on it
|
||||||
for (unsigned int i = 0; i < 7; ++i) {
|
for (unsigned int i = 0; i < sizeof(creationTimeStamp) / sizeof(creationTimeStamp[0]); ++i) {
|
||||||
creationTimeStamp[i] = 0;
|
creationTimeStamp[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,7 +263,7 @@ Document::Document(const Parser& parser, const ImportSettings& settings)
|
||||||
|
|
||||||
ReadGlobalSettings();
|
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,
|
// whether connections are ok or not. Objects may not be evaluated yet,
|
||||||
// though, since this may require valid connections.
|
// though, since this may require valid connections.
|
||||||
ReadObjects();
|
ReadObjects();
|
||||||
|
@ -277,13 +277,18 @@ Document::~Document()
|
||||||
BOOST_FOREACH(ObjectMap::value_type& v, objects) {
|
BOOST_FOREACH(ObjectMap::value_type& v, objects) {
|
||||||
delete v.second;
|
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()
|
void Document::ReadHeader()
|
||||||
{
|
{
|
||||||
// read ID objects from "Objects" section
|
// Read ID objects from "Objects" section
|
||||||
const Scope& sc = parser.GetRootScope();
|
const Scope& sc = parser.GetRootScope();
|
||||||
const Element* const ehead = sc["FBXHeaderExtension"];
|
const Element* const ehead = sc["FBXHeaderExtension"];
|
||||||
if(!ehead || !ehead->Compound()) {
|
if(!ehead || !ehead->Compound()) {
|
||||||
|
@ -293,7 +298,7 @@ void Document::ReadHeader()
|
||||||
const Scope& shead = *ehead->Compound();
|
const Scope& shead = *ehead->Compound();
|
||||||
fbxVersion = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(shead,"FBXVersion",ehead),0));
|
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
|
// the older 6.n fbx format
|
||||||
if(fbxVersion < 7100) {
|
if(fbxVersion < 7100) {
|
||||||
DOMError("unsupported, old format version, supported are only FBX 2011, FBX 2012 and FBX 2013");
|
DOMError("unsupported, old format version, supported are only FBX 2011, FBX 2012 and FBX 2013");
|
||||||
|
|
|
@ -696,7 +696,7 @@ public:
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** Get the Skin attached to this geometry or NULL */
|
/** Get the Skin attached to this geometry or NULL */
|
||||||
const Skin* const DeformerSkin() const {
|
const Skin* DeformerSkin() const {
|
||||||
return skin;
|
return skin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1096,7 +1096,7 @@ public:
|
||||||
return transformLink;
|
return transformLink;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Model* const TargetNode() const {
|
const Model* TargetNode() const {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -179,6 +179,8 @@ void FBXImporter::InternReadFile( const std::string& pFile,
|
||||||
|
|
||||||
// convert the FBX DOM to aiScene
|
// convert the FBX DOM to aiScene
|
||||||
ConvertToAssimpScene(pScene,doc);
|
ConvertToAssimpScene(pScene,doc);
|
||||||
|
|
||||||
|
std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>());
|
||||||
}
|
}
|
||||||
catch(std::exception&) {
|
catch(std::exception&) {
|
||||||
std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>());
|
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)
|
: Object(id,element,name)
|
||||||
,texture(0)
|
,texture(0)
|
||||||
,blendMode(BlendMode_Modulate)
|
,blendMode(BlendMode_Modulate)
|
||||||
|
|
|
@ -466,8 +466,9 @@ void MeshGeometry::ReadVertexDataTangents(std::vector<aiVector3D>& tangents_out,
|
||||||
const std::string& MappingInformationType,
|
const std::string& MappingInformationType,
|
||||||
const std::string& ReferenceInformationType)
|
const std::string& ReferenceInformationType)
|
||||||
{
|
{
|
||||||
|
const char * str = source.Elements().count( "Tangents" ) > 0 ? "Tangents" : "Tangent";
|
||||||
ResolveVertexDataArray(tangents_out,source,MappingInformationType,ReferenceInformationType,
|
ResolveVertexDataArray(tangents_out,source,MappingInformationType,ReferenceInformationType,
|
||||||
"Tangent",
|
str,
|
||||||
"TangentIndex",
|
"TangentIndex",
|
||||||
vertices.size(),
|
vertices.size(),
|
||||||
mapping_counts,
|
mapping_counts,
|
||||||
|
@ -481,8 +482,9 @@ void MeshGeometry::ReadVertexDataBinormals(std::vector<aiVector3D>& binormals_ou
|
||||||
const std::string& MappingInformationType,
|
const std::string& MappingInformationType,
|
||||||
const std::string& ReferenceInformationType)
|
const std::string& ReferenceInformationType)
|
||||||
{
|
{
|
||||||
|
const char * str = source.Elements().count( "Binormals" ) > 0 ? "Binormals" : "Binormal";
|
||||||
ResolveVertexDataArray(binormals_out,source,MappingInformationType,ReferenceInformationType,
|
ResolveVertexDataArray(binormals_out,source,MappingInformationType,ReferenceInformationType,
|
||||||
"Binormal",
|
str,
|
||||||
"BinormalIndex",
|
"BinormalIndex",
|
||||||
vertices.size(),
|
vertices.size(),
|
||||||
mapping_counts,
|
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) {
|
if(element) {
|
||||||
ParseWarning(message,element->KeyToken());
|
ParseWarning(message,element->KeyToken());
|
||||||
|
@ -103,7 +103,7 @@ namespace {
|
||||||
DefaultLogger::get()->warn("FBX-Parser: " + message);
|
DefaultLogger::get()->warn("FBX-Parser: " + message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ParseError(const std::string& message, TokenPtr token)
|
void ParseError(const std::string& message, TokenPtr token)
|
||||||
{
|
{
|
||||||
|
@ -113,6 +113,18 @@ namespace {
|
||||||
ParseError(message);
|
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 {
|
namespace Assimp {
|
||||||
|
@ -275,9 +287,7 @@ uint64_t ParseTokenAsID(const Token& t, const char*& err_out)
|
||||||
return 0L;
|
return 0L;
|
||||||
}
|
}
|
||||||
|
|
||||||
ai_assert(t.end() - data == 9);
|
BE_NCONST uint64_t id = SafeParse<uint64_t>(data+1, t.end());
|
||||||
|
|
||||||
BE_NCONST uint64_t id = *reinterpret_cast<const uint64_t*>(data+1);
|
|
||||||
AI_SWAP8(id);
|
AI_SWAP8(id);
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
@ -316,8 +326,7 @@ size_t ParseTokenAsDim(const Token& t, const char*& err_out)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ai_assert(t.end() - data == 9);
|
BE_NCONST uint64_t id = SafeParse<uint64_t>(data+1, t.end());
|
||||||
BE_NCONST uint64_t id = *reinterpret_cast<const uint64_t*>(data+1);
|
|
||||||
AI_SWAP8(id);
|
AI_SWAP8(id);
|
||||||
return static_cast<size_t>(id);
|
return static_cast<size_t>(id);
|
||||||
}
|
}
|
||||||
|
@ -364,24 +373,10 @@ float ParseTokenAsFloat(const Token& t, const char*& err_out)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data[0] == 'F') {
|
if (data[0] == 'F') {
|
||||||
// Actual size validation happens during Tokenization so
|
return SafeParse<float>(data+1, t.end());
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ai_assert(t.end() - data == sizeof(double) + 1);
|
return SafeParse<double>(data+1, t.end());
|
||||||
|
|
||||||
// Same
|
|
||||||
double out_double;
|
|
||||||
::memcpy(&out_double, data+1, sizeof(double));
|
|
||||||
return static_cast<float>(out_double);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,8 +411,7 @@ int ParseTokenAsInt(const Token& t, const char*& err_out)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ai_assert(t.end() - data == 5);
|
BE_NCONST int32_t ival = SafeParse<int32_t>(data+1, t.end());
|
||||||
BE_NCONST int32_t ival = *reinterpret_cast<const int32_t*>(data+1);
|
|
||||||
AI_SWAP4(ival);
|
AI_SWAP4(ival);
|
||||||
return static_cast<int>(ival);
|
return static_cast<int>(ival);
|
||||||
}
|
}
|
||||||
|
@ -453,10 +447,8 @@ std::string ParseTokenAsString(const Token& t, const char*& err_out)
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
ai_assert(t.end() - data >= 5);
|
|
||||||
|
|
||||||
// read string length
|
// 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_SWAP4(len);
|
||||||
|
|
||||||
ai_assert(t.end() - data == 5 + 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;
|
type = *data;
|
||||||
|
|
||||||
// read number of elements
|
// 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);
|
AI_SWAP4(len);
|
||||||
|
|
||||||
count = 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)
|
// 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,
|
void ReadBinaryDataArray(char type, uint32_t count, const char*& data, const char* end,
|
||||||
std::vector<char>& buff,
|
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 = SafeParse<uint32_t>(data, end);
|
||||||
|
|
||||||
BE_NCONST uint32_t encmode = *reinterpret_cast<const uint32_t*>(data);
|
|
||||||
AI_SWAP4(encmode);
|
AI_SWAP4(encmode);
|
||||||
data += 4;
|
data += 4;
|
||||||
|
|
||||||
// next comes the compressed length
|
// 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);
|
AI_SWAP4(comp_len);
|
||||||
data += 4;
|
data += 4;
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,7 @@ Property* ReadTypedProperty(const Element& element)
|
||||||
ParseTokenAsFloat(*tok[6]))
|
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 new TypedProperty<float>(ParseTokenAsFloat(*tok[4]));
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -143,8 +143,7 @@ private:
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T PropertyGet(const PropertyTable& in, const std::string& name,
|
inline T PropertyGet(const PropertyTable& in, const std::string& name,
|
||||||
const T& defaultValue,
|
const T& defaultValue)
|
||||||
bool ignoreTemplate = false)
|
|
||||||
{
|
{
|
||||||
const Property* const prop = in.Get(name);
|
const Property* const prop = in.Get(name);
|
||||||
if(!prop) {
|
if(!prop) {
|
||||||
|
@ -164,8 +163,7 @@ inline T PropertyGet(const PropertyTable& in, const std::string& name,
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T PropertyGet(const PropertyTable& in, const std::string& name,
|
inline T PropertyGet(const PropertyTable& in, const std::string& name,
|
||||||
bool& result,
|
bool& result)
|
||||||
bool ignoreTemplate = false)
|
|
||||||
{
|
{
|
||||||
const Property* const prop = in.Get(name);
|
const Property* const prop = in.Get(name);
|
||||||
if(!prop) {
|
if(!prop) {
|
||||||
|
|
|
@ -174,7 +174,6 @@ void FindInstancesProcess::Execute( aiScene* pScene)
|
||||||
|
|
||||||
// use a constant epsilon for colors and UV coordinates
|
// use a constant epsilon for colors and UV coordinates
|
||||||
static const float uvEpsilon = 10e-4f;
|
static const float uvEpsilon = 10e-4f;
|
||||||
|
|
||||||
{
|
{
|
||||||
unsigned int i, end = orig->GetNumUVChannels();
|
unsigned int i, end = orig->GetNumUVChannels();
|
||||||
for(i = 0; i < end; ++i) {
|
for(i = 0; i < end; ++i) {
|
||||||
|
|
|
@ -53,7 +53,7 @@ namespace Assimp {
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** The GenFaceNormalsProcess computes vertex normals for all vertizes
|
/** The GenFaceNormalsProcess computes vertex normals for all vertizes
|
||||||
*/
|
*/
|
||||||
class ASSIMP_API_WINONLY GenVertexNormalsProcess : public BaseProcess
|
class ASSIMP_API GenVertexNormalsProcess : public BaseProcess
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@ Intersect IntersectSegmentPlane(const IfcVector3& p,const IfcVector3& n, const I
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ProcessBooleanHalfSpaceDifference(const IfcHalfSpaceSolid* hs, TempMesh& result,
|
void ProcessBooleanHalfSpaceDifference(const IfcHalfSpaceSolid* hs, TempMesh& result,
|
||||||
const TempMesh& first_operand,
|
const TempMesh& first_operand,
|
||||||
ConversionData& conv)
|
ConversionData& /*conv*/)
|
||||||
{
|
{
|
||||||
ai_assert(hs != NULL);
|
ai_assert(hs != NULL);
|
||||||
|
|
||||||
|
|
|
@ -259,7 +259,7 @@ BoundingBox GetBoundingBox(const ClipperLib::Polygon& poly)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void InsertWindowContours(const ContourVector& contours,
|
void InsertWindowContours(const ContourVector& contours,
|
||||||
const std::vector<TempOpening>& openings,
|
const std::vector<TempOpening>& /*openings*/,
|
||||||
TempMesh& curmesh)
|
TempMesh& curmesh)
|
||||||
{
|
{
|
||||||
// fix windows - we need to insert the real, polygonal shapes into the quadratic holes that we have now
|
// fix windows - we need to insert the real, polygonal shapes into the quadratic holes that we have now
|
||||||
|
|
|
@ -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>()) {
|
if(const IfcRectangleProfileDef* const cprofile = def.ToPtr<IfcRectangleProfileDef>()) {
|
||||||
const IfcFloat x = cprofile->XDim*0.5f, y = cprofile->YDim*0.5f;
|
const IfcFloat x = cprofile->XDim*0.5f, y = cprofile->YDim*0.5f;
|
||||||
|
|
|
@ -1045,7 +1045,7 @@ void IFC::GetSchema(EXPRESS::ConversionSchema& out)
|
||||||
namespace STEP {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1253,7 +1253,7 @@ template <> size_t GenericFill<IfcPerformanceHistory>(const DB& db, const LIST&
|
||||||
return base;
|
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;
|
size_t base = 0;
|
||||||
return base;
|
return base;
|
||||||
|
@ -1715,7 +1715,7 @@ template <> size_t GenericFill<IfcPlateType>(const DB& db, const LIST& params, I
|
||||||
return base;
|
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;
|
size_t base = 0;
|
||||||
return base;
|
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
|
// Dispatch the reading to the worker class for this format
|
||||||
DefaultLogger::get()->info("Found a matching importer for this file format");
|
DefaultLogger::get()->info("Found a matching importer for this file format");
|
||||||
pimpl->mProgressHandler->Update();
|
pimpl->mProgressHandler->UpdateFileRead( 0, fileSize );
|
||||||
|
|
||||||
if (profiler) {
|
if (profiler) {
|
||||||
profiler->BeginRegion("import");
|
profiler->BeginRegion("import");
|
||||||
}
|
}
|
||||||
|
|
||||||
pimpl->mScene = imp->ReadFile( this, pFile, pimpl->mIOHandler);
|
pimpl->mScene = imp->ReadFile( this, pFile, pimpl->mIOHandler);
|
||||||
pimpl->mProgressHandler->Update();
|
pimpl->mProgressHandler->UpdateFileRead( fileSize, fileSize );
|
||||||
|
|
||||||
if (profiler) {
|
if (profiler) {
|
||||||
profiler->EndRegion("import");
|
profiler->EndRegion("import");
|
||||||
|
@ -678,7 +687,6 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags)
|
||||||
ScenePreprocessor pre(pimpl->mScene);
|
ScenePreprocessor pre(pimpl->mScene);
|
||||||
pre.ProcessScene();
|
pre.ProcessScene();
|
||||||
|
|
||||||
pimpl->mProgressHandler->Update();
|
|
||||||
if (profiler) {
|
if (profiler) {
|
||||||
profiler->EndRegion("preprocess");
|
profiler->EndRegion("preprocess");
|
||||||
}
|
}
|
||||||
|
@ -768,6 +776,7 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags)
|
||||||
for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) {
|
for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) {
|
||||||
|
|
||||||
BaseProcess* process = pimpl->mPostProcessingSteps[a];
|
BaseProcess* process = pimpl->mPostProcessingSteps[a];
|
||||||
|
pimpl->mProgressHandler->UpdatePostProcess( a, pimpl->mPostProcessingSteps.size() );
|
||||||
if( process->IsActive( pFlags)) {
|
if( process->IsActive( pFlags)) {
|
||||||
|
|
||||||
if (profiler) {
|
if (profiler) {
|
||||||
|
@ -775,7 +784,6 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags)
|
||||||
}
|
}
|
||||||
|
|
||||||
process->ExecuteOnScene ( this );
|
process->ExecuteOnScene ( this );
|
||||||
pimpl->mProgressHandler->Update();
|
|
||||||
|
|
||||||
if (profiler) {
|
if (profiler) {
|
||||||
profiler->EndRegion("postprocess");
|
profiler->EndRegion("postprocess");
|
||||||
|
@ -803,6 +811,7 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags)
|
||||||
}
|
}
|
||||||
#endif // ! DEBUG
|
#endif // ! DEBUG
|
||||||
}
|
}
|
||||||
|
pimpl->mProgressHandler->UpdatePostProcess( pimpl->mPostProcessingSteps.size(), pimpl->mPostProcessingSteps.size() );
|
||||||
|
|
||||||
// update private scene flags
|
// update private scene flags
|
||||||
if( pimpl->mScene )
|
if( pimpl->mScene )
|
||||||
|
|
|
@ -166,6 +166,9 @@ corresponding preprocessor flag to selectively disable formats.
|
||||||
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
|
||||||
# include "FBXImporter.h"
|
# include "FBXImporter.h"
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER
|
||||||
|
# include "AssbinLoader.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
@ -291,6 +294,9 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out)
|
||||||
#if ( !defined ASSIMP_BUILD_NO_FBX_IMPORTER )
|
#if ( !defined ASSIMP_BUILD_NO_FBX_IMPORTER )
|
||||||
out.push_back( new FBXImporter() );
|
out.push_back( new FBXImporter() );
|
||||||
#endif
|
#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
|
* 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.
|
* 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:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -131,10 +131,15 @@ void LimitBoneWeightsProcess::ProcessMesh( aiMesh* pMesh)
|
||||||
|
|
||||||
// and renormalize the weights
|
// and renormalize the weights
|
||||||
float sum = 0.0f;
|
float sum = 0.0f;
|
||||||
for( std::vector<Weight>::const_iterator it = vit->begin(); it != vit->end(); ++it)
|
for( std::vector<Weight>::const_iterator it = vit->begin(); it != vit->end(); ++it ) {
|
||||||
sum += it->mWeight;
|
sum += it->mWeight;
|
||||||
for( std::vector<Weight>::iterator it = vit->begin(); it != vit->end(); ++it)
|
}
|
||||||
it->mWeight /= sum;
|
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) {
|
if (bChanged) {
|
||||||
|
@ -157,18 +162,6 @@ void LimitBoneWeightsProcess::ProcessMesh( aiMesh* pMesh)
|
||||||
const std::vector<aiVertexWeight>& bw = boneWeights[a];
|
const std::vector<aiVertexWeight>& bw = boneWeights[a];
|
||||||
aiBone* bone = pMesh->mBones[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() )
|
if ( bw.empty() )
|
||||||
{
|
{
|
||||||
abNoNeed[a] = bChanged = true;
|
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
|
// 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);
|
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));
|
::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
|
} // end of namespace Assimp
|
||||||
|
|
||||||
|
static const std::string MaterialExt = ".mtl";
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ObjExporter :: ObjExporter(const char* _filename, const aiScene* pScene)
|
ObjExporter :: ObjExporter(const char* _filename, const aiScene* pScene)
|
||||||
|
@ -107,7 +108,7 @@ std::string ObjExporter :: GetMaterialLibName()
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
std::string ObjExporter :: GetMaterialLibFileName()
|
std::string ObjExporter :: GetMaterialLibFileName()
|
||||||
{
|
{
|
||||||
return filename + ".mtl";
|
return filename + MaterialExt;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -144,16 +145,16 @@ void ObjExporter :: WriteMaterialFile()
|
||||||
|
|
||||||
aiColor4D c;
|
aiColor4D c;
|
||||||
if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_DIFFUSE,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)) {
|
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)) {
|
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)) {
|
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;
|
float o;
|
||||||
|
@ -170,16 +171,19 @@ void ObjExporter :: WriteMaterialFile()
|
||||||
|
|
||||||
aiString s;
|
aiString s;
|
||||||
if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_DIFFUSE(0),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)) {
|
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)) {
|
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)) {
|
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)) {
|
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
|
// implementations seem to vary here, so write both variants
|
||||||
|
@ -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 AmbientTexture = "map_ka";
|
||||||
static const std::string SpecularTexture = "map_ks";
|
static const std::string SpecularTexture = "map_ks";
|
||||||
static const std::string OpacityTexture = "map_d";
|
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 BumpTexture1 = "map_bump";
|
||||||
static const std::string BumpTexture2 = "map_Bump";
|
static const std::string BumpTexture2 = "map_Bump";
|
||||||
static const std::string BumpTexture3 = "bump";
|
static const std::string BumpTexture3 = "bump";
|
||||||
|
@ -128,6 +129,7 @@ void ObjFileMtlImporter::load()
|
||||||
{
|
{
|
||||||
switch (*m_DataIt)
|
switch (*m_DataIt)
|
||||||
{
|
{
|
||||||
|
case 'k':
|
||||||
case 'K':
|
case 'K':
|
||||||
{
|
{
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
|
@ -221,14 +223,16 @@ void ObjFileMtlImporter::getColorRGBA( aiColor3D *pColor )
|
||||||
{
|
{
|
||||||
ai_assert( NULL != 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 );
|
m_DataIt = getFloat<DataArrayIt>( m_DataIt, m_DataItEnd, r );
|
||||||
pColor->r = r;
|
pColor->r = r;
|
||||||
|
|
||||||
|
// 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, g );
|
||||||
pColor->g = g;
|
|
||||||
|
|
||||||
m_DataIt = getFloat<DataArrayIt>( m_DataIt, m_DataItEnd, b );
|
m_DataIt = getFloat<DataArrayIt>( m_DataIt, m_DataItEnd, b );
|
||||||
|
}
|
||||||
|
pColor->g = g;
|
||||||
pColor->b = b;
|
pColor->b = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,11 +307,7 @@ void ObjFileMtlImporter::getTexture() {
|
||||||
// Opacity texture
|
// Opacity texture
|
||||||
out = & m_pModel->m_pCurrentMaterial->textureOpacity;
|
out = & m_pModel->m_pCurrentMaterial->textureOpacity;
|
||||||
clampIndex = ObjFile::Material::TextureOpacityType;
|
clampIndex = ObjFile::Material::TextureOpacityType;
|
||||||
} else if (!ASSIMP_strincmp( pPtr,"map_ka",6)) {
|
} else if (!ASSIMP_strincmp( pPtr, EmmissiveTexture.c_str(), EmmissiveTexture.size())) {
|
||||||
// Ambient texture
|
|
||||||
out = & m_pModel->m_pCurrentMaterial->textureAmbient;
|
|
||||||
clampIndex = ObjFile::Material::TextureAmbientType;
|
|
||||||
} else if (!ASSIMP_strincmp(&(*m_DataIt),"map_emissive",6)) {
|
|
||||||
// Emissive texture
|
// Emissive texture
|
||||||
out = & m_pModel->m_pCurrentMaterial->textureEmissive;
|
out = & m_pModel->m_pCurrentMaterial->textureEmissive;
|
||||||
clampIndex = ObjFile::Material::TextureEmissiveType;
|
clampIndex = ObjFile::Material::TextureEmissiveType;
|
||||||
|
|
|
@ -233,12 +233,13 @@ void ObjFileParser::copyNextLine(char *pBuffer, size_t length)
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
void ObjFileParser::getVector( std::vector<aiVector3D> &point3d_array ) {
|
void ObjFileParser::getVector( std::vector<aiVector3D> &point3d_array ) {
|
||||||
size_t numComponents( 0 );
|
size_t numComponents( 0 );
|
||||||
DataArrayIt tmp( m_DataIt );
|
const char* tmp( &m_DataIt[0] );
|
||||||
while( !IsLineEnd( *tmp ) ) {
|
while( !IsLineEnd( *tmp ) ) {
|
||||||
if( *tmp == ' ' ) {
|
if ( !SkipSpaces( &tmp ) ) {
|
||||||
++numComponents;
|
break;
|
||||||
}
|
}
|
||||||
tmp++;
|
SkipToken( tmp );
|
||||||
|
++numComponents;
|
||||||
}
|
}
|
||||||
float x, y, z;
|
float x, y, z;
|
||||||
if( 2 == numComponents ) {
|
if( 2 == numComponents ) {
|
||||||
|
@ -550,13 +551,15 @@ void ObjFileParser::getNewMaterial()
|
||||||
{
|
{
|
||||||
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
||||||
m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
|
m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
|
||||||
if ( m_DataIt == m_DataItEnd )
|
if( m_DataIt == m_DataItEnd ) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
char *pStart = &(*m_DataIt);
|
char *pStart = &(*m_DataIt);
|
||||||
std::string strMat( pStart, *m_DataIt );
|
std::string strMat( pStart, *m_DataIt );
|
||||||
while ( m_DataIt != m_DataItEnd && isSeparator( *m_DataIt ) )
|
while( m_DataIt != m_DataItEnd && isSeparator( *m_DataIt ) ) {
|
||||||
m_DataIt++;
|
++m_DataIt;
|
||||||
|
}
|
||||||
std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( strMat );
|
std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( strMat );
|
||||||
if ( it == m_pModel->m_MaterialMap.end() )
|
if ( it == m_pModel->m_MaterialMap.end() )
|
||||||
{
|
{
|
||||||
|
@ -581,8 +584,9 @@ void ObjFileParser::getNewMaterial()
|
||||||
int ObjFileParser::getMaterialIndex( const std::string &strMaterialName )
|
int ObjFileParser::getMaterialIndex( const std::string &strMaterialName )
|
||||||
{
|
{
|
||||||
int mat_index = -1;
|
int mat_index = -1;
|
||||||
if ( strMaterialName.empty() )
|
if( strMaterialName.empty() ) {
|
||||||
return mat_index;
|
return mat_index;
|
||||||
|
}
|
||||||
for (size_t index = 0; index < m_pModel->m_MaterialLib.size(); ++index)
|
for (size_t index = 0; index < m_pModel->m_MaterialLib.size(); ++index)
|
||||||
{
|
{
|
||||||
if ( strMaterialName == m_pModel->m_MaterialLib[ index ])
|
if ( strMaterialName == m_pModel->m_MaterialLib[ index ])
|
||||||
|
@ -601,8 +605,9 @@ void ObjFileParser::getGroupName()
|
||||||
std::string strGroupName;
|
std::string strGroupName;
|
||||||
|
|
||||||
m_DataIt = getName<DataArrayIt>(m_DataIt, m_DataItEnd, strGroupName);
|
m_DataIt = getName<DataArrayIt>(m_DataIt, m_DataItEnd, strGroupName);
|
||||||
if ( isEndOfBuffer( m_DataIt, m_DataItEnd ) )
|
if( isEndOfBuffer( m_DataIt, m_DataItEnd ) ) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Change active group, if necessary
|
// Change active group, if necessary
|
||||||
if ( m_pModel->m_strActiveGroup != strGroupName )
|
if ( m_pModel->m_strActiveGroup != strGroupName )
|
||||||
|
@ -653,11 +658,13 @@ void ObjFileParser::getGroupNumberAndResolution()
|
||||||
void ObjFileParser::getObjectName()
|
void ObjFileParser::getObjectName()
|
||||||
{
|
{
|
||||||
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
||||||
if (m_DataIt == m_DataItEnd)
|
if( m_DataIt == m_DataItEnd ) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
char *pStart = &(*m_DataIt);
|
char *pStart = &(*m_DataIt);
|
||||||
while ( m_DataIt != m_DataItEnd && !isSeparator( *m_DataIt ) )
|
while( m_DataIt != m_DataItEnd && !isSeparator( *m_DataIt ) ) {
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
|
}
|
||||||
|
|
||||||
std::string strObjectName(pStart, &(*m_DataIt));
|
std::string strObjectName(pStart, &(*m_DataIt));
|
||||||
if (!strObjectName.empty())
|
if (!strObjectName.empty())
|
||||||
|
@ -678,9 +685,10 @@ void ObjFileParser::getObjectName()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate a new object, if current one was not found before
|
// Allocate a new object, if current one was not found before
|
||||||
if ( NULL == m_pModel->m_pCurrent )
|
if( NULL == m_pModel->m_pCurrent ) {
|
||||||
createObject( strObjectName );
|
createObject( strObjectName );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
|
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_pCurrent->m_strObjName = strObjectName;
|
||||||
m_pModel->m_Objects.push_back( m_pModel->m_pCurrent );
|
m_pModel->m_Objects.push_back( m_pModel->m_pCurrent );
|
||||||
|
|
||||||
|
|
||||||
createMesh();
|
createMesh();
|
||||||
|
|
||||||
if( m_pModel->m_pCurrentMaterial )
|
if( m_pModel->m_pCurrentMaterial )
|
||||||
|
|
|
@ -259,4 +259,4 @@ unsigned int tokenize( const string_type& str, std::vector<string_type>& tokens,
|
||||||
|
|
||||||
} // Namespace Assimp
|
} // Namespace Assimp
|
||||||
|
|
||||||
#endif
|
#endif // OBJ_TOOLS_H_INC
|
||||||
|
|
|
@ -376,14 +376,14 @@ void OgreBinarySerializer::ReadMeshSkeletonLink(Mesh *mesh)
|
||||||
mesh->skeletonRef = ReadLine();
|
mesh->skeletonRef = ReadLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OgreBinarySerializer::ReadMeshBounds(Mesh *mesh)
|
void OgreBinarySerializer::ReadMeshBounds(Mesh * /*mesh*/)
|
||||||
{
|
{
|
||||||
// Skip bounds, not compatible with Assimp.
|
// Skip bounds, not compatible with Assimp.
|
||||||
// 2x float vec3 + 1x float sphere radius
|
// 2x float vec3 + 1x float sphere radius
|
||||||
SkipBytes(sizeof(float) * 7);
|
SkipBytes(sizeof(float) * 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OgreBinarySerializer::ReadMeshExtremes(Mesh *mesh)
|
void OgreBinarySerializer::ReadMeshExtremes(Mesh * /*mesh*/)
|
||||||
{
|
{
|
||||||
// Skip extremes, not compatible with Assimp.
|
// Skip extremes, not compatible with Assimp.
|
||||||
size_t numBytes = m_currentLen - MSTREAM_OVERHEAD_SIZE;
|
size_t numBytes = m_currentLen - MSTREAM_OVERHEAD_SIZE;
|
||||||
|
@ -534,7 +534,6 @@ void OgreBinarySerializer::ReadSubMeshTextureAlias(SubMesh *submesh)
|
||||||
void OgreBinarySerializer::ReadSubMeshNames(Mesh *mesh)
|
void OgreBinarySerializer::ReadSubMeshNames(Mesh *mesh)
|
||||||
{
|
{
|
||||||
uint16_t id = 0;
|
uint16_t id = 0;
|
||||||
uint16_t submeshIndex = 0;
|
|
||||||
|
|
||||||
if (!AtEnd())
|
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");
|
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.
|
// 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)");
|
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>();
|
uint16_t boneId = Read<uint16_t>();
|
||||||
Bone *bone = dest->parentSkeleton->BoneById(boneId);
|
Bone *bone = dest->parentSkeleton->BoneById(boneId);
|
||||||
|
@ -1097,7 +1096,7 @@ void OgreBinarySerializer::ReadSkeletonAnimationKeyFrame(VertexAnimationTrack *d
|
||||||
dest->transformKeyFrames.push_back(keyframe);
|
dest->transformKeyFrames.push_back(keyframe);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OgreBinarySerializer::ReadSkeletonAnimationLink(Skeleton *skeleton)
|
void OgreBinarySerializer::ReadSkeletonAnimationLink(Skeleton * /*skeleton*/)
|
||||||
{
|
{
|
||||||
// Skip bounds, not compatible with Assimp.
|
// Skip bounds, not compatible with Assimp.
|
||||||
ReadLine(); // skeleton name
|
ReadLine(); // skeleton name
|
||||||
|
|
|
@ -75,8 +75,8 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
OgreBinarySerializer(MemoryStreamReader *reader, AssetMode mode) :
|
OgreBinarySerializer(MemoryStreamReader *reader, AssetMode mode) :
|
||||||
m_reader(reader),
|
|
||||||
m_currentLen(0),
|
m_currentLen(0),
|
||||||
|
m_reader(reader),
|
||||||
assetMode(mode)
|
assetMode(mode)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -301,11 +301,12 @@ enum MeshChunkId
|
||||||
// unsigned short poseIndex
|
// unsigned short poseIndex
|
||||||
// float influence
|
// float influence
|
||||||
// Optional submesh extreme vertex list chink
|
// Optional submesh extreme vertex list chink
|
||||||
M_TABLE_EXTREMES = 0xE000,
|
M_TABLE_EXTREMES = 0xE000
|
||||||
// unsigned short submesh_index;
|
// unsigned short submesh_index;
|
||||||
// float extremes [n_extremes][3];
|
// float extremes [n_extremes][3];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
static std::string MeshHeaderToString(MeshChunkId id)
|
static std::string MeshHeaderToString(MeshChunkId id)
|
||||||
{
|
{
|
||||||
switch(id)
|
switch(id)
|
||||||
|
@ -347,6 +348,7 @@ static std::string MeshHeaderToString(MeshChunkId id)
|
||||||
}
|
}
|
||||||
return "Unknown_MeshChunkId";
|
return "Unknown_MeshChunkId";
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
enum SkeletonChunkId
|
enum SkeletonChunkId
|
||||||
{
|
{
|
||||||
|
@ -393,6 +395,7 @@ enum SkeletonChunkId
|
||||||
// float scale : scale to apply to trans/scale keys
|
// float scale : scale to apply to trans/scale keys
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
static std::string SkeletonHeaderToString(SkeletonChunkId id)
|
static std::string SkeletonHeaderToString(SkeletonChunkId id)
|
||||||
{
|
{
|
||||||
switch(id)
|
switch(id)
|
||||||
|
@ -409,6 +412,7 @@ static std::string SkeletonHeaderToString(SkeletonChunkId id)
|
||||||
}
|
}
|
||||||
return "Unknown_SkeletonChunkId";
|
return "Unknown_SkeletonChunkId";
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
} // Ogre
|
} // Ogre
|
||||||
} // Assimp
|
} // Assimp
|
||||||
|
|
||||||
|
|
|
@ -404,9 +404,9 @@ size_t IndexData::FaceSize() const
|
||||||
// Mesh
|
// Mesh
|
||||||
|
|
||||||
Mesh::Mesh() :
|
Mesh::Mesh() :
|
||||||
sharedVertexData(0),
|
hasSkeletalAnimations(false),
|
||||||
skeleton(0),
|
skeleton(NULL),
|
||||||
hasSkeletalAnimations(false)
|
sharedVertexData(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -712,8 +712,8 @@ aiMesh *SubMesh::ConvertToAssimpMesh(Mesh *parent)
|
||||||
// MeshXml
|
// MeshXml
|
||||||
|
|
||||||
MeshXml::MeshXml() :
|
MeshXml::MeshXml() :
|
||||||
sharedVertexData(0),
|
skeleton(0),
|
||||||
skeleton(0)
|
sharedVertexData(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -797,8 +797,8 @@ void MeshXml::ConvertToAssimpScene(aiScene* dest)
|
||||||
// SubMeshXml
|
// SubMeshXml
|
||||||
|
|
||||||
SubMeshXml::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::Animation(Skeleton *parent) :
|
Animation::Animation(Skeleton *parent) :
|
||||||
|
parentMesh(NULL),
|
||||||
parentSkeleton(parent),
|
parentSkeleton(parent),
|
||||||
parentMesh(0),
|
|
||||||
length(0.0f),
|
length(0.0f),
|
||||||
baseTime(-1.0f)
|
baseTime(-1.0f)
|
||||||
{
|
{
|
||||||
|
@ -963,6 +963,8 @@ aiAnimation *Animation::ConvertToAssimpAnimation()
|
||||||
// Skeleton
|
// Skeleton
|
||||||
|
|
||||||
Skeleton::Skeleton() :
|
Skeleton::Skeleton() :
|
||||||
|
bones(),
|
||||||
|
animations(),
|
||||||
blendMode(ANIMBLEND_AVERAGE)
|
blendMode(ANIMBLEND_AVERAGE)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -1103,7 +1105,7 @@ aiNode *Bone::ConvertToAssimpNode(Skeleton *skeleton, aiNode *parentNode)
|
||||||
return node;
|
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();
|
aiBone *bone = new aiBone();
|
||||||
bone->mName = name;
|
bone->mName = name;
|
||||||
|
@ -1122,8 +1124,8 @@ aiBone *Bone::ConvertToAssimpBone(Skeleton *parent, const std::vector<aiVertexWe
|
||||||
// VertexAnimationTrack
|
// VertexAnimationTrack
|
||||||
|
|
||||||
VertexAnimationTrack::VertexAnimationTrack() :
|
VertexAnimationTrack::VertexAnimationTrack() :
|
||||||
target(0),
|
type(VAT_NONE),
|
||||||
type(VAT_NONE)
|
target(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define AI_PARSING_UTILS_H_INC
|
#define AI_PARSING_UTILS_H_INC
|
||||||
|
|
||||||
#include "StringComparison.h"
|
#include "StringComparison.h"
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
// NOTE: the functions below are mostly intended as replacement for
|
// NOTE: the functions below are mostly intended as replacement for
|
||||||
|
@ -55,7 +56,9 @@ namespace Assimp {
|
||||||
|
|
||||||
// The functions below accept any character type, but know only
|
// The functions below accept any character type, but know only
|
||||||
// about ASCII. However, UTF-32 is the only safe ASCII superset to
|
// about ASCII. However, UTF-32 is the only safe ASCII superset to
|
||||||
// use since it doesn't have multibyte sequences.
|
// use since it doesn't have multi-byte sequences.
|
||||||
|
|
||||||
|
static const unsigned int BufferSize = 4096;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
template <class char_t>
|
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;
|
return (in >= (char_t)'A' && in <= (char_t)'Z') ? (char_t)(in+0x20) : in;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
template <class char_t>
|
template <class char_t>
|
||||||
AI_FORCE_INLINE char_t ToUpper( char_t in)
|
AI_FORCE_INLINE char_t ToUpper( char_t in) {
|
||||||
{
|
|
||||||
return (in >= (char_t)'a' && in <= (char_t)'z') ? (char_t)(in-0x20) : in;
|
return (in >= (char_t)'a' && in <= (char_t)'z') ? (char_t)(in-0x20) : in;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
template <class char_t>
|
template <class char_t>
|
||||||
AI_FORCE_INLINE bool IsUpper( char_t in)
|
AI_FORCE_INLINE bool IsUpper( char_t in)
|
||||||
{
|
{
|
||||||
return (in >= (char_t)'A' && in <= (char_t)'Z');
|
return (in >= (char_t)'A' && in <= (char_t)'Z');
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
template <class char_t>
|
template <class char_t>
|
||||||
AI_FORCE_INLINE bool IsLower( char_t in)
|
AI_FORCE_INLINE bool IsLower( char_t in)
|
||||||
{
|
{
|
||||||
return (in >= (char_t)'a' && in <= (char_t)'z');
|
return (in >= (char_t)'a' && in <= (char_t)'z');
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
template <class char_t>
|
template <class char_t>
|
||||||
AI_FORCE_INLINE bool IsSpace( char_t in)
|
AI_FORCE_INLINE bool IsSpace( char_t in)
|
||||||
{
|
{
|
||||||
return (in == (char_t)' ' || in == (char_t)'\t');
|
return (in == (char_t)' ' || in == (char_t)'\t');
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
template <class char_t>
|
template <class char_t>
|
||||||
AI_FORCE_INLINE bool IsLineEnd( char_t in)
|
AI_FORCE_INLINE bool IsLineEnd( char_t in)
|
||||||
{
|
{
|
||||||
return (in == (char_t)'\r' || in == (char_t)'\n' || in == (char_t)'\0');
|
return (in == (char_t)'\r' || in == (char_t)'\n' || in == (char_t)'\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
template <class char_t>
|
template <class char_t>
|
||||||
AI_FORCE_INLINE bool IsSpaceOrNewLine( char_t in)
|
AI_FORCE_INLINE bool IsSpaceOrNewLine( char_t in)
|
||||||
{
|
{
|
||||||
return IsSpace<char_t>(in) || IsLineEnd<char_t>(in);
|
return IsSpace<char_t>(in) || IsLineEnd<char_t>(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
template <class char_t>
|
template <class char_t>
|
||||||
AI_FORCE_INLINE bool SkipSpaces( const char_t* in, const char_t** out)
|
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;
|
*out = in;
|
||||||
return !IsLineEnd<char_t>(*in);
|
return !IsLineEnd<char_t>(*in);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
template <class char_t>
|
template <class char_t>
|
||||||
AI_FORCE_INLINE bool SkipSpaces( const char_t** inout)
|
AI_FORCE_INLINE bool SkipSpaces( const char_t** inout)
|
||||||
{
|
{
|
||||||
return SkipSpaces<char_t>(*inout,inout);
|
return SkipSpaces<char_t>(*inout,inout);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
template <class char_t>
|
template <class char_t>
|
||||||
AI_FORCE_INLINE bool SkipLine( const char_t* in, const char_t** out)
|
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
|
// 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;
|
*out = in;
|
||||||
return *in != (char_t)'\0';
|
return *in != (char_t)'\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
template <class char_t>
|
template <class char_t>
|
||||||
AI_FORCE_INLINE bool SkipLine( const char_t** inout)
|
AI_FORCE_INLINE bool SkipLine( const char_t** inout)
|
||||||
{
|
{
|
||||||
return SkipLine<char_t>(*inout,inout);
|
return SkipLine<char_t>(*inout,inout);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
template <class char_t>
|
template <class char_t>
|
||||||
AI_FORCE_INLINE bool SkipSpacesAndLineEnd( const char_t* in, const char_t** out)
|
AI_FORCE_INLINE bool SkipSpacesAndLineEnd( const char_t* in, const char_t** out)
|
||||||
{
|
{
|
||||||
while (*in == (char_t)' ' || *in == (char_t)'\t' ||
|
while( *in == ( char_t )' ' || *in == ( char_t )'\t' || *in == ( char_t )'\r' || *in == ( char_t )'\n' ) {
|
||||||
*in == (char_t)'\r' || *in == (char_t)'\n')in++;
|
++in;
|
||||||
|
}
|
||||||
*out = in;
|
*out = in;
|
||||||
return *in != '\0';
|
return *in != '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
template <class char_t>
|
template <class char_t>
|
||||||
AI_FORCE_INLINE bool SkipSpacesAndLineEnd( const char_t** inout)
|
AI_FORCE_INLINE bool SkipSpacesAndLineEnd( const char_t** inout)
|
||||||
{
|
{
|
||||||
return SkipSpacesAndLineEnd<char_t>(*inout,inout);
|
return SkipSpacesAndLineEnd<char_t>(*inout,inout);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
template <class char_t>
|
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* _out = out;
|
||||||
char* const end = _out+4096;
|
char* const end = _out + BufferSize;
|
||||||
while (!IsLineEnd( *buffer ) && _out < end)
|
while( !IsLineEnd( *buffer ) && _out < end ) {
|
||||||
*_out++ = *buffer++;
|
*_out++ = *buffer++;
|
||||||
|
}
|
||||||
*_out = (char_t)'\0';
|
*_out = (char_t)'\0';
|
||||||
|
|
||||||
while (IsLineEnd( *buffer ) && '\0' != *buffer)++buffer;
|
while( IsLineEnd( *buffer ) && '\0' != *buffer ) {
|
||||||
|
++buffer;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
template <class char_t>
|
template <class char_t>
|
||||||
AI_FORCE_INLINE bool IsNumeric( char_t in)
|
AI_FORCE_INLINE bool IsNumeric( char_t in)
|
||||||
{
|
{
|
||||||
return ( in >= '0' && in <= '9' ) || '-' == in || '+' == in;
|
return ( in >= '0' && in <= '9' ) || '-' == in || '+' == in;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
template <class char_t>
|
template <class char_t>
|
||||||
AI_FORCE_INLINE bool TokenMatch(char_t*& in, const char* token, unsigned int len)
|
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;
|
in += len+1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
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)
|
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;
|
in += len+1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -206,5 +235,9 @@ AI_FORCE_INLINE std::string GetNextToken(const char*& in)
|
||||||
while (!IsSpaceOrNewLine(*in))++in;
|
while (!IsSpaceOrNewLine(*in))++in;
|
||||||
return std::string(cur,(size_t)(in-cur));
|
return std::string(cur,(size_t)(in-cur));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------
|
||||||
|
|
||||||
} // ! namespace Assimp
|
} // ! namespace Assimp
|
||||||
|
|
||||||
#endif // ! AI_PARSING_UTILS_H_INC
|
#endif // ! AI_PARSING_UTILS_H_INC
|
||||||
|
|
|
@ -73,11 +73,13 @@ static const aiImporterDesc desc = {
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
/*
|
||||||
static void getSupportedExtensions(std::vector<std::string> &supportedExtensions) {
|
static void getSupportedExtensions(std::vector<std::string> &supportedExtensions) {
|
||||||
supportedExtensions.push_back( ".jpg" );
|
supportedExtensions.push_back( ".jpg" );
|
||||||
supportedExtensions.push_back( ".png" );
|
supportedExtensions.push_back( ".png" );
|
||||||
supportedExtensions.push_back( ".tga" );
|
supportedExtensions.push_back( ".tga" );
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
using namespace Q3BSP;
|
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);
|
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;
|
IOStream* io_stream = (IOStream*) stream;
|
||||||
|
|
||||||
return io_stream->Read(buf, 1, size);
|
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;
|
IOStream* io_stream = (IOStream*) stream;
|
||||||
|
|
||||||
return io_stream->Write(buf, 1, size);
|
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;
|
IOStream* io_stream = (IOStream*) stream;
|
||||||
|
|
||||||
return io_stream->Tell();
|
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;
|
IOStream* io_stream = (IOStream*) stream;
|
||||||
|
|
||||||
aiOrigin assimp_origin;
|
aiOrigin assimp_origin;
|
||||||
|
@ -115,7 +115,7 @@ int IOSystem2Unzip::close(voidpf opaque, voidpf stream) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int IOSystem2Unzip::testerror(voidpf opaque, voidpf stream) {
|
int IOSystem2Unzip::testerror(voidpf /*opaque*/, voidpf /*stream*/) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -348,8 +348,8 @@ bool STLImporter::LoadBinaryFile()
|
||||||
bool bIsMaterialise = false;
|
bool bIsMaterialise = false;
|
||||||
|
|
||||||
// search for an occurence of "COLOR=" in the header
|
// search for an occurence of "COLOR=" in the header
|
||||||
const char* sz2 = (const char*)mBuffer;
|
const unsigned char* sz2 = (const unsigned char*)mBuffer;
|
||||||
const char* const szEnd = sz2+80;
|
const unsigned char* const szEnd = sz2+80;
|
||||||
while (sz2 < szEnd) {
|
while (sz2 < szEnd) {
|
||||||
|
|
||||||
if ('C' == *sz2++ && 'O' == *sz2++ && 'L' == *sz2++ &&
|
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__
|
#define __FAST_A_TO_F_H_INCLUDED__
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <limits.h>
|
#include <limits>
|
||||||
|
|
||||||
|
#include "StringComparison.h"
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp
|
||||||
{
|
{
|
||||||
|
@ -229,15 +231,45 @@ inline uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int*
|
||||||
template <typename Real>
|
template <typename Real>
|
||||||
inline const char* fast_atoreal_move(const char* c, Real& out, bool check_comma = true)
|
inline const char* fast_atoreal_move(const char* c, Real& out, bool check_comma = true)
|
||||||
{
|
{
|
||||||
Real f;
|
Real f = 0;
|
||||||
|
|
||||||
bool inv = (*c == '-');
|
bool inv = (*c == '-');
|
||||||
if (inv || *c == '+') {
|
if (inv || *c == '+') {
|
||||||
++c;
|
++c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) );
|
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 == '.' || (check_comma && c[0] == ',')) && c[1] >= '0' && c[1] <= '9')
|
||||||
{
|
{
|
||||||
++c;
|
++c;
|
||||||
|
|
||||||
|
@ -255,6 +287,10 @@ inline const char* fast_atoreal_move(const char* c, Real& out, bool check_comma
|
||||||
pl *= fast_atof_table[diff];
|
pl *= fast_atof_table[diff];
|
||||||
f += static_cast<Real>( pl );
|
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.
|
// 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 == '.' ..)
|
// 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 ...
|
//check for 'rounding' artefacts ...
|
||||||
if (outRec->sides == esNeither && pt.Y == op->pt.Y)
|
if (outRec->sides == esNeither && pt.Y == op->pt.Y)
|
||||||
|
{
|
||||||
if (ToFront)
|
if (ToFront)
|
||||||
{
|
{
|
||||||
if (pt.X == op->pt.X +1) return; //ie wrong side of bottomPt
|
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
|
else if (pt.X == op->pt.X -1) return; //ie wrong side of bottomPt
|
||||||
|
}
|
||||||
|
|
||||||
outRec->sides = (EdgeSide)(outRec->sides | e->side);
|
outRec->sides = (EdgeSide)(outRec->sides | e->side);
|
||||||
if (outRec->sides == esBoth)
|
if (outRec->sides == esBoth)
|
||||||
|
|
|
@ -1246,7 +1246,7 @@ extern int ZEXPORT unzReadCurrentFile (file, buf, len)
|
||||||
return UNZ_PARAMERROR;
|
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;
|
return UNZ_END_OF_LIST_OF_FILE;
|
||||||
if (len==0)
|
if (len==0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -81,13 +81,39 @@ public:
|
||||||
* all needed cleanup tasks prior to returning control to the
|
* all needed cleanup tasks prior to returning control to the
|
||||||
* caller). If the loading is aborted, #Importer::ReadFile()
|
* caller). If the loading is aborted, #Importer::ReadFile()
|
||||||
* returns always NULL.
|
* 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;
|
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
|
}; // !class ProgressHandler
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -72,7 +72,7 @@ enum aiImporterFlags
|
||||||
* should be used with care. This only happens for trunk
|
* should be used with care. This only happens for trunk
|
||||||
* (i.e. SVN) versions, experimental code is not included
|
* (i.e. SVN) versions, experimental code is not included
|
||||||
* in releases. */
|
* in releases. */
|
||||||
aiImporterFlags_Experimental = 0x10,
|
aiImporterFlags_Experimental = 0x10
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
FIND_PACKAGE(OpenGL)
|
FIND_PACKAGE(OpenGL)
|
||||||
FIND_PACKAGE(GLUT)
|
FIND_PACKAGE(GLUT)
|
||||||
|
find_library(M_LIB m)
|
||||||
|
|
||||||
IF ( NOT GLUT_FOUND )
|
IF ( NOT GLUT_FOUND )
|
||||||
IF ( MSVC )
|
IF ( MSVC )
|
||||||
|
@ -29,7 +30,7 @@ ADD_EXECUTABLE( assimp_simpleogl
|
||||||
|
|
||||||
SET_PROPERTY(TARGET assimp_simpleogl PROPERTY DEBUG_POSTFIX ${ASSIMP_DEBUG_POSTFIX})
|
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
|
SET_TARGET_PROPERTIES( assimp_simpleogl PROPERTIES
|
||||||
OUTPUT_NAME assimp_simpleogl
|
OUTPUT_NAME assimp_simpleogl
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
// Simple sample to prove that Assimp is easy to use with OpenGL.
|
// 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
|
// It takes a file name as command line parameter, loads it using standard
|
||||||
// settings and displays it.
|
// settings and displays it.
|
||||||
|
@ -9,29 +9,30 @@
|
||||||
// The vc8 solution links against assimp-release-dll_win32 - be sure to
|
// The vc8 solution links against assimp-release-dll_win32 - be sure to
|
||||||
// have this configuration built.
|
// have this configuration built.
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <GL/glut.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/cimport.h>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
|
|
||||||
// the global Assimp scene object
|
/* the global Assimp scene object */
|
||||||
const struct aiScene* scene = NULL;
|
const struct aiScene* scene = NULL;
|
||||||
GLuint scene_list = 0;
|
GLuint scene_list = 0;
|
||||||
struct aiVector3D scene_min, scene_max, scene_center;
|
struct aiVector3D scene_min, scene_max, scene_center;
|
||||||
|
|
||||||
// current rotation angle
|
/* current rotation angle */
|
||||||
static float angle = 0.f;
|
static float angle = 0.f;
|
||||||
|
|
||||||
#define aisgl_min(x,y) (x<y?x:y)
|
#define aisgl_min(x,y) (x<y?x:y)
|
||||||
#define aisgl_max(x,y) (y>x?y:x)
|
#define aisgl_max(x,y) (y>x?y:x)
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
/* ---------------------------------------------------------------------------- */
|
||||||
void reshape(int width, int height)
|
void reshape(int width, int height)
|
||||||
{
|
{
|
||||||
const double aspectRatio = (float) width / height, fieldOfView = 45.0;
|
const double aspectRatio = (float) width / height, fieldOfView = 45.0;
|
||||||
|
@ -43,7 +44,7 @@ void reshape(int width, int height)
|
||||||
glViewport(0, 0, width, height);
|
glViewport(0, 0, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
/* ---------------------------------------------------------------------------- */
|
||||||
void get_bounding_box_for_node (const struct aiNode* nd,
|
void get_bounding_box_for_node (const struct aiNode* nd,
|
||||||
struct aiVector3D* min,
|
struct aiVector3D* min,
|
||||||
struct aiVector3D* max,
|
struct aiVector3D* max,
|
||||||
|
@ -78,7 +79,7 @@ void get_bounding_box_for_node (const struct aiNode* nd,
|
||||||
*trafo = prev;
|
*trafo = prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
/* ---------------------------------------------------------------------------- */
|
||||||
void get_bounding_box (struct aiVector3D* min, struct aiVector3D* max)
|
void get_bounding_box (struct aiVector3D* min, struct aiVector3D* max)
|
||||||
{
|
{
|
||||||
struct aiMatrix4x4 trafo;
|
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);
|
get_bounding_box_for_node(scene->mRootNode,min,max,&trafo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
/* ---------------------------------------------------------------------------- */
|
||||||
void color4_to_float4(const struct aiColor4D *c, float f[4])
|
void color4_to_float4(const struct aiColor4D *c, float f[4])
|
||||||
{
|
{
|
||||||
f[0] = c->r;
|
f[0] = c->r;
|
||||||
|
@ -98,7 +99,7 @@ void color4_to_float4(const struct aiColor4D *c, float f[4])
|
||||||
f[3] = c->a;
|
f[3] = c->a;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
/* ---------------------------------------------------------------------------- */
|
||||||
void set_float4(float f[4], float a, float b, float c, float d)
|
void set_float4(float f[4], float a, float b, float c, float d)
|
||||||
{
|
{
|
||||||
f[0] = a;
|
f[0] = a;
|
||||||
|
@ -107,7 +108,7 @@ void set_float4(float f[4], float a, float b, float c, float d)
|
||||||
f[3] = d;
|
f[3] = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
/* ---------------------------------------------------------------------------- */
|
||||||
void apply_material(const struct aiMaterial *mtl)
|
void apply_material(const struct aiMaterial *mtl)
|
||||||
{
|
{
|
||||||
float c[4];
|
float c[4];
|
||||||
|
@ -173,19 +174,19 @@ void apply_material(const struct aiMaterial *mtl)
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
/* ---------------------------------------------------------------------------- */
|
||||||
void recursive_render (const struct aiScene *sc, const struct aiNode* nd)
|
void recursive_render (const struct aiScene *sc, const struct aiNode* nd)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
unsigned int n = 0, t;
|
unsigned int n = 0, t;
|
||||||
struct aiMatrix4x4 m = nd->mTransformation;
|
struct aiMatrix4x4 m = nd->mTransformation;
|
||||||
|
|
||||||
// update transform
|
/* update transform */
|
||||||
aiTransposeMatrix4(&m);
|
aiTransposeMatrix4(&m);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glMultMatrixf((float*)&m);
|
glMultMatrixf((float*)&m);
|
||||||
|
|
||||||
// draw all meshes assigned to this node
|
/* draw all meshes assigned to this node */
|
||||||
for (; n < nd->mNumMeshes; ++n) {
|
for (; n < nd->mNumMeshes; ++n) {
|
||||||
const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[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) {
|
for (n = 0; n < nd->mNumChildren; ++n) {
|
||||||
recursive_render(sc, nd->mChildren[n]);
|
recursive_render(sc, nd->mChildren[n]);
|
||||||
}
|
}
|
||||||
|
@ -232,7 +233,7 @@ void recursive_render (const struct aiScene *sc, const struct aiNode* nd)
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
/* ---------------------------------------------------------------------------- */
|
||||||
void do_motion (void)
|
void do_motion (void)
|
||||||
{
|
{
|
||||||
static GLint prev_time = 0;
|
static GLint prev_time = 0;
|
||||||
|
@ -244,7 +245,7 @@ void do_motion (void)
|
||||||
prev_time = time;
|
prev_time = time;
|
||||||
|
|
||||||
frames += 1;
|
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);
|
int current_fps = frames * 1000 / (time - prev_fps_time);
|
||||||
printf("%d fps\n", current_fps);
|
printf("%d fps\n", current_fps);
|
||||||
|
@ -256,7 +257,7 @@ void do_motion (void)
|
||||||
glutPostRedisplay ();
|
glutPostRedisplay ();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
/* ---------------------------------------------------------------------------- */
|
||||||
void display(void)
|
void display(void)
|
||||||
{
|
{
|
||||||
float tmp;
|
float tmp;
|
||||||
|
@ -267,27 +268,27 @@ void display(void)
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
gluLookAt(0.f,0.f,3.f,0.f,0.f,-5.f,0.f,1.f,0.f);
|
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);
|
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 = scene_max.x-scene_min.x;
|
||||||
tmp = aisgl_max(scene_max.y - scene_min.y,tmp);
|
tmp = aisgl_max(scene_max.y - scene_min.y,tmp);
|
||||||
tmp = aisgl_max(scene_max.z - scene_min.z,tmp);
|
tmp = aisgl_max(scene_max.z - scene_min.z,tmp);
|
||||||
tmp = 1.f / tmp;
|
tmp = 1.f / tmp;
|
||||||
glScalef(tmp, tmp, tmp);
|
glScalef(tmp, tmp, tmp);
|
||||||
|
|
||||||
// center the model
|
/* center the model */
|
||||||
glTranslatef( -scene_center.x, -scene_center.y, -scene_center.z );
|
glTranslatef( -scene_center.x, -scene_center.y, -scene_center.z );
|
||||||
|
|
||||||
// if the display list has not been made yet, create a new one and
|
/* if the display list has not been made yet, create a new one and
|
||||||
// fill it with scene contents
|
fill it with scene contents */
|
||||||
if(scene_list == 0) {
|
if(scene_list == 0) {
|
||||||
scene_list = glGenLists(1);
|
scene_list = glGenLists(1);
|
||||||
glNewList(scene_list, GL_COMPILE);
|
glNewList(scene_list, GL_COMPILE);
|
||||||
// now begin at the root node of the imported data and traverse
|
/* now begin at the root node of the imported data and traverse
|
||||||
// the scenegraph by multiplying subsequent local transforms
|
the scenegraph by multiplying subsequent local transforms
|
||||||
// together on GL's matrix stack.
|
together on GL's matrix stack. */
|
||||||
recursive_render(scene, scene->mRootNode);
|
recursive_render(scene, scene->mRootNode);
|
||||||
glEndList();
|
glEndList();
|
||||||
}
|
}
|
||||||
|
@ -299,11 +300,11 @@ void display(void)
|
||||||
do_motion();
|
do_motion();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
/* ---------------------------------------------------------------------------- */
|
||||||
int loadasset (const char* path)
|
int loadasset (const char* path)
|
||||||
{
|
{
|
||||||
// we are taking one of the postprocessing presets to avoid
|
/* we are taking one of the postprocessing presets to avoid
|
||||||
// spelling out 20+ single postprocessing flags here.
|
spelling out 20+ single postprocessing flags here. */
|
||||||
scene = aiImportFile(path,aiProcessPreset_TargetRealtime_MaxQuality);
|
scene = aiImportFile(path,aiProcessPreset_TargetRealtime_MaxQuality);
|
||||||
|
|
||||||
if (scene) {
|
if (scene) {
|
||||||
|
@ -316,7 +317,7 @@ int loadasset (const char* path)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
/* ---------------------------------------------------------------------------- */
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct aiLogStream stream;
|
struct aiLogStream stream;
|
||||||
|
@ -330,21 +331,21 @@ int main(int argc, char **argv)
|
||||||
glutDisplayFunc(display);
|
glutDisplayFunc(display);
|
||||||
glutReshapeFunc(reshape);
|
glutReshapeFunc(reshape);
|
||||||
|
|
||||||
// get a handle to the predefined STDOUT log stream and attach
|
/* get a handle to the predefined STDOUT log stream and attach
|
||||||
// it to the logging system. It remains active for all further
|
it to the logging system. It remains active for all further
|
||||||
// calls to aiImportFile(Ex) and aiApplyPostProcessing.
|
calls to aiImportFile(Ex) and aiApplyPostProcessing. */
|
||||||
stream = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT,NULL);
|
stream = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT,NULL);
|
||||||
aiAttachLogStream(&stream);
|
aiAttachLogStream(&stream);
|
||||||
|
|
||||||
// ... same procedure, but this stream now writes the
|
/* ... same procedure, but this stream now writes the
|
||||||
// log messages to assimp_log.txt
|
log messages to assimp_log.txt */
|
||||||
stream = aiGetPredefinedLogStream(aiDefaultLogStream_FILE,"assimp_log.txt");
|
stream = aiGetPredefinedLogStream(aiDefaultLogStream_FILE,"assimp_log.txt");
|
||||||
aiAttachLogStream(&stream);
|
aiAttachLogStream(&stream);
|
||||||
|
|
||||||
// the model name can be specified on the command line. If none
|
/* the model name can be specified on the command line. If none
|
||||||
// is specified, we try to locate one of the more expressive test
|
is specified, we try to locate one of the more expressive test
|
||||||
// models from the repository (/models-nonbsd may be missing in
|
models from the repository (/models-nonbsd may be missing in
|
||||||
// some distributions so we need a fallback from /models!).
|
some distributions so we need a fallback from /models!). */
|
||||||
if( 0 != loadasset( argc >= 2 ? argv[1] : "../../test/models-nonbsd/X/dwarf.x")) {
|
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"))) {
|
if( argc != 1 || (0 != loadasset( "../../../../test/models-nonbsd/X/dwarf.x") && 0 != loadasset( "../../test/models/X/Testwuson.X"))) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -354,14 +355,14 @@ int main(int argc, char **argv)
|
||||||
glClearColor(0.1f,0.1f,0.1f,1.f);
|
glClearColor(0.1f,0.1f,0.1f,1.f);
|
||||||
|
|
||||||
glEnable(GL_LIGHTING);
|
glEnable(GL_LIGHTING);
|
||||||
glEnable(GL_LIGHT0); // Uses default lighting parameters
|
glEnable(GL_LIGHT0); /* Uses default lighting parameters */
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
|
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
|
||||||
glEnable(GL_NORMALIZE);
|
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"))
|
if(getenv("MODEL_IS_BROKEN"))
|
||||||
glFrontFace(GL_CW);
|
glFrontFace(GL_CW);
|
||||||
|
|
||||||
|
@ -370,14 +371,15 @@ int main(int argc, char **argv)
|
||||||
glutGet(GLUT_ELAPSED_TIME);
|
glutGet(GLUT_ELAPSED_TIME);
|
||||||
glutMainLoop();
|
glutMainLoop();
|
||||||
|
|
||||||
// cleanup - calling 'aiReleaseImport' is important, as the library
|
/* cleanup - calling 'aiReleaseImport' is important, as the library
|
||||||
// keeps internal resources until the scene is freed again. Not
|
keeps internal resources until the scene is freed again. Not
|
||||||
// doing so can cause severe resource leaking.
|
doing so can cause severe resource leaking. */
|
||||||
aiReleaseImport(scene);
|
aiReleaseImport(scene);
|
||||||
|
|
||||||
// We added a log stream to the library, it's our job to disable it
|
/* We added a log stream to the library, it's our job to disable it
|
||||||
// again. This will definitely release the last resources allocated
|
again. This will definitely release the last resources allocated
|
||||||
// by Assimp.
|
by Assimp.*/
|
||||||
aiDetachAllLogStreams();
|
aiDetachAllLogStreams();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,6 @@
|
||||||
// Thanks to NeHe on whose OpenGL tutorials this one's based on! :)
|
// Thanks to NeHe on whose OpenGL tutorials this one's based on! :)
|
||||||
// http://nehe.gamedev.net/
|
// http://nehe.gamedev.net/
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
|
@ -36,7 +33,7 @@
|
||||||
#include "assimp/LogStream.hpp"
|
#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";
|
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 keys[256]; // Array used for Keyboard Routine;
|
||||||
bool active=TRUE; // Window Active Flag Set To TRUE by Default
|
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 xrot;
|
||||||
GLfloat yrot;
|
GLfloat yrot;
|
||||||
|
@ -80,6 +77,7 @@ Assimp::Importer importer;
|
||||||
|
|
||||||
void createAILogger()
|
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::NORMAL;
|
||||||
Assimp::Logger::LogSeverity severity = Assimp::Logger::VERBOSE;
|
Assimp::Logger::LogSeverity severity = Assimp::Logger::VERBOSE;
|
||||||
|
|
||||||
|
@ -114,7 +112,7 @@ void logDebug(const char* logString)
|
||||||
|
|
||||||
bool Import3DFromFile( const std::string& pFile)
|
bool Import3DFromFile( const std::string& pFile)
|
||||||
{
|
{
|
||||||
//check if file exists
|
// Check if file exists
|
||||||
std::ifstream fin(pFile.c_str());
|
std::ifstream fin(pFile.c_str());
|
||||||
if(!fin.fail())
|
if(!fin.fail())
|
||||||
{
|
{
|
||||||
|
@ -143,12 +141,14 @@ bool Import3DFromFile( const std::string& pFile)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resize And Initialize The GL Window
|
||||||
void ReSizeGLScene(GLsizei width, GLsizei height) // 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
|
glViewport(0, 0, width, height); // Reset The Current Viewport
|
||||||
|
@ -217,9 +217,6 @@ int LoadGLTextures(const aiScene* scene)
|
||||||
textureIds = new GLuint[numTextures];
|
textureIds = new GLuint[numTextures];
|
||||||
glGenTextures(numTextures, textureIds); /* Texture name generation */
|
glGenTextures(numTextures, textureIds); /* Texture name generation */
|
||||||
|
|
||||||
/* define texture path */
|
|
||||||
//std::string texturepath = "../../../test/models/Obj/";
|
|
||||||
|
|
||||||
/* get iterator */
|
/* get iterator */
|
||||||
std::map<std::string, GLuint*>::iterator itr = textureIdMap.begin();
|
std::map<std::string, GLuint*>::iterator itr = textureIdMap.begin();
|
||||||
|
|
||||||
|
@ -239,48 +236,50 @@ int LoadGLTextures(const aiScene* scene)
|
||||||
|
|
||||||
if (success) /* If no error occured: */
|
if (success) /* If no error occured: */
|
||||||
{
|
{
|
||||||
success = ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE); /* Convert every colour component into
|
// Convert every colour component into unsigned byte.If your image contains
|
||||||
unsigned byte. If your image contains alpha channel you can replace IL_RGB with IL_RGBA */
|
// alpha channel you can replace IL_RGB with IL_RGBA
|
||||||
|
success = ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE);
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
/* Error occured */
|
/* Error occured */
|
||||||
abortGLInit("Couldn't convert image");
|
abortGLInit("Couldn't convert image");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
//glGenTextures(numTextures, &textureIds[i]); /* Texture name generation */
|
// Binding of texture name
|
||||||
glBindTexture(GL_TEXTURE_2D, textureIds[i]); /* Binding of texture name */
|
glBindTexture(GL_TEXTURE_2D, textureIds[i]);
|
||||||
// redefine standard texture values
|
// redefine standard texture values
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); /* We will use linear
|
// We will use linear interpolation for magnification filter
|
||||||
interpolation for magnification filter */
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); /* We will use linear
|
// We will use linear interpolation for minifying filter
|
||||||
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),
|
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,
|
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
|
else
|
||||||
{
|
{
|
||||||
/* Error occured */
|
/* Error occured */
|
||||||
MessageBox(NULL, ("Couldn't load Image: " + fileloc).c_str() , "ERROR", MB_OK | MB_ICONEXCLAMATION);
|
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); /* Because we have already copied image data into texture data
|
ilDeleteImages(numTextures, imageIds);
|
||||||
we can release memory used by image. */
|
|
||||||
|
|
||||||
// Cleanup
|
// Cleanup
|
||||||
delete [] imageIds;
|
delete [] imageIds;
|
||||||
imageIds = NULL;
|
imageIds = NULL;
|
||||||
|
|
||||||
//return success;
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// All Setup For OpenGL goes here
|
||||||
|
int InitGL()
|
||||||
int InitGL() // All Setup For OpenGL goes here
|
|
||||||
{
|
{
|
||||||
if (!LoadGLTextures(scene))
|
if (!LoadGLTextures(scene))
|
||||||
{
|
{
|
||||||
|
@ -307,9 +306,6 @@ int InitGL() // All Setup For OpenGL goes here
|
||||||
glLightfv(GL_LIGHT1, GL_POSITION, LightPosition);
|
glLightfv(GL_LIGHT1, GL_POSITION, LightPosition);
|
||||||
glEnable(GL_LIGHT1);
|
glEnable(GL_LIGHT1);
|
||||||
|
|
||||||
//glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
|
|
||||||
|
|
||||||
|
|
||||||
return TRUE; // Initialization Went OK
|
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);
|
glDisable(GL_COLOR_MATERIAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (t = 0; t < mesh->mNumFaces; ++t) {
|
for (t = 0; t < mesh->mNumFaces; ++t) {
|
||||||
const struct aiFace* face = &mesh->mFaces[t];
|
const struct aiFace* face = &mesh->mFaces[t];
|
||||||
GLenum face_mode;
|
GLenum face_mode;
|
||||||
|
@ -480,14 +474,10 @@ void recursive_render (const struct aiScene *sc, const struct aiNode* nd, float
|
||||||
glNormal3fv(&mesh->mNormals[vertexIndex].x);
|
glNormal3fv(&mesh->mNormals[vertexIndex].x);
|
||||||
glVertex3fv(&mesh->mVertices[vertexIndex].x);
|
glVertex3fv(&mesh->mVertices[vertexIndex].x);
|
||||||
}
|
}
|
||||||
|
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// draw all children
|
// draw all children
|
||||||
for (n = 0; n < nd->mNumChildren; ++n)
|
for (n = 0; n < nd->mNumChildren; ++n)
|
||||||
{
|
{
|
||||||
|
@ -521,12 +511,11 @@ int DrawGLScene() //Here's where we do all the drawing
|
||||||
|
|
||||||
drawAiScene(scene);
|
drawAiScene(scene);
|
||||||
|
|
||||||
|
|
||||||
//xrot+=0.3f;
|
//xrot+=0.3f;
|
||||||
yrot+=0.2f;
|
yrot+=0.2f;
|
||||||
//zrot+=0.4f;
|
//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.");
|
abortGLInit("Window Creation Error.");
|
||||||
return FALSE;
|
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
|
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)
|
switch (wParam)
|
||||||
{
|
{
|
||||||
case SC_SCREENSAVE: // Screensaver trying to start
|
case SC_SCREENSAVE: // Screen-saver trying to start
|
||||||
case SC_MONITORPOWER: // Monitor tryig to enter powersafe
|
case SC_MONITORPOWER: // Monitor trying to enter power-safe
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
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);
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
int WINAPI WinMain( HINSTANCE hInstance, // Instance
|
int WINAPI WinMain( HINSTANCE hInstance, // The instance
|
||||||
HINSTANCE hPrevInstance, // Previous Instance
|
HINSTANCE hPrevInstance, // Previous instance
|
||||||
LPSTR lpCmdLine, // Command Line Parameters
|
LPSTR lpCmdLine, // Command Line Parameters
|
||||||
int nShowCmd ) // Window Show State
|
int nShowCmd ) // Window Show State
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,7 +15,8 @@ SOURCE_GROUP( unit FILES
|
||||||
unit/BoostWorkaround/tupletest.cpp
|
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/AdditionalMessage.cpp
|
||||||
../contrib/cppunit-1.12.1/src/cppunit/Asserter.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/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/XmlOutputter.cpp
|
||||||
../contrib/cppunit-1.12.1/src/cppunit/XmlOutputterHook.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
|
SET( TEST_SRCS
|
||||||
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
|
|
||||||
unit/utFindDegenerates.cpp
|
unit/utFindDegenerates.cpp
|
||||||
unit/utFindDegenerates.h
|
unit/utFindDegenerates.h
|
||||||
unit/utFindInvalidData.cpp
|
unit/utFindInvalidData.cpp
|
||||||
|
@ -165,65 +119,20 @@ add_executable( unit
|
||||||
unit/utNoBoostTest.cpp
|
unit/utNoBoostTest.cpp
|
||||||
unit/utNoBoostTest.h
|
unit/utNoBoostTest.h
|
||||||
unit/BoostWorkaround/tupletest.cpp
|
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 )
|
SOURCE_GROUP(tests FILES ${TEST_SRCS})
|
||||||
FIND_PACKAGE(DirectX REQUIRED)
|
|
||||||
ENDIF( WIN32 )
|
|
||||||
|
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})
|
SET_PROPERTY(TARGET assimp PROPERTY DEBUG_POSTFIX ${ASSIMP_DEBUG_POSTFIX})
|
||||||
|
|
||||||
# TODO: Port to non-Windows platforms.
|
target_link_libraries ( unit assimp ${CPPUNIT_LIBRARY} )
|
||||||
target_link_libraries ( unit assimp ${DirectX_LIBRARY} ${DirectX_D3DX9_LIBRARY} comctl32.lib Winmm.lib )
|
|
||||||
|
|
|
@ -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
|
Ns 0
|
||||||
Ka 0.000000 0.000000 0.000000
|
Ka 0.000000 0.000000 0.000000
|
||||||
Kd 0.8 0.8 0.8
|
Kd 0.8 0.8 0.8
|
||||||
Ks 0.8 0.8 0.8
|
Ks 0
|
||||||
d 1
|
d 1
|
||||||
illum 2
|
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/postprocess.h>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
|
|
|
@ -26,9 +26,8 @@ int main (int argc, char* argv[])
|
||||||
|
|
||||||
// .. and C. They should smoothly work together
|
// .. and C. They should smoothly work together
|
||||||
aiEnableVerboseLogging(AI_TRUE);
|
aiEnableVerboseLogging(AI_TRUE);
|
||||||
aiAttachLogStream(&aiGetPredefinedLogStream(
|
aiLogStream logstream= aiGetPredefinedLogStream(aiDefaultLogStream_FILE, "AssimpLog_C.txt");
|
||||||
aiDefaultLogStream_FILE,
|
aiAttachLogStream(&logstream);
|
||||||
"AssimpLog_C.txt"));
|
|
||||||
|
|
||||||
|
|
||||||
// ............................................................................
|
// ............................................................................
|
||||||
|
|
|
@ -72,7 +72,7 @@ static const aiImporterDesc desc = {
|
||||||
|
|
||||||
|
|
||||||
bool TestPlugin :: CanRead( const std::string& pFile,
|
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('.');
|
std::string::size_type pos = pFile.find_last_of('.');
|
||||||
// no file extension - can't read
|
// no file extension - can't read
|
||||||
|
@ -90,8 +90,8 @@ const aiImporterDesc* TestPlugin :: GetInfo() const
|
||||||
return & desc;
|
return & desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestPlugin :: InternReadFile( const std::string& pFile,
|
void TestPlugin :: InternReadFile( const std::string& /*pFile*/,
|
||||||
aiScene* pScene, IOSystem* pIOHandler)
|
aiScene* /*pScene*/, IOSystem* /*pIOHandler*/)
|
||||||
{
|
{
|
||||||
throw DeadlyImportError(AIUT_DEF_ERROR_TEXT);
|
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/test.x",flags));
|
||||||
//CPPUNIT_ASSERT(pImp->ReadFile("../../test/models/X/dwarf.x",flags)); # is in nonbsd
|
//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/anim_test.x",flags));
|
||||||
//CPPUNIT_ASSERT(pImp->ReadFile("../../test/models/X/dwarf.x",flags)); # is in nonbsd
|
//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/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
|
//CPPUNIT_ASSERT(pImp->ReadFile("../../test/models/X/dwarf.x",flags)); # is in nonbsd
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
namespace noboost {
|
namespace noboost {
|
||||||
|
|
||||||
#define ASSIMP_FORCE_NOBOOST
|
#define ASSIMP_FORCE_NOBOOST
|
||||||
#include "..\..\code\BoostWorkaround\boost\format.hpp"
|
#include "../../code/BoostWorkaround/boost/format.hpp"
|
||||||
using boost::format;
|
using boost::format;
|
||||||
using boost::str;
|
using boost::str;
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ void RemoveCommentsTest :: testSingleLineComments (void)
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void RemoveCommentsTest :: testMultiLineComments (void)
|
void RemoveCommentsTest :: testMultiLineComments (void)
|
||||||
{
|
{
|
||||||
char* szTest =
|
const char* szTest =
|
||||||
"/* comment to be removed */\n"
|
"/* comment to be removed */\n"
|
||||||
"valid text /* \n "
|
"valid text /* \n "
|
||||||
" comment across multiple lines */"
|
" comment across multiple lines */"
|
||||||
|
|
|
@ -656,7 +656,7 @@ uint32_t WriteBinaryScene(const aiScene* scene)
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
// Write a binary model dump
|
// Write a binary model dump
|
||||||
void WriteBinaryDump(const aiScene* scene, FILE* _out, const char* src, const char* cmd,
|
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;
|
out = _out;
|
||||||
shortened = _shortened;
|
shortened = _shortened;
|
||||||
|
|
|
@ -1030,18 +1030,17 @@ void PopulateExportMenu()
|
||||||
//-------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------
|
||||||
void DoExport(size_t formatId)
|
void DoExport(size_t formatId)
|
||||||
{
|
{
|
||||||
if (!g_szFileName) {
|
if (!g_szFileName[0]) {
|
||||||
|
MessageBox(g_hDlg, "No model loaded", "Export", MB_ICONERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Exporter exp;
|
Exporter exp;
|
||||||
const aiExportFormatDesc* const e = exp.GetExportFormatDescription(formatId);
|
const aiExportFormatDesc* const e = exp.GetExportFormatDescription(formatId);
|
||||||
ai_assert(e);
|
ai_assert(e);
|
||||||
|
|
||||||
char szFileName[MAX_PATH*2];
|
char szFileName[MAX_PATH*2];
|
||||||
DWORD dwTemp;
|
DWORD dwTemp = sizeof(szFileName);
|
||||||
if(ERROR_SUCCESS == RegQueryValueEx(g_hRegistry,"ModelExportDest",NULL,NULL,(BYTE*)szFileName, &dwTemp)) {
|
if(ERROR_SUCCESS == RegQueryValueEx(g_hRegistry,"ModelExportDest",NULL,NULL,(BYTE*)szFileName, &dwTemp)) {
|
||||||
ai_assert(dwTemp == MAX_PATH + 1);
|
|
||||||
ai_assert(strlen(szFileName) <= MAX_PATH);
|
ai_assert(strlen(szFileName) <= MAX_PATH);
|
||||||
|
|
||||||
// invent a nice default file name
|
// invent a nice default file name
|
||||||
|
|
Loading…
Reference in New Issue