Merge pull request #3197 from assimp/kimkulling_dev

Kimkulling dev
pull/3204/head
Kim Kulling 2020-05-03 18:58:49 +02:00 committed by GitHub
commit 8675bb0912
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 199 additions and 234 deletions

View File

@ -134,6 +134,12 @@ OPTION ( ASSIMP_IGNORE_GIT_HASH
OFF OFF
) )
IF ( WIN32 )
OPTION ( ASSIMP_BUILD_ASSIMP_VIEW
"If the Assimp view tool is built. (requires DirectX)"
OFF )
ENDIF()
IF (IOS AND NOT ASSIMP_HUNTER_ENABLED) IF (IOS AND NOT ASSIMP_HUNTER_ENABLED)
IF (NOT CMAKE_BUILD_TYPE) IF (NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE "Release") SET(CMAKE_BUILD_TYPE "Release")
@ -512,19 +518,19 @@ ENDIF()
SET ( ASSIMP_BUILD_ARCHITECTURE "" CACHE STRING SET ( ASSIMP_BUILD_ARCHITECTURE "" CACHE STRING
"describe the current architecture." "describe the current architecture."
) )
IF ( ASSIMP_BUILD_ARCHITECTURE STREQUAL "") IF( ASSIMP_BUILD_ARCHITECTURE STREQUAL "")
ELSE () ELSE()
ADD_DEFINITIONS ( -D'ASSIMP_BUILD_ARCHITECTURE="${ASSIMP_BUILD_ARCHITECTURE}"' ) ADD_DEFINITIONS ( -D'ASSIMP_BUILD_ARCHITECTURE="${ASSIMP_BUILD_ARCHITECTURE}"' )
ENDIF () ENDIF()
# ${CMAKE_GENERATOR} # ${CMAKE_GENERATOR}
SET ( ASSIMP_BUILD_COMPILER "" CACHE STRING SET ( ASSIMP_BUILD_COMPILER "" CACHE STRING
"describe the current compiler." "describe the current compiler."
) )
IF ( ASSIMP_BUILD_COMPILER STREQUAL "") IF( ASSIMP_BUILD_COMPILER STREQUAL "")
ELSE () ELSE()
ADD_DEFINITIONS ( -D'ASSIMP_BUILD_COMPILER="${ASSIMP_BUILD_COMPILER}"' ) ADD_DEFINITIONS ( -D'ASSIMP_BUILD_COMPILER="${ASSIMP_BUILD_COMPILER}"' )
ENDIF () ENDIF()
MARK_AS_ADVANCED ( ASSIMP_BUILD_ARCHITECTURE ASSIMP_BUILD_COMPILER ) MARK_AS_ADVANCED ( ASSIMP_BUILD_ARCHITECTURE ASSIMP_BUILD_COMPILER )

View File

