fix_vs2017_warnings
kkulling 2020-03-23 11:46:29 +01:00
commit c1001c0e07
252 changed files with 23211 additions and 22398 deletions

View File

@ -70,8 +70,8 @@ IncludeCategories:
- Regex: '^<.*' - Regex: '^<.*'
Priority: 3 Priority: 3
# IncludeIsMainRegex: '(Test)?$' # IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: true IndentCaseLabels: false
IndentPPDirectives: AfterHash #IndentPPDirectives: AfterHash
IndentWidth: 4 IndentWidth: 4
# IndentWrappedFunctionNames: false # IndentWrappedFunctionNames: false
# JavaScriptQuotes: Leave # JavaScriptQuotes: Leave

22
.github/workflows/ccpp.yml vendored 100644
View File

@ -0,0 +1,22 @@
name: C/C++ CI
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build-ubuntu:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: configure
run: cmake CMakeLists.txt
- name: build
run: cmake --build .
- name: test
run: cd bin && ./unit

View File

@ -255,8 +255,7 @@ IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW)
SET(LIBSTDC++_LIBRARIES -lstdc++) SET(LIBSTDC++_LIBRARIES -lstdc++)
ELSEIF(MSVC) ELSEIF(MSVC)
# enable multi-core compilation with MSVC # enable multi-core compilation with MSVC
ADD_COMPILE_OPTIONS(/MP) ADD_COMPILE_OPTIONS(/MP /bigobj /W4 /WX )
ADD_COMPILE_OPTIONS( /bigobj )
# disable "elements of array '' will be default initialized" warning on MSVC2013 # disable "elements of array '' will be default initialized" warning on MSVC2013
IF(MSVC12) IF(MSVC12)
ADD_COMPILE_OPTIONS(/wd4351) ADD_COMPILE_OPTIONS(/wd4351)
@ -583,8 +582,8 @@ ENDIF()
ADD_SUBDIRECTORY( code/ ) ADD_SUBDIRECTORY( code/ )
IF ( ASSIMP_BUILD_ASSIMP_TOOLS ) IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
# The viewer for windows only # The viewer for windows only
IF ( WIN32 AND DirectX_D3DX9_LIBRARY ) IF ( WIN32 )
OPTION ( ASSIMP_BUILD_ASSIMP_VIEW "If the Assimp view tool is built. (requires DirectX)" ${DirectX_FOUND} ) OPTION ( ASSIMP_BUILD_ASSIMP_VIEW "If the Assimp view tool is built. (requires DirectX)" OFF )
IF ( ASSIMP_BUILD_ASSIMP_VIEW ) IF ( ASSIMP_BUILD_ASSIMP_VIEW )
ADD_SUBDIRECTORY( tools/assimp_view/ ) ADD_SUBDIRECTORY( tools/assimp_view/ )
ENDIF () ENDIF ()

View File

@ -2,6 +2,7 @@ Open Asset Import Library (assimp)
================================== ==================================
A library to import and export various 3d-model-formats including scene-post-processing to generate missing render data. A library to import and export various 3d-model-formats including scene-post-processing to generate missing render data.
### Current project status ### ### Current project status ###
![C/C++ CI](https://github.com/assimp/assimp/workflows/C/C++%20CI/badge.svg)
[![Linux Build Status](https://travis-ci.org/assimp/assimp.svg)](https://travis-ci.org/assimp/assimp) [![Linux Build Status](https://travis-ci.org/assimp/assimp.svg)](https://travis-ci.org/assimp/assimp)
[![Windows Build Status](https://ci.appveyor.com/api/projects/status/tmo433wax6u6cjp4?svg=true)](https://ci.appveyor.com/project/kimkulling/assimp) [![Windows Build Status](https://ci.appveyor.com/api/projects/status/tmo433wax6u6cjp4?svg=true)](https://ci.appveyor.com/project/kimkulling/assimp)
<a href="https://scan.coverity.com/projects/5607"> <a href="https://scan.coverity.com/projects/5607">

View File

@ -35,7 +35,7 @@ if(MSVC)
endif() endif()
set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library" ) set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library" )
file(TO_NATIVE_PATH ${_IMPORT_PREFIX} _IMPORT_PREFIX) file(TO_NATIVE_PATH "${_IMPORT_PREFIX}" _IMPORT_PREFIX)
if(ASSIMP_BUILD_SHARED_LIBS) if(ASSIMP_BUILD_SHARED_LIBS)
set(sharedLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_SHARED_LIBRARY_SUFFIX@") set(sharedLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_SHARED_LIBRARY_SUFFIX@")

View File

@ -35,7 +35,7 @@ if(MSVC)
endif() endif()
set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library" ) set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library" )
file(TO_NATIVE_PATH ${_IMPORT_PREFIX} _IMPORT_PREFIX) file(TO_NATIVE_PATH "${_IMPORT_PREFIX}" _IMPORT_PREFIX)
if(ASSIMP_BUILD_SHARED_LIBS) if(ASSIMP_BUILD_SHARED_LIBS)
set(sharedLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_SHARED_LIBRARY_SUFFIX@") set(sharedLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_SHARED_LIBRARY_SUFFIX@")

View File

@ -80,7 +80,7 @@ namespace {
{ {
chunk_start_pos = writer.GetCurrentPos(); chunk_start_pos = writer.GetCurrentPos();
writer.PutU2(chunk_type); writer.PutU2(chunk_type);
writer.PutU4(CHUNK_SIZE_NOT_SET); writer.PutU4((uint32_t)CHUNK_SIZE_NOT_SET);
} }
~ChunkWriter() { ~ChunkWriter() {
@ -193,21 +193,21 @@ Discreet3DSExporter:: Discreet3DSExporter(std::shared_ptr<IOStream> &outfile, co
CollectTrafos(scene->mRootNode, trafos); CollectTrafos(scene->mRootNode, trafos);
CollectMeshes(scene->mRootNode, meshes); CollectMeshes(scene->mRootNode, meshes);
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAIN); ChunkWriter curRootChunk(writer, Discreet3DS::CHUNK_MAIN);
{ {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_OBJMESH); ChunkWriter curChunk(writer, Discreet3DS::CHUNK_OBJMESH);
WriteMaterials(); WriteMaterials();
WriteMeshes(); WriteMeshes();
{ {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MASTER_SCALE); ChunkWriter curChunk1(writer, Discreet3DS::CHUNK_MASTER_SCALE);
writer.PutF4(1.0f); writer.PutF4(1.0f);
} }
} }
{ {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_KEYFRAMER); ChunkWriter curChunk(writer, Discreet3DS::CHUNK_KEYFRAMER);
WriteHierarchy(*scene->mRootNode, -1, -1); WriteHierarchy(*scene->mRootNode, -1, -1);
} }
} }
@ -223,9 +223,9 @@ int Discreet3DSExporter::WriteHierarchy(const aiNode& node, int seq, int sibling
{ {
// 3DS scene hierarchy is serialized as in http://www.martinreddy.net/gfx/3d/3DS.spec // 3DS scene hierarchy is serialized as in http://www.martinreddy.net/gfx/3d/3DS.spec
{ {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKINFO); ChunkWriter curRootChunk(writer, Discreet3DS::CHUNK_TRACKINFO);
{ {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKOBJNAME); ChunkWriter curChunk(writer, Discreet3DS::CHUNK_TRACKOBJNAME);
// Assimp node names are unique and distinct from all mesh-node // Assimp node names are unique and distinct from all mesh-node
// names we generate; thus we can use them as-is // names we generate; thus we can use them as-is
@ -237,7 +237,7 @@ int Discreet3DSExporter::WriteHierarchy(const aiNode& node, int seq, int sibling
int16_t hierarchy_pos = static_cast<int16_t>(seq); int16_t hierarchy_pos = static_cast<int16_t>(seq);
if (sibling_level != -1) { if (sibling_level != -1) {
hierarchy_pos = sibling_level; hierarchy_pos =(uint16_t) sibling_level;
} }
// Write the hierarchy position // Write the hierarchy position
@ -262,7 +262,7 @@ int Discreet3DSExporter::WriteHierarchy(const aiNode& node, int seq, int sibling
const unsigned int mesh_idx = node.mMeshes[i]; const unsigned int mesh_idx = node.mMeshes[i];
const aiMesh& mesh = *scene->mMeshes[mesh_idx]; const aiMesh& mesh = *scene->mMeshes[mesh_idx];
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKINFO); ChunkWriter curChunk(writer, Discreet3DS::CHUNK_TRACKINFO);
{ {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKOBJNAME); ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKOBJNAME);
WriteString(GetMeshName(mesh, mesh_idx, node)); WriteString(GetMeshName(mesh, mesh_idx, node));
@ -279,7 +279,7 @@ int Discreet3DSExporter::WriteHierarchy(const aiNode& node, int seq, int sibling
void Discreet3DSExporter::WriteMaterials() void Discreet3DSExporter::WriteMaterials()
{ {
for (unsigned int i = 0; i < scene->mNumMaterials; ++i) { for (unsigned int i = 0; i < scene->mNumMaterials; ++i) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MATERIAL); ChunkWriter curRootChunk(writer, Discreet3DS::CHUNK_MAT_MATERIAL);
const aiMaterial& mat = *scene->mMaterials[i]; const aiMaterial& mat = *scene->mMaterials[i];
{ {
@ -290,22 +290,22 @@ void Discreet3DSExporter::WriteMaterials()
aiColor3D color; aiColor3D color;
if (mat.Get(AI_MATKEY_COLOR_DIFFUSE, color) == AI_SUCCESS) { if (mat.Get(AI_MATKEY_COLOR_DIFFUSE, color) == AI_SUCCESS) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_DIFFUSE); ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_DIFFUSE);
WriteColor(color); WriteColor(color);
} }
if (mat.Get(AI_MATKEY_COLOR_SPECULAR, color) == AI_SUCCESS) { if (mat.Get(AI_MATKEY_COLOR_SPECULAR, color) == AI_SUCCESS) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SPECULAR); ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_SPECULAR);
WriteColor(color); WriteColor(color);
} }
if (mat.Get(AI_MATKEY_COLOR_AMBIENT, color) == AI_SUCCESS) { if (mat.Get(AI_MATKEY_COLOR_AMBIENT, color) == AI_SUCCESS) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_AMBIENT); ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_AMBIENT);
WriteColor(color); WriteColor(color);
} }
if (mat.Get(AI_MATKEY_COLOR_EMISSIVE, color) == AI_SUCCESS) { if (mat.Get(AI_MATKEY_COLOR_EMISSIVE, color) == AI_SUCCESS) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SELF_ILLUM); ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_SELF_ILLUM);
WriteColor(color); WriteColor(color);
} }
@ -389,14 +389,14 @@ void Discreet3DSExporter::WriteTexture(const aiMaterial& mat, aiTextureType type
ChunkWriter chunk(writer, chunk_flags); ChunkWriter chunk(writer, chunk_flags);
{ {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAPFILE); ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAPFILE);
WriteString(path); WriteString(path);
} }
WritePercentChunk(blend); WritePercentChunk(blend);
{ {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MAP_TILING); ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_MAP_TILING);
uint16_t val = 0; // WRAP uint16_t val = 0; // WRAP
if (map_mode[0] == aiTextureMapMode_Mirror) { if (map_mode[0] == aiTextureMapMode_Mirror) {
val = 0x2; val = 0x2;
@ -447,7 +447,7 @@ void Discreet3DSExporter::WriteMeshes()
// Vertices in world space // Vertices in world space
{ {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_VERTLIST); ChunkWriter curChunk(writer, Discreet3DS::CHUNK_VERTLIST);
const uint16_t count = static_cast<uint16_t>(mesh.mNumVertices); const uint16_t count = static_cast<uint16_t>(mesh.mNumVertices);
writer.PutU2(count); writer.PutU2(count);
@ -461,7 +461,7 @@ void Discreet3DSExporter::WriteMeshes()
// UV coordinates // UV coordinates
if (mesh.HasTextureCoords(0)) { if (mesh.HasTextureCoords(0)) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAPLIST); ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAPLIST);
const uint16_t count = static_cast<uint16_t>(mesh.mNumVertices); const uint16_t count = static_cast<uint16_t>(mesh.mNumVertices);
writer.PutU2(count); writer.PutU2(count);
@ -474,7 +474,7 @@ void Discreet3DSExporter::WriteMeshes()
// Faces (indices) // Faces (indices)
{ {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_FACELIST); ChunkWriter curChunk(writer, Discreet3DS::CHUNK_FACELIST);
ai_assert(mesh.mNumFaces <= 0xffff); ai_assert(mesh.mNumFaces <= 0xffff);
@ -513,7 +513,7 @@ void Discreet3DSExporter::WriteMeshes()
// Transformation matrix by which the mesh vertices have been pre-transformed with. // Transformation matrix by which the mesh vertices have been pre-transformed with.
{ {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRMATRIX); ChunkWriter curChunk(writer, Discreet3DS::CHUNK_TRMATRIX);
for (unsigned int r = 0; r < 4; ++r) { for (unsigned int r = 0; r < 4; ++r) {
for (unsigned int c = 0; c < 3; ++c) { for (unsigned int c = 0; c < 3; ++c) {
writer.PutF4(trafo[r][c]); writer.PutF4(trafo[r][c]);
@ -526,7 +526,7 @@ void Discreet3DSExporter::WriteMeshes()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Discreet3DSExporter::WriteFaceMaterialChunk(const aiMesh& mesh) void Discreet3DSExporter::WriteFaceMaterialChunk(const aiMesh& mesh)
{ {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_FACEMAT); ChunkWriter curChunk(writer, Discreet3DS::CHUNK_FACEMAT);
const std::string& name = GetMaterialName(*scene->mMaterials[mesh.mMaterialIndex], mesh.mMaterialIndex); const std::string& name = GetMaterialName(*scene->mMaterials[mesh.mMaterialIndex], mesh.mMaterialIndex);
WriteString(name); WriteString(name);
@ -559,7 +559,7 @@ void Discreet3DSExporter::WriteString(const aiString& s) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Discreet3DSExporter::WriteColor(const aiColor3D& color) { void Discreet3DSExporter::WriteColor(const aiColor3D& color) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_RGBF); ChunkWriter curChunk(writer, Discreet3DS::CHUNK_RGBF);
writer.PutF4(color.r); writer.PutF4(color.r);
writer.PutF4(color.g); writer.PutF4(color.g);
writer.PutF4(color.b); writer.PutF4(color.b);
@ -567,13 +567,13 @@ void Discreet3DSExporter::WriteColor(const aiColor3D& color) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Discreet3DSExporter::WritePercentChunk(float f) { void Discreet3DSExporter::WritePercentChunk(float f) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_PERCENTF); ChunkWriter curChunk(writer, Discreet3DS::CHUNK_PERCENTF);
writer.PutF4(f); writer.PutF4(f);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Discreet3DSExporter::WritePercentChunk(double f) { void Discreet3DSExporter::WritePercentChunk(double f) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_PERCENTD); ChunkWriter ccurChunkhunk(writer, Discreet3DS::CHUNK_PERCENTD);
writer.PutF8(f); writer.PutF8(f);
} }

View File

@ -45,14 +45,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_3DSFILEHELPER_H_INC #ifndef AI_3DSFILEHELPER_H_INC
#define AI_3DSFILEHELPER_H_INC #define AI_3DSFILEHELPER_H_INC
#include <assimp/SpatialSort.h>
#include <assimp/SmoothingGroups.h> #include <assimp/SmoothingGroups.h>
#include <assimp/SpatialSort.h>
#include <assimp/StringUtils.h> #include <assimp/StringUtils.h>
#include <assimp/qnan.h> #include <assimp/anim.h>
#include <assimp/material.h>
#include <assimp/camera.h> #include <assimp/camera.h>
#include <assimp/light.h> #include <assimp/light.h>
#include <assimp/anim.h> #include <assimp/material.h>
#include <assimp/qnan.h>
#include <stdio.h> //sprintf #include <stdio.h> //sprintf
namespace Assimp { namespace Assimp {
@ -81,11 +81,9 @@ public:
uint32_t Size; uint32_t Size;
} PACK_STRUCT; } PACK_STRUCT;
//! Used for shading field in material3ds structure //! Used for shading field in material3ds structure
//! From AutoDesk 3ds SDK //! From AutoDesk 3ds SDK
typedef enum typedef enum {
{
// translated to gouraud shading with wireframe active // translated to gouraud shading with wireframe active
Wire = 0x0, Wire = 0x0,
@ -109,8 +107,7 @@ public:
} shadetype3ds; } shadetype3ds;
// Flags for animated keys // Flags for animated keys
enum enum {
{
KEY_USE_TENS = 0x1, KEY_USE_TENS = 0x1,
KEY_USE_CONT = 0x2, KEY_USE_CONT = 0x2,
KEY_USE_BIAS = 0x4, KEY_USE_BIAS = 0x4,
@ -118,8 +115,7 @@ public:
KEY_USE_EASE_FROM = 0x10 KEY_USE_EASE_FROM = 0x10
}; };
enum enum {
{
// ******************************************************************** // ********************************************************************
// Basic chunks which can be found everywhere in the file // Basic chunks which can be found everywhere in the file
@ -322,26 +318,77 @@ public:
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper structure representing a 3ds mesh face */ /** Helper structure representing a 3ds mesh face */
struct Face : public FaceWithSmoothingGroup struct Face : public FaceWithSmoothingGroup {
{
}; };
#ifdef _WIN32
# pragma warning(disable : 4315)
#endif
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper structure representing a texture */ /** Helper structure representing a texture */
struct Texture { struct Texture {
//! Default constructor //! Default constructor
Texture() AI_NO_EXCEPT Texture() AI_NO_EXCEPT
: mOffsetU (0.0) : mTextureBlend(0.0f),
, mOffsetV (0.0) mMapName(),
, mScaleU (1.0) mOffsetU(0.0),
, mScaleV (1.0) mOffsetV(0.0),
, mRotation (0.0) mScaleU(1.0),
, mMapMode (aiTextureMapMode_Wrap) mScaleV(1.0),
, bPrivate() mRotation(0.0),
, iUVSrc (0) { mMapMode(aiTextureMapMode_Wrap),
bPrivate(),
iUVSrc(0) {
mTextureBlend = get_qnan(); mTextureBlend = get_qnan();
} }
Texture(const Texture &other) :
mTextureBlend(other.mTextureBlend),
mMapName(other.mMapName),
mOffsetU(other.mOffsetU),
mOffsetV(other.mOffsetV),
mScaleU(other.mScaleU),
mScaleV(other.mScaleV),
mRotation(other.mRotation),
mMapMode(other.mMapMode),
bPrivate(other.bPrivate),
iUVSrc(other.iUVSrc) {
// empty
}
Texture(Texture &&other) AI_NO_EXCEPT : mTextureBlend(std::move(other.mTextureBlend)),
mMapName(std::move(other.mMapName)),
mOffsetU(std::move(other.mOffsetU)),
mOffsetV(std::move(other.mOffsetV)),
mScaleU(std::move(other.mScaleU)),
mScaleV(std::move(other.mScaleV)),
mRotation(std::move(other.mRotation)),
mMapMode(std::move(other.mMapMode)),
bPrivate(std::move(other.bPrivate)),
iUVSrc(std::move(other.iUVSrc)) {
// empty
}
Texture &operator=(Texture &&other) AI_NO_EXCEPT {
if (this == &other) {
return *this;
}
mTextureBlend = std::move(other.mTextureBlend);
mMapName = std::move(other.mMapName);
mOffsetU = std::move(other.mOffsetU);
mOffsetV = std::move(other.mOffsetV);
mScaleU = std::move(other.mScaleU);
mScaleV = std::move(other.mScaleV);
mRotation = std::move(other.mRotation);
mMapMode = std::move(other.mMapMode);
bPrivate = std::move(other.bPrivate);
iUVSrc = std::move(other.iUVSrc);
return *this;
}
//! Specifies the blend factor for the texture //! Specifies the blend factor for the texture
ai_real mTextureBlend; ai_real mTextureBlend;
@ -367,55 +414,59 @@ struct Texture {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper structure representing a 3ds material */ /** Helper structure representing a 3ds material */
struct Material struct Material {
{
//! Default constructor has been deleted //! Default constructor has been deleted
Material() = delete; Material() :
mName(),
mDiffuse(ai_real(0.6), ai_real(0.6), ai_real(0.6)),
//! Constructor with explicit name mSpecularExponent(ai_real(0.0)),
explicit Material(const std::string &name) mShininessStrength(ai_real(1.0)),
: mName(name) mShading(Discreet3DS::Gouraud),
, mDiffuse ( ai_real( 0.6 ), ai_real( 0.6 ), ai_real( 0.6 ) ) // FIX ... we won't want object to be black mTransparency(ai_real(1.0)),
, mSpecularExponent ( ai_real( 0.0 ) ) mBumpHeight(ai_real(1.0)),
, mShininessStrength ( ai_real( 1.0 ) ) mTwoSided(false) {
, mShading(Discreet3DS::Gouraud) // empty
, mTransparency ( ai_real( 1.0 ) )
, mBumpHeight ( ai_real( 1.0 ) )
, mTwoSided (false)
{
} }
//! Constructor with explicit name
explicit Material(const std::string &name) :
mName(name),
mDiffuse(ai_real(0.6), ai_real(0.6), ai_real(0.6)),
mSpecularExponent(ai_real(0.0)),
mShininessStrength(ai_real(1.0)),
mShading(Discreet3DS::Gouraud),
mTransparency(ai_real(1.0)),
mBumpHeight(ai_real(1.0)),
mTwoSided(false) {
// empty
}
Material(const Material &other) = default; Material(const Material &other) = default;
Material &operator=(const Material &other) = default; Material &operator=(const Material &other) = default;
//! Move constructor. This is explicitly written because MSVC doesn't support defaulting it //! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
Material(Material &&other) AI_NO_EXCEPT Material(Material &&other) AI_NO_EXCEPT
: mName(std::move(other.mName)) : mName(std::move(other.mName)),
, mDiffuse(std::move(other.mDiffuse)) mDiffuse(std::move(other.mDiffuse)),
, mSpecularExponent(std::move(other.mSpecularExponent)) mSpecularExponent(std::move(other.mSpecularExponent)),
, mShininessStrength(std::move(other.mShininessStrength)) mShininessStrength(std::move(other.mShininessStrength)),
, mSpecular(std::move(other.mSpecular)) mSpecular(std::move(other.mSpecular)),
, mAmbient(std::move(other.mAmbient)) mAmbient(std::move(other.mAmbient)),
, mShading(std::move(other.mShading)) mShading(std::move(other.mShading)),
, mTransparency(std::move(other.mTransparency)) mTransparency(std::move(other.mTransparency)),
, sTexDiffuse(std::move(other.sTexDiffuse)) sTexDiffuse(std::move(other.sTexDiffuse)),
, sTexOpacity(std::move(other.sTexOpacity)) sTexOpacity(std::move(other.sTexOpacity)),
, sTexSpecular(std::move(other.sTexSpecular)) sTexSpecular(std::move(other.sTexSpecular)),
, sTexReflective(std::move(other.sTexReflective)) sTexReflective(std::move(other.sTexReflective)),
, sTexBump(std::move(other.sTexBump)) sTexBump(std::move(other.sTexBump)),
, sTexEmissive(std::move(other.sTexEmissive)) sTexEmissive(std::move(other.sTexEmissive)),
, sTexShininess(std::move(other.sTexShininess)) sTexShininess(std::move(other.sTexShininess)),
, mBumpHeight(std::move(other.mBumpHeight)) mBumpHeight(std::move(other.mBumpHeight)),
, mEmissive(std::move(other.mEmissive)) mEmissive(std::move(other.mEmissive)),
, sTexAmbient(std::move(other.sTexAmbient)) sTexAmbient(std::move(other.sTexAmbient)),
, mTwoSided(std::move(other.mTwoSided)) mTwoSided(std::move(other.mTwoSided)) {
{
} }
Material &operator=(Material &&other) AI_NO_EXCEPT { Material &operator=(Material &&other) AI_NO_EXCEPT {
if (this == &other) { if (this == &other) {
return *this; return *this;
@ -444,9 +495,9 @@ struct Material
return *this; return *this;
} }
virtual ~Material() {
virtual ~Material() {} // empty
}
//! Name of the material //! Name of the material
std::string mName; std::string mName;
@ -491,18 +542,15 @@ struct Material
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper structure to represent a 3ds file mesh */ /** Helper structure to represent a 3ds file mesh */
struct Mesh : public MeshWithSmoothingGroups<D3DS::Face> struct Mesh : public MeshWithSmoothingGroups<D3DS::Face> {
{
//! Default constructor has been deleted //! Default constructor has been deleted
Mesh() = delete; Mesh() = delete;
//! Constructor with explicit name //! Constructor with explicit name
explicit Mesh(const std::string &name) explicit Mesh(const std::string &name) :
: mName(name) mName(name) {
{
} }
//! Name of the mesh //! Name of the mesh
std::string mName; std::string mName;
@ -519,53 +567,39 @@ struct Mesh : public MeshWithSmoothingGroups<D3DS::Face>
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Float key - quite similar to aiVectorKey and aiQuatKey. Both are in the /** Float key - quite similar to aiVectorKey and aiQuatKey. Both are in the
C-API, so it would be difficult to make them a template. */ C-API, so it would be difficult to make them a template. */
struct aiFloatKey struct aiFloatKey {
{
double mTime; ///< The time of this key double mTime; ///< The time of this key
ai_real mValue; ///< The value of this key ai_real mValue; ///< The value of this key
#ifdef __cplusplus #ifdef __cplusplus
// time is not compared // time is not compared
bool operator == (const aiFloatKey& o) const bool operator==(const aiFloatKey &o) const { return o.mValue == this->mValue; }
{return o.mValue == this->mValue;}
bool operator != (const aiFloatKey& o) const bool operator!=(const aiFloatKey &o) const { return o.mValue != this->mValue; }
{return o.mValue != this->mValue;}
// Only time is compared. This operator is defined // Only time is compared. This operator is defined
// for use with std::sort // for use with std::sort
bool operator < (const aiFloatKey& o) const bool operator<(const aiFloatKey &o) const { return mTime < o.mTime; }
{return mTime < o.mTime;}
bool operator > (const aiFloatKey& o) const bool operator>(const aiFloatKey &o) const { return mTime > o.mTime; }
{return mTime > o.mTime;}
#endif #endif
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper structure to represent a 3ds file node */ /** Helper structure to represent a 3ds file node */
struct Node struct Node {
{
Node() = delete; Node() = delete;
explicit Node(const std::string &name) explicit Node(const std::string &name) :
: mParent(NULL) mParent(NULL), mName(name), mInstanceNumber(0), mHierarchyPos(0), mHierarchyIndex(0), mInstanceCount(1) {
, mName(name)
, mInstanceNumber(0)
, mHierarchyPos (0)
, mHierarchyIndex (0)
, mInstanceCount (1)
{
aRotationKeys.reserve(20); aRotationKeys.reserve(20);
aPositionKeys.reserve(20); aPositionKeys.reserve(20);
aScalingKeys.reserve(20); aScalingKeys.reserve(20);
} }
~Node() {
~Node()
{
for (unsigned int i = 0; i < mChildren.size(); ++i) for (unsigned int i = 0; i < mChildren.size(); ++i)
delete mChildren[i]; delete mChildren[i];
} }
@ -600,7 +634,6 @@ struct Node
//! Scaling keys loaded from the file //! Scaling keys loaded from the file
std::vector<aiVectorKey> aScalingKeys; std::vector<aiVectorKey> aScalingKeys;
// For target lights (spot lights and directional lights): // For target lights (spot lights and directional lights):
// The position of the target // The position of the target
std::vector<aiVectorKey> aTargetPositionKeys; std::vector<aiVectorKey> aTargetPositionKeys;
@ -616,8 +649,7 @@ struct Node
//! Add a child node, setup the right parent node for it //! Add a child node, setup the right parent node for it
//! \param pc Node to be 'adopted' //! \param pc Node to be 'adopted'
inline Node& push_back(Node* pc) inline Node &push_back(Node *pc) {
{
mChildren.push_back(pc); mChildren.push_back(pc);
pc->mParent = this; pc->mParent = this;
return *this; return *this;
@ -625,8 +657,7 @@ struct Node
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper structure analogue to aiScene */ /** Helper structure analogue to aiScene */
struct Scene struct Scene {
{
//! List of all materials loaded //! List of all materials loaded
//! NOTE: 3ds references materials globally //! NOTE: 3ds references materials globally
std::vector<Material> mMaterials; std::vector<Material> mMaterials;
@ -645,7 +676,6 @@ struct Scene
// Node* pcRootNode; // Node* pcRootNode;
}; };
} // end of namespace D3DS } // end of namespace D3DS
} // end of namespace Assimp } // end of namespace Assimp

View File

@ -158,13 +158,13 @@ void Discreet3DSImporter::SetupProperties(const Importer* /*pImp*/)
void Discreet3DSImporter::InternReadFile( const std::string& pFile, void Discreet3DSImporter::InternReadFile( const std::string& pFile,
aiScene* pScene, IOSystem* pIOHandler) aiScene* pScene, IOSystem* pIOHandler)
{ {
StreamReaderLE stream(pIOHandler->Open(pFile,"rb")); StreamReaderLE theStream(pIOHandler->Open(pFile,"rb"));
// We should have at least one chunk // We should have at least one chunk
if (stream.GetRemainingSize() < 16) { if (theStream.GetRemainingSize() < 16) {
throw DeadlyImportError("3DS file is either empty or corrupt: " + pFile); throw DeadlyImportError("3DS file is either empty or corrupt: " + pFile);
} }
this->stream = &stream; this->stream = &theStream;
// Allocate our temporary 3DS representation // Allocate our temporary 3DS representation
D3DS::Scene _scene; D3DS::Scene _scene;
@ -599,16 +599,19 @@ void Discreet3DSImporter::InverseNodeSearch(D3DS::Node* pcNode,D3DS::Node* pcCur
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Find a node with a specific name in the import hierarchy // Find a node with a specific name in the import hierarchy
D3DS::Node* FindNode(D3DS::Node* root, const std::string& name) D3DS::Node* FindNode(D3DS::Node* root, const std::string& name) {
{ if (root->mName == name) {
if (root->mName == name)
return root; return root;
}
for (std::vector<D3DS::Node*>::iterator it = root->mChildren.begin();it != root->mChildren.end(); ++it) { for (std::vector<D3DS::Node*>::iterator it = root->mChildren.begin();it != root->mChildren.end(); ++it) {
D3DS::Node* nd; D3DS::Node *nd = FindNode(*it, name);
if (( nd = FindNode(*it,name))) if (nullptr != nd) {
return nd; return nd;
} }
return NULL; }
return nullptr;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -256,13 +256,13 @@ void D3MFExporter::writeBaseMaterials() {
tmp.clear(); tmp.clear();
hexDiffuseColor = "#"; hexDiffuseColor = "#";
tmp = DecimalToHexa( color.r ); tmp = DecimalToHexa( (ai_real) color.r );
hexDiffuseColor += tmp; hexDiffuseColor += tmp;
tmp = DecimalToHexa( color.g ); tmp = DecimalToHexa((ai_real)color.g);
hexDiffuseColor += tmp; hexDiffuseColor += tmp;
tmp = DecimalToHexa( color.b ); tmp = DecimalToHexa((ai_real)color.b);
hexDiffuseColor += tmp; hexDiffuseColor += tmp;
tmp = DecimalToHexa( color.a ); tmp = DecimalToHexa((ai_real)color.a);
hexDiffuseColor += tmp; hexDiffuseColor += tmp;
} else { } else {
hexDiffuseColor = "#FFFFFFFF"; hexDiffuseColor = "#FFFFFFFF";

View File

@ -1,4 +1,3 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
@ -6,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -44,25 +41,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Implementation of the AC3D importer class */ /** @file Implementation of the AC3D importer class */
#ifndef ASSIMP_BUILD_NO_AC_IMPORTER #ifndef ASSIMP_BUILD_NO_AC_IMPORTER
// internal headers // internal headers
#include "ACLoader.h" #include "ACLoader.h"
#include <assimp/ParsingUtils.h>
#include <assimp/fast_atof.h>
#include <assimp/Subdivision.h>
#include "Common/Importer.h" #include "Common/Importer.h"
#include <assimp/BaseImporter.h> #include <assimp/BaseImporter.h>
#include <assimp/Importer.hpp> #include <assimp/ParsingUtils.h>
#include <assimp/Subdivision.h>
#include <assimp/config.h>
#include <assimp/fast_atof.h>
#include <assimp/importerdesc.h>
#include <assimp/light.h> #include <assimp/light.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/material.h> #include <assimp/material.h>
#include <assimp/scene.h> #include <assimp/scene.h>
#include <assimp/config.h> #include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
#include <assimp/importerdesc.h> #include <assimp/Importer.hpp>
#include <memory> #include <memory>
using namespace Assimp; using namespace Assimp;
@ -82,83 +77,82 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// skip to the next token // skip to the next token
#define AI_AC_SKIP_TO_NEXT_TOKEN() \ inline const char *AcSkipToNextToken(const char *buffer) {
if (!SkipSpaces(&buffer)) \ if (!SkipSpaces(&buffer)) {
{ \ ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL");
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL"); \ }
continue; \ return buffer;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// read a string (may be enclosed in double quotation marks). buffer must point to " // read a string (may be enclosed in double quotation marks). buffer must point to "
#define AI_AC_GET_STRING(out) \ inline const char *AcGetString(const char *buffer, std::string &out) {
if (*buffer == '\0') { \ if (*buffer == '\0') {
throw DeadlyImportError("AC3D: Unexpected EOF in string"); \ throw DeadlyImportError("AC3D: Unexpected EOF in string");
} \ }
++buffer; \ ++buffer;
const char* sz = buffer; \ const char *sz = buffer;
while ('\"' != *buffer) \ while ('\"' != *buffer) {
{ \ if (IsLineEnd(*buffer)) {
if (IsLineEnd( *buffer )) \ ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL in string");
{ \ out = "ERROR";
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL in string"); \ break;
out = "ERROR"; \ }
break; \ ++buffer;
} \ }
++buffer; \ if (IsLineEnd(*buffer)) {
} \ return buffer;
if (IsLineEnd( *buffer ))continue; \ }
out = std::string(sz,(unsigned int)(buffer-sz)); \ out = std::string(sz, (unsigned int)(buffer - sz));
++buffer; ++buffer;
return buffer;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// read 1 to n floats prefixed with an optional predefined identifier // read 1 to n floats prefixed with an optional predefined identifier
#define AI_AC_CHECKED_LOAD_FLOAT_ARRAY(name,name_length,num,out) \ template <class T>
AI_AC_SKIP_TO_NEXT_TOKEN(); \ inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *name, size_t name_length, size_t num, T *out) {
if (name_length) \ buffer = AcSkipToNextToken(buffer);
{ \ if (0 != name_length) {
if (strncmp(buffer,name,name_length) || !IsSpace(buffer[name_length])) \ if (0 != strncmp(buffer, name, name_length) || !IsSpace(buffer[name_length])) {
{ \ ASSIMP_LOG_ERROR("AC3D: Unexpexted token. " + std::string(name) + " was expected.");
ASSIMP_LOG_ERROR("AC3D: Unexpexted token. " name " was expected."); \ return buffer;
continue; \ }
} \ buffer += name_length + 1;
buffer += name_length+1; \ }
} \ for (unsigned int _i = 0; _i < num; ++_i) {
for (unsigned int i = 0; i < num;++i) \ buffer = AcSkipToNextToken(buffer);
{ \ buffer = fast_atoreal_move<float>(buffer, ((float *)out)[_i]);
AI_AC_SKIP_TO_NEXT_TOKEN(); \
buffer = fast_atoreal_move<float>(buffer,((float*)out)[i]); \
} }
return buffer;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
AC3DImporter::AC3DImporter() AC3DImporter::AC3DImporter() :
: buffer(), buffer(),
configSplitBFCull(), configSplitBFCull(),
configEvalSubdivision(), configEvalSubdivision(),
mNumMeshes(), mNumMeshes(),
mLights(), mLights(),
lights(), mLightsCounter(0),
groups(), mGroupsCounter(0),
polys(), mPolysCounter(0),
worlds() mWorldsCounter(0) {
{
// nothing to be done here // nothing to be done here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
AC3DImporter::~AC3DImporter() AC3DImporter::~AC3DImporter() {
{
// nothing to be done here // nothing to be done here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool AC3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const bool AC3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
{
std::string extension = GetExtension(pFile); std::string extension = GetExtension(pFile);
// fixme: are acc and ac3d *really* used? Some sources say they are // fixme: are acc and ac3d *really* used? Some sources say they are
@ -174,23 +168,20 @@ bool AC3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Loader meta information // Loader meta information
const aiImporterDesc* AC3DImporter::GetInfo () const const aiImporterDesc *AC3DImporter::GetInfo() const {
{
return &desc; return &desc;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get a pointer to the next line from the file // Get a pointer to the next line from the file
bool AC3DImporter::GetNextLine( ) bool AC3DImporter::GetNextLine() {
{
SkipLine(&buffer); SkipLine(&buffer);
return SkipSpaces(&buffer); return SkipSpaces(&buffer);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Parse an object section in an AC file // Parse an object section in an AC file
void AC3DImporter::LoadObjectSection(std::vector<Object>& objects) void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
{
if (!TokenMatch(buffer, "OBJECT", 6)) if (!TokenMatch(buffer, "OBJECT", 6))
return; return;
@ -202,8 +193,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
Object &obj = objects.back(); Object &obj = objects.back();
aiLight *light = NULL; aiLight *light = NULL;
if (!ASSIMP_strincmp(buffer,"light",5)) if (!ASSIMP_strincmp(buffer, "light", 5)) {
{
// This is a light source. Add it to the list // This is a light source. Add it to the list
mLights->push_back(light = new aiLight()); mLights->push_back(light = new aiLight());
@ -219,83 +209,57 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
ASSIMP_LOG_DEBUG("AC3D: Light source encountered"); ASSIMP_LOG_DEBUG("AC3D: Light source encountered");
obj.type = Object::Light; obj.type = Object::Light;
} } else if (!ASSIMP_strincmp(buffer, "group", 5)) {
else if (!ASSIMP_strincmp(buffer,"group",5))
{
obj.type = Object::Group; obj.type = Object::Group;
} } else if (!ASSIMP_strincmp(buffer, "world", 5)) {
else if (!ASSIMP_strincmp(buffer,"world",5))
{
obj.type = Object::World; obj.type = Object::World;
} } else
else obj.type = Object::Poly; obj.type = Object::Poly;
while (GetNextLine()) while (GetNextLine()) {
{ if (TokenMatch(buffer, "kids", 4)) {
if (TokenMatch(buffer,"kids",4))
{
SkipSpaces(&buffer); SkipSpaces(&buffer);
unsigned int num = strtoul10(buffer, &buffer); unsigned int num = strtoul10(buffer, &buffer);
GetNextLine(); GetNextLine();
if (num) if (num) {
{
// load the children of this object recursively // load the children of this object recursively
obj.children.reserve(num); obj.children.reserve(num);
for (unsigned int i = 0; i < num; ++i) for (unsigned int i = 0; i < num; ++i)
LoadObjectSection(obj.children); LoadObjectSection(obj.children);
} }
return; return;
} } else if (TokenMatch(buffer, "name", 4)) {
else if (TokenMatch(buffer,"name",4))
{
SkipSpaces(&buffer); SkipSpaces(&buffer);
AI_AC_GET_STRING(obj.name); buffer = AcGetString(buffer, obj.name);
// If this is a light source, we'll also need to store // If this is a light source, we'll also need to store
// the name of the node in it. // the name of the node in it.
if (light) if (light) {
{
light->mName.Set(obj.name); light->mName.Set(obj.name);
} }
} } else if (TokenMatch(buffer, "texture", 7)) {
else if (TokenMatch(buffer,"texture",7))
{
SkipSpaces(&buffer); SkipSpaces(&buffer);
AI_AC_GET_STRING(obj.texture); buffer = AcGetString(buffer, obj.texture);
} } else if (TokenMatch(buffer, "texrep", 6)) {
else if (TokenMatch(buffer,"texrep",6))
{
SkipSpaces(&buffer); SkipSpaces(&buffer);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,2,&obj.texRepeat); buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 2, &obj.texRepeat);
if (!obj.texRepeat.x || !obj.texRepeat.y) if (!obj.texRepeat.x || !obj.texRepeat.y)
obj.texRepeat = aiVector2D(1.f, 1.f); obj.texRepeat = aiVector2D(1.f, 1.f);
} } else if (TokenMatch(buffer, "texoff", 6)) {
else if (TokenMatch(buffer,"texoff",6))
{
SkipSpaces(&buffer); SkipSpaces(&buffer);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,2,&obj.texOffset); buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 2, &obj.texOffset);
} } else if (TokenMatch(buffer, "rot", 3)) {
else if (TokenMatch(buffer,"rot",3))
{
SkipSpaces(&buffer); SkipSpaces(&buffer);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,9,&obj.rotation); buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 9, &obj.rotation);
} } else if (TokenMatch(buffer, "loc", 3)) {
else if (TokenMatch(buffer,"loc",3))
{
SkipSpaces(&buffer); SkipSpaces(&buffer);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,3,&obj.translation); buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 3, &obj.translation);
} } else if (TokenMatch(buffer, "subdiv", 6)) {
else if (TokenMatch(buffer,"subdiv",6))
{
SkipSpaces(&buffer); SkipSpaces(&buffer);
obj.subDiv = strtoul10(buffer, &buffer); obj.subDiv = strtoul10(buffer, &buffer);
} } else if (TokenMatch(buffer, "crease", 6)) {
else if (TokenMatch(buffer,"crease",6))
{
SkipSpaces(&buffer); SkipSpaces(&buffer);
obj.crease = fast_atof(buffer); obj.crease = fast_atof(buffer);
} } else if (TokenMatch(buffer, "numvert", 7)) {
else if (TokenMatch(buffer,"numvert",7))
{
SkipSpaces(&buffer); SkipSpaces(&buffer);
unsigned int t = strtoul10(buffer, &buffer); unsigned int t = strtoul10(buffer, &buffer);
@ -303,41 +267,32 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
throw DeadlyImportError("AC3D: Too many vertices, would run out of memory"); throw DeadlyImportError("AC3D: Too many vertices, would run out of memory");
} }
obj.vertices.reserve(t); obj.vertices.reserve(t);
for (unsigned int i = 0; i < t;++i) for (unsigned int i = 0; i < t; ++i) {
{ if (!GetNextLine()) {
if (!GetNextLine())
{
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: not all vertices have been parsed yet"); ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: not all vertices have been parsed yet");
break; break;
} } else if (!IsNumeric(*buffer)) {
else if (!IsNumeric(*buffer))
{
ASSIMP_LOG_ERROR("AC3D: Unexpected token: not all vertices have been parsed yet"); ASSIMP_LOG_ERROR("AC3D: Unexpected token: not all vertices have been parsed yet");
--buffer; // make sure the line is processed a second time --buffer; // make sure the line is processed a second time
break; break;
} }
obj.vertices.push_back(aiVector3D()); obj.vertices.push_back(aiVector3D());
aiVector3D &v = obj.vertices.back(); aiVector3D &v = obj.vertices.back();
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,3,&v.x); buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 3, &v.x);
} }
} } else if (TokenMatch(buffer, "numsurf", 7)) {
else if (TokenMatch(buffer,"numsurf",7))
{
SkipSpaces(&buffer); SkipSpaces(&buffer);
bool Q3DWorkAround = false; bool Q3DWorkAround = false;
const unsigned int t = strtoul10(buffer, &buffer); const unsigned int t = strtoul10(buffer, &buffer);
obj.surfaces.reserve(t); obj.surfaces.reserve(t);
for (unsigned int i = 0; i < t;++i) for (unsigned int i = 0; i < t; ++i) {
{
GetNextLine(); GetNextLine();
if (!TokenMatch(buffer,"SURF",4)) if (!TokenMatch(buffer, "SURF", 4)) {
{
// FIX: this can occur for some files - Quick 3D for // FIX: this can occur for some files - Quick 3D for
// example writes no surf chunks // example writes no surf chunks
if (!Q3DWorkAround) if (!Q3DWorkAround) {
{
ASSIMP_LOG_WARN("AC3D: SURF token was expected"); ASSIMP_LOG_WARN("AC3D: SURF token was expected");
ASSIMP_LOG_DEBUG("Continuing with Quick3D Workaround enabled"); ASSIMP_LOG_DEBUG("Continuing with Quick3D Workaround enabled");
} }
@ -351,24 +306,17 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
Surface &surf = obj.surfaces.back(); Surface &surf = obj.surfaces.back();
surf.flags = strtoul_cppstyle(buffer); surf.flags = strtoul_cppstyle(buffer);
while (1) while (1) {
{ if (!GetNextLine()) {
if(!GetNextLine())
{
throw DeadlyImportError("AC3D: Unexpected EOF: surface is incomplete"); throw DeadlyImportError("AC3D: Unexpected EOF: surface is incomplete");
} }
if (TokenMatch(buffer,"mat",3)) if (TokenMatch(buffer, "mat", 3)) {
{
SkipSpaces(&buffer); SkipSpaces(&buffer);
surf.mat = strtoul10(buffer); surf.mat = strtoul10(buffer);
} } else if (TokenMatch(buffer, "refs", 4)) {
else if (TokenMatch(buffer,"refs",4))
{
// --- see fix notes above // --- see fix notes above
if (Q3DWorkAround) if (Q3DWorkAround) {
{ if (!surf.entries.empty()) {
if (!surf.entries.empty())
{
buffer -= 6; buffer -= 6;
break; break;
} }
@ -380,10 +328,8 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
obj.numRefs += m; obj.numRefs += m;
for (unsigned int k = 0; k < m; ++k) for (unsigned int k = 0; k < m; ++k) {
{ if (!GetNextLine()) {
if(!GetNextLine())
{
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: surface references are incomplete"); ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: surface references are incomplete");
break; break;
} }
@ -392,12 +338,9 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
entry.first = strtoul10(buffer, &buffer); entry.first = strtoul10(buffer, &buffer);
SkipSpaces(&buffer); SkipSpaces(&buffer);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,2,&entry.second); buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 2, &entry.second);
} }
} } else {
else
{
--buffer; // make sure the line is processed a second time --buffer; // make sure the line is processed a second time
break; break;
} }
@ -412,24 +355,20 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
// Convert a material from AC3DImporter::Material to aiMaterial // Convert a material from AC3DImporter::Material to aiMaterial
void AC3DImporter::ConvertMaterial(const Object &object, void AC3DImporter::ConvertMaterial(const Object &object,
const Material &matSrc, const Material &matSrc,
aiMaterial& matDest) aiMaterial &matDest) {
{
aiString s; aiString s;
if (matSrc.name.length()) if (matSrc.name.length()) {
{
s.Set(matSrc.name); s.Set(matSrc.name);
matDest.AddProperty(&s, AI_MATKEY_NAME); matDest.AddProperty(&s, AI_MATKEY_NAME);
} }
if (object.texture.length()) if (object.texture.length()) {
{
s.Set(object.texture); s.Set(object.texture);
matDest.AddProperty(&s, AI_MATKEY_TEXTURE_DIFFUSE(0)); matDest.AddProperty(&s, AI_MATKEY_TEXTURE_DIFFUSE(0));
// UV transformation // UV transformation
if (1.f != object.texRepeat.x || 1.f != object.texRepeat.y || if (1.f != object.texRepeat.x || 1.f != object.texRepeat.y ||
object.texOffset.x || object.texOffset.y) object.texOffset.x || object.texOffset.y) {
{
aiUVTransform transform; aiUVTransform transform;
transform.mScaling = object.texRepeat; transform.mScaling = object.texRepeat;
transform.mTranslation = object.texOffset; transform.mTranslation = object.texOffset;
@ -442,13 +381,13 @@ void AC3DImporter::ConvertMaterial(const Object& object,
matDest.AddProperty<aiColor3D>(&matSrc.emis, 1, AI_MATKEY_COLOR_EMISSIVE); matDest.AddProperty<aiColor3D>(&matSrc.emis, 1, AI_MATKEY_COLOR_EMISSIVE);
matDest.AddProperty<aiColor3D>(&matSrc.spec, 1, AI_MATKEY_COLOR_SPECULAR); matDest.AddProperty<aiColor3D>(&matSrc.spec, 1, AI_MATKEY_COLOR_SPECULAR);
int n; int n = -1;
if (matSrc.shin) if (matSrc.shin) {
{
n = aiShadingMode_Phong; n = aiShadingMode_Phong;
matDest.AddProperty<float>(&matSrc.shin, 1, AI_MATKEY_SHININESS); matDest.AddProperty<float>(&matSrc.shin, 1, AI_MATKEY_SHININESS);
} else {
n = aiShadingMode_Gouraud;
} }
else n = aiShadingMode_Gouraud;
matDest.AddProperty<int>(&n, 1, AI_MATKEY_SHADING_MODEL); matDest.AddProperty<int>(&n, 1, AI_MATKEY_SHADING_MODEL);
float f = 1.f - matSrc.trans; float f = 1.f - matSrc.trans;
@ -461,14 +400,11 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
std::vector<aiMesh *> &meshes, std::vector<aiMesh *> &meshes,
std::vector<aiMaterial *> &outMaterials, std::vector<aiMaterial *> &outMaterials,
const std::vector<Material> &materials, const std::vector<Material> &materials,
aiNode* parent) aiNode *parent) {
{
aiNode *node = new aiNode(); aiNode *node = new aiNode();
node->mParent = parent; node->mParent = parent;
if (object.vertices.size()) if (object.vertices.size()) {
{ if (!object.surfaces.size() || !object.numRefs) {
if (!object.surfaces.size() || !object.numRefs)
{
/* " An object with 7 vertices (no surfaces, no materials defined). /* " An object with 7 vertices (no surfaces, no materials defined).
This is a good way of getting point data into AC3D. This is a good way of getting point data into AC3D.
The Vertex->create convex-surface/object can be used on these The Vertex->create convex-surface/object can be used on these
@ -488,8 +424,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
aiFace *faces = mesh->mFaces = new aiFace[mesh->mNumFaces]; aiFace *faces = mesh->mFaces = new aiFace[mesh->mNumFaces];
aiVector3D *verts = mesh->mVertices = new aiVector3D[mesh->mNumVertices]; aiVector3D *verts = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
for (unsigned int i = 0; i < mesh->mNumVertices;++i,++faces,++verts) for (unsigned int i = 0; i < mesh->mNumVertices; ++i, ++faces, ++verts) {
{
*verts = object.vertices[i]; *verts = object.vertices[i];
faces->mNumIndices = 1; faces->mNumIndices = 1;
faces->mIndices = new unsigned int[1]; faces->mIndices = new unsigned int[1];
@ -502,9 +437,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
mesh->mMaterialIndex = 0; mesh->mMaterialIndex = 0;
outMaterials.push_back(new aiMaterial()); outMaterials.push_back(new aiMaterial());
ConvertMaterial(object, materials[0], *outMaterials.back()); ConvertMaterial(object, materials[0], *outMaterials.back());
} } else {
else
{
// need to generate one or more meshes for this object. // need to generate one or more meshes for this object.
// find out how many different materials we have // find out how many different materials we have
typedef std::pair<unsigned int, unsigned int> IntPair; typedef std::pair<unsigned int, unsigned int> IntPair;
@ -514,53 +447,46 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
std::vector<Surface>::iterator it, end = object.surfaces.end(); std::vector<Surface>::iterator it, end = object.surfaces.end();
std::vector<Surface::SurfaceEntry>::iterator it2, end2; std::vector<Surface::SurfaceEntry>::iterator it2, end2;
for (it = object.surfaces.begin(); it != end; ++it) for (it = object.surfaces.begin(); it != end; ++it) {
{
unsigned int idx = (*it).mat; unsigned int idx = (*it).mat;
if (idx >= needMat.size()) if (idx >= needMat.size()) {
{
ASSIMP_LOG_ERROR("AC3D: material index is out of range"); ASSIMP_LOG_ERROR("AC3D: material index is out of range");
idx = 0; idx = 0;
} }
if ((*it).entries.empty()) if ((*it).entries.empty()) {
{
ASSIMP_LOG_WARN("AC3D: surface her zero vertex references"); ASSIMP_LOG_WARN("AC3D: surface her zero vertex references");
} }
// validate all vertex indices to make sure we won't crash here // validate all vertex indices to make sure we won't crash here
for (it2 = (*it).entries.begin(), for (it2 = (*it).entries.begin(),
end2 = (*it).entries.end(); it2 != end2; ++it2) end2 = (*it).entries.end();
{ it2 != end2; ++it2) {
if ((*it2).first >= object.vertices.size()) if ((*it2).first >= object.vertices.size()) {
{
ASSIMP_LOG_WARN("AC3D: Invalid vertex reference"); ASSIMP_LOG_WARN("AC3D: Invalid vertex reference");
(*it2).first = 0; (*it2).first = 0;
} }
} }
if (!needMat[idx].first)++node->mNumMeshes; if (!needMat[idx].first) {
++node->mNumMeshes;
}
switch ((*it).flags & 0xf) switch ((*it).flags & 0xf) {
{
// closed line // closed line
case 0x1: case 0x1:
needMat[idx].first += (unsigned int)(*it).entries.size(); needMat[idx].first += (unsigned int)(*it).entries.size();
needMat[idx].second += (unsigned int)(*it).entries.size() << 1u; needMat[idx].second += (unsigned int)(*it).entries.size() << 1u;
break; break;
// unclosed line // unclosed line
case 0x2: case 0x2:
needMat[idx].first += (unsigned int)(*it).entries.size() - 1; needMat[idx].first += (unsigned int)(*it).entries.size() - 1;
needMat[idx].second += ((unsigned int)(*it).entries.size() - 1) << 1u; needMat[idx].second += ((unsigned int)(*it).entries.size() - 1) << 1u;
break; break;
// 0 == polygon, else unknown // 0 == polygon, else unknown
default: default:
if ((*it).flags & 0xf) {
if ((*it).flags & 0xf)
{
ASSIMP_LOG_WARN("AC3D: The type flag of a surface is unknown"); ASSIMP_LOG_WARN("AC3D: The type flag of a surface is unknown");
(*it).flags &= ~(0xf); (*it).flags &= ~(0xf);
} }
@ -575,16 +501,17 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
unsigned int mat = 0; unsigned int mat = 0;
const size_t oldm = meshes.size(); const size_t oldm = meshes.size();
for (MatTable::const_iterator cit = needMat.begin(), cend = needMat.end(); for (MatTable::const_iterator cit = needMat.begin(), cend = needMat.end();
cit != cend; ++cit, ++mat) cit != cend; ++cit, ++mat) {
{ if (!(*cit).first) {
if (!(*cit).first)continue; continue;
}
// allocate a new aiMesh object // allocate a new aiMesh object
*pip++ = (unsigned int)meshes.size(); *pip++ = (unsigned int)meshes.size();
aiMesh *mesh = new aiMesh(); aiMesh *mesh = new aiMesh();
meshes.push_back(mesh); meshes.push_back(mesh);
mesh->mMaterialIndex = (unsigned int)outMaterials.size(); mesh->mMaterialIndex = static_cast<unsigned int>(outMaterials.size());
outMaterials.push_back(new aiMaterial()); outMaterials.push_back(new aiMaterial());
ConvertMaterial(object, materials[mat], *outMaterials.back()); ConvertMaterial(object, materials[mat], *outMaterials.back());
@ -609,28 +536,23 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
// allocate UV coordinates, but only if the texture name for the // allocate UV coordinates, but only if the texture name for the
// surface is not empty // surface is not empty
aiVector3D *uv = NULL; aiVector3D *uv = NULL;
if(object.texture.length()) if (object.texture.length()) {
{
uv = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices]; uv = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
mesh->mNumUVComponents[0] = 2; mesh->mNumUVComponents[0] = 2;
} }
for (it = object.surfaces.begin(); it != end; ++it) for (it = object.surfaces.begin(); it != end; ++it) {
{ if (mat == (*it).mat) {
if (mat == (*it).mat)
{
const Surface &src = *it; const Surface &src = *it;
// closed polygon // closed polygon
unsigned int type = (*it).flags & 0xf; unsigned int type = (*it).flags & 0xf;
if (!type) if (!type) {
{
aiFace &face = *faces++; aiFace &face = *faces++;
if((face.mNumIndices = (unsigned int)src.entries.size())) face.mNumIndices = (unsigned int)src.entries.size();
{ if (0 != face.mNumIndices) {
face.mIndices = new unsigned int[face.mNumIndices]; face.mIndices = new unsigned int[face.mNumIndices];
for (unsigned int i = 0; i < face.mNumIndices;++i,++vertices) for (unsigned int i = 0; i < face.mNumIndices; ++i, ++vertices) {
{
const Surface::SurfaceEntry &entry = src.entries[i]; const Surface::SurfaceEntry &entry = src.entries[i];
face.mIndices[i] = cur++; face.mIndices[i] = cur++;
@ -640,27 +562,22 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
} }
*vertices = object.vertices[entry.first] + object.translation; *vertices = object.vertices[entry.first] + object.translation;
// copy texture coordinates // copy texture coordinates
if (uv) if (uv) {
{
uv->x = entry.second.x; uv->x = entry.second.x;
uv->y = entry.second.y; uv->y = entry.second.y;
++uv; ++uv;
} }
} }
} }
} } else {
else
{
it2 = (*it).entries.begin(); it2 = (*it).entries.begin();
// either a closed or an unclosed line // either a closed or an unclosed line
unsigned int tmp = (unsigned int)(*it).entries.size(); unsigned int tmp = (unsigned int)(*it).entries.size();
if (0x2 == type) --tmp; if (0x2 == type) --tmp;
for (unsigned int m = 0; m < tmp;++m) for (unsigned int m = 0; m < tmp; ++m) {
{
aiFace &face = *faces++; aiFace &face = *faces++;
face.mNumIndices = 2; face.mNumIndices = 2;
@ -676,26 +593,22 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
*vertices++ = object.vertices[(*it2).first]; *vertices++ = object.vertices[(*it2).first];
// copy texture coordinates // copy texture coordinates
if (uv) if (uv) {
{
uv->x = (*it2).second.x; uv->x = (*it2).second.x;
uv->y = (*it2).second.y; uv->y = (*it2).second.y;
++uv; ++uv;
} }
if (0x1 == type && tmp - 1 == m) {
if (0x1 == type && tmp-1 == m)
{
// if this is a closed line repeat its beginning now // if this is a closed line repeat its beginning now
it2 = (*it).entries.begin(); it2 = (*it).entries.begin();
} } else
else ++it2; ++it2;
// second point // second point
*vertices++ = object.vertices[(*it2).first]; *vertices++ = object.vertices[(*it2).first];
if (uv) if (uv) {
{
uv->x = (*it2).second.x; uv->x = (*it2).second.x;
uv->y = (*it2).second.y; uv->y = (*it2).second.y;
++uv; ++uv;
@ -719,10 +632,8 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
std::copy(cpy.begin(), cpy.end(), meshes.begin() + oldm); std::copy(cpy.begin(), cpy.end(), meshes.begin() + oldm);
// previous meshes are deleted vy Subdivide(). // previous meshes are deleted vy Subdivide().
} } else {
else { ASSIMP_LOG_INFO("AC3D: Letting the subdivision surface untouched due to my configuration: " + object.name);
ASSIMP_LOG_INFO("AC3D: Letting the subdivision surface untouched due to my configuration: "
+object.name);
} }
} }
} }
@ -730,47 +641,41 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
if (object.name.length()) if (object.name.length())
node->mName.Set(object.name); node->mName.Set(object.name);
else else {
{
// generate a name depending on the type of the node // generate a name depending on the type of the node
switch (object.type) switch (object.type) {
{
case Object::Group: case Object::Group:
node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACGroup_%i",groups++); node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACGroup_%i", mGroupsCounter++);
break; break;
case Object::Poly: case Object::Poly:
node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACPoly_%i",polys++); node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACPoly_%i", mPolysCounter++);
break; break;
case Object::Light: case Object::Light:
node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACLight_%i",lights++); node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACLight_%i", mLightsCounter++);
break; break;
// there shouldn't be more than one world, but we don't care // there shouldn't be more than one world, but we don't care
case Object::World: case Object::World:
node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACWorld_%i",worlds++); node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACWorld_%i", mWorldsCounter++);
break; break;
} }
} }
// setup the local transformation matrix of the object // setup the local transformation matrix of the object
// compute the transformation offset to the parent node // compute the transformation offset to the parent node
node->mTransformation = aiMatrix4x4(object.rotation); node->mTransformation = aiMatrix4x4(object.rotation);
if (object.type == Object::Group || !object.numRefs) if (object.type == Object::Group || !object.numRefs) {
{
node->mTransformation.a4 = object.translation.x; node->mTransformation.a4 = object.translation.x;
node->mTransformation.b4 = object.translation.y; node->mTransformation.b4 = object.translation.y;
node->mTransformation.c4 = object.translation.z; node->mTransformation.c4 = object.translation.z;
} }
// add children to the object // add children to the object
if (object.children.size()) if (object.children.size()) {
{
node->mNumChildren = (unsigned int)object.children.size(); node->mNumChildren = (unsigned int)object.children.size();
node->mChildren = new aiNode *[node->mNumChildren]; node->mChildren = new aiNode *[node->mNumChildren];
for (unsigned int i = 0; i < node->mNumChildren;++i) for (unsigned int i = 0; i < node->mNumChildren; ++i) {
{
node->mChildren[i] = ConvertObjectSection(object.children[i], meshes, outMaterials, materials, node); node->mChildren[i] = ConvertObjectSection(object.children[i], meshes, outMaterials, materials, node);
} }
} }
@ -779,8 +684,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void AC3DImporter::SetupProperties(const Importer* pImp) void AC3DImporter::SetupProperties(const Importer *pImp) {
{
configSplitBFCull = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_AC_SEPARATE_BFCULL, 1) ? true : false; configSplitBFCull = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_AC_SEPARATE_BFCULL, 1) ? true : false;
configEvalSubdivision = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_AC_EVAL_SUBDIVISION, 1) ? true : false; configEvalSubdivision = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_AC_EVAL_SUBDIVISION, 1) ? true : false;
} }
@ -788,13 +692,13 @@ void AC3DImporter::SetupProperties(const Importer* pImp)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure. // Imports the given file into the given scene structure.
void AC3DImporter::InternReadFile(const std::string &pFile, void AC3DImporter::InternReadFile(const std::string &pFile,
aiScene* pScene, IOSystem* pIOHandler) aiScene *pScene, IOSystem *pIOHandler) {
{
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb")); std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb"));
// Check whether we can read from the file // Check whether we can read from the file
if( file.get() == NULL) if ( file.get() == nullptr ) {
throw DeadlyImportError("Failed to open AC3D file " + pFile + "."); throw DeadlyImportError("Failed to open AC3D file " + pFile + ".");
}
// allocate storage and copy the contents of the file to a memory buffer // allocate storage and copy the contents of the file to a memory buffer
std::vector<char> mBuffer2; std::vector<char> mBuffer2;
@ -803,7 +707,7 @@ void AC3DImporter::InternReadFile( const std::string& pFile,
buffer = &mBuffer2[0]; buffer = &mBuffer2[0];
mNumMeshes = 0; mNumMeshes = 0;
lights = polys = worlds = groups = 0; mLightsCounter = mPolysCounter = mWorldsCounter = mGroupsCounter = 0;
if (::strncmp(buffer, "AC3D", 4)) { if (::strncmp(buffer, "AC3D", 4)) {
throw DeadlyImportError("AC3D: No valid AC3D file, magic sequence not found"); throw DeadlyImportError("AC3D: No valid AC3D file, magic sequence not found");
@ -824,39 +728,34 @@ void AC3DImporter::InternReadFile( const std::string& pFile,
std::vector<aiLight *> lights; std::vector<aiLight *> lights;
mLights = &lights; mLights = &lights;
while (GetNextLine()) while (GetNextLine()) {
{ if (TokenMatch(buffer, "MATERIAL", 8)) {
if (TokenMatch(buffer,"MATERIAL",8))
{
materials.push_back(Material()); materials.push_back(Material());
Material &mat = materials.back(); Material &mat = materials.back();
// manually parse the material ... sscanf would use the buldin atof ... // manually parse the material ... sscanf would use the buldin atof ...
// Format: (name) rgb %f %f %f amb %f %f %f emis %f %f %f spec %f %f %f shi %d trans %f // Format: (name) rgb %f %f %f amb %f %f %f emis %f %f %f spec %f %f %f shi %d trans %f
AI_AC_SKIP_TO_NEXT_TOKEN(); buffer = AcSkipToNextToken(buffer);
if ('\"' == *buffer) if ('\"' == *buffer) {
{ buffer = AcGetString(buffer, mat.name);
AI_AC_GET_STRING(mat.name); buffer = AcSkipToNextToken(buffer);
AI_AC_SKIP_TO_NEXT_TOKEN();
} }
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("rgb",3,3,&mat.rgb); buffer = TAcCheckedLoadFloatArray(buffer, "rgb", 3, 3, &mat.rgb);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("amb",3,3,&mat.amb); buffer = TAcCheckedLoadFloatArray(buffer, "amb", 3, 3, &mat.amb);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("emis",4,3,&mat.emis); buffer = TAcCheckedLoadFloatArray(buffer, "emis", 4, 3, &mat.emis);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("spec",4,3,&mat.spec); buffer = TAcCheckedLoadFloatArray(buffer, "spec", 4, 3, &mat.spec);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("shi",3,1,&mat.shin); buffer = TAcCheckedLoadFloatArray(buffer, "shi", 3, 1, &mat.shin);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("trans",5,1,&mat.trans); buffer = TAcCheckedLoadFloatArray(buffer, "trans", 5, 1, &mat.trans);
} }
LoadObjectSection(rootObjects); LoadObjectSection(rootObjects);
} }
if (rootObjects.empty() || !mNumMeshes) if (rootObjects.empty() || !mNumMeshes) {
{
throw DeadlyImportError("AC3D: No meshes have been loaded"); throw DeadlyImportError("AC3D: No meshes have been loaded");
} }
if (materials.empty()) if (materials.empty()) {
{
ASSIMP_LOG_WARN("AC3D: No material has been found"); ASSIMP_LOG_WARN("AC3D: No material has been found");
materials.push_back(Material()); materials.push_back(Material());
} }
@ -872,21 +771,22 @@ void AC3DImporter::InternReadFile( const std::string& pFile,
Object *root; Object *root;
if (1 == rootObjects.size()) if (1 == rootObjects.size())
root = &rootObjects[0]; root = &rootObjects[0];
else else {
{
root = new Object(); root = new Object();
} }
// now convert the imported stuff to our output data structure // now convert the imported stuff to our output data structure
pScene->mRootNode = ConvertObjectSection(*root, meshes, omaterials, materials); pScene->mRootNode = ConvertObjectSection(*root, meshes, omaterials, materials);
if (1 != rootObjects.size())delete root; if (1 != rootObjects.size()) {
delete root;
}
if (!::strncmp( pScene->mRootNode->mName.data, "Node", 4)) if (!::strncmp(pScene->mRootNode->mName.data, "Node", 4)) {
pScene->mRootNode->mName.Set("<AC3DWorld>"); pScene->mRootNode->mName.Set("<AC3DWorld>");
}
// copy meshes // copy meshes
if (meshes.empty()) if (meshes.empty()) {
{
throw DeadlyImportError("An unknown error occurred during converting"); throw DeadlyImportError("An unknown error occurred during converting");
} }
pScene->mNumMeshes = (unsigned int)meshes.size(); pScene->mNumMeshes = (unsigned int)meshes.size();
@ -900,8 +800,7 @@ void AC3DImporter::InternReadFile( const std::string& pFile,
// copy lights // copy lights
pScene->mNumLights = (unsigned int)lights.size(); pScene->mNumLights = (unsigned int)lights.size();
if (lights.size()) if (lights.size()) {
{
pScene->mLights = new aiLight *[lights.size()]; pScene->mLights = new aiLight *[lights.size()];
::memcpy(pScene->mLights, &lights[0], lights.size() * sizeof(void *)); ::memcpy(pScene->mLights, &lights[0], lights.size() * sizeof(void *));
} }

View File

@ -68,8 +68,6 @@ public:
AC3DImporter(); AC3DImporter();
~AC3DImporter(); ~AC3DImporter();
// Represents an AC3D material // Represents an AC3D material
struct Material struct Material
{ {
@ -245,8 +243,6 @@ private:
aiMaterial& matDest); aiMaterial& matDest);
private: private:
// points to the next data line // points to the next data line
const char* buffer; const char* buffer;
@ -268,7 +264,7 @@ private:
std::vector<aiLight*>* mLights; std::vector<aiLight*>* mLights;
// name counters // name counters
unsigned int lights, groups, polys, worlds; unsigned int mLightsCounter, mGroupsCounter, mPolysCounter, mWorldsCounter;
}; };
} // end of namespace Assimp } // end of namespace Assimp

View File

@ -465,7 +465,7 @@ std::list<unsigned int> mesh_idx;
{ {
auto VertexIndex_GetMinimal = [](const std::list<SComplexFace>& pFaceList, const size_t* pBiggerThan) -> size_t auto VertexIndex_GetMinimal = [](const std::list<SComplexFace>& pFaceList, const size_t* pBiggerThan) -> size_t
{ {
size_t rv; size_t rv=0;
if(pBiggerThan != nullptr) if(pBiggerThan != nullptr)
{ {

View File

@ -80,7 +80,18 @@ struct Material : public D3DS::Material
} }
Material(const Material &other) = default; Material(const Material &other) = default;
Material &operator=(const Material &other) = default;
Material &operator=(const Material &other) {
if (this == &other) {
return *this;
}
avSubMaterials = other.avSubMaterials;
pcInstance = other.pcInstance;
bNeed = other.bNeed;
return *this;
}
//! Move constructor. This is explicitly written because MSVC doesn't support defaulting it //! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
@ -99,7 +110,7 @@ struct Material : public D3DS::Material
return *this; return *this;
} }
D3DS::Material::operator=(std::move(other)); //D3DS::Material::operator=(std::move(other));
avSubMaterials = std::move(other.avSubMaterials); avSubMaterials = std::move(other.avSubMaterials);
pcInstance = std::move(other.pcInstance); pcInstance = std::move(other.pcInstance);

View File

@ -49,8 +49,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AssbinFileWriter.h" #include "AssbinFileWriter.h"
#include <assimp/scene.h> #include <assimp/scene.h>
#include <assimp/IOSystem.hpp>
#include <assimp/Exporter.hpp> #include <assimp/Exporter.hpp>
#include <assimp/IOSystem.hpp>
namespace Assimp { namespace Assimp {

View File

@ -48,10 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "Common/assbin_chunks.h" #include "Common/assbin_chunks.h"
#include "PostProcessing/ProcessHelper.h" #include "PostProcessing/ProcessHelper.h"
#include <assimp/version.h>
#include <assimp/IOStream.hpp>
#include <assimp/Exporter.hpp>
#include <assimp/Exceptional.h> #include <assimp/Exceptional.h>
#include <assimp/version.h>
#include <assimp/Exporter.hpp>
#include <assimp/IOStream.hpp>
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB #ifdef ASSIMP_BUILD_NO_OWN_ZLIB
# include <zlib.h> # include <zlib.h>
@ -61,6 +61,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <time.h> #include <time.h>
#ifdef _WIN32
# pragma warning(push)
# pragma warning(disable : 4706)
#endif // _WIN32
namespace Assimp { namespace Assimp {
template <typename T> template <typename T>
@ -71,8 +76,7 @@ size_t Write(IOStream * stream, const T& v) {
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
// Serialize an aiString // Serialize an aiString
template <> template <>
inline inline size_t Write<aiString>(IOStream *stream, const aiString &s) {
size_t Write<aiString>(IOStream * stream, const aiString& s) {
const size_t s2 = (uint32_t)s.length; const size_t s2 = (uint32_t)s.length;
stream->Write(&s, 4, 1); stream->Write(&s, 4, 1);
stream->Write(s.data, s2, 1); stream->Write(s.data, s2, 1);
@ -83,8 +87,7 @@ size_t Write<aiString>(IOStream * stream, const aiString& s) {
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
// Serialize an unsigned int as uint32_t // Serialize an unsigned int as uint32_t
template <> template <>
inline inline size_t Write<unsigned int>(IOStream *stream, const unsigned int &w) {
size_t Write<unsigned int>(IOStream * stream, const unsigned int& w) {
const uint32_t t = (uint32_t)w; const uint32_t t = (uint32_t)w;
if (w > t) { if (w > t) {
// this shouldn't happen, integers in Assimp data structures never exceed 2^32 // this shouldn't happen, integers in Assimp data structures never exceed 2^32
@ -99,8 +102,7 @@ size_t Write<unsigned int>(IOStream * stream, const unsigned int& w) {
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
// Serialize an unsigned int as uint16_t // Serialize an unsigned int as uint16_t
template <> template <>
inline inline size_t Write<uint16_t>(IOStream *stream, const uint16_t &w) {
size_t Write<uint16_t>(IOStream * stream, const uint16_t& w) {
static_assert(sizeof(uint16_t) == 2, "sizeof(uint16_t)==2"); static_assert(sizeof(uint16_t) == 2, "sizeof(uint16_t)==2");
stream->Write(&w, 2, 1); stream->Write(&w, 2, 1);
@ -110,8 +112,7 @@ size_t Write<uint16_t>(IOStream * stream, const uint16_t& w) {
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
// Serialize a float // Serialize a float
template <> template <>
inline inline size_t Write<float>(IOStream *stream, const float &f) {
size_t Write<float>(IOStream * stream, const float& f) {
static_assert(sizeof(float) == 4, "sizeof(float)==4"); static_assert(sizeof(float) == 4, "sizeof(float)==4");
stream->Write(&f, 4, 1); stream->Write(&f, 4, 1);
@ -121,8 +122,7 @@ size_t Write<float>(IOStream * stream, const float& f) {
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
// Serialize a double // Serialize a double
template <> template <>
inline inline size_t Write<double>(IOStream *stream, const double &f) {
size_t Write<double>(IOStream * stream, const double& f) {
static_assert(sizeof(double) == 8, "sizeof(double)==8"); static_assert(sizeof(double) == 8, "sizeof(double)==8");
stream->Write(&f, 8, 1); stream->Write(&f, 8, 1);
@ -132,8 +132,7 @@ size_t Write<double>(IOStream * stream, const double& f) {
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
// Serialize a vec3 // Serialize a vec3
template <> template <>
inline inline size_t Write<aiVector3D>(IOStream *stream, const aiVector3D &v) {
size_t Write<aiVector3D>(IOStream * stream, const aiVector3D& v) {
size_t t = Write<float>(stream, v.x); size_t t = Write<float>(stream, v.x);
t += Write<float>(stream, v.y); t += Write<float>(stream, v.y);
t += Write<float>(stream, v.z); t += Write<float>(stream, v.z);
@ -144,8 +143,7 @@ size_t Write<aiVector3D>(IOStream * stream, const aiVector3D& v) {
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
// Serialize a color value // Serialize a color value
template <> template <>
inline inline size_t Write<aiColor3D>(IOStream *stream, const aiColor3D &v) {
size_t Write<aiColor3D>(IOStream * stream, const aiColor3D& v) {
size_t t = Write<float>(stream, v.r); size_t t = Write<float>(stream, v.r);
t += Write<float>(stream, v.g); t += Write<float>(stream, v.g);
t += Write<float>(stream, v.b); t += Write<float>(stream, v.b);
@ -156,8 +154,7 @@ size_t Write<aiColor3D>(IOStream * stream, const aiColor3D& v) {
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
// Serialize a color value // Serialize a color value
template <> template <>
inline inline size_t Write<aiColor4D>(IOStream *stream, const aiColor4D &v) {
size_t Write<aiColor4D>(IOStream * stream, const aiColor4D& v) {
size_t t = Write<float>(stream, v.r); size_t t = Write<float>(stream, v.r);
t += Write<float>(stream, v.g); t += Write<float>(stream, v.g);
t += Write<float>(stream, v.b); t += Write<float>(stream, v.b);
@ -169,8 +166,7 @@ size_t Write<aiColor4D>(IOStream * stream, const aiColor4D& v) {
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
// Serialize a quaternion // Serialize a quaternion
template <> template <>
inline inline size_t Write<aiQuaternion>(IOStream *stream, const aiQuaternion &v) {
size_t Write<aiQuaternion>(IOStream * stream, const aiQuaternion& v) {
size_t t = Write<float>(stream, v.w); size_t t = Write<float>(stream, v.w);
t += Write<float>(stream, v.x); t += Write<float>(stream, v.x);
t += Write<float>(stream, v.y); t += Write<float>(stream, v.y);
@ -183,8 +179,7 @@ size_t Write<aiQuaternion>(IOStream * stream, const aiQuaternion& v) {
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
// Serialize a vertex weight // Serialize a vertex weight
template <> template <>
inline inline size_t Write<aiVertexWeight>(IOStream *stream, const aiVertexWeight &v) {
size_t Write<aiVertexWeight>(IOStream * stream, const aiVertexWeight& v) {
size_t t = Write<unsigned int>(stream, v.mVertexId); size_t t = Write<unsigned int>(stream, v.mVertexId);
return t + Write<float>(stream, v.mWeight); return t + Write<float>(stream, v.mWeight);
@ -193,8 +188,7 @@ size_t Write<aiVertexWeight>(IOStream * stream, const aiVertexWeight& v) {
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
// Serialize a mat4x4 // Serialize a mat4x4
template <> template <>
inline inline size_t Write<aiMatrix4x4>(IOStream *stream, const aiMatrix4x4 &m) {
size_t Write<aiMatrix4x4>(IOStream * stream, const aiMatrix4x4& m) {
for (unsigned int i = 0; i < 4; ++i) { for (unsigned int i = 0; i < 4; ++i) {
for (unsigned int i2 = 0; i2 < 4; ++i2) { for (unsigned int i2 = 0; i2 < 4; ++i2) {
Write<float>(stream, m[i][i2]); Write<float>(stream, m[i][i2]);
@ -207,8 +201,7 @@ size_t Write<aiMatrix4x4>(IOStream * stream, const aiMatrix4x4& m) {
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
// Serialize an aiVectorKey // Serialize an aiVectorKey
template <> template <>
inline inline size_t Write<aiVectorKey>(IOStream *stream, const aiVectorKey &v) {
size_t Write<aiVectorKey>(IOStream * stream, const aiVectorKey& v) {
const size_t t = Write<double>(stream, v.mTime); const size_t t = Write<double>(stream, v.mTime);
return t + Write<aiVector3D>(stream, v.mValue); return t + Write<aiVector3D>(stream, v.mValue);
} }
@ -216,15 +209,13 @@ size_t Write<aiVectorKey>(IOStream * stream, const aiVectorKey& v) {
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
// Serialize an aiQuatKey // Serialize an aiQuatKey
template <> template <>
inline inline size_t Write<aiQuatKey>(IOStream *stream, const aiQuatKey &v) {
size_t Write<aiQuatKey>(IOStream * stream, const aiQuatKey& v) {
const size_t t = Write<double>(stream, v.mTime); const size_t t = Write<double>(stream, v.mTime);
return t + Write<aiQuaternion>(stream, v.mValue); return t + Write<aiQuaternion>(stream, v.mValue);
} }
template <typename T> template <typename T>
inline inline size_t WriteBounds(IOStream *stream, const T *in, unsigned int size) {
size_t WriteBounds(IOStream * stream, const T* in, unsigned int size) {
T minc, maxc; T minc, maxc;
ArrayBounds(in, size, minc, maxc); ArrayBounds(in, size, minc, maxc);
@ -235,10 +226,10 @@ size_t WriteBounds(IOStream * stream, const T* in, unsigned int size) {
// We use this to write out non-byte arrays so that we write using the specializations. // 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. // This way we avoid writing out extra bytes that potentially come from struct alignment.
template <typename T> template <typename T>
inline inline size_t WriteArray(IOStream *stream, const T *in, unsigned int size) {
size_t WriteArray(IOStream * stream, const T* in, unsigned int size) {
size_t n = 0; size_t n = 0;
for (unsigned int i=0; i<size; i++) n += Write<T>(stream,in[i]); for (unsigned int i = 0; i < size; i++)
n += Write<T>(stream, in[i]);
return n; return n;
} }
@ -253,10 +244,8 @@ size_t WriteArray(IOStream * stream, const T* in, unsigned int size) {
* and the chunk contents to the container stream. This allows relatively easy chunk * and the chunk contents to the container stream. This allows relatively easy chunk
* chunk construction, even recursively. * chunk construction, even recursively.
*/ */
class AssbinChunkWriter : public IOStream class AssbinChunkWriter : public IOStream {
{
private: private:
uint8_t *buffer; uint8_t *buffer;
uint32_t magic; uint32_t magic;
IOStream *container; IOStream *container;
@ -264,8 +253,7 @@ private:
private: private:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
void Grow(size_t need = 0) void Grow(size_t need = 0) {
{
size_t new_size = std::max(initial, std::max(need, cur_size + (cur_size >> 1))); size_t new_size = std::max(initial, std::max(need, cur_size + (cur_size >> 1)));
const uint8_t *const old = buffer; const uint8_t *const old = buffer;
@ -280,14 +268,17 @@ private:
} }
public: public:
AssbinChunkWriter(IOStream *container, uint32_t magic, size_t initial = 4096) :
AssbinChunkWriter( IOStream * container, uint32_t magic, size_t initial = 4096) buffer(NULL),
: buffer(NULL), magic(magic), container(container), cur_size(0), cursor(0), initial(initial) magic(magic),
{ container(container),
cur_size(0),
cursor(0),
initial(initial) {
// empty
} }
virtual ~AssbinChunkWriter() virtual ~AssbinChunkWriter() {
{
if (container) { if (container) {
container->Write(&magic, sizeof(uint32_t), 1); container->Write(&magic, sizeof(uint32_t), 1);
container->Write(&cursor, sizeof(uint32_t), 1); container->Write(&cursor, sizeof(uint32_t), 1);
@ -328,7 +319,6 @@ public:
return pCount; return pCount;
} }
}; };
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
@ -337,16 +327,14 @@ public:
* *
* This class writes an .assbin file, and is responsible for the file layout. * This class writes an .assbin file, and is responsible for the file layout.
*/ */
class AssbinFileWriter class AssbinFileWriter {
{
private: private:
bool shortened; bool shortened;
bool compressed; bool compressed;
protected: protected:
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
void WriteBinaryNode( IOStream * container, const aiNode* node) void WriteBinaryNode(IOStream *container, const aiNode *node) {
{
AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AINODE); AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AINODE);
unsigned int nb_metadata = (node->mMetaData != NULL ? node->mMetaData->mNumProperties : 0); unsigned int nb_metadata = (node->mMetaData != NULL ? node->mMetaData->mNumProperties : 0);
@ -371,7 +359,7 @@ protected:
void *value = node->mMetaData->mValues[i].mData; void *value = node->mMetaData->mValues[i].mData;
Write<aiString>(&chunk, key); Write<aiString>(&chunk, key);
Write<uint16_t>(&chunk, type); Write<uint16_t>(&chunk, (uint16_t)type);
switch (type) { switch (type) {
case AI_BOOL: case AI_BOOL:
@ -405,8 +393,7 @@ protected:
} }
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
void WriteBinaryTexture(IOStream * container, const aiTexture* tex) void WriteBinaryTexture(IOStream *container, const aiTexture *tex) {
{
AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AITEXTURE); AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AITEXTURE);
Write<unsigned int>(&chunk, tex->mWidth); Write<unsigned int>(&chunk, tex->mWidth);
@ -417,17 +404,14 @@ protected:
if (!shortened) { if (!shortened) {
if (!tex->mHeight) { if (!tex->mHeight) {
chunk.Write(tex->pcData, 1, tex->mWidth); chunk.Write(tex->pcData, 1, tex->mWidth);
} } else {
else {
chunk.Write(tex->pcData, 1, tex->mWidth * tex->mHeight * 4); chunk.Write(tex->pcData, 1, tex->mWidth * tex->mHeight * 4);
} }
} }
} }
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
void WriteBinaryBone(IOStream * container, const aiBone* b) void WriteBinaryBone(IOStream *container, const aiBone *b) {
{
AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AIBONE); AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AIBONE);
Write<aiString>(&chunk, b->mName); Write<aiString>(&chunk, b->mName);
@ -439,12 +423,12 @@ protected:
if (shortened) { if (shortened) {
WriteBounds(&chunk, b->mWeights, b->mNumWeights); WriteBounds(&chunk, b->mWeights, b->mNumWeights);
} // else write as usual } // else write as usual
else WriteArray<aiVertexWeight>(&chunk,b->mWeights,b->mNumWeights); else
WriteArray<aiVertexWeight>(&chunk, b->mWeights, b->mNumWeights);
} }
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
void WriteBinaryMesh(IOStream * container, const aiMesh* mesh) void WriteBinaryMesh(IOStream *container, const aiMesh *mesh) {
{
AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AIMESH); AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AIMESH);
Write<unsigned int>(&chunk, mesh->mPrimitiveTypes); Write<unsigned int>(&chunk, mesh->mPrimitiveTypes);
@ -483,13 +467,15 @@ protected:
if (shortened) { if (shortened) {
WriteBounds(&chunk, mesh->mVertices, mesh->mNumVertices); WriteBounds(&chunk, mesh->mVertices, mesh->mNumVertices);
} // else write as usual } // else write as usual
else WriteArray<aiVector3D>(&chunk,mesh->mVertices,mesh->mNumVertices); else
WriteArray<aiVector3D>(&chunk, mesh->mVertices, mesh->mNumVertices);
} }
if (mesh->mNormals) { if (mesh->mNormals) {
if (shortened) { if (shortened) {
WriteBounds(&chunk, mesh->mNormals, mesh->mNumVertices); WriteBounds(&chunk, mesh->mNormals, mesh->mNumVertices);
} // else write as usual } // else write as usual
else WriteArray<aiVector3D>(&chunk,mesh->mNormals,mesh->mNumVertices); else
WriteArray<aiVector3D>(&chunk, mesh->mNormals, mesh->mNumVertices);
} }
if (mesh->mTangents && mesh->mBitangents) { if (mesh->mTangents && mesh->mBitangents) {
if (shortened) { if (shortened) {
@ -508,7 +494,8 @@ protected:
if (shortened) { if (shortened) {
WriteBounds(&chunk, mesh->mColors[n], mesh->mNumVertices); WriteBounds(&chunk, mesh->mColors[n], mesh->mNumVertices);
} // else write as usual } // else write as usual
else WriteArray<aiColor4D>(&chunk,mesh->mColors[n],mesh->mNumVertices); else
WriteArray<aiColor4D>(&chunk, mesh->mColors[n], mesh->mNumVertices);
} }
for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++n) { for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++n) {
if (!mesh->mTextureCoords[n]) if (!mesh->mTextureCoords[n])
@ -520,7 +507,8 @@ protected:
if (shortened) { if (shortened) {
WriteBounds(&chunk, mesh->mTextureCoords[n], mesh->mNumVertices); WriteBounds(&chunk, mesh->mTextureCoords[n], mesh->mNumVertices);
} // else write as usual } // else write as usual
else WriteArray<aiVector3D>(&chunk,mesh->mTextureCoords[n],mesh->mNumVertices); else
WriteArray<aiVector3D>(&chunk, mesh->mTextureCoords[n], mesh->mNumVertices);
} }
// write faces. There are no floating-point calculations involved // write faces. There are no floating-point calculations involved
@ -530,7 +518,6 @@ protected:
if (shortened) { if (shortened) {
unsigned int processed = 0; unsigned int processed = 0;
for (unsigned int job; (job = std::min(mesh->mNumFaces - processed, 512u)); processed += job) { for (unsigned int job; (job = std::min(mesh->mNumFaces - processed, 512u)); processed += job) {
uint32_t hash = 0; uint32_t hash = 0;
for (unsigned int a = 0; a < job; ++a) { for (unsigned int a = 0; a < job; ++a) {
@ -545,21 +532,21 @@ protected:
} }
Write<unsigned int>(&chunk, hash); Write<unsigned int>(&chunk, hash);
} }
} } else // else write as usual
else // else write as usual
{ {
// if there are less than 2^16 vertices, we can simply use 16 bit integers ... // if there are less than 2^16 vertices, we can simply use 16 bit integers ...
for (unsigned int i = 0; i < mesh->mNumFaces; ++i) { for (unsigned int i = 0; i < mesh->mNumFaces; ++i) {
const aiFace &f = mesh->mFaces[i]; const aiFace &f = mesh->mFaces[i];
static_assert(AI_MAX_FACE_INDICES <= 0xffff, "AI_MAX_FACE_INDICES <= 0xffff"); static_assert(AI_MAX_FACE_INDICES <= 0xffff, "AI_MAX_FACE_INDICES <= 0xffff");
Write<uint16_t>(&chunk,f.mNumIndices); Write<uint16_t>(&chunk, static_cast<uint16_t>(f.mNumIndices));
for (unsigned int a = 0; a < f.mNumIndices; ++a) { for (unsigned int a = 0; a < f.mNumIndices; ++a) {
if (mesh->mNumVertices < (1u << 16)) { if (mesh->mNumVertices < (1u << 16)) {
Write<uint16_t>(&chunk,f.mIndices[a]); Write<uint16_t>(&chunk, static_cast<uint16_t>(f.mIndices[a]));
} else {
Write<unsigned int>(&chunk, f.mIndices[a]);
} }
else Write<unsigned int>(&chunk,f.mIndices[a]);
} }
} }
} }
@ -574,8 +561,7 @@ protected:
} }
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
void WriteBinaryMaterialProperty(IOStream * container, const aiMaterialProperty* prop) void WriteBinaryMaterialProperty(IOStream *container, const aiMaterialProperty *prop) {
{
AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AIMATERIALPROPERTY); AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AIMATERIALPROPERTY);
Write<aiString>(&chunk, prop->mKey); Write<aiString>(&chunk, prop->mKey);
@ -588,8 +574,7 @@ protected:
} }
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
void WriteBinaryMaterial(IOStream * container, const aiMaterial* mat) void WriteBinaryMaterial(IOStream *container, const aiMaterial *mat) {
{
AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AIMATERIAL); AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AIMATERIAL);
Write<unsigned int>(&chunk, mat->mNumProperties); Write<unsigned int>(&chunk, mat->mNumProperties);
@ -599,8 +584,7 @@ protected:
} }
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
void WriteBinaryNodeAnim(IOStream * container, const aiNodeAnim* nd) void WriteBinaryNodeAnim(IOStream *container, const aiNodeAnim *nd) {
{
AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AINODEANIM); AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AINODEANIM);
Write<aiString>(&chunk, nd->mNodeName); Write<aiString>(&chunk, nd->mNodeName);
@ -615,28 +599,29 @@ protected:
WriteBounds(&chunk, nd->mPositionKeys, nd->mNumPositionKeys); WriteBounds(&chunk, nd->mPositionKeys, nd->mNumPositionKeys);
} // else write as usual } // else write as usual
else WriteArray<aiVectorKey>(&chunk,nd->mPositionKeys,nd->mNumPositionKeys); else
WriteArray<aiVectorKey>(&chunk, nd->mPositionKeys, nd->mNumPositionKeys);
} }
if (nd->mRotationKeys) { if (nd->mRotationKeys) {
if (shortened) { if (shortened) {
WriteBounds(&chunk, nd->mRotationKeys, nd->mNumRotationKeys); WriteBounds(&chunk, nd->mRotationKeys, nd->mNumRotationKeys);
} // else write as usual } // else write as usual
else WriteArray<aiQuatKey>(&chunk,nd->mRotationKeys,nd->mNumRotationKeys); else
WriteArray<aiQuatKey>(&chunk, nd->mRotationKeys, nd->mNumRotationKeys);
} }
if (nd->mScalingKeys) { if (nd->mScalingKeys) {
if (shortened) { if (shortened) {
WriteBounds(&chunk, nd->mScalingKeys, nd->mNumScalingKeys); WriteBounds(&chunk, nd->mScalingKeys, nd->mNumScalingKeys);
} // else write as usual } // else write as usual
else WriteArray<aiVectorKey>(&chunk,nd->mScalingKeys,nd->mNumScalingKeys); else
WriteArray<aiVectorKey>(&chunk, nd->mScalingKeys, nd->mNumScalingKeys);
} }
} }
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
void WriteBinaryAnim( IOStream * container, const aiAnimation* anim ) void WriteBinaryAnim(IOStream *container, const aiAnimation *anim) {
{
AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AIANIMATION); AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AIANIMATION);
Write<aiString>(&chunk, anim->mName); Write<aiString>(&chunk, anim->mName);
@ -651,8 +636,7 @@ protected:
} }
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
void WriteBinaryLight( IOStream * container, const aiLight* l ) void WriteBinaryLight(IOStream *container, const aiLight *l) {
{
AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AILIGHT); AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AILIGHT);
Write<aiString>(&chunk, l->mName); Write<aiString>(&chunk, l->mName);
@ -672,12 +656,10 @@ protected:
Write<float>(&chunk, l->mAngleInnerCone); Write<float>(&chunk, l->mAngleInnerCone);
Write<float>(&chunk, l->mAngleOuterCone); Write<float>(&chunk, l->mAngleOuterCone);
} }
} }
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
void WriteBinaryCamera( IOStream * container, const aiCamera* cam ) void WriteBinaryCamera(IOStream *container, const aiCamera *cam) {
{
AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AICAMERA); AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AICAMERA);
Write<aiString>(&chunk, cam->mName); Write<aiString>(&chunk, cam->mName);
@ -691,8 +673,7 @@ protected:
} }
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
void WriteBinaryScene( IOStream * container, const aiScene* scene) void WriteBinaryScene(IOStream *container, const aiScene *scene) {
{
AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AISCENE); AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AISCENE);
// basic scene information // basic scene information
@ -725,7 +706,6 @@ protected:
WriteBinaryAnim(&chunk, anim); WriteBinaryAnim(&chunk, anim);
} }
// write all textures // write all textures
for (unsigned int i = 0; i < scene->mNumTextures; ++i) { for (unsigned int i = 0; i < scene->mNumTextures; ++i) {
const aiTexture *mesh = scene->mTextures[i]; const aiTexture *mesh = scene->mTextures[i];
@ -743,19 +723,16 @@ protected:
const aiCamera *cam = scene->mCameras[i]; const aiCamera *cam = scene->mCameras[i];
WriteBinaryCamera(&chunk, cam); WriteBinaryCamera(&chunk, cam);
} }
} }
public: public:
AssbinFileWriter(bool shortened, bool compressed) AssbinFileWriter(bool shortened, bool compressed) :
: shortened(shortened), compressed(compressed) shortened(shortened), compressed(compressed) {
{
} }
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
// Write a binary model dump // Write a binary model dump
void WriteBinaryDump(const char* pFile, const char* cmd, IOSystem* pIOSystem, const aiScene* pScene) void WriteBinaryDump(const char *pFile, const char *cmd, IOSystem *pIOSystem, const aiScene *pScene) {
{
IOStream *out = pIOSystem->Open(pFile, "wb"); IOStream *out = pIOSystem->Open(pFile, "wb");
if (!out) if (!out)
throw std::runtime_error("Unable to open output file " + std::string(pFile) + '\n'); throw std::runtime_error("Unable to open output file " + std::string(pFile) + '\n');
@ -813,8 +790,7 @@ public:
// Up to here the data is uncompressed. For compressed files, the rest // Up to here the data is uncompressed. For compressed files, the rest
// is compressed using standard DEFLATE from zlib. // is compressed using standard DEFLATE from zlib.
if (compressed) if (compressed) {
{
AssbinChunkWriter uncompressedStream(NULL, 0); AssbinChunkWriter uncompressedStream(NULL, 0);
WriteBinaryScene(&uncompressedStream, pScene); WriteBinaryScene(&uncompressedStream, pScene);
@ -823,8 +799,7 @@ public:
uint8_t *compressedBuffer = new uint8_t[compressedSize]; uint8_t *compressedBuffer = new uint8_t[compressedSize];
int res = compress2(compressedBuffer, &compressedSize, (const Bytef *)uncompressedStream.GetBufferPointer(), uncompressedSize, 9); int res = compress2(compressedBuffer, &compressedSize, (const Bytef *)uncompressedStream.GetBufferPointer(), uncompressedSize, 9);
if (res != Z_OK) if (res != Z_OK) {
{
delete[] compressedBuffer; delete[] compressedBuffer;
throw DeadlyExportError("Compression failed."); throw DeadlyExportError("Compression failed.");
} }
@ -833,15 +808,12 @@ public:
out->Write(compressedBuffer, sizeof(char), compressedSize); out->Write(compressedBuffer, sizeof(char), compressedSize);
delete[] compressedBuffer; delete[] compressedBuffer;
} } else {
else
{
WriteBinaryScene(out, pScene); WriteBinaryScene(out, pScene);
} }
CloseIOStream(); CloseIOStream();
} } catch (...) {
catch (...) {
CloseIOStream(); CloseIOStream();
throw; throw;
} }
@ -854,5 +826,8 @@ void DumpSceneToAssbin(
AssbinFileWriter fileWriter(shortened, compressed); AssbinFileWriter fileWriter(shortened, compressed);
fileWriter.WriteBinaryDump(pFile, cmd, pIOSystem, pScene); fileWriter.WriteBinaryDump(pFile, cmd, pIOSystem, pScene);
} }
#ifdef _WIN32
# pragma warning(pop)
#endif // _WIN32
} // end of namespace Assimp } // end of namespace Assimp

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -53,10 +51,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "Assbin/AssbinLoader.h" #include "Assbin/AssbinLoader.h"
#include "Common/assbin_chunks.h" #include "Common/assbin_chunks.h"
#include <assimp/MemoryIOWrapper.h> #include <assimp/MemoryIOWrapper.h>
#include <assimp/mesh.h>
#include <assimp/anim.h> #include <assimp/anim.h>
#include <assimp/scene.h>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <assimp/mesh.h>
#include <assimp/scene.h>
#include <memory> #include <memory>
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB #ifdef ASSIMP_BUILD_NO_OWN_ZLIB
@ -105,8 +103,9 @@ template <typename T>
T Read(IOStream *stream) { T Read(IOStream *stream) {
T t; T t;
size_t res = stream->Read(&t, sizeof(T), 1); size_t res = stream->Read(&t, sizeof(T), 1);
if(res != 1) if (res != 1) {
throw DeadlyImportError("Unexpected EOF"); throw DeadlyImportError("Unexpected EOF");
}
return t; return t;
} }
@ -114,9 +113,9 @@ T Read(IOStream * stream) {
template <> template <>
aiVector3D Read<aiVector3D>(IOStream *stream) { aiVector3D Read<aiVector3D>(IOStream *stream) {
aiVector3D v; aiVector3D v;
v.x = Read<float>(stream); v.x = Read<ai_real>(stream);
v.y = Read<float>(stream); v.y = Read<ai_real>(stream);
v.z = Read<float>(stream); v.z = Read<ai_real>(stream);
return v; return v;
} }
@ -124,10 +123,10 @@ aiVector3D Read<aiVector3D>(IOStream * stream) {
template <> template <>
aiColor4D Read<aiColor4D>(IOStream *stream) { aiColor4D Read<aiColor4D>(IOStream *stream) {
aiColor4D c; aiColor4D c;
c.r = Read<float>(stream); c.r = Read<ai_real>(stream);
c.g = Read<float>(stream); c.g = Read<ai_real>(stream);
c.b = Read<float>(stream); c.b = Read<ai_real>(stream);
c.a = Read<float>(stream); c.a = Read<ai_real>(stream);
return c; return c;
} }
@ -135,10 +134,10 @@ aiColor4D Read<aiColor4D>(IOStream * stream) {
template <> template <>
aiQuaternion Read<aiQuaternion>(IOStream *stream) { aiQuaternion Read<aiQuaternion>(IOStream *stream) {
aiQuaternion v; aiQuaternion v;
v.w = Read<float>(stream); v.w = Read<ai_real>(stream);
v.x = Read<float>(stream); v.x = Read<ai_real>(stream);
v.y = Read<float>(stream); v.y = Read<ai_real>(stream);
v.z = Read<float>(stream); v.z = Read<ai_real>(stream);
return v; return v;
} }
@ -147,9 +146,11 @@ template <>
aiString Read<aiString>(IOStream *stream) { aiString Read<aiString>(IOStream *stream) {
aiString s; aiString s;
stream->Read(&s.length, 4, 1); stream->Read(&s.length, 4, 1);
if(s.length) if (s.length) {
stream->Read(s.data, s.length, 1); stream->Read(s.data, s.length, 1);
}
s.data[s.length] = 0; s.data[s.length] = 0;
return s; return s;
} }
@ -158,7 +159,7 @@ template <>
aiVertexWeight Read<aiVertexWeight>(IOStream *stream) { aiVertexWeight Read<aiVertexWeight>(IOStream *stream) {
aiVertexWeight w; aiVertexWeight w;
w.mVertexId = Read<unsigned int>(stream); w.mVertexId = Read<unsigned int>(stream);
w.mWeight = Read<float>(stream); w.mWeight = Read<ai_real>(stream);
return w; return w;
} }
@ -168,7 +169,7 @@ aiMatrix4x4 Read<aiMatrix4x4>(IOStream * stream) {
aiMatrix4x4 m; aiMatrix4x4 m;
for (unsigned int i = 0; i < 4; ++i) { for (unsigned int i = 0; i < 4; ++i) {
for (unsigned int i2 = 0; i2 < 4; ++i2) { for (unsigned int i2 = 0; i2 < 4; ++i2) {
m[i][i2] = Read<float>(stream); m[i][i2] = Read<ai_real>(stream);
} }
} }
return m; return m;
@ -228,8 +229,7 @@ void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** onode, aiNode*
node->mParent = parent; node->mParent = parent;
} }
if (numMeshes) if (numMeshes) {
{
node->mMeshes = new unsigned int[numMeshes]; node->mMeshes = new unsigned int[numMeshes];
for (unsigned int i = 0; i < numMeshes; ++i) { for (unsigned int i = 0; i < numMeshes; ++i) {
node->mMeshes[i] = Read<unsigned int>(stream); node->mMeshes[i] = Read<unsigned int>(stream);
@ -263,7 +263,7 @@ void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** onode, aiNode*
data = new uint64_t(Read<uint64_t>(stream)); data = new uint64_t(Read<uint64_t>(stream));
break; break;
case AI_FLOAT: case AI_FLOAT:
data = new float(Read<float>(stream)); data = new ai_real(Read<ai_real>(stream));
break; break;
case AI_DOUBLE: case AI_DOUBLE:
data = new double(Read<double>(stream)); data = new double(Read<double>(stream));
@ -312,6 +312,7 @@ void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b ) {
static bool fitsIntoUI16(unsigned int mNumVertices) { static bool fitsIntoUI16(unsigned int mNumVertices) {
return (mNumVertices < (1u << 16)); return (mNumVertices < (1u << 16));
} }
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryMesh(IOStream *stream, aiMesh *mesh) { void AssbinImporter::ReadBinaryMesh(IOStream *stream, aiMesh *mesh) {
if (Read<uint32_t>(stream) != ASSBIN_CHUNK_AIMESH) if (Read<uint32_t>(stream) != ASSBIN_CHUNK_AIMESH)
@ -448,10 +449,8 @@ void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat) {
/*uint32_t size =*/Read<uint32_t>(stream); /*uint32_t size =*/Read<uint32_t>(stream);
mat->mNumAllocated = mat->mNumProperties = Read<unsigned int>(stream); mat->mNumAllocated = mat->mNumProperties = Read<unsigned int>(stream);
if (mat->mNumProperties) if (mat->mNumProperties) {
{ if (mat->mProperties) {
if (mat->mProperties)
{
delete[] mat->mProperties; delete[] mat->mProperties;
} }
mat->mProperties = new aiMaterialProperty *[mat->mNumProperties]; mat->mProperties = new aiMaterialProperty *[mat->mNumProperties];
@ -666,7 +665,6 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) {
ReadBinaryCamera(stream, scene->mCameras[i]); ReadBinaryCamera(stream, scene->mCameras[i]);
} }
} }
} }
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
@ -709,8 +707,7 @@ void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
unsigned char *uncompressedData = new unsigned char[uncompressedSize]; unsigned char *uncompressedData = new unsigned char[uncompressedSize];
int res = uncompress(uncompressedData, &uncompressedSize, compressedData, (uLong)len); int res = uncompress(uncompressedData, &uncompressedSize, compressedData, (uLong)len);
if(res != Z_OK) if (res != Z_OK) {
{
delete[] uncompressedData; delete[] uncompressedData;
delete[] compressedData; delete[] compressedData;
pIOHandler->Close(stream); pIOHandler->Close(stream);

View File

@ -8,6 +8,10 @@ For details, see http://sourceforge.net/projects/libb64
#ifndef BASE64_CENCODE_H #ifndef BASE64_CENCODE_H
#define BASE64_CENCODE_H #define BASE64_CENCODE_H
#ifdef _WIN32
#pragma warning(disable : 4127 )
#endif // _WIN32
typedef enum typedef enum
{ {
step_A, step_B, step_C step_A, step_B, step_C

View File

@ -91,20 +91,20 @@ public:
base64_encodestate s; base64_encodestate s;
base64_init_encodestate(&s); base64_init_encodestate(&s);
char* const out = new char[std::max(len * 2, static_cast<size_t>(16u))]; char* const cur_out = new char[std::max(len * 2, static_cast<size_t>(16u))];
const int n = base64_encode_block(reinterpret_cast<const char*>(buffer), static_cast<int>(len), out, &s); const int n = base64_encode_block(reinterpret_cast<const char *>(buffer), static_cast<int>(len), cur_out, &s);
out[n + base64_encode_blockend(out + n, &s)] = '\0'; cur_out[n + base64_encode_blockend(cur_out + n, &s)] = '\0';
// base64 encoding may add newlines, but JSON strings may not contain 'real' newlines // base64 encoding may add newlines, but JSON strings may not contain 'real' newlines
// (only escaped ones). Remove any newlines in out. // (only escaped ones). Remove any newlines in out.
for (char* cur = out; *cur; ++cur) { for (char *cur = cur_out; *cur; ++cur) {
if (*cur == '\n') { if (*cur == '\n') {
*cur = ' '; *cur = ' ';
} }
} }
buff << '\"' << out << "\"\n"; buff << '\"' << cur_out << "\"\n";
delete[] out; delete[] cur_out;
} }
void StartObj(bool is_element = false) { void StartObj(bool is_element = false) {
@ -464,8 +464,8 @@ void Write(JSONWriter& out, const aiMaterial& ai, bool is_elem = true) {
case aiPTI_Float: case aiPTI_Float:
if (prop->mDataLength / sizeof(float) > 1) { if (prop->mDataLength / sizeof(float) > 1) {
out.StartArray(); out.StartArray();
for (unsigned int i = 0; i < prop->mDataLength / sizeof(float); ++i) { for (unsigned int ii = 0; ii < prop->mDataLength / sizeof(float); ++ii) {
out.Element(reinterpret_cast<float*>(prop->mData)[i]); out.Element(reinterpret_cast<float*>(prop->mData)[ii]);
} }
out.EndArray(); out.EndArray();
} }
@ -477,8 +477,8 @@ void Write(JSONWriter& out, const aiMaterial& ai, bool is_elem = true) {
case aiPTI_Integer: case aiPTI_Integer:
if (prop->mDataLength / sizeof(int) > 1) { if (prop->mDataLength / sizeof(int) > 1) {
out.StartArray(); out.StartArray();
for (unsigned int i = 0; i < prop->mDataLength / sizeof(int); ++i) { for (unsigned int ii = 0; ii < prop->mDataLength / sizeof(int); ++ii) {
out.Element(reinterpret_cast<int*>(prop->mData)[i]); out.Element(reinterpret_cast<int*>(prop->mData)[ii]);
} }
out.EndArray(); out.EndArray();
} else { } else {

View File

@ -373,25 +373,25 @@ void WriteDump(const char* pFile, const char* cmd, const aiScene* scene, IOStrea
ioprintf(io," size=\"%i\">\n\t\t\t\t", ioprintf(io," size=\"%i\">\n\t\t\t\t",
static_cast<int>(prop->mDataLength/sizeof(float))); static_cast<int>(prop->mDataLength/sizeof(float)));
for (unsigned int p = 0; p < prop->mDataLength/sizeof(float);++p) { for (unsigned int pp = 0; pp < prop->mDataLength/sizeof(float);++pp) {
ioprintf(io,"%f ",*((float*)(prop->mData+p*sizeof(float)))); ioprintf(io,"%f ",*((float*)(prop->mData+pp*sizeof(float))));
} }
} }
else if (prop->mType == aiPTI_Integer) { else if (prop->mType == aiPTI_Integer) {
ioprintf(io," size=\"%i\">\n\t\t\t\t", ioprintf(io," size=\"%i\">\n\t\t\t\t",
static_cast<int>(prop->mDataLength/sizeof(int))); static_cast<int>(prop->mDataLength/sizeof(int)));
for (unsigned int p = 0; p < prop->mDataLength/sizeof(int);++p) { for (unsigned int pp = 0; pp < prop->mDataLength/sizeof(int);++pp) {
ioprintf(io,"%i ",*((int*)(prop->mData+p*sizeof(int)))); ioprintf(io,"%i ",*((int*)(prop->mData+pp*sizeof(int))));
} }
} }
else if (prop->mType == aiPTI_Buffer) { else if (prop->mType == aiPTI_Buffer) {
ioprintf(io," size=\"%i\">\n\t\t\t\t", ioprintf(io," size=\"%i\">\n\t\t\t\t",
static_cast<int>(prop->mDataLength)); static_cast<int>(prop->mDataLength));
for (unsigned int p = 0; p < prop->mDataLength;++p) { for (unsigned int pp = 0; pp< prop->mDataLength;++pp) {
ioprintf(io,"%2x ",prop->mData[p]); ioprintf(io,"%2x ",prop->mData[pp]);
if (p && 0 == p%30) { if (pp && 0 == pp%30) {
ioprintf(io,"\n\t\t\t\t"); ioprintf(io,"\n\t\t\t\t");
} }
} }

View File

@ -155,37 +155,38 @@ AI_WONT_RETURN void B3DImporter::Fail( string str ){
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
int B3DImporter::ReadByte(){ int B3DImporter::ReadByte(){
if( _pos<_buf.size() ) { if (_pos > _buf.size()) {
return _buf[_pos++]; Fail("EOF");
} }
Fail( "EOF" ); return _buf[_pos++];
return 0;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
int B3DImporter::ReadInt(){ int B3DImporter::ReadInt(){
if( _pos+4<=_buf.size() ){ if (_pos + 4 > _buf.size()) {
Fail("EOF");
}
int n; int n;
memcpy(&n, &_buf[_pos], 4); memcpy(&n, &_buf[_pos], 4);
_pos+=4; _pos+=4;
return n; return n;
} }
Fail( "EOF" );
return 0;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
float B3DImporter::ReadFloat() { float B3DImporter::ReadFloat() {
if( _pos+4<=_buf.size() ){ if (_pos + 4 > _buf.size()) {
Fail("EOF");
}
float n; float n;
memcpy(&n, &_buf[_pos], 4); memcpy(&n, &_buf[_pos], 4);
_pos+=4; _pos+=4;
return n; return n;
} }
Fail( "EOF" );
return 0.0f;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
aiVector2D B3DImporter::ReadVec2(){ aiVector2D B3DImporter::ReadVec2(){
@ -214,6 +215,9 @@ aiQuaternion B3DImporter::ReadQuat(){
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
string B3DImporter::ReadString(){ string B3DImporter::ReadString(){
if (_pos > _buf.size()) {
Fail("EOF");
}
string str; string str;
while( _pos<_buf.size() ){ while( _pos<_buf.size() ){
char c=(char)ReadByte(); char c=(char)ReadByte();
@ -222,7 +226,6 @@ string B3DImporter::ReadString(){
} }
str+=c; str+=c;
} }
Fail( "EOF" );
return string(); return string();
} }
@ -247,7 +250,7 @@ void B3DImporter::ExitChunk(){
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
unsigned B3DImporter::ChunkSize(){ size_t B3DImporter::ChunkSize(){
return _stack.back()-_pos; return _stack.back()-_pos;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -356,12 +359,12 @@ void B3DImporter::ReadVRTS(){
} }
int sz = 12+(_vflags&1?12:0)+(_vflags&2?16:0)+(_tcsets*_tcsize*4); int sz = 12+(_vflags&1?12:0)+(_vflags&2?16:0)+(_tcsets*_tcsize*4);
int n_verts=ChunkSize()/sz; size_t n_verts = ChunkSize()/sz;
int v0=static_cast<int>(_vertices.size()); int v0=static_cast<int>(_vertices.size());
_vertices.resize( v0+n_verts ); _vertices.resize( v0+n_verts );
for( int i=0;i<n_verts;++i ){ for( unsigned int i=0;i<n_verts;++i ){
Vertex &v=_vertices[v0+i]; Vertex &v=_vertices[v0+i];
memset( v.bones,0,sizeof(v.bones) ); memset( v.bones,0,sizeof(v.bones) );
@ -377,13 +380,13 @@ void B3DImporter::ReadVRTS(){
ReadQuat(); //skip v 4bytes... ReadQuat(); //skip v 4bytes...
} }
for( int i=0;i<_tcsets;++i ){ for( int j=0;j<_tcsets;++j ){
float t[4]={0,0,0,0}; float t[4]={0,0,0,0};
for( int j=0;j<_tcsize;++j ){ for( int k=0;k<_tcsize;++k ){
t[j]=ReadFloat(); t[k]=ReadFloat();
} }
t[1] = 1 - t[1]; t[1] = 1 - t[1];
if( !i ) { if( !j ) {
v.texcoords = aiVector3D( t[0],t[1],t[2] ); v.texcoords = aiVector3D( t[0],t[1],t[2] );
} }
} }
@ -408,10 +411,10 @@ void B3DImporter::ReadTRIS(int v0) {
mesh->mNumFaces = 0; mesh->mNumFaces = 0;
mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE; mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
int n_tris = ChunkSize() / 12; size_t n_tris = ChunkSize() / 12;
aiFace *face = mesh->mFaces = new aiFace[n_tris]; aiFace *face = mesh->mFaces = new aiFace[n_tris];
for (int i = 0; i < n_tris; ++i) { for (unsigned int i = 0; i < n_tris; ++i) {
int i0 = ReadInt() + v0; int i0 = ReadInt() + v0;
int i1 = ReadInt() + v0; int i1 = ReadInt() + v0;
int i2 = ReadInt() + v0; int i2 = ReadInt() + v0;
@ -463,7 +466,7 @@ void B3DImporter::ReadBONE(int id) {
Vertex &v = _vertices[vertex]; Vertex &v = _vertices[vertex];
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
if (!v.weights[i]) { if (!v.weights[i]) {
v.bones[i] = id; v.bones[i] = static_cast<unsigned char>(id);
v.weights[i] = weight; v.weights[i] = weight;
break; break;
} }
@ -547,24 +550,24 @@ aiNode *B3DImporter::ReadNODE( aiNode *parent ){
vector<aiNode*> children; vector<aiNode*> children;
while( ChunkSize() ){ while( ChunkSize() ){
string t=ReadChunk(); const string chunk = ReadChunk();
if( t=="MESH" ){ if (chunk == "MESH") {
unsigned int n= static_cast<unsigned int>(_meshes.size()); unsigned int n= static_cast<unsigned int>(_meshes.size());
ReadMESH(); ReadMESH();
for( unsigned int i=n;i<static_cast<unsigned int>(_meshes.size());++i ){ for( unsigned int i=n;i<static_cast<unsigned int>(_meshes.size());++i ){
meshes.push_back( i ); meshes.push_back( i );
} }
}else if( t=="BONE" ){ } else if (chunk == "BONE") {
ReadBONE( nodeid ); ReadBONE( nodeid );
}else if( t=="ANIM" ){ } else if (chunk == "ANIM") {
ReadANIM(); ReadANIM();
}else if( t=="KEYS" ){ } else if (chunk == "KEYS") {
if( !nodeAnim ){ if( !nodeAnim ){
nodeAnim.reset(new aiNodeAnim); nodeAnim.reset(new aiNodeAnim);
nodeAnim->mNodeName=node->mName; nodeAnim->mNodeName=node->mName;
} }
ReadKEYS( nodeAnim.get() ); ReadKEYS( nodeAnim.get() );
}else if( t=="NODE" ){ } else if (chunk == "NODE") {
aiNode *child=ReadNODE( node ); aiNode *child=ReadNODE( node );
children.push_back( child ); children.push_back( child );
} }
@ -613,12 +616,12 @@ void B3DImporter::ReadBB3D( aiScene *scene ){
} }
while( ChunkSize() ){ while( ChunkSize() ){
string t=ReadChunk(); const string chunk = ReadChunk();
if( t=="TEXS" ){ if (chunk == "TEXS") {
ReadTEXS(); ReadTEXS();
}else if( t=="BRUS" ){ } else if (chunk == "BRUS") {
ReadBRUS(); ReadBRUS();
}else if( t=="NODE" ){ } else if (chunk == "NODE") {
ReadNODE( 0 ); ReadNODE( 0 );
} }
ExitChunk(); ExitChunk();
@ -656,37 +659,40 @@ void B3DImporter::ReadBB3D( aiScene *scene ){
vector< vector<aiVertexWeight> > vweights( _nodes.size() ); vector< vector<aiVertexWeight> > vweights( _nodes.size() );
for( int i=0;i<n_verts;i+=3 ){ for (int vertIdx = 0; vertIdx < n_verts; vertIdx += 3) {
for( int j=0;j<3;++j ){ for (int faceIndex = 0; faceIndex < 3; ++faceIndex) {
Vertex &v=_vertices[face->mIndices[j]]; Vertex &v = _vertices[face->mIndices[faceIndex]];
*mv++=v.vertex; *mv++=v.vertex;
if( mn ) *mn++=v.normal; if( mn ) *mn++=v.normal;
if( mc ) *mc++=v.texcoords; if( mc ) *mc++=v.texcoords;
face->mIndices[j]=i+j; face->mIndices[faceIndex] = vertIdx + faceIndex;
for( int k=0;k<4;++k ){ for( int k=0;k<4;++k ){
if( !v.weights[k] ) break; if( !v.weights[k] )
break;
int bone = v.bones[k]; int bone = v.bones[k];
float weight = v.weights[k]; float weight = v.weights[k];
vweights[bone].push_back( aiVertexWeight(i+j,weight) ); vweights[bone].push_back(aiVertexWeight(vertIdx + faceIndex, weight));
} }
} }
++face; ++face;
} }
vector<aiBone*> bones; vector<aiBone*> bones;
for(size_t i=0;i<vweights.size();++i ){ for (size_t weightIndx = 0; weightIndx < vweights.size(); ++weightIndx) {
vector<aiVertexWeight> &weights=vweights[i]; vector<aiVertexWeight> &weights = vweights[weightIndx];
if( !weights.size() ) continue; if (!weights.size()) {
continue;
}
aiBone *bone = new aiBone; aiBone *bone = new aiBone;
bones.push_back( bone ); bones.push_back( bone );
aiNode *bnode=_nodes[i]; aiNode *bnode = _nodes[weightIndx];
bone->mName = bnode->mName; bone->mName = bnode->mName;
bone->mNumWeights = static_cast<unsigned int>(weights.size()); bone->mNumWeights = static_cast<unsigned int>(weights.size());

View File

@ -82,7 +82,7 @@ private:
std::string ReadString(); std::string ReadString();
std::string ReadChunk(); std::string ReadChunk();
void ExitChunk(); void ExitChunk();
unsigned ChunkSize(); size_t ChunkSize();
template<class T> template<class T>
T *to_array( const std::vector<T> &v ); T *to_array( const std::vector<T> &v );
@ -112,10 +112,10 @@ private:
void ReadBB3D( aiScene *scene ); void ReadBB3D( aiScene *scene );
unsigned _pos; size_t _pos;
// unsigned _size; // unsigned _size;
std::vector<unsigned char> _buf; std::vector<unsigned char> _buf;
std::vector<unsigned> _stack; std::vector<size_t> _stack;
std::vector<std::string> _textures; std::vector<std::string> _textures;
std::vector<std::unique_ptr<aiMaterial> > _materials; std::vector<std::unique_ptr<aiMaterial> > _materials;

View File

@ -429,7 +429,7 @@ void BlenderImporter::ResolveImage(aiMaterial* out, const Material* mat, const M
name.length = 1+ ASSIMP_itoa10(name.data+1,static_cast<unsigned int>(MAXLEN-1), static_cast<int32_t>(conv_data.textures->size())); name.length = 1+ ASSIMP_itoa10(name.data+1,static_cast<unsigned int>(MAXLEN-1), static_cast<int32_t>(conv_data.textures->size()));
conv_data.textures->push_back(new aiTexture()); conv_data.textures->push_back(new aiTexture());
aiTexture* tex = conv_data.textures->back(); aiTexture* curTex = conv_data.textures->back();
// usually 'img->name' will be the original file name of the embedded textures, // usually 'img->name' will be the original file name of the embedded textures,
// so we can extract the file extension from it. // so we can extract the file extension from it.
@ -439,19 +439,19 @@ void BlenderImporter::ResolveImage(aiMaterial* out, const Material* mat, const M
--s; --s;
} }
tex->achFormatHint[0] = s+1>e ? '\0' : ::tolower( s[1] ); curTex->achFormatHint[0] = s + 1 > e ? '\0' : (char)::tolower(s[1]);
tex->achFormatHint[1] = s+2>e ? '\0' : ::tolower( s[2] ); curTex->achFormatHint[1] = s + 2 > e ? '\0' : (char)::tolower(s[2]);
tex->achFormatHint[2] = s+3>e ? '\0' : ::tolower( s[3] ); curTex->achFormatHint[2] = s + 3 > e ? '\0' : (char)::tolower(s[3]);
tex->achFormatHint[3] = '\0'; curTex->achFormatHint[3] = '\0';
// tex->mHeight = 0; // tex->mHeight = 0;
tex->mWidth = img->packedfile->size; curTex->mWidth = img->packedfile->size;
uint8_t* ch = new uint8_t[tex->mWidth]; uint8_t *ch = new uint8_t[curTex->mWidth];
conv_data.db.reader->SetCurrentPos(static_cast<size_t>( img->packedfile->data->val)); conv_data.db.reader->SetCurrentPos(static_cast<size_t>( img->packedfile->data->val));
conv_data.db.reader->CopyAndAdvance(ch,tex->mWidth); conv_data.db.reader->CopyAndAdvance(ch, curTex->mWidth);
tex->pcData = reinterpret_cast<aiTexel*>(ch); curTex->pcData = reinterpret_cast<aiTexel *>(ch);
LogInfo("Reading embedded texture, original file was "+std::string(img->name)); LogInfo("Reading embedded texture, original file was "+std::string(img->name));
} else { } else {
@ -1078,9 +1078,9 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
const aiFace& f = out->mFaces[out->mNumFaces++]; const aiFace& f = out->mFaces[out->mNumFaces++];
aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices]; aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
for (unsigned int i = 0; i < f.mNumIndices; ++i,++vo,++out->mNumVertices) { for (unsigned int j = 0; j < f.mNumIndices; ++j,++vo,++out->mNumVertices) {
vo->x = v->uv[i][0]; vo->x = v->uv[j][0];
vo->y = v->uv[i][1]; vo->y = v->uv[j][1];
} }
} }
@ -1098,8 +1098,7 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
vo->x = uv.uv[0]; vo->x = uv.uv[0];
vo->y = uv.uv[1]; vo->y = uv.uv[1];
} }
} } else {
else {
// create textureCoords for every mapped tex // create textureCoords for every mapped tex
for (uint32_t m = 0; m < itMatTexUvMapping->second.size(); ++m) { for (uint32_t m = 0; m < itMatTexUvMapping->second.size(); ++m) {
const MLoopUV *tm = itMatTexUvMapping->second[m]; const MLoopUV *tm = itMatTexUvMapping->second[m];
@ -1139,9 +1138,9 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
const aiFace& f = out->mFaces[out->mNumFaces++]; const aiFace& f = out->mFaces[out->mNumFaces++];
aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices]; aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
for (unsigned int i = 0; i < f.mNumIndices; ++i,++vo,++out->mNumVertices) { for (unsigned int j = 0; j < f.mNumIndices; ++j,++vo,++out->mNumVertices) {
vo->x = v->uv[i][0]; vo->x = v->uv[j][0];
vo->y = v->uv[i][1]; vo->y = v->uv[j][1];
} }
} }
} }

View File

@ -57,7 +57,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
using namespace Assimp::Blender; using namespace Assimp::Blender;
template <typename T> BlenderModifier* god() { template <typename T>
BlenderModifier *god() {
return new T(); return new T();
} }
@ -71,14 +72,12 @@ static const fpCreateModifier creators[] = {
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
struct SharedModifierData : ElemBase struct SharedModifierData : ElemBase {
{
ModifierData modifier; ModifierData modifier;
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderModifierShowcase::ApplyModifiers(aiNode& out, ConversionData& conv_data, const Scene& in, const Object& orig_object ) void BlenderModifierShowcase::ApplyModifiers(aiNode &out, ConversionData &conv_data, const Scene &in, const Object &orig_object) {
{
size_t cnt = 0u, ful = 0u; size_t cnt = 0u, ful = 0u;
// NOTE: this cast is potentially unsafe by design, so we need to perform type checks before // NOTE: this cast is potentially unsafe by design, so we need to perform type checks before
@ -146,19 +145,15 @@ void BlenderModifierShowcase::ApplyModifiers(aiNode& out, ConversionData& conv_d
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool BlenderModifier_Mirror :: IsActive (const ModifierData& modin) bool BlenderModifier_Mirror ::IsActive(const ModifierData &modin) {
{
return modin.type == ModifierData::eModifierType_Mirror; return modin.type == ModifierData::eModifierType_Mirror;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderModifier_Mirror ::DoIt(aiNode &out, ConversionData &conv_data, const ElemBase &orig_modifier, void BlenderModifier_Mirror ::DoIt(aiNode &out, ConversionData &conv_data, const ElemBase &orig_modifier,
const Scene & /*in*/, const Scene & /*in*/,
const Object& orig_object ) const Object &orig_object) {
{
// hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers() // hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers()
const MirrorModifierData &mir = static_cast<const MirrorModifierData &>(orig_modifier); const MirrorModifierData &mir = static_cast<const MirrorModifierData &>(orig_modifier);
ai_assert(mir.modifier.type == ModifierData::eModifierType_Mirror); ai_assert(mir.modifier.type == ModifierData::eModifierType_Mirror);
@ -178,39 +173,46 @@ void BlenderModifier_Mirror :: DoIt(aiNode& out, ConversionData& conv_data, co
if (mir.mirror_ob) { if (mir.mirror_ob) {
const aiVector3D center(mir.mirror_ob->obmat[3][0], mir.mirror_ob->obmat[3][1], mir.mirror_ob->obmat[3][2]); const aiVector3D center(mir.mirror_ob->obmat[3][0], mir.mirror_ob->obmat[3][1], mir.mirror_ob->obmat[3][2]);
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { for (unsigned int j = 0; j < mesh->mNumVertices; ++j) {
aiVector3D& v = mesh->mVertices[i]; aiVector3D &v = mesh->mVertices[j];
v.x = center.x + xs * (center.x - v.x); v.x = center.x + xs * (center.x - v.x);
v.y = center.y + ys * (center.y - v.y); v.y = center.y + ys * (center.y - v.y);
v.z = center.z + zs * (center.z - v.z); v.z = center.z + zs * (center.z - v.z);
} }
} } else {
else { for (unsigned int j = 0; j < mesh->mNumVertices; ++j) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { aiVector3D &v = mesh->mVertices[j];
aiVector3D& v = mesh->mVertices[i]; v.x *= xs;
v.x *= xs;v.y *= ys;v.z *= zs; v.y *= ys;
v.z *= zs;
} }
} }
if (mesh->mNormals) { if (mesh->mNormals) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { for (unsigned int j = 0; j < mesh->mNumVertices; ++j) {
aiVector3D& v = mesh->mNormals[i]; aiVector3D &v = mesh->mNormals[j];
v.x *= xs;v.y *= ys;v.z *= zs; v.x *= xs;
v.y *= ys;
v.z *= zs;
} }
} }
if (mesh->mTangents) { if (mesh->mTangents) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { for (unsigned int j = 0; j < mesh->mNumVertices; ++j) {
aiVector3D& v = mesh->mTangents[i]; aiVector3D &v = mesh->mTangents[j];
v.x *= xs;v.y *= ys;v.z *= zs; v.x *= xs;
v.y *= ys;
v.z *= zs;
} }
} }
if (mesh->mBitangents) { if (mesh->mBitangents) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { for (unsigned int j = 0; j < mesh->mNumVertices; ++j) {
aiVector3D& v = mesh->mBitangents[i]; aiVector3D &v = mesh->mBitangents[j];
v.x *= xs;v.y *= ys;v.z *= zs; v.x *= xs;
v.y *= ys;
v.z *= zs;
} }
} }
@ -218,16 +220,17 @@ void BlenderModifier_Mirror :: DoIt(aiNode& out, ConversionData& conv_data, co
const float vs = mir.flag & MirrorModifierData::Flags_MIRROR_V ? -1.f : 1.f; const float vs = mir.flag & MirrorModifierData::Flags_MIRROR_V ? -1.f : 1.f;
for (unsigned int n = 0; mesh->HasTextureCoords(n); ++n) { for (unsigned int n = 0; mesh->HasTextureCoords(n); ++n) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { for (unsigned int j = 0; j < mesh->mNumVertices; ++j) {
aiVector3D& v = mesh->mTextureCoords[n][i]; aiVector3D &v = mesh->mTextureCoords[n][j];
v.x *= us;v.y *= vs; v.x *= us;
v.y *= vs;
} }
} }
// Only reverse the winding order if an odd number of axes were mirrored. // Only reverse the winding order if an odd number of axes were mirrored.
if (xs * ys * zs < 0) { if (xs * ys * zs < 0) {
for( unsigned int i = 0; i < mesh->mNumFaces; i++) { for (unsigned int j = 0; j < mesh->mNumFaces; ++j ) {
aiFace& face = mesh->mFaces[i]; aiFace &face = mesh->mFaces[j];
for (unsigned int fi = 0; fi < face.mNumIndices / 2; ++fi) for (unsigned int fi = 0; fi < face.mNumIndices / 2; ++fi)
std::swap(face.mIndices[fi], face.mIndices[face.mNumIndices - 1 - fi]); std::swap(face.mIndices[fi], face.mIndices[face.mNumIndices - 1 - fi]);
} }
@ -250,23 +253,20 @@ void BlenderModifier_Mirror :: DoIt(aiNode& out, ConversionData& conv_data, co
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool BlenderModifier_Subdivision :: IsActive (const ModifierData& modin) bool BlenderModifier_Subdivision ::IsActive(const ModifierData &modin) {
{
return modin.type == ModifierData::eModifierType_Subsurf; return modin.type == ModifierData::eModifierType_Subsurf;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderModifier_Subdivision ::DoIt(aiNode &out, ConversionData &conv_data, const ElemBase &orig_modifier, void BlenderModifier_Subdivision ::DoIt(aiNode &out, ConversionData &conv_data, const ElemBase &orig_modifier,
const Scene & /*in*/, const Scene & /*in*/,
const Object& orig_object ) const Object &orig_object) {
{
// hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers() // hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers()
const SubsurfModifierData &mir = static_cast<const SubsurfModifierData &>(orig_modifier); const SubsurfModifierData &mir = static_cast<const SubsurfModifierData &>(orig_modifier);
ai_assert(mir.modifier.type == ModifierData::eModifierType_Subsurf); ai_assert(mir.modifier.type == ModifierData::eModifierType_Subsurf);
Subdivider::Algorithm algo; Subdivider::Algorithm algo;
switch (mir.subdivType) switch (mir.subdivType) {
{
case SubsurfModifierData::TYPE_CatmullClarke: case SubsurfModifierData::TYPE_CatmullClarke:
algo = Subdivider::CATMULL_CLARKE; algo = Subdivider::CATMULL_CLARKE;
break; break;

View File

@ -861,15 +861,15 @@ if ((CMAKE_COMPILER_IS_MINGW) AND (CMAKE_BUILD_TYPE MATCHES Debug))
SET_SOURCE_FILES_PROPERTIES(Importer/StepFile/StepFileGen1.cpp PROPERTIES STATIC_LIBRARY_FLAGS -Os ) SET_SOURCE_FILES_PROPERTIES(Importer/StepFile/StepFileGen1.cpp PROPERTIES STATIC_LIBRARY_FLAGS -Os )
endif() endif()
ADD_ASSIMP_IMPORTER( STEP #ADD_ASSIMP_IMPORTER( STEP
Step/STEPFile.h # Step/STEPFile.h
Importer/StepFile/StepFileImporter.h # Importer/StepFile/StepFileImporter.h
Importer/StepFile/StepFileImporter.cpp # Importer/StepFile/StepFileImporter.cpp
Importer/StepFile/StepFileGen1.cpp # Importer/StepFile/StepFileGen1.cpp
Importer/StepFile/StepFileGen2.cpp # Importer/StepFile/StepFileGen2.cpp
Importer/StepFile/StepFileGen3.cpp # Importer/StepFile/StepFileGen3.cpp
Importer/StepFile/StepReaderGen.h # Importer/StepFile/StepReaderGen.h
) #)
if ((NOT ASSIMP_NO_EXPORT) OR (NOT ASSIMP_EXPORTERS_ENABLED STREQUAL "")) if ((NOT ASSIMP_NO_EXPORT) OR (NOT ASSIMP_EXPORTERS_ENABLED STREQUAL ""))
SET( Exporter_SRCS SET( Exporter_SRCS

View File

@ -1015,8 +1015,8 @@ void COBImporter::ReadPolH_Binary(COB::Scene& out, StreamReaderLE& reader, const
// XXX backface culling flag is 0x10 in flags // XXX backface culling flag is 0x10 in flags
// hole? // hole?
bool hole; bool hole = (reader.GetI1() & 0x08) != 0;
if ((hole = (reader.GetI1() & 0x08) != 0)) { if ( hole ) {
// XXX Basically this should just work fine - then triangulator // XXX Basically this should just work fine - then triangulator
// should output properly triangulated data even for polygons // should output properly triangulated data even for polygons
// with holes. Test data specific to COB is needed to confirm it. // with holes. Test data specific to COB is needed to confirm it.

View File

@ -75,10 +75,10 @@ struct Face
// ------------------ // ------------------
/** COB chunk header information */ /** COB chunk header information */
const unsigned int NO_SIZE = UINT_MAX;
struct ChunkInfo struct ChunkInfo
{ {
enum {NO_SIZE=UINT_MAX};
ChunkInfo () ChunkInfo ()
: id (0) : id (0)
, parent_id (0) , parent_id (0)

View File

@ -1335,32 +1335,34 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
mOutput << startstr << "<animation id=\"" + idstrEscaped + "\" name=\"" + animation_name_escaped + "\">" << endstr; mOutput << startstr << "<animation id=\"" + idstrEscaped + "\" name=\"" + animation_name_escaped + "\">" << endstr;
PushTag(); PushTag();
std::string node_idstr; std::string cur_node_idstr;
for (size_t a = 0; a < anim->mNumChannels; ++a) { for (size_t a = 0; a < anim->mNumChannels; ++a) {
const aiNodeAnim * nodeAnim = anim->mChannels[a]; const aiNodeAnim * nodeAnim = anim->mChannels[a];
// sanity check // sanity check
if ( nodeAnim->mNumPositionKeys != nodeAnim->mNumScalingKeys || nodeAnim->mNumPositionKeys != nodeAnim->mNumRotationKeys ) continue; if (nodeAnim->mNumPositionKeys != nodeAnim->mNumScalingKeys || nodeAnim->mNumPositionKeys != nodeAnim->mNumRotationKeys) {
continue;
}
{ {
node_idstr.clear(); cur_node_idstr.clear();
node_idstr += nodeAnim->mNodeName.data; cur_node_idstr += nodeAnim->mNodeName.data;
node_idstr += std::string( "_matrix-input" ); cur_node_idstr += std::string("_matrix-input");
std::vector<ai_real> frames; std::vector<ai_real> frames;
for( size_t i = 0; i < nodeAnim->mNumPositionKeys; ++i) { for( size_t i = 0; i < nodeAnim->mNumPositionKeys; ++i) {
frames.push_back(static_cast<ai_real>(nodeAnim->mPositionKeys[i].mTime)); frames.push_back(static_cast<ai_real>(nodeAnim->mPositionKeys[i].mTime));
} }
WriteFloatArray( node_idstr , FloatType_Time, (const ai_real*) frames.data(), frames.size()); WriteFloatArray(cur_node_idstr, FloatType_Time, (const ai_real *)frames.data(), frames.size());
frames.clear(); frames.clear();
} }
{ {
node_idstr.clear(); cur_node_idstr.clear();
node_idstr += nodeAnim->mNodeName.data; cur_node_idstr += nodeAnim->mNodeName.data;
node_idstr += std::string("_matrix-output"); cur_node_idstr += std::string("_matrix-output");
std::vector<ai_real> keyframes; std::vector<ai_real> keyframes;
keyframes.reserve(nodeAnim->mNumPositionKeys * 16); keyframes.reserve(nodeAnim->mNumPositionKeys * 16);
@ -1385,7 +1387,7 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
} }
} }
WriteFloatArray( node_idstr, FloatType_Mat4x4, (const ai_real*) keyframes.data(), keyframes.size() / 16); WriteFloatArray(cur_node_idstr, FloatType_Mat4x4, (const ai_real *)keyframes.data(), keyframes.size() / 16);
} }
{ {
@ -1401,16 +1403,16 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
} }
} }
const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-interpolation"); const std::string cur_node_idstr2 = nodeAnim->mNodeName.data + std::string("_matrix-interpolation");
std::string arrayId = XMLIDEncode(node_idstr) + "-array"; std::string arrayId = XMLIDEncode(cur_node_idstr2) + "-array";
mOutput << startstr << "<source id=\"" << XMLIDEncode(node_idstr) << "\">" << endstr; mOutput << startstr << "<source id=\"" << XMLIDEncode(cur_node_idstr2) << "\">" << endstr;
PushTag(); PushTag();
// source array // source array
mOutput << startstr << "<Name_array id=\"" << arrayId << "\" count=\"" << names.size() << "\"> "; mOutput << startstr << "<Name_array id=\"" << arrayId << "\" count=\"" << names.size() << "\"> ";
for( size_t a = 0; a < names.size(); ++a ) { for( size_t aa = 0; aa < names.size(); ++aa ) {
mOutput << names[a] << " "; mOutput << names[aa] << " ";
} }
mOutput << "</Name_array>" << endstr; mOutput << "</Name_array>" << endstr;
@ -1672,13 +1674,13 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
PushTag(); PushTag();
mOutput << startstr << "<instance_material symbol=\"defaultMaterial\" target=\"#" << XMLIDEncode(materials[mesh->mMaterialIndex].name) << "\">" << endstr; mOutput << startstr << "<instance_material symbol=\"defaultMaterial\" target=\"#" << XMLIDEncode(materials[mesh->mMaterialIndex].name) << "\">" << endstr;
PushTag(); PushTag();
for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a ) for( size_t aa = 0; aa < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++aa )
{ {
if( mesh->HasTextureCoords( static_cast<unsigned int>(a) ) ) if( mesh->HasTextureCoords( static_cast<unsigned int>(aa) ) )
// semantic as in <texture texcoord=...> // semantic as in <texture texcoord=...>
// input_semantic as in <input semantic=...> // input_semantic as in <input semantic=...>
// input_set as in <input set=...> // input_set as in <input set=...>
mOutput << startstr << "<bind_vertex_input semantic=\"CHANNEL" << a << "\" input_semantic=\"TEXCOORD\" input_set=\"" << a << "\"/>" << endstr; mOutput << startstr << "<bind_vertex_input semantic=\"CHANNEL" << aa << "\" input_semantic=\"TEXCOORD\" input_set=\"" << aa << "\"/>" << endstr;
} }
PopTag(); PopTag();
mOutput << startstr << "</instance_material>" << endstr; mOutput << startstr << "</instance_material>" << endstr;

View File

@ -714,8 +714,8 @@ void ColladaParser::ReadAnimation(Collada::Animation* pParent)
else if (IsElement("sampler")) else if (IsElement("sampler"))
{ {
// read the ID to assign the corresponding collada channel afterwards. // read the ID to assign the corresponding collada channel afterwards.
int indexID = GetAttribute("id"); int indexId = GetAttribute("id");
std::string id = mReader->getAttributeValue(indexID); std::string id = mReader->getAttributeValue(indexId);
ChannelMap::iterator newChannel = channels.insert(std::make_pair(id, AnimationChannel())).first; ChannelMap::iterator newChannel = channels.insert(std::make_pair(id, AnimationChannel())).first;
// have it read into a channel // have it read into a channel
@ -3339,13 +3339,12 @@ void ColladaParser::TestClosing(const char* pName) {
// Returns the index of the named attribute or -1 if not found. Does not throw, therefore useful for optional attributes // Returns the index of the named attribute or -1 if not found. Does not throw, therefore useful for optional attributes
int ColladaParser::GetAttribute(const char* pAttr) const { int ColladaParser::GetAttribute(const char* pAttr) const {
int index = TestAttribute(pAttr); int index = TestAttribute(pAttr);
if (index != -1) { if (index == -1) {
return index; ThrowException(format() << "Expected attribute \"" << pAttr << "\" for element <" << mReader->getNodeName() << ">.");
} }
// attribute not found -> throw an exception // attribute not found -> throw an exception
ThrowException(format() << "Expected attribute \"" << pAttr << "\" for element <" << mReader->getNodeName() << ">."); return index;
return -1;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -146,7 +146,7 @@ aiScene* BaseImporter::ReadFile(Importer* pImp, const std::string& pFile, IOSyst
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BaseImporter::SetupProperties(const Importer* pImp) void BaseImporter::SetupProperties(const Importer* )
{ {
// the default implementation does nothing // the default implementation does nothing
} }

View File

@ -70,7 +70,7 @@ namespace
template<> template<>
size_t select_ftell<8>(FILE* file) size_t select_ftell<8>(FILE* file)
{ {
return ::_ftelli64(file); return (size_t)::_ftelli64(file);
} }
template<> template<>

View File

@ -44,15 +44,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/StringComparison.h> #include <assimp/StringComparison.h>
#include <assimp/DefaultIOSystem.h>
#include <assimp/DefaultIOStream.h> #include <assimp/DefaultIOStream.h>
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultIOSystem.h>
#include <assimp/ai_assert.h> #include <assimp/ai_assert.h>
#include <stdlib.h> #include <stdlib.h>
#include <assimp/DefaultLogger.hpp>
#ifdef __unix__ #ifdef __unix__
#include <sys/param.h>
# include <stdlib.h> # include <stdlib.h>
# include <sys/param.h>
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
@ -62,8 +62,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
#ifdef _WIN32 #ifdef _WIN32
static std::wstring Utf8ToWide(const char* in) static std::wstring Utf8ToWide(const char *in) {
{
int size = MultiByteToWideChar(CP_UTF8, 0, in, -1, nullptr, 0); int size = MultiByteToWideChar(CP_UTF8, 0, in, -1, nullptr, 0);
// size includes terminating null; std::wstring adds null automatically // size includes terminating null; std::wstring adds null automatically
std::wstring out(static_cast<size_t>(size) - 1, L'\0'); std::wstring out(static_cast<size_t>(size) - 1, L'\0');
@ -71,8 +70,7 @@ static std::wstring Utf8ToWide(const char* in)
return out; return out;
} }
static std::string WideToUtf8(const wchar_t* in) static std::string WideToUtf8(const wchar_t *in) {
{
int size = WideCharToMultiByte(CP_UTF8, 0, in, -1, nullptr, 0, nullptr, nullptr); int size = WideCharToMultiByte(CP_UTF8, 0, in, -1, nullptr, 0, nullptr, nullptr);
// size includes terminating null; std::string adds null automatically // size includes terminating null; std::string adds null automatically
std::string out(static_cast<size_t>(size) - 1, '\0'); std::string out(static_cast<size_t>(size) - 1, '\0');
@ -83,8 +81,7 @@ static std::string WideToUtf8(const wchar_t* in)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Tests for the existence of a file at the given path. // Tests for the existence of a file at the given path.
bool DefaultIOSystem::Exists(const char* pFile) const bool DefaultIOSystem::Exists(const char *pFile) const {
{
#ifdef _WIN32 #ifdef _WIN32
struct __stat64 filestat; struct __stat64 filestat;
if (_wstat64(Utf8ToWide(pFile).c_str(), &filestat) != 0) { if (_wstat64(Utf8ToWide(pFile).c_str(), &filestat) != 0) {
@ -92,18 +89,19 @@ bool DefaultIOSystem::Exists(const char* pFile) const
} }
#else #else
FILE *file = ::fopen(pFile, "rb"); FILE *file = ::fopen(pFile, "rb");
if (!file) if (!file) {
return false; return false;
}
::fclose(file); ::fclose(file);
#endif #endif
return true; return true;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Open a new file with a given path. // Open a new file with a given path.
IOStream* DefaultIOSystem::Open(const char* strFile, const char* strMode) IOStream *DefaultIOSystem::Open(const char *strFile, const char *strMode) {
{
ai_assert(strFile != nullptr); ai_assert(strFile != nullptr);
ai_assert(strMode != nullptr); ai_assert(strMode != nullptr);
FILE *file; FILE *file;
@ -112,23 +110,22 @@ IOStream* DefaultIOSystem::Open(const char* strFile, const char* strMode)
#else #else
file = ::fopen(strFile, strMode); file = ::fopen(strFile, strMode);
#endif #endif
if (!file) if (!file) {
return nullptr; return nullptr;
}
return new DefaultIOStream(file, strFile); return new DefaultIOStream(file, strFile);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Closes the given file and releases all resources associated with it. // Closes the given file and releases all resources associated with it.
void DefaultIOSystem::Close(IOStream* pFile) void DefaultIOSystem::Close(IOStream *pFile) {
{
delete pFile; delete pFile;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns the operation specific directory separator // Returns the operation specific directory separator
char DefaultIOSystem::getOsSeparator() const char DefaultIOSystem::getOsSeparator() const {
{
#ifndef _WIN32 #ifndef _WIN32
return '/'; return '/';
#else #else
@ -138,15 +135,13 @@ char DefaultIOSystem::getOsSeparator() const
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// IOSystem default implementation (ComparePaths isn't a pure virtual function) // IOSystem default implementation (ComparePaths isn't a pure virtual function)
bool IOSystem::ComparePaths(const char* one, const char* second) const bool IOSystem::ComparePaths(const char *one, const char *second) const {
{
return !ASSIMP_stricmp(one, second); return !ASSIMP_stricmp(one, second);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Convert a relative path into an absolute path // Convert a relative path into an absolute path
inline static std::string MakeAbsolutePath(const char* in) inline static std::string MakeAbsolutePath(const char *in) {
{
ai_assert(in); ai_assert(in);
std::string out; std::string out;
#ifdef _WIN32 #ifdef _WIN32
@ -173,8 +168,7 @@ inline static std::string MakeAbsolutePath(const char* in)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// DefaultIOSystem's more specialized implementation // DefaultIOSystem's more specialized implementation
bool DefaultIOSystem::ComparePaths(const char* one, const char* second) const bool DefaultIOSystem::ComparePaths(const char *one, const char *second) const {
{
// chances are quite good both paths are formatted identically, // chances are quite good both paths are formatted identically,
// so we can hopefully return here already // so we can hopefully return here already
if (!ASSIMP_stricmp(one, second)) if (!ASSIMP_stricmp(one, second))
@ -187,8 +181,7 @@ bool DefaultIOSystem::ComparePaths(const char* one, const char* second) const
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
std::string DefaultIOSystem::fileName(const std::string& path) std::string DefaultIOSystem::fileName(const std::string &path) {
{
std::string ret = path; std::string ret = path;
std::size_t last = ret.find_last_of("\\/"); std::size_t last = ret.find_last_of("\\/");
if (last != std::string::npos) ret = ret.substr(last + 1); if (last != std::string::npos) ret = ret.substr(last + 1);
@ -196,8 +189,7 @@ std::string DefaultIOSystem::fileName(const std::string& path)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
std::string DefaultIOSystem::completeBaseName(const std::string& path) std::string DefaultIOSystem::completeBaseName(const std::string &path) {
{
std::string ret = fileName(path); std::string ret = fileName(path);
std::size_t pos = ret.find_last_of('.'); std::size_t pos = ret.find_last_of('.');
if (pos != std::string::npos) ret = ret.substr(0, pos); if (pos != std::string::npos) ret = ret.substr(0, pos);
@ -205,8 +197,7 @@ std::string DefaultIOSystem::completeBaseName(const std::string& path)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
std::string DefaultIOSystem::absolutePath(const std::string& path) std::string DefaultIOSystem::absolutePath(const std::string &path) {
{
std::string ret = path; std::string ret = path;
std::size_t last = ret.find_last_of("\\/"); std::size_t last = ret.find_last_of("\\/");
if (last != std::string::npos) ret = ret.substr(0, last); if (last != std::string::npos) ret = ret.substr(0, last);

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -76,6 +74,11 @@ Here we implement only the C++ interface (Assimp::Exporter).
namespace Assimp { namespace Assimp {
#ifdef _WIN32
# pragma warning( disable : 4800 )
#endif // _WIN32
// PostStepRegistry.cpp // PostStepRegistry.cpp
void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out); void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out);

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -200,9 +198,9 @@ corresponding preprocessor flag to selectively disable formats.
#ifndef ASSIMP_BUILD_NO_M3D_IMPORTER #ifndef ASSIMP_BUILD_NO_M3D_IMPORTER
# include "M3D/M3DImporter.h" # include "M3D/M3DImporter.h"
#endif #endif
#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER //#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER
# include "Importer/StepFile/StepFileImporter.h" //# include "Importer/StepFile/StepFileImporter.h"
#endif //#endif
namespace Assimp { namespace Assimp {
@ -361,9 +359,9 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out)
#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER #ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
out.push_back( new MMDImporter() ); out.push_back( new MMDImporter() );
#endif #endif
#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER //#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER
out.push_back(new StepFile::StepFileImporter()); // out.push_back(new StepFile::StepFileImporter());
#endif //#endif
} }
/** will delete all registered importers. */ /** will delete all registered importers. */

View File

@ -53,6 +53,10 @@ using namespace Assimp;
# define CHAR_BIT 8 # define CHAR_BIT 8
#endif #endif
#ifdef _WIN32
# pragma warning(disable : 4127)
#endif // _WIN32
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructs a spatially sorted representation from the given position array. // Constructs a spatially sorted representation from the given position array.
SpatialSort::SpatialSort( const aiVector3D* pPositions, unsigned int pNumPositions, SpatialSort::SpatialSort( const aiVector3D* pPositions, unsigned int pNumPositions,

View File

@ -53,6 +53,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
void mydummy() {} void mydummy() {}
#ifdef _WIN32
# pragma warning( disable : 4709 )
#endif // _WIN32
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
/** Subdivider stub class to implement the Catmull-Clarke subdivision algorithm. The /** Subdivider stub class to implement the Catmull-Clarke subdivision algorithm. The
* implementation is basing on recursive refinement. Directly evaluating the result is also * implementation is basing on recursive refinement. Directly evaluating the result is also

View File

@ -42,9 +42,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Actually just a dummy, used by the compiler to build the precompiled header. // Actually just a dummy, used by the compiler to build the precompiled header.
#include <assimp/version.h>
#include <assimp/scene.h>
#include "ScenePrivate.h" #include "ScenePrivate.h"
#include <assimp/scene.h>
#include <assimp/version.h>
#include "revision.h" #include "revision.h"
@ -57,8 +57,7 @@ static const char* LEGAL_INFORMATION =
"(c) 2006-2020, assimp team\n" "(c) 2006-2020, assimp team\n"
"License under the terms and conditions of the 3-clause BSD license\n" "License under the terms and conditions of the 3-clause BSD license\n"
"http://assimp.org\n" "http://assimp.org\n";
;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get legal string // Get legal string
@ -119,23 +118,8 @@ ASSIMP_API const char *aiGetBranchName() {
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
ASSIMP_API aiScene::aiScene() ASSIMP_API aiScene::aiScene() :
: mFlags(0) mFlags(0), mRootNode(nullptr), mNumMeshes(0), mMeshes(nullptr), mNumMaterials(0), mMaterials(nullptr), mNumAnimations(0), mAnimations(nullptr), mNumTextures(0), mTextures(nullptr), mNumLights(0), mLights(nullptr), mNumCameras(0), mCameras(nullptr), mMetaData(nullptr), mPrivate(new Assimp::ScenePrivateData()) {
, mRootNode(nullptr)
, mNumMeshes(0)
, mMeshes(nullptr)
, mNumMaterials(0)
, mMaterials(nullptr)
, mNumAnimations(0)
, mAnimations(nullptr)
, mNumTextures(0)
, mTextures(nullptr)
, mNumLights(0)
, mLights(nullptr)
, mNumCameras(0)
, mCameras(nullptr)
, mMetaData(nullptr)
, mPrivate(new Assimp::ScenePrivateData()) {
// empty // empty
} }
@ -184,4 +168,3 @@ ASSIMP_API aiScene::~aiScene() {
delete static_cast<Assimp::ScenePrivateData *>(mPrivate); delete static_cast<Assimp::ScenePrivateData *>(mPrivate);
} }

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -44,8 +43,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Zip File I/O implementation for #Importer * @brief Zip File I/O implementation for #Importer
*/ */
#include <assimp/ZipArchiveIOSystem.h>
#include <assimp/BaseImporter.h> #include <assimp/BaseImporter.h>
#include <assimp/ZipArchiveIOSystem.h>
#include <assimp/ai_assert.h> #include <assimp/ai_assert.h>
@ -59,6 +58,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif #endif
namespace Assimp { namespace Assimp {
// ---------------------------------------------------------------- // ----------------------------------------------------------------
// Wraps an existing Assimp::IOSystem for unzip // Wraps an existing Assimp::IOSystem for unzip
class IOSystem2Unzip { class IOSystem2Unzip {
@ -79,12 +79,10 @@ namespace Assimp {
const char *mode_fopen = nullptr; const char *mode_fopen = nullptr;
if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ) { if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ) {
mode_fopen = "rb"; mode_fopen = "rb";
} } else {
else {
if (mode & ZLIB_FILEFUNC_MODE_EXISTING) { if (mode & ZLIB_FILEFUNC_MODE_EXISTING) {
mode_fopen = "r+b"; mode_fopen = "r+b";
} } else {
else {
if (mode & ZLIB_FILEFUNC_MODE_CREATE) { if (mode & ZLIB_FILEFUNC_MODE_CREATE) {
mode_fopen = "wb"; mode_fopen = "wb";
} }
@ -176,6 +174,7 @@ namespace Assimp {
class ZipFile : public IOStream { class ZipFile : public IOStream {
friend class ZipFileInfo; friend class ZipFileInfo;
explicit ZipFile(size_t size); explicit ZipFile(size_t size);
public: public:
virtual ~ZipFile(); virtual ~ZipFile();
@ -193,11 +192,9 @@ namespace Assimp {
std::unique_ptr<uint8_t[]> m_Buffer; std::unique_ptr<uint8_t[]> m_Buffer;
}; };
// ---------------------------------------------------------------- // ----------------------------------------------------------------
// Info about a read-only file inside a ZIP // Info about a read-only file inside a ZIP
class ZipFileInfo class ZipFileInfo {
{
public: public:
explicit ZipFileInfo(unzFile zip_handle, size_t size); explicit ZipFileInfo(unzFile zip_handle, size_t size);
@ -209,8 +206,8 @@ namespace Assimp {
unz_file_pos_s m_ZipFilePos; unz_file_pos_s m_ZipFilePos;
}; };
ZipFileInfo::ZipFileInfo(unzFile zip_handle, size_t size) ZipFileInfo::ZipFileInfo(unzFile zip_handle, size_t size) :
: m_Size(size) { m_Size(size) {
ai_assert(m_Size != 0); ai_assert(m_Size != 0);
// Workaround for MSVC 2013 - C2797 // Workaround for MSVC 2013 - C2797
m_ZipFilePos.num_of_file = 0; m_ZipFilePos.num_of_file = 0;
@ -229,8 +226,7 @@ namespace Assimp {
ZipFile *zip_file = new ZipFile(m_Size); ZipFile *zip_file = new ZipFile(m_Size);
if (unzReadCurrentFile(zip_handle, zip_file->m_Buffer.get(), static_cast<unsigned int>(m_Size)) != static_cast<int>(m_Size)) if (unzReadCurrentFile(zip_handle, zip_file->m_Buffer.get(), static_cast<unsigned int>(m_Size)) != static_cast<int>(m_Size)) {
{
// Failed, release the memory // Failed, release the memory
delete zip_file; delete zip_file;
zip_file = nullptr; zip_file = nullptr;
@ -240,8 +236,8 @@ namespace Assimp {
return zip_file; return zip_file;
} }
ZipFile::ZipFile(size_t size) ZipFile::ZipFile(size_t size) :
: m_Size(size) { m_Size(size) {
ai_assert(m_Size != 0); ai_assert(m_Size != 0);
m_Buffer = std::unique_ptr<uint8_t[]>(new uint8_t[m_Size]); m_Buffer = std::unique_ptr<uint8_t[]>(new uint8_t[m_Size]);
} }
@ -256,8 +252,7 @@ namespace Assimp {
// Clip down to file size // Clip down to file size
size_t byteSize = pSize * pCount; size_t byteSize = pSize * pCount;
if ((byteSize + m_SeekPtr) > m_Size) if ((byteSize + m_SeekPtr) > m_Size) {
{
pCount = (m_Size - m_SeekPtr) / pSize; pCount = (m_Size - m_SeekPtr) / pSize;
byteSize = pSize * pCount; byteSize = pSize * pCount;
if (byteSize == 0) if (byteSize == 0)
@ -276,8 +271,7 @@ namespace Assimp {
} }
aiReturn ZipFile::Seek(size_t pOffset, aiOrigin pOrigin) { aiReturn ZipFile::Seek(size_t pOffset, aiOrigin pOrigin) {
switch (pOrigin) switch (pOrigin) {
{
case aiOrigin_SET: { case aiOrigin_SET: {
if (pOffset > m_Size) return aiReturn_FAILURE; if (pOffset > m_Size) return aiReturn_FAILURE;
m_SeekPtr = pOffset; m_SeekPtr = pOffset;
@ -335,8 +329,9 @@ namespace Assimp {
ZipArchiveIOSystem::Implement::Implement(IOSystem *pIOHandler, const char *pFilename, const char *pMode) { ZipArchiveIOSystem::Implement::Implement(IOSystem *pIOHandler, const char *pFilename, const char *pMode) {
ai_assert(strcmp(pMode, "r") == 0); ai_assert(strcmp(pMode, "r") == 0);
ai_assert(pFilename != nullptr); ai_assert(pFilename != nullptr);
if (pFilename[0] == 0) if (pFilename[0] == 0 || nullptr == pMode) {
return; return;
}
zlib_filefunc_def mapping = IOSystem2Unzip::get(pIOHandler); zlib_filefunc_def mapping = IOSystem2Unzip::get(pIOHandler);
m_ZipFileHandle = unzOpen2(pFilename, &mapping); m_ZipFileHandle = unzOpen2(pFilename, &mapping);
@ -421,8 +416,7 @@ namespace Assimp {
inline void ReplaceAll(std::string &data, const std::string &before, const std::string &after) { inline void ReplaceAll(std::string &data, const std::string &before, const std::string &after) {
size_t pos = data.find(before); size_t pos = data.find(before);
while (pos != std::string::npos) while (pos != std::string::npos) {
{
data.replace(pos, before.size(), after); data.replace(pos, before.size(), after);
pos = data.find(before, pos + after.size()); pos = data.find(before, pos + after.size());
} }
@ -430,15 +424,13 @@ namespace Assimp {
inline void ReplaceAllChar(std::string &data, const char before, const char after) { inline void ReplaceAllChar(std::string &data, const char before, const char after) {
size_t pos = data.find(before); size_t pos = data.find(before);
while (pos != std::string::npos) while (pos != std::string::npos) {
{
data[pos] = after; data[pos] = after;
pos = data.find(before, pos + 1); pos = data.find(before, pos + 1);
} }
} }
void ZipArchiveIOSystem::Implement::SimplifyFilename(std::string& filename) void ZipArchiveIOSystem::Implement::SimplifyFilename(std::string &filename) {
{
ReplaceAllChar(filename, '\\', '/'); ReplaceAllChar(filename, '\\', '/');
// Remove all . and / from the beginning of the path // Remove all . and / from the beginning of the path
@ -450,8 +442,7 @@ namespace Assimp {
static const std::string relative("/../"); static const std::string relative("/../");
const size_t relsize = relative.size() - 1; const size_t relsize = relative.size() - 1;
pos = filename.find(relative); pos = filename.find(relative);
while (pos != std::string::npos) while (pos != std::string::npos) {
{
// Previous slash // Previous slash
size_t prevpos = filename.rfind('/', pos - 1); size_t prevpos = filename.rfind('/', pos - 1);
if (prevpos == pos) if (prevpos == pos)
@ -463,15 +454,14 @@ namespace Assimp {
} }
} }
ZipArchiveIOSystem::ZipArchiveIOSystem(IOSystem* pIOHandler, const char* pFilename, const char* pMode) ZipArchiveIOSystem::ZipArchiveIOSystem(IOSystem *pIOHandler, const char *pFilename, const char *pMode) :
: pImpl(new Implement(pIOHandler, pFilename, pMode)) { pImpl(new Implement(pIOHandler, pFilename, pMode)) {
} }
// ---------------------------------------------------------------- // ----------------------------------------------------------------
// The ZipArchiveIO // The ZipArchiveIO
ZipArchiveIOSystem::ZipArchiveIOSystem(IOSystem* pIOHandler, const std::string& rFilename, const char* pMode) ZipArchiveIOSystem::ZipArchiveIOSystem(IOSystem *pIOHandler, const std::string &rFilename, const char *pMode) :
: pImpl(new Implement(pIOHandler, rFilename.c_str(), pMode)) pImpl(new Implement(pIOHandler, rFilename.c_str(), pMode)) {
{
} }
ZipArchiveIOSystem::~ZipArchiveIOSystem() { ZipArchiveIOSystem::~ZipArchiveIOSystem() {
@ -498,8 +488,7 @@ namespace Assimp {
IOStream *ZipArchiveIOSystem::Open(const char *pFilename, const char *pMode) { IOStream *ZipArchiveIOSystem::Open(const char *pFilename, const char *pMode) {
ai_assert(pFilename != nullptr); ai_assert(pFilename != nullptr);
for (size_t i = 0; pMode[i] != 0; ++i) for (size_t i = 0; pMode[i] != 0; ++i) {
{
ai_assert(pMode[i] != 'w'); ai_assert(pMode[i] != 'w');
if (pMode[i] == 'w') if (pMode[i] == 'w')
return nullptr; return nullptr;
@ -534,4 +523,4 @@ namespace Assimp {
return isZipArchive(pIOHandler, rFilename.c_str()); return isZipArchive(pIOHandler, rFilename.c_str());
} }
} } // namespace Assimp

View File

@ -48,8 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_FBX_EXPORTER #ifndef ASSIMP_BUILD_NO_FBX_EXPORTER
namespace Assimp { namespace Assimp {
namespace FBX namespace FBX {
{
const std::string NULL_RECORD = { // 25 null bytes in 64-bit and 13 null bytes in 32-bit const std::string NULL_RECORD = { // 25 null bytes in 64-bit and 13 null bytes in 32-bit
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
@ -80,8 +80,8 @@ namespace FBX
TransformInheritance_MAX // end-of-enum sentinel TransformInheritance_MAX // end-of-enum sentinel
}; };
} } // namespace FBX
} } // namespace Assimp
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER #endif // ASSIMP_BUILD_NO_FBX_EXPORTER
#endif // AI_FBXCOMMON_H_INC #endif // AI_FBXCOMMON_H_INC

File diff suppressed because it is too large Load Diff

View File

@ -189,8 +189,7 @@ private:
const aiMatrix4x4 &absolute_transform); const aiMatrix4x4 &absolute_transform);
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
std::vector<unsigned int> ConvertLine(const LineGeometry& line, const Model& model, std::vector<unsigned int> ConvertLine(const LineGeometry& line, aiNode *root_node);
aiNode *parent, aiNode *root_node);
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
aiMesh* SetupEmptyMesh(const Geometry& mesh, aiNode *parent); aiMesh* SetupEmptyMesh(const Geometry& mesh, aiNode *parent);
@ -220,17 +219,15 @@ private:
* - outputVertStartIndices is only used when a material index is specified, it gives for * - outputVertStartIndices is only used when a material index is specified, it gives for
* each output vertex the DOM index it maps to. * each output vertex the DOM index it maps to.
*/ */
void ConvertWeights(aiMesh *out, const Model &model, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform, void ConvertWeights(aiMesh *out, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform,
aiNode *parent = NULL, aiNode *root_node = NULL, aiNode *parent = NULL, unsigned int materialIndex = NO_MATERIAL_SEPARATION,
unsigned int materialIndex = NO_MATERIAL_SEPARATION,
std::vector<unsigned int> *outputVertStartIndices = NULL); std::vector<unsigned int> *outputVertStartIndices = NULL);
// lookup
static const aiNode* GetNodeByName( const aiString& name, aiNode *current_node );
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const Cluster *cl, void ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const Cluster *cl,
std::vector<size_t> &out_indices, std::vector<size_t> &index_out_indices, std::vector<size_t> &out_indices, std::vector<size_t> &index_out_indices,
std::vector<size_t> &count_out_indices, const aiMatrix4x4 &absolute_transform, std::vector<size_t> &count_out_indices, const aiMatrix4x4 &absolute_transform,
aiNode *parent, aiNode *root_node); aiNode *parent );
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertMaterialForMesh(aiMesh* out, const Model& model, const MeshGeometry& geo, void ConvertMaterialForMesh(aiMesh* out, const Model& model, const MeshGeometry& geo,
@ -437,7 +434,7 @@ private:
// 0: not assigned yet, others: index is value - 1 // 0: not assigned yet, others: index is value - 1
unsigned int defaultMaterialIndex; unsigned int defaultMaterialIndex;
std::vector<aiMesh*> meshes; std::vector<aiMesh*> mMeshes;
std::vector<aiMaterial*> materials; std::vector<aiMaterial*> materials;
std::vector<aiAnimation*> animations; std::vector<aiAnimation*> animations;
std::vector<aiLight*> lights; std::vector<aiLight*> lights;
@ -467,9 +464,9 @@ private:
double anim_fps; double anim_fps;
aiScene* const out; aiScene* const mSceneOut;
const FBX::Document& doc; const FBX::Document& doc;
bool mRemoveEmptyBones;
static void BuildBoneList(aiNode *current_node, const aiNode *root_node, const aiScene *scene, static void BuildBoneList(aiNode *current_node, const aiNode *root_node, const aiScene *scene,
std::vector<aiBone*>& bones); std::vector<aiBone*>& bones);

View File

@ -428,8 +428,8 @@ void Document::ReadPropertyTemplates()
const ElementCollection otypes = sdefs.GetCollection("ObjectType"); const ElementCollection otypes = sdefs.GetCollection("ObjectType");
for(ElementMap::const_iterator it = otypes.first; it != otypes.second; ++it) { for(ElementMap::const_iterator it = otypes.first; it != otypes.second; ++it) {
const Element& el = *(*it).second; const Element& el = *(*it).second;
const Scope* sc = el.Compound(); const Scope* curSc = el.Compound();
if(!sc) { if (!curSc) {
DOMWarning("expected nested scope in ObjectType, ignoring",&el); DOMWarning("expected nested scope in ObjectType, ignoring",&el);
continue; continue;
} }
@ -442,24 +442,24 @@ void Document::ReadPropertyTemplates()
const std::string& oname = ParseTokenAsString(*tok[0]); const std::string& oname = ParseTokenAsString(*tok[0]);
const ElementCollection templs = sc->GetCollection("PropertyTemplate"); const ElementCollection templs = curSc->GetCollection("PropertyTemplate");
for(ElementMap::const_iterator it = templs.first; it != templs.second; ++it) { for (ElementMap::const_iterator elemIt = templs.first; elemIt != templs.second; ++elemIt) {
const Element& el = *(*it).second; const Element &innerEl = *(*elemIt).second;
const Scope* sc = el.Compound(); const Scope *innerSc = innerEl.Compound();
if(!sc) { if (!innerSc) {
DOMWarning("expected nested scope in PropertyTemplate, ignoring",&el); DOMWarning("expected nested scope in PropertyTemplate, ignoring",&el);
continue; continue;
} }
const TokenList& tok = el.Tokens(); const TokenList &curTok = innerEl.Tokens();
if(tok.empty()) { if (curTok.empty()) {
DOMWarning("expected name for PropertyTemplate element, ignoring",&el); DOMWarning("expected name for PropertyTemplate element, ignoring",&el);
continue; continue;
} }
const std::string& pname = ParseTokenAsString(*tok[0]); const std::string &pname = ParseTokenAsString(*curTok[0]);
const Element* Properties70 = (*sc)["Properties70"]; const Element *Properties70 = (*innerSc)["Properties70"];
if(Properties70) { if(Properties70) {
std::shared_ptr<const PropertyTable> props = std::make_shared<const PropertyTable>( std::shared_ptr<const PropertyTable> props = std::make_shared<const PropertyTable>(
*Properties70,std::shared_ptr<const PropertyTable>(static_cast<const PropertyTable*>(NULL)) *Properties70,std::shared_ptr<const PropertyTable>(static_cast<const PropertyTable*>(NULL))
@ -529,8 +529,8 @@ const std::vector<const AnimationStack*>& Document::AnimationStacks() const
animationStacksResolved.reserve(animationStacks.size()); animationStacksResolved.reserve(animationStacks.size());
for(uint64_t id : animationStacks) { for(uint64_t id : animationStacks) {
LazyObject* const lazy = GetObject(id); LazyObject* const lazy = GetObject(id);
const AnimationStack* stack; const AnimationStack *stack = lazy->Get<AnimationStack>();
if(!lazy || !(stack = lazy->Get<AnimationStack>())) { if(!lazy || nullptr == stack ) {
DOMWarning("failed to read AnimationStack object"); DOMWarning("failed to read AnimationStack object");
continue; continue;
} }

View File

@ -62,90 +62,81 @@ namespace Assimp {
// so they are specified with an 'A' suffix. // so they are specified with an 'A' suffix.
void FBX::Node::AddP70int( void FBX::Node::AddP70int(
const std::string& name, int32_t value const std::string& cur_name, int32_t value
) { ) {
FBX::Node n("P"); FBX::Node n("P");
n.AddProperties(name, "int", "Integer", "", value); n.AddProperties(cur_name, "int", "Integer", "", value);
AddChild(n); AddChild(n);
} }
void FBX::Node::AddP70bool( void FBX::Node::AddP70bool(
const std::string& name, bool value const std::string& cur_name, bool value
) { ) {
FBX::Node n("P"); FBX::Node n("P");
n.AddProperties(name, "bool", "", "", int32_t(value)); n.AddProperties(cur_name, "bool", "", "", int32_t(value));
AddChild(n); AddChild(n);
} }
void FBX::Node::AddP70double( void FBX::Node::AddP70double(
const std::string& name, double value const std::string &cur_name, double value) {
) {
FBX::Node n("P"); FBX::Node n("P");
n.AddProperties(name, "double", "Number", "", value); n.AddProperties(cur_name, "double", "Number", "", value);
AddChild(n); AddChild(n);
} }
void FBX::Node::AddP70numberA( void FBX::Node::AddP70numberA(
const std::string& name, double value const std::string &cur_name, double value) {
) {
FBX::Node n("P"); FBX::Node n("P");
n.AddProperties(name, "Number", "", "A", value); n.AddProperties(cur_name, "Number", "", "A", value);
AddChild(n); AddChild(n);
} }
void FBX::Node::AddP70color( void FBX::Node::AddP70color(
const std::string& name, double r, double g, double b const std::string &cur_name, double r, double g, double b) {
) {
FBX::Node n("P"); FBX::Node n("P");
n.AddProperties(name, "ColorRGB", "Color", "", r, g, b); n.AddProperties(cur_name, "ColorRGB", "Color", "", r, g, b);
AddChild(n); AddChild(n);
} }
void FBX::Node::AddP70colorA( void FBX::Node::AddP70colorA(
const std::string& name, double r, double g, double b const std::string &cur_name, double r, double g, double b) {
) {
FBX::Node n("P"); FBX::Node n("P");
n.AddProperties(name, "Color", "", "A", r, g, b); n.AddProperties(cur_name, "Color", "", "A", r, g, b);
AddChild(n); AddChild(n);
} }
void FBX::Node::AddP70vector( void FBX::Node::AddP70vector(
const std::string& name, double x, double y, double z const std::string &cur_name, double x, double y, double z) {
) {
FBX::Node n("P"); FBX::Node n("P");
n.AddProperties(name, "Vector3D", "Vector", "", x, y, z); n.AddProperties(cur_name, "Vector3D", "Vector", "", x, y, z);
AddChild(n); AddChild(n);
} }
void FBX::Node::AddP70vectorA( void FBX::Node::AddP70vectorA(
const std::string& name, double x, double y, double z const std::string &cur_name, double x, double y, double z) {
) {
FBX::Node n("P"); FBX::Node n("P");
n.AddProperties(name, "Vector", "", "A", x, y, z); n.AddProperties(cur_name, "Vector", "", "A", x, y, z);
AddChild(n); AddChild(n);
} }
void FBX::Node::AddP70string( void FBX::Node::AddP70string(
const std::string& name, const std::string& value const std::string &cur_name, const std::string &value) {
) {
FBX::Node n("P"); FBX::Node n("P");
n.AddProperties(name, "KString", "", "", value); n.AddProperties(cur_name, "KString", "", "", value);
AddChild(n); AddChild(n);
} }
void FBX::Node::AddP70enum( void FBX::Node::AddP70enum(
const std::string& name, int32_t value const std::string &cur_name, int32_t value) {
) {
FBX::Node n("P"); FBX::Node n("P");
n.AddProperties(name, "enum", "", "", value); n.AddProperties(cur_name, "enum", "", "", value);
AddChild(n); AddChild(n);
} }
void FBX::Node::AddP70time( void FBX::Node::AddP70time(
const std::string& name, int64_t value const std::string &cur_name, int64_t value) {
) {
FBX::Node n("P"); FBX::Node n("P");
n.AddProperties(name, "KTime", "Time", "", value); n.AddProperties(cur_name, "KTime", "Time", "", value);
AddChild(n); AddChild(n);
} }

View File

@ -944,7 +944,9 @@ void FBXExporter::WriteDefinitions ()
FBX::Node defs("Definitions"); FBX::Node defs("Definitions");
defs.AddChild("Version", int32_t(100)); defs.AddChild("Version", int32_t(100));
defs.AddChild("Count", int32_t(total_count)); defs.AddChild("Count", int32_t(total_count));
for (auto &n : object_nodes) { defs.AddChild(n); } for (auto &on : object_nodes) {
defs.AddChild(on);
}
defs.Dump(outfile, binary, 0); defs.Dump(outfile, binary, 0);
} }
@ -1119,10 +1121,10 @@ void FBXExporter::WriteObjects ()
for (size_t fi = 0; fi < m->mNumFaces; ++fi) { for (size_t fi = 0; fi < m->mNumFaces; ++fi) {
const aiFace &f = m->mFaces[fi]; const aiFace &f = m->mFaces[fi];
for (size_t pvi = 0; pvi < f.mNumIndices; ++pvi) { for (size_t pvi = 0; pvi < f.mNumIndices; ++pvi) {
const aiVector3D &n = m->mNormals[f.mIndices[pvi]]; const aiVector3D &curN = m->mNormals[f.mIndices[pvi]];
normal_data.push_back(n.x); normal_data.push_back(curN.x);
normal_data.push_back(n.y); normal_data.push_back(curN.y);
normal_data.push_back(n.z); normal_data.push_back(curN.z);
} }
} }
FBX::Node::WritePropertyNode( FBX::Node::WritePropertyNode(
@ -1226,14 +1228,14 @@ void FBXExporter::WriteObjects ()
for (size_t fi = 0; fi < m->mNumFaces; ++fi) { for (size_t fi = 0; fi < m->mNumFaces; ++fi) {
const aiFace &f = m->mFaces[fi]; const aiFace &f = m->mFaces[fi];
for (size_t pvi = 0; pvi < f.mNumIndices; ++pvi) { for (size_t pvi = 0; pvi < f.mNumIndices; ++pvi) {
const aiVector3D &uv = const aiVector3D &curUv =
m->mTextureCoords[uvi][f.mIndices[pvi]]; m->mTextureCoords[uvi][f.mIndices[pvi]];
auto elem = index_by_uv.find(uv); auto elem = index_by_uv.find(curUv);
if (elem == index_by_uv.end()) { if (elem == index_by_uv.end()) {
index_by_uv[uv] = index; index_by_uv[curUv] = index;
uv_indices.push_back(index); uv_indices.push_back(index);
for (unsigned int x = 0; x < m->mNumUVComponents[uvi]; ++x) { for (unsigned int x = 0; x < m->mNumUVComponents[uvi]; ++x) {
uv_data.push_back(uv[x]); uv_data.push_back(curUv[x]);
} }
++index; ++index;
} else { } else {
@ -2246,7 +2248,7 @@ const std::map<std::string,std::pair<std::string,char>> transform_types = {
// write a single model node to the stream // write a single model node to the stream
void FBXExporter::WriteModelNode( void FBXExporter::WriteModelNode(
StreamWriterLE& outstream, StreamWriterLE& outstream,
bool binary, bool,
const aiNode* node, const aiNode* node,
int64_t node_uid, int64_t node_uid,
const std::string& type, const std::string& type,
@ -2299,16 +2301,13 @@ void FBXExporter::WriteModelNode(
err << item.first; err << item.first;
throw DeadlyExportError(err.str()); throw DeadlyExportError(err.str());
} }
const std::string &name = elem->second.first; const std::string &cur_name = elem->second.first;
const aiVector3D &v = item.second; const aiVector3D &v = item.second;
if (name.compare(0, 4, "Lcl ") == 0) { if (cur_name.compare(0, 4, "Lcl ") == 0) {
// special handling for animatable properties // special handling for animatable properties
p.AddP70( p.AddP70( cur_name, cur_name, "", "A", double(v.x), double(v.y), double(v.z) );
name, name, "", "A",
double(v.x), double(v.y), double(v.z)
);
} else { } else {
p.AddP70vector(name, v.x, v.y, v.z); p.AddP70vector(cur_name, v.x, v.y, v.z);
} }
} }
} }

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -53,6 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "FBXDocumentUtil.h" #include "FBXDocumentUtil.h"
#include "FBXProperties.h" #include "FBXProperties.h"
#include <assimp/ByteSwapper.h> #include <assimp/ByteSwapper.h>
#include <assimp/ParsingUtils.h>
#include <algorithm> // std::transform #include <algorithm> // std::transform
#include "FBXUtil.h" #include "FBXUtil.h"
@ -86,7 +86,7 @@ Material::Material(uint64_t id, const Element& element, const Document& doc, con
std::string templateName; std::string templateName;
// lower-case shading because Blender (for example) writes "Phong" // lower-case shading because Blender (for example) writes "Phong"
std::transform(shading.begin(), shading.end(), shading.begin(), ::tolower); std::transform(shading.begin(), shading.end(), shading.begin(), Assimp::ToLower<char>);
if(shading == "phong") { if(shading == "phong") {
templateName = "Material.FbxSurfacePhong"; templateName = "Material.FbxSurfacePhong";
} }

View File

@ -46,11 +46,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER #ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
#include "FBXParser.h"
#include "FBXMeshGeometry.h"
#include "FBXDocument.h" #include "FBXDocument.h"
#include "FBXImporter.h"
#include "FBXDocumentUtil.h" #include "FBXDocumentUtil.h"
#include "FBXImporter.h"
#include "FBXMeshGeometry.h"
#include "FBXParser.h"
namespace Assimp { namespace Assimp {
namespace FBX { namespace FBX {
@ -58,10 +58,8 @@ namespace FBX {
using namespace Util; using namespace Util;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Model::Model(uint64_t id, const Element& element, const Document& doc, const std::string& name) Model::Model(uint64_t id, const Element &element, const Document &doc, const std::string &name) :
: Object(id,element,name) Object(id, element, name), shading("Y") {
, shading("Y")
{
const Scope &sc = GetRequiredScope(element); const Scope &sc = GetRequiredScope(element);
const Element *const Shading = sc["Shading"]; const Element *const Shading = sc["Shading"];
const Element *const Culling = sc["Culling"]; const Element *const Culling = sc["Culling"];
@ -79,14 +77,11 @@ Model::Model(uint64_t id, const Element& element, const Document& doc, const std
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Model::~Model() Model::~Model() {
{
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Model::ResolveLinks(const Element& element, const Document& doc) void Model::ResolveLinks(const Element&, const Document &doc) {
{
const char *const arr[] = { "Geometry", "Material", "NodeAttribute" }; const char *const arr[] = { "Geometry", "Material", "NodeAttribute" };
// resolve material // resolve material
@ -132,8 +127,7 @@ void Model::ResolveLinks(const Element& element, const Document& doc)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool Model::IsNull() const bool Model::IsNull() const {
{
const std::vector<const NodeAttribute *> &attrs = GetAttributes(); const std::vector<const NodeAttribute *> &attrs = GetAttributes();
for (const NodeAttribute *att : attrs) { for (const NodeAttribute *att : attrs) {
@ -146,8 +140,7 @@ bool Model::IsNull() const
return false; return false;
} }
} // namespace FBX
} //!FBX } // namespace Assimp
} //!Assimp
#endif #endif

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -49,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdint.h> #include <stdint.h>
#include <map> #include <map>
#include <memory> #include <memory>
#include <vector>
#include <assimp/LogAux.h> #include <assimp/LogAux.h>
#include <assimp/fast_atof.h> #include <assimp/fast_atof.h>
@ -126,7 +126,7 @@ public:
const Element* operator[] (const std::string& index) const { const Element* operator[] (const std::string& index) const {
ElementMap::const_iterator it = elements.find(index); ElementMap::const_iterator it = elements.find(index);
return it == elements.end() ? NULL : (*it).second; return it == elements.end() ? nullptr : (*it).second;
} }
const Element* FindElementCaseInsensitive(const std::string& elementName) const { const Element* FindElementCaseInsensitive(const std::string& elementName) const {

View File

@ -209,21 +209,25 @@ DirectPropertyMap PropertyTable::GetUnparsedProperties() const
DirectPropertyMap result; DirectPropertyMap result;
// Loop through all the lazy properties (which is all the properties) // Loop through all the lazy properties (which is all the properties)
for(const LazyPropertyMap::value_type& element : lazyProps) { for(const LazyPropertyMap::value_type& currentElement : lazyProps) {
// Skip parsed properties // Skip parsed properties
if (props.end() != props.find(element.first)) continue; if (props.end() != props.find(currentElement.first)) {
continue;
}
// Read the element's value. // Read the element's value.
// Wrap the naked pointer (since the call site is required to acquire ownership) // Wrap the naked pointer (since the call site is required to acquire ownership)
// std::unique_ptr from C++11 would be preferred both as a wrapper and a return value. // std::unique_ptr from C++11 would be preferred both as a wrapper and a return value.
std::shared_ptr<Property> prop = std::shared_ptr<Property>(ReadTypedProperty(*element.second)); std::shared_ptr<Property> prop = std::shared_ptr<Property>(ReadTypedProperty(*currentElement.second));
// Element could not be read. Skip it. // Element could not be read. Skip it.
if (!prop) continue; if (!prop) {
continue;
}
// Add to result // Add to result
result[element.first] = prop; result[currentElement.first] = prop;
} }
return result; return result;

View File

@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "FBXCompileConfig.h" #include "FBXCompileConfig.h"
#include <assimp/ai_assert.h> #include <assimp/ai_assert.h>
#include <assimp/defs.h>
#include <vector> #include <vector>
#include <string> #include <string>

View File

@ -118,11 +118,11 @@ void HMPImporter::InternReadFile( const std::string& pFile,
aiScene* _pScene, IOSystem* _pIOHandler) aiScene* _pScene, IOSystem* _pIOHandler)
{ {
pScene = _pScene; pScene = _pScene;
pIOHandler = _pIOHandler; mIOHandler = _pIOHandler;
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile)); std::unique_ptr<IOStream> file(mIOHandler->Open(pFile));
// Check whether we can read from the file // Check whether we can read from the file
if( file.get() == NULL) if( file.get() == nullptr)
throw DeadlyImportError( "Failed to open HMP file " + pFile + "."); throw DeadlyImportError( "Failed to open HMP file " + pFile + ".");
// Check whether the HMP file is large enough to contain // Check whether the HMP file is large enough to contain

View File

@ -285,11 +285,11 @@ public:
out.mVerts.reserve(out.mVerts.size() + cnt); out.mVerts.reserve(out.mVerts.size() + cnt);
for(const CurveEntry& entry : curves) { for(const CurveEntry& entry : curves) {
const size_t cnt = out.mVerts.size(); const size_t curCnt = out.mVerts.size();
entry.first->SampleDiscrete(out); entry.first->SampleDiscrete(out);
if (!entry.second && cnt != out.mVerts.size()) { if (!entry.second && curCnt != out.mVerts.size()) {
std::reverse(out.mVerts.begin()+cnt,out.mVerts.end()); std::reverse(out.mVerts.begin() + curCnt, out.mVerts.end());
} }
} }
} }
@ -329,8 +329,8 @@ public:
have_param = true; have_param = true;
break; break;
} }
else if (const Schema_2x3::IfcCartesianPoint* const r = sel->ResolveSelectPtr<Schema_2x3::IfcCartesianPoint>(conv.db)) { else if (const Schema_2x3::IfcCartesianPoint* const curR = sel->ResolveSelectPtr<Schema_2x3::IfcCartesianPoint>(conv.db)) {
ConvertCartesianPoint(point,*r); ConvertCartesianPoint(point, *curR);
have_point = true; have_point = true;
} }
} }
@ -346,8 +346,8 @@ public:
have_param = true; have_param = true;
break; break;
} }
else if (const Schema_2x3::IfcCartesianPoint* const r = sel->ResolveSelectPtr<Schema_2x3::IfcCartesianPoint>(conv.db)) { else if (const Schema_2x3::IfcCartesianPoint* const curR = sel->ResolveSelectPtr<Schema_2x3::IfcCartesianPoint>(conv.db)) {
ConvertCartesianPoint(point,*r); ConvertCartesianPoint(point, *curR);
have_point = true; have_point = true;
} }
} }

View File

@ -101,7 +101,7 @@ void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t m
return; return;
} }
ai_assert(std::count(inmesh.mVertcnt.begin(), inmesh.mVertcnt.end(), 0) == 0); ai_assert(std::count(inmesh.mVertcnt.begin(), inmesh.mVertcnt.end(), 0u) == 0);
typedef std::vector<unsigned int>::const_iterator face_iter; typedef std::vector<unsigned int>::const_iterator face_iter;
@ -379,7 +379,7 @@ void ProcessSweptDiskSolid(const Schema_2x3::IfcSweptDiskSolid &solid, TempMesh&
IfcVector3 q; IfcVector3 q;
bool take_any = false; bool take_any = false;
for (unsigned int i = 0; i < 2; ++i, take_any = true) { for (unsigned int j = 0; j < 2; ++j, take_any = true) {
if ((last_dir == 0 || take_any) && std::abs(d.x) > 1e-6) { if ((last_dir == 0 || take_any) && std::abs(d.x) > 1e-6) {
q.y = startvec.y; q.y = startvec.y;
q.z = startvec.z; q.z = startvec.z;

View File

@ -44,7 +44,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the Industry Foundation Classes loader. * @brief Implementation of the Industry Foundation Classes loader.
*/ */
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER #ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
#include <iterator> #include <iterator>
@ -59,24 +58,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif #endif
#endif #endif
#include "IFCLoader.h"
#include "../STEPParser/STEPFileReader.h" #include "../STEPParser/STEPFileReader.h"
#include "IFCLoader.h"
#include "IFCUtil.h" #include "IFCUtil.h"
#include <assimp/MemoryIOWrapper.h> #include <assimp/MemoryIOWrapper.h>
#include <assimp/importerdesc.h>
#include <assimp/scene.h> #include <assimp/scene.h>
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
#include <assimp/importerdesc.h>
namespace Assimp { namespace Assimp {
template<> const char* LogFunctions<IFCImporter>::Prefix() template <>
{ const char *LogFunctions<IFCImporter>::Prefix() {
static auto prefix = "IFC: "; static auto prefix = "IFC: ";
return prefix; return prefix;
} }
} } // namespace Assimp
using namespace Assimp; using namespace Assimp;
using namespace Assimp::Formatter; using namespace Assimp::Formatter;
@ -98,7 +96,6 @@ using namespace Assimp::IFC;
namespace { namespace {
// forward declarations // forward declarations
void SetUnits(ConversionData &conv); void SetUnits(ConversionData &conv);
void SetCoordinateSpace(ConversionData &conv); void SetCoordinateSpace(ConversionData &conv);
@ -106,7 +103,7 @@ void ProcessSpatialStructures(ConversionData& conv);
void MakeTreeRelative(ConversionData &conv); void MakeTreeRelative(ConversionData &conv);
void ConvertUnit(const ::Assimp::STEP::EXPRESS::DataType &dt, ConversionData &conv); void ConvertUnit(const ::Assimp::STEP::EXPRESS::DataType &dt, ConversionData &conv);
} // anon } // namespace
static const aiImporterDesc desc = { static const aiImporterDesc desc = {
"Industry Foundation Classes (IFC) Importer", "Industry Foundation Classes (IFC) Importer",
@ -121,22 +118,18 @@ static const aiImporterDesc desc = {
"ifc ifczip stp" "ifc ifczip stp"
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
IFCImporter::IFCImporter() IFCImporter::IFCImporter() {}
{}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
IFCImporter::~IFCImporter() IFCImporter::~IFCImporter() {
{
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool IFCImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const bool IFCImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
{
const std::string &extension = GetExtension(pFile); const std::string &extension = GetExtension(pFile);
if (extension == "ifc" || extension == "ifczip") { if (extension == "ifc" || extension == "ifczip") {
return true; return true;
@ -153,15 +146,13 @@ bool IFCImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// List all extensions handled by this loader // List all extensions handled by this loader
const aiImporterDesc* IFCImporter::GetInfo () const const aiImporterDesc *IFCImporter::GetInfo() const {
{
return &desc; return &desc;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Setup configuration properties for the loader // Setup configuration properties for the loader
void IFCImporter::SetupProperties(const Importer* pImp) void IFCImporter::SetupProperties(const Importer *pImp) {
{
settings.skipSpaceRepresentations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_IFC_SKIP_SPACE_REPRESENTATIONS, true); settings.skipSpaceRepresentations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_IFC_SKIP_SPACE_REPRESENTATIONS, true);
settings.useCustomTriangulation = pImp->GetPropertyBool(AI_CONFIG_IMPORT_IFC_CUSTOM_TRIANGULATION, true); settings.useCustomTriangulation = pImp->GetPropertyBool(AI_CONFIG_IMPORT_IFC_CUSTOM_TRIANGULATION, true);
settings.conicSamplingAngle = std::min(std::max((float)pImp->GetPropertyFloat(AI_CONFIG_IMPORT_IFC_SMOOTHING_ANGLE, AI_IMPORT_IFC_DEFAULT_SMOOTHING_ANGLE), 5.0f), 120.0f); settings.conicSamplingAngle = std::min(std::max((float)pImp->GetPropertyFloat(AI_CONFIG_IMPORT_IFC_SMOOTHING_ANGLE, AI_IMPORT_IFC_DEFAULT_SMOOTHING_ANGLE), 5.0f), 120.0f);
@ -169,17 +160,14 @@ void IFCImporter::SetupProperties(const Importer* pImp)
settings.skipAnnotations = true; settings.skipAnnotations = true;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure. // Imports the given file into the given scene structure.
void IFCImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) void IFCImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
{
std::shared_ptr<IOStream> stream(pIOHandler->Open(pFile)); std::shared_ptr<IOStream> stream(pIOHandler->Open(pFile));
if (!stream) { if (!stream) {
ThrowException("Could not open file for reading"); ThrowException("Could not open file for reading");
} }
// if this is a ifczip file, decompress its contents first // if this is a ifczip file, decompress its contents first
if (GetExtension(pFile) == "ifczip") { if (GetExtension(pFile) == "ifczip") {
#ifndef ASSIMP_BUILD_NO_COMPRESSED_IFC #ifndef ASSIMP_BUILD_NO_COMPRESSED_IFC
@ -225,22 +213,19 @@ void IFCImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
free(buffer); free(buffer);
} while (read > 0); } while (read > 0);
size_t filesize = fileInfo.uncompressed_size; size_t filesize = fileInfo.uncompressed_size;
if (total == 0 || size_t(total) != filesize) if (total == 0 || size_t(total) != filesize) {
{
delete[] buff; delete[] buff;
ThrowException("Failed to decompress IFC ZIP file"); ThrowException("Failed to decompress IFC ZIP file");
} }
unzCloseCurrentFile(zip); unzCloseCurrentFile(zip);
stream.reset(new MemoryIOStream(buff, fileInfo.uncompressed_size, true)); stream.reset(new MemoryIOStream(buff, fileInfo.uncompressed_size, true));
break;
if (unzGoToNextFile(zip) == UNZ_END_OF_LIST_OF_FILE) { if (unzGoToNextFile(zip) == UNZ_END_OF_LIST_OF_FILE) {
ThrowException("Found no IFC file member in IFCZIP file (1)"); ThrowException("Found no IFC file member in IFCZIP file (1)");
} }
break;
} while (true); } while (true);
} } else {
else {
ThrowException("Found no IFC file member in IFCZIP file (2)"); ThrowException("Found no IFC file member in IFCZIP file (2)");
} }
@ -336,10 +321,8 @@ void IFCImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
namespace { namespace {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertUnit(const Schema_2x3::IfcNamedUnit& unit,ConversionData& conv) void ConvertUnit(const Schema_2x3::IfcNamedUnit &unit, ConversionData &conv) {
{
if (const Schema_2x3::IfcSIUnit *const si = unit.ToPtr<Schema_2x3::IfcSIUnit>()) { if (const Schema_2x3::IfcSIUnit *const si = unit.ToPtr<Schema_2x3::IfcSIUnit>()) {
if (si->UnitType == "LENGTHUNIT") { if (si->UnitType == "LENGTHUNIT") {
conv.len_scale = si->Prefix ? ConvertSIPrefix(si->Prefix) : 1.f; conv.len_scale = si->Prefix ? ConvertSIPrefix(si->Prefix) : 1.f;
@ -350,15 +333,13 @@ void ConvertUnit(const Schema_2x3::IfcNamedUnit& unit,ConversionData& conv)
IFCImporter::LogWarn("expected base unit for angles to be radian"); IFCImporter::LogWarn("expected base unit for angles to be radian");
} }
} }
} } else if (const Schema_2x3::IfcConversionBasedUnit *const convu = unit.ToPtr<Schema_2x3::IfcConversionBasedUnit>()) {
else if(const Schema_2x3::IfcConversionBasedUnit* const convu = unit.ToPtr<Schema_2x3::IfcConversionBasedUnit>()) {
if (convu->UnitType == "PLANEANGLEUNIT") { if (convu->UnitType == "PLANEANGLEUNIT") {
try { try {
conv.angle_scale = convu->ConversionFactor->ValueComponent->To<::Assimp::STEP::EXPRESS::REAL>(); conv.angle_scale = convu->ConversionFactor->ValueComponent->To<::Assimp::STEP::EXPRESS::REAL>();
ConvertUnit(*convu->ConversionFactor->UnitComponent, conv); ConvertUnit(*convu->ConversionFactor->UnitComponent, conv);
IFCImporter::LogDebug("got units used for angles"); IFCImporter::LogDebug("got units used for angles");
} } catch (std::bad_cast &) {
catch(std::bad_cast&) {
IFCImporter::LogError("skipping unknown IfcConversionBasedUnit.ValueComponent entry - expected REAL"); IFCImporter::LogError("skipping unknown IfcConversionBasedUnit.ValueComponent entry - expected REAL");
} }
} }
@ -366,8 +347,7 @@ void ConvertUnit(const Schema_2x3::IfcNamedUnit& unit,ConversionData& conv)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertUnit(const ::Assimp::STEP::EXPRESS::DataType& dt,ConversionData& conv) void ConvertUnit(const ::Assimp::STEP::EXPRESS::DataType &dt, ConversionData &conv) {
{
try { try {
const ::Assimp::STEP::EXPRESS::ENTITY &e = dt.To<::Assimp::STEP::EXPRESS::ENTITY>(); const ::Assimp::STEP::EXPRESS::ENTITY &e = dt.To<::Assimp::STEP::EXPRESS::ENTITY>();
@ -377,26 +357,22 @@ void ConvertUnit(const ::Assimp::STEP::EXPRESS::DataType& dt,ConversionData& con
} }
ConvertUnit(unit, conv); ConvertUnit(unit, conv);
} } catch (std::bad_cast &) {
catch(std::bad_cast&) {
// not entity, somehow // not entity, somehow
IFCImporter::LogError("skipping unknown IfcUnit entry - expected entity"); IFCImporter::LogError("skipping unknown IfcUnit entry - expected entity");
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void SetUnits(ConversionData& conv) void SetUnits(ConversionData &conv) {
{
// see if we can determine the coordinate space used to express. // see if we can determine the coordinate space used to express.
for (size_t i = 0; i < conv.proj.UnitsInContext->Units.size(); ++i) { for (size_t i = 0; i < conv.proj.UnitsInContext->Units.size(); ++i) {
ConvertUnit(*conv.proj.UnitsInContext->Units[i], conv); ConvertUnit(*conv.proj.UnitsInContext->Units[i], conv);
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void SetCoordinateSpace(ConversionData& conv) void SetCoordinateSpace(ConversionData &conv) {
{
const Schema_2x3::IfcRepresentationContext *fav = NULL; const Schema_2x3::IfcRepresentationContext *fav = NULL;
for (const Schema_2x3::IfcRepresentationContext &v : conv.proj.RepresentationContexts) { for (const Schema_2x3::IfcRepresentationContext &v : conv.proj.RepresentationContexts) {
fav = &v; fav = &v;
@ -413,10 +389,8 @@ void SetCoordinateSpace(ConversionData& conv)
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ResolveObjectPlacement(aiMatrix4x4& m, const Schema_2x3::IfcObjectPlacement& place, ConversionData& conv) void ResolveObjectPlacement(aiMatrix4x4 &m, const Schema_2x3::IfcObjectPlacement &place, ConversionData &conv) {
{
if (const Schema_2x3::IfcLocalPlacement *const local = place.ToPtr<Schema_2x3::IfcLocalPlacement>()) { if (const Schema_2x3::IfcLocalPlacement *const local = place.ToPtr<Schema_2x3::IfcLocalPlacement>()) {
IfcMatrix4 tmp; IfcMatrix4 tmp;
ConvertAxisPlacement(tmp, *local->RelativePlacement, conv); ConvertAxisPlacement(tmp, *local->RelativePlacement, conv);
@ -424,19 +398,17 @@ void ResolveObjectPlacement(aiMatrix4x4& m, const Schema_2x3::IfcObjectPlacement
m = static_cast<aiMatrix4x4>(tmp); m = static_cast<aiMatrix4x4>(tmp);
if (local->PlacementRelTo) { if (local->PlacementRelTo) {
aiMatrix4x4 tmp; aiMatrix4x4 tmpM;
ResolveObjectPlacement(tmp,local->PlacementRelTo.Get(),conv); ResolveObjectPlacement(tmpM, local->PlacementRelTo.Get(), conv);
m = tmp * m; m = tmpM * m;
} }
} } else {
else {
IFCImporter::LogWarn("skipping unknown IfcObjectPlacement entity, type is " + place.GetClassName()); IFCImporter::LogWarn("skipping unknown IfcObjectPlacement entity, type is " + place.GetClassName());
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool ProcessMappedItem(const Schema_2x3::IfcMappedItem& mapped, aiNode* nd_src, std::vector< aiNode* >& subnodes_src, unsigned int matid, ConversionData& conv) bool ProcessMappedItem(const Schema_2x3::IfcMappedItem &mapped, aiNode *nd_src, std::vector<aiNode *> &subnodes_src, unsigned int matid, ConversionData &conv) {
{
// insert a custom node here, the carthesian transform operator is simply a conventional transformation matrix // insert a custom node here, the carthesian transform operator is simply a conventional transformation matrix
std::unique_ptr<aiNode> nd(new aiNode()); std::unique_ptr<aiNode> nd(new aiNode());
nd->mName.Set("IfcMappedItem"); nd->mName.Set("IfcMappedItem");
@ -467,8 +439,8 @@ bool ProcessMappedItem(const Schema_2x3::IfcMappedItem& mapped, aiNode* nd_src,
for (const Schema_2x3::IfcRepresentationItem &item : repr.Items) { for (const Schema_2x3::IfcRepresentationItem &item : repr.Items) {
if (!ProcessRepresentationItem(item, localmatid, meshes, conv)) { if (!ProcessRepresentationItem(item, localmatid, meshes, conv)) {
IFCImporter::LogWarn("skipping mapped entity of type " + item.GetClassName() + ", no representations could be generated"); IFCImporter::LogWarn("skipping mapped entity of type " + item.GetClassName() + ", no representations could be generated");
} } else
else got = true; got = true;
} }
if (!got) { if (!got) {
@ -504,7 +476,6 @@ struct RateRepresentationPredicate {
return 0; return 0;
} }
const std::string &name = r->RepresentationIdentifier.Get(); const std::string &name = r->RepresentationIdentifier.Get();
if (name == "MappedRepresentation") { if (name == "MappedRepresentation") {
if (!r->Items.empty()) { if (!r->Items.empty()) {
@ -557,8 +528,7 @@ struct RateRepresentationPredicate {
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ProcessProductRepresentation(const Schema_2x3::IfcProduct& el, aiNode* nd, std::vector< aiNode* >& subnodes, ConversionData& conv) void ProcessProductRepresentation(const Schema_2x3::IfcProduct &el, aiNode *nd, std::vector<aiNode *> &subnodes, ConversionData &conv) {
{
if (!el.Representation) { if (!el.Representation) {
return; return;
} }
@ -581,8 +551,7 @@ void ProcessProductRepresentation(const Schema_2x3::IfcProduct& el, aiNode* nd,
for (const Schema_2x3::IfcRepresentationItem &item : repr->Items) { for (const Schema_2x3::IfcRepresentationItem &item : repr->Items) {
if (const Schema_2x3::IfcMappedItem *const geo = item.ToPtr<Schema_2x3::IfcMappedItem>()) { if (const Schema_2x3::IfcMappedItem *const geo = item.ToPtr<Schema_2x3::IfcMappedItem>()) {
res = ProcessMappedItem(*geo, nd, subnodes, matid, conv) || res; res = ProcessMappedItem(*geo, nd, subnodes, matid, conv) || res;
} } else {
else {
res = ProcessRepresentationItem(item, matid, meshes, conv) || res; res = ProcessRepresentationItem(item, matid, meshes, conv) || res;
} }
} }
@ -607,22 +576,19 @@ void ProcessMetadata(const Schema_2x3::ListOf< Schema_2x3::Lazy< Schema_2x3::Ifc
if (const ::Assimp::STEP::EXPRESS::STRING *str = singleValue->NominalValue.Get()->ToPtr<::Assimp::STEP::EXPRESS::STRING>()) { if (const ::Assimp::STEP::EXPRESS::STRING *str = singleValue->NominalValue.Get()->ToPtr<::Assimp::STEP::EXPRESS::STRING>()) {
std::string value = static_cast<std::string>(*str); std::string value = static_cast<std::string>(*str);
properties[key] = value; properties[key] = value;
} } else if (const ::Assimp::STEP::EXPRESS::REAL *val1 = singleValue->NominalValue.Get()->ToPtr<::Assimp::STEP::EXPRESS::REAL>()) {
else if (const ::Assimp::STEP::EXPRESS::REAL* val = singleValue->NominalValue.Get()->ToPtr<::Assimp::STEP::EXPRESS::REAL>()) { float value = static_cast<float>(*val1);
float value = static_cast<float>(*val);
std::stringstream s; std::stringstream s;
s << value; s << value;
properties[key] = s.str(); properties[key] = s.str();
} } else if (const ::Assimp::STEP::EXPRESS::INTEGER *val2 = singleValue->NominalValue.Get()->ToPtr<::Assimp::STEP::EXPRESS::INTEGER>()) {
else if (const ::Assimp::STEP::EXPRESS::INTEGER* val = singleValue->NominalValue.Get()->ToPtr<::Assimp::STEP::EXPRESS::INTEGER>()) { int64_t curValue = static_cast<int64_t>(*val2);
int64_t value = static_cast<int64_t>(*val);
std::stringstream s; std::stringstream s;
s << value; s << curValue;
properties[key] = s.str(); properties[key] = s.str();
} }
} }
} } else if (const Schema_2x3::IfcPropertyListValue *const listValue = property.ToPtr<Schema_2x3::IfcPropertyListValue>()) {
else if (const Schema_2x3::IfcPropertyListValue* const listValue = property.ToPtr<Schema_2x3::IfcPropertyListValue>()) {
std::stringstream ss; std::stringstream ss;
ss << "["; ss << "[";
unsigned index = 0; unsigned index = 0;
@ -631,13 +597,11 @@ void ProcessMetadata(const Schema_2x3::ListOf< Schema_2x3::Lazy< Schema_2x3::Ifc
if (const ::Assimp::STEP::EXPRESS::STRING *str = v->ToPtr<::Assimp::STEP::EXPRESS::STRING>()) { if (const ::Assimp::STEP::EXPRESS::STRING *str = v->ToPtr<::Assimp::STEP::EXPRESS::STRING>()) {
std::string value = static_cast<std::string>(*str); std::string value = static_cast<std::string>(*str);
ss << "'" << value << "'"; ss << "'" << value << "'";
} } else if (const ::Assimp::STEP::EXPRESS::REAL *val1 = v->ToPtr<::Assimp::STEP::EXPRESS::REAL>()) {
else if (const ::Assimp::STEP::EXPRESS::REAL* val = v->ToPtr<::Assimp::STEP::EXPRESS::REAL>()) { float value = static_cast<float>(*val1);
float value = static_cast<float>(*val);
ss << value; ss << value;
} } else if (const ::Assimp::STEP::EXPRESS::INTEGER *val2 = v->ToPtr<::Assimp::STEP::EXPRESS::INTEGER>()) {
else if (const ::Assimp::STEP::EXPRESS::INTEGER* val = v->ToPtr<::Assimp::STEP::EXPRESS::INTEGER>()) { int64_t value = static_cast<int64_t>(*val2);
int64_t value = static_cast<int64_t>(*val);
ss << value; ss << value;
} }
if (index + 1 < listValue->ListValues.size()) { if (index + 1 < listValue->ListValues.size()) {
@ -647,25 +611,20 @@ void ProcessMetadata(const Schema_2x3::ListOf< Schema_2x3::Lazy< Schema_2x3::Ifc
} }
ss << "]"; ss << "]";
properties[key] = ss.str(); properties[key] = ss.str();
} } else if (const Schema_2x3::IfcComplexProperty *const complexProp = property.ToPtr<Schema_2x3::IfcComplexProperty>()) {
else if (const Schema_2x3::IfcComplexProperty* const complexProp = property.ToPtr<Schema_2x3::IfcComplexProperty>()) {
if (nest > 2) { // mostly arbitrary limit to prevent stack overflow vulnerabilities if (nest > 2) { // mostly arbitrary limit to prevent stack overflow vulnerabilities
IFCImporter::LogError("maximum nesting level for IfcComplexProperty reached, skipping this property."); IFCImporter::LogError("maximum nesting level for IfcComplexProperty reached, skipping this property.");
} } else {
else {
ProcessMetadata(complexProp->HasProperties, conv, properties, key, nest + 1); ProcessMetadata(complexProp->HasProperties, conv, properties, key, nest + 1);
} }
} } else {
else {
properties[key] = ""; properties[key] = "";
} }
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ProcessMetadata(uint64_t relDefinesByPropertiesID, ConversionData& conv, Metadata& properties) void ProcessMetadata(uint64_t relDefinesByPropertiesID, ConversionData &conv, Metadata &properties) {
{
if (const Schema_2x3::IfcRelDefinesByProperties *const pset = conv.db.GetObject(relDefinesByPropertiesID)->ToPtr<Schema_2x3::IfcRelDefinesByProperties>()) { if (const Schema_2x3::IfcRelDefinesByProperties *const pset = conv.db.GetObject(relDefinesByPropertiesID)->ToPtr<Schema_2x3::IfcRelDefinesByProperties>()) {
if (const Schema_2x3::IfcPropertySet *const set = conv.db.GetObject(pset->RelatingPropertyDefinition->GetID())->ToPtr<Schema_2x3::IfcPropertySet>()) { if (const Schema_2x3::IfcPropertySet *const set = conv.db.GetObject(pset->RelatingPropertyDefinition->GetID())->ToPtr<Schema_2x3::IfcPropertySet>()) {
ProcessMetadata(set->HasProperties, conv, properties); ProcessMetadata(set->HasProperties, conv, properties);
@ -790,7 +749,6 @@ aiNode* ProcessSpatialStructure(aiNode* parent, const Schema_2x3::IfcProduct& el
nd_aggr->mNumChildren = 1; nd_aggr->mNumChildren = 1;
nd_aggr->mChildren = new aiNode *[1](); nd_aggr->mChildren = new aiNode *[1]();
nd_aggr->mChildren[0] = ndnew; nd_aggr->mChildren[0] = ndnew;
if (openings_local.size()) { if (openings_local.size()) {
@ -872,11 +830,9 @@ aiNode* ProcessSpatialStructure(aiNode* parent, const Schema_2x3::IfcProduct& el
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ProcessSpatialStructures(ConversionData& conv) void ProcessSpatialStructures(ConversionData &conv) {
{
// XXX add support for multiple sites (i.e. IfcSpatialStructureElements with composition == COMPLEX) // XXX add support for multiple sites (i.e. IfcSpatialStructureElements with composition == COMPLEX)
// process all products in the file. it is reasonable to assume that a // process all products in the file. it is reasonable to assume that a
// file that is relevant for us contains at least a site or a building. // file that is relevant for us contains at least a site or a building.
const STEP::DB::ObjectMapByType &map = conv.db.GetObjectsByType(); const STEP::DB::ObjectMapByType &map = conv.db.GetObjectsByType();
@ -939,8 +895,7 @@ void ProcessSpatialStructures(ConversionData& conv)
if (nb_nodes == 1) { if (nb_nodes == 1) {
conv.out->mRootNode = nodes[0]; conv.out->mRootNode = nodes[0];
} } else if (nb_nodes > 1) {
else if (nb_nodes > 1) {
conv.out->mRootNode = new aiNode("Root"); conv.out->mRootNode = new aiNode("Root");
conv.out->mRootNode->mParent = NULL; conv.out->mRootNode->mParent = NULL;
conv.out->mRootNode->mNumChildren = static_cast<unsigned int>(nb_nodes); conv.out->mRootNode->mNumChildren = static_cast<unsigned int>(nb_nodes);
@ -953,15 +908,13 @@ void ProcessSpatialStructures(ConversionData& conv)
conv.out->mRootNode->mChildren[i] = node; conv.out->mRootNode->mChildren[i] = node;
} }
} } else {
else {
IFCImporter::ThrowException("failed to determine primary site element"); IFCImporter::ThrowException("failed to determine primary site element");
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void MakeTreeRelative(aiNode* start, const aiMatrix4x4& combined) void MakeTreeRelative(aiNode *start, const aiMatrix4x4 &combined) {
{
// combined is the parent's absolute transformation matrix // combined is the parent's absolute transformation matrix
const aiMatrix4x4 old = start->mTransformation; const aiMatrix4x4 old = start->mTransformation;
@ -976,13 +929,10 @@ void MakeTreeRelative(aiNode* start, const aiMatrix4x4& combined)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void MakeTreeRelative(ConversionData& conv) void MakeTreeRelative(ConversionData &conv) {
{
MakeTreeRelative(conv.out->mRootNode, IfcMatrix4()); MakeTreeRelative(conv.out->mRootNode, IfcMatrix4());
} }
} // !anon } // namespace
#endif #endif

View File

@ -294,7 +294,7 @@ void InsertWindowContours(const ContourVector& contours,
const IfcFloat epsilon = diag/1000.f; const IfcFloat epsilon = diag/1000.f;
// walk through all contour points and find those that lie on the BB corner // walk through all contour points and find those that lie on the BB corner
size_t last_hit = -1, very_first_hit = -1; size_t last_hit = (size_t)-1, very_first_hit = (size_t)-1;
IfcVector2 edge; IfcVector2 edge;
for(size_t n = 0, e=0, size = contour.size();; n=(n+1)%size, ++e) { for(size_t n = 0, e=0, size = contour.size();; n=(n+1)%size, ++e) {
@ -330,7 +330,7 @@ void InsertWindowContours(const ContourVector& contours,
const size_t old = curmesh.mVerts.size(); const size_t old = curmesh.mVerts.size();
size_t cnt = last_hit > n ? size-(last_hit-n) : n-last_hit; size_t cnt = last_hit > n ? size-(last_hit-n) : n-last_hit;
for(size_t a = last_hit, e = 0; e <= cnt; a=(a+1)%size, ++e) { for(size_t a = last_hit, ee = 0; ee <= cnt; a=(a+1)%size, ++ee) {
// hack: this is to fix cases where opening contours are self-intersecting. // hack: this is to fix cases where opening contours are self-intersecting.
// Clipper doesn't produce such polygons, but as soon as we're back in // Clipper doesn't produce such polygons, but as soon as we're back in
// our brave new floating-point world, very small distances are consumed // our brave new floating-point world, very small distances are consumed

View File

@ -45,6 +45,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "code/Step/STEPFile.h" #include "code/Step/STEPFile.h"
#ifdef _WIN32
# pragma warning( disable : 4512 )
#endif // _WIN32
namespace Assimp { namespace Assimp {
namespace IFC { namespace IFC {
namespace Schema_2x3 { namespace Schema_2x3 {

View File

@ -362,8 +362,9 @@ void TempMesh::FixupFaceOrientation()
{ {
std::reverse(mVerts.begin() + nbvsi, mVerts.begin() + nbvsi + nbvc); std::reverse(mVerts.begin() + nbvsi, mVerts.begin() + nbvsi + nbvc);
std::reverse(neighbour.begin() + nbvsi, neighbour.begin() + nbvsi + nbvc); std::reverse(neighbour.begin() + nbvsi, neighbour.begin() + nbvsi + nbvc);
for( size_t a = 0; a < nbvc - 1; ++a ) for (size_t aa = 0; aa < nbvc - 1; ++aa) {
std::swap(neighbour[nbvsi + a], neighbour[nbvsi + a + 1]); std::swap(neighbour[nbvsi + aa], neighbour[nbvsi + aa + 1]);
}
} }
// either way we're done with the neighbour. Mark it as done and continue checking from there recursively // either way we're done with the neighbour. Mark it as done and continue checking from there recursively

View File

@ -50,12 +50,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/TinyFormatter.h> #include <assimp/TinyFormatter.h>
#include <assimp/fast_atof.h> #include <assimp/fast_atof.h>
#include <memory> #include <memory>
#include <functional>
using namespace Assimp; using namespace Assimp;
namespace EXPRESS = STEP::EXPRESS;
#include <functional> namespace EXPRESS = STEP::EXPRESS;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
std::string AddLineNumber(const std::string& s,uint64_t line /*= LINE_NOT_SPECIFIED*/, const std::string& prefix = "") std::string AddLineNumber(const std::string& s,uint64_t line /*= LINE_NOT_SPECIFIED*/, const std::string& prefix = "")
@ -127,8 +126,8 @@ STEP::DB* STEP::ReadFileHeader(std::shared_ptr<IOStream> stream) {
if (list->GetSize() > 1) { if (list->GetSize() > 1) {
ASSIMP_LOG_WARN(AddLineNumber("multiple schemas currently not supported",line)); ASSIMP_LOG_WARN(AddLineNumber("multiple schemas currently not supported",line));
} }
const EXPRESS::STRING* string( nullptr ); const EXPRESS::STRING *string = dynamic_cast<const EXPRESS::STRING *>((*list)[0].get());
if (!list->GetSize() || !(string=dynamic_cast<const EXPRESS::STRING*>( (*list)[0].get() ))) { if (!list->GetSize() || nullptr == string ) {
throw STEP::SyntaxError("expected FILE_SCHEMA to contain a single string literal",line); throw STEP::SyntaxError("expected FILE_SCHEMA to contain a single string literal",line);
} }
head.fileSchema = *string; head.fileSchema = *string;
@ -539,7 +538,7 @@ void STEP::LazyObject::LazyInit() const {
} }
const char* acopy = args; const char* acopy = args;
std::shared_ptr<const EXPRESS::LIST> conv_args = EXPRESS::LIST::Parse(acopy,STEP::SyntaxError::LINE_NOT_SPECIFIED,&db.GetSchema()); std::shared_ptr<const EXPRESS::LIST> conv_args = EXPRESS::LIST::Parse(acopy,(uint64_t)STEP::SyntaxError::LINE_NOT_SPECIFIED,&db.GetSchema());
delete[] args; delete[] args;
args = NULL; args = NULL;

View File

@ -225,7 +225,7 @@ namespace {
, SchemaEntry("presentation_representation_select",NULL ) , SchemaEntry("presentation_representation_select",NULL )
, SchemaEntry("presentation_size_assignment_select",NULL ) , SchemaEntry("presentation_size_assignment_select",NULL )
, SchemaEntry("presentation_style_select",NULL ) , SchemaEntry("presentation_style_select",NULL )
, SchemaEntry("presented_item_select",NULL ) //, SchemaEntry("presented_item_select",NULL )
, SchemaEntry("pressure_measure",NULL ) , SchemaEntry("pressure_measure",NULL )
, SchemaEntry("product_definition_or_assembly_relationship",NULL ) , SchemaEntry("product_definition_or_assembly_relationship",NULL )
, SchemaEntry("product_definition_or_breakdown_element_usage",NULL ) , SchemaEntry("product_definition_or_breakdown_element_usage",NULL )
@ -397,7 +397,7 @@ namespace {
, SchemaEntry("applied_organizational_project_assignment",&STEP::ObjectHelper<applied_organizational_project_assignment,1>::Construct ) , SchemaEntry("applied_organizational_project_assignment",&STEP::ObjectHelper<applied_organizational_project_assignment,1>::Construct )
, SchemaEntry("person_and_organization_assignment",&STEP::ObjectHelper<person_and_organization_assignment,2>::Construct ) , SchemaEntry("person_and_organization_assignment",&STEP::ObjectHelper<person_and_organization_assignment,2>::Construct )
, SchemaEntry("applied_person_and_organization_assignment",&STEP::ObjectHelper<applied_person_and_organization_assignment,1>::Construct ) , SchemaEntry("applied_person_and_organization_assignment",&STEP::ObjectHelper<applied_person_and_organization_assignment,1>::Construct )
, SchemaEntry("presented_item",&STEP::ObjectHelper<presented_item,0>::Construct ) //, SchemaEntry("presented_item",&STEP::ObjectHelper<presented_item,0>::Construct )
, SchemaEntry("applied_presented_item",&STEP::ObjectHelper<applied_presented_item,1>::Construct ) , SchemaEntry("applied_presented_item",&STEP::ObjectHelper<applied_presented_item,1>::Construct )
, SchemaEntry("security_classification_assignment",&STEP::ObjectHelper<security_classification_assignment,1>::Construct ) , SchemaEntry("security_classification_assignment",&STEP::ObjectHelper<security_classification_assignment,1>::Construct )
, SchemaEntry("applied_security_classification_assignment",&STEP::ObjectHelper<applied_security_classification_assignment,1>::Construct ) , SchemaEntry("applied_security_classification_assignment",&STEP::ObjectHelper<applied_security_classification_assignment,1>::Construct )
@ -1014,7 +1014,7 @@ namespace {
, SchemaEntry("presentation_size",&STEP::ObjectHelper<NotImplemented,0>::Construct ) , SchemaEntry("presentation_size",&STEP::ObjectHelper<NotImplemented,0>::Construct )
, SchemaEntry("presentation_style_assignment",&STEP::ObjectHelper<presentation_style_assignment,1>::Construct ) , SchemaEntry("presentation_style_assignment",&STEP::ObjectHelper<presentation_style_assignment,1>::Construct )
, SchemaEntry("presentation_style_by_context",&STEP::ObjectHelper<presentation_style_by_context,1>::Construct ) , SchemaEntry("presentation_style_by_context",&STEP::ObjectHelper<presentation_style_by_context,1>::Construct )
, SchemaEntry("presented_item_representation",&STEP::ObjectHelper<NotImplemented,0>::Construct ) //, SchemaEntry("presented_item_representation",&STEP::ObjectHelper<NotImplemented,0>::Construct )
, SchemaEntry("pressure_measure_with_unit",&STEP::ObjectHelper<pressure_measure_with_unit,0>::Construct ) , SchemaEntry("pressure_measure_with_unit",&STEP::ObjectHelper<pressure_measure_with_unit,0>::Construct )
, SchemaEntry("pressure_unit",&STEP::ObjectHelper<pressure_unit,0>::Construct ) , SchemaEntry("pressure_unit",&STEP::ObjectHelper<pressure_unit,0>::Construct )
, SchemaEntry("procedural_representation",&STEP::ObjectHelper<procedural_representation,0>::Construct ) , SchemaEntry("procedural_representation",&STEP::ObjectHelper<procedural_representation,0>::Construct )
@ -1311,11 +1311,11 @@ void StepFile::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;
} }
*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<measure_with_unit>(const DB& db, const LIST& params, measure_with_unit* in) template <> size_t GenericFill<measure_with_unit>(const DB& db, const LIST& params, measure_with_unit* in)
{ {
@ -1359,8 +1359,7 @@ template <> size_t GenericFill<absorbed_dose_unit>(const DB& db, const LIST& par
if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to absorbed_dose_unit"); } return base; if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to absorbed_dose_unit"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<abstract_variable>(const DB& db, const LIST& params, abstract_variable* in) template <> size_t GenericFill<abstract_variable>(const DB&, const LIST&, abstract_variable*) {
{
size_t base = 0; size_t base = 0;
return base; return base;
} }
@ -1680,7 +1679,7 @@ template <> size_t GenericFill<amount_of_substance_unit>(const DB& db, const LIS
if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to amount_of_substance_unit"); } return base; if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to amount_of_substance_unit"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<angle_direction_reference>(const DB& db, const LIST& params, angle_direction_reference* in) template <> size_t GenericFill<angle_direction_reference>(const DB&, const LIST&, angle_direction_reference*)
{ {
size_t base = 0; size_t base = 0;
return base; return base;

View File

@ -452,11 +452,11 @@ template <> size_t GenericFill<applied_person_and_organization_assignment>(const
return base; return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<presented_item>(const DB& db, const LIST& params, presented_item* in) /*template <> size_t GenericFill<presented_item>(const DB& db, const LIST& params, presented_item* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<applied_presented_item>(const DB& db, const LIST& params, applied_presented_item* in) template <> size_t GenericFill<applied_presented_item>(const DB& db, const LIST& params, applied_presented_item* in)
{ {
@ -642,11 +642,11 @@ template <> size_t GenericFill<atomic_formula>(const DB& db, const LIST& params,
if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to atomic_formula"); } return base; if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to atomic_formula"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<attribute_assertion>(const DB& db, const LIST& params, attribute_assertion* in) /*template <> size_t GenericFill<attribute_assertion>(const DB& db, const LIST& params, attribute_assertion* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<attribute_language_assignment>(const DB& db, const LIST& params, attribute_language_assignment* in) template <> size_t GenericFill<attribute_language_assignment>(const DB& db, const LIST& params, attribute_language_assignment* in)
{ {
@ -683,11 +683,11 @@ template <> size_t GenericFill<attribute_value_assignment>(const DB& db, const L
return base; return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<auxiliary_geometric_representation_item>(const DB& db, const LIST& params, auxiliary_geometric_representation_item* in) /*template <> size_t GenericFill<auxiliary_geometric_representation_item>(const DB& db, const LIST& params, auxiliary_geometric_representation_item* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<placement>(const DB& db, const LIST& params, placement* in) template <> size_t GenericFill<placement>(const DB& db, const LIST& params, placement* in)
{ {
@ -946,7 +946,7 @@ template <> size_t GenericFill<back_chaining_rule>(const DB& db, const LIST& par
if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to back_chaining_rule"); } return base; if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to back_chaining_rule"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<back_chaining_rule_body>(const DB& db, const LIST& params, back_chaining_rule_body* in) /*template <> size_t GenericFill<back_chaining_rule_body>(const DB& db, const LIST& params, back_chaining_rule_body* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
@ -956,7 +956,7 @@ template <> size_t GenericFill<colour>(const DB& db, const LIST& params, colour*
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<background_colour>(const DB& db, const LIST& params, background_colour* in) template <> size_t GenericFill<background_colour>(const DB& db, const LIST& params, background_colour* in)
{ {
@ -987,11 +987,11 @@ template <> size_t GenericFill<bezier_surface>(const DB& db, const LIST& params,
if (params.GetSize() < 7) { throw STEP::TypeError("expected 7 arguments to bezier_surface"); } return base; if (params.GetSize() < 7) { throw STEP::TypeError("expected 7 arguments to bezier_surface"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<generic_expression>(const DB& db, const LIST& params, generic_expression* in) /*template <> size_t GenericFill<generic_expression>(const DB& db, const LIST& params, generic_expression* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<binary_generic_expression>(const DB& db, const LIST& params, binary_generic_expression* in) template <> size_t GenericFill<binary_generic_expression>(const DB& db, const LIST& params, binary_generic_expression* in)
{ {
@ -1004,11 +1004,11 @@ template <> size_t GenericFill<binary_generic_expression>(const DB& db, const LI
return base; return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<binary_numeric_expression>(const DB& db, const LIST& params, binary_numeric_expression* in) /*template <> size_t GenericFill<binary_numeric_expression>(const DB& db, const LIST& params, binary_numeric_expression* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<binary_representation_item>(const DB& db, const LIST& params, binary_representation_item* in) template <> size_t GenericFill<binary_representation_item>(const DB& db, const LIST& params, binary_representation_item* in)
{ {
@ -1071,11 +1071,11 @@ template <> size_t GenericFill<boolean_literal>(const DB& db, const LIST& params
return base; return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<boolean_representation_item>(const DB& db, const LIST& params, boolean_representation_item* in) /*template <> size_t GenericFill<boolean_representation_item>(const DB& db, const LIST& params, boolean_representation_item* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<boolean_result>(const DB& db, const LIST& params, boolean_result* in) template <> size_t GenericFill<boolean_result>(const DB& db, const LIST& params, boolean_result* in)
{ {
@ -1128,7 +1128,7 @@ template <> size_t GenericFill<boundary_curve>(const DB& db, const LIST& params,
if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to boundary_curve"); } return base; if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to boundary_curve"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<bounded_pcurve>(const DB& db, const LIST& params, bounded_pcurve* in) /*template <> size_t GenericFill<bounded_pcurve>(const DB& db, const LIST& params, bounded_pcurve* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
@ -1144,7 +1144,7 @@ template <> size_t GenericFill<founded_item>(const DB& db, const LIST& params, f
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<box_domain>(const DB& db, const LIST& params, box_domain* in) template <> size_t GenericFill<box_domain>(const DB& db, const LIST& params, box_domain* in)
{ {
@ -1218,11 +1218,11 @@ template <> size_t GenericFill<breakdown_element_group_assignment>(const DB& db,
return base; return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<breakdown_element_realization>(const DB& db, const LIST& params, breakdown_element_realization* in) /*template <> size_t GenericFill<breakdown_element_realization>(const DB& db, const LIST& params, breakdown_element_realization* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<breakdown_element_usage>(const DB& db, const LIST& params, breakdown_element_usage* in) template <> size_t GenericFill<breakdown_element_usage>(const DB& db, const LIST& params, breakdown_element_usage* in)
{ {
@ -1784,11 +1784,11 @@ template <> size_t GenericFill<characteristic_type>(const DB& db, const LIST& pa
if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to characteristic_type"); } return base; if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to characteristic_type"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<characterized_class>(const DB& db, const LIST& params, characterized_class* in) /*template <> size_t GenericFill<characterized_class>(const DB& db, const LIST& params, characterized_class* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<characterized_object>(const DB& db, const LIST& params, characterized_object* in) template <> size_t GenericFill<characterized_object>(const DB& db, const LIST& params, characterized_object* in)
{ {
@ -1947,6 +1947,7 @@ template <> size_t GenericFill<colour_rgb>(const DB& db, const LIST& params, col
} while (0); } while (0);
return base; return base;
} }
/*
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<common_datum>(const DB& db, const LIST& params, common_datum* in) template <> size_t GenericFill<common_datum>(const DB& db, const LIST& params, common_datum* in)
{ {
@ -1958,7 +1959,7 @@ template <> size_t GenericFill<comparison_expression>(const DB& db, const LIST&
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<complex_clause>(const DB& db, const LIST& params, complex_clause* in) template <> size_t GenericFill<complex_clause>(const DB& db, const LIST& params, complex_clause* in)
{ {
@ -2792,7 +2793,7 @@ template <> size_t GenericFill<cylindricity_tolerance>(const DB& db, const LIST&
if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to cylindricity_tolerance"); } return base; if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to cylindricity_tolerance"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<date_representation_item>(const DB& db, const LIST& params, date_representation_item* in) /*template <> size_t GenericFill<date_representation_item>(const DB& db, const LIST& params, date_representation_item* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
@ -2802,7 +2803,7 @@ template <> size_t GenericFill<date_time_representation_item>(const DB& db, cons
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<dated_effectivity>(const DB& db, const LIST& params, dated_effectivity* in) template <> size_t GenericFill<dated_effectivity>(const DB& db, const LIST& params, dated_effectivity* in)
{ {

View File

@ -98,11 +98,11 @@ template <> size_t GenericFill<dimension_pair>(const DB& db, const LIST& params,
if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to dimension_pair"); } return base; if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to dimension_pair"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<dimension_text_associativity>(const DB& db, const LIST& params, dimension_text_associativity* in) /*template <> size_t GenericFill<dimension_text_associativity>(const DB& db, const LIST& params, dimension_text_associativity* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<dimensional_location_with_path>(const DB& db, const LIST& params, dimensional_location_with_path* in) template <> size_t GenericFill<dimensional_location_with_path>(const DB& db, const LIST& params, dimensional_location_with_path* in)
{ {
@ -160,11 +160,11 @@ template <> size_t GenericFill<direction>(const DB& db, const LIST& params, dire
return base; return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<document_file>(const DB& db, const LIST& params, document_file* in) /*template <> size_t GenericFill<document_file>(const DB& db, const LIST& params, document_file* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<document_identifier>(const DB& db, const LIST& params, document_identifier* in) template <> size_t GenericFill<document_identifier>(const DB& db, const LIST& params, document_identifier* in)
{ {
@ -347,11 +347,11 @@ template <> size_t GenericFill<draughting_model_item_association>(const DB& db,
if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to draughting_model_item_association"); } return base; if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to draughting_model_item_association"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<pre_defined_colour>(const DB& db, const LIST& params, pre_defined_colour* in) /*template <> size_t GenericFill<pre_defined_colour>(const DB& db, const LIST& params, pre_defined_colour* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<draughting_pre_defined_colour>(const DB& db, const LIST& params, draughting_pre_defined_colour* in) template <> size_t GenericFill<draughting_pre_defined_colour>(const DB& db, const LIST& params, draughting_pre_defined_colour* in)
{ {
@ -461,11 +461,11 @@ template <> size_t GenericFill<draughting_text_literal_with_delineation>(const D
if (params.GetSize() < 7) { throw STEP::TypeError("expected 7 arguments to draughting_text_literal_with_delineation"); } return base; if (params.GetSize() < 7) { throw STEP::TypeError("expected 7 arguments to draughting_text_literal_with_delineation"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<presentation_set>(const DB& db, const LIST& params, presentation_set* in) /*template <> size_t GenericFill<presentation_set>(const DB& db, const LIST& params, presentation_set* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<drawing_revision>(const DB& db, const LIST& params, drawing_revision* in) template <> size_t GenericFill<drawing_revision>(const DB& db, const LIST& params, drawing_revision* in)
{ {
@ -592,11 +592,11 @@ template <> size_t GenericFill<edge_curve>(const DB& db, const LIST& params, edg
return base; return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<edge_loop>(const DB& db, const LIST& params, edge_loop* in) /*template <> size_t GenericFill<edge_loop>(const DB& db, const LIST& params, edge_loop* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<electric_charge_measure_with_unit>(const DB& db, const LIST& params, electric_charge_measure_with_unit* in) template <> size_t GenericFill<electric_charge_measure_with_unit>(const DB& db, const LIST& params, electric_charge_measure_with_unit* in)
{ {
@ -711,11 +711,11 @@ template <> size_t GenericFill<enum_reference_prefix>(const DB& db, const LIST&
if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to enum_reference_prefix"); } return base; if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to enum_reference_prefix"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<evaluated_characteristic>(const DB& db, const LIST& params, evaluated_characteristic* in) /*template <> size_t GenericFill<evaluated_characteristic>(const DB& db, const LIST& params, evaluated_characteristic* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<evaluated_degenerate_pcurve>(const DB& db, const LIST& params, evaluated_degenerate_pcurve* in) template <> size_t GenericFill<evaluated_degenerate_pcurve>(const DB& db, const LIST& params, evaluated_degenerate_pcurve* in)
{ {
@ -867,11 +867,11 @@ template <> size_t GenericFill<explicit_procedural_shape_representation_relation
if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to explicit_procedural_shape_representation_relationship"); } return base; if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to explicit_procedural_shape_representation_relationship"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<expression_conversion_based_unit>(const DB& db, const LIST& params, expression_conversion_based_unit* in) /*template <> size_t GenericFill<expression_conversion_based_unit>(const DB& db, const LIST& params, expression_conversion_based_unit* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<extension>(const DB& db, const LIST& params, extension* in) template <> size_t GenericFill<extension>(const DB& db, const LIST& params, extension* in)
{ {
@ -903,35 +903,35 @@ template <> size_t GenericFill<external_class_library>(const DB& db, const LIST&
if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to external_class_library"); } return base; if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to external_class_library"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<externally_defined_class>(const DB& db, const LIST& params, externally_defined_class* in) /*template <> size_t GenericFill<externally_defined_class>(const DB& db, const LIST& params, externally_defined_class* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<externally_defined_colour>(const DB& db, const LIST& params, externally_defined_colour* in) /*template <> size_t GenericFill<externally_defined_colour>(const DB& db, const LIST& params, externally_defined_colour* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<externally_defined_context_dependent_unit>(const DB& db, const LIST& params, externally_defined_context_dependent_unit* in) /*template <> size_t GenericFill<externally_defined_context_dependent_unit>(const DB& db, const LIST& params, externally_defined_context_dependent_unit* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<externally_defined_conversion_based_unit>(const DB& db, const LIST& params, externally_defined_conversion_based_unit* in) /*template <> size_t GenericFill<externally_defined_conversion_based_unit>(const DB& db, const LIST& params, externally_defined_conversion_based_unit* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<externally_defined_currency>(const DB& db, const LIST& params, externally_defined_currency* in) /*template <> size_t GenericFill<externally_defined_currency>(const DB& db, const LIST& params, externally_defined_currency* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<externally_defined_item>(const DB& db, const LIST& params, externally_defined_item* in) template <> size_t GenericFill<externally_defined_item>(const DB& db, const LIST& params, externally_defined_item* in)
{ {
@ -957,7 +957,7 @@ template <> size_t GenericFill<externally_defined_curve_font>(const DB& db, cons
if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to externally_defined_curve_font"); } return base; if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to externally_defined_curve_font"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<externally_defined_dimension_definition>(const DB& db, const LIST& params, externally_defined_dimension_definition* in) /*template <> size_t GenericFill<externally_defined_dimension_definition>(const DB& db, const LIST& params, externally_defined_dimension_definition* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
@ -979,7 +979,7 @@ template <> size_t GenericFill<externally_defined_marker>(const DB& db, const LI
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<picture_representation_item>(const DB& db, const LIST& params, picture_representation_item* in) template <> size_t GenericFill<picture_representation_item>(const DB& db, const LIST& params, picture_representation_item* in)
{ {
@ -993,7 +993,7 @@ template <> size_t GenericFill<externally_defined_picture_representation_item>(c
if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to externally_defined_picture_representation_item"); } return base; if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to externally_defined_picture_representation_item"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<externally_defined_representation_item>(const DB& db, const LIST& params, externally_defined_representation_item* in) /*template <> size_t GenericFill<externally_defined_representation_item>(const DB& db, const LIST& params, externally_defined_representation_item* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
@ -1003,7 +1003,7 @@ template <> size_t GenericFill<externally_defined_string>(const DB& db, const LI
{ {
size_t base = GenericFill(db, params, static_cast<externally_defined_representation_item*>(in)); size_t base = GenericFill(db, params, static_cast<externally_defined_representation_item*>(in));
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<externally_defined_symbol>(const DB& db, const LIST& params, externally_defined_symbol* in) template <> size_t GenericFill<externally_defined_symbol>(const DB& db, const LIST& params, externally_defined_symbol* in)
{ {
@ -1029,11 +1029,11 @@ template <> size_t GenericFill<externally_defined_tile>(const DB& db, const LIST
if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to externally_defined_tile"); } return base; if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to externally_defined_tile"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<externally_defined_tile_style>(const DB& db, const LIST& params, externally_defined_tile_style* in) /*template <> size_t GenericFill<externally_defined_tile_style>(const DB& db, const LIST& params, externally_defined_tile_style* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<swept_area_solid>(const DB& db, const LIST& params, swept_area_solid* in) template <> size_t GenericFill<swept_area_solid>(const DB& db, const LIST& params, swept_area_solid* in)
{ {
@ -1358,11 +1358,11 @@ template <> size_t GenericFill<forward_chaining_rule>(const DB& db, const LIST&
if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to forward_chaining_rule"); } return base; if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to forward_chaining_rule"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<forward_chaining_rule_premise>(const DB& db, const LIST& params, forward_chaining_rule_premise* in) /*template <> size_t GenericFill<forward_chaining_rule_premise>(const DB& db, const LIST& params, forward_chaining_rule_premise* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<frequency_measure_with_unit>(const DB& db, const LIST& params, frequency_measure_with_unit* in) template <> size_t GenericFill<frequency_measure_with_unit>(const DB& db, const LIST& params, frequency_measure_with_unit* in)
{ {
@ -1454,11 +1454,11 @@ template <> size_t GenericFill<geometric_item_specific_usage>(const DB& db, cons
if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to geometric_item_specific_usage"); } return base; if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to geometric_item_specific_usage"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<geometric_model_element_relationship>(const DB& db, const LIST& params, geometric_model_element_relationship* in) /*template <> size_t GenericFill<geometric_model_element_relationship>(const DB& db, const LIST& params, geometric_model_element_relationship* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<representation_context>(const DB& db, const LIST& params, representation_context* in) template <> size_t GenericFill<representation_context>(const DB& db, const LIST& params, representation_context* in)
{ {
@ -1633,11 +1633,11 @@ template <> size_t GenericFill<indirectly_selected_elements>(const DB& db, const
return base; return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<indirectly_selected_shape_elements>(const DB& db, const LIST& params, indirectly_selected_shape_elements* in) /*template <> size_t GenericFill<indirectly_selected_shape_elements>(const DB& db, const LIST& params, indirectly_selected_shape_elements* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<inductance_measure_with_unit>(const DB& db, const LIST& params, inductance_measure_with_unit* in) template <> size_t GenericFill<inductance_measure_with_unit>(const DB& db, const LIST& params, inductance_measure_with_unit* in)
{ {
@ -1674,11 +1674,11 @@ template <> size_t GenericFill<instance_usage_context_assignment>(const DB& db,
return base; return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<instanced_feature>(const DB& db, const LIST& params, instanced_feature* in) /*template <> size_t GenericFill<instanced_feature>(const DB& db, const LIST& params, instanced_feature* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<literal_number>(const DB& db, const LIST& params, literal_number* in) template <> size_t GenericFill<literal_number>(const DB& db, const LIST& params, literal_number* in)
{ {
@ -1698,11 +1698,11 @@ template <> size_t GenericFill<int_literal>(const DB& db, const LIST& params, in
if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to int_literal"); } return base; if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to int_literal"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<integer_representation_item>(const DB& db, const LIST& params, integer_representation_item* in) /*template <> size_t GenericFill<integer_representation_item>(const DB& db, const LIST& params, integer_representation_item* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<surface_curve>(const DB& db, const LIST& params, surface_curve* in) template <> size_t GenericFill<surface_curve>(const DB& db, const LIST& params, surface_curve* in)
{ {
@ -1734,11 +1734,11 @@ template <> size_t GenericFill<intersection_curve>(const DB& db, const LIST& par
if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to intersection_curve"); } return base; if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to intersection_curve"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<interval_expression>(const DB& db, const LIST& params, interval_expression* in) /*template <> size_t GenericFill<interval_expression>(const DB& db, const LIST& params, interval_expression* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<iso4217_currency>(const DB& db, const LIST& params, iso4217_currency* in) template <> size_t GenericFill<iso4217_currency>(const DB& db, const LIST& params, iso4217_currency* in)
{ {
@ -1746,11 +1746,11 @@ template <> size_t GenericFill<iso4217_currency>(const DB& db, const LIST& param
if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to iso4217_currency"); } return base; if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to iso4217_currency"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<known_source>(const DB& db, const LIST& params, known_source* in) /*template <> size_t GenericFill<known_source>(const DB& db, const LIST& params, known_source* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<laid_defined_transformation>(const DB& db, const LIST& params, laid_defined_transformation* in) template <> size_t GenericFill<laid_defined_transformation>(const DB& db, const LIST& params, laid_defined_transformation* in)
{ {
@ -1943,11 +1943,11 @@ template <> size_t GenericFill<logical_literal>(const DB& db, const LIST& params
return base; return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<logical_representation_item>(const DB& db, const LIST& params, logical_representation_item* in) /*template <> size_t GenericFill<logical_representation_item>(const DB&, const LIST& params, logical_representation_item* )
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<loop>(const DB& db, const LIST& params, loop* in) template <> size_t GenericFill<loop>(const DB& db, const LIST& params, loop* in)
{ {
@ -2105,11 +2105,11 @@ template <> size_t GenericFill<material_property_representation>(const DB& db, c
return base; return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<measure_representation_item>(const DB& db, const LIST& params, measure_representation_item* in) /*template <> size_t GenericFill<measure_representation_item>(const DB& db, const LIST& params, measure_representation_item* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<product_context>(const DB& db, const LIST& params, product_context* in) template <> size_t GenericFill<product_context>(const DB& db, const LIST& params, product_context* in)
{ {
@ -2165,11 +2165,11 @@ template <> size_t GenericFill<mechanical_design_shaded_presentation_representat
if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to mechanical_design_shaded_presentation_representation"); } return base; if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to mechanical_design_shaded_presentation_representation"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<min_and_major_ply_orientation_basis>(const DB& db, const LIST& params, min_and_major_ply_orientation_basis* in) /*template <> size_t GenericFill<min_and_major_ply_orientation_basis>(const DB& db, const LIST& params, min_and_major_ply_orientation_basis* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<modified_geometric_tolerance>(const DB& db, const LIST& params, modified_geometric_tolerance* in) template <> size_t GenericFill<modified_geometric_tolerance>(const DB& db, const LIST& params, modified_geometric_tolerance* in)
{ {
@ -2211,11 +2211,11 @@ template <> size_t GenericFill<multi_language_attribute_assignment>(const DB& db
return base; return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<multiple_arity_boolean_expression>(const DB& db, const LIST& params, multiple_arity_boolean_expression* in) /*template <> size_t GenericFill<multiple_arity_boolean_expression>(const DB& db, const LIST& params, multiple_arity_boolean_expression* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<multiple_arity_generic_expression>(const DB& db, const LIST& params, multiple_arity_generic_expression* in) template <> size_t GenericFill<multiple_arity_generic_expression>(const DB& db, const LIST& params, multiple_arity_generic_expression* in)
{ {
@ -2228,11 +2228,11 @@ template <> size_t GenericFill<multiple_arity_generic_expression>(const DB& db,
return base; return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<multiple_arity_numeric_expression>(const DB& db, const LIST& params, multiple_arity_numeric_expression* in) /*template <> size_t GenericFill<multiple_arity_numeric_expression>(const DB& db, const LIST& params, multiple_arity_numeric_expression* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<next_assembly_usage_occurrence>(const DB& db, const LIST& params, next_assembly_usage_occurrence* in) template <> size_t GenericFill<next_assembly_usage_occurrence>(const DB& db, const LIST& params, next_assembly_usage_occurrence* in)
{ {
@ -2533,11 +2533,11 @@ template <> size_t GenericFill<parametric_representation_context>(const DB& db,
if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to parametric_representation_context"); } return base; if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to parametric_representation_context"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<partial_document_with_structured_text_representation_assignment>(const DB& db, const LIST& params, partial_document_with_structured_text_representation_assignment* in) /*template <> size_t GenericFill<partial_document_with_structured_text_representation_assignment>(const DB& db, const LIST& params, partial_document_with_structured_text_representation_assignment* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<pcurve>(const DB& db, const LIST& params, pcurve* in) template <> size_t GenericFill<pcurve>(const DB& db, const LIST& params, pcurve* in)
{ {
@ -2591,11 +2591,11 @@ template <> size_t GenericFill<perpendicularity_tolerance>(const DB& db, const L
if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to perpendicularity_tolerance"); } return base; if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to perpendicularity_tolerance"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<person_and_organization_address>(const DB& db, const LIST& params, person_and_organization_address* in) /*template <> size_t GenericFill<person_and_organization_address>(const DB& db, const LIST& params, person_and_organization_address* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<personal_address>(const DB& db, const LIST& params, personal_address* in) template <> size_t GenericFill<personal_address>(const DB& db, const LIST& params, personal_address* in)
{ {
@ -2715,11 +2715,11 @@ template <> size_t GenericFill<ply_laminate_table>(const DB& db, const LIST& par
if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to ply_laminate_table"); } return base; if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to ply_laminate_table"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<point_and_vector>(const DB& db, const LIST& params, point_and_vector* in) /*template <> size_t GenericFill<point_and_vector>(const DB& db, const LIST& params, point_and_vector* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<point_on_curve>(const DB& db, const LIST& params, point_on_curve* in) template <> size_t GenericFill<point_on_curve>(const DB& db, const LIST& params, point_on_curve* in)
{ {
@ -2758,11 +2758,11 @@ template <> size_t GenericFill<point_on_surface>(const DB& db, const LIST& param
return base; return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<point_path>(const DB& db, const LIST& params, point_path* in) /*template <> size_t GenericFill<point_path>(const DB& db, const LIST& params, point_path* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<point_replica>(const DB& db, const LIST& params, point_replica* in) template <> size_t GenericFill<point_replica>(const DB& db, const LIST& params, point_replica* in)
{ {
@ -2904,11 +2904,11 @@ template <> size_t GenericFill<pre_defined_marker>(const DB& db, const LIST& par
if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to pre_defined_marker"); } return base; if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to pre_defined_marker"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<pre_defined_point_marker_symbol>(const DB& db, const LIST& params, pre_defined_point_marker_symbol* in) /*template <> size_t GenericFill<pre_defined_point_marker_symbol>(const DB& db, const LIST& params, pre_defined_point_marker_symbol* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<pre_defined_surface_condition_symbol>(const DB& db, const LIST& params, pre_defined_surface_condition_symbol* in) template <> size_t GenericFill<pre_defined_surface_condition_symbol>(const DB& db, const LIST& params, pre_defined_surface_condition_symbol* in)
{ {
@ -3002,7 +3002,7 @@ template <> size_t GenericFill<procedural_representation_sequence>(const DB& db,
return base; return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<procedural_shape_representation>(const DB& db, const LIST& params, procedural_shape_representation* in) /*template <> size_t GenericFill<procedural_shape_representation>(const DB& db, const LIST& params, procedural_shape_representation* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
@ -3012,7 +3012,7 @@ template <> size_t GenericFill<procedural_shape_representation_sequence>(const D
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<product_category>(const DB& db, const LIST& params, product_category* in) template <> size_t GenericFill<product_category>(const DB& db, const LIST& params, product_category* in)
{ {
@ -3033,11 +3033,11 @@ template <> size_t GenericFill<product_category>(const DB& db, const LIST& param
return base; return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<product_class>(const DB& db, const LIST& params, product_class* in) /*template <> size_t GenericFill<product_class>(const DB& db, const LIST& params, product_class* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<product_concept_context>(const DB& db, const LIST& params, product_concept_context* in) template <> size_t GenericFill<product_concept_context>(const DB& db, const LIST& params, product_concept_context* in)
{ {
@ -3131,11 +3131,11 @@ template <> size_t GenericFill<product_definition_with_associated_documents>(con
return base; return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<product_identification>(const DB& db, const LIST& params, product_identification* in) /*template <> size_t GenericFill<product_identification>(const DB& db, const LIST& params, product_identification* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<product_material_composition_relationship>(const DB& db, const LIST& params, product_material_composition_relationship* in) template <> size_t GenericFill<product_material_composition_relationship>(const DB& db, const LIST& params, product_material_composition_relationship* in)
{ {
@ -3174,11 +3174,11 @@ template <> size_t GenericFill<product_related_product_category>(const DB& db, c
return base; return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<product_specification>(const DB& db, const LIST& params, product_specification* in) /*template <> size_t GenericFill<product_specification>(const DB& db, const LIST& params, product_specification* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<tolerance_zone_definition>(const DB& db, const LIST& params, tolerance_zone_definition* in) template <> size_t GenericFill<tolerance_zone_definition>(const DB& db, const LIST& params, tolerance_zone_definition* in)
{ {
@ -3289,11 +3289,11 @@ template <> size_t GenericFill<radius_dimension>(const DB& db, const LIST& param
if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to radius_dimension"); } return base; if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to radius_dimension"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<range_characteristic>(const DB& db, const LIST& params, range_characteristic* in) /*template <> size_t GenericFill<range_characteristic>(const DB& db, const LIST& params, range_characteristic* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<ratio_unit>(const DB& db, const LIST& params, ratio_unit* in) template <> size_t GenericFill<ratio_unit>(const DB& db, const LIST& params, ratio_unit* in)
{ {
@ -3318,11 +3318,11 @@ template <> size_t GenericFill<rational_b_spline_surface>(const DB& db, const LI
if (params.GetSize() < 7) { throw STEP::TypeError("expected 7 arguments to rational_b_spline_surface"); } return base; if (params.GetSize() < 7) { throw STEP::TypeError("expected 7 arguments to rational_b_spline_surface"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<rational_representation_item>(const DB& db, const LIST& params, rational_representation_item* in) /*template <> size_t GenericFill<rational_representation_item>(const DB& db, const LIST& params, rational_representation_item* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<real_literal>(const DB& db, const LIST& params, real_literal* in) template <> size_t GenericFill<real_literal>(const DB& db, const LIST& params, real_literal* in)
{ {
@ -3330,11 +3330,11 @@ template <> size_t GenericFill<real_literal>(const DB& db, const LIST& params, r
if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to real_literal"); } return base; if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to real_literal"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<real_representation_item>(const DB& db, const LIST& params, real_representation_item* in) /*template <> size_t GenericFill<real_representation_item>(const DB& db, const LIST& params, real_representation_item* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<rectangular_composite_surface>(const DB& db, const LIST& params, rectangular_composite_surface* in) template <> size_t GenericFill<rectangular_composite_surface>(const DB& db, const LIST& params, rectangular_composite_surface* in)
{ {
@ -3410,11 +3410,11 @@ template <> size_t GenericFill<relative_event_occurrence>(const DB& db, const LI
return base; return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<rep_item_group>(const DB& db, const LIST& params, rep_item_group* in) /*template <> size_t GenericFill<rep_item_group>(const DB& db, const LIST& params, rep_item_group* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<reparametrised_composite_curve_segment>(const DB& db, const LIST& params, reparametrised_composite_curve_segment* in) template <> size_t GenericFill<reparametrised_composite_curve_segment>(const DB& db, const LIST& params, reparametrised_composite_curve_segment* in)
{ {
@ -3449,11 +3449,11 @@ template <> size_t GenericFill<requirement_assigned_object>(const DB& db, const
return base; return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<requirement_assignment>(const DB& db, const LIST& params, requirement_assignment* in) /*template <> size_t GenericFill<requirement_assignment>(const DB& db, const LIST& params, requirement_assignment* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<requirement_source>(const DB& db, const LIST& params, requirement_source* in) template <> size_t GenericFill<requirement_source>(const DB& db, const LIST& params, requirement_source* in)
{ {
@ -3891,7 +3891,7 @@ template <> size_t GenericFill<shell_based_wireframe_shape_representation>(const
if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to shell_based_wireframe_shape_representation"); } return base; if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to shell_based_wireframe_shape_representation"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<si_absorbed_dose_unit>(const DB& db, const LIST& params, si_absorbed_dose_unit* in) /*template <> size_t GenericFill<si_absorbed_dose_unit>(const DB& db, const LIST& params, si_absorbed_dose_unit* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
@ -3991,7 +3991,7 @@ template <> size_t GenericFill<si_resistance_unit>(const DB& db, const LIST& par
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<si_unit>(const DB& db, const LIST& params, si_unit* in) template <> size_t GenericFill<si_unit>(const DB& db, const LIST& params, si_unit* in)
{ {
@ -4010,7 +4010,7 @@ template <> size_t GenericFill<si_unit>(const DB& db, const LIST& params, si_uni
return base; return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<simple_boolean_expression>(const DB& db, const LIST& params, simple_boolean_expression* in) /*template <> size_t GenericFill<simple_boolean_expression>(const DB& db, const LIST& params, simple_boolean_expression* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
@ -4026,7 +4026,7 @@ template <> size_t GenericFill<slash_expression>(const DB& db, const LIST& param
{ {
size_t base = GenericFill(db, params, static_cast<binary_numeric_expression*>(in)); size_t base = GenericFill(db, params, static_cast<binary_numeric_expression*>(in));
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<smeared_material_definition>(const DB& db, const LIST& params, smeared_material_definition* in) template <> size_t GenericFill<smeared_material_definition>(const DB& db, const LIST& params, smeared_material_definition* in)
{ {
@ -5450,11 +5450,11 @@ template <> size_t GenericFill<unary_generic_expression>(const DB& db, const LIS
return base; return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<unary_numeric_expression>(const DB& db, const LIST& params, unary_numeric_expression* in) /*template <> size_t GenericFill<unary_numeric_expression>(const DB& db, const LIST& params, unary_numeric_expression* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<uncertainty_assigned_representation>(const DB& db, const LIST& params, uncertainty_assigned_representation* in) template <> size_t GenericFill<uncertainty_assigned_representation>(const DB& db, const LIST& params, uncertainty_assigned_representation* in)
{ {
@ -5508,7 +5508,7 @@ template <> size_t GenericFill<usage_association>(const DB& db, const LIST& para
if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to usage_association"); } return base; if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to usage_association"); } return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<user_defined_curve_font>(const DB& db, const LIST& params, user_defined_curve_font* in) /*template <> size_t GenericFill<user_defined_curve_font>(const DB& db, const LIST& params, user_defined_curve_font* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
@ -5524,7 +5524,7 @@ template <> size_t GenericFill<user_defined_terminator_symbol>(const DB& db, con
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<user_selected_shape_elements>(const DB& db, const LIST& params, user_selected_shape_elements* in) template <> size_t GenericFill<user_selected_shape_elements>(const DB& db, const LIST& params, user_selected_shape_elements* in)
{ {
@ -5549,11 +5549,11 @@ template <> size_t GenericFill<value_representation_item>(const DB& db, const LI
return base; return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<variable_semantics>(const DB& db, const LIST& params, variable_semantics* in) /*template <> size_t GenericFill<variable_semantics>(const DB& db, const LIST& params, variable_semantics* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<variational_representation_item>(const DB& db, const LIST& params, variational_representation_item* in) template <> size_t GenericFill<variational_representation_item>(const DB& db, const LIST& params, variational_representation_item* in)
{ {
@ -5577,11 +5577,11 @@ template <> size_t GenericFill<vector>(const DB& db, const LIST& params, vector*
return base; return base;
} }
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<vector_style>(const DB& db, const LIST& params, vector_style* in) /*template <> size_t GenericFill<vector_style>(const DB& db, const LIST& params, vector_style* in)
{ {
size_t base = 0; size_t base = 0;
return base; return base;
} }*/
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<velocity_measure_with_unit>(const DB& db, const LIST& params, velocity_measure_with_unit* in) template <> size_t GenericFill<velocity_measure_with_unit>(const DB& db, const LIST& params, velocity_measure_with_unit* in)
{ {

View File

@ -93,7 +93,7 @@ const aiImporterDesc *StepFileImporter::GetInfo() const {
static const std::string mode = "rb"; static const std::string mode = "rb";
static const std::string StepFileSchema = "CONFIG_CONTROL_DESIGN"; static const std::string StepFileSchema = "CONFIG_CONTROL_DESIGN";
void StepFileImporter::InternReadFile(const std::string &file, aiScene* pScene, IOSystem* pIOHandler) { void StepFileImporter::InternReadFile(const std::string &file, aiScene*, IOSystem* pIOHandler) {
// Read file into memory // Read file into memory
std::shared_ptr<IOStream> fileStream(pIOHandler->Open(file, mode)); std::shared_ptr<IOStream> fileStream(pIOHandler->Open(file, mode));
if (!fileStream.get()) { if (!fileStream.get()) {

View File

@ -45,6 +45,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "code/Step/STEPFile.h" #include "code/Step/STEPFile.h"
#ifdef _WIN32
# pragma warning( disable : 4512 )
#endif // _WIN32
namespace Assimp { namespace Assimp {
namespace StepFile { namespace StepFile {
using namespace STEP; using namespace STEP;
@ -404,7 +407,7 @@ namespace StepFile {
// C++ wrapper type for presentation_style_select // C++ wrapper type for presentation_style_select
typedef SELECT presentation_style_select; typedef SELECT presentation_style_select;
// C++ wrapper type for presented_item_select // C++ wrapper type for presented_item_select
typedef SELECT presented_item_select; //typedef SELECT presented_item_select;
// C++ wrapper type for pressure_measure // C++ wrapper type for pressure_measure
typedef REAL pressure_measure; typedef REAL pressure_measure;
// C++ wrapper type for product_definition_or_assembly_relationship // C++ wrapper type for product_definition_or_assembly_relationship
@ -545,7 +548,7 @@ namespace StepFile {
struct absorbed_dose_measure_with_unit; struct absorbed_dose_measure_with_unit;
struct derived_unit; struct derived_unit;
struct absorbed_dose_unit; struct absorbed_dose_unit;
struct abstract_variable; //struct abstract_variable;
struct acceleration_measure_with_unit; struct acceleration_measure_with_unit;
struct acceleration_unit; struct acceleration_unit;
struct action; struct action;
@ -646,7 +649,7 @@ namespace StepFile {
struct applied_organizational_project_assignment; struct applied_organizational_project_assignment;
struct person_and_organization_assignment; struct person_and_organization_assignment;
struct applied_person_and_organization_assignment; struct applied_person_and_organization_assignment;
struct presented_item; //struct presented_item;
struct applied_presented_item; struct applied_presented_item;
struct security_classification_assignment; struct security_classification_assignment;
struct applied_security_classification_assignment; struct applied_security_classification_assignment;

View File

@ -185,10 +185,12 @@ void AnimResolver::UpdateAnimRangeSetup()
for (unsigned int i = 0; i < num; ++i) { for (unsigned int i = 0; i < num; ++i) {
m = n+old_size*(i+1); m = n+old_size*(i+1);
std::copy(n,n+old_size,m); std::copy(n,n+old_size,m);
const bool res = ((*it).pre == LWO::PrePostBehaviour_Oscillate);
if ((*it).pre == LWO::PrePostBehaviour_Oscillate && (reverse = !reverse)) reverse = !reverse;
if (res && reverse ) {
std::reverse(m,m+old_size-1); std::reverse(m,m+old_size-1);
} }
}
// update time values // update time values
n = (*it).keys.end() - (old_size+1); n = (*it).keys.end() - (old_size+1);
@ -533,7 +535,7 @@ void AnimResolver::GetKeys(std::vector<aiVectorKey>& out,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Extract animation channel // Extract animation channel
void AnimResolver::ExtractAnimChannel(aiNodeAnim** out, unsigned int flags /*= 0*/) void AnimResolver::ExtractAnimChannel(aiNodeAnim** out, unsigned int /*= 0*/)
{ {
*out = NULL; *out = NULL;

View File

@ -45,24 +45,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the LWO importer class * @brief Implementation of the LWO importer class
*/ */
#ifndef ASSIMP_BUILD_NO_LWO_IMPORTER #ifndef ASSIMP_BUILD_NO_LWO_IMPORTER
// internal headers // internal headers
#include "LWO/LWOLoader.h" #include "LWO/LWOLoader.h"
#include "PostProcessing/ProcessHelper.h"
#include "PostProcessing/ConvertToLHProcess.h" #include "PostProcessing/ConvertToLHProcess.h"
#include "PostProcessing/ProcessHelper.h"
#include <assimp/StringComparison.h>
#include <assimp/SGSpatialSort.h>
#include <assimp/ByteSwapper.h> #include <assimp/ByteSwapper.h>
#include <assimp/IOSystem.hpp> #include <assimp/SGSpatialSort.h>
#include <assimp/StringComparison.h>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <assimp/IOSystem.hpp>
#include <memory>
#include <sstream>
#include <iomanip> #include <iomanip>
#include <map> #include <map>
#include <memory>
#include <sstream>
using namespace Assimp; using namespace Assimp;
@ -81,8 +80,8 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
LWOImporter::LWOImporter() LWOImporter::LWOImporter() :
: mIsLWO2(), mIsLWO2(),
mIsLXOB(), mIsLXOB(),
mLayers(), mLayers(),
mCurLayer(), mCurLayer(),
@ -91,22 +90,23 @@ LWOImporter::LWOImporter()
mSurfaces(), mSurfaces(),
mFileBuffer(), mFileBuffer(),
fileSize(), fileSize(),
pScene(), mScene(nullptr),
configSpeedFlag(), configSpeedFlag(),
configLayerIndex(), configLayerIndex(),
hasNamedLayer() hasNamedLayer() {
{} // empty
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
LWOImporter::~LWOImporter() LWOImporter::~LWOImporter() {
{} // empty
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool LWOImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const bool LWOImporter::CanRead(const std::string &file, IOSystem *pIOHandler, bool checkSig) const {
{ const std::string extension = GetExtension(file);
const std::string extension = GetExtension(pFile);
if (extension == "lwo" || extension == "lxo") { if (extension == "lwo" || extension == "lxo") {
return true; return true;
} }
@ -117,15 +117,14 @@ bool LWOImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
tokens[0] = AI_LWO_FOURCC_LWOB; tokens[0] = AI_LWO_FOURCC_LWOB;
tokens[1] = AI_LWO_FOURCC_LWO2; tokens[1] = AI_LWO_FOURCC_LWO2;
tokens[2] = AI_LWO_FOURCC_LXOB; tokens[2] = AI_LWO_FOURCC_LXOB;
return CheckMagicToken(pIOHandler,pFile,tokens,3,8); return CheckMagicToken(pIOHandler, file, tokens, 3, 8);
} }
return false; return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Setup configuration properties // Setup configuration properties
void LWOImporter::SetupProperties(const Importer* pImp) void LWOImporter::SetupProperties(const Importer *pImp) {
{
configSpeedFlag = (0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED, 0) ? true : false); configSpeedFlag = (0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED, 0) ? true : false);
configLayerIndex = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY, UINT_MAX); configLayerIndex = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY, UINT_MAX);
configLayerName = pImp->GetPropertyString(AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY, ""); configLayerName = pImp->GetPropertyString(AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY, "");
@ -133,8 +132,7 @@ void LWOImporter::SetupProperties(const Importer* pImp)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get list of file extensions // Get list of file extensions
const aiImporterDesc* LWOImporter::GetInfo () const const aiImporterDesc *LWOImporter::GetInfo() const {
{
return &desc; return &desc;
} }
@ -142,26 +140,29 @@ const aiImporterDesc* LWOImporter::GetInfo () const
// Imports the given file into the given scene structure. // Imports the given file into the given scene structure.
void LWOImporter::InternReadFile(const std::string &pFile, void LWOImporter::InternReadFile(const std::string &pFile,
aiScene *pScene, aiScene *pScene,
IOSystem* pIOHandler) IOSystem *pIOHandler) {
{
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb")); std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb"));
// Check whether we can read from the file // Check whether we can read from the file
if( file.get() == NULL) if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open LWO file " + pFile + "."); throw DeadlyImportError("Failed to open LWO file " + pFile + ".");
}
if((this->fileSize = (unsigned int)file->FileSize()) < 12) if ((this->fileSize = (unsigned int)file->FileSize()) < 12) {
throw DeadlyImportError("LWO: The file is too small to contain the IFF header"); throw DeadlyImportError("LWO: The file is too small to contain the IFF header");
}
// Allocate storage and copy the contents of the file to a memory buffer // Allocate storage and copy the contents of the file to a memory buffer
std::vector<uint8_t> mBuffer(fileSize); std::vector<uint8_t> mBuffer(fileSize);
file->Read(&mBuffer[0], 1, fileSize); file->Read(&mBuffer[0], 1, fileSize);
this->pScene = pScene; mScene = pScene;
// Determine the type of the file // Determine the type of the file
uint32_t fileType; uint32_t fileType;
const char *sz = IFF::ReadHeader(&mBuffer[0], fileType); const char *sz = IFF::ReadHeader(&mBuffer[0], fileType);
if (sz)throw DeadlyImportError(sz); if (sz) {
throw DeadlyImportError(sz);
}
mFileBuffer = &mBuffer[0] + 12; mFileBuffer = &mBuffer[0] + 12;
fileSize -= 12; fileSize -= 12;
@ -186,7 +187,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
mLayers->push_back(Layer()); mLayers->push_back(Layer());
mCurLayer = &mLayers->back(); mCurLayer = &mLayers->back();
mCurLayer->mName = "<LWODefault>"; mCurLayer->mName = "<LWODefault>";
mCurLayer->mIndex = -1; mCurLayer->mIndex = (uint16_t) -1;
// old lightwave file format (prior to v6) // old lightwave file format (prior to v6)
if (AI_LWO_FOURCC_LWOB == fileType) { if (AI_LWO_FOURCC_LWOB == fileType) {
@ -195,20 +196,16 @@ void LWOImporter::InternReadFile( const std::string& pFile,
mIsLWO2 = false; mIsLWO2 = false;
mIsLXOB = false; mIsLXOB = false;
LoadLWOBFile(); LoadLWOBFile();
} } else if (AI_LWO_FOURCC_LWO2 == fileType) {
// New lightwave format // New lightwave format
else if (AI_LWO_FOURCC_LWO2 == fileType) {
mIsLXOB = false; mIsLXOB = false;
ASSIMP_LOG_INFO("LWO file format: LWO2 (>= LightWave 6)"); ASSIMP_LOG_INFO("LWO file format: LWO2 (>= LightWave 6)");
} } else if (AI_LWO_FOURCC_LXOB == fileType) {
// MODO file format // MODO file format
else if (AI_LWO_FOURCC_LXOB == fileType) {
mIsLXOB = true; mIsLXOB = true;
ASSIMP_LOG_INFO("LWO file format: LXOB (Modo)"); ASSIMP_LOG_INFO("LWO file format: LXOB (Modo)");
} }
// we don't know this format else {
else
{
char szBuff[5]; char szBuff[5];
szBuff[0] = (char)(fileType >> 24u); szBuff[0] = (char)(fileType >> 24u);
szBuff[1] = (char)(fileType >> 16u); szBuff[1] = (char)(fileType >> 16u);
@ -235,8 +232,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
} }
if (configLayerName.length() && !hasNamedLayer) { if (configLayerName.length() && !hasNamedLayer) {
throw DeadlyImportError("LWO2: Unable to find the requested layer: " throw DeadlyImportError("LWO2: Unable to find the requested layer: " + configLayerName);
+ configLayerName);
} }
} }
@ -271,8 +267,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
} }
unsigned int idx = (*it).surfaceIndex; unsigned int idx = (*it).surfaceIndex;
if (idx >= mTags->size()) if (idx >= mTags->size()) {
{
ASSIMP_LOG_WARN("LWO: Invalid face surface index"); ASSIMP_LOG_WARN("LWO: Invalid face surface index");
idx = UINT_MAX; idx = UINT_MAX;
} }
@ -291,8 +286,8 @@ void LWOImporter::InternReadFile( const std::string& pFile,
if (UINT_MAX == iDefaultSurface) { if (UINT_MAX == iDefaultSurface) {
pSorted.erase(pSorted.end() - 1); pSorted.erase(pSorted.end() - 1);
} }
for (unsigned int p = 0,i = 0;i < mSurfaces->size();++i) { for (unsigned int p = 0, j = 0; j < mSurfaces->size(); ++j) {
SortedRep& sorted = pSorted[i]; SortedRep &sorted = pSorted[j];
if (sorted.empty()) if (sorted.empty())
continue; continue;
@ -307,9 +302,9 @@ void LWOImporter::InternReadFile( const std::string& pFile,
mesh->mNumVertices += layer.mFaces[*it].mNumIndices; mesh->mNumVertices += layer.mFaces[*it].mNumIndices;
} }
aiVector3D *nrm = NULL, * pv = mesh->mVertices = new aiVector3D[mesh->mNumVertices]; aiVector3D *nrm = nullptr, *pv = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
aiFace *pf = mesh->mFaces = new aiFace[mesh->mNumFaces]; aiFace *pf = mesh->mFaces = new aiFace[mesh->mNumFaces];
mesh->mMaterialIndex = i; mesh->mMaterialIndex = j;
// find out which vertex color channels and which texture coordinate // find out which vertex color channels and which texture coordinate
// channels are really required by the material attached to this mesh // channels are really required by the material attached to this mesh
@ -325,8 +320,8 @@ void LWOImporter::InternReadFile( const std::string& pFile,
} }
#endif #endif
FindUVChannels(_mSurfaces[i],sorted,layer,vUVChannelIndices); FindUVChannels(_mSurfaces[j], sorted, layer, vUVChannelIndices);
FindVCChannels(_mSurfaces[i],sorted,layer,vVColorIndices); FindVCChannels(_mSurfaces[j], sorted, layer, vVColorIndices);
// allocate storage for UV and CV channels // allocate storage for UV and CV channels
aiVector3D *pvUV[AI_MAX_NUMBER_OF_TEXTURECOORDS]; aiVector3D *pvUV[AI_MAX_NUMBER_OF_TEXTURECOORDS];
@ -341,8 +336,9 @@ void LWOImporter::InternReadFile( const std::string& pFile,
mesh->mNumUVComponents[0] = 2; mesh->mNumUVComponents[0] = 2;
} }
if (layer.mNormals.name.length()) if (layer.mNormals.name.length()) {
nrm = mesh->mNormals = new aiVector3D[mesh->mNumVertices]; nrm = mesh->mNormals = new aiVector3D[mesh->mNumVertices];
}
aiColor4D *pvVC[AI_MAX_NUMBER_OF_COLOR_SETS]; aiColor4D *pvVC[AI_MAX_NUMBER_OF_COLOR_SETS];
for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_COLOR_SETS; ++mui) { for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_COLOR_SETS; ++mui) {
@ -415,7 +411,8 @@ void LWOImporter::InternReadFile( const std::string& pFile,
} }
pf->mIndices = face.mIndices; pf->mIndices = face.mIndices;
pf->mNumIndices = face.mNumIndices; pf->mNumIndices = face.mNumIndices;
unsigned int** p = (unsigned int**)&face.mIndices;*p = NULL; // HACK: make sure it won't be deleted unsigned int **facePtr = (unsigned int **)&face.mIndices;
*facePtr = nullptr; // HACK: make sure it won't be deleted
pf++; pf++;
} }
@ -423,9 +420,8 @@ void LWOImporter::InternReadFile( const std::string& pFile,
// Compute normal vectors for the mesh - we can't use our GenSmoothNormal- // Compute normal vectors for the mesh - we can't use our GenSmoothNormal-
// Step here since it wouldn't handle smoothing groups correctly for LWO. // Step here since it wouldn't handle smoothing groups correctly for LWO.
// So we use a separate implementation. // So we use a separate implementation.
ComputeNormals(mesh,smoothingGroups,_mSurfaces[i]); ComputeNormals(mesh, smoothingGroups, _mSurfaces[j]);
} } else {
else {
ASSIMP_LOG_DEBUG("LWO2: No need to compute normals, they're already there"); ASSIMP_LOG_DEBUG("LWO2: No need to compute normals, they're already there");
} }
++p; ++p;
@ -470,8 +466,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LWOImporter::ComputeNormals(aiMesh *mesh, const std::vector<unsigned int> &smoothingGroups, void LWOImporter::ComputeNormals(aiMesh *mesh, const std::vector<unsigned int> &smoothingGroups,
const LWO::Surface& surface) const LWO::Surface &surface) {
{
// Allocate output storage // Allocate output storage
mesh->mNormals = new aiVector3D[mesh->mNumVertices]; mesh->mNormals = new aiVector3D[mesh->mNumVertices];
@ -510,11 +505,9 @@ void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>&
// Now generate the spatial sort tree // Now generate the spatial sort tree
SGSpatialSort sSort; SGSpatialSort sSort;
std::vector<unsigned int>::const_iterator it = smoothingGroups.begin(); std::vector<unsigned int>::const_iterator it = smoothingGroups.begin();
for( begin = mesh->mFaces; begin != end; ++begin, ++it) for (begin = mesh->mFaces; begin != end; ++begin, ++it) {
{
aiFace &face = *begin; aiFace &face = *begin;
for (unsigned int i = 0; i < face.mNumIndices;++i) for (unsigned int i = 0; i < face.mNumIndices; ++i) {
{
unsigned int tt = face.mIndices[i]; unsigned int tt = face.mIndices[i];
sSort.Add(mesh->mVertices[tt], tt, *it); sSort.Add(mesh->mVertices[tt], tt, *it);
} }
@ -532,14 +525,12 @@ void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>&
for (begin = mesh->mFaces, it = smoothingGroups.begin(); begin != end; ++begin, ++it) { for (begin = mesh->mFaces, it = smoothingGroups.begin(); begin != end; ++begin, ++it) {
const aiFace &face = *begin; const aiFace &face = *begin;
unsigned int *beginIdx = face.mIndices, *const endIdx = face.mIndices + face.mNumIndices; unsigned int *beginIdx = face.mIndices, *const endIdx = face.mIndices + face.mNumIndices;
for (; beginIdx != endIdx; ++beginIdx) for (; beginIdx != endIdx; ++beginIdx) {
{
unsigned int idx = *beginIdx; unsigned int idx = *beginIdx;
sSort.FindPositions(mesh->mVertices[idx], *it, posEpsilon, poResult, true); sSort.FindPositions(mesh->mVertices[idx], *it, posEpsilon, poResult, true);
std::vector<unsigned int>::const_iterator a, end = poResult.end();
aiVector3D vNormals; aiVector3D vNormals;
for (a = poResult.begin();a != end;++a) { for (std::vector<unsigned int>::const_iterator a = poResult.begin(); a != poResult.end(); ++a) {
const aiVector3D &v = faceNormals[*a]; const aiVector3D &v = faceNormals[*a];
if (v * faceNormals[idx] < fLimit) if (v * faceNormals[idx] < fLimit)
continue; continue;
@ -555,21 +546,19 @@ void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>&
for (begin = mesh->mFaces, it = smoothingGroups.begin(); begin != end; ++begin, ++it) { for (begin = mesh->mFaces, it = smoothingGroups.begin(); begin != end; ++begin, ++it) {
const aiFace &face = *begin; const aiFace &face = *begin;
unsigned int *beginIdx = face.mIndices, *const endIdx = face.mIndices + face.mNumIndices; unsigned int *beginIdx = face.mIndices, *const endIdx = face.mIndices + face.mNumIndices;
for (; beginIdx != endIdx; ++beginIdx) for (; beginIdx != endIdx; ++beginIdx) {
{
unsigned int idx = *beginIdx; unsigned int idx = *beginIdx;
if (vertexDone[idx]) if (vertexDone[idx])
continue; continue;
sSort.FindPositions(mesh->mVertices[idx], *it, posEpsilon, poResult, true); sSort.FindPositions(mesh->mVertices[idx], *it, posEpsilon, poResult, true);
std::vector<unsigned int>::const_iterator a, end = poResult.end();
aiVector3D vNormals; aiVector3D vNormals;
for (a = poResult.begin();a != end;++a) { for (std::vector<unsigned int>::const_iterator a = poResult.begin(); a != poResult.end(); ++a) {
const aiVector3D &v = faceNormals[*a]; const aiVector3D &v = faceNormals[*a];
vNormals += v; vNormals += v;
} }
vNormals.Normalize(); vNormals.Normalize();
for (a = poResult.begin();a != end;++a) { for (std::vector<unsigned int>::const_iterator a = poResult.begin(); a != poResult.end(); ++a) {
mesh->mNormals[*a] = vNormals; mesh->mNormals[*a] = vNormals;
vertexDone[*a] = true; vertexDone[*a] = true;
} }
@ -579,10 +568,9 @@ void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>&
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LWOImporter::GenerateNodeGraph(std::map<uint16_t,aiNode*>& apcNodes) void LWOImporter::GenerateNodeGraph(std::map<uint16_t, aiNode *> &apcNodes) {
{
// now generate the final nodegraph - generate a root node and attach children // now generate the final nodegraph - generate a root node and attach children
aiNode* root = pScene->mRootNode = new aiNode(); aiNode *root = mScene->mRootNode = new aiNode();
root->mName.Set("<LWORoot>"); root->mName.Set("<LWORoot>");
//Set parent of all children, inserting pivots //Set parent of all children, inserting pivots
@ -622,7 +610,7 @@ void LWOImporter::GenerateNodeGraph(std::map<uint16_t,aiNode*>& apcNodes)
} }
//Set children of all parents //Set children of all parents
apcNodes[-1] = root; apcNodes[(uint16_t)-1] = root;
for (auto itMapParentNodes = apcNodes.begin(); itMapParentNodes != apcNodes.end(); ++itMapParentNodes) { for (auto itMapParentNodes = apcNodes.begin(); itMapParentNodes != apcNodes.end(); ++itMapParentNodes) {
for (auto itMapChildNodes = apcNodes.begin(); itMapChildNodes != apcNodes.end(); ++itMapChildNodes) { for (auto itMapChildNodes = apcNodes.begin(); itMapChildNodes != apcNodes.end(); ++itMapChildNodes) {
if ((itMapParentNodes->first != itMapChildNodes->first) && (itMapParentNodes->second == itMapChildNodes->second->mParent)) { if ((itMapParentNodes->first != itMapChildNodes->first) && (itMapParentNodes->second == itMapChildNodes->second->mParent)) {
@ -640,28 +628,27 @@ void LWOImporter::GenerateNodeGraph(std::map<uint16_t,aiNode*>& apcNodes)
} }
} }
if (!pScene->mRootNode->mNumChildren) if (!mScene->mRootNode->mNumChildren)
throw DeadlyImportError("LWO: Unable to build a valid node graph"); throw DeadlyImportError("LWO: Unable to build a valid node graph");
// Remove a single root node with no meshes assigned to it ... // Remove a single root node with no meshes assigned to it ...
if (1 == pScene->mRootNode->mNumChildren) { if (1 == mScene->mRootNode->mNumChildren) {
aiNode* pc = pScene->mRootNode->mChildren[0]; aiNode *pc = mScene->mRootNode->mChildren[0];
pc->mParent = pScene->mRootNode->mChildren[0] = NULL; pc->mParent = mScene->mRootNode->mChildren[0] = nullptr;
delete pScene->mRootNode; delete mScene->mRootNode;
pScene->mRootNode = pc; mScene->mRootNode = pc;
} }
// convert the whole stuff to RH with CCW winding // convert the whole stuff to RH with CCW winding
MakeLeftHandedProcess maker; MakeLeftHandedProcess maker;
maker.Execute(pScene); maker.Execute(mScene);
FlipWindingOrderProcess flipper; FlipWindingOrderProcess flipper;
flipper.Execute(pScene); flipper.Execute(mScene);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LWOImporter::ResolveTags() void LWOImporter::ResolveTags() {
{
// --- this function is used for both LWO2 and LWOB // --- this function is used for both LWO2 and LWOB
mMapping->resize(mTags->size(), UINT_MAX); mMapping->resize(mTags->size(), UINT_MAX);
for (unsigned int a = 0; a < mTags->size(); ++a) { for (unsigned int a = 0; a < mTags->size(); ++a) {
@ -680,8 +667,7 @@ void LWOImporter::ResolveTags()
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LWOImporter::ResolveClips() void LWOImporter::ResolveClips() {
{
for (unsigned int i = 0; i < mClips.size(); ++i) { for (unsigned int i = 0; i < mClips.size(); ++i) {
Clip &clip = mClips[i]; Clip &clip = mClips[i];
@ -707,8 +693,7 @@ void LWOImporter::ResolveClips()
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LWOImporter::AdjustTexturePath(std::string& out) void LWOImporter::AdjustTexturePath(std::string &out) {
{
// --- this function is used for both LWO2 and LWOB // --- this function is used for both LWO2 and LWOB
if (!mIsLWO2 && ::strstr(out.c_str(), "(sequence)")) { if (!mIsLWO2 && ::strstr(out.c_str(), "(sequence)")) {
@ -725,16 +710,13 @@ void LWOImporter::AdjustTexturePath(std::string& out)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWOTags(unsigned int size) void LWOImporter::LoadLWOTags(unsigned int size) {
{
// --- this function is used for both LWO2 and LWOB // --- this function is used for both LWO2 and LWOB
const char *szCur = (const char *)mFileBuffer, *szLast = szCur; const char *szCur = (const char *)mFileBuffer, *szLast = szCur;
const char *const szEnd = szLast + size; const char *const szEnd = szLast + size;
while (szCur < szEnd) while (szCur < szEnd) {
{ if (!(*szCur)) {
if (!(*szCur))
{
const size_t len = (size_t)(szCur - szLast); const size_t len = (size_t)(szCur - szLast);
// FIX: skip empty-sized tags // FIX: skip empty-sized tags
if (len) if (len)
@ -747,27 +729,24 @@ void LWOImporter::LoadLWOTags(unsigned int size)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWOPoints(unsigned int length) void LWOImporter::LoadLWOPoints(unsigned int length) {
{
// --- this function is used for both LWO2 and LWOB but for // --- this function is used for both LWO2 and LWOB but for
// LWO2 we need to allocate 25% more storage - it could be we'll // LWO2 we need to allocate 25% more storage - it could be we'll
// need to duplicate some points later. // need to duplicate some points later.
const size_t vertexLen = 12; const size_t vertexLen = 12;
if ((length % vertexLen) != 0) if ((length % vertexLen) != 0) {
{
throw DeadlyImportError("LWO2: Points chunk length is not multiple of vertexLen (12)"); throw DeadlyImportError("LWO2: Points chunk length is not multiple of vertexLen (12)");
} }
unsigned int regularSize = (unsigned int)mCurLayer->mTempPoints.size() + length / 12; unsigned int regularSize = (unsigned int)mCurLayer->mTempPoints.size() + length / 12;
if (mIsLWO2) if (mIsLWO2) {
{
mCurLayer->mTempPoints.reserve(regularSize + (regularSize >> 2u)); mCurLayer->mTempPoints.reserve(regularSize + (regularSize >> 2u));
mCurLayer->mTempPoints.resize(regularSize); mCurLayer->mTempPoints.resize(regularSize);
// initialize all point referrers with the default values // initialize all point referrers with the default values
mCurLayer->mPointReferrers.reserve(regularSize + (regularSize >> 2u)); mCurLayer->mPointReferrers.reserve(regularSize + (regularSize >> 2u));
mCurLayer->mPointReferrers.resize(regularSize, UINT_MAX); mCurLayer->mPointReferrers.resize(regularSize, UINT_MAX);
} } else
else mCurLayer->mTempPoints.resize( regularSize ); mCurLayer->mTempPoints.resize(regularSize);
// perform endianness conversions // perform endianness conversions
#ifndef AI_BUILD_BIG_ENDIAN #ifndef AI_BUILD_BIG_ENDIAN
@ -778,20 +757,19 @@ void LWOImporter::LoadLWOPoints(unsigned int length)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2Polygons(unsigned int length) void LWOImporter::LoadLWO2Polygons(unsigned int length) {
{
LE_NCONST uint16_t *const end = (LE_NCONST uint16_t *)(mFileBuffer + length); LE_NCONST uint16_t *const end = (LE_NCONST uint16_t *)(mFileBuffer + length);
const uint32_t type = GetU4(); const uint32_t type = GetU4();
// Determine the type of the polygons // Determine the type of the polygons
switch (type) switch (type) {
{
// read unsupported stuff too (although we won't process it) // read unsupported stuff too (although we won't process it)
case AI_LWO_MBAL: case AI_LWO_MBAL:
ASSIMP_LOG_WARN("LWO2: Encountered unsupported primitive chunk (METABALL)"); ASSIMP_LOG_WARN("LWO2: Encountered unsupported primitive chunk (METABALL)");
break; break;
case AI_LWO_CURV: case AI_LWO_CURV:
ASSIMP_LOG_WARN("LWO2: Encountered unsupported primitive chunk (SPLINE)");; ASSIMP_LOG_WARN("LWO2: Encountered unsupported primitive chunk (SPLINE)");
;
break; break;
// These are ok with no restrictions // These are ok with no restrictions
@ -814,8 +792,7 @@ void LWOImporter::LoadLWO2Polygons(unsigned int length)
CountVertsAndFacesLWO2(iNumVertices, iNumFaces, cursor, end); CountVertsAndFacesLWO2(iNumVertices, iNumFaces, cursor, end);
// allocate the output array and copy face indices // allocate the output array and copy face indices
if (iNumFaces) if (iNumFaces) {
{
cursor = (uint16_t *)mFileBuffer; cursor = (uint16_t *)mFileBuffer;
mCurLayer->mFaces.resize(iNumFaces, LWO::Face(type)); mCurLayer->mFaces.resize(iNumFaces, LWO::Face(type));
@ -826,10 +803,8 @@ void LWOImporter::LoadLWO2Polygons(unsigned int length)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LWOImporter::CountVertsAndFacesLWO2(unsigned int &verts, unsigned int &faces, void LWOImporter::CountVertsAndFacesLWO2(unsigned int &verts, unsigned int &faces,
uint16_t*& cursor, const uint16_t* const end, unsigned int max) uint16_t *&cursor, const uint16_t *const end, unsigned int max) {
{ while (cursor < end && max--) {
while (cursor < end && max--)
{
uint16_t numIndices; uint16_t numIndices;
::memcpy(&numIndices, cursor++, 2); ::memcpy(&numIndices, cursor++, 2);
AI_LSWAP2(numIndices); AI_LSWAP2(numIndices);
@ -838,8 +813,7 @@ void LWOImporter::CountVertsAndFacesLWO2(unsigned int& verts, unsigned int& face
verts += numIndices; verts += numIndices;
++faces; ++faces;
for(uint16_t i = 0; i < numIndices; i++) for (uint16_t i = 0; i < numIndices; i++) {
{
ReadVSizedIntLWO2((uint8_t *&)cursor); ReadVSizedIntLWO2((uint8_t *&)cursor);
} }
} }
@ -848,10 +822,8 @@ void LWOImporter::CountVertsAndFacesLWO2(unsigned int& verts, unsigned int& face
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LWOImporter::CopyFaceIndicesLWO2(FaceList::iterator &it, void LWOImporter::CopyFaceIndicesLWO2(FaceList::iterator &it,
uint16_t *&cursor, uint16_t *&cursor,
const uint16_t* const end) const uint16_t *const end) {
{ while (cursor < end) {
while (cursor < end)
{
LWO::Face &face = *it++; LWO::Face &face = *it++;
uint16_t numIndices; uint16_t numIndices;
::memcpy(&numIndices, cursor++, 2); ::memcpy(&numIndices, cursor++, 2);
@ -861,24 +833,20 @@ void LWOImporter::CopyFaceIndicesLWO2(FaceList::iterator& it,
if (face.mNumIndices) /* byte swapping has already been done */ if (face.mNumIndices) /* byte swapping has already been done */
{ {
face.mIndices = new unsigned int[face.mNumIndices]; face.mIndices = new unsigned int[face.mNumIndices];
for(unsigned int i = 0; i < face.mNumIndices; i++) for (unsigned int i = 0; i < face.mNumIndices; i++) {
{
face.mIndices[i] = ReadVSizedIntLWO2((uint8_t *&)cursor) + mCurLayer->mPointIDXOfs; face.mIndices[i] = ReadVSizedIntLWO2((uint8_t *&)cursor) + mCurLayer->mPointIDXOfs;
if(face.mIndices[i] > mCurLayer->mTempPoints.size()) if (face.mIndices[i] > mCurLayer->mTempPoints.size()) {
{
ASSIMP_LOG_WARN("LWO2: Failure evaluating face record, index is out of range"); ASSIMP_LOG_WARN("LWO2: Failure evaluating face record, index is out of range");
face.mIndices[i] = (unsigned int)mCurLayer->mTempPoints.size() - 1; face.mIndices[i] = (unsigned int)mCurLayer->mTempPoints.size() - 1;
} }
} }
} } else
else throw DeadlyImportError("LWO2: Encountered invalid face record with zero indices"); throw DeadlyImportError("LWO2: Encountered invalid face record with zero indices");
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2PolygonTags(unsigned int length) void LWOImporter::LoadLWO2PolygonTags(unsigned int length) {
{
LE_NCONST uint8_t *const end = mFileBuffer + length; LE_NCONST uint8_t *const end = mFileBuffer + length;
AI_LWO_VALIDATE_CHUNK_LENGTH(length, PTAG, 4); AI_LWO_VALIDATE_CHUNK_LENGTH(length, PTAG, 4);
@ -887,8 +855,7 @@ void LWOImporter::LoadLWO2PolygonTags(unsigned int length)
if (type != AI_LWO_SURF && type != AI_LWO_SMGP) if (type != AI_LWO_SURF && type != AI_LWO_SMGP)
return; return;
while (mFileBuffer < end) while (mFileBuffer < end) {
{
unsigned int i = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mFaceIDXOfs; unsigned int i = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mFaceIDXOfs;
unsigned int j = GetU2(); unsigned int j = GetU2();
@ -911,8 +878,7 @@ void LWOImporter::LoadLWO2PolygonTags(unsigned int length)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <class T> template <class T>
VMapEntry* FindEntry(std::vector< T >& list,const std::string& name, bool perPoly) VMapEntry *FindEntry(std::vector<T> &list, const std::string &name, bool perPoly) {
{
for (auto &elem : list) { for (auto &elem : list) {
if (elem.name == name) { if (elem.name == name) {
if (!perPoly) { if (!perPoly) {
@ -929,8 +895,7 @@ VMapEntry* FindEntry(std::vector< T >& list,const std::string& name, bool perPol
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <class T> template <class T>
inline void CreateNewEntry(T& chan, unsigned int srcIdx) inline void CreateNewEntry(T &chan, unsigned int srcIdx) {
{
if (!chan.name.length()) if (!chan.name.length())
return; return;
@ -943,8 +908,7 @@ inline void CreateNewEntry(T& chan, unsigned int srcIdx)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <class T> template <class T>
inline void CreateNewEntry(std::vector< T >& list, unsigned int srcIdx) inline void CreateNewEntry(std::vector<T> &list, unsigned int srcIdx) {
{
for (auto &elem : list) { for (auto &elem : list) {
CreateNewEntry(elem, srcIdx); CreateNewEntry(elem, srcIdx);
} }
@ -952,8 +916,7 @@ inline void CreateNewEntry(std::vector< T >& list, unsigned int srcIdx)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
inline void LWOImporter::DoRecursiveVMAPAssignment(VMapEntry *base, unsigned int numRead, inline void LWOImporter::DoRecursiveVMAPAssignment(VMapEntry *base, unsigned int numRead,
unsigned int idx, float* data) unsigned int idx, float *data) {
{
ai_assert(NULL != data); ai_assert(NULL != data);
LWO::ReferrerList &refList = mCurLayer->mPointReferrers; LWO::ReferrerList &refList = mCurLayer->mPointReferrers;
unsigned int i; unsigned int i;
@ -972,8 +935,7 @@ inline void LWOImporter::DoRecursiveVMAPAssignment(VMapEntry* base, unsigned int
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
inline void AddToSingleLinkedList(ReferrerList& refList, unsigned int srcIdx, unsigned int destIdx) inline void AddToSingleLinkedList(ReferrerList &refList, unsigned int srcIdx, unsigned int destIdx) {
{
if (UINT_MAX == refList[srcIdx]) { if (UINT_MAX == refList[srcIdx]) {
refList[srcIdx] = destIdx; refList[srcIdx] = destIdx;
return; return;
@ -983,8 +945,7 @@ inline void AddToSingleLinkedList(ReferrerList& refList, unsigned int srcIdx, un
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Load LWO2 vertex map // Load LWO2 vertex map
void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly) void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly) {
{
LE_NCONST uint8_t *const end = mFileBuffer + length; LE_NCONST uint8_t *const end = mFileBuffer + length;
AI_LWO_VALIDATE_CHUNK_LENGTH(length, VMAP, 6); AI_LWO_VALIDATE_CHUNK_LENGTH(length, VMAP, 6);
@ -997,12 +958,10 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
std::string name; std::string name;
GetS0(name, length); GetS0(name, length);
switch (type) switch (type) {
{
case AI_LWO_TXUV: case AI_LWO_TXUV:
if (dims != 2) { if (dims != 2) {
ASSIMP_LOG_WARN("LWO2: Skipping UV channel \'" ASSIMP_LOG_WARN("LWO2: Skipping UV channel \'" + name + "\' with !2 components");
+ name + "\' with !2 components");
return; return;
} }
base = FindEntry(mCurLayer->mUVChannels, name, perPoly); base = FindEntry(mCurLayer->mUVChannels, name, perPoly);
@ -1010,18 +969,15 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
case AI_LWO_WGHT: case AI_LWO_WGHT:
case AI_LWO_MNVW: case AI_LWO_MNVW:
if (dims != 1) { if (dims != 1) {
ASSIMP_LOG_WARN("LWO2: Skipping Weight Channel \'" ASSIMP_LOG_WARN("LWO2: Skipping Weight Channel \'" + name + "\' with !1 components");
+ name + "\' with !1 components");
return; return;
} }
base = FindEntry((type == AI_LWO_WGHT ? mCurLayer->mWeightChannels base = FindEntry((type == AI_LWO_WGHT ? mCurLayer->mWeightChannels : mCurLayer->mSWeightChannels), name, perPoly);
: mCurLayer->mSWeightChannels),name,perPoly);
break; break;
case AI_LWO_RGB: case AI_LWO_RGB:
case AI_LWO_RGBA: case AI_LWO_RGBA:
if (dims != 3 && dims != 4) { if (dims != 3 && dims != 4) {
ASSIMP_LOG_WARN("LWO2: Skipping Color Map \'" ASSIMP_LOG_WARN("LWO2: Skipping Color Map \'" + name + "\' with a dimension > 4 or < 3");
+ name + "\' with a dimension > 4 or < 3");
return; return;
} }
base = FindEntry(mCurLayer->mVColorChannels, name, perPoly); base = FindEntry(mCurLayer->mVColorChannels, name, perPoly);
@ -1096,8 +1052,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
do { do {
if (tmp == srcIdx) if (tmp == srcIdx)
break; break;
} } while ((tmp = refList[tmp]) != UINT_MAX);
while ((tmp = refList[tmp]) != UINT_MAX);
if (tmp == UINT_MAX) { if (tmp == UINT_MAX) {
continue; continue;
} }
@ -1138,8 +1093,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Load LWO2 clip // Load LWO2 clip
void LWOImporter::LoadLWO2Clip(unsigned int length) void LWOImporter::LoadLWO2Clip(unsigned int length) {
{
AI_LWO_VALIDATE_CHUNK_LENGTH(length, CLIP, 10); AI_LWO_VALIDATE_CHUNK_LENGTH(length, CLIP, 10);
mClips.push_back(LWO::Clip()); mClips.push_back(LWO::Clip());
@ -1149,8 +1103,7 @@ void LWOImporter::LoadLWO2Clip(unsigned int length)
clip.idx = GetU4(); clip.idx = GetU4();
IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer); IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
switch (head.type) switch (head.type) {
{
case AI_LWO_STIL: case AI_LWO_STIL:
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, STIL, 1); AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, STIL, 1);
@ -1163,9 +1116,12 @@ void LWOImporter::LoadLWO2Clip(unsigned int length)
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, ISEQ, 16); AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, ISEQ, 16);
// Image sequence. We'll later take the first. // Image sequence. We'll later take the first.
{ {
uint8_t digits = GetU1(); mFileBuffer++; uint8_t digits = GetU1();
int16_t offset = GetU2(); mFileBuffer+=4; mFileBuffer++;
int16_t start = GetU2(); mFileBuffer+=4; int16_t offset = GetU2();
mFileBuffer += 4;
int16_t start = GetU2();
mFileBuffer += 4;
std::string s; std::string s;
std::ostringstream ss; std::ostringstream ss;
@ -1209,8 +1165,7 @@ void LWOImporter::LoadLWO2Clip(unsigned int length)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Load envelope description // Load envelope description
void LWOImporter::LoadLWO2Envelope(unsigned int length) void LWOImporter::LoadLWO2Envelope(unsigned int length) {
{
LE_NCONST uint8_t *const end = mFileBuffer + length; LE_NCONST uint8_t *const end = mFileBuffer + length;
AI_LWO_VALIDATE_CHUNK_LENGTH(length, ENVL, 4); AI_LWO_VALIDATE_CHUNK_LENGTH(length, ENVL, 4);
@ -1223,18 +1178,15 @@ void LWOImporter::LoadLWO2Envelope(unsigned int length)
// It looks like there might be an extra U4 right after the index, // It looks like there might be an extra U4 right after the index,
// at least in modo (LXOB) files: we'll ignore it if it's zero, // at least in modo (LXOB) files: we'll ignore it if it's zero,
// otherwise it represents the start of a subchunk, so we backtrack. // otherwise it represents the start of a subchunk, so we backtrack.
if (mIsLXOB) if (mIsLXOB) {
{
uint32_t extra = GetU4(); uint32_t extra = GetU4();
if (extra) if (extra) {
{
mFileBuffer -= 4; mFileBuffer -= 4;
} }
} }
// ... and read all subchunks // ... and read all subchunks
while (true) while (true) {
{
if (mFileBuffer + 6 >= end) break; if (mFileBuffer + 6 >= end) break;
LE_NCONST IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer); LE_NCONST IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
@ -1242,8 +1194,7 @@ void LWOImporter::LoadLWO2Envelope(unsigned int length)
throw DeadlyImportError("LWO2: Invalid envelope chunk length"); throw DeadlyImportError("LWO2: Invalid envelope chunk length");
uint8_t *const next = mFileBuffer + head.length; uint8_t *const next = mFileBuffer + head.length;
switch (head.type) switch (head.type) {
{
// Type & representation of the envelope // Type & representation of the envelope
case AI_LWO_TYPE: case AI_LWO_TYPE:
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, TYPE, 2); AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, TYPE, 2);
@ -1267,8 +1218,7 @@ void LWOImporter::LoadLWO2Envelope(unsigned int length)
break; break;
// keyframe // keyframe
case AI_LWO_KEY: case AI_LWO_KEY: {
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, KEY, 8); AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, KEY, 8);
envelope.keys.push_back(LWO::Key()); envelope.keys.push_back(LWO::Key());
@ -1280,27 +1230,31 @@ void LWOImporter::LoadLWO2Envelope(unsigned int length)
} }
// interval interpolation // interval interpolation
case AI_LWO_SPAN: case AI_LWO_SPAN: {
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, SPAN, 4); AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, SPAN, 4);
if (envelope.keys.size() < 2) if (envelope.keys.size() < 2)
ASSIMP_LOG_WARN("LWO2: Unexpected SPAN chunk"); ASSIMP_LOG_WARN("LWO2: Unexpected SPAN chunk");
else { else {
LWO::Key &key = envelope.keys.back(); LWO::Key &key = envelope.keys.back();
switch (GetU4()) switch (GetU4()) {
{
case AI_LWO_STEP: case AI_LWO_STEP:
key.inter = LWO::IT_STEP;break; key.inter = LWO::IT_STEP;
break;
case AI_LWO_LINE: case AI_LWO_LINE:
key.inter = LWO::IT_LINE;break; key.inter = LWO::IT_LINE;
break;
case AI_LWO_TCB: case AI_LWO_TCB:
key.inter = LWO::IT_TCB;break; key.inter = LWO::IT_TCB;
break;
case AI_LWO_HERM: case AI_LWO_HERM:
key.inter = LWO::IT_HERM;break; key.inter = LWO::IT_HERM;
break;
case AI_LWO_BEZI: case AI_LWO_BEZI:
key.inter = LWO::IT_BEZI;break; key.inter = LWO::IT_BEZI;
break;
case AI_LWO_BEZ2: case AI_LWO_BEZ2:
key.inter = LWO::IT_BEZ2;break; key.inter = LWO::IT_BEZ2;
break;
default: default:
ASSIMP_LOG_WARN("LWO2: Unknown interval interpolation mode"); ASSIMP_LOG_WARN("LWO2: Unknown interval interpolation mode");
}; };
@ -1321,19 +1275,16 @@ void LWOImporter::LoadLWO2Envelope(unsigned int length)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Load file - master function // Load file - master function
void LWOImporter::LoadLWO2File() void LWOImporter::LoadLWO2File() {
{
bool skip = false; bool skip = false;
LE_NCONST uint8_t *const end = mFileBuffer + fileSize; LE_NCONST uint8_t *const end = mFileBuffer + fileSize;
unsigned int iUnnamed = 0; unsigned int iUnnamed = 0;
while (true) while (true) {
{
if (mFileBuffer + sizeof(IFF::ChunkHeader) > end) break; if (mFileBuffer + sizeof(IFF::ChunkHeader) > end) break;
const IFF::ChunkHeader head = IFF::LoadChunk(mFileBuffer); const IFF::ChunkHeader head = IFF::LoadChunk(mFileBuffer);
if (mFileBuffer + head.length > end) if (mFileBuffer + head.length > end) {
{
throw DeadlyImportError("LWO2: Chunk length points behind the file"); throw DeadlyImportError("LWO2: Chunk length points behind the file");
break; break;
} }
@ -1344,11 +1295,9 @@ void LWOImporter::LoadLWO2File()
continue; continue;
} }
switch (head.type) switch (head.type) {
{
// new layer // new layer
case AI_LWO_LAYR: case AI_LWO_LAYR: {
{
// add a new layer to the list .... // add a new layer to the list ....
mLayers->push_back(LWO::Layer()); mLayers->push_back(LWO::Layer());
LWO::Layer &layer = mLayers->back(); LWO::Layer &layer = mLayers->back();
@ -1362,8 +1311,8 @@ void LWOImporter::LoadLWO2File()
// Continue loading this layer or ignore it? Check the layer index property // Continue loading this layer or ignore it? Check the layer index property
if (UINT_MAX != configLayerIndex && (configLayerIndex - 1) != layer.mIndex) { if (UINT_MAX != configLayerIndex && (configLayerIndex - 1) != layer.mIndex) {
skip = true; skip = true;
} } else
else skip = false; skip = false;
// pivot point // pivot point
mFileBuffer += 2; /* unknown */ mFileBuffer += 2; /* unknown */
@ -1382,13 +1331,14 @@ void LWOImporter::LoadLWO2File()
// load this layer or ignore it? Check the layer name property // load this layer or ignore it? Check the layer name property
if (configLayerName.length() && configLayerName != layer.mName) { if (configLayerName.length() && configLayerName != layer.mName) {
skip = true; skip = true;
} } else
else hasNamedLayer = true; hasNamedLayer = true;
// optional: parent of this layer // optional: parent of this layer
if (mFileBuffer + 2 <= next) if (mFileBuffer + 2 <= next)
layer.mParent = GetU2(); layer.mParent = GetU2();
else layer.mParent = -1; else
layer.mParent = (uint16_t) -1;
// Set layer skip parameter // Set layer skip parameter
layer.skip = skip; layer.skip = skip;
@ -1397,8 +1347,7 @@ void LWOImporter::LoadLWO2File()
} }
// vertex list // vertex list
case AI_LWO_PNTS: case AI_LWO_PNTS: {
{
if (skip) if (skip)
break; break;
@ -1409,25 +1358,23 @@ void LWOImporter::LoadLWO2File()
} }
// vertex tags // vertex tags
case AI_LWO_VMAD: case AI_LWO_VMAD:
if (mCurLayer->mFaces.empty()) if (mCurLayer->mFaces.empty()) {
{
ASSIMP_LOG_WARN("LWO2: Unexpected VMAD chunk"); ASSIMP_LOG_WARN("LWO2: Unexpected VMAD chunk");
break; break;
} }
// --- intentionally no break here // --- intentionally no break here
case AI_LWO_VMAP: case AI_LWO_VMAP: {
{
if (skip) if (skip)
break; break;
if (mCurLayer->mTempPoints.empty()) if (mCurLayer->mTempPoints.empty())
ASSIMP_LOG_WARN("LWO2: Unexpected VMAP chunk"); ASSIMP_LOG_WARN("LWO2: Unexpected VMAP chunk");
else LoadLWO2VertexMap(head.length,head.type == AI_LWO_VMAD); else
LoadLWO2VertexMap(head.length, head.type == AI_LWO_VMAD);
break; break;
} }
// face list // face list
case AI_LWO_POLS: case AI_LWO_POLS: {
{
if (skip) if (skip)
break; break;
@ -1437,8 +1384,7 @@ void LWOImporter::LoadLWO2File()
break; break;
} }
// polygon tags // polygon tags
case AI_LWO_PTAG: case AI_LWO_PTAG: {
{
if (skip) if (skip)
break; break;
@ -1450,8 +1396,7 @@ void LWOImporter::LoadLWO2File()
break; break;
} }
// list of tags // list of tags
case AI_LWO_TAGS: case AI_LWO_TAGS: {
{
if (!mTags->empty()) { if (!mTags->empty()) {
ASSIMP_LOG_WARN("LWO2: SRFS chunk encountered twice"); ASSIMP_LOG_WARN("LWO2: SRFS chunk encountered twice");
} else { } else {
@ -1461,22 +1406,19 @@ void LWOImporter::LoadLWO2File()
} }
// surface chunk // surface chunk
case AI_LWO_SURF: case AI_LWO_SURF: {
{
LoadLWO2Surface(head.length); LoadLWO2Surface(head.length);
break; break;
} }
// clip chunk // clip chunk
case AI_LWO_CLIP: case AI_LWO_CLIP: {
{
LoadLWO2Clip(head.length); LoadLWO2Clip(head.length);
break; break;
} }
// envelope chunk // envelope chunk
case AI_LWO_ENVL: case AI_LWO_ENVL: {
{
LoadLWO2Envelope(head.length); LoadLWO2Envelope(head.length);
break; break;
} }

View File

@ -76,9 +76,6 @@ public:
LWOImporter(); LWOImporter();
~LWOImporter(); ~LWOImporter();
public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. * See BaseImporter::CanRead() for details.
@ -86,7 +83,6 @@ public:
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const; bool checkSig) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Called prior to ReadFile(). /** Called prior to ReadFile().
* The function is a request to the importer to update its configuration * The function is a request to the importer to update its configuration
@ -389,7 +385,7 @@ protected:
unsigned int fileSize; unsigned int fileSize;
/** Output scene */ /** Output scene */
aiScene* pScene; aiScene* mScene;
/** Configuration option: speed flag set? */ /** Configuration option: speed flag set? */
bool configSpeedFlag; bool configSpeedFlag;
@ -406,8 +402,8 @@ protected:
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
inline float LWOImporter::GetF4() inline
{ float LWOImporter::GetF4() {
float f; float f;
::memcpy(&f, mFileBuffer, 4); ::memcpy(&f, mFileBuffer, 4);
mFileBuffer += 4; mFileBuffer += 4;

View File

@ -43,30 +43,24 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Implementation of the material oart of the LWO importer class */ /** @file Implementation of the material oart of the LWO importer class */
#ifndef ASSIMP_BUILD_NO_LWO_IMPORTER #ifndef ASSIMP_BUILD_NO_LWO_IMPORTER
// internal headers // internal headers
#include "LWOLoader.h" #include "LWOLoader.h"
#include <assimp/ByteSwapper.h> #include <assimp/ByteSwapper.h>
using namespace Assimp; using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <class T> template <class T>
T lerp(const T& one, const T& two, float val) T lerp(const T &one, const T &two, float val) {
{
return one + (two - one) * val; return one + (two - one) * val;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Convert a lightwave mapping mode to our's // Convert a lightwave mapping mode to our's
inline aiTextureMapMode GetMapMode(LWO::Texture::Wrap in) inline aiTextureMapMode GetMapMode(LWO::Texture::Wrap in) {
{ switch (in) {
switch (in)
{
case LWO::Texture::REPEAT: case LWO::Texture::REPEAT:
return aiTextureMapMode_Wrap; return aiTextureMapMode_Wrap;
@ -84,8 +78,7 @@ inline aiTextureMapMode GetMapMode(LWO::Texture::Wrap in)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTextureType type) bool LWOImporter::HandleTextures(aiMaterial *pcMat, const TextureList &in, aiTextureType type) {
{
ai_assert(NULL != pcMat); ai_assert(NULL != pcMat);
unsigned int cur = 0, temp = 0; unsigned int cur = 0, temp = 0;
@ -101,9 +94,8 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
// as they are, the GenUVcoords step will compute UV // as they are, the GenUVcoords step will compute UV
// channels if they're not there. // channels if they're not there.
aiTextureMapping mapping; aiTextureMapping mapping = aiTextureMapping_OTHER;
switch (texture.mapMode) switch (texture.mapMode) {
{
case LWO::Texture::Planar: case LWO::Texture::Planar:
mapping = aiTextureMapping_PLANE; mapping = aiTextureMapping_PLANE;
break; break;
@ -120,8 +112,7 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
ASSIMP_LOG_ERROR("LWO2: Unsupported texture mapping: FrontProjection"); ASSIMP_LOG_ERROR("LWO2: Unsupported texture mapping: FrontProjection");
mapping = aiTextureMapping_OTHER; mapping = aiTextureMapping_OTHER;
break; break;
case LWO::Texture::UV: case LWO::Texture::UV: {
{
if (UINT_MAX == texture.mRealUVIndex) { if (UINT_MAX == texture.mRealUVIndex) {
// We have no UV index for this texture, so we can't display it // We have no UV index for this texture, so we can't display it
continue; continue;
@ -132,8 +123,7 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
pcMat->AddProperty<int>((int *)&temp, 1, AI_MATKEY_UVWSRC(type, cur)); pcMat->AddProperty<int>((int *)&temp, 1, AI_MATKEY_UVWSRC(type, cur));
mapping = aiTextureMapping_UV; mapping = aiTextureMapping_UV;
} } break;
break;
default: default:
ai_assert(false); ai_assert(false);
}; };
@ -178,7 +168,6 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
if ((*clip).idx == temp) { if ((*clip).idx == temp) {
candidate = clip; candidate = clip;
} }
} }
if (candidate == end) { if (candidate == end) {
ASSIMP_LOG_ERROR("LWO2: Clip index is out of bounds"); ASSIMP_LOG_ERROR("LWO2: Clip index is out of bounds");
@ -191,8 +180,7 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
s.Set("$texture.png"); s.Set("$texture.png");
//continue; //continue;
} } else {
else {
if (Clip::UNSUPPORTED == (*candidate).type) { if (Clip::UNSUPPORTED == (*candidate).type) {
ASSIMP_LOG_ERROR("LWO2: Clip type is not supported"); ASSIMP_LOG_ERROR("LWO2: Clip type is not supported");
continue; continue;
@ -207,9 +195,7 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
} }
pcMat->AddProperty(&flags, 1, AI_MATKEY_TEXFLAGS(type, cur)); pcMat->AddProperty(&flags, 1, AI_MATKEY_TEXFLAGS(type, cur));
} }
} } else {
else
{
std::string ss = texture.mFileName; std::string ss = texture.mFileName;
if (!ss.length()) { if (!ss.length()) {
ASSIMP_LOG_WARN("LWOB: Empty file name"); ASSIMP_LOG_WARN("LWOB: Empty file name");
@ -224,8 +210,7 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
pcMat->AddProperty<float>(&texture.mStrength, 1, AI_MATKEY_TEXBLEND(type, cur)); pcMat->AddProperty<float>(&texture.mStrength, 1, AI_MATKEY_TEXBLEND(type, cur));
// add the blend operation // add the blend operation
switch (texture.blendType) switch (texture.blendType) {
{
case LWO::Texture::Normal: case LWO::Texture::Normal:
case LWO::Texture::Multiply: case LWO::Texture::Multiply:
temp = (unsigned int)aiTextureOp_Multiply; temp = (unsigned int)aiTextureOp_Multiply;
@ -247,7 +232,6 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
default: default:
temp = (unsigned int)aiTextureOp_Multiply; temp = (unsigned int)aiTextureOp_Multiply;
ASSIMP_LOG_WARN("LWO2: Unsupported texture blend mode: alpha or displacement"); ASSIMP_LOG_WARN("LWO2: Unsupported texture blend mode: alpha or displacement");
} }
// Setup texture operation // Setup texture operation
pcMat->AddProperty<int>((int *)&temp, 1, AI_MATKEY_TEXOP(type, cur)); pcMat->AddProperty<int>((int *)&temp, 1, AI_MATKEY_TEXOP(type, cur));
@ -270,8 +254,7 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LWOImporter::ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat) void LWOImporter::ConvertMaterial(const LWO::Surface &surf, aiMaterial *pcMat) {
{
// copy the name of the surface // copy the name of the surface
aiString st; aiString st;
st.Set(surf.mName); st.Set(surf.mName);
@ -285,28 +268,26 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat)
pcMat->AddProperty(&surf.mBumpIntensity, 1, AI_MATKEY_BUMPSCALING); pcMat->AddProperty(&surf.mBumpIntensity, 1, AI_MATKEY_BUMPSCALING);
aiShadingMode m; aiShadingMode m;
if (surf.mSpecularValue && surf.mGlossiness) if (surf.mSpecularValue && surf.mGlossiness) {
{
float fGloss; float fGloss;
if (mIsLWO2) { if (mIsLWO2) {
fGloss = std::pow(surf.mGlossiness * ai_real(10.0) + ai_real(2.0), ai_real(2.0)); fGloss = std::pow(surf.mGlossiness * ai_real(10.0) + ai_real(2.0), ai_real(2.0));
} } else {
else
{
if (16.0 >= surf.mGlossiness) if (16.0 >= surf.mGlossiness)
fGloss = 6.0; fGloss = 6.0;
else if (64.0 >= surf.mGlossiness) else if (64.0 >= surf.mGlossiness)
fGloss = 20.0; fGloss = 20.0;
else if (256.0 >= surf.mGlossiness) else if (256.0 >= surf.mGlossiness)
fGloss = 50.0; fGloss = 50.0;
else fGloss = 80.0; else
fGloss = 80.0;
} }
pcMat->AddProperty(&surf.mSpecularValue, 1, AI_MATKEY_SHININESS_STRENGTH); pcMat->AddProperty(&surf.mSpecularValue, 1, AI_MATKEY_SHININESS_STRENGTH);
pcMat->AddProperty(&fGloss, 1, AI_MATKEY_SHININESS); pcMat->AddProperty(&fGloss, 1, AI_MATKEY_SHININESS);
m = aiShadingMode_Phong; m = aiShadingMode_Phong;
} } else
else m = aiShadingMode_Gouraud; m = aiShadingMode_Gouraud;
// specular color // specular color
aiColor3D clr = lerp(aiColor3D(1.0, 1.0, 1.0), surf.mColor, surf.mColorHighlights); aiColor3D clr = lerp(aiColor3D(1.0, 1.0, 1.0), surf.mColor, surf.mColorHighlights);
@ -330,7 +311,6 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat)
pcMat->AddProperty(&def, 1, AI_MATKEY_BLEND_FUNC); pcMat->AddProperty(&def, 1, AI_MATKEY_BLEND_FUNC);
} }
// ADD TEXTURES to the material // ADD TEXTURES to the material
// TODO: find out how we can handle COLOR textures correctly... // TODO: find out how we can handle COLOR textures correctly...
bool b = HandleTextures(pcMat, surf.mColorTextures, aiTextureType_DIFFUSE); bool b = HandleTextures(pcMat, surf.mColorTextures, aiTextureType_DIFFUSE);
@ -349,15 +329,12 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat)
m = aiShadingMode_Toon; m = aiShadingMode_Toon;
break; break;
} } else if (shader.functionName == "LW_RealFresnel" || shader.functionName == "LW_FastFresnel") {
else if (shader.functionName == "LW_RealFresnel" || shader.functionName == "LW_FastFresnel") {
ASSIMP_LOG_INFO("LWO2: Mapping LW_RealFresnel/LW_FastFresnel to aiShadingMode_Fresnel"); ASSIMP_LOG_INFO("LWO2: Mapping LW_RealFresnel/LW_FastFresnel to aiShadingMode_Fresnel");
m = aiShadingMode_Fresnel; m = aiShadingMode_Fresnel;
break; break;
} } else {
else
{
ASSIMP_LOG_WARN_F("LWO2: Unknown surface shader: ", shader.functionName); ASSIMP_LOG_WARN_F("LWO2: Unknown surface shader: ", shader.functionName);
} }
} }
@ -377,8 +354,7 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
char LWOImporter::FindUVChannels(LWO::TextureList &list, char LWOImporter::FindUVChannels(LWO::TextureList &list,
LWO::Layer& /*layer*/,LWO::UVChannel& uv, unsigned int next) LWO::Layer & /*layer*/, LWO::UVChannel &uv, unsigned int next) {
{
char ret = 0; char ret = 0;
for (auto &texture : list) { for (auto &texture : list) {
@ -391,11 +367,9 @@ char LWOImporter::FindUVChannels(LWO::TextureList& list,
ret = 1; ret = 1;
// got it. // got it.
if (texture.mRealUVIndex == UINT_MAX || texture.mRealUVIndex == next) if (texture.mRealUVIndex == UINT_MAX || texture.mRealUVIndex == next) {
{
texture.mRealUVIndex = next; texture.mRealUVIndex = next;
} } else {
else {
// channel mismatch. need to duplicate the material. // channel mismatch. need to duplicate the material.
ASSIMP_LOG_WARN("LWO: Channel mismatch, would need to duplicate surface [design bug]"); ASSIMP_LOG_WARN("LWO: Channel mismatch, would need to duplicate surface [design bug]");
@ -409,8 +383,7 @@ char LWOImporter::FindUVChannels(LWO::TextureList& list,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LWOImporter::FindUVChannels(LWO::Surface &surf, void LWOImporter::FindUVChannels(LWO::Surface &surf,
LWO::SortedRep &sorted, LWO::Layer &layer, LWO::SortedRep &sorted, LWO::Layer &layer,
unsigned int out[AI_MAX_NUMBER_OF_TEXTURECOORDS]) unsigned int out[AI_MAX_NUMBER_OF_TEXTURECOORDS]) {
{
unsigned int next = 0, extra = 0, num_extra = 0; unsigned int next = 0, extra = 0, num_extra = 0;
// Check whether we have an UV entry != 0 for one of the faces in 'sorted' // Check whether we have an UV entry != 0 for one of the faces in 'sorted'
@ -429,10 +402,10 @@ void LWOImporter::FindUVChannels(LWO::Surface& surf,
if (extra >= AI_MAX_NUMBER_OF_TEXTURECOORDS) { if (extra >= AI_MAX_NUMBER_OF_TEXTURECOORDS) {
ASSIMP_LOG_ERROR("LWO: Maximum number of UV channels for " ASSIMP_LOG_ERROR("LWO: Maximum number of UV channels for "
"this mesh reached. Skipping channel \'" + uv.name + "\'"); "this mesh reached. Skipping channel \'" +
uv.name + "\'");
} } else {
else {
// Search through all textures assigned to 'surf' and look for this UV channel // Search through all textures assigned to 'surf' and look for this UV channel
char had = 0; char had = 0;
had |= FindUVChannels(surf.mColorTextures, layer, uv, next); had |= FindUVChannels(surf.mColorTextures, layer, uv, next);
@ -474,8 +447,7 @@ void LWOImporter::FindUVChannels(LWO::Surface& surf,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LWOImporter::FindVCChannels(const LWO::Surface &surf, LWO::SortedRep &sorted, const LWO::Layer &layer, void LWOImporter::FindVCChannels(const LWO::Surface &surf, LWO::SortedRep &sorted, const LWO::Layer &layer,
unsigned int out[AI_MAX_NUMBER_OF_COLOR_SETS]) unsigned int out[AI_MAX_NUMBER_OF_COLOR_SETS]) {
{
unsigned int next = 0; unsigned int next = 0;
// Check whether we have an vc entry != 0 for one of the faces in 'sorted' // Check whether we have an vc entry != 0 for one of the faces in 'sorted'
@ -489,8 +461,7 @@ void LWOImporter::FindVCChannels(const LWO::Surface& surf, LWO::SortedRep& sorte
} }
out[0] = i; out[0] = i;
++next; ++next;
} } else {
else {
for (LWO::SortedRep::iterator it = sorted.begin(); it != sorted.end(); ++it) { for (LWO::SortedRep::iterator it = sorted.begin(); it != sorted.end(); ++it) {
const LWO::Face &face = layer.mFaces[*it]; const LWO::Face &face = layer.mFaces[*it];
@ -502,10 +473,10 @@ void LWOImporter::FindVCChannels(const LWO::Surface& surf, LWO::SortedRep& sorte
if (next >= AI_MAX_NUMBER_OF_COLOR_SETS) { if (next >= AI_MAX_NUMBER_OF_COLOR_SETS) {
ASSIMP_LOG_ERROR("LWO: Maximum number of vertex color channels for " ASSIMP_LOG_ERROR("LWO: Maximum number of vertex color channels for "
"this mesh reached. Skipping channel \'" + vc.name + "\'"); "this mesh reached. Skipping channel \'" +
vc.name + "\'");
} } else {
else {
out[next++] = i; out[next++] = i;
} }
it = sorted.end() - 1; it = sorted.end() - 1;
@ -521,11 +492,9 @@ void LWOImporter::FindVCChannels(const LWO::Surface& surf, LWO::SortedRep& sorte
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2ImageMap(unsigned int size, LWO::Texture& tex ) void LWOImporter::LoadLWO2ImageMap(unsigned int size, LWO::Texture &tex) {
{
LE_NCONST uint8_t *const end = mFileBuffer + size; LE_NCONST uint8_t *const end = mFileBuffer + size;
while (true) while (true) {
{
if (mFileBuffer + 6 >= end) break; if (mFileBuffer + 6 >= end) break;
LE_NCONST IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer); LE_NCONST IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
@ -533,8 +502,7 @@ void LWOImporter::LoadLWO2ImageMap(unsigned int size, LWO::Texture& tex )
throw DeadlyImportError("LWO2: Invalid SURF.BLOCK chunk length"); throw DeadlyImportError("LWO2: Invalid SURF.BLOCK chunk length");
uint8_t *const next = mFileBuffer + head.length; uint8_t *const next = mFileBuffer + head.length;
switch (head.type) switch (head.type) {
{
case AI_LWO_PROJ: case AI_LWO_PROJ:
tex.mapMode = (Texture::MappingMode)GetU2(); tex.mapMode = (Texture::MappingMode)GetU2();
break; break;
@ -563,37 +531,32 @@ void LWOImporter::LoadLWO2ImageMap(unsigned int size, LWO::Texture& tex )
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2Procedural(unsigned int /*size*/, LWO::Texture& tex ) void LWOImporter::LoadLWO2Procedural(unsigned int /*size*/, LWO::Texture &tex) {
{
// --- not supported at the moment // --- not supported at the moment
ASSIMP_LOG_ERROR("LWO2: Found procedural texture, this is not supported"); ASSIMP_LOG_ERROR("LWO2: Found procedural texture, this is not supported");
tex.bCanUse = false; tex.bCanUse = false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2Gradient(unsigned int /*size*/, LWO::Texture& tex ) void LWOImporter::LoadLWO2Gradient(unsigned int /*size*/, LWO::Texture &tex) {
{
// --- not supported at the moment // --- not supported at the moment
ASSIMP_LOG_ERROR("LWO2: Found gradient texture, this is not supported"); ASSIMP_LOG_ERROR("LWO2: Found gradient texture, this is not supported");
tex.bCanUse = false; tex.bCanUse = false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2TextureHeader(unsigned int size, LWO::Texture& tex ) void LWOImporter::LoadLWO2TextureHeader(unsigned int size, LWO::Texture &tex) {
{
LE_NCONST uint8_t *const end = mFileBuffer + size; LE_NCONST uint8_t *const end = mFileBuffer + size;
// get the ordinal string // get the ordinal string
GetS0(tex.ordinal, size); GetS0(tex.ordinal, size);
// we could crash later if this is an empty string ... // we could crash later if this is an empty string ...
if (!tex.ordinal.length()) if (!tex.ordinal.length()) {
{
ASSIMP_LOG_ERROR("LWO2: Ill-formed SURF.BLOK ordinal string"); ASSIMP_LOG_ERROR("LWO2: Ill-formed SURF.BLOK ordinal string");
tex.ordinal = "\x00"; tex.ordinal = "\x00";
} }
while (true) while (true) {
{
if (mFileBuffer + 6 >= end) break; if (mFileBuffer + 6 >= end) break;
const IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer); const IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
@ -601,8 +564,7 @@ void LWOImporter::LoadLWO2TextureHeader(unsigned int size, LWO::Texture& tex )
throw DeadlyImportError("LWO2: Invalid texture header chunk length"); throw DeadlyImportError("LWO2: Invalid texture header chunk length");
uint8_t *const next = mFileBuffer + head.length; uint8_t *const next = mFileBuffer + head.length;
switch (head.type) switch (head.type) {
{
case AI_LWO_CHAN: case AI_LWO_CHAN:
tex.type = GetU4(); tex.type = GetU4();
break; break;
@ -619,8 +581,7 @@ void LWOImporter::LoadLWO2TextureHeader(unsigned int size, LWO::Texture& tex )
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader* head, unsigned int size ) void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader *head, unsigned int size) {
{
ai_assert(!mSurfaces->empty()); ai_assert(!mSurfaces->empty());
LWO::Surface &surf = mSurfaces->back(); LWO::Surface &surf = mSurfaces->back();
LWO::Texture tex; LWO::Texture tex;
@ -630,8 +591,7 @@ void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader* head, unsi
size -= head->length + 6; size -= head->length + 6;
// now get the exact type of the texture // now get the exact type of the texture
switch (head->type) switch (head->type) {
{
case AI_LWO_PROC: case AI_LWO_PROC:
LoadLWO2Procedural(size, tex); LoadLWO2Procedural(size, tex);
break; break;
@ -644,22 +604,28 @@ void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader* head, unsi
// get the destination channel // get the destination channel
TextureList *listRef = NULL; TextureList *listRef = NULL;
switch (tex.type) switch (tex.type) {
{
case AI_LWO_COLR: case AI_LWO_COLR:
listRef = &surf.mColorTextures;break; listRef = &surf.mColorTextures;
break;
case AI_LWO_DIFF: case AI_LWO_DIFF:
listRef = &surf.mDiffuseTextures;break; listRef = &surf.mDiffuseTextures;
break;
case AI_LWO_SPEC: case AI_LWO_SPEC:
listRef = &surf.mSpecularTextures;break; listRef = &surf.mSpecularTextures;
break;
case AI_LWO_GLOS: case AI_LWO_GLOS:
listRef = &surf.mGlossinessTextures;break; listRef = &surf.mGlossinessTextures;
break;
case AI_LWO_BUMP: case AI_LWO_BUMP:
listRef = &surf.mBumpTextures;break; listRef = &surf.mBumpTextures;
break;
case AI_LWO_TRAN: case AI_LWO_TRAN:
listRef = &surf.mOpacityTextures;break; listRef = &surf.mOpacityTextures;
break;
case AI_LWO_REFL: case AI_LWO_REFL:
listRef = &surf.mReflectionTextures;break; listRef = &surf.mReflectionTextures;
break;
default: default:
ASSIMP_LOG_WARN("LWO2: Encountered unknown texture type"); ASSIMP_LOG_WARN("LWO2: Encountered unknown texture type");
return; return;
@ -676,8 +642,7 @@ void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader* head, unsi
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader* /*head*/, unsigned int size ) void LWOImporter::LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader * /*head*/, unsigned int size) {
{
LE_NCONST uint8_t *const end = mFileBuffer + size; LE_NCONST uint8_t *const end = mFileBuffer + size;
ai_assert(!mSurfaces->empty()); ai_assert(!mSurfaces->empty());
@ -688,15 +653,13 @@ void LWOImporter::LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader* /*head*/, u
GetS0(shader.ordinal, size); GetS0(shader.ordinal, size);
// we could crash later if this is an empty string ... // we could crash later if this is an empty string ...
if (!shader.ordinal.length()) if (!shader.ordinal.length()) {
{
ASSIMP_LOG_ERROR("LWO2: Ill-formed SURF.BLOK ordinal string"); ASSIMP_LOG_ERROR("LWO2: Ill-formed SURF.BLOK ordinal string");
shader.ordinal = "\x00"; shader.ordinal = "\x00";
} }
// read the header // read the header
while (true) while (true) {
{
if (mFileBuffer + 6 >= end) break; if (mFileBuffer + 6 >= end) break;
const IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer); const IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
@ -704,8 +667,7 @@ void LWOImporter::LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader* /*head*/, u
throw DeadlyImportError("LWO2: Invalid shader header chunk length"); throw DeadlyImportError("LWO2: Invalid shader header chunk length");
uint8_t *const next = mFileBuffer + head.length; uint8_t *const next = mFileBuffer + head.length;
switch (head.type) switch (head.type) {
{
case AI_LWO_ENAB: case AI_LWO_ENAB:
shader.enabled = GetU2() ? true : false; shader.enabled = GetU2() ? true : false;
break; break;
@ -727,8 +689,7 @@ void LWOImporter::LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader* /*head*/, u
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2Surface(unsigned int size) void LWOImporter::LoadLWO2Surface(unsigned int size) {
{
LE_NCONST uint8_t *const end = mFileBuffer + size; LE_NCONST uint8_t *const end = mFileBuffer + size;
mSurfaces->push_back(LWO::Surface()); mSurfaces->push_back(LWO::Surface());
@ -741,19 +702,20 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
GetS0(derived, (unsigned int)(end - mFileBuffer)); GetS0(derived, (unsigned int)(end - mFileBuffer));
if (derived.length()) { if (derived.length()) {
// yes, find this surface // yes, find this surface
for (SurfaceList::iterator it = mSurfaces->begin(), end = mSurfaces->end()-1; it != end; ++it) { for (SurfaceList::iterator it = mSurfaces->begin(), itEnd = mSurfaces->end() - 1; it != itEnd; ++it) {
if ((*it).mName == derived) { if ((*it).mName == derived) {
// we have it ... // we have it ...
surf = *it; surf = *it;
derived.clear();break; derived.clear();
break;
} }
} }
if (derived.size()) if (derived.size()) {
ASSIMP_LOG_WARN("LWO2: Unable to find source surface: " + derived); ASSIMP_LOG_WARN("LWO2: Unable to find source surface: " + derived);
} }
}
while (true) while (true) {
{
if (mFileBuffer + 6 >= end) if (mFileBuffer + 6 >= end)
break; break;
const IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer); const IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
@ -762,11 +724,9 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
throw DeadlyImportError("LWO2: Invalid surface chunk length"); throw DeadlyImportError("LWO2: Invalid surface chunk length");
uint8_t *const next = mFileBuffer + head.length; uint8_t *const next = mFileBuffer + head.length;
switch (head.type) switch (head.type) {
{
// diffuse color // diffuse color
case AI_LWO_COLR: case AI_LWO_COLR: {
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, COLR, 12); AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, COLR, 12);
surf.mColor.r = GetF4(); surf.mColor.r = GetF4();
surf.mColor.g = GetF4(); surf.mColor.g = GetF4();
@ -774,22 +734,19 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
break; break;
} }
// diffuse strength ... hopefully // diffuse strength ... hopefully
case AI_LWO_DIFF: case AI_LWO_DIFF: {
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, DIFF, 4); AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, DIFF, 4);
surf.mDiffuseValue = GetF4(); surf.mDiffuseValue = GetF4();
break; break;
} }
// specular strength ... hopefully // specular strength ... hopefully
case AI_LWO_SPEC: case AI_LWO_SPEC: {
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, SPEC, 4); AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, SPEC, 4);
surf.mSpecularValue = GetF4(); surf.mSpecularValue = GetF4();
break; break;
} }
// transparency // transparency
case AI_LWO_TRAN: case AI_LWO_TRAN: {
{
// transparency explicitly disabled? // transparency explicitly disabled?
if (surf.mTransparency == 10e10f) if (surf.mTransparency == 10e10f)
break; break;
@ -799,65 +756,56 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
break; break;
} }
// additive transparency // additive transparency
case AI_LWO_ADTR: case AI_LWO_ADTR: {
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, ADTR, 4); AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, ADTR, 4);
surf.mAdditiveTransparency = GetF4(); surf.mAdditiveTransparency = GetF4();
break; break;
} }
// wireframe mode // wireframe mode
case AI_LWO_LINE: case AI_LWO_LINE: {
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, LINE, 2); AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, LINE, 2);
if (GetU2() & 0x1) if (GetU2() & 0x1)
surf.mWireframe = true; surf.mWireframe = true;
break; break;
} }
// glossiness // glossiness
case AI_LWO_GLOS: case AI_LWO_GLOS: {
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, GLOS, 4); AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, GLOS, 4);
surf.mGlossiness = GetF4(); surf.mGlossiness = GetF4();
break; break;
} }
// bump intensity // bump intensity
case AI_LWO_BUMP: case AI_LWO_BUMP: {
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, BUMP, 4); AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, BUMP, 4);
surf.mBumpIntensity = GetF4(); surf.mBumpIntensity = GetF4();
break; break;
} }
// color highlights // color highlights
case AI_LWO_CLRH: case AI_LWO_CLRH: {
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, CLRH, 4); AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, CLRH, 4);
surf.mColorHighlights = GetF4(); surf.mColorHighlights = GetF4();
break; break;
} }
// index of refraction // index of refraction
case AI_LWO_RIND: case AI_LWO_RIND: {
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, RIND, 4); AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, RIND, 4);
surf.mIOR = GetF4(); surf.mIOR = GetF4();
break; break;
} }
// polygon sidedness // polygon sidedness
case AI_LWO_SIDE: case AI_LWO_SIDE: {
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, SIDE, 2); AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, SIDE, 2);
surf.bDoubleSided = (3 == GetU2()); surf.bDoubleSided = (3 == GetU2());
break; break;
} }
// maximum smoothing angle // maximum smoothing angle
case AI_LWO_SMAN: case AI_LWO_SMAN: {
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, SMAN, 4); AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, SMAN, 4);
surf.mMaximumSmoothAngle = std::fabs(GetF4()); surf.mMaximumSmoothAngle = std::fabs(GetF4());
break; break;
} }
// vertex color channel to be applied to the surface // vertex color channel to be applied to the surface
case AI_LWO_VCOL: case AI_LWO_VCOL: {
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, VCOL, 12); AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, VCOL, 12);
surf.mDiffuseValue *= GetF4(); // strength surf.mDiffuseValue *= GetF4(); // strength
ReadVSizedIntLWO2(mFileBuffer); // skip envelope ReadVSizedIntLWO2(mFileBuffer); // skip envelope
@ -868,13 +816,11 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
break; break;
} }
// surface bock entry // surface bock entry
case AI_LWO_BLOK: case AI_LWO_BLOK: {
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, BLOK, 4); AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, BLOK, 4);
IFF::SubChunkHeader head2 = IFF::LoadSubChunk(mFileBuffer); IFF::SubChunkHeader head2 = IFF::LoadSubChunk(mFileBuffer);
switch (head2.type) switch (head2.type) {
{
case AI_LWO_PROC: case AI_LWO_PROC:
case AI_LWO_GRAD: case AI_LWO_GRAD:
case AI_LWO_IMAP: case AI_LWO_IMAP:

View File

@ -45,22 +45,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the LWS importer class * @brief Implementation of the LWS importer class
*/ */
#ifndef ASSIMP_BUILD_NO_LWS_IMPORTER #ifndef ASSIMP_BUILD_NO_LWS_IMPORTER
#include "LWS/LWSLoader.h" #include "LWS/LWSLoader.h"
#include "PostProcessing/ConvertToLHProcess.h"
#include "Common/Importer.h" #include "Common/Importer.h"
#include "PostProcessing/ConvertToLHProcess.h"
#include <assimp/ParsingUtils.h>
#include <assimp/fast_atof.h>
#include <assimp/SceneCombiner.h>
#include <assimp/GenericProperty.h> #include <assimp/GenericProperty.h>
#include <assimp/ParsingUtils.h>
#include <assimp/SceneCombiner.h>
#include <assimp/SkeletonMeshBuilder.h> #include <assimp/SkeletonMeshBuilder.h>
#include <assimp/DefaultLogger.hpp> #include <assimp/fast_atof.h>
#include <assimp/scene.h>
#include <assimp/IOSystem.hpp>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <memory> #include <memory>
@ -81,8 +80,7 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Recursive parsing of LWS files // Recursive parsing of LWS files
void LWS::Element::Parse (const char*& buffer) void LWS::Element::Parse(const char *&buffer) {
{
for (; SkipSpacesAndLineEnd(&buffer); SkipLine(&buffer)) { for (; SkipSpacesAndLineEnd(&buffer); SkipLine(&buffer)) {
// begin of a new element with children // begin of a new element with children
@ -91,8 +89,7 @@ void LWS::Element::Parse (const char*& buffer)
++buffer; ++buffer;
SkipSpaces(&buffer); SkipSpaces(&buffer);
sub = true; sub = true;
} } else if (*buffer == '}')
else if (*buffer == '}')
return; return;
children.push_back(Element()); children.push_back(Element());
@ -100,12 +97,12 @@ void LWS::Element::Parse (const char*& buffer)
// copy data line - read token per token // copy data line - read token per token
const char *cur = buffer; const char *cur = buffer;
while (!IsSpaceOrNewLine(*buffer)) ++buffer; while (!IsSpaceOrNewLine(*buffer))
++buffer;
children.back().tokens[0] = std::string(cur, (size_t)(buffer - cur)); children.back().tokens[0] = std::string(cur, (size_t)(buffer - cur));
SkipSpaces(&buffer); SkipSpaces(&buffer);
if (children.back().tokens[0] == "Plugin") if (children.back().tokens[0] == "Plugin") {
{
ASSIMP_LOG_DEBUG("LWS: Skipping over plugin-specific data"); ASSIMP_LOG_DEBUG("LWS: Skipping over plugin-specific data");
// strange stuff inside Plugin/Endplugin blocks. Needn't // strange stuff inside Plugin/Endplugin blocks. Needn't
@ -120,7 +117,8 @@ void LWS::Element::Parse (const char*& buffer)
} }
cur = buffer; cur = buffer;
while (!IsLineEnd(*buffer)) ++buffer; while (!IsLineEnd(*buffer))
++buffer;
children.back().tokens[1] = std::string(cur, (size_t)(buffer - cur)); children.back().tokens[1] = std::string(cur, (size_t)(buffer - cur));
// parse more elements recursively // parse more elements recursively
@ -131,28 +129,25 @@ void LWS::Element::Parse (const char*& buffer)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
LWSImporter::LWSImporter() LWSImporter::LWSImporter() :
: configSpeedFlag(), configSpeedFlag(),
io(), io(),
first(), first(),
last(), last(),
fps(), fps(),
noSkeletonMesh() noSkeletonMesh() {
{
// nothing to do here // nothing to do here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
LWSImporter::~LWSImporter() LWSImporter::~LWSImporter() {
{
// nothing to do here // nothing to do here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool LWSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler,bool checkSig) const bool LWSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
{
const std::string extension = GetExtension(pFile); const std::string extension = GetExtension(pFile);
if (extension == "lws" || extension == "mot") if (extension == "lws" || extension == "mot")
return true; return true;
@ -169,15 +164,13 @@ bool LWSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler,bool c
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get list of file extensions // Get list of file extensions
const aiImporterDesc* LWSImporter::GetInfo () const const aiImporterDesc *LWSImporter::GetInfo() const {
{
return &desc; return &desc;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Setup configuration properties // Setup configuration properties
void LWSImporter::SetupProperties(const Importer* pImp) void LWSImporter::SetupProperties(const Importer *pImp) {
{
// AI_CONFIG_FAVOUR_SPEED // AI_CONFIG_FAVOUR_SPEED
configSpeedFlag = (0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED, 0)); configSpeedFlag = (0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED, 0));
@ -198,15 +191,15 @@ void LWSImporter::SetupProperties(const Importer* pImp)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Read an envelope description // Read an envelope description
void LWSImporter::ReadEnvelope(const LWS::Element& dad, LWO::Envelope& fill ) void LWSImporter::ReadEnvelope(const LWS::Element &dad, LWO::Envelope &fill) {
{
if (dad.children.empty()) { if (dad.children.empty()) {
ASSIMP_LOG_ERROR("LWS: Envelope descriptions must not be empty"); ASSIMP_LOG_ERROR("LWS: Envelope descriptions must not be empty");
return; return;
} }
// reserve enough storage // reserve enough storage
std::list< LWS::Element >::const_iterator it = dad.children.begin();; std::list<LWS::Element>::const_iterator it = dad.children.begin();
;
fill.keys.reserve(strtoul10(it->tokens[1].c_str())); fill.keys.reserve(strtoul10(it->tokens[1].c_str()));
for (++it; it != dad.children.end(); ++it) { for (++it; it != dad.children.end(); ++it) {
@ -255,8 +248,7 @@ void LWSImporter::ReadEnvelope(const LWS::Element& dad, LWO::Envelope& fill )
SkipSpaces(&c); SkipSpaces(&c);
c = fast_atoreal_move<float>(c, key.params[i]); c = fast_atoreal_move<float>(c, key.params[i]);
} }
} } else if ((*it).tokens[0] == "Behaviors") {
else if ((*it).tokens[0] == "Behaviors") {
SkipSpaces(&c); SkipSpaces(&c);
fill.pre = (LWO::PrePostBehaviour)strtoul10(c, &c); fill.pre = (LWO::PrePostBehaviour)strtoul10(c, &c);
SkipSpaces(&c); SkipSpaces(&c);
@ -271,8 +263,7 @@ void LWSImporter::ReadEnvelope_Old(
std::list<LWS::Element>::const_iterator &it, std::list<LWS::Element>::const_iterator &it,
const std::list<LWS::Element>::const_iterator &end, const std::list<LWS::Element>::const_iterator &end,
LWS::NodeDesc &nodes, LWS::NodeDesc &nodes,
unsigned int /*version*/) unsigned int /*version*/) {
{
unsigned int num, sub_num; unsigned int num, sub_num;
if (++it == end) goto unexpected_end; if (++it == end) goto unexpected_end;
@ -311,8 +302,7 @@ unexpected_end:
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Setup a nice name for a node // Setup a nice name for a node
void LWSImporter::SetupNodeName(aiNode* nd, LWS::NodeDesc& src) void LWSImporter::SetupNodeName(aiNode *nd, LWS::NodeDesc &src) {
{
const unsigned int combined = src.number | ((unsigned int)src.type) << 28u; const unsigned int combined = src.number | ((unsigned int)src.type) << 28u;
// the name depends on the type. We break LWS's strange naming convention // the name depends on the type. We break LWS's strange naming convention
@ -323,7 +313,8 @@ void LWSImporter::SetupNodeName(aiNode* nd, LWS::NodeDesc& src)
std::string::size_type s = src.path.find_last_of("\\/"); std::string::size_type s = src.path.find_last_of("\\/");
if (s == std::string::npos) if (s == std::string::npos)
s = 0; s = 0;
else ++s; else
++s;
std::string::size_type t = src.path.substr(s).find_last_of("."); std::string::size_type t = src.path.substr(s).find_last_of(".");
nd->mName.length = ::ai_snprintf(nd->mName.data, MAXLEN, "%s_(%08X)", src.path.substr(s).substr(0, t).c_str(), combined); nd->mName.length = ::ai_snprintf(nd->mName.data, MAXLEN, "%s_(%08X)", src.path.substr(s).substr(0, t).c_str(), combined);
@ -339,8 +330,7 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
BatchLoader &batch, BatchLoader &batch,
aiCamera **&camOut, aiCamera **&camOut,
aiLight **&lightOut, aiLight **&lightOut,
std::vector<aiNodeAnim*>& animOut) std::vector<aiNodeAnim *> &animOut) {
{
// Setup a very cryptic name for the node, we want the user to be happy // Setup a very cryptic name for the node, we want the user to be happy
SetupNodeName(nd, src); SetupNodeName(nd, src);
aiNode *ndAnim = nd; aiNode *ndAnim = nd;
@ -354,8 +344,7 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
obj = batch.GetImport(src.id); obj = batch.GetImport(src.id);
if (!obj) { if (!obj) {
ASSIMP_LOG_ERROR("LWS: Failed to read external file " + src.path); ASSIMP_LOG_ERROR("LWS: Failed to read external file " + src.path);
} } else {
else {
if (obj->mRootNode->mNumChildren == 1) { if (obj->mRootNode->mNumChildren == 1) {
//If the pivot is not set for this layer, get it from the external object //If the pivot is not set for this layer, get it from the external object
@ -418,11 +407,10 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
lit->mAngleInnerCone = (float)AI_DEG_TO_RAD(src.lightConeAngle); lit->mAngleInnerCone = (float)AI_DEG_TO_RAD(src.lightConeAngle);
lit->mAngleOuterCone = lit->mAngleInnerCone + (float)AI_DEG_TO_RAD(src.lightEdgeAngle); lit->mAngleOuterCone = lit->mAngleInnerCone + (float)AI_DEG_TO_RAD(src.lightEdgeAngle);
} } else if (src.lightType == 1) { /* directional light source */
else if (src.lightType == 1) { /* directional light source */
lit->mType = aiLightSource_DIRECTIONAL; lit->mType = aiLightSource_DIRECTIONAL;
} } else
else lit->mType = aiLightSource_POINT; lit->mType = aiLightSource_POINT;
// fixme: no proper handling of light falloffs yet // fixme: no proper handling of light falloffs yet
if (src.lightFalloffType == 1) if (src.lightFalloffType == 1)
@ -471,15 +459,13 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Determine the exact location of a LWO file // Determine the exact location of a LWO file
std::string LWSImporter::FindLWOFile(const std::string& in) std::string LWSImporter::FindLWOFile(const std::string &in) {
{
// insert missing directory separator if necessary // insert missing directory separator if necessary
std::string tmp; std::string tmp;
if (in.length() > 3 && in[1] == ':'&& in[2] != '\\' && in[2] != '/') if (in.length() > 3 && in[1] == ':' && in[2] != '\\' && in[2] != '/') {
{
tmp = in[0] + (std::string(":\\") + in.substr(2)); tmp = in[0] + (std::string(":\\") + in.substr(2));
} } else
else tmp = in; tmp = in;
if (io->Exists(tmp)) { if (io->Exists(tmp)) {
return in; return in;
@ -503,7 +489,6 @@ std::string LWSImporter::FindLWOFile(const std::string& in)
return test; return test;
} }
// return original path, maybe the IOsystem knows better // return original path, maybe the IOsystem knows better
return tmp; return tmp;
} }
@ -511,8 +496,7 @@ std::string LWSImporter::FindLWOFile(const std::string& in)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Read file into given scene data structure // Read file into given scene data structure
void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene,
IOSystem* pIOHandler) IOSystem *pIOHandler) {
{
io = pIOHandler; io = pIOHandler;
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb")); std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb"));
@ -526,7 +510,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
TextFileToBuffer(file.get(), mBuffer); TextFileToBuffer(file.get(), mBuffer);
// Parse the file structure // Parse the file structure
LWS::Element root; const char* dummy = &mBuffer[0]; LWS::Element root;
const char *dummy = &mBuffer[0];
root.Parse(dummy); root.Parse(dummy);
// Construct a Batchimporter to read more files recursively // Construct a Batchimporter to read more files recursively
@ -594,8 +579,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (version >= 4) { // handle LWSC 4 explicit ID if (version >= 4) { // handle LWSC 4 explicit ID
SkipSpaces(&c); SkipSpaces(&c);
d.number = strtoul16(c, &c) & AI_LWS_MASK; d.number = strtoul16(c, &c) & AI_LWS_MASK;
} } else
else d.number = cur_object++; d.number = cur_object++;
// and add the file to the import list // and add the file to the import list
SkipSpaces(&c); SkipSpaces(&c);
@ -616,8 +601,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (version >= 4) { // handle LWSC 4 explicit ID if (version >= 4) { // handle LWSC 4 explicit ID
d.number = strtoul16(c, &c) & AI_LWS_MASK; d.number = strtoul16(c, &c) & AI_LWS_MASK;
SkipSpaces(&c); SkipSpaces(&c);
} } else
else d.number = cur_object++; d.number = cur_object++;
std::string path = FindLWOFile(c); std::string path = FindLWOFile(c);
d.id = batch.AddLoadRequest(path, 0, NULL); d.id = batch.AddLoadRequest(path, 0, NULL);
@ -634,8 +619,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (version >= 4) { // handle LWSC 4 explicit ID if (version >= 4) { // handle LWSC 4 explicit ID
d.number = strtoul16(c, &c) & AI_LWS_MASK; d.number = strtoul16(c, &c) & AI_LWS_MASK;
SkipSpaces(&c); SkipSpaces(&c);
} } else
else d.number = cur_object++; d.number = cur_object++;
d.name = c; d.name = c;
nodes.push_back(d); nodes.push_back(d);
@ -695,11 +680,13 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (nodes.empty()) if (nodes.empty())
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'Pre/PostBehavior'"); ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'Pre/PostBehavior'");
else { else {
for (std::list<LWO::Envelope>::iterator it = nodes.back().channels.begin(); it != nodes.back().channels.end(); ++it) { for (std::list<LWO::Envelope>::iterator envelopeIt = nodes.back().channels.begin(); envelopeIt != nodes.back().channels.end(); ++envelopeIt) {
// two ints per envelope // two ints per envelope
LWO::Envelope& env = *it; LWO::Envelope &env = *envelopeIt;
env.pre = (LWO::PrePostBehaviour) strtoul10(c,&c); SkipSpaces(&c); env.pre = (LWO::PrePostBehaviour)strtoul10(c, &c);
env.post = (LWO::PrePostBehaviour) strtoul10(c,&c); SkipSpaces(&c); SkipSpaces(&c);
env.post = (LWO::PrePostBehaviour)strtoul10(c, &c);
SkipSpaces(&c);
} }
} }
} }
@ -708,7 +695,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (nodes.empty()) if (nodes.empty())
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'ParentItem\'"); ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'ParentItem\'");
else nodes.back().parent = strtoul16(c,&c); else
nodes.back().parent = strtoul16(c, &c);
} }
// 'ParentObject': deprecated one for older formats // 'ParentObject': deprecated one for older formats
else if (version < 3 && (*it).tokens[0] == "ParentObject") { else if (version < 3 && (*it).tokens[0] == "ParentObject") {
@ -728,8 +716,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (version >= 4) { // handle LWSC 4 explicit ID if (version >= 4) { // handle LWSC 4 explicit ID
d.number = strtoul16(c, &c) & AI_LWS_MASK; d.number = strtoul16(c, &c) & AI_LWS_MASK;
} } else
else d.number = cur_camera++; d.number = cur_camera++;
nodes.push_back(d); nodes.push_back(d);
num_camera++; num_camera++;
@ -739,7 +727,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::CAMERA) if (nodes.empty() || nodes.back().type != LWS::NodeDesc::CAMERA)
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'CameraName\'"); ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'CameraName\'");
else nodes.back().name = c; else
nodes.back().name = c;
} }
// 'AddLight': add a light to the scenegraph // 'AddLight': add a light to the scenegraph
else if ((*it).tokens[0] == "AddLight") { else if ((*it).tokens[0] == "AddLight") {
@ -750,8 +739,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (version >= 4) { // handle LWSC 4 explicit ID if (version >= 4) { // handle LWSC 4 explicit ID
d.number = strtoul16(c, &c) & AI_LWS_MASK; d.number = strtoul16(c, &c) & AI_LWS_MASK;
} } else
else d.number = cur_light++; d.number = cur_light++;
nodes.push_back(d); nodes.push_back(d);
num_light++; num_light++;
@ -761,14 +750,16 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightName\'"); ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightName\'");
else nodes.back().name = c; else
nodes.back().name = c;
} }
// 'LightIntensity': set intensity of currently active light // 'LightIntensity': set intensity of currently active light
else if ((*it).tokens[0] == "LightIntensity" || (*it).tokens[0] == "LgtIntensity") { else if ((*it).tokens[0] == "LightIntensity" || (*it).tokens[0] == "LgtIntensity") {
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightIntensity\'"); ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightIntensity\'");
else fast_atoreal_move<float>(c, nodes.back().lightIntensity ); else
fast_atoreal_move<float>(c, nodes.back().lightIntensity);
} }
// 'LightType': set type of currently active light // 'LightType': set type of currently active light
@ -776,7 +767,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightType\'"); ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightType\'");
else nodes.back().lightType = strtoul10(c); else
nodes.back().lightType = strtoul10(c);
} }
// 'LightFalloffType': set falloff type of currently active light // 'LightFalloffType': set falloff type of currently active light
@ -784,7 +776,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightFalloffType\'"); ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightFalloffType\'");
else nodes.back().lightFalloffType = strtoul10(c); else
nodes.back().lightFalloffType = strtoul10(c);
} }
// 'LightConeAngle': set cone angle of currently active light // 'LightConeAngle': set cone angle of currently active light
@ -792,7 +785,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightConeAngle\'"); ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightConeAngle\'");
else nodes.back().lightConeAngle = fast_atof(c); else
nodes.back().lightConeAngle = fast_atof(c);
} }
// 'LightEdgeAngle': set area where we're smoothing from min to max intensity // 'LightEdgeAngle': set area where we're smoothing from min to max intensity
@ -800,7 +794,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightEdgeAngle\'"); ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightEdgeAngle\'");
else nodes.back().lightEdgeAngle = fast_atof(c); else
nodes.back().lightEdgeAngle = fast_atof(c);
} }
// 'LightColor': set color of currently active light // 'LightColor': set color of currently active light
@ -834,32 +829,33 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
} }
// resolve parenting // resolve parenting
for (std::list<LWS::NodeDesc>::iterator it = nodes.begin(); it != nodes.end(); ++it) { for (std::list<LWS::NodeDesc>::iterator ndIt = nodes.begin(); ndIt != nodes.end(); ++ndIt) {
// check whether there is another node which calls us a parent // check whether there is another node which calls us a parent
for (std::list<LWS::NodeDesc>::iterator dit = nodes.begin(); dit != nodes.end(); ++dit) { for (std::list<LWS::NodeDesc>::iterator dit = nodes.begin(); dit != nodes.end(); ++dit) {
if (dit != it && *it == (*dit).parent) { if (dit != ndIt && *ndIt == (*dit).parent) {
if ((*dit).parent_resolved) { if ((*dit).parent_resolved) {
// fixme: it's still possible to produce an overflow due to cross references .. // fixme: it's still possible to produce an overflow due to cross references ..
ASSIMP_LOG_ERROR("LWS: Found cross reference in scene-graph"); ASSIMP_LOG_ERROR("LWS: Found cross reference in scene-graph");
continue; continue;
} }
(*it).children.push_back(&*dit); ndIt->children.push_back(&*dit);
(*dit).parent_resolved = &*it; (*dit).parent_resolved = &*ndIt;
} }
} }
} }
// find out how many nodes have no parent yet // find out how many nodes have no parent yet
unsigned int no_parent = 0; unsigned int no_parent = 0;
for (std::list<LWS::NodeDesc>::iterator it = nodes.begin(); it != nodes.end(); ++it) { for (std::list<LWS::NodeDesc>::iterator ndIt = nodes.begin(); ndIt != nodes.end(); ++ndIt) {
if (!(*it).parent_resolved) if (!ndIt->parent_resolved) {
++no_parent; ++no_parent;
} }
if (!no_parent) }
if (!no_parent) {
throw DeadlyImportError("LWS: Unable to find scene root node"); throw DeadlyImportError("LWS: Unable to find scene root node");
}
// Load all subsequent files // Load all subsequent files
batch.LoadAll(); batch.LoadAll();
@ -884,14 +880,14 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
nd->mName.Set("<LWSRoot>"); nd->mName.Set("<LWSRoot>");
nd->mChildren = new aiNode *[no_parent]; nd->mChildren = new aiNode *[no_parent];
for (std::list<LWS::NodeDesc>::iterator it = nodes.begin(); it != nodes.end(); ++it) { for (std::list<LWS::NodeDesc>::iterator ndIt = nodes.begin(); ndIt != nodes.end(); ++ndIt) {
if (!(*it).parent_resolved) { if (!ndIt->parent_resolved) {
aiNode *ro = nd->mChildren[nd->mNumChildren++] = new aiNode(); aiNode *ro = nd->mChildren[nd->mNumChildren++] = new aiNode();
ro->mParent = nd; ro->mParent = nd;
// ... and build the scene graph. If we encounter object nodes, // ... and build the scene graph. If we encounter object nodes,
// add then to our attachment table. // add then to our attachment table.
BuildGraph(ro,*it, attach, batch, cams, lights, anims); BuildGraph(ro, *ndIt, attach, batch, cams, lights, anims);
} }
} }
@ -920,7 +916,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
// OK ... finally build the output graph // OK ... finally build the output graph
SceneCombiner::MergeScenes(&pScene, master, attach, SceneCombiner::MergeScenes(&pScene, master, attach,
AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES | (!configSpeedFlag ? ( AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES | (!configSpeedFlag ? (
AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY | AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES) : 0)); AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY | AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES) :
0));
// Check flags // Check flags
if (!pScene->mNumMeshes || !pScene->mNumMaterials) { if (!pScene->mNumMeshes || !pScene->mNumMaterials) {
@ -931,7 +928,6 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
SkeletonMeshBuilder builder(pScene); SkeletonMeshBuilder builder(pScene);
} }
} }
} }
#endif // !! ASSIMP_BUILD_NO_LWS_IMPORTER #endif // !! ASSIMP_BUILD_NO_LWS_IMPORTER

View File

@ -64,9 +64,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/Exporter.hpp> #include <assimp/Exporter.hpp>
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
#include "M3DWrapper.h"
#include "M3DExporter.h" #include "M3DExporter.h"
#include "M3DMaterials.h" #include "M3DMaterials.h"
#include "M3DWrapper.h"
// RESOURCES: // RESOURCES:
// https://gitlab.com/bztsrc/model3d/blob/master/docs/m3d_format.md // https://gitlab.com/bztsrc/model3d/blob/master/docs/m3d_format.md
@ -132,13 +132,13 @@ void addProp(m3dm_t *m, uint8_t type, uint32_t value) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// convert aiString to identifier safe C string. This is a duplication of _m3d_safestr // convert aiString to identifier safe C string. This is a duplication of _m3d_safestr
char *SafeStr(aiString str, bool isStrict) char *SafeStr(aiString str, bool isStrict) {
{
char *s = (char *)&str.data; char *s = (char *)&str.data;
char *d, *ret; char *d, *ret;
int i, len; int i, len;
for(len = str.length + 1; *s && (*s == ' ' || *s == '\t'); s++, len--); for (len = str.length + 1; *s && (*s == ' ' || *s == '\t'); s++, len--)
;
if (len > 255) len = 255; if (len > 255) len = 255;
ret = (char *)M3D_MALLOC(len + 1); ret = (char *)M3D_MALLOC(len + 1);
if (!ret) { if (!ret) {
@ -147,7 +147,8 @@ char *SafeStr(aiString str, bool isStrict)
for (i = 0, d = ret; i < len && *s && *s != '\r' && *s != '\n'; s++, d++, i++) { for (i = 0, d = ret; i < len && *s && *s != '\r' && *s != '\n'; s++, d++, i++) {
*d = isStrict && (*s == ' ' || *s == '\t' || *s == '/' || *s == '\\') ? '_' : (*s == '\t' ? ' ' : *s); *d = isStrict && (*s == ' ' || *s == '\t' || *s == '/' || *s == '\\') ? '_' : (*s == '\t' ? ' ' : *s);
} }
for(; d > ret && (*(d-1) == ' ' || *(d-1) == '\t'); d--); for (; d > ret && (*(d - 1) == ' ' || *(d - 1) == '\t'); d--)
;
*d = 0; *d = 0;
return ret; return ret;
} }
@ -290,10 +291,10 @@ void ExportSceneM3D(
// Worker function for exporting a scene to ASCII A3D. // Worker function for exporting a scene to ASCII A3D.
// Prototyped and registered in Exporter.cpp // Prototyped and registered in Exporter.cpp
void ExportSceneM3DA( void ExportSceneM3DA(
const char *pFile, const char *,
IOSystem *pIOSystem, IOSystem*,
const aiScene *pScene, const aiScene*,
const ExportProperties *pProperties const ExportProperties *
) { ) {
#ifdef M3D_ASCII #ifdef M3D_ASCII

View File

@ -56,9 +56,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
#include <memory> #include <memory>
#include "M3DWrapper.h"
#include "M3DImporter.h" #include "M3DImporter.h"
#include "M3DMaterials.h" #include "M3DMaterials.h"
#include "M3DWrapper.h"
// RESOURCES: // RESOURCES:
// https://gitlab.com/bztsrc/model3d/blob/master/docs/m3d_format.md // https://gitlab.com/bztsrc/model3d/blob/master/docs/m3d_format.md
@ -256,9 +256,9 @@ void M3DImporter::importMaterials(const M3DWrapper &m3d) {
for (i = 0; i < m3d->nummaterial; i++) { for (i = 0; i < m3d->nummaterial; i++) {
m = &m3d->material[i]; m = &m3d->material[i];
aiMaterial *mat = new aiMaterial; aiMaterial *newMat = new aiMaterial;
name.Set(std::string(m->name)); name.Set(std::string(m->name));
mat->AddProperty(&name, AI_MATKEY_NAME); newMat->AddProperty(&name, AI_MATKEY_NAME);
for (j = 0; j < m->numprop; j++) { for (j = 0; j < m->numprop; j++) {
// look up property type // look up property type
// 0 - 127 scalar values, // 0 - 127 scalar values,
@ -271,29 +271,36 @@ void M3DImporter::importMaterials(const M3DWrapper &m3d) {
break; break;
} }
// should never happen, but be safe than sorry // should never happen, but be safe than sorry
if (k == 256) continue; if (k == 256)
continue;
// scalar properties // scalar properties
if (m->prop[j].type < 128 && aiProps[k].pKey) { if (m->prop[j].type < 128 && aiProps[k].pKey) {
switch (m3d_propertytypes[k].format) { switch (m3d_propertytypes[k].format) {
case m3dpf_color: case m3dpf_color:
c = mkColor(m->prop[j].value.color); c = mkColor(m->prop[j].value.color);
mat->AddProperty(&c, 1, aiProps[k].pKey, aiProps[k].type, aiProps[k].index); newMat->AddProperty(&c, 1, aiProps[k].pKey, aiProps[k].type, aiProps[k].index);
break; break;
case m3dpf_float: case m3dpf_float:
f = m->prop[j].value.fnum; f = m->prop[j].value.fnum;
mat->AddProperty(&f, 1, aiProps[k].pKey, aiProps[k].type, aiProps[k].index); newMat->AddProperty(&f, 1, aiProps[k].pKey, aiProps[k].type, aiProps[k].index);
break; break;
default: default:
n = m->prop[j].value.num; n = m->prop[j].value.num;
if (m->prop[j].type == m3dp_il) { if (m->prop[j].type == m3dp_il) {
switch (n) { switch (n) {
case 0: n = aiShadingMode_NoShading; break; case 0:
case 2: n = aiShadingMode_Phong; break; n = aiShadingMode_NoShading;
default: n = aiShadingMode_Gouraud; break; break;
case 2:
n = aiShadingMode_Phong;
break;
default:
n = aiShadingMode_Gouraud;
break;
} }
} }
mat->AddProperty(&n, 1, aiProps[k].pKey, aiProps[k].type, aiProps[k].index); newMat->AddProperty(&n, 1, aiProps[k].pKey, aiProps[k].type, aiProps[k].index);
break; break;
} }
} }
@ -403,7 +410,6 @@ void M3DImporter::importMeshes(const M3DWrapper &m3d) {
ai_assert(m3d); ai_assert(m3d);
ai_assert(mScene->mRootNode != nullptr); ai_assert(mScene->mRootNode != nullptr);
for (i = 0; i < m3d->numface; i++) { for (i = 0; i < m3d->numface; i++) {
// we must switch mesh if material changes // we must switch mesh if material changes
if (lastMat != m3d->face[i].materialid) { if (lastMat != m3d->face[i].materialid) {

View File

@ -100,6 +100,10 @@ M3DWrapper::M3DWrapper() {
} }
M3DWrapper::M3DWrapper(IOSystem *pIOHandler, const std::vector<unsigned char> &buffer) { M3DWrapper::M3DWrapper(IOSystem *pIOHandler, const std::vector<unsigned char> &buffer) {
if (nullptr == pIOHandler) {
ai_assert(nullptr != pIOHandler);
}
#ifdef ASSIMP_USE_M3D_READFILECB #ifdef ASSIMP_USE_M3D_READFILECB
// pass this IOHandler to the C callback in a thread-local pointer // pass this IOHandler to the C callback in a thread-local pointer
m3dimporter_pIOHandler = pIOHandler; m3dimporter_pIOHandler = pIOHandler;

File diff suppressed because it is too large Load Diff

View File

@ -45,21 +45,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the MD5 importer class * @brief Implementation of the MD5 importer class
*/ */
#ifndef ASSIMP_BUILD_NO_MD5_IMPORTER #ifndef ASSIMP_BUILD_NO_MD5_IMPORTER
// internal headers // internal headers
#include <assimp/RemoveComments.h>
#include "MD5Loader.h" #include "MD5Loader.h"
#include <assimp/MathFunctions.h>
#include <assimp/RemoveComments.h>
#include <assimp/SkeletonMeshBuilder.h>
#include <assimp/StringComparison.h> #include <assimp/StringComparison.h>
#include <assimp/fast_atof.h> #include <assimp/fast_atof.h>
#include <assimp/MathFunctions.h>
#include <assimp/SkeletonMeshBuilder.h>
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/IOSystem.hpp>
#include <assimp/DefaultLogger.hpp>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <assimp/Importer.hpp>
#include <memory> #include <memory>
using namespace Assimp; using namespace Assimp;
@ -67,7 +66,6 @@ using namespace Assimp;
// Minimum weight value. Weights inside [-n ... n] are ignored // Minimum weight value. Weights inside [-n ... n] are ignored
#define AI_MD5_WEIGHT_EPSILON Math::getEpsilon<float>() #define AI_MD5_WEIGHT_EPSILON Math::getEpsilon<float>()
static const aiImporterDesc desc = { static const aiImporterDesc desc = {
"Doom 3 / MD5 Mesh Importer", "Doom 3 / MD5 Mesh Importer",
"", "",
@ -83,28 +81,20 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
MD5Importer::MD5Importer() MD5Importer::MD5Importer() :
: mIOHandler() mIOHandler(nullptr), mBuffer(), fileSize(), iLineNumber(), pScene(), bHadMD5Mesh(), bHadMD5Anim(), bHadMD5Camera(), configNoAutoLoad(false) {
, mBuffer() // empty
, fileSize() }
, iLineNumber()
, pScene()
, pIOHandler()
, bHadMD5Mesh()
, bHadMD5Anim()
, bHadMD5Camera()
, configNoAutoLoad (false)
{}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
MD5Importer::~MD5Importer() MD5Importer::~MD5Importer() {
{} // empty
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool MD5Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const bool MD5Importer::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
{
const std::string extension = GetExtension(pFile); const std::string extension = GetExtension(pFile);
if (extension == "md5anim" || extension == "md5mesh" || extension == "md5camera") if (extension == "md5anim" || extension == "md5mesh" || extension == "md5camera")
@ -121,15 +111,13 @@ bool MD5Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get list of all supported extensions // Get list of all supported extensions
const aiImporterDesc* MD5Importer::GetInfo () const const aiImporterDesc *MD5Importer::GetInfo() const {
{
return &desc; return &desc;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Setup import properties // Setup import properties
void MD5Importer::SetupProperties(const Importer* pImp) void MD5Importer::SetupProperties(const Importer *pImp) {
{
// AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD // AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD
configNoAutoLoad = (0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD, 0)); configNoAutoLoad = (0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD, 0));
} }
@ -137,9 +125,8 @@ void MD5Importer::SetupProperties(const Importer* pImp)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure. // Imports the given file into the given scene structure.
void MD5Importer::InternReadFile(const std::string &pFile, void MD5Importer::InternReadFile(const std::string &pFile,
aiScene* _pScene, IOSystem* _pIOHandler) aiScene *_pScene, IOSystem *pIOHandler) {
{ mIOHandler = pIOHandler;
pIOHandler = _pIOHandler;
pScene = _pScene; pScene = _pScene;
bHadMD5Mesh = bHadMD5Anim = bHadMD5Camera = false; bHadMD5Mesh = bHadMD5Anim = bHadMD5Camera = false;
@ -151,25 +138,21 @@ void MD5Importer::InternReadFile( const std::string& pFile,
try { try {
if (extension == "md5camera") { if (extension == "md5camera") {
LoadMD5CameraFile(); LoadMD5CameraFile();
} } else if (configNoAutoLoad || extension == "md5anim") {
else if (configNoAutoLoad || extension == "md5anim") {
// determine file extension and process just *one* file // determine file extension and process just *one* file
if (extension.length() == 0) { if (extension.length() == 0) {
throw DeadlyImportError("Failure, need file extension to determine MD5 part type"); throw DeadlyImportError("Failure, need file extension to determine MD5 part type");
} }
if (extension == "md5anim") { if (extension == "md5anim") {
LoadMD5AnimFile(); LoadMD5AnimFile();
} } else if (extension == "md5mesh") {
else if (extension == "md5mesh") {
LoadMD5MeshFile(); LoadMD5MeshFile();
} }
} } else {
else {
LoadMD5MeshFile(); LoadMD5MeshFile();
LoadMD5AnimFile(); LoadMD5AnimFile();
} }
} } catch (...) { // std::exception, Assimp::DeadlyImportError
catch ( ... ) { // std::exception, Assimp::DeadlyImportError
UnloadFileFromMemory(); UnloadFileFromMemory();
throw; throw;
} }
@ -194,8 +177,7 @@ void MD5Importer::InternReadFile( const std::string& pFile,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Load a file into a memory buffer // Load a file into a memory buffer
void MD5Importer::LoadFileIntoMemory (IOStream* file) void MD5Importer::LoadFileIntoMemory(IOStream *file) {
{
// unload the previous buffer, if any // unload the previous buffer, if any
UnloadFileFromMemory(); UnloadFileFromMemory();
@ -217,8 +199,7 @@ void MD5Importer::LoadFileIntoMemory (IOStream* file)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Unload the current memory buffer // Unload the current memory buffer
void MD5Importer::UnloadFileFromMemory () void MD5Importer::UnloadFileFromMemory() {
{
// delete the file buffer // delete the file buffer
delete[] mBuffer; delete[] mBuffer;
mBuffer = NULL; mBuffer = NULL;
@ -227,8 +208,7 @@ void MD5Importer::UnloadFileFromMemory ()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Build unique vertices // Build unique vertices
void MD5Importer::MakeDataUnique (MD5::MeshDesc& meshSrc) void MD5Importer::MakeDataUnique(MD5::MeshDesc &meshSrc) {
{
std::vector<bool> abHad(meshSrc.mVertices.size(), false); std::vector<bool> abHad(meshSrc.mVertices.size(), false);
// allocate enough storage to keep the output structures // allocate enough storage to keep the output structures
@ -252,8 +232,8 @@ void MD5Importer::MakeDataUnique (MD5::MeshDesc& meshSrc)
// generate a new vertex // generate a new vertex
meshSrc.mVertices[iNewIndex] = meshSrc.mVertices[face.mIndices[i]]; meshSrc.mVertices[iNewIndex] = meshSrc.mVertices[face.mIndices[i]];
face.mIndices[i] = iNewIndex++; face.mIndices[i] = iNewIndex++;
} } else
else abHad[face.mIndices[i]] = true; abHad[face.mIndices[i]] = true;
} }
// swap face order // swap face order
std::swap(face.mIndices[0], face.mIndices[2]); std::swap(face.mIndices[0], face.mIndices[2]);
@ -262,8 +242,7 @@ void MD5Importer::MakeDataUnique (MD5::MeshDesc& meshSrc)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Recursive node graph construction from a MD5MESH // Recursive node graph construction from a MD5MESH
void MD5Importer::AttachChilds_Mesh(int iParentID,aiNode* piParent, BoneList& bones) void MD5Importer::AttachChilds_Mesh(int iParentID, aiNode *piParent, BoneList &bones) {
{
ai_assert(NULL != piParent && !piParent->mNumChildren); ai_assert(NULL != piParent && !piParent->mNumChildren);
// First find out how many children we'll have // First find out how many children we'll have
@ -313,8 +292,7 @@ void MD5Importer::AttachChilds_Mesh(int iParentID,aiNode* piParent, BoneList& bo
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Recursive node graph construction from a MD5ANIM // Recursive node graph construction from a MD5ANIM
void MD5Importer::AttachChilds_Anim(int iParentID,aiNode* piParent, AnimBoneList& bones,const aiNodeAnim** node_anims) void MD5Importer::AttachChilds_Anim(int iParentID, aiNode *piParent, AnimBoneList &bones, const aiNodeAnim **node_anims) {
{
ai_assert(NULL != piParent && !piParent->mNumChildren); ai_assert(NULL != piParent && !piParent->mNumChildren);
// First find out how many children we'll have // First find out how many children we'll have
@ -327,8 +305,7 @@ void MD5Importer::AttachChilds_Anim(int iParentID,aiNode* piParent, AnimBoneList
piParent->mChildren = new aiNode *[piParent->mNumChildren]; piParent->mChildren = new aiNode *[piParent->mNumChildren];
for (int i = 0; i < (int)bones.size(); ++i) { for (int i = 0; i < (int)bones.size(); ++i) {
// (avoid infinite recursion) // (avoid infinite recursion)
if (iParentID != i && bones[i].mParentIndex == iParentID) if (iParentID != i && bones[i].mParentIndex == iParentID) {
{
aiNode *pc; aiNode *pc;
// setup a new node // setup a new node
*piParent->mChildren++ = pc = new aiNode(); *piParent->mChildren++ = pc = new aiNode();
@ -337,7 +314,8 @@ void MD5Importer::AttachChilds_Anim(int iParentID,aiNode* piParent, AnimBoneList
// get the corresponding animation channel and its first frame // get the corresponding animation channel and its first frame
const aiNodeAnim **cur = node_anims; const aiNodeAnim **cur = node_anims;
while ((**cur).mNodeName != pc->mName)++cur; while ((**cur).mNodeName != pc->mName)
++cur;
aiMatrix4x4::Translation((**cur).mPositionKeys[0].mValue, pc->mTransformation); aiMatrix4x4::Translation((**cur).mPositionKeys[0].mValue, pc->mTransformation);
pc->mTransformation = pc->mTransformation * aiMatrix4x4((**cur).mRotationKeys[0].mValue.GetMatrix()); pc->mTransformation = pc->mTransformation * aiMatrix4x4((**cur).mRotationKeys[0].mValue.GetMatrix());
@ -353,13 +331,12 @@ void MD5Importer::AttachChilds_Anim(int iParentID,aiNode* piParent, AnimBoneList
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Load a MD5MESH file // Load a MD5MESH file
void MD5Importer::LoadMD5MeshFile () void MD5Importer::LoadMD5MeshFile() {
{
std::string pFile = mFile + "md5mesh"; std::string pFile = mFile + "md5mesh";
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb")); std::unique_ptr<IOStream> file(mIOHandler->Open(pFile, "rb"));
// Check whether we can read from the file // Check whether we can read from the file
if( file.get() == NULL || !file->FileSize()) { if (file.get() == nullptr || !file->FileSize()) {
ASSIMP_LOG_WARN("Failed to access MD5MESH file: " + pFile); ASSIMP_LOG_WARN("Failed to access MD5MESH file: " + pFile);
return; return;
} }
@ -442,8 +419,7 @@ void MD5Importer::LoadMD5MeshFile ()
::memset(piCount, 0, sizeof(unsigned int) * meshParser.mJoints.size()); ::memset(piCount, 0, sizeof(unsigned int) * meshParser.mJoints.size());
for (MD5::VertexList::const_iterator iter = meshSrc.mVertices.begin(); iter != meshSrc.mVertices.end(); ++iter, ++pv) { for (MD5::VertexList::const_iterator iter = meshSrc.mVertices.begin(); iter != meshSrc.mVertices.end(); ++iter, ++pv) {
for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights;++w) for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights; ++w) {
{
MD5::WeightDesc &weightDesc = meshSrc.mWeights[w]; MD5::WeightDesc &weightDesc = meshSrc.mWeights[w];
/* FIX for some invalid exporters */ /* FIX for some invalid exporters */
if (!(weightDesc.mWeight < AI_MD5_WEIGHT_EPSILON && weightDesc.mWeight >= -AI_MD5_WEIGHT_EPSILON)) if (!(weightDesc.mWeight < AI_MD5_WEIGHT_EPSILON && weightDesc.mWeight >= -AI_MD5_WEIGHT_EPSILON))
@ -458,8 +434,7 @@ void MD5Importer::LoadMD5MeshFile ()
if (mesh->mNumBones) // just for safety if (mesh->mNumBones) // just for safety
{ {
mesh->mBones = new aiBone *[mesh->mNumBones]; mesh->mBones = new aiBone *[mesh->mNumBones];
for (unsigned int q = 0,h = 0; q < meshParser.mJoints.size();++q) for (unsigned int q = 0, h = 0; q < meshParser.mJoints.size(); ++q) {
{
if (!piCount[q]) continue; if (!piCount[q]) continue;
aiBone *p = mesh->mBones[h] = new aiBone(); aiBone *p = mesh->mBones[h] = new aiBone();
p->mNumWeights = piCount[q]; p->mNumWeights = piCount[q];
@ -561,8 +536,7 @@ void MD5Importer::LoadMD5MeshFile ()
// set this also as material name // set this also as material name
mat->AddProperty(&meshSrc.mShader, AI_MATKEY_NAME); mat->AddProperty(&meshSrc.mShader, AI_MATKEY_NAME);
} } else {
else {
mat->AddProperty(&meshSrc.mShader, AI_MATKEY_TEXTURE_DIFFUSE(0)); mat->AddProperty(&meshSrc.mShader, AI_MATKEY_TEXTURE_DIFFUSE(0));
} }
mesh->mMaterialIndex = n++; mesh->mMaterialIndex = n++;
@ -572,10 +546,9 @@ void MD5Importer::LoadMD5MeshFile ()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Load an MD5ANIM file // Load an MD5ANIM file
void MD5Importer::LoadMD5AnimFile () void MD5Importer::LoadMD5AnimFile() {
{
std::string pFile = mFile + "md5anim"; std::string pFile = mFile + "md5anim";
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb")); std::unique_ptr<IOStream> file(mIOHandler->Open(pFile, "rb"));
// Check whether we can read from the file // Check whether we can read from the file
if (!file.get() || !file->FileSize()) { if (!file.get() || !file->FileSize()) {
@ -594,8 +567,7 @@ void MD5Importer::LoadMD5AnimFile ()
if (animParser.mAnimatedBones.empty() || animParser.mFrames.empty() || if (animParser.mAnimatedBones.empty() || animParser.mFrames.empty() ||
animParser.mBaseFrames.size() != animParser.mAnimatedBones.size()) { animParser.mBaseFrames.size() != animParser.mAnimatedBones.size()) {
ASSIMP_LOG_ERROR("MD5ANIM: No frames or animated bones loaded"); ASSIMP_LOG_ERROR("MD5ANIM: No frames or animated bones loaded");
} } else {
else {
bHadMD5Anim = true; bHadMD5Anim = true;
pScene->mAnimations = new aiAnimation *[pScene->mNumAnimations = 1]; pScene->mAnimations = new aiAnimation *[pScene->mNumAnimations = 1];
@ -622,14 +594,12 @@ void MD5Importer::LoadMD5AnimFile ()
// now process all values in there ... read all joints // now process all values in there ... read all joints
MD5::BaseFrameDesc *pcBaseFrame = &animParser.mBaseFrames[0]; MD5::BaseFrameDesc *pcBaseFrame = &animParser.mBaseFrames[0];
for (AnimBoneList::const_iterator iter2 = animParser.mAnimatedBones.begin(); iter2 != animParser.mAnimatedBones.end(); ++iter2, for (AnimBoneList::const_iterator iter2 = animParser.mAnimatedBones.begin(); iter2 != animParser.mAnimatedBones.end(); ++iter2,
++pcAnimNode,++pcBaseFrame) ++pcAnimNode, ++pcBaseFrame) {
{
if ((*iter2).iFirstKeyIndex >= (*iter).mValues.size()) { if ((*iter2).iFirstKeyIndex >= (*iter).mValues.size()) {
// Allow for empty frames // Allow for empty frames
if ((*iter2).iFlags != 0) { if ((*iter2).iFlags != 0) {
throw DeadlyImportError("MD5: Keyframe index is out of range"); throw DeadlyImportError("MD5: Keyframe index is out of range");
} }
continue; continue;
} }
@ -644,16 +614,16 @@ void MD5Importer::LoadMD5AnimFile ()
for (unsigned int i = 0; i < 3; ++i) { for (unsigned int i = 0; i < 3; ++i) {
if ((*iter2).iFlags & (1u << i)) { if ((*iter2).iFlags & (1u << i)) {
vKey->mValue[i] = *fpCur++; vKey->mValue[i] = *fpCur++;
} } else
else vKey->mValue[i] = pcBaseFrame->vPositionXYZ[i]; vKey->mValue[i] = pcBaseFrame->vPositionXYZ[i];
} }
// orientation component // orientation component
for (unsigned int i = 0; i < 3; ++i) { for (unsigned int i = 0; i < 3; ++i) {
if ((*iter2).iFlags & (8u << i)) { if ((*iter2).iFlags & (8u << i)) {
vTemp[i] = *fpCur++; vTemp[i] = *fpCur++;
} } else
else vTemp[i] = pcBaseFrame->vRotationQuat[i]; vTemp[i] = pcBaseFrame->vRotationQuat[i];
} }
MD5::ConvertQuaternion(vTemp, qKey->mValue); MD5::ConvertQuaternion(vTemp, qKey->mValue);
@ -683,10 +653,9 @@ void MD5Importer::LoadMD5AnimFile ()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Load an MD5CAMERA file // Load an MD5CAMERA file
void MD5Importer::LoadMD5CameraFile () void MD5Importer::LoadMD5CameraFile() {
{
std::string pFile = mFile + "md5camera"; std::string pFile = mFile + "md5camera";
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb")); std::unique_ptr<IOStream> file(mIOHandler->Open(pFile, "rb"));
// Check whether we can read from the file // Check whether we can read from the file
if (!file.get() || !file->FileSize()) { if (!file.get() || !file->FileSize()) {
@ -727,8 +696,7 @@ void MD5Importer::LoadMD5CameraFile ()
if (!cuts.size()) { if (!cuts.size()) {
cuts.push_back(0); cuts.push_back(0);
cuts.push_back(static_cast<unsigned int>(frames.size() - 1)); cuts.push_back(static_cast<unsigned int>(frames.size() - 1));
} } else {
else {
cuts.insert(cuts.begin(), 0); cuts.insert(cuts.begin(), 0);
if (cuts.back() < frames.size() - 1) if (cuts.back() < frames.size() - 1)

View File

@ -40,7 +40,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file MD5Loader.h /** @file MD5Loader.h
* @brief Definition of the .MD5 importer class. * @brief Definition of the .MD5 importer class.
* http://www.modwiki.net/wiki/MD5_(file_format) * http://www.modwiki.net/wiki/MD5_(file_format)
@ -48,8 +47,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_MD5LOADER_H_INCLUDED #ifndef AI_MD5LOADER_H_INCLUDED
#define AI_MD5LOADER_H_INCLUDED #define AI_MD5LOADER_H_INCLUDED
#include <assimp/BaseImporter.h>
#include "MD5Parser.h" #include "MD5Parser.h"
#include <assimp/BaseImporter.h>
#include <assimp/types.h> #include <assimp/types.h>
@ -64,15 +63,11 @@ using namespace Assimp::MD5;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Importer class for the MD5 file format /** Importer class for the MD5 file format
*/ */
class MD5Importer : public BaseImporter class MD5Importer : public BaseImporter {
{
public: public:
MD5Importer(); MD5Importer();
~MD5Importer(); ~MD5Importer();
public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. * See BaseImporter::CanRead() for details.
@ -81,7 +76,6 @@ public:
bool checkSig) const; bool checkSig) const;
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Return importer meta information. /** Return importer meta information.
* See #BaseImporter::GetInfo for the details * See #BaseImporter::GetInfo for the details
@ -102,9 +96,6 @@ protected:
void InternReadFile(const std::string &pFile, aiScene *pScene, void InternReadFile(const std::string &pFile, aiScene *pScene,
IOSystem *pIOHandler); IOSystem *pIOHandler);
protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Load a *.MD5MESH file. /** Load a *.MD5MESH file.
*/ */
@ -154,7 +145,6 @@ protected:
void LoadFileIntoMemory(IOStream *pFile); void LoadFileIntoMemory(IOStream *pFile);
void UnloadFileFromMemory(); void UnloadFileFromMemory();
/** IOSystem to be used to access files */ /** IOSystem to be used to access files */
IOSystem *mIOHandler; IOSystem *mIOHandler;
@ -174,9 +164,6 @@ protected:
/** Scene to be filled */ /** Scene to be filled */
aiScene *pScene; aiScene *pScene;
/** (Custom) I/O handler implementation */
IOSystem* pIOHandler;
/** true if a MD5MESH file has already been parsed */ /** true if a MD5MESH file has already been parsed */
bool bHadMD5Mesh; bool bHadMD5Mesh;

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -43,7 +41,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Implementation of the MDC importer class */ /** @file Implementation of the MDC importer class */
#ifndef ASSIMP_BUILD_NO_MDC_IMPORTER #ifndef ASSIMP_BUILD_NO_MDC_IMPORTER
// internal headers // internal headers
@ -51,11 +48,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "MD3/MD3FileData.h" #include "MD3/MD3FileData.h"
#include "MDC/MDCNormalTable.h" // shouldn't be included by other units #include "MDC/MDCNormalTable.h" // shouldn't be included by other units
#include <assimp/DefaultLogger.hpp>
#include <assimp/Importer.hpp>
#include <assimp/IOSystem.hpp>
#include <assimp/scene.h>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <assimp/Importer.hpp>
#include <memory> #include <memory>
@ -80,8 +77,7 @@ void MDC::BuildVertex(const Frame& frame,
const BaseVertex &bvert, const BaseVertex &bvert,
const CompressedVertex &cvert, const CompressedVertex &cvert,
aiVector3D &vXYZOut, aiVector3D &vXYZOut,
aiVector3D& vNorOut) aiVector3D &vNorOut) {
{
// compute the position // compute the position
const float xd = (cvert.xd - AI_MDC_CVERT_BIAS) * AI_MDC_DELTA_SCALING; const float xd = (cvert.xd - AI_MDC_CVERT_BIAS) * AI_MDC_DELTA_SCALING;
const float yd = (cvert.yd - AI_MDC_CVERT_BIAS) * AI_MDC_DELTA_SCALING; const float yd = (cvert.yd - AI_MDC_CVERT_BIAS) * AI_MDC_DELTA_SCALING;
@ -98,26 +94,27 @@ void MDC::BuildVertex(const Frame& frame,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
MDCImporter::MDCImporter() MDCImporter::MDCImporter() :
: configFrameID(), configFrameID(),
pcHeader(), pcHeader(),
mBuffer(), mBuffer(),
fileSize() fileSize() {
{ // empty
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
MDCImporter::~MDCImporter() MDCImporter::~MDCImporter() {
{ // empty
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool MDCImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const bool MDCImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
{
const std::string extension = GetExtension(pFile); const std::string extension = GetExtension(pFile);
if (extension == "mdc") if (extension == "mdc") {
return true; return true;
}
// if check for extension is not enough, check for the magic tokens // if check for extension is not enough, check for the magic tokens
if (!extension.length() || checkSig) { if (!extension.length() || checkSig) {
@ -129,15 +126,13 @@ bool MDCImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const aiImporterDesc* MDCImporter::GetInfo () const const aiImporterDesc *MDCImporter::GetInfo() const {
{
return &desc; return &desc;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Validate the header of the given MDC file // Validate the header of the given MDC file
void MDCImporter::ValidateHeader() void MDCImporter::ValidateHeader() {
{
AI_SWAP4(this->pcHeader->ulVersion); AI_SWAP4(this->pcHeader->ulVersion);
AI_SWAP4(this->pcHeader->ulFlags); AI_SWAP4(this->pcHeader->ulFlags);
AI_SWAP4(this->pcHeader->ulNumFrames); AI_SWAP4(this->pcHeader->ulNumFrames);
@ -147,8 +142,7 @@ void MDCImporter::ValidateHeader()
AI_SWAP4(this->pcHeader->ulOffsetBorderFrames); AI_SWAP4(this->pcHeader->ulOffsetBorderFrames);
if (pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_BE && if (pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_BE &&
pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_LE) pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_LE) {
{
char szBuffer[5]; char szBuffer[5];
szBuffer[0] = ((char *)&pcHeader->ulIdent)[0]; szBuffer[0] = ((char *)&pcHeader->ulIdent)[0];
szBuffer[1] = ((char *)&pcHeader->ulIdent)[1]; szBuffer[1] = ((char *)&pcHeader->ulIdent)[1];
@ -157,7 +151,8 @@ void MDCImporter::ValidateHeader()
szBuffer[4] = '\0'; szBuffer[4] = '\0';
throw DeadlyImportError("Invalid MDC magic word: should be IDPC, the " throw DeadlyImportError("Invalid MDC magic word: should be IDPC, the "
"magic word found is " + std::string( szBuffer )); "magic word found is " +
std::string(szBuffer));
} }
if (pcHeader->ulVersion != AI_MDC_VERSION) { if (pcHeader->ulVersion != AI_MDC_VERSION) {
@ -165,8 +160,7 @@ void MDCImporter::ValidateHeader()
} }
if (pcHeader->ulOffsetBorderFrames + pcHeader->ulNumFrames * sizeof(MDC::Frame) > this->fileSize || if (pcHeader->ulOffsetBorderFrames + pcHeader->ulNumFrames * sizeof(MDC::Frame) > this->fileSize ||
pcHeader->ulOffsetSurfaces + pcHeader->ulNumSurfaces * sizeof(MDC::Surface) > this->fileSize) pcHeader->ulOffsetSurfaces + pcHeader->ulNumSurfaces * sizeof(MDC::Surface) > this->fileSize) {
{
throw DeadlyImportError("Some of the offset values in the MDC header are invalid " throw DeadlyImportError("Some of the offset values in the MDC header are invalid "
"and point to something behind the file."); "and point to something behind the file.");
} }
@ -178,8 +172,7 @@ void MDCImporter::ValidateHeader()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Validate the header of a given MDC file surface // Validate the header of a given MDC file surface
void MDCImporter::ValidateSurfaceHeader(BE_NCONST MDC::Surface* pcSurf) void MDCImporter::ValidateSurfaceHeader(BE_NCONST MDC::Surface *pcSurf) {
{
AI_SWAP4(pcSurf->ulFlags); AI_SWAP4(pcSurf->ulFlags);
AI_SWAP4(pcSurf->ulNumCompFrames); AI_SWAP4(pcSurf->ulNumCompFrames);
AI_SWAP4(pcSurf->ulNumBaseFrames); AI_SWAP4(pcSurf->ulNumBaseFrames);
@ -202,8 +195,7 @@ void MDCImporter::ValidateSurfaceHeader(BE_NCONST MDC::Surface* pcSurf)
pcSurf->ulOffsetTexCoords + pcSurf->ulNumVertices * sizeof(MDC::TexturCoord) > iMax || pcSurf->ulOffsetTexCoords + pcSurf->ulNumVertices * sizeof(MDC::TexturCoord) > iMax ||
pcSurf->ulOffsetShaders + pcSurf->ulNumShaders * sizeof(MDC::Shader) > iMax || pcSurf->ulOffsetShaders + pcSurf->ulNumShaders * sizeof(MDC::Shader) > iMax ||
pcSurf->ulOffsetFrameBaseFrames + pcSurf->ulNumBaseFrames * 2 > iMax || pcSurf->ulOffsetFrameBaseFrames + pcSurf->ulNumBaseFrames * 2 > iMax ||
(pcSurf->ulNumCompFrames && pcSurf->ulOffsetFrameCompFrames + pcSurf->ulNumCompFrames * 2 > iMax)) (pcSurf->ulNumCompFrames && pcSurf->ulOffsetFrameCompFrames + pcSurf->ulNumCompFrames * 2 > iMax)) {
{
throw DeadlyImportError("Some of the offset values in the MDC surface header " throw DeadlyImportError("Some of the offset values in the MDC surface header "
"are invalid and point somewhere behind the file."); "are invalid and point somewhere behind the file.");
} }
@ -211,8 +203,7 @@ void MDCImporter::ValidateSurfaceHeader(BE_NCONST MDC::Surface* pcSurf)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Setup configuration properties // Setup configuration properties
void MDCImporter::SetupProperties(const Importer* pImp) void MDCImporter::SetupProperties(const Importer *pImp) {
{
// The AI_CONFIG_IMPORT_MDC_KEYFRAME option overrides the // The AI_CONFIG_IMPORT_MDC_KEYFRAME option overrides the
// AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option. // AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
if (static_cast<unsigned int>(-1) == (configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MDC_KEYFRAME, -1))) { if (static_cast<unsigned int>(-1) == (configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MDC_KEYFRAME, -1))) {
@ -223,18 +214,19 @@ void MDCImporter::SetupProperties(const Importer* pImp)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure. // Imports the given file into the given scene structure.
void MDCImporter::InternReadFile( void MDCImporter::InternReadFile(
const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
{
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile)); std::unique_ptr<IOStream> file(pIOHandler->Open(pFile));
// Check whether we can read from the file // Check whether we can read from the file
if( file.get() == NULL) if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open MDC file " + pFile + "."); throw DeadlyImportError("Failed to open MDC file " + pFile + ".");
}
// check whether the mdc file is large enough to contain the file header // check whether the mdc file is large enough to contain the file header
fileSize = (unsigned int)file->FileSize(); fileSize = static_cast<unsigned int>(file->FileSize());
if( fileSize < sizeof(MDC::Header)) if (fileSize < sizeof(MDC::Header)) {
throw DeadlyImportError("MDC File is too small."); throw DeadlyImportError("MDC File is too small.");
}
std::vector<unsigned char> mBuffer2(fileSize); std::vector<unsigned char> mBuffer2(fileSize);
file->Read(&mBuffer2[0], 1, fileSize); file->Read(&mBuffer2[0], 1, fileSize);
@ -260,12 +252,13 @@ void MDCImporter::InternReadFile(
BE_NCONST MDC::Surface *pcSurface, *pcSurface2; BE_NCONST MDC::Surface *pcSurface, *pcSurface2;
pcSurface = pcSurface2 = new (mBuffer + pcHeader->ulOffsetSurfaces) MDC::Surface; pcSurface = pcSurface2 = new (mBuffer + pcHeader->ulOffsetSurfaces) MDC::Surface;
unsigned int iNumShaders = 0; unsigned int iNumShaders = 0;
for (unsigned int i = 0; i < pcHeader->ulNumSurfaces;++i) for (unsigned int i = 0; i < pcHeader->ulNumSurfaces; ++i) {
{
// validate the surface header // validate the surface header
this->ValidateSurfaceHeader(pcSurface2); this->ValidateSurfaceHeader(pcSurface2);
if (pcSurface2->ulNumVertices && pcSurface2->ulNumTriangles)++pScene->mNumMeshes; if (pcSurface2->ulNumVertices && pcSurface2->ulNumTriangles) {
++pScene->mNumMeshes;
}
iNumShaders += pcSurface2->ulNumShaders; iNumShaders += pcSurface2->ulNumShaders;
pcSurface2 = new ((int8_t *)pcSurface2 + pcSurface2->ulOffsetEnd) MDC::Surface; pcSurface2 = new ((int8_t *)pcSurface2 + pcSurface2->ulOffsetEnd) MDC::Surface;
} }
@ -273,13 +266,13 @@ void MDCImporter::InternReadFile(
pScene->mMeshes = new aiMesh *[pScene->mNumMeshes]; pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
// necessary that we don't crash if an exception occurs // necessary that we don't crash if an exception occurs
for (unsigned int i = 0; i < pScene->mNumMeshes;++i) for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
pScene->mMeshes[i] = NULL; pScene->mMeshes[i] = NULL;
}
// now read all surfaces // now read all surfaces
unsigned int iDefaultMatIndex = UINT_MAX; unsigned int iDefaultMatIndex = UINT_MAX;
for (unsigned int i = 0, iNum = 0; i < pcHeader->ulNumSurfaces;++i) for (unsigned int i = 0, iNum = 0; i < pcHeader->ulNumSurfaces; ++i) {
{
if (!pcSurface->ulNumVertices || !pcSurface->ulNumTriangles) continue; if (!pcSurface->ulNumVertices || !pcSurface->ulNumTriangles) continue;
aiMesh *pcMesh = pScene->mMeshes[iNum++] = new aiMesh(); aiMesh *pcMesh = pScene->mMeshes[iNum++] = new aiMesh();
@ -287,12 +280,10 @@ void MDCImporter::InternReadFile(
pcMesh->mNumVertices = pcMesh->mNumFaces * 3; pcMesh->mNumVertices = pcMesh->mNumFaces * 3;
// store the name of the surface for use as node name. // store the name of the surface for use as node name.
pcMesh->mName.Set(std::string(pcSurface->ucName pcMesh->mName.Set(std::string(pcSurface->ucName, strnlen(pcSurface->ucName, AI_MDC_MAXQPATH - 1)));
, strnlen(pcSurface->ucName, AI_MDC_MAXQPATH - 1)));
// go to the first shader in the file. ignore the others. // go to the first shader in the file. ignore the others.
if (pcSurface->ulNumShaders) if (pcSurface->ulNumShaders) {
{
const MDC::Shader *pcShader = (const MDC::Shader *)((int8_t *)pcSurface + pcSurface->ulOffsetShaders); const MDC::Shader *pcShader = (const MDC::Shader *)((int8_t *)pcSurface + pcSurface->ulOffsetShaders);
pcMesh->mMaterialIndex = (unsigned int)aszShaders.size(); pcMesh->mMaterialIndex = (unsigned int)aszShaders.size();
@ -301,13 +292,13 @@ void MDCImporter::InternReadFile(
::strnlen(pcShader->ucName, sizeof(pcShader->ucName)))); ::strnlen(pcShader->ucName, sizeof(pcShader->ucName))));
} }
// need to create a default material // need to create a default material
else if (UINT_MAX == iDefaultMatIndex) else if (UINT_MAX == iDefaultMatIndex) {
{
pcMesh->mMaterialIndex = iDefaultMatIndex = (unsigned int)aszShaders.size(); pcMesh->mMaterialIndex = iDefaultMatIndex = (unsigned int)aszShaders.size();
aszShaders.push_back(std::string()); aszShaders.push_back(std::string());
} }
// otherwise assign a reference to the default material // otherwise assign a reference to the default material
else pcMesh->mMaterialIndex = iDefaultMatIndex; else
pcMesh->mMaterialIndex = iDefaultMatIndex;
// allocate output storage for the mesh // allocate output storage for the mesh
aiVector3D *pcVertCur = pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices]; aiVector3D *pcVertCur = pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
@ -316,36 +307,32 @@ void MDCImporter::InternReadFile(
aiFace *pcFaceCur = pcMesh->mFaces = new aiFace[pcMesh->mNumFaces]; aiFace *pcFaceCur = pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
// create all vertices/faces // create all vertices/faces
BE_NCONST MDC::Triangle* pcTriangle = (BE_NCONST MDC::Triangle*) BE_NCONST MDC::Triangle *pcTriangle = (BE_NCONST MDC::Triangle *)((int8_t *)pcSurface + pcSurface->ulOffsetTriangles);
((int8_t*)pcSurface+pcSurface->ulOffsetTriangles);
BE_NCONST MDC::TexturCoord* const pcUVs = (BE_NCONST MDC::TexturCoord*) BE_NCONST MDC::TexturCoord *const pcUVs = (BE_NCONST MDC::TexturCoord *)((int8_t *)pcSurface + pcSurface->ulOffsetTexCoords);
((int8_t*)pcSurface+pcSurface->ulOffsetTexCoords);
// get a pointer to the uncompressed vertices // get a pointer to the uncompressed vertices
int16_t iOfs = *((int16_t *)((int8_t *)pcSurface + int16_t iOfs = *((int16_t *)((int8_t *)pcSurface +
pcSurface->ulOffsetFrameBaseFrames) + this->configFrameID); pcSurface->ulOffsetFrameBaseFrames) +
this->configFrameID);
AI_SWAP2(iOfs); AI_SWAP2(iOfs);
BE_NCONST MDC::BaseVertex* const pcVerts = (BE_NCONST MDC::BaseVertex*) BE_NCONST MDC::BaseVertex *const pcVerts = (BE_NCONST MDC::BaseVertex *)((int8_t *)pcSurface + pcSurface->ulOffsetBaseVerts) +
((int8_t*)pcSurface+pcSurface->ulOffsetBaseVerts) +
((int)iOfs * pcSurface->ulNumVertices * 4); ((int)iOfs * pcSurface->ulNumVertices * 4);
// do the main swapping stuff ... // do the main swapping stuff ...
#if (defined AI_BUILD_BIG_ENDIAN) #if (defined AI_BUILD_BIG_ENDIAN)
// swap all triangles // swap all triangles
for (unsigned int i = 0; i < pcSurface->ulNumTriangles;++i) for (unsigned int i = 0; i < pcSurface->ulNumTriangles; ++i) {
{
AI_SWAP4(pcTriangle[i].aiIndices[0]); AI_SWAP4(pcTriangle[i].aiIndices[0]);
AI_SWAP4(pcTriangle[i].aiIndices[1]); AI_SWAP4(pcTriangle[i].aiIndices[1]);
AI_SWAP4(pcTriangle[i].aiIndices[2]); AI_SWAP4(pcTriangle[i].aiIndices[2]);
} }
// swap all vertices // swap all vertices
for (unsigned int i = 0; i < pcSurface->ulNumVertices*pcSurface->ulNumBaseFrames;++i) for (unsigned int i = 0; i < pcSurface->ulNumVertices * pcSurface->ulNumBaseFrames; ++i) {
{
AI_SWAP2(pcVerts->normal); AI_SWAP2(pcVerts->normal);
AI_SWAP2(pcVerts->x); AI_SWAP2(pcVerts->x);
AI_SWAP2(pcVerts->y); AI_SWAP2(pcVerts->y);
@ -353,8 +340,7 @@ void MDCImporter::InternReadFile(
} }
// swap all texture coordinates // swap all texture coordinates
for (unsigned int i = 0; i < pcSurface->ulNumVertices;++i) for (unsigned int i = 0; i < pcSurface->ulNumVertices; ++i) {
{
AI_SWAP4(pcUVs->u); AI_SWAP4(pcUVs->u);
AI_SWAP4(pcUVs->v); AI_SWAP4(pcUVs->v);
} }
@ -365,44 +351,37 @@ void MDCImporter::InternReadFile(
int16_t *mdcCompVert = NULL; int16_t *mdcCompVert = NULL;
// access compressed frames for large frame numbers, but never for the first // access compressed frames for large frame numbers, but never for the first
if( this->configFrameID && pcSurface->ulNumCompFrames > 0 ) if (this->configFrameID && pcSurface->ulNumCompFrames > 0) {
{
mdcCompVert = (int16_t *)((int8_t *)pcSurface + pcSurface->ulOffsetFrameCompFrames) + this->configFrameID; mdcCompVert = (int16_t *)((int8_t *)pcSurface + pcSurface->ulOffsetFrameCompFrames) + this->configFrameID;
AI_SWAP2P(mdcCompVert); AI_SWAP2P(mdcCompVert);
if( *mdcCompVert >= 0 ) if (*mdcCompVert >= 0) {
{
pcCVerts = (const MDC::CompressedVertex *)((int8_t *)pcSurface + pcCVerts = (const MDC::CompressedVertex *)((int8_t *)pcSurface +
pcSurface->ulOffsetCompVerts) + *mdcCompVert * pcSurface->ulNumVertices; pcSurface->ulOffsetCompVerts) +
} *mdcCompVert * pcSurface->ulNumVertices;
else mdcCompVert = NULL; } else
mdcCompVert = NULL;
} }
// copy all faces // copy all faces
for (unsigned int iFace = 0; iFace < pcSurface->ulNumTriangles; ++iFace, for (unsigned int iFace = 0; iFace < pcSurface->ulNumTriangles; ++iFace,
++pcTriangle,++pcFaceCur) ++pcTriangle, ++pcFaceCur) {
{
const unsigned int iOutIndex = iFace * 3; const unsigned int iOutIndex = iFace * 3;
pcFaceCur->mNumIndices = 3; pcFaceCur->mNumIndices = 3;
pcFaceCur->mIndices = new unsigned int[3]; pcFaceCur->mIndices = new unsigned int[3];
for (unsigned int iIndex = 0; iIndex < 3; ++iIndex, for (unsigned int iIndex = 0; iIndex < 3; ++iIndex,
++pcVertCur,++pcUVCur,++pcNorCur) ++pcVertCur, ++pcUVCur, ++pcNorCur) {
{
uint32_t quak = pcTriangle->aiIndices[iIndex]; uint32_t quak = pcTriangle->aiIndices[iIndex];
if (quak >= pcSurface->ulNumVertices) if (quak >= pcSurface->ulNumVertices) {
{
ASSIMP_LOG_ERROR("MDC vertex index is out of range"); ASSIMP_LOG_ERROR("MDC vertex index is out of range");
quak = pcSurface->ulNumVertices - 1; quak = pcSurface->ulNumVertices - 1;
} }
// compressed vertices? // compressed vertices?
if (mdcCompVert) if (mdcCompVert) {
{
MDC::BuildVertex(*pcFrame, pcVerts[quak], pcCVerts[quak], MDC::BuildVertex(*pcFrame, pcVerts[quak], pcCVerts[quak],
*pcVertCur, *pcNorCur); *pcVertCur, *pcNorCur);
} } else {
else
{
// copy position // copy position
pcVertCur->x = pcVerts[quak].x * AI_MDC_BASE_SCALING; pcVertCur->x = pcVerts[quak].x * AI_MDC_BASE_SCALING;
pcVertCur->y = pcVerts[quak].y * AI_MDC_BASE_SCALING; pcVertCur->y = pcVerts[quak].y * AI_MDC_BASE_SCALING;
@ -432,8 +411,7 @@ void MDCImporter::InternReadFile(
// create a flat node graph with a root node and one child for each surface // create a flat node graph with a root node and one child for each surface
if (!pScene->mNumMeshes) if (!pScene->mNumMeshes)
throw DeadlyImportError("Invalid MDC file: File contains no valid mesh"); throw DeadlyImportError("Invalid MDC file: File contains no valid mesh");
else if (1 == pScene->mNumMeshes) else if (1 == pScene->mNumMeshes) {
{
pScene->mRootNode = new aiNode(); pScene->mRootNode = new aiNode();
if (nullptr != pScene->mMeshes[0]) { if (nullptr != pScene->mMeshes[0]) {
pScene->mRootNode->mName = pScene->mMeshes[0]->mName; pScene->mRootNode->mName = pScene->mMeshes[0]->mName;
@ -441,15 +419,12 @@ void MDCImporter::InternReadFile(
pScene->mRootNode->mMeshes = new unsigned int[1]; pScene->mRootNode->mMeshes = new unsigned int[1];
pScene->mRootNode->mMeshes[0] = 0; pScene->mRootNode->mMeshes[0] = 0;
} }
} } else {
else
{
pScene->mRootNode = new aiNode(); pScene->mRootNode = new aiNode();
pScene->mRootNode->mNumChildren = pScene->mNumMeshes; pScene->mRootNode->mNumChildren = pScene->mNumMeshes;
pScene->mRootNode->mChildren = new aiNode *[pScene->mNumMeshes]; pScene->mRootNode->mChildren = new aiNode *[pScene->mNumMeshes];
pScene->mRootNode->mName.Set("<root>"); pScene->mRootNode->mName.Set("<root>");
for (unsigned int i = 0; i < pScene->mNumMeshes;++i) for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
{
aiNode *pcNode = pScene->mRootNode->mChildren[i] = new aiNode(); aiNode *pcNode = pScene->mRootNode->mChildren[i] = new aiNode();
pcNode->mParent = pScene->mRootNode; pcNode->mParent = pScene->mRootNode;
pcNode->mName = pScene->mMeshes[i]->mName; pcNode->mName = pScene->mMeshes[i]->mName;
@ -462,8 +437,7 @@ void MDCImporter::InternReadFile(
// create materials // create materials
pScene->mNumMaterials = (unsigned int)aszShaders.size(); pScene->mNumMaterials = (unsigned int)aszShaders.size();
pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials]; pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials];
for (unsigned int i = 0; i < pScene->mNumMaterials;++i) for (unsigned int i = 0; i < pScene->mNumMaterials; ++i) {
{
aiMaterial *pcMat = new aiMaterial(); aiMaterial *pcMat = new aiMaterial();
pScene->mMaterials[i] = pcMat; pScene->mMaterials[i] = pcMat;
@ -477,14 +451,15 @@ void MDCImporter::InternReadFile(
clr.b = clr.g = clr.r = 0.05f; clr.b = clr.g = clr.r = 0.05f;
pcMat->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_AMBIENT); pcMat->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_AMBIENT);
if (name.length())clr.b = clr.g = clr.r = 1.0f; if (name.length())
else clr.b = clr.g = clr.r = 0.6f; clr.b = clr.g = clr.r = 1.0f;
else
clr.b = clr.g = clr.r = 0.6f;
pcMat->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_DIFFUSE); pcMat->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_DIFFUSE);
pcMat->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_SPECULAR); pcMat->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_SPECULAR);
if (name.length()) if (name.length()) {
{
aiString path; aiString path;
path.Set(name); path.Set(name);
pcMat->AddProperty(&path, AI_MATKEY_TEXTURE_DIFFUSE(0)); pcMat->AddProperty(&path, AI_MATKEY_TEXTURE_DIFFUSE(0));

View File

@ -68,6 +68,10 @@ namespace Assimp {
namespace MDL { namespace MDL {
namespace HalfLife { namespace HalfLife {
#ifdef _WIN32
# pragma warning(disable : 4706)
#endif // _WIN32
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
HL1MDLLoader::HL1MDLLoader( HL1MDLLoader::HL1MDLLoader(
aiScene *scene, aiScene *scene,
@ -817,25 +821,25 @@ void HL1MDLLoader::read_meshes() {
mesh_faces.reserve(num_faces); mesh_faces.reserve(num_faces);
if (is_triangle_fan) { if (is_triangle_fan) {
for (int i = 0; i < num_faces; ++i) { for (int faceIdx = 0; faceIdx < num_faces; ++faceIdx) {
mesh_faces.push_back(HL1MeshFace{ mesh_faces.push_back(HL1MeshFace{
tricmds[0], tricmds[0],
tricmds[i + 1], tricmds[faceIdx + 1],
tricmds[i + 2] }); tricmds[faceIdx + 2] });
} }
} else { } else {
for (int i = 0; i < num_faces; ++i) { for (int faceIdx = 0; faceIdx < num_faces; ++faceIdx) {
if (i & 1) { if (i & 1) {
// Preserve winding order. // Preserve winding order.
mesh_faces.push_back(HL1MeshFace{ mesh_faces.push_back(HL1MeshFace{
tricmds[i + 1], tricmds[faceIdx + 1],
tricmds[i], tricmds[faceIdx],
tricmds[i + 2] }); tricmds[faceIdx + 2] });
} else { } else {
mesh_faces.push_back(HL1MeshFace{ mesh_faces.push_back(HL1MeshFace{
tricmds[i], tricmds[faceIdx],
tricmds[i + 1], tricmds[faceIdx + 1],
tricmds[i + 2] }); tricmds[faceIdx + 2] });
} }
} }
} }
@ -1122,10 +1126,10 @@ void HL1MDLLoader::read_sequence_infos() {
aiNode *blend_controller_node = blend_controllers_node->mChildren[j] = new aiNode(); aiNode *blend_controller_node = blend_controllers_node->mChildren[j] = new aiNode();
blend_controller_node->mParent = blend_controllers_node; blend_controller_node->mParent = blend_controllers_node;
aiMetadata *md = blend_controller_node->mMetaData = aiMetadata::Alloc(3); aiMetadata *metaData = blend_controller_node->mMetaData = aiMetadata::Alloc(3);
md->Set(0, "Start", pseqdesc->blendstart[j]); metaData->Set(0, "Start", pseqdesc->blendstart[j]);
md->Set(1, "End", pseqdesc->blendend[j]); metaData->Set(1, "End", pseqdesc->blendend[j]);
md->Set(2, "MotionFlags", pseqdesc->blendtype[j]); metaData->Set(2, "MotionFlags", pseqdesc->blendtype[j]);
} }
} }
} }
@ -1151,10 +1155,10 @@ void HL1MDLLoader::read_sequence_infos() {
aiNode *pEvent = pEventsNode->mChildren[j] = new aiNode(); aiNode *pEvent = pEventsNode->mChildren[j] = new aiNode();
pEvent->mParent = pEventsNode; pEvent->mParent = pEventsNode;
aiMetadata *md = pEvent->mMetaData = aiMetadata::Alloc(3); aiMetadata *metaData = pEvent->mMetaData = aiMetadata::Alloc(3);
md->Set(0, "Frame", pevent->frame); metaData->Set(0, "Frame", pevent->frame);
md->Set(1, "ScriptEvent", pevent->event); metaData->Set(1, "ScriptEvent", pevent->event);
md->Set(2, "Options", aiString(pevent->options)); metaData->Set(2, "Options", aiString(pevent->options));
} }
} }

View File

@ -68,7 +68,7 @@ struct HL1MeshTrivert {
normindex(normindex), normindex(normindex),
s(s), s(s),
t(t), t(t),
localindex() { localindex(localindex) {
} }
HL1MeshTrivert(const Trivert &a) : HL1MeshTrivert(const Trivert &a) :

View File

@ -49,17 +49,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_MDL_IMPORTER #ifndef ASSIMP_BUILD_NO_MDL_IMPORTER
#include "MDL/MDLLoader.h" #include "MDL/MDLLoader.h"
#include "MDL/MDLDefaultColorMap.h"
#include "MD2/MD2FileData.h" #include "MD2/MD2FileData.h"
#include "MDL/HalfLife/HL1MDLLoader.h" #include "MDL/HalfLife/HL1MDLLoader.h"
#include "MDL/MDLDefaultColorMap.h"
#include <assimp/qnan.h>
#include <assimp/StringUtils.h> #include <assimp/StringUtils.h>
#include <assimp/Importer.hpp> #include <assimp/importerdesc.h>
#include <assimp/IOSystem.hpp> #include <assimp/qnan.h>
#include <assimp/scene.h> #include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#include <assimp/importerdesc.h> #include <assimp/IOSystem.hpp>
#include <assimp/Importer.hpp>
#include <memory> #include <memory>
@ -91,13 +91,8 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
MDLImporter::MDLImporter() MDLImporter::MDLImporter() :
: configFrameID() configFrameID(), mBuffer(), iGSFileVersion(), mIOHandler(nullptr), pScene(), iFileSize() {
, mBuffer()
, iGSFileVersion()
, pIOHandler()
, pScene()
, iFileSize() {
// empty // empty
} }
@ -130,8 +125,7 @@ bool MDLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Setup configuration properties // Setup configuration properties
void MDLImporter::SetupProperties(const Importer* pImp) void MDLImporter::SetupProperties(const Importer *pImp) {
{
configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MDL_KEYFRAME, -1); configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MDL_KEYFRAME, -1);
// The // The
@ -159,22 +153,20 @@ void MDLImporter::SetupProperties(const Importer* pImp)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get a list of all supported extensions // Get a list of all supported extensions
const aiImporterDesc* MDLImporter::GetInfo () const const aiImporterDesc *MDLImporter::GetInfo() const {
{
return &desc; return &desc;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure. // Imports the given file into the given scene structure.
void MDLImporter::InternReadFile(const std::string &pFile, void MDLImporter::InternReadFile(const std::string &pFile,
aiScene* _pScene, IOSystem* _pIOHandler) aiScene *_pScene, IOSystem *pIOHandler) {
{
pScene = _pScene; pScene = _pScene;
pIOHandler = _pIOHandler; mIOHandler = pIOHandler;
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile)); std::unique_ptr<IOStream> file(pIOHandler->Open(pFile));
// Check whether we can read from the file // Check whether we can read from the file
if( file.get() == NULL) { if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open MDL file " + pFile + "."); throw DeadlyImportError("Failed to open MDL file " + pFile + ".");
} }
@ -191,7 +183,7 @@ void MDLImporter::InternReadFile( const std::string& pFile,
delete[] mBuffer; delete[] mBuffer;
mBuffer = nullptr; mBuffer = nullptr;
} }
AI_DEBUG_INVALIDATE_PTR(pIOHandler); AI_DEBUG_INVALIDATE_PTR(mIOHandler);
AI_DEBUG_INVALIDATE_PTR(pScene); AI_DEBUG_INVALIDATE_PTR(pScene);
}; };
@ -246,23 +238,18 @@ void MDLImporter::InternReadFile( const std::string& pFile,
} }
// IDST/IDSQ Format (CS:S/HL^2, etc ...) // IDST/IDSQ Format (CS:S/HL^2, etc ...)
else if (AI_MDL_MAGIC_NUMBER_BE_HL2a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2a == iMagicWord || else if (AI_MDL_MAGIC_NUMBER_BE_HL2a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2a == iMagicWord ||
AI_MDL_MAGIC_NUMBER_BE_HL2b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2b == iMagicWord) AI_MDL_MAGIC_NUMBER_BE_HL2b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2b == iMagicWord) {
{
iGSFileVersion = 0; iGSFileVersion = 0;
HalfLife::HalfLifeMDLBaseHeader *pHeader = (HalfLife::HalfLifeMDLBaseHeader *)mBuffer; HalfLife::HalfLifeMDLBaseHeader *pHeader = (HalfLife::HalfLifeMDLBaseHeader *)mBuffer;
if (pHeader->version == AI_MDL_HL1_VERSION) if (pHeader->version == AI_MDL_HL1_VERSION) {
{
ASSIMP_LOG_DEBUG("MDL subtype: Half-Life 1/Goldsrc Engine, magic word is IDST/IDSQ"); ASSIMP_LOG_DEBUG("MDL subtype: Half-Life 1/Goldsrc Engine, magic word is IDST/IDSQ");
InternReadFile_HL1(pFile, iMagicWord); InternReadFile_HL1(pFile, iMagicWord);
} } else {
else
{
ASSIMP_LOG_DEBUG("MDL subtype: Source(tm) Engine, magic word is IDST/IDSQ"); ASSIMP_LOG_DEBUG("MDL subtype: Source(tm) Engine, magic word is IDST/IDSQ");
InternReadFile_HL2(); InternReadFile_HL2();
} }
} } else {
else {
// print the magic word to the log file // print the magic word to the log file
throw DeadlyImportError("Unknown MDL subformat " + pFile + throw DeadlyImportError("Unknown MDL subformat " + pFile +
". Magic word (" + std::string((char *)&iMagicWord, 4) + ") is not known"); ". Magic word (" + std::string((char *)&iMagicWord, 4) + ") is not known");
@ -281,10 +268,8 @@ void MDLImporter::InternReadFile( const std::string& pFile,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Check whether we're still inside the valid file range // Check whether we're still inside the valid file range
void MDLImporter::SizeCheck(const void* szPos) void MDLImporter::SizeCheck(const void *szPos) {
{ if (!szPos || (const unsigned char *)szPos > this->mBuffer + this->iFileSize) {
if (!szPos || (const unsigned char*)szPos > this->mBuffer + this->iFileSize)
{
throw DeadlyImportError("Invalid MDL file. The file is too small " throw DeadlyImportError("Invalid MDL file. The file is too small "
"or contains invalid data."); "or contains invalid data.");
} }
@ -292,22 +277,25 @@ void MDLImporter::SizeCheck(const void* szPos)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Just for debugging purposes // Just for debugging purposes
void MDLImporter::SizeCheck(const void* szPos, const char* szFile, unsigned int iLine) void MDLImporter::SizeCheck(const void *szPos, const char *szFile, unsigned int iLine) {
{
ai_assert(NULL != szFile); ai_assert(NULL != szFile);
if (!szPos || (const unsigned char*)szPos > mBuffer + iFileSize) if (!szPos || (const unsigned char *)szPos > mBuffer + iFileSize) {
{
// remove a directory if there is one // remove a directory if there is one
const char *szFilePtr = ::strrchr(szFile, '\\'); const char *szFilePtr = ::strrchr(szFile, '\\');
if (!szFilePtr) { if (!szFilePtr) {
if(!(szFilePtr = ::strrchr(szFile,'/'))) szFilePtr = ::strrchr(szFile, '/');
if (nullptr == szFilePtr) {
szFilePtr = szFile; szFilePtr = szFile;
} }
if (szFilePtr)++szFilePtr; }
if (szFilePtr) {
++szFilePtr;
}
char szBuffer[1024]; char szBuffer[1024];
::sprintf(szBuffer, "Invalid MDL file. The file is too small " ::sprintf(szBuffer, "Invalid MDL file. The file is too small "
"or contains invalid data (File: %s Line: %u)",szFilePtr,iLine); "or contains invalid data (File: %s Line: %u)",
szFilePtr, iLine);
throw DeadlyImportError(szBuffer); throw DeadlyImportError(szBuffer);
} }
@ -315,8 +303,7 @@ void MDLImporter::SizeCheck(const void* szPos, const char* szFile, unsigned int
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Validate a quake file header // Validate a quake file header
void MDLImporter::ValidateHeader_Quake1(const MDL::Header* pcHeader) void MDLImporter::ValidateHeader_Quake1(const MDL::Header *pcHeader) {
{
// some values may not be NULL // some values may not be NULL
if (!pcHeader->num_frames) if (!pcHeader->num_frames)
throw DeadlyImportError("[Quake 1 MDL] There are no frames in the file"); throw DeadlyImportError("[Quake 1 MDL] There are no frames in the file");
@ -328,8 +315,7 @@ void MDLImporter::ValidateHeader_Quake1(const MDL::Header* pcHeader)
throw DeadlyImportError("[Quake 1 MDL] There are no triangles in the file"); throw DeadlyImportError("[Quake 1 MDL] There are no triangles in the file");
// check whether the maxima are exceeded ...however, this applies for Quake 1 MDLs only // check whether the maxima are exceeded ...however, this applies for Quake 1 MDLs only
if (!this->iGSFileVersion) if (!this->iGSFileVersion) {
{
if (pcHeader->num_verts > AI_MDL_MAX_VERTS) if (pcHeader->num_verts > AI_MDL_MAX_VERTS)
ASSIMP_LOG_WARN("Quake 1 MDL model has more than AI_MDL_MAX_VERTS vertices"); ASSIMP_LOG_WARN("Quake 1 MDL model has more than AI_MDL_MAX_VERTS vertices");
@ -350,8 +336,7 @@ void MDLImporter::ValidateHeader_Quake1(const MDL::Header* pcHeader)
#ifdef AI_BUILD_BIG_ENDIAN #ifdef AI_BUILD_BIG_ENDIAN
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void FlipQuakeHeader(BE_NCONST MDL::Header* pcHeader) void FlipQuakeHeader(BE_NCONST MDL::Header *pcHeader) {
{
AI_SWAP4(pcHeader->ident); AI_SWAP4(pcHeader->ident);
AI_SWAP4(pcHeader->version); AI_SWAP4(pcHeader->version);
AI_SWAP4(pcHeader->boundingradius); AI_SWAP4(pcHeader->boundingradius);
@ -360,8 +345,7 @@ void FlipQuakeHeader(BE_NCONST MDL::Header* pcHeader)
AI_SWAP4(pcHeader->num_skins); AI_SWAP4(pcHeader->num_skins);
AI_SWAP4(pcHeader->num_tris); AI_SWAP4(pcHeader->num_tris);
AI_SWAP4(pcHeader->num_verts); AI_SWAP4(pcHeader->num_verts);
for (unsigned int i = 0; i < 3;++i) for (unsigned int i = 0; i < 3; ++i) {
{
AI_SWAP4(pcHeader->scale[i]); AI_SWAP4(pcHeader->scale[i]);
AI_SWAP4(pcHeader->translate[i]); AI_SWAP4(pcHeader->translate[i]);
} }
@ -450,15 +434,13 @@ void MDLImporter::InternReadFile_Quake1() {
VALIDATE_FILE_SIZE((const unsigned char *)(pcVertices + pcHeader->num_verts)); VALIDATE_FILE_SIZE((const unsigned char *)(pcVertices + pcHeader->num_verts));
#ifdef AI_BUILD_BIG_ENDIAN #ifdef AI_BUILD_BIG_ENDIAN
for (int i = 0; i<pcHeader->num_verts;++i) for (int i = 0; i < pcHeader->num_verts; ++i) {
{
AI_SWAP4(pcTexCoords[i].onseam); AI_SWAP4(pcTexCoords[i].onseam);
AI_SWAP4(pcTexCoords[i].s); AI_SWAP4(pcTexCoords[i].s);
AI_SWAP4(pcTexCoords[i].t); AI_SWAP4(pcTexCoords[i].t);
} }
for (int i = 0; i<pcHeader->num_tris;++i) for (int i = 0; i < pcHeader->num_tris; ++i) {
{
AI_SWAP4(pcTriangles[i].facesfront); AI_SWAP4(pcTriangles[i].facesfront);
AI_SWAP4(pcTriangles[i].vertex[0]); AI_SWAP4(pcTriangles[i].vertex[0]);
AI_SWAP4(pcTriangles[i].vertex[1]); AI_SWAP4(pcTriangles[i].vertex[1]);
@ -492,20 +474,17 @@ void MDLImporter::InternReadFile_Quake1() {
// now iterate through all triangles // now iterate through all triangles
unsigned int iCurrent = 0; unsigned int iCurrent = 0;
for (unsigned int i = 0; i < (unsigned int) pcHeader->num_tris;++i) for (unsigned int i = 0; i < (unsigned int)pcHeader->num_tris; ++i) {
{
pcMesh->mFaces[i].mIndices = new unsigned int[3]; pcMesh->mFaces[i].mIndices = new unsigned int[3];
pcMesh->mFaces[i].mNumIndices = 3; pcMesh->mFaces[i].mNumIndices = 3;
unsigned int iTemp = iCurrent; unsigned int iTemp = iCurrent;
for (unsigned int c = 0; c < 3;++c,++iCurrent) for (unsigned int c = 0; c < 3; ++c, ++iCurrent) {
{
pcMesh->mFaces[i].mIndices[c] = iCurrent; pcMesh->mFaces[i].mIndices[c] = iCurrent;
// read vertices // read vertices
unsigned int iIndex = pcTriangles->vertex[c]; unsigned int iIndex = pcTriangles->vertex[c];
if (iIndex >= (unsigned int)pcHeader->num_verts) if (iIndex >= (unsigned int)pcHeader->num_verts) {
{
iIndex = pcHeader->num_verts - 1; iIndex = pcHeader->num_verts - 1;
ASSIMP_LOG_WARN("Index overflow in Q1-MDL vertex list."); ASSIMP_LOG_WARN("Index overflow in Q1-MDL vertex list.");
} }
@ -537,7 +516,6 @@ void MDLImporter::InternReadFile_Quake1() {
// Scale s and t to range from 0.0 to 1.0 // Scale s and t to range from 0.0 to 1.0
pcMesh->mTextureCoords[0][iCurrent].x = (s + 0.5f) / pcHeader->skinwidth; pcMesh->mTextureCoords[0][iCurrent].x = (s + 0.5f) / pcHeader->skinwidth;
pcMesh->mTextureCoords[0][iCurrent].y = 1.0f - (t + 0.5f) / pcHeader->skinheight; pcMesh->mTextureCoords[0][iCurrent].y = 1.0f - (t + 0.5f) / pcHeader->skinheight;
} }
pcMesh->mFaces[i].mIndices[0] = iTemp + 2; pcMesh->mFaces[i].mIndices[0] = iTemp + 2;
pcMesh->mFaces[i].mIndices[1] = iTemp + 1; pcMesh->mFaces[i].mIndices[1] = iTemp + 1;
@ -549,8 +527,7 @@ void MDLImporter::InternReadFile_Quake1() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Setup material properties for Quake and older GameStudio files // Setup material properties for Quake and older GameStudio files
void MDLImporter::SetupMaterialProperties_3DGS_MDL5_Quake1( ) void MDLImporter::SetupMaterialProperties_3DGS_MDL5_Quake1() {
{
const MDL::Header *const pcHeader = (const MDL::Header *)this->mBuffer; const MDL::Header *const pcHeader = (const MDL::Header *)this->mBuffer;
// allocate ONE material // allocate ONE material
@ -573,8 +550,7 @@ void MDLImporter::SetupMaterialProperties_3DGS_MDL5_Quake1( )
pScene->mTextures = NULL; pScene->mTextures = NULL;
pScene->mNumTextures = 0; pScene->mNumTextures = 0;
} } else {
else {
clr.b = clr.a = clr.g = clr.r = 1.0f; clr.b = clr.a = clr.g = clr.r = 1.0f;
aiString szString; aiString szString;
::memcpy(szString.data, AI_MAKE_EMBEDDED_TEXNAME(0), 3); ::memcpy(szString.data, AI_MAKE_EMBEDDED_TEXNAME(0), 3);
@ -586,15 +562,16 @@ void MDLImporter::SetupMaterialProperties_3DGS_MDL5_Quake1( )
pcHelper->AddProperty<aiColor4D>(&clr, 1, AI_MATKEY_COLOR_DIFFUSE); pcHelper->AddProperty<aiColor4D>(&clr, 1, AI_MATKEY_COLOR_DIFFUSE);
pcHelper->AddProperty<aiColor4D>(&clr, 1, AI_MATKEY_COLOR_SPECULAR); pcHelper->AddProperty<aiColor4D>(&clr, 1, AI_MATKEY_COLOR_SPECULAR);
clr.r *= 0.05f;clr.g *= 0.05f; clr.r *= 0.05f;
clr.b *= 0.05f;clr.a = 1.0f; clr.g *= 0.05f;
clr.b *= 0.05f;
clr.a = 1.0f;
pcHelper->AddProperty<aiColor4D>(&clr, 1, AI_MATKEY_COLOR_AMBIENT); pcHelper->AddProperty<aiColor4D>(&clr, 1, AI_MATKEY_COLOR_AMBIENT);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Read a MDL 3,4,5 file // Read a MDL 3,4,5 file
void MDLImporter::InternReadFile_3DGS_MDL345( ) void MDLImporter::InternReadFile_3DGS_MDL345() {
{
ai_assert(NULL != pScene); ai_assert(NULL != pScene);
// the header of MDL 3/4/5 is nearly identical to the original Quake1 header // the header of MDL 3/4/5 is nearly identical to the original Quake1 header
@ -618,19 +595,16 @@ void MDLImporter::InternReadFile_3DGS_MDL345( )
AI_SWAP4(pcSkin->group); AI_SWAP4(pcSkin->group);
// create one output image // create one output image
unsigned int iSkip = i ? UINT_MAX : 0; unsigned int iSkip = i ? UINT_MAX : 0;
if (5 <= iGSFileVersion) if (5 <= iGSFileVersion) {
{
// MDL5 format could contain MIPmaps // MDL5 format could contain MIPmaps
CreateTexture_3DGS_MDL5((unsigned char *)pcSkin + sizeof(uint32_t), CreateTexture_3DGS_MDL5((unsigned char *)pcSkin + sizeof(uint32_t),
pcSkin->group, &iSkip); pcSkin->group, &iSkip);
} } else {
else {
CreateTexture_3DGS_MDL4((unsigned char *)pcSkin + sizeof(uint32_t), CreateTexture_3DGS_MDL4((unsigned char *)pcSkin + sizeof(uint32_t),
pcSkin->group, &iSkip); pcSkin->group, &iSkip);
} }
// need to skip one image // need to skip one image
szCurrent += iSkip + sizeof(uint32_t); szCurrent += iSkip + sizeof(uint32_t);
} }
// get a pointer to the texture coordinates // get a pointer to the texture coordinates
BE_NCONST MDL::TexCoord_MDL3 *pcTexCoords = (BE_NCONST MDL::TexCoord_MDL3 *)szCurrent; BE_NCONST MDL::TexCoord_MDL3 *pcTexCoords = (BE_NCONST MDL::TexCoord_MDL3 *)szCurrent;
@ -816,8 +790,7 @@ void MDLImporter::InternReadFile_3DGS_MDL345( )
void MDLImporter::ImportUVCoordinate_3DGS_MDL345( void MDLImporter::ImportUVCoordinate_3DGS_MDL345(
aiVector3D &vOut, aiVector3D &vOut,
const MDL::TexCoord_MDL3 *pcSrc, const MDL::TexCoord_MDL3 *pcSrc,
unsigned int iIndex) unsigned int iIndex) {
{
ai_assert(NULL != pcSrc); ai_assert(NULL != pcSrc);
const MDL::Header *const pcHeader = (const MDL::Header *)this->mBuffer; const MDL::Header *const pcHeader = (const MDL::Header *)this->mBuffer;
@ -843,8 +816,7 @@ void MDLImporter::ImportUVCoordinate_3DGS_MDL345(
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Compute UV coordinates for a MDL5 file // Compute UV coordinates for a MDL5 file
void MDLImporter::CalculateUVCoordinates_MDL5() void MDLImporter::CalculateUVCoordinates_MDL5() {
{
const MDL::Header *const pcHeader = (const MDL::Header *)this->mBuffer; const MDL::Header *const pcHeader = (const MDL::Header *)this->mBuffer;
if (pcHeader->num_skins && this->pScene->mNumTextures) { if (pcHeader->num_skins && this->pScene->mNumTextures) {
const aiTexture *pcTex = this->pScene->mTextures[0]; const aiTexture *pcTex = this->pScene->mTextures[0];
@ -859,8 +831,7 @@ void MDLImporter::CalculateUVCoordinates_MDL5()
piPtr += 3; piPtr += 3;
iHeight = (unsigned int)*piPtr++; iHeight = (unsigned int)*piPtr++;
iWidth = (unsigned int)*piPtr; iWidth = (unsigned int)*piPtr;
if (!iHeight || !iWidth) if (!iHeight || !iWidth) {
{
ASSIMP_LOG_WARN("Either the width or the height of the " ASSIMP_LOG_WARN("Either the width or the height of the "
"embedded DDS texture is zero. Unable to compute final texture " "embedded DDS texture is zero. Unable to compute final texture "
"coordinates. The texture coordinates remain in their original " "coordinates. The texture coordinates remain in their original "
@ -868,8 +839,7 @@ void MDLImporter::CalculateUVCoordinates_MDL5()
iWidth = 1; iWidth = 1;
iHeight = 1; iHeight = 1;
} }
} } else {
else {
iWidth = pcTex->mWidth; iWidth = pcTex->mWidth;
iHeight = pcTex->mHeight; iHeight = pcTex->mHeight;
} }
@ -878,8 +848,7 @@ void MDLImporter::CalculateUVCoordinates_MDL5()
const float fWidth = (float)iWidth; const float fWidth = (float)iWidth;
const float fHeight = (float)iHeight; const float fHeight = (float)iHeight;
aiMesh *pcMesh = this->pScene->mMeshes[0]; aiMesh *pcMesh = this->pScene->mMeshes[0];
for (unsigned int i = 0; i < pcMesh->mNumVertices;++i) for (unsigned int i = 0; i < pcMesh->mNumVertices; ++i) {
{
pcMesh->mTextureCoords[0][i].x /= fWidth; pcMesh->mTextureCoords[0][i].x /= fWidth;
pcMesh->mTextureCoords[0][i].y /= fHeight; pcMesh->mTextureCoords[0][i].y /= fHeight;
pcMesh->mTextureCoords[0][i].y = 1.0f - pcMesh->mTextureCoords[0][i].y; // DX to OGL pcMesh->mTextureCoords[0][i].y = 1.0f - pcMesh->mTextureCoords[0][i].y; // DX to OGL
@ -890,8 +859,7 @@ void MDLImporter::CalculateUVCoordinates_MDL5()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Validate the header of a MDL7 file // Validate the header of a MDL7 file
void MDLImporter::ValidateHeader_3DGS_MDL7(const MDL::Header_MDL7* pcHeader) void MDLImporter::ValidateHeader_3DGS_MDL7(const MDL::Header_MDL7 *pcHeader) {
{
ai_assert(NULL != pcHeader); ai_assert(NULL != pcHeader);
// There are some fixed sizes ... // There are some fixed sizes ...
@ -916,8 +884,7 @@ void MDLImporter::ValidateHeader_3DGS_MDL7(const MDL::Header_MDL7* pcHeader)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// resolve bone animation matrices // resolve bone animation matrices
void MDLImporter::CalcAbsBoneMatrices_3DGS_MDL7(MDL::IntBone_MDL7** apcOutBones) void MDLImporter::CalcAbsBoneMatrices_3DGS_MDL7(MDL::IntBone_MDL7 **apcOutBones) {
{
const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7 *)this->mBuffer; const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7 *)this->mBuffer;
const MDL::Bone_MDL7 *pcBones = (const MDL::Bone_MDL7 *)(pcHeader + 1); const MDL::Bone_MDL7 *pcBones = (const MDL::Bone_MDL7 *)(pcHeader + 1);
ai_assert(NULL != apcOutBones); ai_assert(NULL != apcOutBones);
@ -979,8 +946,7 @@ void MDLImporter::CalcAbsBoneMatrices_3DGS_MDL7(MDL::IntBone_MDL7** apcOutBones)
// no real name for our poor bone is specified :-( // no real name for our poor bone is specified :-(
pcOutBone->mName.length = ai_snprintf(pcOutBone->mName.data, MAXLEN, pcOutBone->mName.length = ai_snprintf(pcOutBone->mName.data, MAXLEN,
"UnnamedBone_%i", iBone); "UnnamedBone_%i", iBone);
} } else {
else {
// Make sure we won't run over the buffer's end if there is no // Make sure we won't run over the buffer's end if there is no
// terminal 0 character (however the documentation says there // terminal 0 character (however the documentation says there
// should be one) // should be one)
@ -1005,15 +971,13 @@ void MDLImporter::CalcAbsBoneMatrices_3DGS_MDL7(MDL::IntBone_MDL7** apcOutBones)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// read bones from a MDL7 file // read bones from a MDL7 file
MDL::IntBone_MDL7** MDLImporter::LoadBones_3DGS_MDL7() MDL::IntBone_MDL7 **MDLImporter::LoadBones_3DGS_MDL7() {
{
const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7 *)this->mBuffer; const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7 *)this->mBuffer;
if (pcHeader->bones_num) { if (pcHeader->bones_num) {
// validate the size of the bone data structure in the file // validate the size of the bone data structure in the file
if (AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS != pcHeader->bone_stc_size && if (AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS != pcHeader->bone_stc_size &&
AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_32_CHARS != pcHeader->bone_stc_size && AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_32_CHARS != pcHeader->bone_stc_size &&
AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_NOT_THERE != pcHeader->bone_stc_size) AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_NOT_THERE != pcHeader->bone_stc_size) {
{
ASSIMP_LOG_WARN("Unknown size of bone data structure"); ASSIMP_LOG_WARN("Unknown size of bone data structure");
return NULL; return NULL;
} }
@ -1032,8 +996,7 @@ MDL::IntBone_MDL7** MDLImporter::LoadBones_3DGS_MDL7()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// read faces from a MDL7 file // read faces from a MDL7 file
void MDLImporter::ReadFaces_3DGS_MDL7(const MDL::IntGroupInfo_MDL7 &groupInfo, void MDLImporter::ReadFaces_3DGS_MDL7(const MDL::IntGroupInfo_MDL7 &groupInfo,
MDL::IntGroupData_MDL7& groupData) MDL::IntGroupData_MDL7 &groupData) {
{
const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7 *)this->mBuffer; const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7 *)this->mBuffer;
MDL::Triangle_MDL7 *pcGroupTris = groupInfo.pcGroupTris; MDL::Triangle_MDL7 *pcGroupTris = groupInfo.pcGroupTris;
@ -1051,7 +1014,7 @@ void MDLImporter::ReadFaces_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo,
unsigned int iIndex = pcGroupTris->v_index[c]; unsigned int iIndex = pcGroupTris->v_index[c];
if (iIndex > (unsigned int)groupInfo.pcGroup->numverts) { if (iIndex > (unsigned int)groupInfo.pcGroup->numverts) {
// (we might need to read this section a second time - to process frame vertices correctly) // (we might need to read this section a second time - to process frame vertices correctly)
pcGroupTris->v_index[c] = iIndex = groupInfo.pcGroup->numverts-1; pcGroupTris->v_index[c] = (uint16_t) (iIndex = groupInfo.pcGroup->numverts - 1 );
ASSIMP_LOG_WARN("Index overflow in MDL7 vertex list"); ASSIMP_LOG_WARN("Index overflow in MDL7 vertex list");
} }
@ -1066,7 +1029,8 @@ void MDLImporter::ReadFaces_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo,
// if we have bones, save the index // if we have bones, save the index
if (!groupData.aiBones.empty()) { if (!groupData.aiBones.empty()) {
groupData.aiBones[iOutIndex] = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts, groupData.aiBones[iOutIndex] = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,
iIndex,pcHeader->mainvertex_stc_size).vertindex; iIndex, pcHeader->mainvertex_stc_size)
.vertindex;
} }
// now read the normal vector // now read the normal vector
@ -1079,12 +1043,13 @@ void MDLImporter::ReadFaces_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo,
AI_SWAP4(vNormal.y); AI_SWAP4(vNormal.y);
vNormal.z = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts, iIndex, pcHeader->mainvertex_stc_size).norm[2]; vNormal.z = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts, iIndex, pcHeader->mainvertex_stc_size).norm[2];
AI_SWAP4(vNormal.z); AI_SWAP4(vNormal.z);
} } else if (AI_MDL7_FRAMEVERTEX120503_STCSIZE <= pcHeader->mainvertex_stc_size) {
else if (AI_MDL7_FRAMEVERTEX120503_STCSIZE <= pcHeader->mainvertex_stc_size) {
// read the normal vector from Quake2's smart table // read the normal vector from Quake2's smart table
aiVector3D &vNormal = groupData.vNormals[iOutIndex]; aiVector3D &vNormal = groupData.vNormals[iOutIndex];
MD2::LookupNormalIndex(_AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts, iIndex, MD2::LookupNormalIndex(_AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts, iIndex,
pcHeader->mainvertex_stc_size) .norm162index,vNormal); pcHeader->mainvertex_stc_size)
.norm162index,
vNormal);
} }
// validate and process the first uv coordinate set // validate and process the first uv coordinate set
if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV) { if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV) {
@ -1158,8 +1123,7 @@ bool MDLImporter::ProcessFrames_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInf
MDL::IntGroupData_MDL7 &groupData, MDL::IntGroupData_MDL7 &groupData,
MDL::IntSharedData_MDL7 &shared, MDL::IntSharedData_MDL7 &shared,
const unsigned char *szCurrent, const unsigned char *szCurrent,
const unsigned char** szCurrentOut) const unsigned char **szCurrentOut) {
{
ai_assert(nullptr != szCurrent); ai_assert(nullptr != szCurrent);
ai_assert(nullptr != szCurrentOut); ai_assert(nullptr != szCurrentOut);
@ -1219,11 +1183,12 @@ bool MDLImporter::ProcessFrames_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInf
AI_SWAP4(vNormal.y); AI_SWAP4(vNormal.y);
vNormal.z = _AI_MDL7_ACCESS_VERT(pcFrameVertices, qq, pcHeader->framevertex_stc_size).norm[2]; vNormal.z = _AI_MDL7_ACCESS_VERT(pcFrameVertices, qq, pcHeader->framevertex_stc_size).norm[2];
AI_SWAP4(vNormal.z); AI_SWAP4(vNormal.z);
} } else if (AI_MDL7_FRAMEVERTEX120503_STCSIZE <= pcHeader->mainvertex_stc_size) {
else if (AI_MDL7_FRAMEVERTEX120503_STCSIZE <= pcHeader->mainvertex_stc_size) {
// read the normal vector from Quake2's smart table // read the normal vector from Quake2's smart table
MD2::LookupNormalIndex(_AI_MDL7_ACCESS_VERT(pcFrameVertices, qq, MD2::LookupNormalIndex(_AI_MDL7_ACCESS_VERT(pcFrameVertices, qq,
pcHeader->framevertex_stc_size) .norm162index,vNormal); pcHeader->framevertex_stc_size)
.norm162index,
vNormal);
} }
// FIXME: O(n^2) at the moment ... // FIXME: O(n^2) at the moment ...
@ -1241,7 +1206,8 @@ bool MDLImporter::ProcessFrames_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInf
} }
// get the next triangle in the list // get the next triangle in the list
pcGroupTris = (BE_NCONST MDL::Triangle_MDL7 *)((const char *) pcGroupTris = (BE_NCONST MDL::Triangle_MDL7 *)((const char *)
pcGroupTris + pcHeader->triangle_stc_size); pcGroupTris +
pcHeader->triangle_stc_size);
} }
} }
} }
@ -1260,8 +1226,7 @@ bool MDLImporter::ProcessFrames_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInf
void MDLImporter::SortByMaterials_3DGS_MDL7( void MDLImporter::SortByMaterials_3DGS_MDL7(
const MDL::IntGroupInfo_MDL7 &groupInfo, const MDL::IntGroupInfo_MDL7 &groupInfo,
MDL::IntGroupData_MDL7 &groupData, MDL::IntGroupData_MDL7 &groupData,
MDL::IntSplitGroupData_MDL7& splitGroupData) MDL::IntSplitGroupData_MDL7 &splitGroupData) {
{
const unsigned int iNumMaterials = (unsigned int)splitGroupData.shared.pcMats.size(); const unsigned int iNumMaterials = (unsigned int)splitGroupData.shared.pcMats.size();
if (!groupData.bNeed2UV) { if (!groupData.bNeed2UV) {
// if we don't need a second set of texture coordinates there is no reason to keep it in memory ... // if we don't need a second set of texture coordinates there is no reason to keep it in memory ...
@ -1284,13 +1249,10 @@ void MDLImporter::SortByMaterials_3DGS_MDL7(
// one skin assigned. No warning in this case // one skin assigned. No warning in this case
if (0xFFFFFFFF != groupData.pcFaces[iFace].iMatIndex[0]) if (0xFFFFFFFF != groupData.pcFaces[iFace].iMatIndex[0])
ASSIMP_LOG_WARN("Index overflow in MDL7 material list [#0]"); ASSIMP_LOG_WARN("Index overflow in MDL7 material list [#0]");
} else
splitGroupData.aiSplit[groupData.pcFaces[iFace].iMatIndex[0]]->push_back(iFace);
} }
else splitGroupData.aiSplit[groupData.pcFaces[iFace]. } else {
iMatIndex[0]]->push_back(iFace);
}
}
else
{
// we need to build combined materials for each combination of // we need to build combined materials for each combination of
std::vector<MDL::IntMaterial_MDL7> avMats; std::vector<MDL::IntMaterial_MDL7> avMats;
avMats.reserve(iNumMaterials * 2); avMats.reserve(iNumMaterials * 2);
@ -1358,8 +1320,7 @@ void MDLImporter::SortByMaterials_3DGS_MDL7(
splitGroupData.shared.pcMats.resize(avMats.size()); splitGroupData.shared.pcMats.resize(avMats.size());
for (unsigned int o = 0; o < avMats.size(); ++o) for (unsigned int o = 0; o < avMats.size(); ++o)
splitGroupData.shared.pcMats[o] = avMats[o].pcMat; splitGroupData.shared.pcMats[o] = avMats[o].pcMat;
} } else {
else {
// This might result in redundant materials ... // This might result in redundant materials ...
splitGroupData.shared.pcMats.resize(iNumMaterials + avMats.size()); splitGroupData.shared.pcMats.resize(iNumMaterials + avMats.size());
for (unsigned int o = iNumMaterials; o < avMats.size(); ++o) for (unsigned int o = iNumMaterials; o < avMats.size(); ++o)
@ -1375,8 +1336,7 @@ void MDLImporter::SortByMaterials_3DGS_MDL7(
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Read a MDL7 file // Read a MDL7 file
void MDLImporter::InternReadFile_3DGS_MDL7( ) void MDLImporter::InternReadFile_3DGS_MDL7() {
{
ai_assert(NULL != pScene); ai_assert(NULL != pScene);
MDL::IntSharedData_MDL7 sharedData; MDL::IntSharedData_MDL7 sharedData;
@ -1454,7 +1414,8 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
// read all skins // read all skins
sharedData.pcMats.reserve(sharedData.pcMats.size() + groupInfo.pcGroup->numskins); sharedData.pcMats.reserve(sharedData.pcMats.size() + groupInfo.pcGroup->numskins);
sharedData.abNeedMaterials.resize(sharedData.abNeedMaterials.size() + sharedData.abNeedMaterials.resize(sharedData.abNeedMaterials.size() +
groupInfo.pcGroup->numskins,false); groupInfo.pcGroup->numskins,
false);
for (unsigned int iSkin = 0; iSkin < (unsigned int)groupInfo.pcGroup->numskins; ++iSkin) { for (unsigned int iSkin = 0; iSkin < (unsigned int)groupInfo.pcGroup->numskins; ++iSkin) {
ParseSkinLump_3DGS_MDL7(szCurrent, &szCurrent, sharedData.pcMats); ParseSkinLump_3DGS_MDL7(szCurrent, &szCurrent, sharedData.pcMats);
@ -1508,8 +1469,7 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
MDL::IntSplitGroupData_MDL7 splitGroupData(sharedData, avOutList[iGroup]); MDL::IntSplitGroupData_MDL7 splitGroupData(sharedData, avOutList[iGroup]);
MDL::IntGroupData_MDL7 groupData; MDL::IntGroupData_MDL7 groupData;
if (groupInfo.pcGroup->numtris && groupInfo.pcGroup->numverts) if (groupInfo.pcGroup->numtris && groupInfo.pcGroup->numverts) {
{
// build output vectors // build output vectors
const unsigned int iNumVertices = groupInfo.pcGroup->numtris * 3; const unsigned int iNumVertices = groupInfo.pcGroup->numtris * 3;
groupData.vPositions.resize(iNumVertices); groupData.vPositions.resize(iNumVertices);
@ -1541,8 +1501,8 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
if (!splitGroupData.aiSplit[qq]->empty()) if (!splitGroupData.aiSplit[qq]->empty())
sharedData.abNeedMaterials[qq] = true; sharedData.abNeedMaterials[qq] = true;
} }
} } else
else ASSIMP_LOG_WARN("[3DGS MDL7] Mesh group consists of 0 " ASSIMP_LOG_WARN("[3DGS MDL7] Mesh group consists of 0 "
"vertices or faces. It will be skipped."); "vertices or faces. It will be skipped.");
// process all frames and generate output meshes // process all frames and generate output meshes
@ -1557,7 +1517,8 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
for (uint32_t i = 0; i < pcHeader->groups_num; ++i) for (uint32_t i = 0; i < pcHeader->groups_num; ++i)
pScene->mNumMeshes += (unsigned int)avOutList[i].size(); pScene->mNumMeshes += (unsigned int)avOutList[i].size();
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; { pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
{
unsigned int p = 0, q = 0; unsigned int p = 0, q = 0;
for (uint32_t i = 0; i < pcHeader->groups_num; ++i) { for (uint32_t i = 0; i < pcHeader->groups_num; ++i) {
for (unsigned int a = 0; a < avOutList[i].size(); ++a) { for (unsigned int a = 0; a < avOutList[i].size(); ++a) {
@ -1600,8 +1561,8 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
pcOldRoot->mChildren[0] = NULL; pcOldRoot->mChildren[0] = NULL;
delete pcOldRoot; delete pcOldRoot;
pScene->mRootNode->mParent = NULL; pScene->mRootNode->mParent = NULL;
} } else
else pScene->mRootNode->mName.Set("<mesh_root>"); pScene->mRootNode->mName.Set("<mesh_root>");
delete[] avOutList; delete[] avOutList;
delete[] aszGroupNameBuffer; delete[] aszGroupNameBuffer;
@ -1622,7 +1583,8 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
// add bones to the nodegraph // add bones to the nodegraph
AddBonesToNodeGraph_3DGS_MDL7((const Assimp::MDL::IntBone_MDL7 **) AddBonesToNodeGraph_3DGS_MDL7((const Assimp::MDL::IntBone_MDL7 **)
sharedData.apcOutBones,pc,0xffff); sharedData.apcOutBones,
pc, 0xffff);
// this steps build a valid output animation // this steps build a valid output animation
BuildOutputAnims_3DGS_MDL7((const Assimp::MDL::IntBone_MDL7 **) BuildOutputAnims_3DGS_MDL7((const Assimp::MDL::IntBone_MDL7 **)
@ -1632,19 +1594,16 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Copy materials // Copy materials
void MDLImporter::CopyMaterials_3DGS_MDL7(MDL::IntSharedData_MDL7 &shared) void MDLImporter::CopyMaterials_3DGS_MDL7(MDL::IntSharedData_MDL7 &shared) {
{
pScene->mNumMaterials = (unsigned int)shared.pcMats.size(); pScene->mNumMaterials = (unsigned int)shared.pcMats.size();
pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials]; pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials];
for (unsigned int i = 0; i < pScene->mNumMaterials; ++i) for (unsigned int i = 0; i < pScene->mNumMaterials; ++i)
pScene->mMaterials[i] = shared.pcMats[i]; pScene->mMaterials[i] = shared.pcMats[i];
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Process material references // Process material references
void MDLImporter::HandleMaterialReferences_3DGS_MDL7() void MDLImporter::HandleMaterialReferences_3DGS_MDL7() {
{
// search for referrer materials // search for referrer materials
for (unsigned int i = 0; i < pScene->mNumMaterials; ++i) { for (unsigned int i = 0; i < pScene->mNumMaterials; ++i) {
int iIndex = 0; int iIndex = 0;
@ -1675,16 +1634,14 @@ void MDLImporter::HandleMaterialReferences_3DGS_MDL7()
void MDLImporter::ParseBoneTrafoKeys_3DGS_MDL7( void MDLImporter::ParseBoneTrafoKeys_3DGS_MDL7(
const MDL::IntGroupInfo_MDL7 &groupInfo, const MDL::IntGroupInfo_MDL7 &groupInfo,
IntFrameInfo_MDL7 &frame, IntFrameInfo_MDL7 &frame,
MDL::IntSharedData_MDL7& shared) MDL::IntSharedData_MDL7 &shared) {
{
const MDL::Header_MDL7 *const pcHeader = (const MDL::Header_MDL7 *)this->mBuffer; const MDL::Header_MDL7 *const pcHeader = (const MDL::Header_MDL7 *)this->mBuffer;
// only the first group contains bone animation keys // only the first group contains bone animation keys
if (frame.pcFrame->transmatrix_count) { if (frame.pcFrame->transmatrix_count) {
if (!groupInfo.iIndex) { if (!groupInfo.iIndex) {
// skip all frames vertices. We can't support them // skip all frames vertices. We can't support them
const MDL::BoneTransform_MDL7* pcBoneTransforms = (const MDL::BoneTransform_MDL7*) const MDL::BoneTransform_MDL7 *pcBoneTransforms = (const MDL::BoneTransform_MDL7 *)(((const char *)frame.pcFrame) + pcHeader->frame_stc_size +
(((const char*)frame.pcFrame) + pcHeader->frame_stc_size +
frame.pcFrame->vertices_count * pcHeader->framevertex_stc_size); frame.pcFrame->vertices_count * pcHeader->framevertex_stc_size);
// read all transformation matrices // read all transformation matrices
@ -1692,16 +1649,13 @@ void MDLImporter::ParseBoneTrafoKeys_3DGS_MDL7(
if (pcBoneTransforms->bone_index >= pcHeader->bones_num) { if (pcBoneTransforms->bone_index >= pcHeader->bones_num) {
ASSIMP_LOG_WARN("Index overflow in frame area. " ASSIMP_LOG_WARN("Index overflow in frame area. "
"Unable to parse this bone transformation"); "Unable to parse this bone transformation");
} } else {
else {
AddAnimationBoneTrafoKey_3DGS_MDL7(frame.iIndex, AddAnimationBoneTrafoKey_3DGS_MDL7(frame.iIndex,
pcBoneTransforms, shared.apcOutBones); pcBoneTransforms, shared.apcOutBones);
} }
pcBoneTransforms = (const MDL::BoneTransform_MDL7*)( pcBoneTransforms = (const MDL::BoneTransform_MDL7 *)((const char *)pcBoneTransforms + pcHeader->bonetrans_stc_size);
(const char*)pcBoneTransforms + pcHeader->bonetrans_stc_size);
} }
} } else {
else {
ASSIMP_LOG_WARN("Ignoring animation keyframes in groups != 0"); ASSIMP_LOG_WARN("Ignoring animation keyframes in groups != 0");
} }
} }
@ -1710,8 +1664,7 @@ void MDLImporter::ParseBoneTrafoKeys_3DGS_MDL7(
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Attach bones to the output nodegraph // Attach bones to the output nodegraph
void MDLImporter::AddBonesToNodeGraph_3DGS_MDL7(const MDL::IntBone_MDL7 **apcBones, void MDLImporter::AddBonesToNodeGraph_3DGS_MDL7(const MDL::IntBone_MDL7 **apcBones,
aiNode* pcParent,uint16_t iParentIndex) aiNode *pcParent, uint16_t iParentIndex) {
{
ai_assert(NULL != apcBones && NULL != pcParent); ai_assert(NULL != apcBones && NULL != pcParent);
// get a pointer to the header ... // get a pointer to the header ...
@ -1742,8 +1695,7 @@ void MDLImporter::AddBonesToNodeGraph_3DGS_MDL7(const MDL::IntBone_MDL7** apcBon
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Build output animations // Build output animations
void MDLImporter::BuildOutputAnims_3DGS_MDL7( void MDLImporter::BuildOutputAnims_3DGS_MDL7(
const MDL::IntBone_MDL7** apcBonesOut) const MDL::IntBone_MDL7 **apcBonesOut) {
{
ai_assert(NULL != apcBonesOut); ai_assert(NULL != apcBonesOut);
const MDL::Header_MDL7 *const pcHeader = (const MDL::Header_MDL7 *)mBuffer; const MDL::Header_MDL7 *const pcHeader = (const MDL::Header_MDL7 *)mBuffer;
@ -1755,7 +1707,9 @@ void MDLImporter::BuildOutputAnims_3DGS_MDL7(
// get the last frame ... (needn't be equal to pcHeader->frames_num) // get the last frame ... (needn't be equal to pcHeader->frames_num)
for (size_t qq = 0; qq < apcBonesOut[i]->pkeyPositions.size(); ++qq) { for (size_t qq = 0; qq < apcBonesOut[i]->pkeyPositions.size(); ++qq) {
pcAnim->mDuration = std::max(pcAnim->mDuration, (double) pcAnim->mDuration = std::max(pcAnim->mDuration, (double)
apcBonesOut[i]->pkeyPositions[qq].mTime); apcBonesOut[i]
->pkeyPositions[qq]
.mTime);
} }
++pcAnim->mNumChannels; ++pcAnim->mNumChannels;
} }
@ -1793,15 +1747,14 @@ void MDLImporter::BuildOutputAnims_3DGS_MDL7(
pScene->mNumAnimations = 1; pScene->mNumAnimations = 1;
pScene->mAnimations = new aiAnimation *[1]; pScene->mAnimations = new aiAnimation *[1];
pScene->mAnimations[0] = pcAnim; pScene->mAnimations[0] = pcAnim;
} } else
else delete pcAnim; delete pcAnim;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void MDLImporter::AddAnimationBoneTrafoKey_3DGS_MDL7(unsigned int iTrafo, void MDLImporter::AddAnimationBoneTrafoKey_3DGS_MDL7(unsigned int iTrafo,
const MDL::BoneTransform_MDL7 *pcBoneTransforms, const MDL::BoneTransform_MDL7 *pcBoneTransforms,
MDL::IntBone_MDL7** apcBonesOut) MDL::IntBone_MDL7 **apcBonesOut) {
{
ai_assert(NULL != pcBoneTransforms); ai_assert(NULL != pcBoneTransforms);
ai_assert(NULL != apcBonesOut); ai_assert(NULL != apcBonesOut);
@ -1844,8 +1797,7 @@ void MDLImporter::AddAnimationBoneTrafoKey_3DGS_MDL7(unsigned int iTrafo,
// Construct output meshes // Construct output meshes
void MDLImporter::GenerateOutputMeshes_3DGS_MDL7( void MDLImporter::GenerateOutputMeshes_3DGS_MDL7(
MDL::IntGroupData_MDL7 &groupData, MDL::IntGroupData_MDL7 &groupData,
MDL::IntSplitGroupData_MDL7& splitGroupData) MDL::IntSplitGroupData_MDL7 &splitGroupData) {
{
const MDL::IntSharedData_MDL7 &shared = splitGroupData.shared; const MDL::IntSharedData_MDL7 &shared = splitGroupData.shared;
// get a pointer to the header ... // get a pointer to the header ...
@ -1910,7 +1862,7 @@ void MDLImporter::GenerateOutputMeshes_3DGS_MDL7(
std::vector<std::vector<unsigned int>> aaiVWeightList; std::vector<std::vector<unsigned int>> aaiVWeightList;
aaiVWeightList.resize(iNumOutBones); aaiVWeightList.resize(iNumOutBones);
int iCurrent = 0; int iCurrentWeight = 0;
for (unsigned int iFace = 0; iFace < pcMesh->mNumFaces; ++iFace) { for (unsigned int iFace = 0; iFace < pcMesh->mNumFaces; ++iFace) {
unsigned int iSrcFace = splitGroupData.aiSplit[i]->operator[](iFace); unsigned int iSrcFace = splitGroupData.aiSplit[i]->operator[](iFace);
const MDL::IntFace_MDL7 &oldFace = groupData.pcFaces[iSrcFace]; const MDL::IntFace_MDL7 &oldFace = groupData.pcFaces[iSrcFace];
@ -1924,9 +1876,9 @@ void MDLImporter::GenerateOutputMeshes_3DGS_MDL7(
"The bone index of a vertex exceeds the allowed range. "); "The bone index of a vertex exceeds the allowed range. ");
iBone = iNumOutBones - 1; iBone = iNumOutBones - 1;
} }
aaiVWeightList[ iBone ].push_back ( iCurrent ); aaiVWeightList[iBone].push_back(iCurrentWeight);
} }
++iCurrent; ++iCurrentWeight;
} }
} }
// now check which bones are required ... // now check which bones are required ...
@ -1937,8 +1889,7 @@ void MDLImporter::GenerateOutputMeshes_3DGS_MDL7(
} }
pcMesh->mBones = new aiBone *[pcMesh->mNumBones]; pcMesh->mBones = new aiBone *[pcMesh->mNumBones];
iCurrent = 0; iCurrent = 0;
for (std::vector<std::vector<unsigned int> >::const_iterator k = aaiVWeightList.begin();k!= aaiVWeightList.end();++k,++iCurrent) for (std::vector<std::vector<unsigned int>>::const_iterator k = aaiVWeightList.begin(); k != aaiVWeightList.end(); ++k, ++iCurrent) {
{
if ((*k).empty()) if ((*k).empty())
continue; continue;
@ -1968,8 +1919,7 @@ void MDLImporter::GenerateOutputMeshes_3DGS_MDL7(
void MDLImporter::JoinSkins_3DGS_MDL7( void MDLImporter::JoinSkins_3DGS_MDL7(
aiMaterial *pcMat1, aiMaterial *pcMat1,
aiMaterial *pcMat2, aiMaterial *pcMat2,
aiMaterial* pcMatOut) aiMaterial *pcMatOut) {
{
ai_assert(NULL != pcMat1 && NULL != pcMat2 && NULL != pcMatOut); ai_assert(NULL != pcMat1 && NULL != pcMat2 && NULL != pcMatOut);
// first create a full copy of the first skin property set // first create a full copy of the first skin property set
@ -1991,8 +1941,7 @@ void MDLImporter::JoinSkins_3DGS_MDL7(
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Read a Half-life 1 MDL // Read a Half-life 1 MDL
void MDLImporter::InternReadFile_HL1(const std::string& pFile, const uint32_t iMagicWord) void MDLImporter::InternReadFile_HL1(const std::string &pFile, const uint32_t iMagicWord) {
{
// We can't correctly load an MDL from a MDL "sequence" file. // We can't correctly load an MDL from a MDL "sequence" file.
if (iMagicWord == AI_MDL_MAGIC_NUMBER_BE_HL2b || iMagicWord == AI_MDL_MAGIC_NUMBER_LE_HL2b) if (iMagicWord == AI_MDL_MAGIC_NUMBER_BE_HL2b || iMagicWord == AI_MDL_MAGIC_NUMBER_LE_HL2b)
throw DeadlyImportError("Impossible to properly load a model from an MDL sequence file."); throw DeadlyImportError("Impossible to properly load a model from an MDL sequence file.");
@ -2000,7 +1949,7 @@ void MDLImporter::InternReadFile_HL1(const std::string& pFile, const uint32_t iM
// Read the MDL file. // Read the MDL file.
HalfLife::HL1MDLLoader loader( HalfLife::HL1MDLLoader loader(
pScene, pScene,
pIOHandler, mIOHandler,
mBuffer, mBuffer,
pFile, pFile,
mHL1ImportSettings); mHL1ImportSettings);
@ -2008,8 +1957,7 @@ void MDLImporter::InternReadFile_HL1(const std::string& pFile, const uint32_t iM
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Read a half-life 2 MDL // Read a half-life 2 MDL
void MDLImporter::InternReadFile_HL2( ) void MDLImporter::InternReadFile_HL2() {
{
//const MDL::Header_HL2* pcHeader = (const MDL::Header_HL2*)this->mBuffer; //const MDL::Header_HL2* pcHeader = (const MDL::Header_HL2*)this->mBuffer;
throw DeadlyImportError("HL2 MDLs are not implemented"); throw DeadlyImportError("HL2 MDLs are not implemented");
} }

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -58,7 +57,6 @@ struct aiTexture;
namespace Assimp { namespace Assimp {
using namespace MDL; using namespace MDL;
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -436,7 +434,7 @@ protected:
unsigned int iGSFileVersion; unsigned int iGSFileVersion;
/** Output I/O handler. used to load external lmp files */ /** Output I/O handler. used to load external lmp files */
IOSystem* pIOHandler; IOSystem* mIOHandler;
/** Output scene to be filled */ /** Output scene to be filled */
aiScene* pScene; aiScene* pScene;

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -43,38 +41,34 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Implementation of the material part of the MDL importer class */ /** @file Implementation of the material part of the MDL importer class */
#ifndef ASSIMP_BUILD_NO_MDL_IMPORTER #ifndef ASSIMP_BUILD_NO_MDL_IMPORTER
// internal headers // internal headers
#include "MDLLoader.h"
#include "MDLDefaultColorMap.h" #include "MDLDefaultColorMap.h"
#include <assimp/StringUtils.h> #include "MDLLoader.h"
#include <assimp/texture.h>
#include <assimp/IOSystem.hpp>
#include <assimp/DefaultLogger.hpp>
#include <assimp/scene.h>
#include <assimp/Defines.h> #include <assimp/Defines.h>
#include <assimp/StringUtils.h>
#include <assimp/qnan.h> #include <assimp/qnan.h>
#include <assimp/scene.h>
#include <assimp/texture.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <memory> #include <memory>
using namespace Assimp; using namespace Assimp;
static aiTexel *const bad_texel = reinterpret_cast<aiTexel *>(SIZE_MAX); static aiTexel *const bad_texel = reinterpret_cast<aiTexel *>(SIZE_MAX);
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Find a suitable palette file or take the default one // Find a suitable palette file or take the default one
void MDLImporter::SearchPalette(const unsigned char** pszColorMap) void MDLImporter::SearchPalette(const unsigned char **pszColorMap) {
{
// now try to find the color map in the current directory // now try to find the color map in the current directory
IOStream* pcStream = pIOHandler->Open(configPalette,"rb"); IOStream *pcStream = mIOHandler->Open(configPalette, "rb");
const unsigned char *szColorMap = (const unsigned char *)::g_aclrDefaultColorMap; const unsigned char *szColorMap = (const unsigned char *)::g_aclrDefaultColorMap;
if(pcStream) if (pcStream) {
{ if (pcStream->FileSize() >= 768) {
if (pcStream->FileSize() >= 768)
{
size_t len = 256 * 3; size_t len = 256 * 3;
unsigned char *colorMap = new unsigned char[len]; unsigned char *colorMap = new unsigned char[len];
szColorMap = colorMap; szColorMap = colorMap;
@ -83,24 +77,23 @@ void MDLImporter::SearchPalette(const unsigned char** pszColorMap)
"It will be used to decode embedded textures in palletized formats."); "It will be used to decode embedded textures in palletized formats.");
} }
delete pcStream; delete pcStream;
pcStream = NULL; pcStream = nullptr;
} }
*pszColorMap = szColorMap; *pszColorMap = szColorMap;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Free the palette again // Free the palette again
void MDLImporter::FreePalette(const unsigned char* szColorMap) void MDLImporter::FreePalette(const unsigned char *szColorMap) {
{ if (szColorMap != (const unsigned char *)::g_aclrDefaultColorMap) {
if (szColorMap != (const unsigned char*)::g_aclrDefaultColorMap)
delete[] szColorMap; delete[] szColorMap;
} }
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Check whether we can replace a texture with a single color // Check whether we can replace a texture with a single color
aiColor4D MDLImporter::ReplaceTextureWithColor(const aiTexture* pcTexture) aiColor4D MDLImporter::ReplaceTextureWithColor(const aiTexture *pcTexture) {
{ ai_assert(nullptr != pcTexture);
ai_assert(NULL != pcTexture);
aiColor4D clrOut; aiColor4D clrOut;
clrOut.r = get_qnan(); clrOut.r = get_qnan();
@ -111,17 +104,14 @@ aiColor4D MDLImporter::ReplaceTextureWithColor(const aiTexture* pcTexture)
const aiTexel *pcTexel = pcTexture->pcData + 1; const aiTexel *pcTexel = pcTexture->pcData + 1;
const aiTexel *const pcTexelEnd = &pcTexture->pcData[iNumPixels]; const aiTexel *const pcTexelEnd = &pcTexture->pcData[iNumPixels];
while (pcTexel != pcTexelEnd) while (pcTexel != pcTexelEnd) {
{ if (*pcTexel != *(pcTexel - 1)) {
if (*pcTexel != *(pcTexel-1)) pcTexel = nullptr;
{
pcTexel = NULL;
break; break;
} }
++pcTexel; ++pcTexel;
} }
if (pcTexel) if (pcTexel) {
{
clrOut.r = pcTexture->pcData->r / 255.0f; clrOut.r = pcTexture->pcData->r / 255.0f;
clrOut.g = pcTexture->pcData->g / 255.0f; clrOut.g = pcTexture->pcData->g / 255.0f;
clrOut.b = pcTexture->pcData->b / 255.0f; clrOut.b = pcTexture->pcData->b / 255.0f;
@ -132,8 +122,7 @@ aiColor4D MDLImporter::ReplaceTextureWithColor(const aiTexture* pcTexture)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Read a texture from a MDL3 file // Read a texture from a MDL3 file
void MDLImporter::CreateTextureARGB8_3DGS_MDL3(const unsigned char* szData) void MDLImporter::CreateTextureARGB8_3DGS_MDL3(const unsigned char *szData) {
{
const MDL::Header *pcHeader = (const MDL::Header *)mBuffer; //the endianness is already corrected in the InternReadFile_3DGS_MDL345 function const MDL::Header *pcHeader = (const MDL::Header *)mBuffer; //the endianness is already corrected in the InternReadFile_3DGS_MDL345 function
VALIDATE_FILE_SIZE(szData + pcHeader->skinwidth * VALIDATE_FILE_SIZE(szData + pcHeader->skinwidth *
@ -150,8 +139,7 @@ void MDLImporter::CreateTextureARGB8_3DGS_MDL3(const unsigned char* szData)
this->SearchPalette(&szColorMap); this->SearchPalette(&szColorMap);
// copy texture data // copy texture data
for (unsigned int i = 0; i < pcNew->mWidth*pcNew->mHeight;++i) for (unsigned int i = 0; i < pcNew->mWidth * pcNew->mHeight; ++i) {
{
const unsigned char val = szData[i]; const unsigned char val = szData[i];
const unsigned char *sz = &szColorMap[val * 3]; const unsigned char *sz = &szColorMap[val * 3];
@ -172,21 +160,18 @@ void MDLImporter::CreateTextureARGB8_3DGS_MDL3(const unsigned char* szData)
pScene->mTextures[this->pScene->mNumTextures] = pcNew; pScene->mTextures[this->pScene->mNumTextures] = pcNew;
pScene->mNumTextures++; pScene->mNumTextures++;
delete[] pc; delete[] pc;
return;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Read a texture from a MDL4 file // Read a texture from a MDL4 file
void MDLImporter::CreateTexture_3DGS_MDL4(const unsigned char *szData, void MDLImporter::CreateTexture_3DGS_MDL4(const unsigned char *szData,
unsigned int iType, unsigned int iType,
unsigned int* piSkip) unsigned int *piSkip) {
{ ai_assert(nullptr != piSkip);
ai_assert(NULL != piSkip);
const MDL::Header *pcHeader = (const MDL::Header *)mBuffer; //the endianness is already corrected in the InternReadFile_3DGS_MDL345 function const MDL::Header *pcHeader = (const MDL::Header *)mBuffer; //the endianness is already corrected in the InternReadFile_3DGS_MDL345 function
if (iType == 1 || iType > 3) if (iType == 1 || iType > 3) {
{
ASSIMP_LOG_ERROR("Unsupported texture file format"); ASSIMP_LOG_ERROR("Unsupported texture file format");
return; return;
} }
@ -202,16 +187,12 @@ void MDLImporter::CreateTexture_3DGS_MDL4(const unsigned char* szData,
ParseTextureColorData(szData, iType, piSkip, pcNew); ParseTextureColorData(szData, iType, piSkip, pcNew);
// store the texture // store the texture
if (!bNoRead) if (!bNoRead) {
{ if (!this->pScene->mNumTextures) {
if (!this->pScene->mNumTextures)
{
pScene->mNumTextures = 1; pScene->mNumTextures = 1;
pScene->mTextures = new aiTexture *[1]; pScene->mTextures = new aiTexture *[1];
pScene->mTextures[0] = pcNew; pScene->mTextures[0] = pcNew;
} } else {
else
{
aiTexture **pc = pScene->mTextures; aiTexture **pc = pScene->mTextures;
pScene->mTextures = new aiTexture *[pScene->mNumTextures + 1]; pScene->mTextures = new aiTexture *[pScene->mNumTextures + 1];
for (unsigned int i = 0; i < this->pScene->mNumTextures; ++i) for (unsigned int i = 0; i < this->pScene->mNumTextures; ++i)
@ -220,9 +201,8 @@ void MDLImporter::CreateTexture_3DGS_MDL4(const unsigned char* szData,
pScene->mNumTextures++; pScene->mNumTextures++;
delete[] pc; delete[] pc;
} }
} } else {
else { pcNew->pcData = nullptr;
pcNew->pcData = NULL;
delete pcNew; delete pcNew;
} }
return; return;
@ -233,8 +213,7 @@ void MDLImporter::CreateTexture_3DGS_MDL4(const unsigned char* szData,
void MDLImporter::ParseTextureColorData(const unsigned char *szData, void MDLImporter::ParseTextureColorData(const unsigned char *szData,
unsigned int iType, unsigned int iType,
unsigned int *piSkip, unsigned int *piSkip,
aiTexture* pcNew) aiTexture *pcNew) {
{
const bool do_read = bad_texel != pcNew->pcData; const bool do_read = bad_texel != pcNew->pcData;
// allocate storage for the texture image // allocate storage for the texture image
@ -244,16 +223,13 @@ void MDLImporter::ParseTextureColorData(const unsigned char* szData,
// R5G6B5 format (with or without MIPs) // R5G6B5 format (with or without MIPs)
// **************************************************************** // ****************************************************************
if (2 == iType || 10 == iType) if (2 == iType || 10 == iType) {
{
VALIDATE_FILE_SIZE(szData + pcNew->mWidth * pcNew->mHeight * 2); VALIDATE_FILE_SIZE(szData + pcNew->mWidth * pcNew->mHeight * 2);
// copy texture data // copy texture data
unsigned int i; unsigned int i;
if (do_read) if (do_read) {
{ for (i = 0; i < pcNew->mWidth * pcNew->mHeight; ++i) {
for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
{
MDL::RGB565 val = ((MDL::RGB565 *)szData)[i]; MDL::RGB565 val = ((MDL::RGB565 *)szData)[i];
AI_SWAP2(val); AI_SWAP2(val);
@ -262,29 +238,26 @@ void MDLImporter::ParseTextureColorData(const unsigned char* szData,
pcNew->pcData[i].g = (unsigned char)val.g << 2; pcNew->pcData[i].g = (unsigned char)val.g << 2;
pcNew->pcData[i].b = (unsigned char)val.r << 3; pcNew->pcData[i].b = (unsigned char)val.r << 3;
} }
} else {
i = pcNew->mWidth * pcNew->mHeight;
} }
else i = pcNew->mWidth*pcNew->mHeight;
*piSkip = i * 2; *piSkip = i * 2;
// apply MIP maps // apply MIP maps
if (10 == iType) if (10 == iType) {
{
*piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 1; *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 1;
VALIDATE_FILE_SIZE(szData + *piSkip); VALIDATE_FILE_SIZE(szData + *piSkip);
} }
} }
// ARGB4 format (with or without MIPs) // ARGB4 format (with or without MIPs)
// **************************************************************** // ****************************************************************
else if (3 == iType || 11 == iType) else if (3 == iType || 11 == iType) {
{
VALIDATE_FILE_SIZE(szData + pcNew->mWidth * pcNew->mHeight * 4); VALIDATE_FILE_SIZE(szData + pcNew->mWidth * pcNew->mHeight * 4);
// copy texture data // copy texture data
unsigned int i; unsigned int i;
if (do_read) if (do_read) {
{ for (i = 0; i < pcNew->mWidth * pcNew->mHeight; ++i) {
for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
{
MDL::ARGB4 val = ((MDL::ARGB4 *)szData)[i]; MDL::ARGB4 val = ((MDL::ARGB4 *)szData)[i];
AI_SWAP2(val); AI_SWAP2(val);
@ -293,29 +266,25 @@ void MDLImporter::ParseTextureColorData(const unsigned char* szData,
pcNew->pcData[i].g = (unsigned char)val.g << 4; pcNew->pcData[i].g = (unsigned char)val.g << 4;
pcNew->pcData[i].b = (unsigned char)val.b << 4; pcNew->pcData[i].b = (unsigned char)val.b << 4;
} }
} } else
else i = pcNew->mWidth*pcNew->mHeight; i = pcNew->mWidth * pcNew->mHeight;
*piSkip = i * 2; *piSkip = i * 2;
// apply MIP maps // apply MIP maps
if (11 == iType) if (11 == iType) {
{
*piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 1; *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 1;
VALIDATE_FILE_SIZE(szData + *piSkip); VALIDATE_FILE_SIZE(szData + *piSkip);
} }
} }
// RGB8 format (with or without MIPs) // RGB8 format (with or without MIPs)
// **************************************************************** // ****************************************************************
else if (4 == iType || 12 == iType) else if (4 == iType || 12 == iType) {
{
VALIDATE_FILE_SIZE(szData + pcNew->mWidth * pcNew->mHeight * 3); VALIDATE_FILE_SIZE(szData + pcNew->mWidth * pcNew->mHeight * 3);
// copy texture data // copy texture data
unsigned int i; unsigned int i;
if (do_read) if (do_read) {
{ for (i = 0; i < pcNew->mWidth * pcNew->mHeight; ++i) {
for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
{
const unsigned char *_szData = &szData[i * 3]; const unsigned char *_szData = &szData[i * 3];
pcNew->pcData[i].a = 0xFF; pcNew->pcData[i].a = 0xFF;
@ -323,30 +292,25 @@ void MDLImporter::ParseTextureColorData(const unsigned char* szData,
pcNew->pcData[i].g = *_szData++; pcNew->pcData[i].g = *_szData++;
pcNew->pcData[i].r = *_szData; pcNew->pcData[i].r = *_szData;
} }
} } else
else i = pcNew->mWidth*pcNew->mHeight; i = pcNew->mWidth * pcNew->mHeight;
// apply MIP maps // apply MIP maps
*piSkip = i * 3; *piSkip = i * 3;
if (12 == iType) if (12 == iType) {
{
*piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) * 3; *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) * 3;
VALIDATE_FILE_SIZE(szData + *piSkip); VALIDATE_FILE_SIZE(szData + *piSkip);
} }
} }
// ARGB8 format (with ir without MIPs) // ARGB8 format (with ir without MIPs)
// **************************************************************** // ****************************************************************
else if (5 == iType || 13 == iType) else if (5 == iType || 13 == iType) {
{
VALIDATE_FILE_SIZE(szData + pcNew->mWidth * pcNew->mHeight * 4); VALIDATE_FILE_SIZE(szData + pcNew->mWidth * pcNew->mHeight * 4);
// copy texture data // copy texture data
unsigned int i; unsigned int i;
if (do_read) if (do_read) {
{ for (i = 0; i < pcNew->mWidth * pcNew->mHeight; ++i) {
for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
{
const unsigned char *_szData = &szData[i * 4]; const unsigned char *_szData = &szData[i * 4];
pcNew->pcData[i].b = *_szData++; pcNew->pcData[i].b = *_szData++;
@ -354,32 +318,29 @@ void MDLImporter::ParseTextureColorData(const unsigned char* szData,
pcNew->pcData[i].r = *_szData++; pcNew->pcData[i].r = *_szData++;
pcNew->pcData[i].a = *_szData; pcNew->pcData[i].a = *_szData;
} }
} else {
i = pcNew->mWidth * pcNew->mHeight;
} }
else i = pcNew->mWidth*pcNew->mHeight;
// apply MIP maps // apply MIP maps
*piSkip = i << 2; *piSkip = i << 2;
if (13 == iType) if (13 == iType) {
{
*piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 2; *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 2;
} }
} }
// palletized 8 bit texture. As for Quake 1 // palletized 8 bit texture. As for Quake 1
// **************************************************************** // ****************************************************************
else if (0 == iType) else if (0 == iType) {
{
VALIDATE_FILE_SIZE(szData + pcNew->mWidth * pcNew->mHeight); VALIDATE_FILE_SIZE(szData + pcNew->mWidth * pcNew->mHeight);
// copy texture data // copy texture data
unsigned int i; unsigned int i;
if (do_read) if (do_read) {
{
const unsigned char *szColorMap; const unsigned char *szColorMap;
SearchPalette(&szColorMap); SearchPalette(&szColorMap);
for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i) for (i = 0; i < pcNew->mWidth * pcNew->mHeight; ++i) {
{
const unsigned char val = szData[i]; const unsigned char val = szData[i];
const unsigned char *sz = &szColorMap[val * 3]; const unsigned char *sz = &szColorMap[val * 3];
@ -390,8 +351,8 @@ void MDLImporter::ParseTextureColorData(const unsigned char* szData,
} }
this->FreePalette(szColorMap); this->FreePalette(szColorMap);
} } else
else i = pcNew->mWidth*pcNew->mHeight; i = pcNew->mWidth * pcNew->mHeight;
*piSkip = i; *piSkip = i;
// FIXME: Also support for MIP maps? // FIXME: Also support for MIP maps?
@ -402,8 +363,7 @@ void MDLImporter::ParseTextureColorData(const unsigned char* szData,
// Get a texture from a MDL5 file // Get a texture from a MDL5 file
void MDLImporter::CreateTexture_3DGS_MDL5(const unsigned char *szData, void MDLImporter::CreateTexture_3DGS_MDL5(const unsigned char *szData,
unsigned int iType, unsigned int iType,
unsigned int* piSkip) unsigned int *piSkip) {
{
ai_assert(NULL != piSkip); ai_assert(NULL != piSkip);
bool bNoRead = *piSkip == UINT_MAX; bool bNoRead = *piSkip == UINT_MAX;
@ -429,14 +389,12 @@ void MDLImporter::CreateTexture_3DGS_MDL5(const unsigned char* szData,
// however, one can easily try out what MED does if you have // however, one can easily try out what MED does if you have
// a model with a DDS texture and export it to MDL5 ... // a model with a DDS texture and export it to MDL5 ...
// yeah, it embedds the DDS file. // yeah, it embedds the DDS file.
if (6 == iType) if (6 == iType) {
{
// this is a compressed texture in DDS format // this is a compressed texture in DDS format
*piSkip = pcNew->mWidth; *piSkip = pcNew->mWidth;
VALIDATE_FILE_SIZE(szData + *piSkip); VALIDATE_FILE_SIZE(szData + *piSkip);
if (!bNoRead) if (!bNoRead) {
{
// place a hint and let the application know that this is a DDS file // place a hint and let the application know that this is a DDS file
pcNew->mHeight = 0; pcNew->mHeight = 0;
pcNew->achFormatHint[0] = 'd'; pcNew->achFormatHint[0] = 'd';
@ -447,25 +405,19 @@ void MDLImporter::CreateTexture_3DGS_MDL5(const unsigned char* szData,
pcNew->pcData = (aiTexel *)new unsigned char[pcNew->mWidth]; pcNew->pcData = (aiTexel *)new unsigned char[pcNew->mWidth];
::memcpy(pcNew->pcData, szData, pcNew->mWidth); ::memcpy(pcNew->pcData, szData, pcNew->mWidth);
} }
} } else {
else
{
// parse the color data of the texture // parse the color data of the texture
ParseTextureColorData(szData, iType, piSkip, pcNew); ParseTextureColorData(szData, iType, piSkip, pcNew);
} }
*piSkip += sizeof(uint32_t) * 2; *piSkip += sizeof(uint32_t) * 2;
if (!bNoRead) if (!bNoRead) {
{
// store the texture // store the texture
if (!this->pScene->mNumTextures) if (!this->pScene->mNumTextures) {
{
pScene->mNumTextures = 1; pScene->mNumTextures = 1;
pScene->mTextures = new aiTexture *[1]; pScene->mTextures = new aiTexture *[1];
pScene->mTextures[0] = pcNew; pScene->mTextures[0] = pcNew;
} } else {
else
{
aiTexture **pc = pScene->mTextures; aiTexture **pc = pScene->mTextures;
pScene->mTextures = new aiTexture *[pScene->mNumTextures + 1]; pScene->mTextures = new aiTexture *[pScene->mNumTextures + 1];
for (unsigned int i = 0; i < pScene->mNumTextures; ++i) for (unsigned int i = 0; i < pScene->mNumTextures; ++i)
@ -475,8 +427,7 @@ void MDLImporter::CreateTexture_3DGS_MDL5(const unsigned char* szData,
pScene->mNumTextures++; pScene->mNumTextures++;
delete[] pc; delete[] pc;
} }
} } else {
else {
pcNew->pcData = NULL; pcNew->pcData = NULL;
delete pcNew; delete pcNew;
} }
@ -491,24 +442,19 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
aiMaterial *pcMatOut, aiMaterial *pcMatOut,
unsigned int iType, unsigned int iType,
unsigned int iWidth, unsigned int iWidth,
unsigned int iHeight) unsigned int iHeight) {
{
std::unique_ptr<aiTexture> pcNew; std::unique_ptr<aiTexture> pcNew;
// get the type of the skin // get the type of the skin
unsigned int iMasked = (unsigned int)(iType & 0xF); unsigned int iMasked = (unsigned int)(iType & 0xF);
if (0x1 == iMasked) if (0x1 == iMasked) {
{
// ***** REFERENCE TO ANOTHER SKIN INDEX ***** // ***** REFERENCE TO ANOTHER SKIN INDEX *****
int referrer = (int)iWidth; int referrer = (int)iWidth;
pcMatOut->AddProperty<int>(&referrer, 1, AI_MDL7_REFERRER_MATERIAL); pcMatOut->AddProperty<int>(&referrer, 1, AI_MDL7_REFERRER_MATERIAL);
} } else if (0x6 == iMasked) {
else if (0x6 == iMasked)
{
// ***** EMBEDDED DDS FILE ***** // ***** EMBEDDED DDS FILE *****
if (1 != iHeight) if (1 != iHeight) {
{
ASSIMP_LOG_WARN("Found a reference to an embedded DDS texture, " ASSIMP_LOG_WARN("Found a reference to an embedded DDS texture, "
"but texture height is not equal to 1, which is not supported by MED"); "but texture height is not equal to 1, which is not supported by MED");
} }
@ -526,12 +472,9 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
pcNew->pcData = (aiTexel *)new unsigned char[pcNew->mWidth]; pcNew->pcData = (aiTexel *)new unsigned char[pcNew->mWidth];
memcpy(pcNew->pcData, szCurrent, pcNew->mWidth); memcpy(pcNew->pcData, szCurrent, pcNew->mWidth);
szCurrent += iWidth; szCurrent += iWidth;
} } else if (0x7 == iMasked) {
else if (0x7 == iMasked)
{
// ***** REFERENCE TO EXTERNAL FILE ***** // ***** REFERENCE TO EXTERNAL FILE *****
if (1 != iHeight) if (1 != iHeight) {
{
ASSIMP_LOG_WARN("Found a reference to an external texture, " ASSIMP_LOG_WARN("Found a reference to an external texture, "
"but texture height is not equal to 1, which is not supported by MED"); "but texture height is not equal to 1, which is not supported by MED");
} }
@ -547,22 +490,17 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
// place this as diffuse texture // place this as diffuse texture
pcMatOut->AddProperty(&szFile, AI_MATKEY_TEXTURE_DIFFUSE(0)); pcMatOut->AddProperty(&szFile, AI_MATKEY_TEXTURE_DIFFUSE(0));
} } else if (iMasked || !iType || (iType && iWidth && iHeight)) {
else if (iMasked || !iType || (iType && iWidth && iHeight))
{
pcNew.reset(new aiTexture()); pcNew.reset(new aiTexture());
if (!iHeight || !iWidth) if (!iHeight || !iWidth) {
{
ASSIMP_LOG_WARN("Found embedded texture, but its width " ASSIMP_LOG_WARN("Found embedded texture, but its width "
"an height are both 0. Is this a joke?"); "an height are both 0. Is this a joke?");
// generate an empty chess pattern // generate an empty chess pattern
pcNew->mWidth = pcNew->mHeight = 8; pcNew->mWidth = pcNew->mHeight = 8;
pcNew->pcData = new aiTexel[64]; pcNew->pcData = new aiTexel[64];
for (unsigned int x = 0; x < 8;++x) for (unsigned int x = 0; x < 8; ++x) {
{ for (unsigned int y = 0; y < 8; ++y) {
for (unsigned int y = 0; y < 8;++y)
{
const bool bSet = ((0 == x % 2 && 0 != y % 2) || const bool bSet = ((0 == x % 2 && 0 != y % 2) ||
(0 != x % 2 && 0 == y % 2)); (0 != x % 2 && 0 == y % 2));
@ -571,9 +509,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
pc->a = 0xFF; pc->a = 0xFF;
} }
} }
} } else {
else
{
// it is a standard color texture. Fill in width and height // it is a standard color texture. Fill in width and height
// and call the same function we used for loading MDL5 files // and call the same function we used for loading MDL5 files
@ -592,12 +528,13 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
// texture instead of material colors ... posssible they have // texture instead of material colors ... posssible they have
// been converted to MDL7 from other formats, such as MDL5 // been converted to MDL7 from other formats, such as MDL5
aiColor4D clrTexture; aiColor4D clrTexture;
if (pcNew)clrTexture = ReplaceTextureWithColor(pcNew.get()); if (pcNew)
else clrTexture.r = get_qnan(); clrTexture = ReplaceTextureWithColor(pcNew.get());
else
clrTexture.r = get_qnan();
// check whether a material definition is contained in the skin // check whether a material definition is contained in the skin
if (iType & AI_MDL7_SKINTYPE_MATERIAL) if (iType & AI_MDL7_SKINTYPE_MATERIAL) {
{
BE_NCONST MDL::Material_MDL7 *pcMatIn = (BE_NCONST MDL::Material_MDL7 *)szCurrent; BE_NCONST MDL::Material_MDL7 *pcMatIn = (BE_NCONST MDL::Material_MDL7 *)szCurrent;
szCurrent = (unsigned char *)(pcMatIn + 1); szCurrent = (unsigned char *)(pcMatIn + 1);
VALIDATE_FILE_SIZE(szCurrent); VALIDATE_FILE_SIZE(szCurrent);
@ -605,8 +542,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
aiColor3D clrTemp; aiColor3D clrTemp;
#define COLOR_MULTIPLY_RGB() \ #define COLOR_MULTIPLY_RGB() \
if (is_not_qnan(clrTexture.r)) \ if (is_not_qnan(clrTexture.r)) { \
{ \
clrTemp.r *= clrTexture.r; \ clrTemp.r *= clrTexture.r; \
clrTemp.g *= clrTexture.g; \ clrTemp.g *= clrTexture.g; \
clrTemp.b *= clrTexture.b; \ clrTemp.b *= clrTexture.b; \
@ -666,31 +602,26 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
// read phong power // read phong power
int iShadingMode = (int)aiShadingMode_Gouraud; int iShadingMode = (int)aiShadingMode_Gouraud;
AI_SWAP4(pcMatIn->Power); AI_SWAP4(pcMatIn->Power);
if (0.0f != pcMatIn->Power) if (0.0f != pcMatIn->Power) {
{
iShadingMode = (int)aiShadingMode_Phong; iShadingMode = (int)aiShadingMode_Phong;
// pcMatIn is packed, we can't form pointers to its members // pcMatIn is packed, we can't form pointers to its members
float power = pcMatIn->Power; float power = pcMatIn->Power;
pcMatOut->AddProperty<float>(&power, 1, AI_MATKEY_SHININESS); pcMatOut->AddProperty<float>(&power, 1, AI_MATKEY_SHININESS);
} }
pcMatOut->AddProperty<int>(&iShadingMode, 1, AI_MATKEY_SHADING_MODEL); pcMatOut->AddProperty<int>(&iShadingMode, 1, AI_MATKEY_SHADING_MODEL);
} } else if (is_not_qnan(clrTexture.r)) {
else if (is_not_qnan(clrTexture.r))
{
pcMatOut->AddProperty<aiColor4D>(&clrTexture, 1, AI_MATKEY_COLOR_DIFFUSE); pcMatOut->AddProperty<aiColor4D>(&clrTexture, 1, AI_MATKEY_COLOR_DIFFUSE);
pcMatOut->AddProperty<aiColor4D>(&clrTexture, 1, AI_MATKEY_COLOR_SPECULAR); pcMatOut->AddProperty<aiColor4D>(&clrTexture, 1, AI_MATKEY_COLOR_SPECULAR);
} }
// if the texture could be replaced by a single material color // if the texture could be replaced by a single material color
// we don't need the texture anymore // we don't need the texture anymore
if (is_not_qnan(clrTexture.r)) if (is_not_qnan(clrTexture.r)) {
{
pcNew.reset(); pcNew.reset();
} }
// If an ASCII effect description (HLSL?) is contained in the file, // If an ASCII effect description (HLSL?) is contained in the file,
// we can simply ignore it ... // we can simply ignore it ...
if (iType & AI_MDL7_SKINTYPE_MATERIAL_ASCDEF) if (iType & AI_MDL7_SKINTYPE_MATERIAL_ASCDEF) {
{
VALIDATE_FILE_SIZE(szCurrent); VALIDATE_FILE_SIZE(szCurrent);
int32_t iMe = *((int32_t *)szCurrent); int32_t iMe = *((int32_t *)szCurrent);
AI_SWAP4(iMe); AI_SWAP4(iMe);
@ -700,29 +631,24 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
// If an embedded texture has been loaded setup the corresponding // If an embedded texture has been loaded setup the corresponding
// data structures in the aiScene instance // data structures in the aiScene instance
if (pcNew && pScene->mNumTextures <= 999) if (pcNew && pScene->mNumTextures <= 999) {
{
// place this as diffuse texture // place this as diffuse texture
char szCurrent[5]; char current[5];
ai_snprintf(szCurrent,5,"*%i",this->pScene->mNumTextures); ai_snprintf(current, 5, "*%i", this->pScene->mNumTextures);
aiString szFile; aiString szFile;
const size_t iLen = strlen((const char*)szCurrent); const size_t iLen = strlen((const char *)current);
::memcpy(szFile.data,(const char*)szCurrent,iLen+1); ::memcpy(szFile.data, (const char *)current, iLen + 1);
szFile.length = (ai_uint32)iLen; szFile.length = (ai_uint32)iLen;
pcMatOut->AddProperty(&szFile, AI_MATKEY_TEXTURE_DIFFUSE(0)); pcMatOut->AddProperty(&szFile, AI_MATKEY_TEXTURE_DIFFUSE(0));
// store the texture // store the texture
if (!pScene->mNumTextures) if (!pScene->mNumTextures) {
{
pScene->mNumTextures = 1; pScene->mNumTextures = 1;
pScene->mTextures = new aiTexture *[1]; pScene->mTextures = new aiTexture *[1];
pScene->mTextures[0] = pcNew.release(); pScene->mTextures[0] = pcNew.release();
} } else {
else
{
aiTexture **pc = pScene->mTextures; aiTexture **pc = pScene->mTextures;
pScene->mTextures = new aiTexture *[pScene->mNumTextures + 1]; pScene->mTextures = new aiTexture *[pScene->mNumTextures + 1];
for (unsigned int i = 0; i < pScene->mNumTextures; ++i) { for (unsigned int i = 0; i < pScene->mNumTextures; ++i) {
@ -745,24 +671,18 @@ void MDLImporter::SkipSkinLump_3DGS_MDL7(
const unsigned char **szCurrentOut, const unsigned char **szCurrentOut,
unsigned int iType, unsigned int iType,
unsigned int iWidth, unsigned int iWidth,
unsigned int iHeight) unsigned int iHeight) {
{
// get the type of the skin // get the type of the skin
const unsigned int iMasked = (unsigned int)(iType & 0xF); const unsigned int iMasked = (unsigned int)(iType & 0xF);
if (0x6 == iMasked) if (0x6 == iMasked) {
{
szCurrent += iWidth; szCurrent += iWidth;
} }
if (0x7 == iMasked) if (0x7 == iMasked) {
{ const size_t iLen = std::strlen((const char *)szCurrent);
const size_t iLen = ::strlen((const char*)szCurrent);
szCurrent += iLen + 1; szCurrent += iLen + 1;
} } else if (iMasked || !iType) {
else if (iMasked || !iType) if (iMasked || !iType || (iType && iWidth && iHeight)) {
{
if (iMasked || !iType || (iType && iWidth && iHeight))
{
// ParseTextureColorData(..., aiTexture::pcData == bad_texel) will simply // ParseTextureColorData(..., aiTexture::pcData == bad_texel) will simply
// return the size of the color data in bytes in iSkip // return the size of the color data in bytes in iSkip
unsigned int iSkip = 0; unsigned int iSkip = 0;
@ -774,7 +694,7 @@ void MDLImporter::SkipSkinLump_3DGS_MDL7(
ParseTextureColorData(szCurrent, iMasked, &iSkip, &tex); ParseTextureColorData(szCurrent, iMasked, &iSkip, &tex);
// FIX: Important, otherwise the destructor will crash // FIX: Important, otherwise the destructor will crash
tex.pcData = NULL; tex.pcData = nullptr;
// skip length of texture data // skip length of texture data
szCurrent += iSkip; szCurrent += iSkip;
@ -782,16 +702,14 @@ void MDLImporter::SkipSkinLump_3DGS_MDL7(
} }
// check whether a material definition is contained in the skin // check whether a material definition is contained in the skin
if (iType & AI_MDL7_SKINTYPE_MATERIAL) if (iType & AI_MDL7_SKINTYPE_MATERIAL) {
{
BE_NCONST MDL::Material_MDL7 *pcMatIn = (BE_NCONST MDL::Material_MDL7 *)szCurrent; BE_NCONST MDL::Material_MDL7 *pcMatIn = (BE_NCONST MDL::Material_MDL7 *)szCurrent;
szCurrent = (unsigned char *)(pcMatIn + 1); szCurrent = (unsigned char *)(pcMatIn + 1);
} }
// if an ASCII effect description (HLSL?) is contained in the file, // if an ASCII effect description (HLSL?) is contained in the file,
// we can simply ignore it ... // we can simply ignore it ...
if (iType & AI_MDL7_SKINTYPE_MATERIAL_ASCDEF) if (iType & AI_MDL7_SKINTYPE_MATERIAL_ASCDEF) {
{
int32_t iMe = *((int32_t *)szCurrent); int32_t iMe = *((int32_t *)szCurrent);
AI_SWAP4(iMe); AI_SWAP4(iMe);
szCurrent += sizeof(char) * iMe + sizeof(int32_t); szCurrent += sizeof(char) * iMe + sizeof(int32_t);
@ -803,10 +721,9 @@ void MDLImporter::SkipSkinLump_3DGS_MDL7(
void MDLImporter::ParseSkinLump_3DGS_MDL7( void MDLImporter::ParseSkinLump_3DGS_MDL7(
const unsigned char *szCurrent, const unsigned char *szCurrent,
const unsigned char **szCurrentOut, const unsigned char **szCurrentOut,
std::vector<aiMaterial*>& pcMats) std::vector<aiMaterial *> &pcMats) {
{ ai_assert(nullptr != szCurrent);
ai_assert(NULL != szCurrent); ai_assert(nullptr != szCurrentOut);
ai_assert(NULL != szCurrentOut);
*szCurrentOut = szCurrent; *szCurrentOut = szCurrent;
BE_NCONST MDL::Skin_MDL7 *pcSkin = (BE_NCONST MDL::Skin_MDL7 *)szCurrent; BE_NCONST MDL::Skin_MDL7 *pcSkin = (BE_NCONST MDL::Skin_MDL7 *)szCurrent;
@ -825,8 +742,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
pcSkin->typ, pcSkin->width, pcSkin->height); pcSkin->typ, pcSkin->width, pcSkin->height);
// place the name of the skin in the material // place the name of the skin in the material
if (pcSkin->texture_name[0]) if (pcSkin->texture_name[0]) {
{
// the 0 termination could be there or not - we can't know // the 0 termination could be there or not - we can't know
aiString szFile; aiString szFile;
::memcpy(szFile.data, pcSkin->texture_name, sizeof(pcSkin->texture_name)); ::memcpy(szFile.data, pcSkin->texture_name, sizeof(pcSkin->texture_name));

View File

@ -199,9 +199,9 @@ namespace vmd
stream->write((char*)&ik_count, sizeof(int)); stream->write((char*)&ik_count, sizeof(int));
for (int i = 0; i < ik_count; i++) for (int i = 0; i < ik_count; i++)
{ {
const VmdIkEnable& ik_enable = this->ik_enable.at(i); const VmdIkEnable& ik_enable_ref = this->ik_enable.at(i);
stream->write(ik_enable.ik_name.c_str(), 20); stream->write(ik_enable_ref.ik_name.c_str(), 20);
stream->write((char*)&ik_enable.enable, sizeof(uint8_t)); stream->write((char *)&ik_enable_ref.enable, sizeof(uint8_t));
} }
} }
}; };

View File

@ -261,19 +261,19 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
TempTriangle& t = triangles[i]; TempTriangle& t = triangles[i];
stream.IncPtr(2); stream.IncPtr(2);
for (unsigned int i = 0; i < 3; ++i) { for (unsigned int j = 0; j < 3; ++j) {
t.indices[i] = stream.GetI2(); t.indices[j] = stream.GetI2();
} }
for (unsigned int i = 0; i < 3; ++i) { for (unsigned int j = 0; j < 3; ++j) {
ReadVector(stream,t.normals[i]); ReadVector(stream,t.normals[j]);
} }
for (unsigned int i = 0; i < 3; ++i) { for (unsigned int j = 0; j < 3; ++j) {
stream >> (float&)(t.uv[i].x); // see note in ReadColor() stream >> (float&)(t.uv[j].x); // see note in ReadColor()
} }
for (unsigned int i = 0; i < 3; ++i) { for (unsigned int j = 0; j < 3; ++j) {
stream >> (float&)(t.uv[i].y); stream >> (float&)(t.uv[j].y);
} }
t.sg = stream.GetI1(); t.sg = stream.GetI1();
@ -296,8 +296,8 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
stream >> num; stream >> num;
t.triangles.resize(num); t.triangles.resize(num);
for (unsigned int i = 0; i < num; ++i) { for (unsigned int j = 0; j < num; ++j) {
t.triangles[i] = stream.GetI2(); t.triangles[j] = stream.GetI2();
} }
t.mat = stream.GetI1(); t.mat = stream.GetI1();
if (t.mat == UINT_MAX) { if (t.mat == UINT_MAX) {
@ -309,8 +309,8 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
stream >> mat; stream >> mat;
std::vector<TempMaterial> materials(mat); std::vector<TempMaterial> materials(mat);
for (unsigned int i = 0;i < mat; ++i) { for (unsigned int j = 0;j < mat; ++j) {
TempMaterial& t = materials[i]; TempMaterial& t = materials[j];
stream.CopyAndAdvance(t.name,32); stream.CopyAndAdvance(t.name,32);
t.name[32] = '\0'; t.name[32] = '\0';
@ -338,8 +338,8 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
stream >> joint; stream >> joint;
std::vector<TempJoint> joints(joint); std::vector<TempJoint> joints(joint);
for(unsigned int i = 0; i < joint; ++i) { for(unsigned int ii = 0; ii < joint; ++ii) {
TempJoint& j = joints[i]; TempJoint& j = joints[ii];
stream.IncPtr(1); stream.IncPtr(1);
stream.CopyAndAdvance(j.name,32); stream.CopyAndAdvance(j.name,32);
@ -494,17 +494,17 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
typedef std::map<unsigned int,unsigned int> BoneSet; typedef std::map<unsigned int,unsigned int> BoneSet;
BoneSet mybones; BoneSet mybones;
for (unsigned int i = 0,n = 0; i < m->mNumFaces; ++i) { for (unsigned int j = 0,n = 0; j < m->mNumFaces; ++j) {
aiFace& f = m->mFaces[i]; aiFace& f = m->mFaces[j];
if (g.triangles[i]>triangles.size()) { if (g.triangles[j]>triangles.size()) {
throw DeadlyImportError("MS3D: Encountered invalid triangle index, file is malformed"); throw DeadlyImportError("MS3D: Encountered invalid triangle index, file is malformed");
} }
TempTriangle& t = triangles[g.triangles[i]]; TempTriangle& t = triangles[g.triangles[i]];
f.mIndices = new unsigned int[f.mNumIndices=3]; f.mIndices = new unsigned int[f.mNumIndices=3];
for (unsigned int i = 0; i < 3; ++i,++n) { for (unsigned int k = 0; k < 3; ++k,++n) {
if (t.indices[i]>vertices.size()) { if (t.indices[k]>vertices.size()) {
throw DeadlyImportError("MS3D: Encountered invalid vertex index, file is malformed"); throw DeadlyImportError("MS3D: Encountered invalid vertex index, file is malformed");
} }
@ -545,11 +545,11 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
} }
// .. and collect bone weights // .. and collect bone weights
for (unsigned int i = 0,n = 0; i < m->mNumFaces; ++i) { for (unsigned int j = 0,n = 0; j < m->mNumFaces; ++j) {
TempTriangle& t = triangles[g.triangles[i]]; TempTriangle& t = triangles[g.triangles[j]];
for (unsigned int i = 0; i < 3; ++i,++n) { for (unsigned int k = 0; k < 3; ++k,++n) {
const TempVertex& v = vertices[t.indices[i]]; const TempVertex& v = vertices[t.indices[k]];
for(unsigned int a = 0; a < 4; ++a) { for(unsigned int a = 0; a < 4; ++a) {
const unsigned int bone = v.bone_id[a]; const unsigned int bone = v.bone_id[a];
if(bone==UINT_MAX){ if(bone==UINT_MAX){

View File

@ -332,8 +332,7 @@ unsigned int aiGetMaterialTextureCount(const C_STRUCT aiMaterial* pMat,
aiMaterialProperty* prop = pMat->mProperties[i]; aiMaterialProperty* prop = pMat->mProperties[i];
if ( prop /* just a sanity check ... */ if ( prop /* just a sanity check ... */
&& 0 == strcmp( prop->mKey.data, _AI_MATKEY_TEXTURE_BASE ) && 0 == strcmp(prop->mKey.data, _AI_MATKEY_TEXTURE_BASE) && static_cast < aiTextureType>(prop->mSemantic) == type) {
&& prop->mSemantic == type) {
max = std::max(max,prop->mIndex+1); max = std::max(max,prop->mIndex+1);
} }
@ -562,7 +561,8 @@ uint32_t Assimp::ComputeMaterialHash(const aiMaterial* mat, bool includeMatName
// Exclude all properties whose first character is '?' from the hash // Exclude all properties whose first character is '?' from the hash
// See doc for aiMaterialProperty. // See doc for aiMaterialProperty.
if ((prop = mat->mProperties[i]) && (includeMatName || prop->mKey.data[0] != '?')) { prop = mat->mProperties[ i ];
if ( nullptr != prop && (includeMatName || prop->mKey.data[0] != '?')) {
hash = SuperFastHash(prop->mKey.data,(unsigned int)prop->mKey.length,hash); hash = SuperFastHash(prop->mKey.data,(unsigned int)prop->mKey.length,hash);
hash = SuperFastHash(prop->mData,prop->mDataLength,hash); hash = SuperFastHash(prop->mData,prop->mDataLength,hash);

File diff suppressed because it is too large Load Diff

View File

@ -185,8 +185,8 @@ private:
// for spheres, cones and cylinders: center point of the object // for spheres, cones and cylinders: center point of the object
aiVector3D center, radius, dir; aiVector3D center, radius, dir;
static const size_t MaxNameLen = 128;
char name[128]; char name[MaxNameLen];
std::vector<aiVector3D> vertices, normals, uvs; std::vector<aiVector3D> vertices, normals, uvs;
std::vector<unsigned int> faces; std::vector<unsigned int> faces;

View File

@ -86,7 +86,7 @@ void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Worker function for exporting a scene to Wavefront OBJ without the material file. Prototyped and registered in Exporter.cpp // Worker function for exporting a scene to Wavefront OBJ without the material file. Prototyped and registered in Exporter.cpp
void ExportSceneObjNoMtl(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties) { void ExportSceneObjNoMtl(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* ) {
// invoke the exporter // invoke the exporter
ObjExporter exporter(pFile, pScene, true); ObjExporter exporter(pFile, pScene, true);

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -44,10 +43,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef OBJ_FILEDATA_H_INC #ifndef OBJ_FILEDATA_H_INC
# define OBJ_FILEDATA_H_INC # define OBJ_FILEDATA_H_INC
#include <vector>
#include <map>
#include <assimp/types.h>
# include <assimp/mesh.h> # include <assimp/mesh.h>
# include <assimp/types.h>
# include <map>
# include <vector>
namespace Assimp { namespace Assimp {
namespace ObjFile { namespace ObjFile {
@ -75,12 +74,8 @@ struct Face {
Material *m_pMaterial; Material *m_pMaterial;
//! \brief Default constructor //! \brief Default constructor
Face( aiPrimitiveType pt = aiPrimitiveType_POLYGON) Face(aiPrimitiveType pt = aiPrimitiveType_POLYGON) :
: m_PrimitiveType( pt ) m_PrimitiveType(pt), m_vertices(), m_normals(), m_texturCoords(), m_pMaterial(0L) {
, m_vertices()
, m_normals()
, m_texturCoords()
, m_pMaterial( 0L ) {
// empty // empty
} }
@ -181,14 +176,13 @@ struct Material {
aiColor3D transparent; aiColor3D transparent;
//! Constructor //! Constructor
Material() Material() :
: diffuse ( ai_real( 0.6 ), ai_real( 0.6 ), ai_real( 0.6 ) ) diffuse(ai_real(0.6), ai_real(0.6), ai_real(0.6)),
, alpha (ai_real( 1.0 ) ) alpha(ai_real(1.0)),
, shineness ( ai_real( 0.0) ) shineness(ai_real(0.0)),
, illumination_model (1) illumination_model(1),
, ior ( ai_real( 1.0 ) ) ior(ai_real(1.0)),
, transparent( ai_real( 1.0), ai_real (1.0), ai_real(1.0)) { transparent(ai_real(1.0), ai_real(1.0), ai_real(1.0)) {
std::fill_n(clamp, static_cast<unsigned int>(TextureTypeCount), false); std::fill_n(clamp, static_cast<unsigned int>(TextureTypeCount), false);
} }
@ -220,20 +214,15 @@ struct Mesh {
bool m_hasVertexColors; bool m_hasVertexColors;
/// Constructor /// Constructor
explicit Mesh( const std::string &name ) explicit Mesh(const std::string &name) :
: m_name( name ) m_name(name), m_pMaterial(NULL), m_uiNumIndices(0), m_uiMaterialIndex(NoMaterial), m_hasNormals(false) {
, m_pMaterial(NULL)
, m_uiNumIndices(0)
, m_uiMaterialIndex( NoMaterial )
, m_hasNormals(false) {
memset(m_uiUVCoordinates, 0, sizeof(unsigned int) * AI_MAX_NUMBER_OF_TEXTURECOORDS); memset(m_uiUVCoordinates, 0, sizeof(unsigned int) * AI_MAX_NUMBER_OF_TEXTURECOORDS);
} }
/// Destructor /// Destructor
~Mesh() { ~Mesh() {
for (std::vector<Face *>::iterator it = m_Faces.begin(); for (std::vector<Face *>::iterator it = m_Faces.begin();
it != m_Faces.end(); ++it) it != m_Faces.end(); ++it) {
{
delete *it; delete *it;
} }
} }
@ -292,8 +281,7 @@ struct Model {
m_pGroupFaceIDs(NULL), m_pGroupFaceIDs(NULL),
m_strActiveGroup(""), m_strActiveGroup(""),
m_TextureCoordDim(0), m_TextureCoordDim(0),
m_pCurrentMesh(NULL) m_pCurrentMesh(NULL) {
{
// empty // empty
} }

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -44,16 +42,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER #ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER
#include "ObjFileImporter.h" #include "ObjFileImporter.h"
#include "ObjFileParser.h"
#include "ObjFileData.h" #include "ObjFileData.h"
#include <assimp/IOStreamBuffer.h> #include "ObjFileParser.h"
#include <memory>
#include <assimp/DefaultIOSystem.h> #include <assimp/DefaultIOSystem.h>
#include <assimp/Importer.hpp> #include <assimp/IOStreamBuffer.h>
#include <assimp/scene.h>
#include <assimp/ai_assert.h> #include <assimp/ai_assert.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/Importer.hpp>
#include <memory>
static const aiImporterDesc desc = { static const aiImporterDesc desc = {
"Wavefront Object Importer", "Wavefront Object Importer",
@ -76,10 +74,8 @@ using namespace std;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Default constructor // Default constructor
ObjFileImporter::ObjFileImporter() ObjFileImporter::ObjFileImporter() :
: m_Buffer() m_Buffer(), m_pRootObject(nullptr), m_strAbsPath(std::string(1, DefaultIOSystem().getOsSeparator())) {}
, m_pRootObject( nullptr )
, m_strAbsPath( std::string(1, DefaultIOSystem().getOsSeparator()) ) {}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor. // Destructor.
@ -255,8 +251,7 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene
// Creates all nodes of the model // Creates all nodes of the model
aiNode *ObjFileImporter::createNodes(const ObjFile::Model *pModel, const ObjFile::Object *pObject, aiNode *ObjFileImporter::createNodes(const ObjFile::Model *pModel, const ObjFile::Object *pObject,
aiNode *pParent, aiScene *pScene, aiNode *pParent, aiScene *pScene,
std::vector<aiMesh*> &MeshArray ) std::vector<aiMesh *> &MeshArray) {
{
ai_assert(NULL != pModel); ai_assert(NULL != pModel);
if (NULL == pObject) { if (NULL == pObject) {
return NULL; return NULL;
@ -334,8 +329,7 @@ aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const Obj
pMesh->mName.Set(pObjMesh->m_name); pMesh->mName.Set(pObjMesh->m_name);
} }
for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) {
{
ObjFile::Face *const inp = pObjMesh->m_Faces[index]; ObjFile::Face *const inp = pObjMesh->m_Faces[index];
ai_assert(NULL != inp); ai_assert(NULL != inp);
@ -374,8 +368,7 @@ aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const Obj
f.mIndices = new unsigned int[2]; f.mIndices = new unsigned int[2];
} }
continue; continue;
} } else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) {
else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) {
for (size_t i = 0; i < inp->m_vertices.size(); ++i) { for (size_t i = 0; i < inp->m_vertices.size(); ++i) {
aiFace &f = pMesh->mFaces[outIndex++]; aiFace &f = pMesh->mFaces[outIndex++];
uiIdxCount += f.mNumIndices = 1; uiIdxCount += f.mNumIndices = 1;
@ -437,8 +430,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
pMesh->mColors[0] = new aiColor4D[pMesh->mNumVertices]; pMesh->mColors[0] = new aiColor4D[pMesh->mNumVertices];
// Allocate buffer for texture coordinates // Allocate buffer for texture coordinates
if ( !pModel->m_TextureCoord.empty() && pObjMesh->m_uiUVCoordinates[0] ) if (!pModel->m_TextureCoord.empty() && pObjMesh->m_uiUVCoordinates[0]) {
{
pMesh->mNumUVComponents[0] = pModel->m_TextureCoordDim; pMesh->mNumUVComponents[0] = pModel->m_TextureCoordDim;
pMesh->mTextureCoords[0] = new aiVector3D[pMesh->mNumVertices]; pMesh->mTextureCoords[0] = new aiVector3D[pMesh->mNumVertices];
} }
@ -463,34 +455,26 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
// Copy all normals // Copy all normals
if (normalsok && !pModel->m_Normals.empty() && vertexIndex < sourceFace->m_normals.size()) { if (normalsok && !pModel->m_Normals.empty() && vertexIndex < sourceFace->m_normals.size()) {
const unsigned int normal = sourceFace->m_normals.at(vertexIndex); const unsigned int normal = sourceFace->m_normals.at(vertexIndex);
if ( normal >= pModel->m_Normals.size() ) if (normal >= pModel->m_Normals.size()) {
{
normalsok = false; normalsok = false;
} } else {
else
{
pMesh->mNormals[newIndex] = pModel->m_Normals[normal]; pMesh->mNormals[newIndex] = pModel->m_Normals[normal];
} }
} }
// Copy all vertex colors // Copy all vertex colors
if ( !pModel->m_VertexColors.empty()) if (!pModel->m_VertexColors.empty()) {
{
const aiVector3D &color = pModel->m_VertexColors[vertex]; const aiVector3D &color = pModel->m_VertexColors[vertex];
pMesh->mColors[0][newIndex] = aiColor4D(color.x, color.y, color.z, 1.0); pMesh->mColors[0][newIndex] = aiColor4D(color.x, color.y, color.z, 1.0);
} }
// Copy all texture coordinates // Copy all texture coordinates
if ( uvok && !pModel->m_TextureCoord.empty() && vertexIndex < sourceFace->m_texturCoords.size()) if (uvok && !pModel->m_TextureCoord.empty() && vertexIndex < sourceFace->m_texturCoords.size()) {
{
const unsigned int tex = sourceFace->m_texturCoords.at(vertexIndex); const unsigned int tex = sourceFace->m_texturCoords.at(vertexIndex);
if ( tex >= pModel->m_TextureCoord.size() ) if (tex >= pModel->m_TextureCoord.size()) {
{
uvok = false; uvok = false;
} } else {
else
{
const aiVector3D &coord3d = pModel->m_TextureCoord[tex]; const aiVector3D &coord3d = pModel->m_TextureCoord[tex];
pMesh->mTextureCoords[0][newIndex] = aiVector3D(coord3d.x, coord3d.y, coord3d.z); pMesh->mTextureCoords[0][newIndex] = aiVector3D(coord3d.x, coord3d.y, coord3d.z);
} }
@ -530,22 +514,19 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
pDestFace[-1].mIndices[1] = newIndex; pDestFace[-1].mIndices[1] = newIndex;
} }
} } else if (last) {
else if (last) {
outIndex++; outIndex++;
} }
++newIndex; ++newIndex;
} }
} }
if (!normalsok) if (!normalsok) {
{
delete[] pMesh->mNormals; delete[] pMesh->mNormals;
pMesh->mNormals = nullptr; pMesh->mNormals = nullptr;
} }
if (!uvok) if (!uvok) {
{
delete[] pMesh->mTextureCoords[0]; delete[] pMesh->mTextureCoords[0];
pMesh->mTextureCoords[0] = nullptr; pMesh->mTextureCoords[0] = nullptr;
} }
@ -553,17 +534,14 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Counts all stored meshes // Counts all stored meshes
void ObjFileImporter::countObjects(const std::vector<ObjFile::Object*> &rObjects, int &iNumMeshes) void ObjFileImporter::countObjects(const std::vector<ObjFile::Object *> &rObjects, int &iNumMeshes) {
{
iNumMeshes = 0; iNumMeshes = 0;
if (rObjects.empty()) if (rObjects.empty())
return; return;
iNumMeshes += static_cast<unsigned int>(rObjects.size()); iNumMeshes += static_cast<unsigned int>(rObjects.size());
for (auto object: rObjects) for (auto object : rObjects) {
{ if (!object->m_SubObjects.empty()) {
if (!object->m_SubObjects.empty())
{
countObjects(object->m_SubObjects, iNumMeshes); countObjects(object->m_SubObjects, iNumMeshes);
} }
} }
@ -595,8 +573,7 @@ void ObjFileImporter::createMaterials(const ObjFile::Model* pModel, aiScene* pSc
} }
pScene->mMaterials = new aiMaterial *[numMaterials]; pScene->mMaterials = new aiMaterial *[numMaterials];
for ( unsigned int matIndex = 0; matIndex < numMaterials; matIndex++ ) for (unsigned int matIndex = 0; matIndex < numMaterials; matIndex++) {
{
// Store material name // Store material name
std::map<std::string, ObjFile::Material *>::const_iterator it; std::map<std::string, ObjFile::Material *>::const_iterator it;
it = pModel->m_MaterialMap.find(pModel->m_MaterialLib[matIndex]); it = pModel->m_MaterialMap.find(pModel->m_MaterialLib[matIndex]);
@ -611,8 +588,7 @@ void ObjFileImporter::createMaterials(const ObjFile::Model* pModel, aiScene* pSc
// convert illumination model // convert illumination model
int sm = 0; int sm = 0;
switch (pCurrentMaterial->illumination_model) switch (pCurrentMaterial->illumination_model) {
{
case 0: case 0:
sm = aiShadingMode_NoShading; sm = aiShadingMode_NoShading;
break; break;
@ -644,71 +620,58 @@ void ObjFileImporter::createMaterials(const ObjFile::Model* pModel, aiScene* pSc
// Adding textures // Adding textures
const int uvwIndex = 0; const int uvwIndex = 0;
if ( 0 != pCurrentMaterial->texture.length ) if (0 != pCurrentMaterial->texture.length) {
{
mat->AddProperty(&pCurrentMaterial->texture, AI_MATKEY_TEXTURE_DIFFUSE(0)); mat->AddProperty(&pCurrentMaterial->texture, AI_MATKEY_TEXTURE_DIFFUSE(0));
mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_DIFFUSE(0)); mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_DIFFUSE(0));
if (pCurrentMaterial->clamp[ObjFile::Material::TextureDiffuseType]) if (pCurrentMaterial->clamp[ObjFile::Material::TextureDiffuseType]) {
{
addTextureMappingModeProperty(mat, aiTextureType_DIFFUSE); addTextureMappingModeProperty(mat, aiTextureType_DIFFUSE);
} }
} }
if ( 0 != pCurrentMaterial->textureAmbient.length ) if (0 != pCurrentMaterial->textureAmbient.length) {
{
mat->AddProperty(&pCurrentMaterial->textureAmbient, AI_MATKEY_TEXTURE_AMBIENT(0)); mat->AddProperty(&pCurrentMaterial->textureAmbient, AI_MATKEY_TEXTURE_AMBIENT(0));
mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_AMBIENT(0)); mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_AMBIENT(0));
if (pCurrentMaterial->clamp[ObjFile::Material::TextureAmbientType]) if (pCurrentMaterial->clamp[ObjFile::Material::TextureAmbientType]) {
{
addTextureMappingModeProperty(mat, aiTextureType_AMBIENT); addTextureMappingModeProperty(mat, aiTextureType_AMBIENT);
} }
} }
if ( 0 != pCurrentMaterial->textureEmissive.length ) if (0 != pCurrentMaterial->textureEmissive.length) {
{
mat->AddProperty(&pCurrentMaterial->textureEmissive, AI_MATKEY_TEXTURE_EMISSIVE(0)); mat->AddProperty(&pCurrentMaterial->textureEmissive, AI_MATKEY_TEXTURE_EMISSIVE(0));
mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_EMISSIVE(0)); mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_EMISSIVE(0));
} }
if ( 0 != pCurrentMaterial->textureSpecular.length ) if (0 != pCurrentMaterial->textureSpecular.length) {
{
mat->AddProperty(&pCurrentMaterial->textureSpecular, AI_MATKEY_TEXTURE_SPECULAR(0)); mat->AddProperty(&pCurrentMaterial->textureSpecular, AI_MATKEY_TEXTURE_SPECULAR(0));
mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_SPECULAR(0)); mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_SPECULAR(0));
if (pCurrentMaterial->clamp[ObjFile::Material::TextureSpecularType]) if (pCurrentMaterial->clamp[ObjFile::Material::TextureSpecularType]) {
{
addTextureMappingModeProperty(mat, aiTextureType_SPECULAR); addTextureMappingModeProperty(mat, aiTextureType_SPECULAR);
} }
} }
if ( 0 != pCurrentMaterial->textureBump.length ) if (0 != pCurrentMaterial->textureBump.length) {
{
mat->AddProperty(&pCurrentMaterial->textureBump, AI_MATKEY_TEXTURE_HEIGHT(0)); mat->AddProperty(&pCurrentMaterial->textureBump, AI_MATKEY_TEXTURE_HEIGHT(0));
mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_HEIGHT(0)); mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_HEIGHT(0));
if (pCurrentMaterial->clamp[ObjFile::Material::TextureBumpType]) if (pCurrentMaterial->clamp[ObjFile::Material::TextureBumpType]) {
{
addTextureMappingModeProperty(mat, aiTextureType_HEIGHT); addTextureMappingModeProperty(mat, aiTextureType_HEIGHT);
} }
} }
if ( 0 != pCurrentMaterial->textureNormal.length ) if (0 != pCurrentMaterial->textureNormal.length) {
{
mat->AddProperty(&pCurrentMaterial->textureNormal, AI_MATKEY_TEXTURE_NORMALS(0)); mat->AddProperty(&pCurrentMaterial->textureNormal, AI_MATKEY_TEXTURE_NORMALS(0));
mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_NORMALS(0)); mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_NORMALS(0));
if (pCurrentMaterial->clamp[ObjFile::Material::TextureNormalType]) if (pCurrentMaterial->clamp[ObjFile::Material::TextureNormalType]) {
{
addTextureMappingModeProperty(mat, aiTextureType_NORMALS); addTextureMappingModeProperty(mat, aiTextureType_NORMALS);
} }
} }
if( 0 != pCurrentMaterial->textureReflection[0].length ) if (0 != pCurrentMaterial->textureReflection[0].length) {
{
ObjFile::Material::TextureType type = 0 != pCurrentMaterial->textureReflection[1].length ? ObjFile::Material::TextureType type = 0 != pCurrentMaterial->textureReflection[1].length ?
ObjFile::Material::TextureReflectionCubeTopType : ObjFile::Material::TextureReflectionCubeTopType :
ObjFile::Material::TextureReflectionSphereType; ObjFile::Material::TextureReflectionSphereType;
unsigned count = type == ObjFile::Material::TextureReflectionSphereType ? 1 : 6; unsigned count = type == ObjFile::Material::TextureReflectionSphereType ? 1 : 6;
for( unsigned i = 0; i < count; i++ ) for (unsigned i = 0; i < count; i++) {
{
mat->AddProperty(&pCurrentMaterial->textureReflection[i], AI_MATKEY_TEXTURE_REFLECTION(i)); mat->AddProperty(&pCurrentMaterial->textureReflection[i], AI_MATKEY_TEXTURE_REFLECTION(i));
mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_REFLECTION(i)); mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_REFLECTION(i));
@ -717,32 +680,26 @@ void ObjFileImporter::createMaterials(const ObjFile::Model* pModel, aiScene* pSc
} }
} }
if ( 0 != pCurrentMaterial->textureDisp.length ) if (0 != pCurrentMaterial->textureDisp.length) {
{
mat->AddProperty(&pCurrentMaterial->textureDisp, AI_MATKEY_TEXTURE_DISPLACEMENT(0)); mat->AddProperty(&pCurrentMaterial->textureDisp, AI_MATKEY_TEXTURE_DISPLACEMENT(0));
mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_DISPLACEMENT(0)); mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_DISPLACEMENT(0));
if (pCurrentMaterial->clamp[ObjFile::Material::TextureDispType]) if (pCurrentMaterial->clamp[ObjFile::Material::TextureDispType]) {
{
addTextureMappingModeProperty(mat, aiTextureType_DISPLACEMENT); addTextureMappingModeProperty(mat, aiTextureType_DISPLACEMENT);
} }
} }
if ( 0 != pCurrentMaterial->textureOpacity.length ) if (0 != pCurrentMaterial->textureOpacity.length) {
{
mat->AddProperty(&pCurrentMaterial->textureOpacity, AI_MATKEY_TEXTURE_OPACITY(0)); mat->AddProperty(&pCurrentMaterial->textureOpacity, AI_MATKEY_TEXTURE_OPACITY(0));
mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_OPACITY(0)); mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_OPACITY(0));
if (pCurrentMaterial->clamp[ObjFile::Material::TextureOpacityType]) if (pCurrentMaterial->clamp[ObjFile::Material::TextureOpacityType]) {
{
addTextureMappingModeProperty(mat, aiTextureType_OPACITY); addTextureMappingModeProperty(mat, aiTextureType_OPACITY);
} }
} }
if ( 0 != pCurrentMaterial->textureSpecularity.length ) if (0 != pCurrentMaterial->textureSpecularity.length) {
{
mat->AddProperty(&pCurrentMaterial->textureSpecularity, AI_MATKEY_TEXTURE_SHININESS(0)); mat->AddProperty(&pCurrentMaterial->textureSpecularity, AI_MATKEY_TEXTURE_SHININESS(0));
mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_SHININESS(0)); mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_SHININESS(0));
if (pCurrentMaterial->clamp[ObjFile::Material::TextureSpecularityType]) if (pCurrentMaterial->clamp[ObjFile::Material::TextureSpecularityType]) {
{
addTextureMappingModeProperty(mat, aiTextureType_SHININESS); addTextureMappingModeProperty(mat, aiTextureType_SHININESS);
} }
} }
@ -758,8 +715,7 @@ void ObjFileImporter::createMaterials(const ObjFile::Model* pModel, aiScene* pSc
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Appends this node to the parent node // Appends this node to the parent node
void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild) void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild) {
{
// Checking preconditions // Checking preconditions
ai_assert(NULL != pParent); ai_assert(NULL != pParent);
ai_assert(NULL != pChild); ai_assert(NULL != pChild);

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -54,7 +53,7 @@ namespace Assimp {
namespace ObjFile { namespace ObjFile {
struct Object; struct Object;
struct Model; struct Model;
} } // namespace ObjFile
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
/// \class ObjFileImporter /// \class ObjFileImporter

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -41,16 +39,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER #ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER
#include <stdlib.h>
#include "ObjFileMtlImporter.h" #include "ObjFileMtlImporter.h"
#include "ObjTools.h"
#include "ObjFileData.h" #include "ObjFileData.h"
#include <assimp/fast_atof.h> #include "ObjTools.h"
#include <assimp/ParsingUtils.h> #include <assimp/ParsingUtils.h>
#include <assimp/fast_atof.h>
#include <assimp/material.h> #include <assimp/material.h>
#include <stdlib.h>
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
namespace Assimp { namespace Assimp {
@ -92,11 +89,12 @@ ObjFileMtlImporter::ObjFileMtlImporter( std::vector<char> &buffer,
m_DataIt(buffer.begin()), m_DataIt(buffer.begin()),
m_DataItEnd(buffer.end()), m_DataItEnd(buffer.end()),
m_pModel(pModel), m_pModel(pModel),
m_uiLine( 0 ) m_uiLine(0),
{ m_buffer() {
ai_assert( NULL != m_pModel ); ai_assert(nullptr != m_pModel);
if ( NULL == m_pModel->m_pDefaultMaterial ) m_buffer.resize(BUFFERSIZE);
{ std::fill(m_buffer.begin(), m_buffer.end(), '\0');
if (nullptr == m_pModel->m_pDefaultMaterial) {
m_pModel->m_pDefaultMaterial = new ObjFile::Material; m_pModel->m_pDefaultMaterial = new ObjFile::Material;
m_pModel->m_pDefaultMaterial->MaterialName.Set("default"); m_pModel->m_pDefaultMaterial->MaterialName.Set("default");
} }
@ -105,65 +103,39 @@ ObjFileMtlImporter::ObjFileMtlImporter( std::vector<char> &buffer,
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Destructor // Destructor
ObjFileMtlImporter::~ObjFileMtlImporter() ObjFileMtlImporter::~ObjFileMtlImporter() {
{
// empty // empty
} }
// -------------------------------------------------------------------
// Private copy constructor
ObjFileMtlImporter::ObjFileMtlImporter(const ObjFileMtlImporter & )
{
// empty
}
// -------------------------------------------------------------------
// Private copy constructor
ObjFileMtlImporter &ObjFileMtlImporter::operator = ( const ObjFileMtlImporter & )
{
return *this;
}
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Loads the material description // Loads the material description
void ObjFileMtlImporter::load() void ObjFileMtlImporter::load() {
{
if (m_DataIt == m_DataItEnd) if (m_DataIt == m_DataItEnd)
return; return;
while ( m_DataIt != m_DataItEnd ) while (m_DataIt != m_DataItEnd) {
{ switch (*m_DataIt) {
switch (*m_DataIt)
{
case 'k': case 'k':
case 'K': case 'K': {
{
++m_DataIt; ++m_DataIt;
if (*m_DataIt == 'a') // Ambient color if (*m_DataIt == 'a') // Ambient color
{ {
++m_DataIt; ++m_DataIt;
getColorRGBA(&m_pModel->m_pCurrentMaterial->ambient); getColorRGBA(&m_pModel->m_pCurrentMaterial->ambient);
} } else if (*m_DataIt == 'd') // Diffuse color
else if (*m_DataIt == 'd') // Diffuse color
{ {
++m_DataIt; ++m_DataIt;
getColorRGBA(&m_pModel->m_pCurrentMaterial->diffuse); getColorRGBA(&m_pModel->m_pCurrentMaterial->diffuse);
} } else if (*m_DataIt == 's') {
else if (*m_DataIt == 's')
{
++m_DataIt; ++m_DataIt;
getColorRGBA(&m_pModel->m_pCurrentMaterial->specular); getColorRGBA(&m_pModel->m_pCurrentMaterial->specular);
} } else if (*m_DataIt == 'e') {
else if (*m_DataIt == 'e')
{
++m_DataIt; ++m_DataIt;
getColorRGBA(&m_pModel->m_pCurrentMaterial->emissive); getColorRGBA(&m_pModel->m_pCurrentMaterial->emissive);
} }
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine); m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
} } break;
break; case 'T': {
case 'T':
{
++m_DataIt; ++m_DataIt;
if (*m_DataIt == 'f') // Material transmission if (*m_DataIt == 'f') // Material transmission
{ {
@ -171,10 +143,8 @@ void ObjFileMtlImporter::load()
getColorRGBA(&m_pModel->m_pCurrentMaterial->transparent); getColorRGBA(&m_pModel->m_pCurrentMaterial->transparent);
} }
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine); m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
} } break;
break; case 'd': {
case 'd':
{
if (*(m_DataIt + 1) == 'i' && *(m_DataIt + 2) == 's' && *(m_DataIt + 3) == 'p') { if (*(m_DataIt + 1) == 'i' && *(m_DataIt + 2) == 's' && *(m_DataIt + 3) == 'p') {
// A displacement map // A displacement map
getTexture(); getTexture();
@ -184,15 +154,12 @@ void ObjFileMtlImporter::load()
getFloatValue(m_pModel->m_pCurrentMaterial->alpha); getFloatValue(m_pModel->m_pCurrentMaterial->alpha);
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine); m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
} }
} } break;
break;
case 'N': case 'N':
case 'n': case 'n': {
{
++m_DataIt; ++m_DataIt;
switch(*m_DataIt) switch (*m_DataIt) {
{
case 's': // Specular exponent case 's': // Specular exponent
++m_DataIt; ++m_DataIt;
getFloatValue(m_pModel->m_pCurrentMaterial->shineness); getFloatValue(m_pModel->m_pCurrentMaterial->shineness);
@ -206,8 +173,7 @@ void ObjFileMtlImporter::load()
break; break;
} }
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine); m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
} } break;
break;
case 'm': // Texture case 'm': // Texture
case 'b': // quick'n'dirty - for 'bump' sections case 'b': // quick'n'dirty - for 'bump' sections
@ -215,30 +181,25 @@ void ObjFileMtlImporter::load()
{ {
getTexture(); getTexture();
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine); m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
} } break;
break;
case 'i': // Illumination model case 'i': // Illumination model
{ {
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
getIlluminationModel(m_pModel->m_pCurrentMaterial->illumination_model); getIlluminationModel(m_pModel->m_pCurrentMaterial->illumination_model);
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine); m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
} } break;
break;
default: default: {
{
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine); m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
} } break;
break;
} }
} }
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Loads a color definition // Loads a color definition
void ObjFileMtlImporter::getColorRGBA( aiColor3D *pColor ) void ObjFileMtlImporter::getColorRGBA(aiColor3D *pColor) {
{
ai_assert(NULL != pColor); ai_assert(NULL != pColor);
ai_real r(0.0), g(0.0), b(0.0); ai_real r(0.0), g(0.0), b(0.0);
@ -256,24 +217,21 @@ void ObjFileMtlImporter::getColorRGBA( aiColor3D *pColor )
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Loads the kind of illumination model. // Loads the kind of illumination model.
void ObjFileMtlImporter::getIlluminationModel( int &illum_model ) void ObjFileMtlImporter::getIlluminationModel(int &illum_model) {
{ m_DataIt = CopyNextWord<DataArrayIt>(m_DataIt, m_DataItEnd, &m_buffer[0], BUFFERSIZE);
m_DataIt = CopyNextWord<DataArrayIt>( m_DataIt, m_DataItEnd, m_buffer, BUFFERSIZE ); illum_model = atoi(&m_buffer[0]);
illum_model = atoi(m_buffer);
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Loads a single float value. // Loads a single float value.
void ObjFileMtlImporter::getFloatValue( ai_real &value ) void ObjFileMtlImporter::getFloatValue(ai_real &value) {
{ m_DataIt = CopyNextWord<DataArrayIt>(m_DataIt, m_DataItEnd, &m_buffer[0], BUFFERSIZE);
m_DataIt = CopyNextWord<DataArrayIt>( m_DataIt, m_DataItEnd, m_buffer, BUFFERSIZE ); value = (ai_real)fast_atof(&m_buffer[0]);
value = (ai_real) fast_atof(m_buffer);
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Creates a material from loaded data. // Creates a material from loaded data.
void ObjFileMtlImporter::createMaterial() void ObjFileMtlImporter::createMaterial() {
{
std::string line; std::string line;
while (!IsLineEnd(*m_DataIt)) { while (!IsLineEnd(*m_DataIt)) {
line += *m_DataIt; line += *m_DataIt;
@ -398,90 +356,57 @@ void ObjFileMtlImporter::getTextureOption(bool &clamp, int &clampIndex, aiString
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
// If there is any more texture option // If there is any more texture option
while (!isEndOfBuffer(m_DataIt, m_DataItEnd) && *m_DataIt == '-') while (!isEndOfBuffer(m_DataIt, m_DataItEnd) && *m_DataIt == '-') {
{
const char *pPtr(&(*m_DataIt)); const char *pPtr(&(*m_DataIt));
//skip option key and value //skip option key and value
int skipToken = 1; int skipToken = 1;
if (!ASSIMP_strincmp(pPtr, ClampOption.c_str(), static_cast<unsigned int>(ClampOption.size()))) if (!ASSIMP_strincmp(pPtr, ClampOption.c_str(), static_cast<unsigned int>(ClampOption.size()))) {
{
DataArrayIt it = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); DataArrayIt it = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
char value[3]; char value[3];
CopyNextWord(it, m_DataItEnd, value, sizeof(value) / sizeof(*value)); CopyNextWord(it, m_DataItEnd, value, sizeof(value) / sizeof(*value));
if (!ASSIMP_strincmp(value, "on", 2)) if (!ASSIMP_strincmp(value, "on", 2)) {
{
clamp = true; clamp = true;
} }
skipToken = 2; skipToken = 2;
} } else if (!ASSIMP_strincmp(pPtr, TypeOption.c_str(), static_cast<unsigned int>(TypeOption.size()))) {
else if( !ASSIMP_strincmp( pPtr, TypeOption.c_str(), static_cast<unsigned int>(TypeOption.size()) ) )
{
DataArrayIt it = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); DataArrayIt it = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
char value[12]; char value[12];
CopyNextWord(it, m_DataItEnd, value, sizeof(value) / sizeof(*value)); CopyNextWord(it, m_DataItEnd, value, sizeof(value) / sizeof(*value));
if( !ASSIMP_strincmp( value, "cube_top", 8 ) ) if (!ASSIMP_strincmp(value, "cube_top", 8)) {
{
clampIndex = ObjFile::Material::TextureReflectionCubeTopType; clampIndex = ObjFile::Material::TextureReflectionCubeTopType;
out = &m_pModel->m_pCurrentMaterial->textureReflection[0]; out = &m_pModel->m_pCurrentMaterial->textureReflection[0];
} } else if (!ASSIMP_strincmp(value, "cube_bottom", 11)) {
else if( !ASSIMP_strincmp( value, "cube_bottom", 11 ) )
{
clampIndex = ObjFile::Material::TextureReflectionCubeBottomType; clampIndex = ObjFile::Material::TextureReflectionCubeBottomType;
out = &m_pModel->m_pCurrentMaterial->textureReflection[1]; out = &m_pModel->m_pCurrentMaterial->textureReflection[1];
} } else if (!ASSIMP_strincmp(value, "cube_front", 10)) {
else if( !ASSIMP_strincmp( value, "cube_front", 10 ) )
{
clampIndex = ObjFile::Material::TextureReflectionCubeFrontType; clampIndex = ObjFile::Material::TextureReflectionCubeFrontType;
out = &m_pModel->m_pCurrentMaterial->textureReflection[2]; out = &m_pModel->m_pCurrentMaterial->textureReflection[2];
} } else if (!ASSIMP_strincmp(value, "cube_back", 9)) {
else if( !ASSIMP_strincmp( value, "cube_back", 9 ) )
{
clampIndex = ObjFile::Material::TextureReflectionCubeBackType; clampIndex = ObjFile::Material::TextureReflectionCubeBackType;
out = &m_pModel->m_pCurrentMaterial->textureReflection[3]; out = &m_pModel->m_pCurrentMaterial->textureReflection[3];
} } else if (!ASSIMP_strincmp(value, "cube_left", 9)) {
else if( !ASSIMP_strincmp( value, "cube_left", 9 ) )
{
clampIndex = ObjFile::Material::TextureReflectionCubeLeftType; clampIndex = ObjFile::Material::TextureReflectionCubeLeftType;
out = &m_pModel->m_pCurrentMaterial->textureReflection[4]; out = &m_pModel->m_pCurrentMaterial->textureReflection[4];
} } else if (!ASSIMP_strincmp(value, "cube_right", 10)) {
else if( !ASSIMP_strincmp( value, "cube_right", 10 ) )
{
clampIndex = ObjFile::Material::TextureReflectionCubeRightType; clampIndex = ObjFile::Material::TextureReflectionCubeRightType;
out = &m_pModel->m_pCurrentMaterial->textureReflection[5]; out = &m_pModel->m_pCurrentMaterial->textureReflection[5];
} } else if (!ASSIMP_strincmp(value, "sphere", 6)) {
else if( !ASSIMP_strincmp( value, "sphere", 6 ) )
{
clampIndex = ObjFile::Material::TextureReflectionSphereType; clampIndex = ObjFile::Material::TextureReflectionSphereType;
out = &m_pModel->m_pCurrentMaterial->textureReflection[0]; out = &m_pModel->m_pCurrentMaterial->textureReflection[0];
} }
skipToken = 2; skipToken = 2;
} } else if (!ASSIMP_strincmp(pPtr, BlendUOption.c_str(), static_cast<unsigned int>(BlendUOption.size())) || !ASSIMP_strincmp(pPtr, BlendVOption.c_str(), static_cast<unsigned int>(BlendVOption.size())) || !ASSIMP_strincmp(pPtr, BoostOption.c_str(), static_cast<unsigned int>(BoostOption.size())) || !ASSIMP_strincmp(pPtr, ResolutionOption.c_str(), static_cast<unsigned int>(ResolutionOption.size())) || !ASSIMP_strincmp(pPtr, BumpOption.c_str(), static_cast<unsigned int>(BumpOption.size())) || !ASSIMP_strincmp(pPtr, ChannelOption.c_str(), static_cast<unsigned int>(ChannelOption.size()))) {
else if (!ASSIMP_strincmp(pPtr, BlendUOption.c_str(), static_cast<unsigned int>(BlendUOption.size()))
|| !ASSIMP_strincmp(pPtr, BlendVOption.c_str(), static_cast<unsigned int>(BlendVOption.size()))
|| !ASSIMP_strincmp(pPtr, BoostOption.c_str(), static_cast<unsigned int>(BoostOption.size()))
|| !ASSIMP_strincmp(pPtr, ResolutionOption.c_str(), static_cast<unsigned int>(ResolutionOption.size()))
|| !ASSIMP_strincmp(pPtr, BumpOption.c_str(), static_cast<unsigned int>(BumpOption.size()))
|| !ASSIMP_strincmp(pPtr, ChannelOption.c_str(), static_cast<unsigned int>(ChannelOption.size())))
{
skipToken = 2; skipToken = 2;
} } else if (!ASSIMP_strincmp(pPtr, ModifyMapOption.c_str(), static_cast<unsigned int>(ModifyMapOption.size()))) {
else if (!ASSIMP_strincmp(pPtr, ModifyMapOption.c_str(), static_cast<unsigned int>(ModifyMapOption.size())))
{
skipToken = 3; skipToken = 3;
} } else if (!ASSIMP_strincmp(pPtr, OffsetOption.c_str(), static_cast<unsigned int>(OffsetOption.size())) || !ASSIMP_strincmp(pPtr, ScaleOption.c_str(), static_cast<unsigned int>(ScaleOption.size())) || !ASSIMP_strincmp(pPtr, TurbulenceOption.c_str(), static_cast<unsigned int>(TurbulenceOption.size()))) {
else if ( !ASSIMP_strincmp(pPtr, OffsetOption.c_str(), static_cast<unsigned int>(OffsetOption.size()))
|| !ASSIMP_strincmp(pPtr, ScaleOption.c_str(), static_cast<unsigned int>(ScaleOption.size()))
|| !ASSIMP_strincmp(pPtr, TurbulenceOption.c_str(), static_cast<unsigned int>(TurbulenceOption.size()))
)
{
skipToken = 4; skipToken = 4;
} }
for (int i = 0; i < skipToken; ++i) for (int i = 0; i < skipToken; ++i) {
{
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
} }
} }

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -41,9 +40,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef OBJFILEMTLIMPORTER_H_INC #ifndef OBJFILEMTLIMPORTER_H_INC
#define OBJFILEMTLIMPORTER_H_INC #define OBJFILEMTLIMPORTER_H_INC
#include <vector>
#include <string>
#include <assimp/defs.h> #include <assimp/defs.h>
#include <string>
#include <vector>
struct aiColor3D; struct aiColor3D;
struct aiString; struct aiString;
@ -53,34 +52,31 @@ namespace Assimp {
namespace ObjFile { namespace ObjFile {
struct Model; struct Model;
struct Material; struct Material;
} } // namespace ObjFile
/** /**
* @class ObjFileMtlImporter * @class ObjFileMtlImporter
* @brief Loads the material description from a mtl file. * @brief Loads the material description from a mtl file.
*/ */
class ObjFileMtlImporter class ObjFileMtlImporter {
{
public: public:
static const size_t BUFFERSIZE = 2048; static const size_t BUFFERSIZE = 2048;
typedef std::vector<char> DataArray; typedef std::vector<char> DataArray;
typedef std::vector<char>::iterator DataArrayIt; typedef std::vector<char>::iterator DataArrayIt;
typedef std::vector<char>::const_iterator ConstDataArrayIt; typedef std::vector<char>::const_iterator ConstDataArrayIt;
public: //! \brief The class default constructor
//! \brief Default constructor
ObjFileMtlImporter(std::vector<char> &buffer, const std::string &strAbsPath, ObjFileMtlImporter(std::vector<char> &buffer, const std::string &strAbsPath,
ObjFile::Model *pModel); ObjFile::Model *pModel);
//! \brief DEstructor //! \brief The class destructor
~ObjFileMtlImporter(); ~ObjFileMtlImporter();
ObjFileMtlImporter(const ObjFileMtlImporter &rOther) = delete;
ObjFileMtlImporter &operator=(const ObjFileMtlImporter &rOther) = delete;
private: private:
/// Copy constructor, empty. /// Copy constructor, empty.
ObjFileMtlImporter(const ObjFileMtlImporter &rOther);
/// \brief Assignment operator, returns only a reference of this instance.
ObjFileMtlImporter &operator = (const ObjFileMtlImporter &rOther);
/// Load the whole material description /// Load the whole material description
void load(); void load();
/// Get color data. /// Get color data.
@ -107,7 +103,7 @@ private:
//! Current line in file //! Current line in file
unsigned int m_uiLine; unsigned int m_uiLine;
//! Helper buffer //! Helper buffer
char m_buffer[BUFFERSIZE]; std::vector<char> m_buffer;
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -43,14 +41,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER #ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER
#include "ObjFileParser.h" #include "ObjFileParser.h"
#include "ObjFileData.h"
#include "ObjFileMtlImporter.h" #include "ObjFileMtlImporter.h"
#include "ObjTools.h" #include "ObjTools.h"
#include "ObjFileData.h"
#include <assimp/ParsingUtils.h>
#include <assimp/BaseImporter.h> #include <assimp/BaseImporter.h>
#include <assimp/DefaultIOSystem.h> #include <assimp/DefaultIOSystem.h>
#include <assimp/DefaultLogger.hpp> #include <assimp/ParsingUtils.h>
#include <assimp/material.h> #include <assimp/material.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
#include <cstdlib> #include <cstdlib>
#include <memory> #include <memory>
@ -60,29 +58,30 @@ namespace Assimp {
const std::string ObjFileParser::DEFAULT_MATERIAL = AI_DEFAULT_MATERIAL_NAME; const std::string ObjFileParser::DEFAULT_MATERIAL = AI_DEFAULT_MATERIAL_NAME;
ObjFileParser::ObjFileParser() ObjFileParser::ObjFileParser() :
: m_DataIt()
, m_DataItEnd()
, m_pModel( nullptr )
, m_uiLine( 0 )
, m_pIO( nullptr )
, m_progress( nullptr )
, m_originalObjFileName() {
// empty
}
ObjFileParser::ObjFileParser( IOStreamBuffer<char> &streamBuffer, const std::string &modelName,
IOSystem *io, ProgressHandler* progress,
std::string originalObjFileName) :
m_DataIt(), m_DataIt(),
m_DataItEnd(), m_DataItEnd(),
m_pModel(nullptr), m_pModel(nullptr),
m_uiLine(0), m_uiLine(0),
m_buffer(),
m_pIO(nullptr),
m_progress(nullptr),
m_originalObjFileName() {
std::fill_n(m_buffer, Buffersize, '\0');
}
ObjFileParser::ObjFileParser(IOStreamBuffer<char> &streamBuffer, const std::string &modelName,
IOSystem *io, ProgressHandler *progress,
const std::string &originalObjFileName) :
m_DataIt(),
m_DataItEnd(),
m_pModel(nullptr),
m_uiLine(0),
m_buffer(),
m_pIO(io), m_pIO(io),
m_progress(progress), m_progress(progress),
m_originalObjFileName(std::move(originalObjFileName)) m_originalObjFileName(originalObjFileName) {
{ std::fill_n(m_buffer, Buffersize, '\0');
std::fill_n(m_buffer, Buffersize,0);
// Create the model instance to store all the data // Create the model instance to store all the data
m_pModel.reset(new ObjFile::Model()); m_pModel.reset(new ObjFile::Model());
@ -98,8 +97,7 @@ ObjFileParser::ObjFileParser( IOStreamBuffer<char> &streamBuffer, const std::str
parseFile(streamBuffer); parseFile(streamBuffer);
} }
ObjFileParser::~ObjFileParser() ObjFileParser::~ObjFileParser() {
{
} }
void ObjFileParser::setBuffer(std::vector<char> &buffer) { void ObjFileParser::setBuffer(std::vector<char> &buffer) {
@ -161,23 +159,18 @@ void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
++m_DataIt; ++m_DataIt;
getVector3(m_pModel->m_Normals); getVector3(m_pModel->m_Normals);
} }
} } break;
break;
case 'p': // Parse a face, line or point statement case 'p': // Parse a face, line or point statement
case 'l': case 'l':
case 'f': case 'f': {
{ getFace(*m_DataIt == 'f' ? aiPrimitiveType_POLYGON : (*m_DataIt == 'l' ? aiPrimitiveType_LINE : aiPrimitiveType_POINT));
getFace(*m_DataIt == 'f' ? aiPrimitiveType_POLYGON : (*m_DataIt == 'l' } break;
? aiPrimitiveType_LINE : aiPrimitiveType_POINT));
}
break;
case '#': // Parse a comment case '#': // Parse a comment
{ {
getComment(); getComment();
} } break;
break;
case 'u': // Parse a material desc. setter case 'u': // Parse a material desc. setter
{ {
@ -189,12 +182,10 @@ void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
if (nextSpace != std::string::npos) if (nextSpace != std::string::npos)
name = name.substr(0, nextSpace); name = name.substr(0, nextSpace);
if(name == "usemtl") if (name == "usemtl") {
{
getMaterialDesc(); getMaterialDesc();
} }
} } break;
break;
case 'm': // Parse a material library or merging group ('mg') case 'm': // Parse a material library or merging group ('mg')
{ {
@ -212,33 +203,27 @@ void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
getMaterialLib(); getMaterialLib();
else else
goto pf_skip_line; goto pf_skip_line;
} } break;
break;
case 'g': // Parse group name case 'g': // Parse group name
{ {
getGroupName(); getGroupName();
} } break;
break;
case 's': // Parse group number case 's': // Parse group number
{ {
getGroupNumber(); getGroupNumber();
} } break;
break;
case 'o': // Parse object name case 'o': // Parse object name
{ {
getObjectName(); getObjectName();
} } break;
break;
default: default: {
{
pf_skip_line: pf_skip_line:
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine); m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
} } break;
break;
} }
} }
} }
@ -497,7 +482,6 @@ void ObjFileParser::getFace( aiPrimitiveType type ) {
delete face; delete face;
throw DeadlyImportError("OBJ: Invalid face indice"); throw DeadlyImportError("OBJ: Invalid face indice");
} }
} }
m_DataIt += iStep; m_DataIt += iStep;
} }
@ -691,16 +675,13 @@ 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 ])
{
mat_index = (int)index; mat_index = (int)index;
break; break;
} }
@ -729,14 +710,11 @@ void ObjFileParser::getGroupName() {
createObject(groupName); createObject(groupName);
// New group name, creating a new entry // New group name, creating a new entry
if (it == m_pModel->m_Groups.end()) if (it == m_pModel->m_Groups.end()) {
{
std::vector<unsigned int> *pFaceIDArray = new std::vector<unsigned int>; std::vector<unsigned int> *pFaceIDArray = new std::vector<unsigned int>;
m_pModel->m_Groups[groupName] = pFaceIDArray; m_pModel->m_Groups[groupName] = pFaceIDArray;
m_pModel->m_pGroupFaceIDs = (pFaceIDArray); m_pModel->m_pGroupFaceIDs = (pFaceIDArray);
} } else {
else
{
m_pModel->m_pGroupFaceIDs = (*it).second; m_pModel->m_pGroupFaceIDs = (*it).second;
} }
m_pModel->m_strActiveGroup = groupName; m_pModel->m_strActiveGroup = groupName;
@ -746,8 +724,7 @@ void ObjFileParser::getGroupName() {
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Not supported // Not supported
void ObjFileParser::getGroupNumber() void ObjFileParser::getGroupNumber() {
{
// Not used // Not used
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine); m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
@ -755,8 +732,7 @@ void ObjFileParser::getGroupNumber()
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Not supported // Not supported
void ObjFileParser::getGroupNumberAndResolution() void ObjFileParser::getGroupNumberAndResolution() {
{
// Not used // Not used
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine); m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
@ -765,8 +741,7 @@ void ObjFileParser::getGroupNumberAndResolution()
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Stores values for a new object instance, name will be used to // Stores values for a new object instance, name will be used to
// identify it. // identify it.
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;
@ -777,18 +752,15 @@ void ObjFileParser::getObjectName()
} }
std::string strObjectName(pStart, &(*m_DataIt)); std::string strObjectName(pStart, &(*m_DataIt));
if (!strObjectName.empty()) if (!strObjectName.empty()) {
{
// Reset current object // Reset current object
m_pModel->m_pCurrent = NULL; m_pModel->m_pCurrent = NULL;
// Search for actual object // Search for actual object
for (std::vector<ObjFile::Object *>::const_iterator it = m_pModel->m_Objects.begin(); for (std::vector<ObjFile::Object *>::const_iterator it = m_pModel->m_Objects.begin();
it != m_pModel->m_Objects.end(); it != m_pModel->m_Objects.end();
++it) ++it) {
{ if ((*it)->m_strObjName == strObjectName) {
if ((*it)->m_strObjName == strObjectName)
{
m_pModel->m_pCurrent = *it; m_pModel->m_pCurrent = *it;
break; break;
} }
@ -803,8 +775,7 @@ void ObjFileParser::getObjectName()
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Creates a new object instance // Creates a new object instance
void ObjFileParser::createObject(const std::string &objName) void ObjFileParser::createObject(const std::string &objName) {
{
ai_assert(NULL != m_pModel); ai_assert(NULL != m_pModel);
m_pModel->m_pCurrent = new ObjFile::Object; m_pModel->m_pCurrent = new ObjFile::Object;
@ -813,8 +784,7 @@ void ObjFileParser::createObject(const std::string &objName)
createMesh(objName); createMesh(objName);
if( m_pModel->m_pCurrentMaterial ) if (m_pModel->m_pCurrentMaterial) {
{
m_pModel->m_pCurrentMesh->m_uiMaterialIndex = m_pModel->m_pCurrentMesh->m_uiMaterialIndex =
getMaterialIndex(m_pModel->m_pCurrentMaterial->MaterialName.data); getMaterialIndex(m_pModel->m_pCurrentMaterial->MaterialName.data);
m_pModel->m_pCurrentMesh->m_pMaterial = m_pModel->m_pCurrentMaterial; m_pModel->m_pCurrentMesh->m_pMaterial = m_pModel->m_pCurrentMaterial;
@ -822,40 +792,32 @@ void ObjFileParser::createObject(const std::string &objName)
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Creates a new mesh // Creates a new mesh
void ObjFileParser::createMesh( const std::string &meshName ) void ObjFileParser::createMesh(const std::string &meshName) {
{
ai_assert(NULL != m_pModel); ai_assert(NULL != m_pModel);
m_pModel->m_pCurrentMesh = new ObjFile::Mesh(meshName); m_pModel->m_pCurrentMesh = new ObjFile::Mesh(meshName);
m_pModel->m_Meshes.push_back(m_pModel->m_pCurrentMesh); m_pModel->m_Meshes.push_back(m_pModel->m_pCurrentMesh);
unsigned int meshId = static_cast<unsigned int>(m_pModel->m_Meshes.size() - 1); unsigned int meshId = static_cast<unsigned int>(m_pModel->m_Meshes.size() - 1);
if ( NULL != m_pModel->m_pCurrent ) if (NULL != m_pModel->m_pCurrent) {
{
m_pModel->m_pCurrent->m_Meshes.push_back(meshId); m_pModel->m_pCurrent->m_Meshes.push_back(meshId);
} } else {
else
{
ASSIMP_LOG_ERROR("OBJ: No object detected to attach a new mesh instance."); ASSIMP_LOG_ERROR("OBJ: No object detected to attach a new mesh instance.");
} }
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Returns true, if a new mesh must be created. // Returns true, if a new mesh must be created.
bool ObjFileParser::needsNewMesh( const std::string &materialName ) bool ObjFileParser::needsNewMesh(const std::string &materialName) {
{
// If no mesh data yet // If no mesh data yet
if (m_pModel->m_pCurrentMesh == nullptr) if (m_pModel->m_pCurrentMesh == nullptr) {
{
return true; return true;
} }
bool newMat = false; bool newMat = false;
int matIdx = getMaterialIndex(materialName); int matIdx = getMaterialIndex(materialName);
int curMatIdx = m_pModel->m_pCurrentMesh->m_uiMaterialIndex; int curMatIdx = m_pModel->m_pCurrentMesh->m_uiMaterialIndex;
if ( curMatIdx != int(ObjFile::Mesh::NoMaterial) if (curMatIdx != int(ObjFile::Mesh::NoMaterial) && curMatIdx != matIdx
&& curMatIdx != matIdx
// no need create a new mesh if no faces in current // no need create a new mesh if no faces in current
// lets say 'usemtl' goes straight after 'g' // lets say 'usemtl' goes straight after 'g'
&& !m_pModel->m_pCurrentMesh->m_Faces.empty() ) && !m_pModel->m_pCurrentMesh->m_Faces.empty()) {
{
// New material -> only one material per mesh, so we need to create a new // New material -> only one material per mesh, so we need to create a new
// material // material
newMat = true; newMat = true;
@ -865,8 +827,7 @@ bool ObjFileParser::needsNewMesh( const std::string &materialName )
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Shows an error in parsing process. // Shows an error in parsing process.
void ObjFileParser::reportErrorTokenInFace() void ObjFileParser::reportErrorTokenInFace() {
{
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine); m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
ASSIMP_LOG_ERROR("OBJ: Not supported token in face description detected"); ASSIMP_LOG_ERROR("OBJ: Not supported token in face description detected");
} }

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -42,14 +41,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef OBJ_FILEPARSER_H_INC #ifndef OBJ_FILEPARSER_H_INC
#define OBJ_FILEPARSER_H_INC #define OBJ_FILEPARSER_H_INC
#include <vector> #include <assimp/IOStreamBuffer.h>
#include <string> #include <assimp/mesh.h>
#include <map>
#include <memory>
#include <assimp/vector2.h> #include <assimp/vector2.h>
#include <assimp/vector3.h> #include <assimp/vector3.h>
#include <assimp/mesh.h> #include <map>
#include <assimp/IOStreamBuffer.h> #include <memory>
#include <string>
#include <vector>
namespace Assimp { namespace Assimp {
@ -59,7 +58,7 @@ namespace ObjFile {
struct Material; struct Material;
struct Point3; struct Point3;
struct Point2; struct Point2;
} } // namespace ObjFile
class ObjFileImporter; class ObjFileImporter;
class IOSystem; class IOSystem;
@ -78,7 +77,7 @@ public:
/// @brief The default constructor. /// @brief The default constructor.
ObjFileParser(); ObjFileParser();
/// @brief Constructor with data array. /// @brief Constructor with data array.
ObjFileParser(IOStreamBuffer<char> &streamBuffer, const std::string &modelName, IOSystem* io, ProgressHandler* progress, std::string originalObjFileName); ObjFileParser(IOStreamBuffer<char> &streamBuffer, const std::string &modelName, IOSystem *io, ProgressHandler *progress, const std::string &originalObjFileName);
/// @brief Destructor /// @brief Destructor
~ObjFileParser(); ~ObjFileParser();
/// @brief If you want to load in-core data. /// @brief If you want to load in-core data.
@ -86,6 +85,9 @@ public:
/// @brief Model getter. /// @brief Model getter.
ObjFile::Model *GetModel() const; ObjFile::Model *GetModel() const;
ObjFileParser(const ObjFileParser&) = delete;
ObjFileParser &operator=(const ObjFileParser& ) = delete;
protected: protected:
/// Parse the loaded file /// Parse the loaded file
void parseFile(IOStreamBuffer<char> &streamBuffer); void parseFile(IOStreamBuffer<char> &streamBuffer);
@ -137,8 +139,6 @@ protected:
private: private:
// Copy and assignment constructor should be private // Copy and assignment constructor should be private
// because the class contains pointer to allocated memory // because the class contains pointer to allocated memory
ObjFileParser(const ObjFileParser& rhs);
ObjFileParser& operator=(const ObjFileParser& rhs);
/// Default material name /// Default material name
static const std::string DEFAULT_MATERIAL; static const std::string DEFAULT_MATERIAL;

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -46,8 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef OBJ_TOOLS_H_INC #ifndef OBJ_TOOLS_H_INC
#define OBJ_TOOLS_H_INC #define OBJ_TOOLS_H_INC
#include <assimp/fast_atof.h>
#include <assimp/ParsingUtils.h> #include <assimp/ParsingUtils.h>
#include <assimp/fast_atof.h>
#include <vector> #include <vector>
namespace Assimp { namespace Assimp {
@ -59,12 +58,9 @@ namespace Assimp {
*/ */
template <class char_t> template <class char_t>
inline bool isEndOfBuffer(char_t it, char_t end) { inline bool isEndOfBuffer(char_t it, char_t end) {
if ( it == end ) if (it == end) {
{
return true; return true;
} } else {
else
{
--end; --end;
} }
return (it == end); return (it == end);
@ -76,10 +72,8 @@ inline bool isEndOfBuffer( char_t it, char_t end ) {
* @return Pointer to next space * @return Pointer to next space
*/ */
template <class Char_T> template <class Char_T>
inline Char_T getNextWord( Char_T pBuffer, Char_T pEnd ) inline Char_T getNextWord(Char_T pBuffer, Char_T pEnd) {
{ while (!isEndOfBuffer(pBuffer, pEnd)) {
while ( !isEndOfBuffer( pBuffer, pEnd ) )
{
if (!IsSpaceOrNewLine(*pBuffer) || IsLineEnd(*pBuffer)) { if (!IsSpaceOrNewLine(*pBuffer) || IsLineEnd(*pBuffer)) {
//if ( *pBuffer != '\\' ) //if ( *pBuffer != '\\' )
break; break;
@ -95,10 +89,8 @@ inline Char_T getNextWord( Char_T pBuffer, Char_T pEnd )
* @return Pointer to next token * @return Pointer to next token
*/ */
template <class Char_T> template <class Char_T>
inline Char_T getNextToken( Char_T pBuffer, Char_T pEnd ) inline Char_T getNextToken(Char_T pBuffer, Char_T pEnd) {
{ while (!isEndOfBuffer(pBuffer, pEnd)) {
while ( !isEndOfBuffer( pBuffer, pEnd ) )
{
if (IsSpaceOrNewLine(*pBuffer)) if (IsSpaceOrNewLine(*pBuffer))
break; break;
pBuffer++; pBuffer++;
@ -138,8 +130,7 @@ inline char_t skipLine( char_t it, char_t end, unsigned int &uiLine ) {
* @return Current-iterator with new position * @return Current-iterator with new position
*/ */
template <class char_t> template <class char_t>
inline char_t getName( char_t it, char_t end, std::string &name ) inline char_t getName(char_t it, char_t end, std::string &name) {
{
name = ""; name = "";
if (isEndOfBuffer(it, end)) { if (isEndOfBuffer(it, end)) {
return end; return end;
@ -175,21 +166,18 @@ inline char_t getName( char_t it, char_t end, std::string &name )
* @return Current-iterator with new position * @return Current-iterator with new position
*/ */
template <class char_t> template <class char_t>
inline char_t getNameNoSpace( char_t it, char_t end, std::string &name ) inline char_t getNameNoSpace(char_t it, char_t end, std::string &name) {
{
name = ""; name = "";
if (isEndOfBuffer(it, end)) { if (isEndOfBuffer(it, end)) {
return end; return end;
} }
char *pStart = &(*it); char *pStart = &(*it);
while( !isEndOfBuffer( it, end ) && !IsLineEnd( *it ) while (!isEndOfBuffer(it, end) && !IsLineEnd(*it) && !IsSpaceOrNewLine(*it)) {
&& !IsSpaceOrNewLine( *it ) ) {
++it; ++it;
} }
while( isEndOfBuffer( it, end ) || IsLineEnd( *it ) while (isEndOfBuffer(it, end) || IsLineEnd(*it) || IsSpaceOrNewLine(*it)) {
|| IsSpaceOrNewLine( *it ) ) {
--it; --it;
} }
++it; ++it;
@ -216,12 +204,10 @@ inline char_t getNameNoSpace( char_t it, char_t end, std::string &name )
* @return Current-iterator with new position * @return Current-iterator with new position
*/ */
template <class char_t> template <class char_t>
inline char_t CopyNextWord( char_t it, char_t end, char *pBuffer, size_t length ) inline char_t CopyNextWord(char_t it, char_t end, char *pBuffer, size_t length) {
{
size_t index = 0; size_t index = 0;
it = getNextWord<char_t>(it, end); it = getNextWord<char_t>(it, end);
while( !IsSpaceOrNewLine( *it ) && !isEndOfBuffer( it, end ) ) while (!IsSpaceOrNewLine(*it) && !isEndOfBuffer(it, end)) {
{
pBuffer[index] = *it; pBuffer[index] = *it;
index++; index++;
if (index == length - 1) if (index == length - 1)
@ -239,8 +225,7 @@ inline char_t CopyNextWord( char_t it, char_t end, char *pBuffer, size_t length
* @return Current-iterator with new position * @return Current-iterator with new position
*/ */
template <class char_t> template <class char_t>
inline char_t getFloat( char_t it, char_t end, ai_real &value ) inline char_t getFloat(char_t it, char_t end, ai_real &value) {
{
static const size_t BUFFERSIZE = 1024; static const size_t BUFFERSIZE = 1024;
char buffer[BUFFERSIZE]; char buffer[BUFFERSIZE];
it = CopyNextWord<char_t>(it, end, buffer, BUFFERSIZE); it = CopyNextWord<char_t>(it, end, buffer, BUFFERSIZE);
@ -257,15 +242,13 @@ inline char_t getFloat( char_t it, char_t end, ai_real &value )
*/ */
template <class string_type> template <class string_type>
unsigned int tokenize(const string_type &str, std::vector<string_type> &tokens, unsigned int tokenize(const string_type &str, std::vector<string_type> &tokens,
const string_type& delimiters ) const string_type &delimiters) {
{
// Skip delimiters at beginning. // Skip delimiters at beginning.
typename string_type::size_type lastPos = str.find_first_not_of(delimiters, 0); typename string_type::size_type lastPos = str.find_first_not_of(delimiters, 0);
// Find first "non-delimiter". // Find first "non-delimiter".
typename string_type::size_type pos = str.find_first_of(delimiters, lastPos); typename string_type::size_type pos = str.find_first_of(delimiters, lastPos);
while ( string_type::npos != pos || string_type::npos != lastPos ) while (string_type::npos != pos || string_type::npos != lastPos) {
{
// Found a token, add it to the vector. // Found a token, add it to the vector.
string_type tmp = str.substr(lastPos, pos - lastPos); string_type tmp = str.substr(lastPos, pos - lastPos);
if (!tmp.empty() && ' ' != tmp[0]) if (!tmp.empty() && ' ' != tmp[0])
@ -282,10 +265,11 @@ unsigned int tokenize( const string_type& str, std::vector<string_type>& tokens,
} }
template <class string_type> template <class string_type>
string_type trim_whitespaces(string_type str) string_type trim_whitespaces(string_type str) {
{ while (!str.empty() && IsSpace(str[0]))
while (!str.empty() && IsSpace(str[0])) str.erase(0); str.erase(0);
while (!str.empty() && IsSpace(str[str.length() - 1])) str.erase(str.length() - 1); while (!str.empty() && IsSpace(str[str.length() - 1]))
str.erase(str.length() - 1);
return str; return str;
} }

View File

@ -41,22 +41,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "OgreBinarySerializer.h" #include "OgreBinarySerializer.h"
#include "OgreXmlSerializer.h"
#include "OgreParsingUtils.h" #include "OgreParsingUtils.h"
#include "OgreXmlSerializer.h"
#include <assimp/TinyFormatter.h> #include <assimp/TinyFormatter.h>
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER #ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
// Define as 1 to get verbose logging. // Define as 1 to get verbose logging.
#define OGRE_BINARY_SERIALIZER_DEBUG 0 #define OGRE_BINARY_SERIALIZER_DEBUG 0
namespace Assimp namespace Assimp {
{ namespace Ogre {
namespace Ogre
{
const std::string MESH_VERSION_1_8 = "[MeshSerializer_v1.8]"; const std::string MESH_VERSION_1_8 = "[MeshSerializer_v1.8]";
const std::string SKELETON_VERSION_1_8 = "[Serializer_v1.80]"; const std::string SKELETON_VERSION_1_8 = "[Serializer_v1.80]";
@ -69,70 +66,58 @@ const long MSTREAM_BONE_SIZE_WITHOUT_SCALE = MSTREAM_OVERHEAD_S
const long MSTREAM_KEYFRAME_SIZE_WITHOUT_SCALE = MSTREAM_OVERHEAD_SIZE + (sizeof(float) * 8); const long MSTREAM_KEYFRAME_SIZE_WITHOUT_SCALE = MSTREAM_OVERHEAD_SIZE + (sizeof(float) * 8);
template <> template <>
inline bool OgreBinarySerializer::Read<bool>() inline bool OgreBinarySerializer::Read<bool>() {
{
return (m_reader->GetU1() > 0); return (m_reader->GetU1() > 0);
} }
template <> template <>
inline char OgreBinarySerializer::Read<char>() inline char OgreBinarySerializer::Read<char>() {
{
return static_cast<char>(m_reader->GetU1()); return static_cast<char>(m_reader->GetU1());
} }
template <> template <>
inline uint8_t OgreBinarySerializer::Read<uint8_t>() inline uint8_t OgreBinarySerializer::Read<uint8_t>() {
{
return m_reader->GetU1(); return m_reader->GetU1();
} }
template <> template <>
inline uint16_t OgreBinarySerializer::Read<uint16_t>() inline uint16_t OgreBinarySerializer::Read<uint16_t>() {
{
return m_reader->GetU2(); return m_reader->GetU2();
} }
template <> template <>
inline uint32_t OgreBinarySerializer::Read<uint32_t>() inline uint32_t OgreBinarySerializer::Read<uint32_t>() {
{
return m_reader->GetU4(); return m_reader->GetU4();
} }
template <> template <>
inline float OgreBinarySerializer::Read<float>() inline float OgreBinarySerializer::Read<float>() {
{
return m_reader->GetF4(); return m_reader->GetF4();
} }
void OgreBinarySerializer::ReadBytes(char *dest, size_t numBytes) void OgreBinarySerializer::ReadBytes(char *dest, size_t numBytes) {
{
ReadBytes(static_cast<void *>(dest), numBytes); ReadBytes(static_cast<void *>(dest), numBytes);
} }
void OgreBinarySerializer::ReadBytes(uint8_t *dest, size_t numBytes) void OgreBinarySerializer::ReadBytes(uint8_t *dest, size_t numBytes) {
{
ReadBytes(static_cast<void *>(dest), numBytes); ReadBytes(static_cast<void *>(dest), numBytes);
} }
void OgreBinarySerializer::ReadBytes(void *dest, size_t numBytes) void OgreBinarySerializer::ReadBytes(void *dest, size_t numBytes) {
{
m_reader->CopyAndAdvance(dest, numBytes); m_reader->CopyAndAdvance(dest, numBytes);
} }
uint8_t *OgreBinarySerializer::ReadBytes(size_t numBytes) uint8_t *OgreBinarySerializer::ReadBytes(size_t numBytes) {
{
uint8_t *bytes = new uint8_t[numBytes]; uint8_t *bytes = new uint8_t[numBytes];
ReadBytes(bytes, numBytes); ReadBytes(bytes, numBytes);
return bytes; return bytes;
} }
void OgreBinarySerializer::ReadVector(aiVector3D &vec) void OgreBinarySerializer::ReadVector(aiVector3D &vec) {
{
m_reader->CopyAndAdvance(&vec.x, sizeof(float) * 3); m_reader->CopyAndAdvance(&vec.x, sizeof(float) * 3);
} }
void OgreBinarySerializer::ReadQuaternion(aiQuaternion &quat) void OgreBinarySerializer::ReadQuaternion(aiQuaternion &quat) {
{
float temp[4]; float temp[4];
m_reader->CopyAndAdvance(temp, sizeof(float) * 4); m_reader->CopyAndAdvance(temp, sizeof(float) * 4);
quat.x = temp[0]; quat.x = temp[0];
@ -141,24 +126,20 @@ void OgreBinarySerializer::ReadQuaternion(aiQuaternion &quat)
quat.w = temp[3]; quat.w = temp[3];
} }
bool OgreBinarySerializer::AtEnd() const bool OgreBinarySerializer::AtEnd() const {
{
return (m_reader->GetRemainingSize() == 0); return (m_reader->GetRemainingSize() == 0);
} }
std::string OgreBinarySerializer::ReadString(size_t len) std::string OgreBinarySerializer::ReadString(size_t len) {
{
std::string str; std::string str;
str.resize(len); str.resize(len);
ReadBytes(&str[0], len); ReadBytes(&str[0], len);
return str; return str;
} }
std::string OgreBinarySerializer::ReadLine() std::string OgreBinarySerializer::ReadLine() {
{
std::string str; std::string str;
while(!AtEnd()) while (!AtEnd()) {
{
char c = Read<char>(); char c = Read<char>();
if (c == '\n') if (c == '\n')
break; break;
@ -167,30 +148,25 @@ std::string OgreBinarySerializer::ReadLine()
return str; return str;
} }
uint16_t OgreBinarySerializer::ReadHeader(bool readLen) uint16_t OgreBinarySerializer::ReadHeader(bool readLen) {
{
uint16_t id = Read<uint16_t>(); uint16_t id = Read<uint16_t>();
if (readLen) if (readLen)
m_currentLen = Read<uint32_t>(); m_currentLen = Read<uint32_t>();
#if (OGRE_BINARY_SERIALIZER_DEBUG == 1) #if (OGRE_BINARY_SERIALIZER_DEBUG == 1)
if (id != HEADER_CHUNK_ID) if (id != HEADER_CHUNK_ID) {
{ ASSIMP_LOG_DEBUG(Formatter::format() << (assetMode == AM_Mesh ? MeshHeaderToString(static_cast<MeshChunkId>(id)) : SkeletonHeaderToString(static_cast<SkeletonChunkId>(id))));
ASSIMP_LOG_DEBUG(Formatter::format() << (assetMode == AM_Mesh
? MeshHeaderToString(static_cast<MeshChunkId>(id)) : SkeletonHeaderToString(static_cast<SkeletonChunkId>(id))));
} }
#endif #endif
return id; return id;
} }
void OgreBinarySerializer::RollbackHeader() void OgreBinarySerializer::RollbackHeader() {
{
m_reader->IncPtr(-MSTREAM_OVERHEAD_SIZE); m_reader->IncPtr(-MSTREAM_OVERHEAD_SIZE);
} }
void OgreBinarySerializer::SkipBytes(size_t numBytes) void OgreBinarySerializer::SkipBytes(size_t numBytes) {
{
#if (OGRE_BINARY_SERIALIZER_DEBUG == 1) #if (OGRE_BINARY_SERIALIZER_DEBUG == 1)
ASSIMP_LOG_DEBUG_F("Skipping ", numBytes, " bytes"); ASSIMP_LOG_DEBUG_F("Skipping ", numBytes, " bytes");
#endif #endif
@ -200,8 +176,7 @@ void OgreBinarySerializer::SkipBytes(size_t numBytes)
// Mesh // Mesh
Mesh *OgreBinarySerializer::ImportMesh(MemoryStreamReader *stream) Mesh *OgreBinarySerializer::ImportMesh(MemoryStreamReader *stream) {
{
OgreBinarySerializer serializer(stream, OgreBinarySerializer::AM_Mesh); OgreBinarySerializer serializer(stream, OgreBinarySerializer::AM_Mesh);
uint16_t id = serializer.ReadHeader(false); uint16_t id = serializer.ReadHeader(false);
@ -211,20 +186,16 @@ Mesh *OgreBinarySerializer::ImportMesh(MemoryStreamReader *stream)
/// @todo Check what we can actually support. /// @todo Check what we can actually support.
std::string version = serializer.ReadLine(); std::string version = serializer.ReadLine();
if (version != MESH_VERSION_1_8) if (version != MESH_VERSION_1_8) {
{
throw DeadlyExportError(Formatter::format() << "Mesh version " << version << " not supported by this importer. Run OgreMeshUpgrader tool on the file and try again." throw DeadlyExportError(Formatter::format() << "Mesh version " << version << " not supported by this importer. Run OgreMeshUpgrader tool on the file and try again."
<< " Supported versions: " << MESH_VERSION_1_8); << " Supported versions: " << MESH_VERSION_1_8);
} }
Mesh *mesh = new Mesh(); Mesh *mesh = new Mesh();
while (!serializer.AtEnd()) while (!serializer.AtEnd()) {
{
id = serializer.ReadHeader(); id = serializer.ReadHeader();
switch(id) switch (id) {
{ case M_MESH: {
case M_MESH:
{
serializer.ReadMesh(mesh); serializer.ReadMesh(mesh);
break; break;
} }
@ -233,15 +204,13 @@ Mesh *OgreBinarySerializer::ImportMesh(MemoryStreamReader *stream)
return mesh; return mesh;
} }
void OgreBinarySerializer::ReadMesh(Mesh *mesh) void OgreBinarySerializer::ReadMesh(Mesh *mesh) {
{
mesh->hasSkeletalAnimations = Read<bool>(); mesh->hasSkeletalAnimations = Read<bool>();
ASSIMP_LOG_DEBUG("Reading Mesh"); ASSIMP_LOG_DEBUG("Reading Mesh");
ASSIMP_LOG_DEBUG_F(" - Skeletal animations: ", mesh->hasSkeletalAnimations ? "true" : "false"); ASSIMP_LOG_DEBUG_F(" - Skeletal animations: ", mesh->hasSkeletalAnimations ? "true" : "false");
if (!AtEnd()) if (!AtEnd()) {
{
uint16_t id = ReadHeader(); uint16_t id = ReadHeader();
while (!AtEnd() && while (!AtEnd() &&
(id == M_GEOMETRY || (id == M_GEOMETRY ||
@ -254,63 +223,50 @@ void OgreBinarySerializer::ReadMesh(Mesh *mesh)
id == M_EDGE_LISTS || id == M_EDGE_LISTS ||
id == M_POSES || id == M_POSES ||
id == M_ANIMATIONS || id == M_ANIMATIONS ||
id == M_TABLE_EXTREMES)) id == M_TABLE_EXTREMES)) {
{ switch (id) {
switch(id) case M_GEOMETRY: {
{
case M_GEOMETRY:
{
mesh->sharedVertexData = new VertexData(); mesh->sharedVertexData = new VertexData();
ReadGeometry(mesh->sharedVertexData); ReadGeometry(mesh->sharedVertexData);
break; break;
} }
case M_SUBMESH: case M_SUBMESH: {
{
ReadSubMesh(mesh); ReadSubMesh(mesh);
break; break;
} }
case M_MESH_SKELETON_LINK: case M_MESH_SKELETON_LINK: {
{
ReadMeshSkeletonLink(mesh); ReadMeshSkeletonLink(mesh);
break; break;
} }
case M_MESH_BONE_ASSIGNMENT: case M_MESH_BONE_ASSIGNMENT: {
{
ReadBoneAssignment(mesh->sharedVertexData); ReadBoneAssignment(mesh->sharedVertexData);
break; break;
} }
case M_MESH_LOD: case M_MESH_LOD: {
{
ReadMeshLodInfo(mesh); ReadMeshLodInfo(mesh);
break; break;
} }
case M_MESH_BOUNDS: case M_MESH_BOUNDS: {
{
ReadMeshBounds(mesh); ReadMeshBounds(mesh);
break; break;
} }
case M_SUBMESH_NAME_TABLE: case M_SUBMESH_NAME_TABLE: {
{
ReadSubMeshNames(mesh); ReadSubMeshNames(mesh);
break; break;
} }
case M_EDGE_LISTS: case M_EDGE_LISTS: {
{
ReadEdgeList(mesh); ReadEdgeList(mesh);
break; break;
} }
case M_POSES: case M_POSES: {
{
ReadPoses(mesh); ReadPoses(mesh);
break; break;
} }
case M_ANIMATIONS: case M_ANIMATIONS: {
{
ReadAnimations(mesh); ReadAnimations(mesh);
break; break;
} }
case M_TABLE_EXTREMES: case M_TABLE_EXTREMES: {
{
ReadMeshExtremes(mesh); ReadMeshExtremes(mesh);
break; break;
} }
@ -326,8 +282,7 @@ void OgreBinarySerializer::ReadMesh(Mesh *mesh)
NormalizeBoneWeights(mesh->sharedVertexData); NormalizeBoneWeights(mesh->sharedVertexData);
} }
void OgreBinarySerializer::ReadMeshLodInfo(Mesh *mesh) void OgreBinarySerializer::ReadMeshLodInfo(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.
// @todo Put this stuff to scene/mesh custom properties. If manual mesh the app can use the information. // @todo Put this stuff to scene/mesh custom properties. If manual mesh the app can use the information.
ReadLine(); // strategy name ReadLine(); // strategy name
@ -335,8 +290,7 @@ void OgreBinarySerializer::ReadMeshLodInfo(Mesh *mesh)
bool manual = Read<bool>(); bool manual = Read<bool>();
/// @note Main mesh is considered as LOD 0, start from index 1. /// @note Main mesh is considered as LOD 0, start from index 1.
for (size_t i=1; i<numLods; ++i) for (size_t i = 1; i < numLods; ++i) {
{
uint16_t id = ReadHeader(); uint16_t id = ReadHeader();
if (id != M_MESH_LOD_USAGE) { if (id != M_MESH_LOD_USAGE) {
throw DeadlyImportError("M_MESH_LOD does not contain a M_MESH_LOD_USAGE for each LOD level"); throw DeadlyImportError("M_MESH_LOD does not contain a M_MESH_LOD_USAGE for each LOD level");
@ -344,19 +298,15 @@ void OgreBinarySerializer::ReadMeshLodInfo(Mesh *mesh)
m_reader->IncPtr(sizeof(float)); // user value m_reader->IncPtr(sizeof(float)); // user value
if (manual) if (manual) {
{
id = ReadHeader(); id = ReadHeader();
if (id != M_MESH_LOD_MANUAL) { if (id != M_MESH_LOD_MANUAL) {
throw DeadlyImportError("Manual M_MESH_LOD_USAGE does not contain M_MESH_LOD_MANUAL"); throw DeadlyImportError("Manual M_MESH_LOD_USAGE does not contain M_MESH_LOD_MANUAL");
} }
ReadLine(); // manual mesh name (ref to another mesh) ReadLine(); // manual mesh name (ref to another mesh)
} } else {
else for (size_t si = 0, silen = mesh->NumSubMeshes(); si < silen; ++si) {
{
for(size_t si=0, silen=mesh->NumSubMeshes(); si<silen; ++si)
{
id = ReadHeader(); id = ReadHeader();
if (id != M_MESH_LOD_GENERATED) { if (id != M_MESH_LOD_GENERATED) {
throw DeadlyImportError("Generated M_MESH_LOD_USAGE does not contain M_MESH_LOD_GENERATED"); throw DeadlyImportError("Generated M_MESH_LOD_USAGE does not contain M_MESH_LOD_GENERATED");
@ -365,8 +315,7 @@ void OgreBinarySerializer::ReadMeshLodInfo(Mesh *mesh)
uint32_t indexCount = Read<uint32_t>(); uint32_t indexCount = Read<uint32_t>();
bool is32bit = Read<bool>(); bool is32bit = Read<bool>();
if (indexCount > 0) if (indexCount > 0) {
{
uint32_t len = indexCount * (is32bit ? sizeof(uint32_t) : sizeof(uint16_t)); uint32_t len = indexCount * (is32bit ? sizeof(uint32_t) : sizeof(uint16_t));
m_reader->IncPtr(len); m_reader->IncPtr(len);
} }
@ -375,27 +324,23 @@ void OgreBinarySerializer::ReadMeshLodInfo(Mesh *mesh)
} }
} }
void OgreBinarySerializer::ReadMeshSkeletonLink(Mesh *mesh) 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;
SkipBytes(numBytes); SkipBytes(numBytes);
} }
void OgreBinarySerializer::ReadBoneAssignment(VertexData *dest) void OgreBinarySerializer::ReadBoneAssignment(VertexData *dest) {
{
if (!dest) { if (!dest) {
throw DeadlyImportError("Cannot read bone assignments, vertex data is null."); throw DeadlyImportError("Cannot read bone assignments, vertex data is null.");
} }
@ -408,8 +353,7 @@ void OgreBinarySerializer::ReadBoneAssignment(VertexData *dest)
dest->boneAssignments.push_back(ba); dest->boneAssignments.push_back(ba);
} }
void OgreBinarySerializer::ReadSubMesh(Mesh *mesh) void OgreBinarySerializer::ReadSubMesh(Mesh *mesh) {
{
uint16_t id = 0; uint16_t id = 0;
SubMesh *submesh = new SubMesh(); SubMesh *submesh = new SubMesh();
@ -425,8 +369,7 @@ void OgreBinarySerializer::ReadSubMesh(Mesh *mesh)
ASSIMP_LOG_DEBUG_F(" - Uses shared geometry: ", submesh->usesSharedVertexData ? "true" : "false"); ASSIMP_LOG_DEBUG_F(" - Uses shared geometry: ", submesh->usesSharedVertexData ? "true" : "false");
// Index buffer // Index buffer
if (submesh->indexData->count > 0) if (submesh->indexData->count > 0) {
{
uint32_t numBytes = submesh->indexData->count * (submesh->indexData->is32bit ? sizeof(uint32_t) : sizeof(uint16_t)); uint32_t numBytes = submesh->indexData->count * (submesh->indexData->is32bit ? sizeof(uint32_t) : sizeof(uint16_t));
uint8_t *indexBuffer = ReadBytes(numBytes); uint8_t *indexBuffer = ReadBytes(numBytes);
submesh->indexData->buffer = MemoryStreamPtr(new Assimp::MemoryIOStream(indexBuffer, numBytes, true)); submesh->indexData->buffer = MemoryStreamPtr(new Assimp::MemoryIOStream(indexBuffer, numBytes, true));
@ -437,8 +380,7 @@ void OgreBinarySerializer::ReadSubMesh(Mesh *mesh)
} }
// Vertex buffer if not referencing the shared geometry // Vertex buffer if not referencing the shared geometry
if (!submesh->usesSharedVertexData) if (!submesh->usesSharedVertexData) {
{
id = ReadHeader(); id = ReadHeader();
if (id != M_GEOMETRY) { if (id != M_GEOMETRY) {
throw DeadlyImportError("M_SUBMESH does not contain M_GEOMETRY, but shader geometry is set to false"); throw DeadlyImportError("M_SUBMESH does not contain M_GEOMETRY, but shader geometry is set to false");
@ -449,28 +391,22 @@ void OgreBinarySerializer::ReadSubMesh(Mesh *mesh)
} }
// Bone assignment, submesh operation and texture aliases // Bone assignment, submesh operation and texture aliases
if (!AtEnd()) if (!AtEnd()) {
{
id = ReadHeader(); id = ReadHeader();
while (!AtEnd() && while (!AtEnd() &&
(id == M_SUBMESH_OPERATION || (id == M_SUBMESH_OPERATION ||
id == M_SUBMESH_BONE_ASSIGNMENT || id == M_SUBMESH_BONE_ASSIGNMENT ||
id == M_SUBMESH_TEXTURE_ALIAS)) id == M_SUBMESH_TEXTURE_ALIAS)) {
{ switch (id) {
switch(id) case M_SUBMESH_OPERATION: {
{
case M_SUBMESH_OPERATION:
{
ReadSubMeshOperation(submesh); ReadSubMeshOperation(submesh);
break; break;
} }
case M_SUBMESH_BONE_ASSIGNMENT: case M_SUBMESH_BONE_ASSIGNMENT: {
{
ReadBoneAssignment(submesh->vertexData); ReadBoneAssignment(submesh->vertexData);
break; break;
} }
case M_SUBMESH_TEXTURE_ALIAS: case M_SUBMESH_TEXTURE_ALIAS: {
{
ReadSubMeshTextureAlias(submesh); ReadSubMeshTextureAlias(submesh);
break; break;
} }
@ -489,8 +425,7 @@ void OgreBinarySerializer::ReadSubMesh(Mesh *mesh)
mesh->subMeshes.push_back(submesh); mesh->subMeshes.push_back(submesh);
} }
void OgreBinarySerializer::NormalizeBoneWeights(VertexData *vertexData) const void OgreBinarySerializer::NormalizeBoneWeights(VertexData *vertexData) const {
{
if (!vertexData || vertexData->boneAssignments.empty()) if (!vertexData || vertexData->boneAssignments.empty())
return; return;
@ -503,18 +438,14 @@ void OgreBinarySerializer::NormalizeBoneWeights(VertexData *vertexData) const
Some exporters won't care if the sum of all bone weights Some exporters won't care if the sum of all bone weights
for a single vertex equals 1 or not, so validate here. */ for a single vertex equals 1 or not, so validate here. */
const float epsilon = 0.05f; const float epsilon = 0.05f;
for (const uint32_t vertexIndex : influencedVertices) for (const uint32_t vertexIndex : influencedVertices) {
{
float sum = 0.0f; float sum = 0.0f;
for (VertexBoneAssignmentList::const_iterator baIter=vertexData->boneAssignments.begin(), baEnd=vertexData->boneAssignments.end(); baIter != baEnd; ++baIter) for (VertexBoneAssignmentList::const_iterator baIter = vertexData->boneAssignments.begin(), baEnd = vertexData->boneAssignments.end(); baIter != baEnd; ++baIter) {
{
if (baIter->vertexIndex == vertexIndex) if (baIter->vertexIndex == vertexIndex)
sum += baIter->weight; sum += baIter->weight;
} }
if ((sum < (1.0f - epsilon)) || (sum > (1.0f + epsilon))) if ((sum < (1.0f - epsilon)) || (sum > (1.0f + epsilon))) {
{ for (auto &boneAssign : vertexData->boneAssignments) {
for (auto &boneAssign : vertexData->boneAssignments)
{
if (boneAssign.vertexIndex == vertexIndex) if (boneAssign.vertexIndex == vertexIndex)
boneAssign.weight /= sum; boneAssign.weight /= sum;
} }
@ -522,26 +453,21 @@ void OgreBinarySerializer::NormalizeBoneWeights(VertexData *vertexData) const
} }
} }
void OgreBinarySerializer::ReadSubMeshOperation(SubMesh *submesh) void OgreBinarySerializer::ReadSubMeshOperation(SubMesh *submesh) {
{
submesh->operationType = static_cast<SubMesh::OperationType>(Read<uint16_t>()); submesh->operationType = static_cast<SubMesh::OperationType>(Read<uint16_t>());
} }
void OgreBinarySerializer::ReadSubMeshTextureAlias(SubMesh *submesh) void OgreBinarySerializer::ReadSubMeshTextureAlias(SubMesh *submesh) {
{
submesh->textureAliasName = ReadLine(); submesh->textureAliasName = ReadLine();
submesh->textureAliasRef = ReadLine(); submesh->textureAliasRef = ReadLine();
} }
void OgreBinarySerializer::ReadSubMeshNames(Mesh *mesh) void OgreBinarySerializer::ReadSubMeshNames(Mesh *mesh) {
{
uint16_t id = 0; uint16_t id = 0;
if (!AtEnd()) if (!AtEnd()) {
{
id = ReadHeader(); id = ReadHeader();
while (!AtEnd() && id == M_SUBMESH_NAME_TABLE_ELEMENT) while (!AtEnd() && id == M_SUBMESH_NAME_TABLE_ELEMENT) {
{
uint16_t submeshIndex = Read<uint16_t>(); uint16_t submeshIndex = Read<uint16_t>();
SubMesh *submesh = mesh->GetSubMesh(submeshIndex); SubMesh *submesh = mesh->GetSubMesh(submeshIndex);
if (!submesh) { if (!submesh) {
@ -559,28 +485,22 @@ void OgreBinarySerializer::ReadSubMeshNames(Mesh *mesh)
} }
} }
void OgreBinarySerializer::ReadGeometry(VertexData *dest) void OgreBinarySerializer::ReadGeometry(VertexData *dest) {
{
dest->count = Read<uint32_t>(); dest->count = Read<uint32_t>();
ASSIMP_LOG_DEBUG_F(" - Reading geometry of ", dest->count, " vertices"); ASSIMP_LOG_DEBUG_F(" - Reading geometry of ", dest->count, " vertices");
if (!AtEnd()) if (!AtEnd()) {
{
uint16_t id = ReadHeader(); uint16_t id = ReadHeader();
while (!AtEnd() && while (!AtEnd() &&
(id == M_GEOMETRY_VERTEX_DECLARATION || (id == M_GEOMETRY_VERTEX_DECLARATION ||
id == M_GEOMETRY_VERTEX_BUFFER)) id == M_GEOMETRY_VERTEX_BUFFER)) {
{ switch (id) {
switch(id) case M_GEOMETRY_VERTEX_DECLARATION: {
{
case M_GEOMETRY_VERTEX_DECLARATION:
{
ReadGeometryVertexDeclaration(dest); ReadGeometryVertexDeclaration(dest);
break; break;
} }
case M_GEOMETRY_VERTEX_BUFFER: case M_GEOMETRY_VERTEX_BUFFER: {
{
ReadGeometryVertexBuffer(dest); ReadGeometryVertexBuffer(dest);
break; break;
} }
@ -594,13 +514,10 @@ void OgreBinarySerializer::ReadGeometry(VertexData *dest)
} }
} }
void OgreBinarySerializer::ReadGeometryVertexDeclaration(VertexData *dest) void OgreBinarySerializer::ReadGeometryVertexDeclaration(VertexData *dest) {
{ if (!AtEnd()) {
if (!AtEnd())
{
uint16_t id = ReadHeader(); uint16_t id = ReadHeader();
while (!AtEnd() && id == M_GEOMETRY_VERTEX_ELEMENT) while (!AtEnd() && id == M_GEOMETRY_VERTEX_ELEMENT) {
{
ReadGeometryVertexElement(dest); ReadGeometryVertexElement(dest);
if (!AtEnd()) if (!AtEnd())
@ -611,8 +528,7 @@ void OgreBinarySerializer::ReadGeometryVertexDeclaration(VertexData *dest)
} }
} }
void OgreBinarySerializer::ReadGeometryVertexElement(VertexData *dest) void OgreBinarySerializer::ReadGeometryVertexElement(VertexData *dest) {
{
VertexElement element; VertexElement element;
element.source = Read<uint16_t>(); element.source = Read<uint16_t>();
element.type = static_cast<VertexElement::Type>(Read<uint16_t>()); element.type = static_cast<VertexElement::Type>(Read<uint16_t>());
@ -626,8 +542,7 @@ void OgreBinarySerializer::ReadGeometryVertexElement(VertexData *dest)
dest->vertexElements.push_back(element); dest->vertexElements.push_back(element);
} }
void OgreBinarySerializer::ReadGeometryVertexBuffer(VertexData *dest) void OgreBinarySerializer::ReadGeometryVertexBuffer(VertexData *dest) {
{
uint16_t bindIndex = Read<uint16_t>(); uint16_t bindIndex = Read<uint16_t>();
uint16_t vertexSize = Read<uint16_t>(); uint16_t vertexSize = Read<uint16_t>();
@ -645,20 +560,16 @@ void OgreBinarySerializer::ReadGeometryVertexBuffer(VertexData *dest)
ASSIMP_LOG_DEBUG_F(" - Read vertex buffer for source ", bindIndex, " of ", numBytes, " bytes"); ASSIMP_LOG_DEBUG_F(" - 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.
if (!AtEnd()) if (!AtEnd()) {
{
uint16_t id = ReadHeader(); uint16_t id = ReadHeader();
while (!AtEnd() && id == M_EDGE_LIST_LOD) while (!AtEnd() && id == M_EDGE_LIST_LOD) {
{
m_reader->IncPtr(sizeof(uint16_t)); // lod index m_reader->IncPtr(sizeof(uint16_t)); // lod index
bool manual = Read<bool>(); bool manual = Read<bool>();
if (!manual) if (!manual) {
{
m_reader->IncPtr(sizeof(uint8_t)); m_reader->IncPtr(sizeof(uint8_t));
uint32_t numTriangles = Read<uint32_t>(); uint32_t numTriangles = Read<uint32_t>();
uint32_t numEdgeGroups = Read<uint32_t>(); uint32_t numEdgeGroups = Read<uint32_t>();
@ -666,16 +577,14 @@ void OgreBinarySerializer::ReadEdgeList(Mesh * /*mesh*/)
size_t skipBytes = (sizeof(uint32_t) * 8 + sizeof(float) * 4) * numTriangles; size_t skipBytes = (sizeof(uint32_t) * 8 + sizeof(float) * 4) * numTriangles;
m_reader->IncPtr(skipBytes); m_reader->IncPtr(skipBytes);
for (size_t i=0; i<numEdgeGroups; ++i) for (size_t i = 0; i < numEdgeGroups; ++i) {
{ uint16_t curId = ReadHeader();
uint16_t id = ReadHeader(); if (curId != M_EDGE_GROUP)
if (id != M_EDGE_GROUP)
throw DeadlyImportError("M_EDGE_GROUP not found in M_EDGE_LIST_LOD"); throw DeadlyImportError("M_EDGE_GROUP not found in M_EDGE_LIST_LOD");
m_reader->IncPtr(sizeof(uint32_t) * 3); m_reader->IncPtr(sizeof(uint32_t) * 3);
uint32_t numEdges = Read<uint32_t>(); uint32_t numEdges = Read<uint32_t>();
for (size_t j=0; j<numEdges; ++j) for (size_t j = 0; j < numEdges; ++j) {
{
m_reader->IncPtr(sizeof(uint32_t) * 6 + sizeof(uint8_t)); m_reader->IncPtr(sizeof(uint32_t) * 6 + sizeof(uint8_t));
} }
} }
@ -689,13 +598,10 @@ void OgreBinarySerializer::ReadEdgeList(Mesh * /*mesh*/)
} }
} }
void OgreBinarySerializer::ReadPoses(Mesh *mesh) void OgreBinarySerializer::ReadPoses(Mesh *mesh) {
{ if (!AtEnd()) {
if (!AtEnd())
{
uint16_t id = ReadHeader(); uint16_t id = ReadHeader();
while (!AtEnd() && id == M_POSE) while (!AtEnd() && id == M_POSE) {
{
Pose *pose = new Pose(); Pose *pose = new Pose();
pose->name = ReadLine(); pose->name = ReadLine();
pose->target = Read<uint16_t>(); pose->target = Read<uint16_t>();
@ -713,13 +619,10 @@ void OgreBinarySerializer::ReadPoses(Mesh *mesh)
} }
} }
void OgreBinarySerializer::ReadPoseVertices(Pose *pose) void OgreBinarySerializer::ReadPoseVertices(Pose *pose) {
{ if (!AtEnd()) {
if (!AtEnd())
{
uint16_t id = ReadHeader(); uint16_t id = ReadHeader();
while (!AtEnd() && id == M_POSE_VERTEX) while (!AtEnd() && id == M_POSE_VERTEX) {
{
Pose::Vertex v; Pose::Vertex v;
v.index = Read<uint32_t>(); v.index = Read<uint32_t>();
ReadVector(v.offset); ReadVector(v.offset);
@ -736,13 +639,10 @@ void OgreBinarySerializer::ReadPoseVertices(Pose *pose)
} }
} }
void OgreBinarySerializer::ReadAnimations(Mesh *mesh) void OgreBinarySerializer::ReadAnimations(Mesh *mesh) {
{ if (!AtEnd()) {
if (!AtEnd())
{
uint16_t id = ReadHeader(); uint16_t id = ReadHeader();
while (!AtEnd() && id == M_ANIMATION) while (!AtEnd() && id == M_ANIMATION) {
{
Animation *anim = new Animation(mesh); Animation *anim = new Animation(mesh);
anim->name = ReadLine(); anim->name = ReadLine();
anim->length = Read<float>(); anim->length = Read<float>();
@ -759,13 +659,10 @@ void OgreBinarySerializer::ReadAnimations(Mesh *mesh)
} }
} }
void OgreBinarySerializer::ReadAnimation(Animation *anim) void OgreBinarySerializer::ReadAnimation(Animation *anim) {
{ if (!AtEnd()) {
if (!AtEnd())
{
uint16_t id = ReadHeader(); uint16_t id = ReadHeader();
if (id == M_ANIMATION_BASEINFO) if (id == M_ANIMATION_BASEINFO) {
{
anim->baseName = ReadLine(); anim->baseName = ReadLine();
anim->baseTime = Read<float>(); anim->baseTime = Read<float>();
@ -773,8 +670,7 @@ void OgreBinarySerializer::ReadAnimation(Animation *anim)
id = ReadHeader(); id = ReadHeader();
} }
while (!AtEnd() && id == M_ANIMATION_TRACK) while (!AtEnd() && id == M_ANIMATION_TRACK) {
{
VertexAnimationTrack track; VertexAnimationTrack track;
track.type = static_cast<VertexAnimationTrack::Type>(Read<uint16_t>()); track.type = static_cast<VertexAnimationTrack::Type>(Read<uint16_t>());
track.target = Read<uint16_t>(); track.target = Read<uint16_t>();
@ -791,17 +687,13 @@ void OgreBinarySerializer::ReadAnimation(Animation *anim)
} }
} }
void OgreBinarySerializer::ReadAnimationKeyFrames(Animation *anim, VertexAnimationTrack *track) void OgreBinarySerializer::ReadAnimationKeyFrames(Animation *anim, VertexAnimationTrack *track) {
{ if (!AtEnd()) {
if (!AtEnd())
{
uint16_t id = ReadHeader(); uint16_t id = ReadHeader();
while (!AtEnd() && while (!AtEnd() &&
(id == M_ANIMATION_MORPH_KEYFRAME || (id == M_ANIMATION_MORPH_KEYFRAME ||
id == M_ANIMATION_POSE_KEYFRAME)) id == M_ANIMATION_POSE_KEYFRAME)) {
{ if (id == M_ANIMATION_MORPH_KEYFRAME) {
if (id == M_ANIMATION_MORPH_KEYFRAME)
{
MorphKeyFrame kf; MorphKeyFrame kf;
kf.timePos = Read<float>(); kf.timePos = Read<float>();
bool hasNormals = Read<bool>(); bool hasNormals = Read<bool>();
@ -814,17 +706,13 @@ void OgreBinarySerializer::ReadAnimationKeyFrames(Animation *anim, VertexAnimati
kf.buffer = MemoryStreamPtr(new Assimp::MemoryIOStream(morphBuffer, numBytes, true)); kf.buffer = MemoryStreamPtr(new Assimp::MemoryIOStream(morphBuffer, numBytes, true));
track->morphKeyFrames.push_back(kf); track->morphKeyFrames.push_back(kf);
} } else if (id == M_ANIMATION_POSE_KEYFRAME) {
else if (id == M_ANIMATION_POSE_KEYFRAME)
{
PoseKeyFrame kf; PoseKeyFrame kf;
kf.timePos = Read<float>(); kf.timePos = Read<float>();
if (!AtEnd()) if (!AtEnd()) {
{
id = ReadHeader(); id = ReadHeader();
while (!AtEnd() && id == M_ANIMATION_POSE_REF) while (!AtEnd() && id == M_ANIMATION_POSE_REF) {
{
PoseRef pr; PoseRef pr;
pr.index = Read<uint16_t>(); pr.index = Read<uint16_t>();
pr.influence = Read<float>(); pr.influence = Read<float>();
@ -850,15 +738,13 @@ void OgreBinarySerializer::ReadAnimationKeyFrames(Animation *anim, VertexAnimati
// Skeleton // Skeleton
bool OgreBinarySerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, Mesh *mesh) bool OgreBinarySerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, Mesh *mesh) {
{
if (!mesh || mesh->skeletonRef.empty()) if (!mesh || mesh->skeletonRef.empty())
return false; return false;
// Highly unusual to see in read world cases but support // Highly unusual to see in read world cases but support
// binary mesh referencing a XML skeleton file. // binary mesh referencing a XML skeleton file.
if (EndsWith(mesh->skeletonRef, ".skeleton.xml", false)) if (EndsWith(mesh->skeletonRef, ".skeleton.xml", false)) {
{
OgreXmlSerializer::ImportSkeleton(pIOHandler, mesh); OgreXmlSerializer::ImportSkeleton(pIOHandler, mesh);
return false; return false;
} }
@ -874,8 +760,7 @@ bool OgreBinarySerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, Mesh *me
return true; return true;
} }
bool OgreBinarySerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml *mesh) bool OgreBinarySerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml *mesh) {
{
if (!mesh || mesh->skeletonRef.empty()) if (!mesh || mesh->skeletonRef.empty())
return false; return false;
@ -890,16 +775,13 @@ bool OgreBinarySerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml
return true; return true;
} }
MemoryStreamReaderPtr OgreBinarySerializer::OpenReader(Assimp::IOSystem *pIOHandler, const std::string &filename) MemoryStreamReaderPtr OgreBinarySerializer::OpenReader(Assimp::IOSystem *pIOHandler, const std::string &filename) {
{ if (!EndsWith(filename, ".skeleton", false)) {
if (!EndsWith(filename, ".skeleton", false))
{
ASSIMP_LOG_ERROR_F("Imported Mesh is referencing to unsupported '", filename, "' skeleton file."); ASSIMP_LOG_ERROR_F("Imported Mesh is referencing to unsupported '", filename, "' skeleton file.");
return MemoryStreamReaderPtr(); return MemoryStreamReaderPtr();
} }
if (!pIOHandler->Exists(filename)) if (!pIOHandler->Exists(filename)) {
{
ASSIMP_LOG_ERROR_F("Failed to find skeleton file '", filename, "' that is referenced by imported Mesh."); ASSIMP_LOG_ERROR_F("Failed to find skeleton file '", filename, "' that is referenced by imported Mesh.");
return MemoryStreamReaderPtr(); return MemoryStreamReaderPtr();
} }
@ -912,8 +794,7 @@ MemoryStreamReaderPtr OgreBinarySerializer::OpenReader(Assimp::IOSystem *pIOHand
return MemoryStreamReaderPtr(new MemoryStreamReader(f)); return MemoryStreamReaderPtr(new MemoryStreamReader(f));
} }
void OgreBinarySerializer::ReadSkeleton(Skeleton *skeleton) void OgreBinarySerializer::ReadSkeleton(Skeleton *skeleton) {
{
uint16_t id = ReadHeader(false); uint16_t id = ReadHeader(false);
if (id != HEADER_CHUNK_ID) { if (id != HEADER_CHUNK_ID) {
throw DeadlyExportError("Invalid Ogre Skeleton file header."); throw DeadlyExportError("Invalid Ogre Skeleton file header.");
@ -921,8 +802,7 @@ void OgreBinarySerializer::ReadSkeleton(Skeleton *skeleton)
// This deserialization supports both versions of the skeleton spec // This deserialization supports both versions of the skeleton spec
std::string version = ReadLine(); std::string version = ReadLine();
if (version != SKELETON_VERSION_1_8 && version != SKELETON_VERSION_1_1) if (version != SKELETON_VERSION_1_8 && version != SKELETON_VERSION_1_1) {
{
throw DeadlyExportError(Formatter::format() << "Skeleton version " << version << " not supported by this importer." throw DeadlyExportError(Formatter::format() << "Skeleton version " << version << " not supported by this importer."
<< " Supported versions: " << SKELETON_VERSION_1_8 << " and " << SKELETON_VERSION_1_1); << " Supported versions: " << SKELETON_VERSION_1_8 << " and " << SKELETON_VERSION_1_1);
} }
@ -932,20 +812,15 @@ void OgreBinarySerializer::ReadSkeleton(Skeleton *skeleton)
bool firstBone = true; bool firstBone = true;
bool firstAnim = true; bool firstAnim = true;
while (!AtEnd()) while (!AtEnd()) {
{
id = ReadHeader(); id = ReadHeader();
switch(id) switch (id) {
{ case SKELETON_BLENDMODE: {
case SKELETON_BLENDMODE:
{
skeleton->blendMode = static_cast<Skeleton::BlendMode>(Read<uint16_t>()); skeleton->blendMode = static_cast<Skeleton::BlendMode>(Read<uint16_t>());
break; break;
} }
case SKELETON_BONE: case SKELETON_BONE: {
{ if (firstBone) {
if (firstBone)
{
ASSIMP_LOG_DEBUG(" - Bones"); ASSIMP_LOG_DEBUG(" - Bones");
firstBone = false; firstBone = false;
} }
@ -953,15 +828,12 @@ void OgreBinarySerializer::ReadSkeleton(Skeleton *skeleton)
ReadBone(skeleton); ReadBone(skeleton);
break; break;
} }
case SKELETON_BONE_PARENT: case SKELETON_BONE_PARENT: {
{
ReadBoneParent(skeleton); ReadBoneParent(skeleton);
break; break;
} }
case SKELETON_ANIMATION: case SKELETON_ANIMATION: {
{ if (firstAnim) {
if (firstAnim)
{
ASSIMP_LOG_DEBUG(" - Animations"); ASSIMP_LOG_DEBUG(" - Animations");
firstAnim = false; firstAnim = false;
} }
@ -969,8 +841,7 @@ void OgreBinarySerializer::ReadSkeleton(Skeleton *skeleton)
ReadSkeletonAnimation(skeleton); ReadSkeletonAnimation(skeleton);
break; break;
} }
case SKELETON_ANIMATION_LINK: case SKELETON_ANIMATION_LINK: {
{
ReadSkeletonAnimationLink(skeleton); ReadSkeletonAnimationLink(skeleton);
break; break;
} }
@ -978,16 +849,14 @@ void OgreBinarySerializer::ReadSkeleton(Skeleton *skeleton)
} }
// Calculate bone matrices for root bones. Recursively calculates their children. // Calculate bone matrices for root bones. Recursively calculates their children.
for (size_t i=0, len=skeleton->bones.size(); i<len; ++i) for (size_t i = 0, len = skeleton->bones.size(); i < len; ++i) {
{
Bone *bone = skeleton->bones[i]; Bone *bone = skeleton->bones[i];
if (!bone->IsParented()) if (!bone->IsParented())
bone->CalculateWorldMatrixAndDefaultPose(skeleton); bone->CalculateWorldMatrixAndDefaultPose(skeleton);
} }
} }
void OgreBinarySerializer::ReadBone(Skeleton *skeleton) void OgreBinarySerializer::ReadBone(Skeleton *skeleton) {
{
Bone *bone = new Bone(); Bone *bone = new Bone();
bone->name = ReadLine(); bone->name = ReadLine();
bone->id = Read<uint16_t>(); bone->id = Read<uint16_t>();
@ -1010,8 +879,7 @@ void OgreBinarySerializer::ReadBone(Skeleton *skeleton)
skeleton->bones.push_back(bone); skeleton->bones.push_back(bone);
} }
void OgreBinarySerializer::ReadBoneParent(Skeleton *skeleton) void OgreBinarySerializer::ReadBoneParent(Skeleton *skeleton) {
{
uint16_t childId = Read<uint16_t>(); uint16_t childId = Read<uint16_t>();
uint16_t parentId = Read<uint16_t>(); uint16_t parentId = Read<uint16_t>();
@ -1024,17 +892,14 @@ void OgreBinarySerializer::ReadBoneParent(Skeleton *skeleton)
throw DeadlyImportError(Formatter::format() << "Failed to find bones for parenting: Child id " << childId << " for parent id " << parentId); throw DeadlyImportError(Formatter::format() << "Failed to find bones for parenting: Child id " << childId << " for parent id " << parentId);
} }
void OgreBinarySerializer::ReadSkeletonAnimation(Skeleton *skeleton) void OgreBinarySerializer::ReadSkeletonAnimation(Skeleton *skeleton) {
{
Animation *anim = new Animation(skeleton); Animation *anim = new Animation(skeleton);
anim->name = ReadLine(); anim->name = ReadLine();
anim->length = Read<float>(); anim->length = Read<float>();
if (!AtEnd()) if (!AtEnd()) {
{
uint16_t id = ReadHeader(); uint16_t id = ReadHeader();
if (id == SKELETON_ANIMATION_BASEINFO) if (id == SKELETON_ANIMATION_BASEINFO) {
{
anim->baseName = ReadLine(); anim->baseName = ReadLine();
anim->baseTime = Read<float>(); anim->baseTime = Read<float>();
@ -1042,8 +907,7 @@ void OgreBinarySerializer::ReadSkeletonAnimation(Skeleton *skeleton)
id = ReadHeader(); id = ReadHeader();
} }
while (!AtEnd() && id == SKELETON_ANIMATION_TRACK) while (!AtEnd() && id == SKELETON_ANIMATION_TRACK) {
{
ReadSkeletonAnimationTrack(skeleton, anim); ReadSkeletonAnimationTrack(skeleton, anim);
if (!AtEnd()) if (!AtEnd())
@ -1058,8 +922,7 @@ void OgreBinarySerializer::ReadSkeletonAnimation(Skeleton *skeleton)
ASSIMP_LOG_DEBUG_F(" ", anim->name, " (", anim->length, " sec, ", anim->tracks.size(), " tracks)"); ASSIMP_LOG_DEBUG_F(" ", 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);
if (!bone) { if (!bone) {
@ -1071,8 +934,7 @@ void OgreBinarySerializer::ReadSkeletonAnimationTrack(Skeleton * /*skeleton*/, A
track.boneName = bone->name; track.boneName = bone->name;
uint16_t id = ReadHeader(); uint16_t id = ReadHeader();
while (!AtEnd() && id == SKELETON_ANIMATION_TRACK_KEYFRAME) while (!AtEnd() && id == SKELETON_ANIMATION_TRACK_KEYFRAME) {
{
ReadSkeletonAnimationKeyFrame(&track); ReadSkeletonAnimationKeyFrame(&track);
if (!AtEnd()) if (!AtEnd())
@ -1084,8 +946,7 @@ void OgreBinarySerializer::ReadSkeletonAnimationTrack(Skeleton * /*skeleton*/, A
dest->tracks.push_back(track); dest->tracks.push_back(track);
} }
void OgreBinarySerializer::ReadSkeletonAnimationKeyFrame(VertexAnimationTrack *dest) void OgreBinarySerializer::ReadSkeletonAnimationKeyFrame(VertexAnimationTrack *dest) {
{
TransformKeyFrame keyframe; TransformKeyFrame keyframe;
keyframe.timePos = Read<float>(); keyframe.timePos = Read<float>();
@ -1100,14 +961,13 @@ 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
SkipBytes(sizeof(float) * 3); // scale SkipBytes(sizeof(float) * 3); // scale
} }
} // Ogre } // namespace Ogre
} // Assimp } // namespace Assimp
#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER #endif // ASSIMP_BUILD_NO_OGRE_IMPORTER

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,

View File

@ -206,8 +206,8 @@ aiMaterial* OgreImporter::ReadMaterial(const std::string &pFile, Assimp::IOSyste
aiMaterial *material = new aiMaterial(); aiMaterial *material = new aiMaterial();
m_textures.clear(); m_textures.clear();
aiString ts(materialName); aiString matName(materialName);
material->AddProperty(&ts, AI_MATKEY_NAME); material->AddProperty(&matName, AI_MATKEY_NAME);
// The stringstream will push words from a line until newline. // The stringstream will push words from a line until newline.
// It will also trim whitespace from line start and between words. // It will also trim whitespace from line start and between words.
@ -279,14 +279,14 @@ aiMaterial* OgreImporter::ReadMaterial(const std::string &pFile, Assimp::IOSyste
else if (linePart=="$colormap") else if (linePart=="$colormap")
{ {
ss >> linePart; ss >> linePart;
aiString ts(linePart); aiString cm(linePart);
material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0)); material->AddProperty(&cm, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0));
} }
else if (linePart=="$normalmap") else if (linePart=="$normalmap")
{ {
ss >> linePart; ss >> linePart;
aiString ts(linePart); aiString nm(linePart);
material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0)); material->AddProperty(&nm, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0));
} }
else if (linePart=="$shininess_strength") else if (linePart=="$shininess_strength")
{ {

View File

@ -46,26 +46,25 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER #ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
#include <assimp/ParsingUtils.h> #include <assimp/ParsingUtils.h>
#include <functional>
#include <algorithm>
#include <stdint.h> #include <stdint.h>
#include <sstream> #include <algorithm>
#include <cctype> #include <cctype>
#include <functional>
#include <sstream>
namespace Assimp { namespace Assimp {
namespace Ogre { namespace Ogre {
/// Returns a lower cased copy of @s. /// Returns a lower cased copy of @s.
static AI_FORCE_INLINE static AI_FORCE_INLINE std::string ToLower(const std::string &s) {
std::string ToLower(std::string s) std::string lower(s);
{ std::transform(lower.begin(), lower.end(), lower.begin(), Assimp::ToLower<char>);
std::transform(s.begin(), s.end(), s.begin(), ::tolower);
return s; return lower;
} }
/// Returns if @c s ends with @c suffix. If @c caseSensitive is false, both strings will be lower cased before matching. /// Returns if @c s ends with @c suffix. If @c caseSensitive is false, both strings will be lower cased before matching.
static AI_FORCE_INLINE static AI_FORCE_INLINE bool EndsWith( const std::string &s, const std::string &suffix, bool caseSensitive = true) {
bool EndsWith(const std::string &s, const std::string &suffix, bool caseSensitive = true) {
if (s.empty() || suffix.empty()) { if (s.empty() || suffix.empty()) {
return false; return false;
} else if (s.length() < suffix.length()) { } else if (s.length() < suffix.length()) {
@ -86,7 +85,8 @@ bool EndsWith(const std::string &s, const std::string &suffix, bool caseSensitiv
/// Trim from start /// Trim from start
static AI_FORCE_INLINE static AI_FORCE_INLINE
std::string &TrimLeft(std::string &s, bool newlines = true) { std::string &
TrimLeft(std::string &s, bool newlines = true) {
if (!newlines) { if (!newlines) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](char c) { return !Assimp::IsSpace<char>(c); })); s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](char c) { return !Assimp::IsSpace<char>(c); }));
} else { } else {
@ -97,7 +97,8 @@ std::string &TrimLeft(std::string &s, bool newlines = true) {
/// Trim from end /// Trim from end
static AI_FORCE_INLINE static AI_FORCE_INLINE
std::string &TrimRight(std::string &s, bool newlines = true) { std::string &
TrimRight(std::string &s, bool newlines = true) {
if (!newlines) { if (!newlines) {
s.erase(std::find_if(s.rbegin(), s.rend(), [](char c) { return !Assimp::IsSpace<char>(c); }).base(), s.end()); s.erase(std::find_if(s.rbegin(), s.rend(), [](char c) { return !Assimp::IsSpace<char>(c); }).base(), s.end());
} else { } else {
@ -108,13 +109,15 @@ std::string &TrimRight(std::string &s, bool newlines = true) {
/// Trim from both ends /// Trim from both ends
static AI_FORCE_INLINE static AI_FORCE_INLINE
std::string &Trim(std::string &s, bool newlines = true) { std::string &
Trim(std::string &s, bool newlines = true) {
return TrimLeft(TrimRight(s, newlines), newlines); return TrimLeft(TrimRight(s, newlines), newlines);
} }
/// Skips a line from current @ss position until a newline. Returns the skipped part. /// Skips a line from current @ss position until a newline. Returns the skipped part.
static AI_FORCE_INLINE static AI_FORCE_INLINE
std::string SkipLine(std::stringstream &ss) { std::string
SkipLine(std::stringstream &ss) {
std::string skipped; std::string skipped;
getline(ss, skipped); getline(ss, skipped);
return skipped; return skipped;
@ -123,14 +126,15 @@ std::string SkipLine(std::stringstream &ss) {
/// Skips a line and reads next element from @c ss to @c nextElement. /// Skips a line and reads next element from @c ss to @c nextElement.
/** @return Skipped line content until newline. */ /** @return Skipped line content until newline. */
static AI_FORCE_INLINE static AI_FORCE_INLINE
std::string NextAfterNewLine(std::stringstream &ss, std::string &nextElement) { std::string
NextAfterNewLine(std::stringstream &ss, std::string &nextElement) {
std::string skipped = SkipLine(ss); std::string skipped = SkipLine(ss);
ss >> nextElement; ss >> nextElement;
return skipped; return skipped;
} }
} // Ogre } // namespace Ogre
} // Assimp } // namespace Assimp
#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER #endif // ASSIMP_BUILD_NO_OGRE_IMPORTER
#endif // AI_OGREPARSINGUTILS_H_INC #endif // AI_OGREPARSINGUTILS_H_INC

View File

@ -53,140 +53,94 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Define as 1 to get verbose logging. // Define as 1 to get verbose logging.
#define OGRE_XML_SERIALIZER_DEBUG 0 #define OGRE_XML_SERIALIZER_DEBUG 0
namespace Assimp namespace Assimp {
{ namespace Ogre {
namespace Ogre
{
AI_WONT_RETURN void ThrowAttibuteError(const XmlReader *reader, const std::string &name, const std::string &error = "") AI_WONT_RETURN_SUFFIX; AI_WONT_RETURN void ThrowAttibuteError(const XmlReader *reader, const std::string &name, const std::string &error = "") AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void ThrowAttibuteError(const XmlReader* reader, const std::string &name, const std::string &error) AI_WONT_RETURN void ThrowAttibuteError(const XmlReader *reader, const std::string &name, const std::string &error) {
{ if (!error.empty()) {
if (!error.empty())
{
throw DeadlyImportError(error + " in node '" + std::string(reader->getNodeName()) + "' and attribute '" + name + "'"); throw DeadlyImportError(error + " in node '" + std::string(reader->getNodeName()) + "' and attribute '" + name + "'");
} } else {
else
{
throw DeadlyImportError("Attribute '" + name + "' does not exist in node '" + std::string(reader->getNodeName()) + "'"); throw DeadlyImportError("Attribute '" + name + "' does not exist in node '" + std::string(reader->getNodeName()) + "'");
} }
} }
template <> template <>
int32_t OgreXmlSerializer::ReadAttribute<int32_t>(const char *name) const int32_t OgreXmlSerializer::ReadAttribute<int32_t>(const char *name) const {
{ if (!HasAttribute(name)) {
if (HasAttribute(name)) ThrowAttibuteError(m_reader, name);
{ }
return static_cast<int32_t>(m_reader->getAttributeValueAsInt(name)); return static_cast<int32_t>(m_reader->getAttributeValueAsInt(name));
} }
else
{
ThrowAttibuteError(m_reader, name);
return 0;
}
}
template <> template <>
uint32_t OgreXmlSerializer::ReadAttribute<uint32_t>(const char *name) const uint32_t OgreXmlSerializer::ReadAttribute<uint32_t>(const char *name) const {
{ if (!HasAttribute(name)) {
if (HasAttribute(name)) ThrowAttibuteError(m_reader, name);
{
/** @note This is hackish. But we are never expecting unsigned values that go outside the
int32_t range. Just monitor for negative numbers and kill the import. */
int32_t temp = ReadAttribute<int32_t>(name);
if (temp >= 0)
{
return static_cast<uint32_t>(temp);
} }
else // @note This is hackish. But we are never expecting unsigned values that go outside the
{ // int32_t range. Just monitor for negative numbers and kill the import.
int32_t temp = ReadAttribute<int32_t>(name);
if (temp < 0) {
ThrowAttibuteError(m_reader, name, "Found a negative number value where expecting a uint32_t value"); ThrowAttibuteError(m_reader, name, "Found a negative number value where expecting a uint32_t value");
} }
}
else return static_cast<uint32_t>(temp);
{
ThrowAttibuteError(m_reader, name);
}
return 0;
} }
template <> template <>
uint16_t OgreXmlSerializer::ReadAttribute<uint16_t>(const char *name) const uint16_t OgreXmlSerializer::ReadAttribute<uint16_t>(const char *name) const {
{ if (!HasAttribute(name)) {
if (HasAttribute(name)) ThrowAttibuteError(m_reader, name);
{ }
return static_cast<uint16_t>(ReadAttribute<uint32_t>(name)); return static_cast<uint16_t>(ReadAttribute<uint32_t>(name));
} }
else
{
ThrowAttibuteError(m_reader, name);
}
return 0;
}
template <> template <>
float OgreXmlSerializer::ReadAttribute<float>(const char *name) const float OgreXmlSerializer::ReadAttribute<float>(const char *name) const {
{ if (!HasAttribute(name)) {
if (HasAttribute(name)) ThrowAttibuteError(m_reader, name);
{ }
return m_reader->getAttributeValueAsFloat(name); return m_reader->getAttributeValueAsFloat(name);
} }
else
{
ThrowAttibuteError(m_reader, name);
return 0;
}
}
template <> template <>
std::string OgreXmlSerializer::ReadAttribute<std::string>(const char *name) const std::string OgreXmlSerializer::ReadAttribute<std::string>(const char *name) const {
{
const char *value = m_reader->getAttributeValue(name); const char *value = m_reader->getAttributeValue(name);
if (value) if (nullptr == value) {
{ ThrowAttibuteError(m_reader, name);
}
return std::string(value); return std::string(value);
} }
else
{
ThrowAttibuteError(m_reader, name);
return "";
}
}
template <> template <>
bool OgreXmlSerializer::ReadAttribute<bool>(const char *name) const bool OgreXmlSerializer::ReadAttribute<bool>(const char *name) const {
{
std::string value = Ogre::ToLower(ReadAttribute<std::string>(name)); std::string value = Ogre::ToLower(ReadAttribute<std::string>(name));
if (ASSIMP_stricmp(value, "true") == 0) if (ASSIMP_stricmp(value, "true") == 0) {
{
return true; return true;
} } else if (ASSIMP_stricmp(value, "false") == 0) {
else if (ASSIMP_stricmp(value, "false") == 0)
{
return false; return false;
} } else {
else
{
ThrowAttibuteError(m_reader, name, "Boolean value is expected to be 'true' or 'false', encountered '" + value + "'"); ThrowAttibuteError(m_reader, name, "Boolean value is expected to be 'true' or 'false', encountered '" + value + "'");
return false; return false;
} }
} }
bool OgreXmlSerializer::HasAttribute(const char *name) const bool OgreXmlSerializer::HasAttribute(const char *name) const {
{
return (m_reader->getAttributeValue(name) != 0); return (m_reader->getAttributeValue(name) != 0);
} }
std::string &OgreXmlSerializer::NextNode() std::string &OgreXmlSerializer::NextNode() {
{ do {
do if (!m_reader->read()) {
{
if (!m_reader->read())
{
m_currentNodeName = ""; m_currentNodeName = "";
return m_currentNodeName; return m_currentNodeName;
} }
} } while (m_reader->getNodeType() != irr::io::EXN_ELEMENT);
while(m_reader->getNodeType() != irr::io::EXN_ELEMENT);
CurrentNodeName(true); CurrentNodeName(true);
#if (OGRE_XML_SERIALIZER_DEBUG == 1) #if (OGRE_XML_SERIALIZER_DEBUG == 1)
@ -195,20 +149,17 @@ std::string &OgreXmlSerializer::NextNode()
return m_currentNodeName; return m_currentNodeName;
} }
bool OgreXmlSerializer::CurrentNodeNameEquals(const std::string &name) const bool OgreXmlSerializer::CurrentNodeNameEquals(const std::string &name) const {
{
return (ASSIMP_stricmp(m_currentNodeName, name) == 0); return (ASSIMP_stricmp(m_currentNodeName, name) == 0);
} }
std::string OgreXmlSerializer::CurrentNodeName(bool forceRead) std::string OgreXmlSerializer::CurrentNodeName(bool forceRead) {
{
if (forceRead) if (forceRead)
m_currentNodeName = std::string(m_reader->getNodeName()); m_currentNodeName = std::string(m_reader->getNodeName());
return m_currentNodeName; return m_currentNodeName;
} }
std::string &OgreXmlSerializer::SkipCurrentNode() std::string &OgreXmlSerializer::SkipCurrentNode() {
{
#if (OGRE_XML_SERIALIZER_DEBUG == 1) #if (OGRE_XML_SERIALIZER_DEBUG == 1)
ASSIMP_LOG_DEBUG("Skipping node <" + m_currentNodeName + ">"); ASSIMP_LOG_DEBUG("Skipping node <" + m_currentNodeName + ">");
#endif #endif
@ -330,26 +281,18 @@ void OgreXmlSerializer::ReadMesh(MeshXml *mesh) {
m_currentNodeName == nnSubMeshNames || m_currentNodeName == nnSubMeshNames ||
m_currentNodeName == nnExtremes || m_currentNodeName == nnExtremes ||
m_currentNodeName == nnPoses || m_currentNodeName == nnPoses ||
m_currentNodeName == nnAnimations) m_currentNodeName == nnAnimations) {
{ if (m_currentNodeName == nnSharedGeometry) {
if (m_currentNodeName == nnSharedGeometry)
{
mesh->sharedVertexData = new VertexDataXml(); mesh->sharedVertexData = new VertexDataXml();
ReadGeometry(mesh->sharedVertexData); ReadGeometry(mesh->sharedVertexData);
} } else if (m_currentNodeName == nnSubMeshes) {
else if (m_currentNodeName == nnSubMeshes)
{
NextNode(); NextNode();
while (m_currentNodeName == nnSubMesh) { while (m_currentNodeName == nnSubMesh) {
ReadSubMesh(mesh); ReadSubMesh(mesh);
} }
} } else if (m_currentNodeName == nnBoneAssignments) {
else if (m_currentNodeName == nnBoneAssignments)
{
ReadBoneAssignments(mesh->sharedVertexData); ReadBoneAssignments(mesh->sharedVertexData);
} } else if (m_currentNodeName == nnSkeletonLink) {
else if (m_currentNodeName == nnSkeletonLink)
{
mesh->skeletonRef = ReadAttribute<std::string>("name"); mesh->skeletonRef = ReadAttribute<std::string>("name");
ASSIMP_LOG_DEBUG_F("Read skeleton link ", mesh->skeletonRef); ASSIMP_LOG_DEBUG_F("Read skeleton link ", mesh->skeletonRef);
NextNode(); NextNode();
@ -360,8 +303,7 @@ void OgreXmlSerializer::ReadMesh(MeshXml *mesh) {
} }
} }
void OgreXmlSerializer::ReadGeometry(VertexDataXml *dest) void OgreXmlSerializer::ReadGeometry(VertexDataXml *dest) {
{
dest->count = ReadAttribute<uint32_t>("vertexcount"); dest->count = ReadAttribute<uint32_t>("vertexcount");
ASSIMP_LOG_DEBUG_F(" - Reading geometry of ", dest->count, " vertices"); ASSIMP_LOG_DEBUG_F(" - Reading geometry of ", dest->count, " vertices");
@ -371,8 +313,7 @@ void OgreXmlSerializer::ReadGeometry(VertexDataXml *dest)
} }
} }
void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest) void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest) {
{
bool positions = (HasAttribute("positions") && ReadAttribute<bool>("positions")); bool positions = (HasAttribute("positions") && ReadAttribute<bool>("positions"));
bool normals = (HasAttribute("normals") && ReadAttribute<bool>("normals")); bool normals = (HasAttribute("normals") && ReadAttribute<bool>("normals"));
bool tangents = (HasAttribute("tangents") && ReadAttribute<bool>("tangents")); bool tangents = (HasAttribute("tangents") && ReadAttribute<bool>("tangents"));
@ -383,23 +324,19 @@ void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest)
throw DeadlyImportError("Vertex buffer does not contain positions!"); throw DeadlyImportError("Vertex buffer does not contain positions!");
} }
if (positions) if (positions) {
{
ASSIMP_LOG_DEBUG(" - Contains positions"); ASSIMP_LOG_DEBUG(" - Contains positions");
dest->positions.reserve(dest->count); dest->positions.reserve(dest->count);
} }
if (normals) if (normals) {
{
ASSIMP_LOG_DEBUG(" - Contains normals"); ASSIMP_LOG_DEBUG(" - Contains normals");
dest->normals.reserve(dest->count); dest->normals.reserve(dest->count);
} }
if (tangents) if (tangents) {
{
ASSIMP_LOG_DEBUG(" - Contains tangents"); ASSIMP_LOG_DEBUG(" - Contains tangents");
dest->tangents.reserve(dest->count); dest->tangents.reserve(dest->count);
} }
if (uvs > 0) if (uvs > 0) {
{
ASSIMP_LOG_DEBUG_F(" - Contains ", uvs, " texture coords"); ASSIMP_LOG_DEBUG_F(" - Contains ", uvs, " texture coords");
dest->uvs.resize(uvs); dest->uvs.resize(uvs);
for (size_t i = 0, len = dest->uvs.size(); i < len; ++i) { for (size_t i = 0, len = dest->uvs.size(); i < len; ++i) {
@ -420,42 +357,33 @@ void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest)
m_currentNodeName == nnBinormal || m_currentNodeName == nnBinormal ||
m_currentNodeName == nnTexCoord || m_currentNodeName == nnTexCoord ||
m_currentNodeName == nnColorDiffuse || m_currentNodeName == nnColorDiffuse ||
m_currentNodeName == nnColorSpecular) m_currentNodeName == nnColorSpecular) {
{
if (m_currentNodeName == nnVertex) { if (m_currentNodeName == nnVertex) {
NextNode(); NextNode();
} }
/// @todo Implement nnBinormal, nnColorDiffuse and nnColorSpecular /// @todo Implement nnBinormal, nnColorDiffuse and nnColorSpecular
if (positions && m_currentNodeName == nnPosition) if (positions && m_currentNodeName == nnPosition) {
{
aiVector3D pos; aiVector3D pos;
pos.x = ReadAttribute<float>(anX); pos.x = ReadAttribute<float>(anX);
pos.y = ReadAttribute<float>(anY); pos.y = ReadAttribute<float>(anY);
pos.z = ReadAttribute<float>(anZ); pos.z = ReadAttribute<float>(anZ);
dest->positions.push_back(pos); dest->positions.push_back(pos);
} } else if (normals && m_currentNodeName == nnNormal) {
else if (normals && m_currentNodeName == nnNormal)
{
aiVector3D normal; aiVector3D normal;
normal.x = ReadAttribute<float>(anX); normal.x = ReadAttribute<float>(anX);
normal.y = ReadAttribute<float>(anY); normal.y = ReadAttribute<float>(anY);
normal.z = ReadAttribute<float>(anZ); normal.z = ReadAttribute<float>(anZ);
dest->normals.push_back(normal); dest->normals.push_back(normal);
} } else if (tangents && m_currentNodeName == nnTangent) {
else if (tangents && m_currentNodeName == nnTangent)
{
aiVector3D tangent; aiVector3D tangent;
tangent.x = ReadAttribute<float>(anX); tangent.x = ReadAttribute<float>(anX);
tangent.y = ReadAttribute<float>(anY); tangent.y = ReadAttribute<float>(anY);
tangent.z = ReadAttribute<float>(anZ); tangent.z = ReadAttribute<float>(anZ);
dest->tangents.push_back(tangent); dest->tangents.push_back(tangent);
} } else if (uvs > 0 && m_currentNodeName == nnTexCoord) {
else if (uvs > 0 && m_currentNodeName == nnTexCoord) for (auto &curUvs : dest->uvs) {
{
for(auto &uvs : dest->uvs)
{
if (m_currentNodeName != nnTexCoord) { if (m_currentNodeName != nnTexCoord) {
throw DeadlyImportError("Vertex buffer declared more UVs than can be found in a vertex"); throw DeadlyImportError("Vertex buffer declared more UVs than can be found in a vertex");
} }
@ -463,47 +391,31 @@ void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest)
aiVector3D uv; aiVector3D uv;
uv.x = ReadAttribute<float>("u"); uv.x = ReadAttribute<float>("u");
uv.y = (ReadAttribute<float>("v") * -1) + 1; // Flip UV from Ogre to Assimp form uv.y = (ReadAttribute<float>("v") * -1) + 1; // Flip UV from Ogre to Assimp form
uvs.push_back(uv); curUvs.push_back(uv);
NextNode(); NextNode();
} }
// Continue main loop as above already read next node // Continue main loop as above already read next node
continue; continue;
} } else {
else
{
/// @todo Remove this stuff once implemented. We only want to log warnings once per element. /// @todo Remove this stuff once implemented. We only want to log warnings once per element.
bool warn = true; bool warn = true;
if (m_currentNodeName == nnBinormal) if (m_currentNodeName == nnBinormal) {
{ if (warnBinormal) {
if (warnBinormal)
{
warnBinormal = false; warnBinormal = false;
} } else {
else
{
warn = false; warn = false;
} }
} } else if (m_currentNodeName == nnColorDiffuse) {
else if (m_currentNodeName == nnColorDiffuse) if (warnColorDiffuse) {
{
if (warnColorDiffuse)
{
warnColorDiffuse = false; warnColorDiffuse = false;
} } else {
else
{
warn = false; warn = false;
} }
} } else if (m_currentNodeName == nnColorSpecular) {
else if (m_currentNodeName == nnColorSpecular) if (warnColorSpecular) {
{
if (warnColorSpecular)
{
warnColorSpecular = false; warnColorSpecular = false;
} } else {
else
{
warn = false; warn = false;
} }
} }
@ -526,8 +438,7 @@ void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest)
if (tangents && dest->tangents.size() != dest->count) { if (tangents && dest->tangents.size() != dest->count) {
throw DeadlyImportError(Formatter::format() << "Read only " << dest->tangents.size() << " tangents when should have read " << dest->count); throw DeadlyImportError(Formatter::format() << "Read only " << dest->tangents.size() << " tangents when should have read " << dest->count);
} }
for(unsigned int i=0; i<dest->uvs.size(); ++i) for (unsigned int i = 0; i < dest->uvs.size(); ++i) {
{
if (dest->uvs[i].size() != dest->count) { if (dest->uvs[i].size() != dest->count) {
throw DeadlyImportError(Formatter::format() << "Read only " << dest->uvs[i].size() throw DeadlyImportError(Formatter::format() << "Read only " << dest->uvs[i].size()
<< " uvs for uv index " << i << " when should have read " << dest->count); << " uvs for uv index " << i << " when should have read " << dest->count);
@ -535,8 +446,7 @@ void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest)
} }
} }
void OgreXmlSerializer::ReadSubMesh(MeshXml *mesh) void OgreXmlSerializer::ReadSubMesh(MeshXml *mesh) {
{
static const char *anMaterial = "material"; static const char *anMaterial = "material";
static const char *anUseSharedVertices = "usesharedvertices"; static const char *anUseSharedVertices = "usesharedvertices";
static const char *anCount = "count"; static const char *anCount = "count";
@ -568,16 +478,13 @@ void OgreXmlSerializer::ReadSubMesh(MeshXml *mesh)
while (m_currentNodeName == nnFaces || while (m_currentNodeName == nnFaces ||
m_currentNodeName == nnGeometry || m_currentNodeName == nnGeometry ||
m_currentNodeName == nnTextures || m_currentNodeName == nnTextures ||
m_currentNodeName == nnBoneAssignments) m_currentNodeName == nnBoneAssignments) {
{ if (m_currentNodeName == nnFaces) {
if (m_currentNodeName == nnFaces)
{
submesh->indexData->faceCount = ReadAttribute<uint32_t>(anCount); submesh->indexData->faceCount = ReadAttribute<uint32_t>(anCount);
submesh->indexData->faces.reserve(submesh->indexData->faceCount); submesh->indexData->faces.reserve(submesh->indexData->faceCount);
NextNode(); NextNode();
while(m_currentNodeName == nnFace) while (m_currentNodeName == nnFace) {
{
aiFace face; aiFace face;
face.mNumIndices = 3; face.mNumIndices = 3;
face.mIndices = new unsigned int[3]; face.mIndices = new unsigned int[3];
@ -622,8 +529,7 @@ void OgreXmlSerializer::ReadSubMesh(MeshXml *mesh)
mesh->subMeshes.push_back(submesh); mesh->subMeshes.push_back(submesh);
} }
void OgreXmlSerializer::ReadBoneAssignments(VertexDataXml *dest) void OgreXmlSerializer::ReadBoneAssignments(VertexDataXml *dest) {
{
if (!dest) { if (!dest) {
throw DeadlyImportError("Cannot read bone assignments, vertex data is null."); throw DeadlyImportError("Cannot read bone assignments, vertex data is null.");
} }
@ -635,8 +541,7 @@ void OgreXmlSerializer::ReadBoneAssignments(VertexDataXml *dest)
std::set<uint32_t> influencedVertices; std::set<uint32_t> influencedVertices;
NextNode(); NextNode();
while(m_currentNodeName == nnVertexBoneAssignment) while (m_currentNodeName == nnVertexBoneAssignment) {
{
VertexBoneAssignment ba; VertexBoneAssignment ba;
ba.vertexIndex = ReadAttribute<uint32_t>(anVertexIndex); ba.vertexIndex = ReadAttribute<uint32_t>(anVertexIndex);
ba.boneIndex = ReadAttribute<uint16_t>(anBoneIndex); ba.boneIndex = ReadAttribute<uint16_t>(anBoneIndex);
@ -652,18 +557,14 @@ void OgreXmlSerializer::ReadBoneAssignments(VertexDataXml *dest)
Some exporters won't care if the sum of all bone weights Some exporters won't care if the sum of all bone weights
for a single vertex equals 1 or not, so validate here. */ for a single vertex equals 1 or not, so validate here. */
const float epsilon = 0.05f; const float epsilon = 0.05f;
for (const uint32_t vertexIndex : influencedVertices) for (const uint32_t vertexIndex : influencedVertices) {
{
float sum = 0.0f; float sum = 0.0f;
for (VertexBoneAssignmentList::const_iterator baIter=dest->boneAssignments.begin(), baEnd=dest->boneAssignments.end(); baIter != baEnd; ++baIter) for (VertexBoneAssignmentList::const_iterator baIter = dest->boneAssignments.begin(), baEnd = dest->boneAssignments.end(); baIter != baEnd; ++baIter) {
{
if (baIter->vertexIndex == vertexIndex) if (baIter->vertexIndex == vertexIndex)
sum += baIter->weight; sum += baIter->weight;
} }
if ((sum < (1.0f - epsilon)) || (sum > (1.0f + epsilon))) if ((sum < (1.0f - epsilon)) || (sum > (1.0f + epsilon))) {
{ for (auto &boneAssign : dest->boneAssignments) {
for (auto &boneAssign : dest->boneAssignments)
{
if (boneAssign.vertexIndex == vertexIndex) if (boneAssign.vertexIndex == vertexIndex)
boneAssign.weight /= sum; boneAssign.weight /= sum;
} }
@ -675,15 +576,13 @@ void OgreXmlSerializer::ReadBoneAssignments(VertexDataXml *dest)
// Skeleton // Skeleton
bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml *mesh) bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml *mesh) {
{
if (!mesh || mesh->skeletonRef.empty()) if (!mesh || mesh->skeletonRef.empty())
return false; return false;
// Highly unusual to see in read world cases but support // Highly unusual to see in read world cases but support
// XML mesh referencing a binary skeleton file. // XML mesh referencing a binary skeleton file.
if (EndsWith(mesh->skeletonRef, ".skeleton", false)) if (EndsWith(mesh->skeletonRef, ".skeleton", false)) {
{
if (OgreBinarySerializer::ImportSkeleton(pIOHandler, mesh)) if (OgreBinarySerializer::ImportSkeleton(pIOHandler, mesh))
return true; return true;
@ -705,8 +604,7 @@ bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml *me
return true; return true;
} }
bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, Mesh *mesh) bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, Mesh *mesh) {
{
if (!mesh || mesh->skeletonRef.empty()) if (!mesh || mesh->skeletonRef.empty())
return false; return false;
@ -721,16 +619,13 @@ bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, Mesh *mesh)
return true; return true;
} }
XmlReaderPtr OgreXmlSerializer::OpenReader(Assimp::IOSystem *pIOHandler, const std::string &filename) XmlReaderPtr OgreXmlSerializer::OpenReader(Assimp::IOSystem *pIOHandler, const std::string &filename) {
{ if (!EndsWith(filename, ".skeleton.xml", false)) {
if (!EndsWith(filename, ".skeleton.xml", false))
{
ASSIMP_LOG_ERROR_F("Imported Mesh is referencing to unsupported '", filename, "' skeleton file."); ASSIMP_LOG_ERROR_F("Imported Mesh is referencing to unsupported '", filename, "' skeleton file.");
return XmlReaderPtr(); return XmlReaderPtr();
} }
if (!pIOHandler->Exists(filename)) if (!pIOHandler->Exists(filename)) {
{
ASSIMP_LOG_ERROR_F("Failed to find skeleton file '", filename, "' that is referenced by imported Mesh."); ASSIMP_LOG_ERROR_F("Failed to find skeleton file '", filename, "' that is referenced by imported Mesh.");
return XmlReaderPtr(); return XmlReaderPtr();
} }
@ -748,8 +643,7 @@ XmlReaderPtr OgreXmlSerializer::OpenReader(Assimp::IOSystem *pIOHandler, const s
return reader; return reader;
} }
void OgreXmlSerializer::ReadSkeleton(Skeleton *skeleton) void OgreXmlSerializer::ReadSkeleton(Skeleton *skeleton) {
{
if (NextNode() != nnSkeleton) { if (NextNode() != nnSkeleton) {
throw DeadlyImportError("Root node is <" + m_currentNodeName + "> expecting <skeleton>"); throw DeadlyImportError("Root node is <" + m_currentNodeName + "> expecting <skeleton>");
} }
@ -758,8 +652,7 @@ void OgreXmlSerializer::ReadSkeleton(Skeleton *skeleton)
// Optional blend mode from root node // Optional blend mode from root node
if (HasAttribute("blendmode")) { if (HasAttribute("blendmode")) {
skeleton->blendMode = (ToLower(ReadAttribute<std::string>("blendmode")) == "cumulative" skeleton->blendMode = (ToLower(ReadAttribute<std::string>("blendmode")) == "cumulative" ? Skeleton::ANIMBLEND_CUMULATIVE : Skeleton::ANIMBLEND_AVERAGE);
? Skeleton::ANIMBLEND_CUMULATIVE : Skeleton::ANIMBLEND_AVERAGE);
} }
NextNode(); NextNode();
@ -768,8 +661,7 @@ void OgreXmlSerializer::ReadSkeleton(Skeleton *skeleton)
while (m_currentNodeName == nnBones || while (m_currentNodeName == nnBones ||
m_currentNodeName == nnBoneHierarchy || m_currentNodeName == nnBoneHierarchy ||
m_currentNodeName == nnAnimations || m_currentNodeName == nnAnimations ||
m_currentNodeName == nnAnimationLinks) m_currentNodeName == nnAnimationLinks) {
{
if (m_currentNodeName == nnBones) if (m_currentNodeName == nnBones)
ReadBones(skeleton); ReadBones(skeleton);
else if (m_currentNodeName == nnBoneHierarchy) else if (m_currentNodeName == nnBoneHierarchy)
@ -781,8 +673,7 @@ void OgreXmlSerializer::ReadSkeleton(Skeleton *skeleton)
} }
} }
void OgreXmlSerializer::ReadAnimations(Skeleton *skeleton) void OgreXmlSerializer::ReadAnimations(Skeleton *skeleton) {
{
if (skeleton->bones.empty()) { if (skeleton->bones.empty()) {
throw DeadlyImportError("Cannot read <animations> for a Skeleton without bones"); throw DeadlyImportError("Cannot read <animations> for a Skeleton without bones");
} }
@ -790,8 +681,7 @@ void OgreXmlSerializer::ReadAnimations(Skeleton *skeleton)
ASSIMP_LOG_DEBUG(" - Animations"); ASSIMP_LOG_DEBUG(" - Animations");
NextNode(); NextNode();
while(m_currentNodeName == nnAnimation) while (m_currentNodeName == nnAnimation) {
{
Animation *anim = new Animation(skeleton); Animation *anim = new Animation(skeleton);
anim->name = ReadAttribute<std::string>("name"); anim->name = ReadAttribute<std::string>("name");
anim->length = ReadAttribute<float>("length"); anim->length = ReadAttribute<float>("length");
@ -807,11 +697,9 @@ void OgreXmlSerializer::ReadAnimations(Skeleton *skeleton)
} }
} }
void OgreXmlSerializer::ReadAnimationTracks(Animation *dest) void OgreXmlSerializer::ReadAnimationTracks(Animation *dest) {
{
NextNode(); NextNode();
while(m_currentNodeName == nnTrack) while (m_currentNodeName == nnTrack) {
{
VertexAnimationTrack track; VertexAnimationTrack track;
track.type = VertexAnimationTrack::VAT_TRANSFORM; track.type = VertexAnimationTrack::VAT_TRANSFORM;
track.boneName = ReadAttribute<std::string>("bone"); track.boneName = ReadAttribute<std::string>("bone");
@ -826,27 +714,21 @@ void OgreXmlSerializer::ReadAnimationTracks(Animation *dest)
} }
} }
void OgreXmlSerializer::ReadAnimationKeyFrames(Animation *anim, VertexAnimationTrack *dest) void OgreXmlSerializer::ReadAnimationKeyFrames(Animation *anim, VertexAnimationTrack *dest) {
{
const aiVector3D zeroVec(0.f, 0.f, 0.f); const aiVector3D zeroVec(0.f, 0.f, 0.f);
NextNode(); NextNode();
while(m_currentNodeName == nnKeyFrame) while (m_currentNodeName == nnKeyFrame) {
{
TransformKeyFrame keyframe; TransformKeyFrame keyframe;
keyframe.timePos = ReadAttribute<float>("time"); keyframe.timePos = ReadAttribute<float>("time");
NextNode(); NextNode();
while(m_currentNodeName == nnTranslate || m_currentNodeName == nnRotate || m_currentNodeName == nnScale) while (m_currentNodeName == nnTranslate || m_currentNodeName == nnRotate || m_currentNodeName == nnScale) {
{ if (m_currentNodeName == nnTranslate) {
if (m_currentNodeName == nnTranslate)
{
keyframe.position.x = ReadAttribute<float>(anX); keyframe.position.x = ReadAttribute<float>(anX);
keyframe.position.y = ReadAttribute<float>(anY); keyframe.position.y = ReadAttribute<float>(anY);
keyframe.position.z = ReadAttribute<float>(anZ); keyframe.position.z = ReadAttribute<float>(anZ);
} } else if (m_currentNodeName == nnRotate) {
else if (m_currentNodeName == nnRotate)
{
float angle = ReadAttribute<float>("angle"); float angle = ReadAttribute<float>("angle");
if (NextNode() != nnAxis) { if (NextNode() != nnAxis) {
@ -857,17 +739,14 @@ void OgreXmlSerializer::ReadAnimationKeyFrames(Animation *anim, VertexAnimationT
axis.x = ReadAttribute<float>(anX); axis.x = ReadAttribute<float>(anX);
axis.y = ReadAttribute<float>(anY); axis.y = ReadAttribute<float>(anY);
axis.z = ReadAttribute<float>(anZ); axis.z = ReadAttribute<float>(anZ);
if (axis.Equal(zeroVec)) if (axis.Equal(zeroVec)) {
{
axis.x = 1.0f; axis.x = 1.0f;
if (angle != 0) { if (angle != 0) {
ASSIMP_LOG_WARN_F("Found invalid a key frame with a zero rotation axis in animation: ", anim->name); ASSIMP_LOG_WARN_F("Found invalid a key frame with a zero rotation axis in animation: ", anim->name);
} }
} }
keyframe.rotation = aiQuaternion(axis, angle); keyframe.rotation = aiQuaternion(axis, angle);
} } else if (m_currentNodeName == nnScale) {
else if (m_currentNodeName == nnScale)
{
keyframe.scale.x = ReadAttribute<float>(anX); keyframe.scale.x = ReadAttribute<float>(anX);
keyframe.scale.y = ReadAttribute<float>(anY); keyframe.scale.y = ReadAttribute<float>(anY);
keyframe.scale.z = ReadAttribute<float>(anZ); keyframe.scale.z = ReadAttribute<float>(anZ);
@ -880,14 +759,12 @@ void OgreXmlSerializer::ReadAnimationKeyFrames(Animation *anim, VertexAnimationT
} }
} }
void OgreXmlSerializer::ReadBoneHierarchy(Skeleton *skeleton) void OgreXmlSerializer::ReadBoneHierarchy(Skeleton *skeleton) {
{
if (skeleton->bones.empty()) { if (skeleton->bones.empty()) {
throw DeadlyImportError("Cannot read <bonehierarchy> for a Skeleton without bones"); throw DeadlyImportError("Cannot read <bonehierarchy> for a Skeleton without bones");
} }
while(NextNode() == nnBoneParent) while (NextNode() == nnBoneParent) {
{
const std::string name = ReadAttribute<std::string>("bone"); const std::string name = ReadAttribute<std::string>("bone");
const std::string parentName = ReadAttribute<std::string>("parent"); const std::string parentName = ReadAttribute<std::string>("parent");
@ -901,29 +778,25 @@ void OgreXmlSerializer::ReadBoneHierarchy(Skeleton *skeleton)
} }
// Calculate bone matrices for root bones. Recursively calculates their children. // Calculate bone matrices for root bones. Recursively calculates their children.
for (size_t i=0, len=skeleton->bones.size(); i<len; ++i) for (size_t i = 0, len = skeleton->bones.size(); i < len; ++i) {
{
Bone *bone = skeleton->bones[i]; Bone *bone = skeleton->bones[i];
if (!bone->IsParented()) if (!bone->IsParented())
bone->CalculateWorldMatrixAndDefaultPose(skeleton); bone->CalculateWorldMatrixAndDefaultPose(skeleton);
} }
} }
static bool BoneCompare(Bone *a, Bone *b) static bool BoneCompare(Bone *a, Bone *b) {
{
ai_assert(nullptr != a); ai_assert(nullptr != a);
ai_assert(nullptr != b); ai_assert(nullptr != b);
return (a->id < b->id); return (a->id < b->id);
} }
void OgreXmlSerializer::ReadBones(Skeleton *skeleton) void OgreXmlSerializer::ReadBones(Skeleton *skeleton) {
{
ASSIMP_LOG_DEBUG(" - Bones"); ASSIMP_LOG_DEBUG(" - Bones");
NextNode(); NextNode();
while(m_currentNodeName == nnBone) while (m_currentNodeName == nnBone) {
{
Bone *bone = new Bone(); Bone *bone = new Bone();
bone->id = ReadAttribute<uint16_t>("id"); bone->id = ReadAttribute<uint16_t>("id");
bone->name = ReadAttribute<std::string>("name"); bone->name = ReadAttribute<std::string>("name");
@ -931,16 +804,12 @@ void OgreXmlSerializer::ReadBones(Skeleton *skeleton)
NextNode(); NextNode();
while (m_currentNodeName == nnPosition || while (m_currentNodeName == nnPosition ||
m_currentNodeName == nnRotation || m_currentNodeName == nnRotation ||
m_currentNodeName == nnScale) m_currentNodeName == nnScale) {
{ if (m_currentNodeName == nnPosition) {
if (m_currentNodeName == nnPosition)
{
bone->position.x = ReadAttribute<float>(anX); bone->position.x = ReadAttribute<float>(anX);
bone->position.y = ReadAttribute<float>(anY); bone->position.y = ReadAttribute<float>(anY);
bone->position.z = ReadAttribute<float>(anZ); bone->position.z = ReadAttribute<float>(anZ);
} } else if (m_currentNodeName == nnRotation) {
else if (m_currentNodeName == nnRotation)
{
float angle = ReadAttribute<float>("angle"); float angle = ReadAttribute<float>("angle");
if (NextNode() != nnAxis) { if (NextNode() != nnAxis) {
@ -953,17 +822,12 @@ void OgreXmlSerializer::ReadBones(Skeleton *skeleton)
axis.z = ReadAttribute<float>(anZ); axis.z = ReadAttribute<float>(anZ);
bone->rotation = aiQuaternion(axis, angle); bone->rotation = aiQuaternion(axis, angle);
} } else if (m_currentNodeName == nnScale) {
else if (m_currentNodeName == nnScale)
{
/// @todo Implement taking scale into account in matrix/pose calculations! /// @todo Implement taking scale into account in matrix/pose calculations!
if (HasAttribute("factor")) if (HasAttribute("factor")) {
{
float factor = ReadAttribute<float>("factor"); float factor = ReadAttribute<float>("factor");
bone->scale.Set(factor, factor, factor); bone->scale.Set(factor, factor, factor);
} } else {
else
{
if (HasAttribute(anX)) if (HasAttribute(anX))
bone->scale.x = ReadAttribute<float>(anX); bone->scale.x = ReadAttribute<float>(anX);
if (HasAttribute(anY)) if (HasAttribute(anY))
@ -985,8 +849,7 @@ void OgreXmlSerializer::ReadBones(Skeleton *skeleton)
// Validate that bone indexes are not skipped. // Validate that bone indexes are not skipped.
/** @note Left this from original authors code, but not sure if this is strictly necessary /** @note Left this from original authors code, but not sure if this is strictly necessary
as per the Ogre skeleton spec. It might be more that other (later) code in this imported does not break. */ as per the Ogre skeleton spec. It might be more that other (later) code in this imported does not break. */
for (size_t i=0, len=skeleton->bones.size(); i<len; ++i) for (size_t i = 0, len = skeleton->bones.size(); i < len; ++i) {
{
Bone *b = skeleton->bones[i]; Bone *b = skeleton->bones[i];
ASSIMP_LOG_DEBUG_F(" ", b->id, " ", b->name); ASSIMP_LOG_DEBUG_F(" ", b->id, " ", b->name);
@ -996,7 +859,7 @@ void OgreXmlSerializer::ReadBones(Skeleton *skeleton)
} }
} }
} // Ogre } // namespace Ogre
} // Assimp } // namespace Assimp
#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER #endif // ASSIMP_BUILD_NO_OGRE_IMPORTER

View File

@ -1212,8 +1212,8 @@ void OpenGEXImporter::resolveReferences() {
if( RefInfo::MeshRef == currentRefInfo->m_type ) { if( RefInfo::MeshRef == currentRefInfo->m_type ) {
for( size_t i = 0; i < currentRefInfo->m_Names.size(); ++i ) { for( size_t i = 0; i < currentRefInfo->m_Names.size(); ++i ) {
const std::string &name( currentRefInfo->m_Names[ i ] ); const std::string &name( currentRefInfo->m_Names[ i ] );
ReferenceMap::const_iterator it( m_mesh2refMap.find( name ) ); ReferenceMap::const_iterator curIt( m_mesh2refMap.find( name ) );
if( m_mesh2refMap.end() != it ) { if (m_mesh2refMap.end() != curIt) {
unsigned int meshIdx = static_cast<unsigned int>(m_mesh2refMap[ name ]); unsigned int meshIdx = static_cast<unsigned int>(m_mesh2refMap[ name ]);
node->mMeshes[ i ] = meshIdx; node->mMeshes[ i ] = meshIdx;
} }
@ -1221,8 +1221,8 @@ void OpenGEXImporter::resolveReferences() {
} else if( RefInfo::MaterialRef == currentRefInfo->m_type ) { } else if( RefInfo::MaterialRef == currentRefInfo->m_type ) {
for ( size_t i = 0; i < currentRefInfo->m_Names.size(); ++i ) { for ( size_t i = 0; i < currentRefInfo->m_Names.size(); ++i ) {
const std::string name( currentRefInfo->m_Names[ i ] ); const std::string name( currentRefInfo->m_Names[ i ] );
ReferenceMap::const_iterator it( m_material2refMap.find( name ) ); ReferenceMap::const_iterator curIt(m_material2refMap.find(name));
if ( m_material2refMap.end() != it ) { if (m_material2refMap.end() != curIt) {
if ( nullptr != m_currentMesh ) { if ( nullptr != m_currentMesh ) {
unsigned int matIdx = static_cast< unsigned int >( m_material2refMap[ name ] ); unsigned int matIdx = static_cast< unsigned int >( m_material2refMap[ name ] );
if ( m_currentMesh->mMaterialIndex != 0 ) { if ( m_currentMesh->mMaterialIndex != 0 ) {

View File

@ -5,7 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -49,10 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// internal headers // internal headers
#include "PlyLoader.h" #include "PlyLoader.h"
#include <assimp/IOStreamBuffer.h> #include <assimp/IOStreamBuffer.h>
#include <memory>
#include <assimp/IOSystem.hpp>
#include <assimp/scene.h>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/IOSystem.hpp>
#include <memory>
using namespace ::Assimp; using namespace ::Assimp;
@ -69,29 +68,27 @@ static const aiImporterDesc desc = {
"ply" "ply"
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Internal stuff // Internal stuff
namespace { namespace {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Checks that property index is within range // Checks that property index is within range
template <class T> template <class T>
inline inline const T &GetProperty(const std::vector<T> &props, int idx) {
const T &GetProperty(const std::vector<T> &props, int idx) {
if (static_cast<size_t>(idx) >= props.size()) { if (static_cast<size_t>(idx) >= props.size()) {
throw DeadlyImportError("Invalid .ply file: Property index is out of range."); throw DeadlyImportError("Invalid .ply file: Property index is out of range.");
} }
return props[idx]; return props[idx];
} }
} } // namespace
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
PLYImporter::PLYImporter() PLYImporter::PLYImporter() :
: mBuffer(nullptr) mBuffer(nullptr),
, pcDOM(nullptr) pcDOM(nullptr),
, mGeneratedMesh(nullptr) { mGeneratedMesh(nullptr) {
// empty // empty
} }
@ -108,11 +105,15 @@ bool PLYImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool c
if (extension == "ply") { if (extension == "ply") {
return true; return true;
} else if (!extension.length() || checkSig) { }
if (!extension.length() || checkSig) {
if (!pIOHandler) { if (!pIOHandler) {
return true; return true;
} }
static const char* tokens[] = { "ply" }; static const char *tokens[] = {
"ply"
};
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1); return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
} }
@ -397,19 +398,25 @@ void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementIn
bool haveColor = false; bool haveColor = false;
if (0xFFFFFFFF != aiColors[0]) { if (0xFFFFFFFF != aiColors[0]) {
cOut.r = NormalizeColorValue(GetProperty(instElement->alProperties, cOut.r = NormalizeColorValue(GetProperty(instElement->alProperties,
aiColors[0]).avList.front(), aiColorsTypes[0]); aiColors[0])
.avList.front(),
aiColorsTypes[0]);
haveColor = true; haveColor = true;
} }
if (0xFFFFFFFF != aiColors[1]) { if (0xFFFFFFFF != aiColors[1]) {
cOut.g = NormalizeColorValue(GetProperty(instElement->alProperties, cOut.g = NormalizeColorValue(GetProperty(instElement->alProperties,
aiColors[1]).avList.front(), aiColorsTypes[1]); aiColors[1])
.avList.front(),
aiColorsTypes[1]);
haveColor = true; haveColor = true;
} }
if (0xFFFFFFFF != aiColors[2]) { if (0xFFFFFFFF != aiColors[2]) {
cOut.b = NormalizeColorValue(GetProperty(instElement->alProperties, cOut.b = NormalizeColorValue(GetProperty(instElement->alProperties,
aiColors[2]).avList.front(), aiColorsTypes[2]); aiColors[2])
.avList.front(),
aiColorsTypes[2]);
haveColor = true; haveColor = true;
} }
@ -418,7 +425,9 @@ void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementIn
cOut.a = 1.0; cOut.a = 1.0;
} else { } else {
cOut.a = NormalizeColorValue(GetProperty(instElement->alProperties, cOut.a = NormalizeColorValue(GetProperty(instElement->alProperties,
aiColors[3]).avList.front(), aiColorsTypes[3]); aiColors[3])
.avList.front(),
aiColorsTypes[3]);
haveColor = true; haveColor = true;
} }
@ -474,7 +483,6 @@ void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementIn
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Convert a color component to [0...1] // Convert a color component to [0...1]
ai_real PLYImporter::NormalizeColorValue(PLY::PropertyInstance::ValueUnion val, PLY::EDataType eType) { ai_real PLYImporter::NormalizeColorValue(PLY::PropertyInstance::ValueUnion val, PLY::EDataType eType) {
@ -684,44 +692,50 @@ void PLYImporter::LoadFace(const PLY::Element* pcElement, const PLY::ElementInst
void PLYImporter::GetMaterialColor(const std::vector<PLY::PropertyInstance> &avList, void PLYImporter::GetMaterialColor(const std::vector<PLY::PropertyInstance> &avList,
unsigned int aiPositions[4], unsigned int aiPositions[4],
PLY::EDataType aiTypes[4], PLY::EDataType aiTypes[4],
aiColor4D* clrOut) aiColor4D *clrOut) {
{
ai_assert(NULL != clrOut); ai_assert(NULL != clrOut);
if (0xFFFFFFFF == aiPositions[0])clrOut->r = 0.0f; if (0xFFFFFFFF == aiPositions[0])
else clrOut->r = 0.0f;
{ else {
clrOut->r = NormalizeColorValue(GetProperty(avList, clrOut->r = NormalizeColorValue(GetProperty(avList,
aiPositions[0]).avList.front(), aiTypes[0]); aiPositions[0])
.avList.front(),
aiTypes[0]);
} }
if (0xFFFFFFFF == aiPositions[1])clrOut->g = 0.0f; if (0xFFFFFFFF == aiPositions[1])
else clrOut->g = 0.0f;
{ else {
clrOut->g = NormalizeColorValue(GetProperty(avList, clrOut->g = NormalizeColorValue(GetProperty(avList,
aiPositions[1]).avList.front(), aiTypes[1]); aiPositions[1])
.avList.front(),
aiTypes[1]);
} }
if (0xFFFFFFFF == aiPositions[2])clrOut->b = 0.0f; if (0xFFFFFFFF == aiPositions[2])
else clrOut->b = 0.0f;
{ else {
clrOut->b = NormalizeColorValue(GetProperty(avList, clrOut->b = NormalizeColorValue(GetProperty(avList,
aiPositions[2]).avList.front(), aiTypes[2]); aiPositions[2])
.avList.front(),
aiTypes[2]);
} }
// assume 1.0 for the alpha channel ifit is not set // assume 1.0 for the alpha channel ifit is not set
if (0xFFFFFFFF == aiPositions[3])clrOut->a = 1.0f; if (0xFFFFFFFF == aiPositions[3])
else clrOut->a = 1.0f;
{ else {
clrOut->a = NormalizeColorValue(GetProperty(avList, clrOut->a = NormalizeColorValue(GetProperty(avList,
aiPositions[3]).avList.front(), aiTypes[3]); aiPositions[3])
.avList.front(),
aiTypes[3]);
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Extract a material from the PLY DOM // Extract a material from the PLY DOM
void PLYImporter::LoadMaterial(std::vector<aiMaterial*>* pvOut, std::string &defaultTexture, const bool pointsOnly) void PLYImporter::LoadMaterial(std::vector<aiMaterial *> *pvOut, std::string &defaultTexture, const bool pointsOnly) {
{
ai_assert(NULL != pvOut); ai_assert(NULL != pvOut);
// diffuse[4], specular[4], ambient[4] // diffuse[4], specular[4], ambient[4]
@ -749,102 +763,74 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial*>* pvOut, std::string &def
// search in the DOM for a vertex entry // search in the DOM for a vertex entry
unsigned int _i = 0; unsigned int _i = 0;
for (std::vector<PLY::Element>::const_iterator i = this->pcDOM->alElements.begin(); for (std::vector<PLY::Element>::const_iterator i = this->pcDOM->alElements.begin();
i != this->pcDOM->alElements.end(); ++i, ++_i) i != this->pcDOM->alElements.end(); ++i, ++_i) {
{ if (PLY::EEST_Material == (*i).eSemantic) {
if (PLY::EEST_Material == (*i).eSemantic)
{
pcList = &this->pcDOM->alElementData[_i]; pcList = &this->pcDOM->alElementData[_i];
// now check whether which coordinate sets are available // now check whether which coordinate sets are available
unsigned int _a = 0; unsigned int _a = 0;
for (std::vector<PLY::Property>::const_iterator for (std::vector<PLY::Property>::const_iterator
a = (*i).alProperties.begin(); a = (*i).alProperties.begin();
a != (*i).alProperties.end(); ++a, ++_a) a != (*i).alProperties.end(); ++a, ++_a) {
{
if ((*a).bIsList) continue; if ((*a).bIsList) continue;
// pohng specularity ----------------------------------- // pohng specularity -----------------------------------
if (PLY::EST_PhongPower == (*a).Semantic) if (PLY::EST_PhongPower == (*a).Semantic) {
{
iPhong = _a; iPhong = _a;
ePhong = (*a).eType; ePhong = (*a).eType;
} }
// general opacity ----------------------------------- // general opacity -----------------------------------
if (PLY::EST_Opacity == (*a).Semantic) if (PLY::EST_Opacity == (*a).Semantic) {
{
iOpacity = _a; iOpacity = _a;
eOpacity = (*a).eType; eOpacity = (*a).eType;
} }
// diffuse color channels ----------------------------------- // diffuse color channels -----------------------------------
if (PLY::EST_DiffuseRed == (*a).Semantic) if (PLY::EST_DiffuseRed == (*a).Semantic) {
{
aaiPositions[0][0] = _a; aaiPositions[0][0] = _a;
aaiTypes[0][0] = (*a).eType; aaiTypes[0][0] = (*a).eType;
} } else if (PLY::EST_DiffuseGreen == (*a).Semantic) {
else if (PLY::EST_DiffuseGreen == (*a).Semantic)
{
aaiPositions[0][1] = _a; aaiPositions[0][1] = _a;
aaiTypes[0][1] = (*a).eType; aaiTypes[0][1] = (*a).eType;
} } else if (PLY::EST_DiffuseBlue == (*a).Semantic) {
else if (PLY::EST_DiffuseBlue == (*a).Semantic)
{
aaiPositions[0][2] = _a; aaiPositions[0][2] = _a;
aaiTypes[0][2] = (*a).eType; aaiTypes[0][2] = (*a).eType;
} } else if (PLY::EST_DiffuseAlpha == (*a).Semantic) {
else if (PLY::EST_DiffuseAlpha == (*a).Semantic)
{
aaiPositions[0][3] = _a; aaiPositions[0][3] = _a;
aaiTypes[0][3] = (*a).eType; aaiTypes[0][3] = (*a).eType;
} }
// specular color channels ----------------------------------- // specular color channels -----------------------------------
else if (PLY::EST_SpecularRed == (*a).Semantic) else if (PLY::EST_SpecularRed == (*a).Semantic) {
{
aaiPositions[1][0] = _a; aaiPositions[1][0] = _a;
aaiTypes[1][0] = (*a).eType; aaiTypes[1][0] = (*a).eType;
} } else if (PLY::EST_SpecularGreen == (*a).Semantic) {
else if (PLY::EST_SpecularGreen == (*a).Semantic)
{
aaiPositions[1][1] = _a; aaiPositions[1][1] = _a;
aaiTypes[1][1] = (*a).eType; aaiTypes[1][1] = (*a).eType;
} } else if (PLY::EST_SpecularBlue == (*a).Semantic) {
else if (PLY::EST_SpecularBlue == (*a).Semantic)
{
aaiPositions[1][2] = _a; aaiPositions[1][2] = _a;
aaiTypes[1][2] = (*a).eType; aaiTypes[1][2] = (*a).eType;
} } else if (PLY::EST_SpecularAlpha == (*a).Semantic) {
else if (PLY::EST_SpecularAlpha == (*a).Semantic)
{
aaiPositions[1][3] = _a; aaiPositions[1][3] = _a;
aaiTypes[1][3] = (*a).eType; aaiTypes[1][3] = (*a).eType;
} }
// ambient color channels ----------------------------------- // ambient color channels -----------------------------------
else if (PLY::EST_AmbientRed == (*a).Semantic) else if (PLY::EST_AmbientRed == (*a).Semantic) {
{
aaiPositions[2][0] = _a; aaiPositions[2][0] = _a;
aaiTypes[2][0] = (*a).eType; aaiTypes[2][0] = (*a).eType;
} } else if (PLY::EST_AmbientGreen == (*a).Semantic) {
else if (PLY::EST_AmbientGreen == (*a).Semantic)
{
aaiPositions[2][1] = _a; aaiPositions[2][1] = _a;
aaiTypes[2][1] = (*a).eType; aaiTypes[2][1] = (*a).eType;
} } else if (PLY::EST_AmbientBlue == (*a).Semantic) {
else if (PLY::EST_AmbientBlue == (*a).Semantic)
{
aaiPositions[2][2] = _a; aaiPositions[2][2] = _a;
aaiTypes[2][2] = (*a).eType; aaiTypes[2][2] = (*a).eType;
} } else if (PLY::EST_AmbientAlpha == (*a).Semantic) {
else if (PLY::EST_AmbientAlpha == (*a).Semantic)
{
aaiPositions[2][3] = _a; aaiPositions[2][3] = _a;
aaiTypes[2][3] = (*a).eType; aaiTypes[2][3] = (*a).eType;
} }
} }
break; break;
} } else if (PLY::EEST_TextureFile == (*i).eSemantic) {
else if (PLY::EEST_TextureFile == (*i).eSemantic)
{
defaultTexture = (*i).szName; defaultTexture = (*i).szName;
} }
} }
@ -895,21 +881,17 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial*>* pvOut, std::string &def
pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED); pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED);
//default texture //default texture
if (!defaultTexture.empty()) if (!defaultTexture.empty()) {
{
const aiString name(defaultTexture.c_str()); const aiString name(defaultTexture.c_str());
pcHelper->AddProperty(&name, _AI_MATKEY_TEXTURE_BASE, aiTextureType_DIFFUSE, 0); pcHelper->AddProperty(&name, _AI_MATKEY_TEXTURE_BASE, aiTextureType_DIFFUSE, 0);
} }
if (!pointsOnly) if (!pointsOnly) {
{
const int two_sided = 1;
pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED); pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED);
} }
//set to wireframe, so when using this material info we can switch to points rendering //set to wireframe, so when using this material info we can switch to points rendering
if (pointsOnly) if (pointsOnly) {
{
const int wireframe = 1; const int wireframe = 1;
pcHelper->AddProperty(&wireframe, 1, AI_MATKEY_ENABLE_WIREFRAME); pcHelper->AddProperty(&wireframe, 1, AI_MATKEY_ENABLE_WIREFRAME);
} }
@ -917,9 +899,7 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial*>* pvOut, std::string &def
// add the newly created material instance to the list // add the newly created material instance to the list
pvOut->push_back(pcHelper); pvOut->push_back(pcHelper);
} }
} } else {
else
{
// generate a default material // generate a default material
aiMaterial *pcHelper = new aiMaterial(); aiMaterial *pcHelper = new aiMaterial();
@ -938,22 +918,19 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial*>* pvOut, std::string &def
// The face order is absolutely undefined for PLY, so we have to // The face order is absolutely undefined for PLY, so we have to
// use two-sided rendering to be sure it's ok. // use two-sided rendering to be sure it's ok.
if (!pointsOnly) if (!pointsOnly) {
{
const int two_sided = 1; const int two_sided = 1;
pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED); pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED);
} }
//default texture //default texture
if (!defaultTexture.empty()) if (!defaultTexture.empty()) {
{
const aiString name(defaultTexture.c_str()); const aiString name(defaultTexture.c_str());
pcHelper->AddProperty(&name, _AI_MATKEY_TEXTURE_BASE, aiTextureType_DIFFUSE, 0); pcHelper->AddProperty(&name, _AI_MATKEY_TEXTURE_BASE, aiTextureType_DIFFUSE, 0);
} }
//set to wireframe, so when using this material info we can switch to points rendering //set to wireframe, so when using this material info we can switch to points rendering
if (pointsOnly) if (pointsOnly) {
{
const int wireframe = 1; const int wireframe = 1;
pcHelper->AddProperty(&wireframe, 1, AI_MATKEY_ENABLE_WIREFRAME); pcHelper->AddProperty(&wireframe, 1, AI_MATKEY_ENABLE_WIREFRAME);
} }

Some files were not shown because too many files have changed in this diff Show More