|
@@ -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/GenericProperty.h>
|
|
#include <assimp/ParsingUtils.h>
|
|
#include <assimp/ParsingUtils.h>
|
|
-#include <assimp/fast_atof.h>
|
|
|
|
#include <assimp/SceneCombiner.h>
|
|
#include <assimp/SceneCombiner.h>
|
|
-#include <assimp/GenericProperty.h>
|
|
|
|
#include <assimp/SkeletonMeshBuilder.h>
|
|
#include <assimp/SkeletonMeshBuilder.h>
|
|
-#include <assimp/DefaultLogger.hpp>
|
|
|
|
|
|
+#include <assimp/fast_atof.h>
|
|
|
|
+#include <assimp/importerdesc.h>
|
|
#include <assimp/scene.h>
|
|
#include <assimp/scene.h>
|
|
|
|
+#include <assimp/DefaultLogger.hpp>
|
|
#include <assimp/IOSystem.hpp>
|
|
#include <assimp/IOSystem.hpp>
|
|
-#include <assimp/importerdesc.h>
|
|
|
|
|
|
|
|
#include <memory>
|
|
#include <memory>
|
|
|
|
|
|
@@ -81,9 +80,8 @@ static const aiImporterDesc desc = {
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ------------------------------------------------------------------------------------------------
|
|
// Recursive parsing of LWS files
|
|
// Recursive parsing of LWS files
|
|
-void LWS::Element::Parse (const char*& buffer)
|
|
|
|
-{
|
|
|
|
- for (;SkipSpacesAndLineEnd(&buffer);SkipLine(&buffer)) {
|
|
|
|
|
|
+void LWS::Element::Parse(const char *&buffer) {
|
|
|
|
+ for (; SkipSpacesAndLineEnd(&buffer); SkipLine(&buffer)) {
|
|
|
|
|
|
// begin of a new element with children
|
|
// begin of a new element with children
|
|
bool sub = false;
|
|
bool sub = false;
|
|
@@ -91,27 +89,26 @@ 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());
|
|
|
|
|
|
// copy data line - read token per token
|
|
// copy data line - read token per token
|
|
|
|
|
|
- const char* cur = buffer;
|
|
|
|
- while (!IsSpaceOrNewLine(*buffer)) ++buffer;
|
|
|
|
- children.back().tokens[0] = std::string(cur,(size_t) (buffer-cur));
|
|
|
|
|
|
+ const char *cur = buffer;
|
|
|
|
+ while (!IsSpaceOrNewLine(*buffer))
|
|
|
|
+ ++buffer;
|
|
|
|
+ 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
|
|
// follow LWS syntax, so we skip over it
|
|
// follow LWS syntax, so we skip over it
|
|
- for (;SkipSpacesAndLineEnd(&buffer);SkipLine(&buffer)) {
|
|
|
|
- if (!::strncmp(buffer,"EndPlugin",9)) {
|
|
|
|
|
|
+ for (; SkipSpacesAndLineEnd(&buffer); SkipLine(&buffer)) {
|
|
|
|
+ if (!::strncmp(buffer, "EndPlugin", 9)) {
|
|
//SkipLine(&buffer);
|
|
//SkipLine(&buffer);
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
@@ -120,8 +117,9 @@ void LWS::Element::Parse (const char*& buffer)
|
|
}
|
|
}
|
|
|
|
|
|
cur = buffer;
|
|
cur = buffer;
|
|
- while (!IsLineEnd(*buffer)) ++buffer;
|
|
|
|
- children.back().tokens[1] = std::string(cur,(size_t) (buffer-cur));
|
|
|
|
|
|
+ while (!IsLineEnd(*buffer))
|
|
|
|
+ ++buffer;
|
|
|
|
+ children.back().tokens[1] = std::string(cur, (size_t)(buffer - cur));
|
|
|
|
|
|
// parse more elements recursively
|
|
// parse more elements recursively
|
|
if (sub)
|
|
if (sub)
|
|
@@ -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()
|
|
|
|
- : configSpeedFlag(),
|
|
|
|
- io(),
|
|
|
|
- first(),
|
|
|
|
- last(),
|
|
|
|
- fps(),
|
|
|
|
- noSkeletonMesh()
|
|
|
|
-{
|
|
|
|
|
|
+LWSImporter::LWSImporter() :
|
|
|
|
+ configSpeedFlag(),
|
|
|
|
+ io(),
|
|
|
|
+ first(),
|
|
|
|
+ last(),
|
|
|
|
+ fps(),
|
|
|
|
+ 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;
|
|
@@ -162,69 +157,67 @@ bool LWSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler,bool c
|
|
uint32_t tokens[2];
|
|
uint32_t tokens[2];
|
|
tokens[0] = AI_MAKE_MAGIC("LWSC");
|
|
tokens[0] = AI_MAKE_MAGIC("LWSC");
|
|
tokens[1] = AI_MAKE_MAGIC("LWMO");
|
|
tokens[1] = AI_MAKE_MAGIC("LWMO");
|
|
- return CheckMagicToken(pIOHandler,pFile,tokens,2);
|
|
|
|
|
|
+ return CheckMagicToken(pIOHandler, pFile, tokens, 2);
|
|
}
|
|
}
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ------------------------------------------------------------------------------------------------
|
|
// 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));
|
|
|
|
|
|
// AI_CONFIG_IMPORT_LWS_ANIM_START
|
|
// AI_CONFIG_IMPORT_LWS_ANIM_START
|
|
first = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_LWS_ANIM_START,
|
|
first = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_LWS_ANIM_START,
|
|
- 150392 /* magic hack */);
|
|
|
|
|
|
+ 150392 /* magic hack */);
|
|
|
|
|
|
// AI_CONFIG_IMPORT_LWS_ANIM_END
|
|
// AI_CONFIG_IMPORT_LWS_ANIM_END
|
|
last = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_LWS_ANIM_END,
|
|
last = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_LWS_ANIM_END,
|
|
- 150392 /* magic hack */);
|
|
|
|
|
|
+ 150392 /* magic hack */);
|
|
|
|
|
|
if (last < first) {
|
|
if (last < first) {
|
|
- std::swap(last,first);
|
|
|
|
|
|
+ std::swap(last, first);
|
|
}
|
|
}
|
|
|
|
|
|
- noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
|
|
|
|
|
|
+ noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES, 0) != 0;
|
|
}
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ------------------------------------------------------------------------------------------------
|
|
// 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) {
|
|
- const char* c = (*it).tokens[1].c_str();
|
|
|
|
|
|
+ const char *c = (*it).tokens[1].c_str();
|
|
|
|
|
|
if ((*it).tokens[0] == "Key") {
|
|
if ((*it).tokens[0] == "Key") {
|
|
fill.keys.push_back(LWO::Key());
|
|
fill.keys.push_back(LWO::Key());
|
|
- LWO::Key& key = fill.keys.back();
|
|
|
|
|
|
+ LWO::Key &key = fill.keys.back();
|
|
|
|
|
|
float f;
|
|
float f;
|
|
SkipSpaces(&c);
|
|
SkipSpaces(&c);
|
|
- c = fast_atoreal_move<float>(c,key.value);
|
|
|
|
|
|
+ c = fast_atoreal_move<float>(c, key.value);
|
|
SkipSpaces(&c);
|
|
SkipSpaces(&c);
|
|
- c = fast_atoreal_move<float>(c,f);
|
|
|
|
|
|
+ c = fast_atoreal_move<float>(c, f);
|
|
|
|
|
|
key.time = f;
|
|
key.time = f;
|
|
|
|
|
|
- unsigned int span = strtoul10(c,&c), num = 0;
|
|
|
|
|
|
+ unsigned int span = strtoul10(c, &c), num = 0;
|
|
switch (span) {
|
|
switch (span) {
|
|
|
|
|
|
case 0:
|
|
case 0:
|
|
@@ -251,16 +244,15 @@ void LWSImporter::ReadEnvelope(const LWS::Element& dad, LWO::Envelope& fill )
|
|
default:
|
|
default:
|
|
ASSIMP_LOG_ERROR("LWS: Unknown span type");
|
|
ASSIMP_LOG_ERROR("LWS: Unknown span type");
|
|
}
|
|
}
|
|
- for (unsigned int i = 0; i < num;++i) {
|
|
|
|
|
|
+ for (unsigned int i = 0; i < num; ++i) {
|
|
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);
|
|
- fill.post = (LWO::PrePostBehaviour) strtoul10(c,&c);
|
|
|
|
|
|
+ fill.post = (LWO::PrePostBehaviour)strtoul10(c, &c);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -268,36 +260,35 @@ void LWSImporter::ReadEnvelope(const LWS::Element& dad, LWO::Envelope& fill )
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ------------------------------------------------------------------------------------------------
|
|
// Read animation channels in the old LightWave animation format
|
|
// Read animation channels in the old LightWave animation format
|
|
void LWSImporter::ReadEnvelope_Old(
|
|
void LWSImporter::ReadEnvelope_Old(
|
|
- std::list< LWS::Element >::const_iterator& it,
|
|
|
|
- const std::list< LWS::Element >::const_iterator& end,
|
|
|
|
- LWS::NodeDesc& nodes,
|
|
|
|
- unsigned int /*version*/)
|
|
|
|
-{
|
|
|
|
- unsigned int num,sub_num;
|
|
|
|
- if (++it == end)goto unexpected_end;
|
|
|
|
|
|
+ std::list<LWS::Element>::const_iterator &it,
|
|
|
|
+ const std::list<LWS::Element>::const_iterator &end,
|
|
|
|
+ LWS::NodeDesc &nodes,
|
|
|
|
+ unsigned int /*version*/) {
|
|
|
|
+ unsigned int num, sub_num;
|
|
|
|
+ if (++it == end) goto unexpected_end;
|
|
|
|
|
|
num = strtoul10((*it).tokens[0].c_str());
|
|
num = strtoul10((*it).tokens[0].c_str());
|
|
for (unsigned int i = 0; i < num; ++i) {
|
|
for (unsigned int i = 0; i < num; ++i) {
|
|
|
|
|
|
nodes.channels.push_back(LWO::Envelope());
|
|
nodes.channels.push_back(LWO::Envelope());
|
|
- LWO::Envelope& envl = nodes.channels.back();
|
|
|
|
|
|
+ LWO::Envelope &envl = nodes.channels.back();
|
|
|
|
|
|
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) {
|
|
|
|
|
|
- if (++it == end)goto unexpected_end;
|
|
|
|
|
|
+ if (++it == end) goto unexpected_end;
|
|
|
|
|
|
// parse value and time, skip the rest for the moment.
|
|
// parse value and time, skip the rest for the moment.
|
|
LWO::Key key;
|
|
LWO::Key key;
|
|
- const char* c = fast_atoreal_move<float>((*it).tokens[0].c_str(),key.value);
|
|
|
|
|
|
+ const char *c = fast_atoreal_move<float>((*it).tokens[0].c_str(), key.value);
|
|
SkipSpaces(&c);
|
|
SkipSpaces(&c);
|
|
float f;
|
|
float f;
|
|
- fast_atoreal_move<float>((*it).tokens[0].c_str(),f);
|
|
|
|
|
|
+ fast_atoreal_move<float>((*it).tokens[0].c_str(), f);
|
|
key.time = f;
|
|
key.time = f;
|
|
|
|
|
|
envl.keys.push_back(key);
|
|
envl.keys.push_back(key);
|
|
@@ -311,51 +302,49 @@ 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
|
|
// and return human-readable, but still machine-parsable and unique, strings.
|
|
// and return human-readable, but still machine-parsable and unique, strings.
|
|
- if (src.type == LWS::NodeDesc::OBJECT) {
|
|
|
|
|
|
+ if (src.type == LWS::NodeDesc::OBJECT) {
|
|
|
|
|
|
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 ++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);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- nd->mName.length = ::ai_snprintf(nd->mName.data, MAXLEN, "%s_(%08X)",src.name,combined);
|
|
|
|
|
|
+ nd->mName.length = ::ai_snprintf(nd->mName.data, MAXLEN, "%s_(%08X)", src.name, combined);
|
|
}
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ------------------------------------------------------------------------------------------------
|
|
// Recursively build the scenegraph
|
|
// Recursively build the scenegraph
|
|
-void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<AttachmentInfo>& attach,
|
|
|
|
- BatchLoader& batch,
|
|
|
|
- aiCamera**& camOut,
|
|
|
|
- aiLight**& lightOut,
|
|
|
|
- std::vector<aiNodeAnim*>& animOut)
|
|
|
|
-{
|
|
|
|
|
|
+void LWSImporter::BuildGraph(aiNode *nd, LWS::NodeDesc &src, std::vector<AttachmentInfo> &attach,
|
|
|
|
+ BatchLoader &batch,
|
|
|
|
+ aiCamera **&camOut,
|
|
|
|
+ aiLight **&lightOut,
|
|
|
|
+ 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);
|
|
|
|
- aiNode* ndAnim = nd;
|
|
|
|
|
|
+ SetupNodeName(nd, src);
|
|
|
|
+ aiNode *ndAnim = nd;
|
|
|
|
|
|
// If the node is an object
|
|
// If the node is an object
|
|
if (src.type == LWS::NodeDesc::OBJECT) {
|
|
if (src.type == LWS::NodeDesc::OBJECT) {
|
|
|
|
|
|
// If the object is from an external file, get it
|
|
// If the object is from an external file, get it
|
|
- aiScene* obj = NULL;
|
|
|
|
- if (src.path.length() ) {
|
|
|
|
|
|
+ aiScene *obj = NULL;
|
|
|
|
+ if (src.path.length()) {
|
|
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
|
|
@@ -366,7 +355,7 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
|
|
}
|
|
}
|
|
|
|
|
|
//Remove first node from obj (the old pivot), reset transform of second node (the mesh node)
|
|
//Remove first node from obj (the old pivot), reset transform of second node (the mesh node)
|
|
- aiNode* newRootNode = obj->mRootNode->mChildren[0];
|
|
|
|
|
|
+ aiNode *newRootNode = obj->mRootNode->mChildren[0];
|
|
obj->mRootNode->mChildren[0] = NULL;
|
|
obj->mRootNode->mChildren[0] = NULL;
|
|
delete obj->mRootNode;
|
|
delete obj->mRootNode;
|
|
|
|
|
|
@@ -384,7 +373,7 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
|
|
|
|
|
|
//Add the attachment node to it
|
|
//Add the attachment node to it
|
|
nd->mNumChildren = 1;
|
|
nd->mNumChildren = 1;
|
|
- nd->mChildren = new aiNode*[1];
|
|
|
|
|
|
+ nd->mChildren = new aiNode *[1];
|
|
nd->mChildren[0] = new aiNode();
|
|
nd->mChildren[0] = new aiNode();
|
|
nd->mChildren[0]->mParent = nd;
|
|
nd->mChildren[0]->mParent = nd;
|
|
nd->mChildren[0]->mTransformation.a4 = -src.pivotPos.x;
|
|
nd->mChildren[0]->mTransformation.a4 = -src.pivotPos.x;
|
|
@@ -397,16 +386,16 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
|
|
|
|
|
|
//Push attachment, if the object came from an external file
|
|
//Push attachment, if the object came from an external file
|
|
if (obj) {
|
|
if (obj) {
|
|
- attach.push_back(AttachmentInfo(obj,nd));
|
|
|
|
|
|
+ attach.push_back(AttachmentInfo(obj, nd));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// If object is a light source - setup a corresponding ai structure
|
|
// If object is a light source - setup a corresponding ai structure
|
|
else if (src.type == LWS::NodeDesc::LIGHT) {
|
|
else if (src.type == LWS::NodeDesc::LIGHT) {
|
|
- aiLight* lit = *lightOut++ = new aiLight();
|
|
|
|
|
|
+ aiLight *lit = *lightOut++ = new aiLight();
|
|
|
|
|
|
// compute final light color
|
|
// compute final light color
|
|
- lit->mColorDiffuse = lit->mColorSpecular = src.lightColor*src.lightIntensity;
|
|
|
|
|
|
+ lit->mColorDiffuse = lit->mColorSpecular = src.lightColor * src.lightIntensity;
|
|
|
|
|
|
// name to attach light to node -> unique due to LWs indexing system
|
|
// name to attach light to node -> unique due to LWs indexing system
|
|
lit->mName = nd->mName;
|
|
lit->mName = nd->mName;
|
|
@@ -415,14 +404,13 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
|
|
if (src.lightType == 2) { /* spot light */
|
|
if (src.lightType == 2) { /* spot light */
|
|
|
|
|
|
lit->mType = aiLightSource_SPOT;
|
|
lit->mType = aiLightSource_SPOT;
|
|
- lit->mAngleInnerCone = (float)AI_DEG_TO_RAD( src.lightConeAngle );
|
|
|
|
- lit->mAngleOuterCone = lit->mAngleInnerCone+(float)AI_DEG_TO_RAD( src.lightEdgeAngle );
|
|
|
|
|
|
+ lit->mAngleInnerCone = (float)AI_DEG_TO_RAD(src.lightConeAngle);
|
|
|
|
+ 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 lit->mType = aiLightSource_POINT;
|
|
|
|
|
|
+ } else
|
|
|
|
+ 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)
|
|
@@ -435,22 +423,22 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
|
|
|
|
|
|
// If object is a camera - setup a corresponding ai structure
|
|
// If object is a camera - setup a corresponding ai structure
|
|
else if (src.type == LWS::NodeDesc::CAMERA) {
|
|
else if (src.type == LWS::NodeDesc::CAMERA) {
|
|
- 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
|
|
cam->mName = nd->mName;
|
|
cam->mName = nd->mName;
|
|
}
|
|
}
|
|
|
|
|
|
// Get the node transformation from the LWO key
|
|
// Get the node transformation from the LWO key
|
|
- LWO::AnimResolver resolver(src.channels,fps);
|
|
|
|
|
|
+ LWO::AnimResolver resolver(src.channels, fps);
|
|
resolver.ExtractBindPose(ndAnim->mTransformation);
|
|
resolver.ExtractBindPose(ndAnim->mTransformation);
|
|
|
|
|
|
// .. and construct animation channels
|
|
// .. and construct animation channels
|
|
- aiNodeAnim* anim = NULL;
|
|
|
|
|
|
+ aiNodeAnim *anim = NULL;
|
|
|
|
|
|
if (first != last) {
|
|
if (first != last) {
|
|
- resolver.SetAnimationRange(first,last);
|
|
|
|
- resolver.ExtractAnimChannel(&anim,AI_LWO_ANIM_FLAG_SAMPLE_ANIMS|AI_LWO_ANIM_FLAG_START_AT_ZERO);
|
|
|
|
|
|
+ resolver.SetAnimationRange(first, last);
|
|
|
|
+ resolver.ExtractAnimChannel(&anim, AI_LWO_ANIM_FLAG_SAMPLE_ANIMS | AI_LWO_ANIM_FLAG_START_AT_ZERO);
|
|
if (anim) {
|
|
if (anim) {
|
|
anim->mNodeName = ndAnim->mName;
|
|
anim->mNodeName = ndAnim->mName;
|
|
animOut.push_back(anim);
|
|
animOut.push_back(anim);
|
|
@@ -459,27 +447,25 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
|
|
|
|
|
|
// Add children
|
|
// Add children
|
|
if (!src.children.empty()) {
|
|
if (!src.children.empty()) {
|
|
- nd->mChildren = new aiNode*[src.children.size()];
|
|
|
|
- for (std::list<LWS::NodeDesc*>::iterator it = src.children.begin(); it != src.children.end(); ++it) {
|
|
|
|
- aiNode* ndd = nd->mChildren[nd->mNumChildren++] = new aiNode();
|
|
|
|
|
|
+ nd->mChildren = new aiNode *[src.children.size()];
|
|
|
|
+ for (std::list<LWS::NodeDesc *>::iterator it = src.children.begin(); it != src.children.end(); ++it) {
|
|
|
|
+ aiNode *ndd = nd->mChildren[nd->mNumChildren++] = new aiNode();
|
|
ndd->mParent = nd;
|
|
ndd->mParent = nd;
|
|
|
|
|
|
- BuildGraph(ndd,**it,attach,batch,camOut,lightOut,animOut);
|
|
|
|
|
|
+ BuildGraph(ndd, **it, attach, batch, camOut, lightOut, animOut);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ------------------------------------------------------------------------------------------------
|
|
// 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 tmp = in;
|
|
|
|
|
|
+ } else
|
|
|
|
+ tmp = in;
|
|
|
|
|
|
if (io->Exists(tmp)) {
|
|
if (io->Exists(tmp)) {
|
|
return in;
|
|
return in;
|
|
@@ -503,35 +489,34 @@ 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;
|
|
}
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ------------------------------------------------------------------------------------------------
|
|
// Read file into given scene data structure
|
|
// Read file into given scene data structure
|
|
-void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
|
|
|
|
- IOSystem* pIOHandler)
|
|
|
|
-{
|
|
|
|
|
|
+void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene,
|
|
|
|
+ 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) {
|
|
|
|
- throw DeadlyImportError( "Failed to open LWS file " + pFile + ".");
|
|
|
|
|
|
+ if (file.get() == NULL) {
|
|
|
|
+ throw DeadlyImportError("Failed to open LWS 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 > mBuffer;
|
|
|
|
- TextFileToBuffer(file.get(),mBuffer);
|
|
|
|
|
|
+ std::vector<char> 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
|
|
BatchLoader batch(pIOHandler);
|
|
BatchLoader batch(pIOHandler);
|
|
-// batch.SetBasePath(pFile);
|
|
|
|
|
|
+ // 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;
|
|
@@ -541,7 +526,7 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
|
|
|
|
|
|
// check magic identifier, 'LWSC'
|
|
// check magic identifier, 'LWSC'
|
|
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;
|
|
@@ -554,54 +539,54 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
|
|
unsigned int version = strtoul10((*it).tokens[0].c_str());
|
|
unsigned int version = strtoul10((*it).tokens[0].c_str());
|
|
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.;
|
|
|
|
- fps = 25.; /* seems to be a good default frame rate */
|
|
|
|
|
|
+ last = 60.;
|
|
|
|
+ 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 straghtforward 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() */)
|
|
|
|
- first = strtoul10(c,&c)-1.; /* we're zero-based */
|
|
|
|
|
|
+ if (150392. != first /* see SetupProperties() */)
|
|
|
|
+ first = strtoul10(c, &c) - 1.; /* we're zero-based */
|
|
}
|
|
}
|
|
|
|
|
|
// 'LastFrame': end of animation slice
|
|
// 'LastFrame': end of animation slice
|
|
else if ((*it).tokens[0] == "LastFrame") {
|
|
else if ((*it).tokens[0] == "LastFrame") {
|
|
- if (150392. != last /* see SetupProperties() */)
|
|
|
|
- last = strtoul10(c,&c)-1.; /* we're zero-based */
|
|
|
|
|
|
+ if (150392. != last /* see SetupProperties() */)
|
|
|
|
+ last = strtoul10(c, &c) - 1.; /* we're zero-based */
|
|
}
|
|
}
|
|
|
|
|
|
// 'FramesPerSecond': frames per second
|
|
// 'FramesPerSecond': frames per second
|
|
else if ((*it).tokens[0] == "FramesPerSecond") {
|
|
else if ((*it).tokens[0] == "FramesPerSecond") {
|
|
- fps = strtoul10(c,&c);
|
|
|
|
|
|
+ fps = strtoul10(c, &c);
|
|
}
|
|
}
|
|
|
|
|
|
// 'LoadObjectLayer': load a layer of a specific LWO file
|
|
// 'LoadObjectLayer': load a layer of a specific LWO file
|
|
else if ((*it).tokens[0] == "LoadObjectLayer") {
|
|
else if ((*it).tokens[0] == "LoadObjectLayer") {
|
|
|
|
|
|
// get layer index
|
|
// get layer index
|
|
- const int layer = strtoul10(c,&c);
|
|
|
|
|
|
+ const int layer = strtoul10(c, &c);
|
|
|
|
|
|
// setup the layer to be loaded
|
|
// setup the layer to be loaded
|
|
BatchLoader::PropertyMap props;
|
|
BatchLoader::PropertyMap props;
|
|
- SetGenericProperty(props.ints,AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY,layer);
|
|
|
|
|
|
+ SetGenericProperty(props.ints, AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY, layer);
|
|
|
|
|
|
// add node to list
|
|
// add node to list
|
|
LWS::NodeDesc d;
|
|
LWS::NodeDesc d;
|
|
d.type = LWS::NodeDesc::OBJECT;
|
|
d.type = LWS::NodeDesc::OBJECT;
|
|
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;
|
|
|
|
- }
|
|
|
|
- else d.number = cur_object++;
|
|
|
|
|
|
+ d.number = strtoul16(c, &c) & AI_LWS_MASK;
|
|
|
|
+ } else
|
|
|
|
+ d.number = cur_object++;
|
|
|
|
|
|
// and add the file to the import list
|
|
// and add the file to the import list
|
|
SkipSpaces(&c);
|
|
SkipSpaces(&c);
|
|
- std::string path = FindLWOFile( c );
|
|
|
|
|
|
+ std::string path = FindLWOFile(c);
|
|
d.path = path;
|
|
d.path = path;
|
|
- 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++;
|
|
@@ -614,12 +599,12 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
|
|
d.type = LWS::NodeDesc::OBJECT;
|
|
d.type = LWS::NodeDesc::OBJECT;
|
|
|
|
|
|
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 d.number = cur_object++;
|
|
|
|
- std::string path = FindLWOFile( c );
|
|
|
|
- d.id = batch.AddLoadRequest(path,0,NULL);
|
|
|
|
|
|
+ } else
|
|
|
|
+ d.number = cur_object++;
|
|
|
|
+ std::string path = FindLWOFile(c);
|
|
|
|
+ d.id = batch.AddLoadRequest(path, 0, NULL);
|
|
|
|
|
|
d.path = path;
|
|
d.path = path;
|
|
nodes.push_back(d);
|
|
nodes.push_back(d);
|
|
@@ -632,10 +617,10 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
|
|
LWS::NodeDesc d;
|
|
LWS::NodeDesc d;
|
|
d.type = LWS::NodeDesc::OBJECT;
|
|
d.type = LWS::NodeDesc::OBJECT;
|
|
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 d.number = cur_object++;
|
|
|
|
|
|
+ } else
|
|
|
|
+ d.number = cur_object++;
|
|
d.name = c;
|
|
d.name = c;
|
|
nodes.push_back(d);
|
|
nodes.push_back(d);
|
|
|
|
|
|
@@ -662,13 +647,13 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
|
|
|
|
|
|
// important: index of channel
|
|
// important: index of channel
|
|
nodes.back().channels.push_back(LWO::Envelope());
|
|
nodes.back().channels.push_back(LWO::Envelope());
|
|
- LWO::Envelope& env = nodes.back().channels.back();
|
|
|
|
|
|
+ LWO::Envelope &env = nodes.back().channels.back();
|
|
|
|
|
|
env.index = strtoul10(c);
|
|
env.index = strtoul10(c);
|
|
|
|
|
|
// currently we can just interpret the standard channels 0...9
|
|
// currently we can just interpret the standard channels 0...9
|
|
// (hack) assume that index-i yields the binary channel type from LWO
|
|
// (hack) assume that index-i yields the binary channel type from LWO
|
|
- env.type = (LWO::EnvelopeType)(env.index+1);
|
|
|
|
|
|
+ env.type = (LWO::EnvelopeType)(env.index + 1);
|
|
|
|
|
|
}
|
|
}
|
|
// 'Envelope': a single animation channel
|
|
// 'Envelope': a single animation channel
|
|
@@ -676,18 +661,18 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
|
|
if (nodes.empty() || nodes.back().channels.empty())
|
|
if (nodes.empty() || nodes.back().channels.empty())
|
|
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'Envelope\'");
|
|
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'Envelope\'");
|
|
else {
|
|
else {
|
|
- ReadEnvelope((*it),nodes.back().channels.back());
|
|
|
|
|
|
+ ReadEnvelope((*it), nodes.back().channels.back());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// 'ObjectMotion': animation information for older lightwave formats
|
|
// 'ObjectMotion': animation information for older lightwave formats
|
|
- else if (version < 3 && ((*it).tokens[0] == "ObjectMotion" ||
|
|
|
|
- (*it).tokens[0] == "CameraMotion" ||
|
|
|
|
- (*it).tokens[0] == "LightMotion")) {
|
|
|
|
|
|
+ else if (version < 3 && ((*it).tokens[0] == "ObjectMotion" ||
|
|
|
|
+ (*it).tokens[0] == "CameraMotion" ||
|
|
|
|
+ (*it).tokens[0] == "LightMotion")) {
|
|
|
|
|
|
if (nodes.empty())
|
|
if (nodes.empty())
|
|
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'<Light|Object|Camera>Motion\'");
|
|
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'<Light|Object|Camera>Motion\'");
|
|
else {
|
|
else {
|
|
- ReadEnvelope_Old(it,root.children.end(),nodes.back(),version);
|
|
|
|
|
|
+ ReadEnvelope_Old(it, root.children.end(), nodes.back(), version);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// 'Pre/PostBehavior': pre/post animation behaviour for LWSC 2
|
|
// 'Pre/PostBehavior': pre/post animation behaviour for LWSC 2
|
|
@@ -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;
|
|
|
|
- env.pre = (LWO::PrePostBehaviour) strtoul10(c,&c); SkipSpaces(&c);
|
|
|
|
- env.post = (LWO::PrePostBehaviour) strtoul10(c,&c); SkipSpaces(&c);
|
|
|
|
|
|
+ LWO::Envelope &env = *envelopeIt;
|
|
|
|
+ env.pre = (LWO::PrePostBehaviour)strtoul10(c, &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") {
|
|
@@ -716,7 +704,7 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
|
|
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'ParentObject\'");
|
|
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'ParentObject\'");
|
|
|
|
|
|
else {
|
|
else {
|
|
- nodes.back().parent = strtoul10(c,&c) | (1u << 28u);
|
|
|
|
|
|
+ nodes.back().parent = strtoul10(c, &c) | (1u << 28u);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// 'AddCamera': add a camera to the scenegraph
|
|
// 'AddCamera': add a camera to the scenegraph
|
|
@@ -727,9 +715,9 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
|
|
d.type = LWS::NodeDesc::CAMERA;
|
|
d.type = LWS::NodeDesc::CAMERA;
|
|
|
|
|
|
if (version >= 4) { // handle LWSC 4 explicit ID
|
|
if (version >= 4) { // handle LWSC 4 explicit ID
|
|
- d.number = strtoul16(c,&c) & AI_LWS_MASK;
|
|
|
|
- }
|
|
|
|
- else d.number = cur_camera++;
|
|
|
|
|
|
+ d.number = strtoul16(c, &c) & AI_LWS_MASK;
|
|
|
|
+ } else
|
|
|
|
+ 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") {
|
|
@@ -749,9 +738,9 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
|
|
d.type = LWS::NodeDesc::LIGHT;
|
|
d.type = LWS::NodeDesc::LIGHT;
|
|
|
|
|
|
if (version >= 4) { // handle LWSC 4 explicit ID
|
|
if (version >= 4) { // handle LWSC 4 explicit ID
|
|
- d.number = strtoul16(c,&c) & AI_LWS_MASK;
|
|
|
|
- }
|
|
|
|
- else d.number = cur_light++;
|
|
|
|
|
|
+ d.number = strtoul16(c, &c) & AI_LWS_MASK;
|
|
|
|
+ } else
|
|
|
|
+ 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
|
|
@@ -809,11 +804,11 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
|
|
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightColor\'");
|
|
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightColor\'");
|
|
|
|
|
|
else {
|
|
else {
|
|
- c = fast_atoreal_move<float>(c, (float&) nodes.back().lightColor.r );
|
|
|
|
|
|
+ c = fast_atoreal_move<float>(c, (float &)nodes.back().lightColor.r);
|
|
SkipSpaces(&c);
|
|
SkipSpaces(&c);
|
|
- c = fast_atoreal_move<float>(c, (float&) nodes.back().lightColor.g );
|
|
|
|
|
|
+ c = fast_atoreal_move<float>(c, (float &)nodes.back().lightColor.g);
|
|
SkipSpaces(&c);
|
|
SkipSpaces(&c);
|
|
- c = fast_atoreal_move<float>(c, (float&) nodes.back().lightColor.b );
|
|
|
|
|
|
+ c = fast_atoreal_move<float>(c, (float &)nodes.back().lightColor.b);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -822,11 +817,11 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
|
|
if (nodes.empty())
|
|
if (nodes.empty())
|
|
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'PivotPosition\'");
|
|
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'PivotPosition\'");
|
|
else {
|
|
else {
|
|
- c = fast_atoreal_move<float>(c, (float&) nodes.back().pivotPos.x );
|
|
|
|
|
|
+ c = fast_atoreal_move<float>(c, (float &)nodes.back().pivotPos.x);
|
|
SkipSpaces(&c);
|
|
SkipSpaces(&c);
|
|
- c = fast_atoreal_move<float>(c, (float&) nodes.back().pivotPos.y );
|
|
|
|
|
|
+ c = fast_atoreal_move<float>(c, (float &)nodes.back().pivotPos.y);
|
|
SkipSpaces(&c);
|
|
SkipSpaces(&c);
|
|
- c = fast_atoreal_move<float>(c, (float&) nodes.back().pivotPos.z );
|
|
|
|
|
|
+ c = fast_atoreal_move<float>(c, (float &)nodes.back().pivotPos.z);
|
|
// Mark pivotPos as set
|
|
// Mark pivotPos as set
|
|
nodes.back().isPivotSet = true;
|
|
nodes.back().isPivotSet = true;
|
|
}
|
|
}
|
|
@@ -834,79 +829,80 @@ 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);
|
|
|
|
- (*dit).parent_resolved = &*it;
|
|
|
|
|
|
+ ndIt->children.push_back(&*dit);
|
|
|
|
+ (*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) {
|
|
|
|
- if (!(*it).parent_resolved)
|
|
|
|
- ++ no_parent;
|
|
|
|
|
|
+ for (std::list<LWS::NodeDesc>::iterator ndIt = nodes.begin(); ndIt != nodes.end(); ++ndIt) {
|
|
|
|
+ if (!ndIt->parent_resolved) {
|
|
|
|
+ ++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();
|
|
|
|
|
|
// and build the final output graph by attaching the loaded external
|
|
// and build the final output graph by attaching the loaded external
|
|
// files to ourselves. first build a master graph
|
|
// files to ourselves. first build a master graph
|
|
- aiScene* master = new aiScene();
|
|
|
|
- aiNode* nd = master->mRootNode = new aiNode();
|
|
|
|
|
|
+ aiScene *master = new aiScene();
|
|
|
|
+ aiNode *nd = master->mRootNode = new aiNode();
|
|
|
|
|
|
// allocate storage for cameras&lights
|
|
// allocate storage for cameras&lights
|
|
if (num_camera) {
|
|
if (num_camera) {
|
|
- master->mCameras = new aiCamera*[master->mNumCameras = num_camera];
|
|
|
|
|
|
+ master->mCameras = new aiCamera *[master->mNumCameras = num_camera];
|
|
}
|
|
}
|
|
- aiCamera** cams = master->mCameras;
|
|
|
|
|
|
+ aiCamera **cams = master->mCameras;
|
|
if (num_light) {
|
|
if (num_light) {
|
|
- master->mLights = new aiLight*[master->mNumLights = num_light];
|
|
|
|
|
|
+ master->mLights = new aiLight *[master->mNumLights = num_light];
|
|
}
|
|
}
|
|
- aiLight** lights = master->mLights;
|
|
|
|
|
|
+ aiLight **lights = master->mLights;
|
|
|
|
|
|
std::vector<AttachmentInfo> attach;
|
|
std::vector<AttachmentInfo> attach;
|
|
- std::vector<aiNodeAnim*> anims;
|
|
|
|
|
|
+ std::vector<aiNodeAnim *> anims;
|
|
|
|
|
|
nd->mName.Set("<LWSRoot>");
|
|
nd->mName.Set("<LWSRoot>");
|
|
- nd->mChildren = new aiNode*[no_parent];
|
|
|
|
- for (std::list<LWS::NodeDesc>::iterator it = nodes.begin(); it != nodes.end(); ++it) {
|
|
|
|
- if (!(*it).parent_resolved) {
|
|
|
|
- aiNode* ro = nd->mChildren[ nd->mNumChildren++ ] = new aiNode();
|
|
|
|
|
|
+ nd->mChildren = new aiNode *[no_parent];
|
|
|
|
+ for (std::list<LWS::NodeDesc>::iterator ndIt = nodes.begin(); ndIt != nodes.end(); ++ndIt) {
|
|
|
|
+ if (!ndIt->parent_resolved) {
|
|
|
|
+ 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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// create a master animation channel for us
|
|
// create a master animation channel for us
|
|
if (anims.size()) {
|
|
if (anims.size()) {
|
|
- master->mAnimations = new aiAnimation*[master->mNumAnimations = 1];
|
|
|
|
- aiAnimation* anim = master->mAnimations[0] = new aiAnimation();
|
|
|
|
|
|
+ master->mAnimations = new aiAnimation *[master->mNumAnimations = 1];
|
|
|
|
+ aiAnimation *anim = master->mAnimations[0] = new aiAnimation();
|
|
anim->mName.Set("LWSMasterAnim");
|
|
anim->mName.Set("LWSMasterAnim");
|
|
|
|
|
|
// LWS uses seconds as time units, but we convert to frames
|
|
// LWS uses seconds as time units, but we convert to frames
|
|
anim->mTicksPerSecond = fps;
|
|
anim->mTicksPerSecond = fps;
|
|
- anim->mDuration = last-(first-1); /* fixme ... zero or one-based?*/
|
|
|
|
|
|
+ anim->mDuration = last - (first - 1); /* fixme ... zero or one-based?*/
|
|
|
|
|
|
- anim->mChannels = new aiNodeAnim*[anim->mNumChannels = static_cast<unsigned int>(anims.size())];
|
|
|
|
- std::copy(anims.begin(),anims.end(),anim->mChannels);
|
|
|
|
|
|
+ anim->mChannels = new aiNodeAnim *[anim->mNumChannels = static_cast<unsigned int>(anims.size())];
|
|
|
|
+ std::copy(anims.begin(), anims.end(), anim->mChannels);
|
|
}
|
|
}
|
|
|
|
|
|
// convert the master scene to RH
|
|
// convert the master scene to RH
|
|
@@ -918,9 +914,10 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
|
|
flipper.Execute(master);
|
|
flipper.Execute(master);
|
|
|
|
|
|
// OK ... finally build the output graph
|
|
// OK ... finally build the output graph
|
|
- SceneCombiner::MergeScenes(&pScene,master,attach,
|
|
|
|
- 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));
|
|
|
|
|
|
+ SceneCombiner::MergeScenes(&pScene, master, attach,
|
|
|
|
+ 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));
|
|
|
|
|
|
// 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
|