@ -9,16 +9,17 @@ Licensed under a 3-clause BSD license. See the LICENSE file for more information
#ifndef ASSIMP_BUILD_NO_EXPORT #ifndef ASSIMP_BUILD_NO_EXPORT
#ifndef ASSIMP_BUILD_NO_ASSJSON_EXPORTER #ifndef ASSIMP_BUILD_NO_ASSJSON_EXPORTER
#include <assimp/Importer.hpp> #include <assimp/scene.h>
#include <assimp/Exporter.hpp> #include <assimp/Exporter.hpp>
#include <assimp/IOStream.hpp> #include <assimp/IOStream.hpp>
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
#include <assimp/scene.h> #include <assimp/Importer.hpp>
#include <assimp/Exceptional.h>
#include <sstream>
#include <limits>
#include <cassert> #include <cassert>
#include <limits>
#include <memory> #include <memory>
#include <sstream>
#define CURRENT_FORMAT_VERSION 100 #define CURRENT_FORMAT_VERSION 100
@ -28,11 +29,11 @@ Licensed under a 3-clause BSD license. See the LICENSE file for more information
#include "mesh_splitter.h" #include "mesh_splitter.h"
extern "C" { extern "C" {
#include "cencode.h" #include "cencode.h"
} }
namespace Assimp { namespace Assimp {
void ExportAssimp2Json(const char*, Assimp::IOSystem*, const aiScene*, const Assimp::ExportProperties*); void ExportAssimp2Json(const char *, Assimp::IOSystem *, const aiScene *, const Assimp::ExportProperties *);
// small utility class to simplify serializing the aiScene to Json // small utility class to simplify serializing the aiScene to Json
class JSONWriter { class JSONWriter {
@ -42,10 +43,8 @@ public:
Flag_WriteSpecialFloats = 0x2, Flag_WriteSpecialFloats = 0x2,
}; };
JSONWriter(Assimp::IOStream& out, unsigned int flags = 0u) JSONWriter(Assimp::IOStream &out, unsigned int flags = 0u) :
: out(out) out(out), first(), flags(flags) {
, first()
, flags(flags) {
// make sure that all formatting happens using the standard, C locale and not the user's current locale // make sure that all formatting happens using the standard, C locale and not the user's current locale
buff.imbue(std::locale("C")); buff.imbue(std::locale("C"));
} }
@ -68,30 +67,30 @@ public:
indent.erase(indent.end() - 1); indent.erase(indent.end() - 1);
} }
void Key(const std::string& name) { void Key(const std::string &name) {
AddIndentation(); AddIndentation();
Delimit(); Delimit();
buff << '\"' + name + "\": "; buff << '\"' + name + "\": ";
} }
template<typename Literal> template <typename Literal>
void Element(const Literal& name) { void Element(const Literal &name) {
AddIndentation(); AddIndentation();
Delimit(); Delimit();
LiteralToString(buff, name) << '\n'; LiteralToString(buff, name) << '\n';
} }
template<typename Literal> template <typename Literal>
void SimpleValue(const Literal& s) { void SimpleValue(const Literal &s) {
LiteralToString(buff, s) << '\n'; LiteralToString(buff, s) << '\n';
} }
void SimpleValue(const void* buffer, size_t len) { void SimpleValue(const void *buffer, size_t len) {
base64_encodestate s; base64_encodestate s;
base64_init_encodestate(&s); base64_init_encodestate(&s);
char* const cur_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), cur_out, &s); const int n = base64_encode_block(reinterpret_cast<const char *>(buffer), static_cast<int>(len), cur_out, &s);
cur_out[n + base64_encode_blockend(cur_out + n, &s)] = '\0'; cur_out[n + base64_encode_blockend(cur_out + n, &s)] = '\0';
@ -156,21 +155,20 @@ public:
void Delimit() { void Delimit() {
if (!first) { if (!first) {
buff << ','; buff << ',';
} } else {
else {
buff << ' '; buff << ' ';
first = false; first = false;
} }
} }
private: private:
template<typename Literal> template <typename Literal>
std::stringstream& LiteralToString(std::stringstream& stream, const Literal& s) { std::stringstream &LiteralToString(std::stringstream &stream, const Literal &s) {
stream << s; stream << s;
return stream; return stream;
} }
std::stringstream& LiteralToString(std::stringstream& stream, const aiString& s) { std::stringstream &LiteralToString(std::stringstream &stream, const aiString &s) {
std::string t; std::string t;
// escape backslashes and single quotes, both would render the JSON invalid if left as is // escape backslashes and single quotes, both would render the JSON invalid if left as is
@ -189,7 +187,7 @@ private:
return stream; return stream;
} }
std::stringstream& LiteralToString(std::stringstream& stream, float f) { std::stringstream &LiteralToString(std::stringstream &stream, float f) {
if (!std::numeric_limits<float>::is_iec559) { if (!std::numeric_limits<float>::is_iec559) {
// on a non IEEE-754 platform, we make no assumptions about the representation or existence // on a non IEEE-754 platform, we make no assumptions about the representation or existence
// of special floating-point numbers. // of special floating-point numbers.
@ -228,7 +226,7 @@ private:
} }
private: private:
Assimp::IOStream& out; Assimp::IOStream &out;
std::string indent, newline; std::string indent, newline;
std::stringstream buff; std::stringstream buff;
bool first; bool first;
@ -236,7 +234,7 @@ private:
unsigned int flags; unsigned int flags;
}; };
void Write(JSONWriter& out, const aiVector3D& ai, bool is_elem = true) { void Write(JSONWriter &out, const aiVector3D &ai, bool is_elem = true) {
out.StartArray(is_elem); out.StartArray(is_elem);
out.Element(ai.x); out.Element(ai.x);
out.Element(ai.y); out.Element(ai.y);
@ -244,7 +242,7 @@ void Write(JSONWriter& out, const aiVector3D& ai, bool is_elem = true) {
out.EndArray(); out.EndArray();
} }
void Write(JSONWriter& out, const aiQuaternion& ai, bool is_elem = true) { void Write(JSONWriter &out, const aiQuaternion &ai, bool is_elem = true) {
out.StartArray(is_elem); out.StartArray(is_elem);
out.Element(ai.w); out.Element(ai.w);
out.Element(ai.x); out.Element(ai.x);
@ -253,7 +251,7 @@ void Write(JSONWriter& out, const aiQuaternion& ai, bool is_elem = true) {
out.EndArray(); out.EndArray();
} }
void Write(JSONWriter& out, const aiColor3D& ai, bool is_elem = true) { void Write(JSONWriter &out, const aiColor3D &ai, bool is_elem = true) {
out.StartArray(is_elem); out.StartArray(is_elem);
out.Element(ai.r); out.Element(ai.r);
out.Element(ai.g); out.Element(ai.g);
@ -261,7 +259,7 @@ void Write(JSONWriter& out, const aiColor3D& ai, bool is_elem = true) {
out.EndArray(); out.EndArray();
} }
void Write(JSONWriter& out, const aiMatrix4x4& ai, bool is_elem = true) { void Write(JSONWriter &out, const aiMatrix4x4 &ai, bool is_elem = true) {
out.StartArray(is_elem); out.StartArray(is_elem);
for (unsigned int x = 0; x < 4; ++x) { for (unsigned int x = 0; x < 4; ++x) {
for (unsigned int y = 0; y < 4; ++y) { for (unsigned int y = 0; y < 4; ++y) {
@ -271,7 +269,7 @@ void Write(JSONWriter& out, const aiMatrix4x4& ai, bool is_elem = true) {
out.EndArray(); out.EndArray();
} }
void Write(JSONWriter& out, const aiBone& ai, bool is_elem = true) { void Write(JSONWriter &out, const aiBone &ai, bool is_elem = true) {
out.StartObj(is_elem); out.StartObj(is_elem);
out.Key("name"); out.Key("name");
@ -292,7 +290,7 @@ void Write(JSONWriter& out, const aiBone& ai, bool is_elem = true) {
out.EndObj(); out.EndObj();
} }
void Write(JSONWriter& out, const aiFace& ai, bool is_elem = true) { void Write(JSONWriter &out, const aiFace &ai, bool is_elem = true) {
out.StartArray(is_elem); out.StartArray(is_elem);
for (unsigned int i = 0; i < ai.mNumIndices; ++i) { for (unsigned int i = 0; i < ai.mNumIndices; ++i) {
out.Element(ai.mIndices[i]); out.Element(ai.mIndices[i]);
@ -300,7 +298,7 @@ void Write(JSONWriter& out, const aiFace& ai, bool is_elem = true) {
out.EndArray(); out.EndArray();
} }
void Write(JSONWriter& out, const aiMesh& ai, bool is_elem = true) { void Write(JSONWriter &out, const aiMesh &ai, bool is_elem = true) {
out.StartObj(is_elem); out.StartObj(is_elem);
out.Key("name"); out.Key("name");
@ -411,7 +409,7 @@ void Write(JSONWriter& out, const aiMesh& ai, bool is_elem = true) {
out.EndObj(); out.EndObj();
} }
void Write(JSONWriter& out, const aiNode& ai, bool is_elem = true) { void Write(JSONWriter &out, const aiNode &ai, bool is_elem = true) {
out.StartObj(is_elem); out.StartObj(is_elem);
out.Key("name"); out.Key("name");
@ -441,13 +439,13 @@ void Write(JSONWriter& out, const aiNode& ai, bool is_elem = true) {
out.EndObj(); out.EndObj();
} }
void Write(JSONWriter& out, const aiMaterial& ai, bool is_elem = true) { void Write(JSONWriter &out, const aiMaterial &ai, bool is_elem = true) {
out.StartObj(is_elem); out.StartObj(is_elem);
out.Key("properties"); out.Key("properties");
out.StartArray(); out.StartArray();
for (unsigned int i = 0; i < ai.mNumProperties; ++i) { for (unsigned int i = 0; i < ai.mNumProperties; ++i) {
const aiMaterialProperty* const prop = ai.mProperties[i]; const aiMaterialProperty *const prop = ai.mProperties[i];
out.StartObj(true); out.StartObj(true);
out.Key("key"); out.Key("key");
out.SimpleValue(prop->mKey); out.SimpleValue(prop->mKey);
@ -465,12 +463,11 @@ void Write(JSONWriter& out, const aiMaterial& ai, bool is_elem = true) {
if (prop->mDataLength / sizeof(float) > 1) { if (prop->mDataLength / sizeof(float) > 1) {
out.StartArray(); out.StartArray();
for (unsigned int ii = 0; ii < prop->mDataLength / sizeof(float); ++ii) { for (unsigned int ii = 0; ii < prop->mDataLength / sizeof(float); ++ii) {
out.Element(reinterpret_cast<float*>(prop->mData)[ii]); out.Element(reinterpret_cast<float *>(prop->mData)[ii]);
} }
out.EndArray(); out.EndArray();
} } else {
else { out.SimpleValue(*reinterpret_cast<float *>(prop->mData));
out.SimpleValue(*reinterpret_cast<float*>(prop->mData));
} }
break; break;
@ -478,27 +475,23 @@ void Write(JSONWriter& out, const aiMaterial& ai, bool is_elem = true) {
if (prop->mDataLength / sizeof(int) > 1) { if (prop->mDataLength / sizeof(int) > 1) {
out.StartArray(); out.StartArray();
for (unsigned int ii = 0; ii < prop->mDataLength / sizeof(int); ++ii) { for (unsigned int ii = 0; ii < prop->mDataLength / sizeof(int); ++ii) {
out.Element(reinterpret_cast<int*>(prop->mData)[ii]); out.Element(reinterpret_cast<int *>(prop->mData)[ii]);
} }
out.EndArray(); out.EndArray();
} else { } else {
out.SimpleValue(*reinterpret_cast<int*>(prop->mData)); out.SimpleValue(*reinterpret_cast<int *>(prop->mData));
} }
break; break;
case aiPTI_String: case aiPTI_String: {
{
aiString s; aiString s;
aiGetMaterialString(&ai, prop->mKey.data, prop->mSemantic, prop->mIndex, &s); aiGetMaterialString(&ai, prop->mKey.data, prop->mSemantic, prop->mIndex, &s);
out.SimpleValue(s); out.SimpleValue(s);
} } break;
break; case aiPTI_Buffer: {
case aiPTI_Buffer:
{
// binary data is written as series of hex-encoded octets // binary data is written as series of hex-encoded octets
out.SimpleValue(prop->mData, prop->mDataLength); out.SimpleValue(prop->mData, prop->mDataLength);
} } break;
break;
default: default:
assert(false); assert(false);
} }
@ -510,7 +503,7 @@ void Write(JSONWriter& out, const aiMaterial& ai, bool is_elem = true) {
out.EndObj(); out.EndObj();
} }
void Write(JSONWriter& out, const aiTexture& ai, bool is_elem = true) { void Write(JSONWriter &out, const aiTexture &ai, bool is_elem = true) {
out.StartObj(is_elem); out.StartObj(is_elem);
out.Key("width"); out.Key("width");
@ -525,13 +518,12 @@ void Write(JSONWriter& out, const aiTexture& ai, bool is_elem = true) {
out.Key("data"); out.Key("data");
if (!ai.mHeight) { if (!ai.mHeight) {
out.SimpleValue(ai.pcData, ai.mWidth); out.SimpleValue(ai.pcData, ai.mWidth);
} } else {
else {
out.StartArray(); out.StartArray();
for (unsigned int y = 0; y < ai.mHeight; ++y) { for (unsigned int y = 0; y < ai.mHeight; ++y) {
out.StartArray(true); out.StartArray(true);
for (unsigned int x = 0; x < ai.mWidth; ++x) { for (unsigned int x = 0; x < ai.mWidth; ++x) {
const aiTexel& tx = ai.pcData[y*ai.mWidth + x]; const aiTexel &tx = ai.pcData[y * ai.mWidth + x];
out.StartArray(true); out.StartArray(true);
out.Element(static_cast<unsigned int>(tx.r)); out.Element(static_cast<unsigned int>(tx.r));
out.Element(static_cast<unsigned int>(tx.g)); out.Element(static_cast<unsigned int>(tx.g));
@ -547,7 +539,7 @@ void Write(JSONWriter& out, const aiTexture& ai, bool is_elem = true) {
out.EndObj(); out.EndObj();
} }
void Write(JSONWriter& out, const aiLight& ai, bool is_elem = true) { void Write(JSONWriter &out, const aiLight &ai, bool is_elem = true) {
out.StartObj(is_elem); out.StartObj(is_elem);
out.Key("name"); out.Key("name");
@ -585,7 +577,6 @@ void Write(JSONWriter& out, const aiLight& ai, bool is_elem = true) {
if (ai.mType != aiLightSource_POINT) { if (ai.mType != aiLightSource_POINT) {
out.Key("direction"); out.Key("direction");
Write(out, ai.mDirection, false); Write(out, ai.mDirection, false);
} }
if (ai.mType != aiLightSource_DIRECTIONAL) { if (ai.mType != aiLightSource_DIRECTIONAL) {
@ -596,7 +587,7 @@ void Write(JSONWriter& out, const aiLight& ai, bool is_elem = true) {
out.EndObj(); out.EndObj();
} }
void Write(JSONWriter& out, const aiNodeAnim& ai, bool is_elem = true) { void Write(JSONWriter &out, const aiNodeAnim &ai, bool is_elem = true) {
out.StartObj(is_elem); out.StartObj(is_elem);
out.Key("name"); out.Key("name");
@ -612,7 +603,7 @@ void Write(JSONWriter& out, const aiNodeAnim& ai, bool is_elem = true) {
out.Key("positionkeys"); out.Key("positionkeys");
out.StartArray(); out.StartArray();
for (unsigned int n = 0; n < ai.mNumPositionKeys; ++n) { for (unsigned int n = 0; n < ai.mNumPositionKeys; ++n) {
const aiVectorKey& pos = ai.mPositionKeys[n]; const aiVectorKey &pos = ai.mPositionKeys[n];
out.StartArray(true); out.StartArray(true);
out.Element(pos.mTime); out.Element(pos.mTime);
Write(out, pos.mValue); Write(out, pos.mValue);
@ -625,7 +616,7 @@ void Write(JSONWriter& out, const aiNodeAnim& ai, bool is_elem = true) {
out.Key("rotationkeys"); out.Key("rotationkeys");
out.StartArray(); out.StartArray();
for (unsigned int n = 0; n < ai.mNumRotationKeys; ++n) { for (unsigned int n = 0; n < ai.mNumRotationKeys; ++n) {
const aiQuatKey& rot = ai.mRotationKeys[n]; const aiQuatKey &rot = ai.mRotationKeys[n];
out.StartArray(true); out.StartArray(true);
out.Element(rot.mTime); out.Element(rot.mTime);
Write(out, rot.mValue); Write(out, rot.mValue);
@ -638,7 +629,7 @@ void Write(JSONWriter& out, const aiNodeAnim& ai, bool is_elem = true) {
out.Key("scalingkeys"); out.Key("scalingkeys");
out.StartArray(); out.StartArray();
for (unsigned int n = 0; n < ai.mNumScalingKeys; ++n) { for (unsigned int n = 0; n < ai.mNumScalingKeys; ++n) {
const aiVectorKey& scl = ai.mScalingKeys[n]; const aiVectorKey &scl = ai.mScalingKeys[n];
out.StartArray(true); out.StartArray(true);
out.Element(scl.mTime); out.Element(scl.mTime);
Write(out, scl.mValue); Write(out, scl.mValue);
@ -649,7 +640,7 @@ void Write(JSONWriter& out, const aiNodeAnim& ai, bool is_elem = true) {
out.EndObj(); out.EndObj();
} }
void Write(JSONWriter& out, const aiAnimation& ai, bool is_elem = true) { void Write(JSONWriter &out, const aiAnimation &ai, bool is_elem = true) {
out.StartObj(is_elem); out.StartObj(is_elem);
out.Key("name"); out.Key("name");
@ -670,7 +661,7 @@ void Write(JSONWriter& out, const aiAnimation& ai, bool is_elem = true) {
out.EndObj(); out.EndObj();
} }
void Write(JSONWriter& out, const aiCamera& ai, bool is_elem = true) { void Write(JSONWriter &out, const aiCamera &ai, bool is_elem = true) {
out.StartObj(is_elem); out.StartObj(is_elem);
out.Key("name"); out.Key("name");
@ -697,7 +688,7 @@ void Write(JSONWriter& out, const aiCamera& ai, bool is_elem = true) {
out.EndObj(); out.EndObj();
} }
void WriteFormatInfo(JSONWriter& out) { void WriteFormatInfo(JSONWriter &out) {
out.StartObj(); out.StartObj();
out.Key("format"); out.Key("format");
out.SimpleValue("\"assimp2json\""); out.SimpleValue("\"assimp2json\"");
@ -706,7 +697,7 @@ void WriteFormatInfo(JSONWriter& out) {
out.EndObj(); out.EndObj();
} }
void Write(JSONWriter& out, const aiScene& ai) { void Write(JSONWriter &out, const aiScene &ai) {
out.StartObj(); out.StartObj();
out.Key("__metadata__"); out.Key("__metadata__");
@ -774,15 +765,14 @@ void Write(JSONWriter& out, const aiScene& ai) {
out.EndObj(); out.EndObj();
} }
void ExportAssimp2Json(const char *file, Assimp::IOSystem *io, const aiScene *scene, const Assimp::ExportProperties *) {
void ExportAssimp2Json(const char* file, Assimp::IOSystem* io, const aiScene* scene, const Assimp::ExportProperties*) {
std::unique_ptr<Assimp::IOStream> str(io->Open(file, "wt")); std::unique_ptr<Assimp::IOStream> str(io->Open(file, "wt"));
if (!str) { if (!str) {
//throw Assimp::DeadlyExportError("could not open output file"); throw DeadlyExportError("could not open output file");
} }
// get a copy of the scene so we can modify it // get a copy of the scene so we can modify it
aiScene* scenecopy_tmp; aiScene *scenecopy_tmp;
aiCopyScene(scene, &scenecopy_tmp); aiCopyScene(scene, &scenecopy_tmp);
try { try {
@ -795,15 +785,14 @@ void ExportAssimp2Json(const char* file, Assimp::IOSystem* io, const aiScene* sc
JSONWriter s(*str, JSONWriter::Flag_WriteSpecialFloats); JSONWriter s(*str, JSONWriter::Flag_WriteSpecialFloats);
Write(s, *scenecopy_tmp); Write(s, *scenecopy_tmp);
} } catch (...) {
catch (...) {
aiFreeScene(scenecopy_tmp); aiFreeScene(scenecopy_tmp);
throw; throw;
} }
aiFreeScene(scenecopy_tmp); aiFreeScene(scenecopy_tmp);
} }
} } // namespace Assimp
#endif // ASSIMP_BUILD_NO_ASSJSON_EXPORTER #endif // ASSIMP_BUILD_NO_ASSJSON_EXPORTER
#endif // ASSIMP_BUILD_NO_EXPORT #endif // ASSIMP_BUILD_NO_EXPORT

View File

@ -65,7 +65,7 @@ using namespace Assimp::Formatter;
BlenderBMeshConverter::BlenderBMeshConverter(const Mesh *mesh) : BlenderBMeshConverter::BlenderBMeshConverter(const Mesh *mesh) :
BMesh(mesh), BMesh(mesh),
triMesh(nullptr) { triMesh(nullptr) {
// empty ai_assert(nullptr != mesh);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -117,14 +115,16 @@ void LWS::Element::Parse(const char *&buffer) {
} }
cur = buffer; cur = buffer;
while (!IsLineEnd(*buffer)) while (!IsLineEnd(*buffer)) {
++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
if (sub) if (sub) {
children.back().Parse(buffer); children.back().Parse(buffer);
} }
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -149,8 +149,9 @@ LWSImporter::~LWSImporter() {
// 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;
}
// if check for extension is not enough, check for the magic tokens LWSC and LWMO // if check for extension is not enough, check for the magic tokens LWSC and LWMO
if (!extension.length() || checkSig) { if (!extension.length() || checkSig) {
@ -199,7 +200,7 @@ void LWSImporter::ReadEnvelope(const LWS::Element &dad, LWO::Envelope &fill) {
// 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) {
@ -219,7 +220,6 @@ void LWSImporter::ReadEnvelope(const LWS::Element &dad, LWO::Envelope &fill) {
unsigned int span = strtoul10(c, &c), num = 0; unsigned int span = strtoul10(c, &c), num = 0;
switch (span) { switch (span) {
case 0: case 0:
key.inter = LWO::IT_TCB; key.inter = LWO::IT_TCB;
num = 5; num = 5;
@ -276,7 +276,9 @@ void LWSImporter::ReadEnvelope_Old(
envl.index = i; envl.index = i;
envl.type = (LWO::EnvelopeType)(i + 1); envl.type = (LWO::EnvelopeType)(i + 1);
if (++it == end) goto unexpected_end; if (++it == end) {
goto unexpected_end;
}
sub_num = strtoul10((*it).tokens[0].c_str()); sub_num = strtoul10((*it).tokens[0].c_str());
for (unsigned int n = 0; n < sub_num; ++n) { for (unsigned int n = 0; n < sub_num; ++n) {
@ -311,10 +313,11 @@ void LWSImporter::SetupNodeName(aiNode *nd, LWS::NodeDesc &src) {
if (src.path.length()) { if (src.path.length()) {
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 } else {
++s; ++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);
@ -325,7 +328,7 @@ void LWSImporter::SetupNodeName(aiNode *nd, LWS::NodeDesc &src) {
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Recursively build the scenegraph // Recursively build the scene-graph
void LWSImporter::BuildGraph(aiNode *nd, LWS::NodeDesc &src, std::vector<AttachmentInfo> &attach, void LWSImporter::BuildGraph(aiNode *nd, LWS::NodeDesc &src, std::vector<AttachmentInfo> &attach,
BatchLoader &batch, BatchLoader &batch,
aiCamera **&camOut, aiCamera **&camOut,
@ -409,20 +412,19 @@ void LWSImporter::BuildGraph(aiNode *nd, LWS::NodeDesc &src, std::vector<Attachm
} 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
if (src.lightFalloffType == 1)
lit->mAttenuationConstant = 1.f;
else if (src.lightFalloffType == 1)
lit->mAttenuationLinear = 1.f;
else
lit->mAttenuationQuadratic = 1.f;
} }
// If object is a camera - setup a corresponding ai structure // fixme: no proper handling of light falloffs yet
else if (src.type == LWS::NodeDesc::CAMERA) { if (src.lightFalloffType == 1) {
lit->mAttenuationConstant = 1.f;
} else if (src.lightFalloffType == 2) {
lit->mAttenuationLinear = 1.f;
} else {
lit->mAttenuationQuadratic = 1.f;
}
} else if (src.type == LWS::NodeDesc::CAMERA) { // If object is a camera - setup a corresponding ai structure
aiCamera *cam = *camOut++ = new aiCamera(); aiCamera *cam = *camOut++ = new aiCamera();
// name to attach cam to node -> unique due to LWs indexing system // name to attach cam to node -> unique due to LWs indexing system
@ -434,7 +436,7 @@ void LWSImporter::BuildGraph(aiNode *nd, LWS::NodeDesc &src, std::vector<Attachm
resolver.ExtractBindPose(ndAnim->mTransformation); resolver.ExtractBindPose(ndAnim->mTransformation);
// .. and construct animation channels // .. and construct animation channels
aiNodeAnim *anim = NULL; aiNodeAnim *anim = nullptr;
if (first != last) { if (first != last) {
resolver.SetAnimationRange(first, last); resolver.SetAnimationRange(first, last);
@ -461,11 +463,10 @@ 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(in);
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 }
tmp = in;
if (io->Exists(tmp)) { if (io->Exists(tmp)) {
return in; return in;
@ -495,13 +496,12 @@ 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"));
// 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 LWS file " + pFile + "."); throw DeadlyImportError("Failed to open LWS file " + pFile + ".");
} }
@ -514,9 +514,8 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene,
const char *dummy = &mBuffer[0]; const char *dummy = &mBuffer[0];
root.Parse(dummy); root.Parse(dummy);
// Construct a Batchimporter to read more files recursively // Construct a Batch-importer to read more files recursively
BatchLoader batch(pIOHandler); BatchLoader batch(pIOHandler);
// batch.SetBasePath(pFile);
// Construct an array to receive the flat output graph // Construct an array to receive the flat output graph
std::list<LWS::NodeDesc> nodes; std::list<LWS::NodeDesc> nodes;
@ -528,11 +527,13 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene,
bool motion_file = false; bool motion_file = false;
std::list<LWS::Element>::const_iterator it = root.children.begin(); std::list<LWS::Element>::const_iterator it = root.children.begin();
if ((*it).tokens[0] == "LWMO") if ((*it).tokens[0] == "LWMO") {
motion_file = true; motion_file = true;
}
if ((*it).tokens[0] != "LWSC" && !motion_file) if ((*it).tokens[0] != "LWSC" && !motion_file) {
throw DeadlyImportError("LWS: Not a LightWave scene, magic tag LWSC not found"); throw DeadlyImportError("LWS: Not a LightWave scene, magic tag LWSC not found");
}
// get file format version and print to log // get file format version and print to log
++it; ++it;
@ -540,31 +541,26 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene,
ASSIMP_LOG_INFO("LWS file format version is " + (*it).tokens[0]); ASSIMP_LOG_INFO("LWS file format version is " + (*it).tokens[0]);
first = 0.; first = 0.;
last = 60.; last = 60.;
fps = 25.; /* seems to be a good default frame rate */ fps = 25.; // seems to be a good default frame rate
// Now read all elements in a very straghtforward manner // Now read all elements in a very straightforward manner
for (; it != root.children.end(); ++it) { for (; it != root.children.end(); ++it) {
const char *c = (*it).tokens[1].c_str(); const char *c = (*it).tokens[1].c_str();
// 'FirstFrame': begin of animation slice // 'FirstFrame': begin of animation slice
if ((*it).tokens[0] == "FirstFrame") { if ((*it).tokens[0] == "FirstFrame") {
if (150392. != first /* see SetupProperties() */) // see SetupProperties()
first = strtoul10(c, &c) - 1.; /* we're zero-based */ if (150392. != first ) {
first = strtoul10(c, &c) - 1.; // we're zero-based
} }
} else if ((*it).tokens[0] == "LastFrame") { // 'LastFrame': end of animation slice
// 'LastFrame': end of animation slice // see SetupProperties()
else if ((*it).tokens[0] == "LastFrame") { if (150392. != last ) {
if (150392. != last /* see SetupProperties() */) last = strtoul10(c, &c) - 1.; // we're zero-based
last = strtoul10(c, &c) - 1.; /* we're zero-based */
} }
} else if ((*it).tokens[0] == "FramesPerSecond") { // 'FramesPerSecond': frames per second
// 'FramesPerSecond': frames per second
else if ((*it).tokens[0] == "FramesPerSecond") {
fps = strtoul10(c, &c); fps = strtoul10(c, &c);
} } else if ((*it).tokens[0] == "LoadObjectLayer") { // 'LoadObjectLayer': load a layer of a specific LWO file
// 'LoadObjectLayer': load a layer of a specific LWO file
else if ((*it).tokens[0] == "LoadObjectLayer") {
// get layer index // get layer index
const int layer = strtoul10(c, &c); const int layer = strtoul10(c, &c);
@ -579,8 +575,9 @@ 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);
@ -589,10 +586,8 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene,
d.id = batch.AddLoadRequest(path, 0, &props); d.id = batch.AddLoadRequest(path, 0, &props);
nodes.push_back(d); nodes.push_back(d);
num_object++; ++num_object;
} } else if ((*it).tokens[0] == "LoadObject") { // 'LoadObject': load a LWO file into the scene-graph
// 'LoadObject': load a LWO file into the scenegraph
else if ((*it).tokens[0] == "LoadObject") {
// add node to list // add node to list
LWS::NodeDesc d; LWS::NodeDesc d;
@ -601,17 +596,16 @@ 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);
d.path = path; d.path = path;
nodes.push_back(d); nodes.push_back(d);
num_object++; ++num_object;
} } else if ((*it).tokens[0] == "AddNullObject") { // 'AddNullObject': add a dummy node to the hierarchy
// 'AddNullObject': add a dummy node to the hierarchy
else if ((*it).tokens[0] == "AddNullObject") {
// add node to list // add node to list
LWS::NodeDesc d; LWS::NodeDesc d;
@ -619,8 +613,9 @@ 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);
@ -775,7 +770,6 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene,
else if ((*it).tokens[0] == "LightFalloffType") { else if ((*it).tokens[0] == "LightFalloffType") {
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 else
nodes.back().lightFalloffType = strtoul10(c); nodes.back().lightFalloffType = strtoul10(c);

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -48,17 +47,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AssetLib/LWO/LWOFileData.h" #include "AssetLib/LWO/LWOFileData.h"
#include <assimp/SceneCombiner.h>
#include <assimp/BaseImporter.h> #include <assimp/BaseImporter.h>
#include <assimp/SceneCombiner.h>
struct aiImporterDesc; struct aiImporterDesc;
namespace Assimp { namespace Assimp {
class BatchLoader; class BatchLoader;
class Importer; class Importer;
class IOSystem; class IOSystem;
namespace LWS { namespace LWS {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Represents an element in a LWS file. /** Represents an element in a LWS file.
@ -66,18 +65,16 @@ namespace Assimp {
* This can either be a single data line - <name> <value> or a data * This can either be a single data line - <name> <value> or a data
* group - { name <data_line0> ... n } * group - { name <data_line0> ... n }
*/ */
class Element class Element {
{
public: public:
Element() Element() {}
{}
// first: name, second: rest // first: name, second: rest
std::string tokens[2]; std::string tokens[2];
std::list<Element> children; std::list<Element> children;
//! Recursive parsing function //! Recursive parsing function
void Parse (const char*& buffer); void Parse(const char *&buffer);
}; };
#define AI_LWS_MASK (0xffffffff >> 4u) #define AI_LWS_MASK (0xffffffff >> 4u)
@ -85,23 +82,9 @@ public:
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Represents a LWS scenegraph element /** Represents a LWS scenegraph element
*/ */
struct NodeDesc struct NodeDesc {
{ NodeDesc() :
NodeDesc() type(), id(), number(0), parent(0), name(""), isPivotSet(false), lightColor(1.f, 1.f, 1.f), lightIntensity(1.f), lightType(0), lightFalloffType(0), lightConeAngle(45.f), lightEdgeAngle(), parent_resolved(NULL) {}
: type()
, id()
, number (0)
, parent (0)
, name ("")
, isPivotSet (false)
, lightColor (1.f,1.f,1.f)
, lightIntensity (1.f)
, lightType (0)
, lightFalloffType (0)
, lightConeAngle (45.f)
, lightEdgeAngle()
, parent_resolved (NULL)
{}
enum { enum {
@ -122,17 +105,15 @@ struct NodeDesc
unsigned int parent; unsigned int parent;
// lights & cameras & dummies: name // lights & cameras & dummies: name
const char* name; const char *name;
// animation channels // animation channels
std::list< LWO::Envelope > channels; std::list<LWO::Envelope> channels;
// position of pivot point // position of pivot point
aiVector3D pivotPos; aiVector3D pivotPos;
bool isPivotSet; bool isPivotSet;
// color of light source // color of light source
aiColor3D lightColor; aiColor3D lightColor;
@ -151,17 +132,14 @@ struct NodeDesc
// soft cone angle of (spot) light source // soft cone angle of (spot) light source
float lightEdgeAngle; float lightEdgeAngle;
// list of resolved children // list of resolved children
std::list< NodeDesc* > children; std::list<NodeDesc *> children;
// resolved parent node // resolved parent node
NodeDesc* parent_resolved; NodeDesc *parent_resolved;
// for std::find() // for std::find()
bool operator == (unsigned int num) const { bool operator==(unsigned int num) const {
if (!num) if (!num)
return false; return false;
unsigned int _type = num >> 28u; unsigned int _type = num >> 28u;
@ -179,73 +157,65 @@ struct NodeDesc
* contain mainly descriptions how LWO objects are composed together * contain mainly descriptions how LWO objects are composed together
* in a scene. * in a scene.
*/ */
class LWSImporter : public BaseImporter class LWSImporter : public BaseImporter {
{
public: public:
LWSImporter(); LWSImporter();
~LWSImporter(); ~LWSImporter();
public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Check whether we can read a specific file // Check whether we can read a specific file
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
bool checkSig) const; bool checkSig) const;
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Get list of supported extensions // Get list of supported extensions
const aiImporterDesc* GetInfo () const; const aiImporterDesc *GetInfo() const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Import file into given scene data structure // Import file into given scene data structure
void InternReadFile( const std::string& pFile, aiScene* pScene, void InternReadFile(const std::string &pFile, aiScene *pScene,
IOSystem* pIOHandler); IOSystem *pIOHandler);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Setup import properties // Setup import properties
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer *pImp);
private: private:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Read an envelope description // Read an envelope description
void ReadEnvelope(const LWS::Element& dad, LWO::Envelope& out ); void ReadEnvelope(const LWS::Element &dad, LWO::Envelope &out);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Read an envelope description for the older LW file format // Read an envelope description for the older LW file format
void ReadEnvelope_Old(std::list< LWS::Element >::const_iterator& it, void ReadEnvelope_Old(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);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Setup a nice name for a node // Setup a nice name for a node
void SetupNodeName(aiNode* nd, LWS::NodeDesc& src); void SetupNodeName(aiNode *nd, LWS::NodeDesc &src);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Recursively build the scenegraph // Recursively build the scenegraph
void BuildGraph(aiNode* nd, void BuildGraph(aiNode *nd,
LWS::NodeDesc& src, LWS::NodeDesc &src,
std::vector<AttachmentInfo>& attach, std::vector<AttachmentInfo> &attach,
BatchLoader& batch, BatchLoader &batch,
aiCamera**& camOut, aiCamera **&camOut,
aiLight**& lightOut, aiLight **&lightOut,
std::vector<aiNodeAnim*>& animOut); std::vector<aiNodeAnim *> &animOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Try several dirs until we find the right location of a LWS file. // Try several dirs until we find the right location of a LWS file.
std::string FindLWOFile(const std::string& in); std::string FindLWOFile(const std::string &in);
private: private:
bool configSpeedFlag; bool configSpeedFlag;
IOSystem* io; IOSystem *io;
double first,last,fps; double first, last, fps;
bool noSkeletonMesh; bool noSkeletonMesh;
}; };

View File

@ -66,10 +66,16 @@ public:
: runtime_error(errorText) { : runtime_error(errorText) {
// empty // empty
} }
}; };
typedef DeadlyImportError DeadlyExportError; class DeadlyExportError : public runtime_error {
public:
/** Constructor with arguments */
explicit DeadlyExportError(const std::string &errorText) :
runtime_error(errorText) {
// empty
}
};
#ifdef _MSC_VER #ifdef _MSC_VER
# pragma warning(default : 4275) # pragma warning(default : 4275)