Merge branch 'master' into GLTF2_recursive_references_fix
commit
2006eeed85
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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 *));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<>
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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()) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
1656
code/M3D/m3d.h
1656
code/M3D/m3d.h
File diff suppressed because it is too large
Load Diff
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) :
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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){
|
||||||
|
|
|
@ -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
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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")
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 ) {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,9 +45,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef AI_PLYLOADER_H_INCLUDED
|
#ifndef AI_PLYLOADER_H_INCLUDED
|
||||||
#define AI_PLYLOADER_H_INCLUDED
|
#define AI_PLYLOADER_H_INCLUDED
|
||||||
|
|
||||||
|
#include "PlyParser.h"
|
||||||
#include <assimp/BaseImporter.h>
|
#include <assimp/BaseImporter.h>
|
||||||
#include <assimp/types.h>
|
#include <assimp/types.h>
|
||||||
#include "PlyParser.h"
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
struct aiNode;
|
struct aiNode;
|
||||||
|
@ -62,14 +61,11 @@ using namespace PLY;
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Importer class to load the stanford PLY file format
|
/** Importer class to load the stanford PLY file format
|
||||||
*/
|
*/
|
||||||
class PLYImporter : public BaseImporter
|
class PLYImporter : public BaseImporter {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
PLYImporter();
|
PLYImporter();
|
||||||
~PLYImporter();
|
~PLYImporter();
|
||||||
|
|
||||||
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.
|
||||||
|
@ -88,7 +84,6 @@ public:
|
||||||
void LoadFace(const PLY::Element *pcElement, const PLY::ElementInstance *instElement, unsigned int pos);
|
void LoadFace(const PLY::Element *pcElement, const PLY::ElementInstance *instElement, unsigned int pos);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Return importer meta information.
|
/** Return importer meta information.
|
||||||
* See #BaseImporter::GetInfo for the details
|
* See #BaseImporter::GetInfo for the details
|
||||||
|
@ -102,7 +97,6 @@ protected:
|
||||||
void InternReadFile(const std::string &pFile, aiScene *pScene,
|
void InternReadFile(const std::string &pFile, aiScene *pScene,
|
||||||
IOSystem *pIOHandler);
|
IOSystem *pIOHandler);
|
||||||
|
|
||||||
protected:
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Extract a material list from the DOM
|
/** Extract a material list from the DOM
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -62,7 +62,7 @@ bool ArmaturePopulate::IsActive(unsigned int pFlags) const {
|
||||||
return (pFlags & aiProcess_PopulateArmatureData) != 0;
|
return (pFlags & aiProcess_PopulateArmatureData) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArmaturePopulate::SetupProperties(const Importer *pImp) {
|
void ArmaturePopulate::SetupProperties(const Importer *) {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,9 +162,9 @@ void ArmaturePopulate::BuildNodeList(const aiNode *current_node,
|
||||||
// A bone stack allows us to have multiple armatures, with the same bone names
|
// A bone stack allows us to have multiple armatures, with the same bone names
|
||||||
// A bone stack allows us also to retrieve bones true transform even with
|
// A bone stack allows us also to retrieve bones true transform even with
|
||||||
// duplicate names :)
|
// duplicate names :)
|
||||||
void ArmaturePopulate::BuildBoneStack(aiNode *current_node,
|
void ArmaturePopulate::BuildBoneStack(aiNode *,
|
||||||
const aiNode *root_node,
|
const aiNode *root_node,
|
||||||
const aiScene *scene,
|
const aiScene*,
|
||||||
const std::vector<aiBone *> &bones,
|
const std::vector<aiBone *> &bones,
|
||||||
std::map<aiBone *, aiNode *> &bone_stack,
|
std::map<aiBone *, aiNode *> &bone_stack,
|
||||||
std::vector<aiNode *> &node_stack) {
|
std::vector<aiNode *> &node_stack) {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue