|
|
@@ -1,7 +1,7 @@
|
|
|
#include <cstring>
|
|
|
+#include <fstream>
|
|
|
#include "Skeleton.h"
|
|
|
-#include "Scanner.h"
|
|
|
-#include "Parser.h"
|
|
|
+#include "BinaryStream.h"
|
|
|
|
|
|
|
|
|
//======================================================================================================================
|
|
|
@@ -9,97 +9,93 @@
|
|
|
//======================================================================================================================
|
|
|
void Skeleton::load(const char* filename)
|
|
|
{
|
|
|
- Scanner scanner(filename);
|
|
|
- const Scanner::Token* token;
|
|
|
-
|
|
|
- //
|
|
|
- // BONES NUM
|
|
|
- //
|
|
|
- token = &scanner.getNextToken();
|
|
|
- if(token->getCode() != Scanner::TC_NUMBER || token->getDataType() != Scanner::DT_INT)
|
|
|
+ std::ifstream fs;
|
|
|
+ fs.open(filename);
|
|
|
+ if(!fs.good())
|
|
|
{
|
|
|
- throw PARSER_EXCEPTION_EXPECTED("integer");
|
|
|
+ throw EXCEPTION("Cannot open \"" + filename + "\"");
|
|
|
}
|
|
|
- bones.resize(token->getValue().getInt(), Bone());
|
|
|
|
|
|
- for(uint i=0; i<bones.size(); i++)
|
|
|
+ try
|
|
|
{
|
|
|
- Bone& bone = bones[i];
|
|
|
- bone.id = i;
|
|
|
+ BinaryStream bs(fs.rdbuf());
|
|
|
|
|
|
- ///@todo clean
|
|
|
- /*Mat3 m3_(Axisang(-PI/2, Vec3(1,0,0)));
|
|
|
- Mat4 m4_(Vec3(0), m3_, 1.0);*/
|
|
|
+ // Bones num
|
|
|
+ uint bonesNum = bs.readUint();
|
|
|
+ bones.resize(bonesNum);
|
|
|
|
|
|
- // NAME
|
|
|
- token = &scanner.getNextToken();
|
|
|
- if(token->getCode() != Scanner::TC_STRING)
|
|
|
+ // For all bones
|
|
|
+ for(uint i=0; i<bones.size(); i++)
|
|
|
{
|
|
|
- throw PARSER_EXCEPTION_EXPECTED("string");
|
|
|
- }
|
|
|
- bone.name = token->getValue().getString();
|
|
|
+ Bone& bone = bones[i];
|
|
|
+ bone.id = i;
|
|
|
|
|
|
- // head
|
|
|
- Parser::parseMathVector(scanner, bone.head);
|
|
|
+ bone.name = bs.readString();
|
|
|
|
|
|
- //bone.head = m3_ * bone.head;
|
|
|
+ for(uint j=0; j<3; j++)
|
|
|
+ {
|
|
|
+ bone.head[i] = bs.readFloat();
|
|
|
+ }
|
|
|
|
|
|
- // tail
|
|
|
- Parser::parseMathVector(scanner, bone.tail);
|
|
|
+ for(uint j=0; j<3; j++)
|
|
|
+ {
|
|
|
+ bone.tail[i] = bs.readFloat();
|
|
|
+ }
|
|
|
|
|
|
- //bone.tail = m3_ * bone.tail;
|
|
|
+ // Matrix
|
|
|
+ Mat4 m4;
|
|
|
+ for(uint j=0; j<16; j++)
|
|
|
+ {
|
|
|
+ m4[i] = bs.readFloat();
|
|
|
+ }
|
|
|
|
|
|
- // matrix
|
|
|
- Mat4 m4;
|
|
|
- Parser::parseMathVector(scanner, m4);
|
|
|
+ // Matrix for real
|
|
|
+ bone.rotSkelSpace = m4.getRotationPart();
|
|
|
+ bone.tslSkelSpace = m4.getTranslationPart();
|
|
|
+ Mat4 MAi(m4.getInverse());
|
|
|
+ bone.rotSkelSpaceInv = MAi.getRotationPart();
|
|
|
+ bone.tslSkelSpaceInv = MAi.getTranslationPart();
|
|
|
|
|
|
- //m4 = m4_ * m4;
|
|
|
+ // Parent
|
|
|
+ uint parentId = bs.readUint();
|
|
|
+ if(parentId == 0xFFFFFFFF)
|
|
|
+ {
|
|
|
+ bone.parent = NULL;
|
|
|
+ }
|
|
|
+ else if(parentId >= bonesNum)
|
|
|
+ {
|
|
|
+ throw EXCEPTION("Incorrect parent id");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ bone.parent = &bones[parentId];
|
|
|
+ }
|
|
|
|
|
|
- // matrix for real
|
|
|
- bone.rotSkelSpace = m4.getRotationPart();
|
|
|
- bone.tslSkelSpace = m4.getTranslationPart();
|
|
|
- Mat4 MAi(m4.getInverse());
|
|
|
- bone.rotSkelSpaceInv = MAi.getRotationPart();
|
|
|
- bone.tslSkelSpaceInv = MAi.getTranslationPart();
|
|
|
+ // Children
|
|
|
+ uint childsNum = bs.readUint();
|
|
|
|
|
|
- // parent
|
|
|
- token = &scanner.getNextToken();
|
|
|
- if((token->getCode() != Scanner::TC_NUMBER || token->getDataType() != Scanner::DT_INT) &&
|
|
|
- (token->getCode() != Scanner::TC_IDENTIFIER || strcmp(token->getValue().getString(), "NULL") != 0))
|
|
|
- {
|
|
|
- throw PARSER_EXCEPTION_EXPECTED("integer or NULL");
|
|
|
- }
|
|
|
+ if(childsNum > Bone::MAX_CHILDS_PER_BONE)
|
|
|
+ {
|
|
|
+ throw EXCEPTION("Children for bone \"" + bone.getName() + "\" exceed the max");
|
|
|
+ }
|
|
|
|
|
|
- if(token->getCode() == Scanner::TC_IDENTIFIER)
|
|
|
- {
|
|
|
- bone.parent = NULL;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- bone.parent = &bones[token->getValue().getInt()];
|
|
|
- }
|
|
|
+ bone.childsNum = childsNum;
|
|
|
|
|
|
- // childs
|
|
|
- token = &scanner.getNextToken();
|
|
|
- if(token->getCode() != Scanner::TC_NUMBER || token->getDataType() != Scanner::DT_INT)
|
|
|
- {
|
|
|
- throw PARSER_EXCEPTION_EXPECTED("integer");
|
|
|
- }
|
|
|
+ for(uint j=0; j<bone.childsNum; j++)
|
|
|
+ {
|
|
|
+ uint id = bs.readUint();
|
|
|
|
|
|
- if(token->getValue().getInt() > Bone::MAX_CHILDS_PER_BONE)
|
|
|
- {
|
|
|
- throw PARSER_EXCEPTION("Childs for bone \"" + bone.getName() + "\" exceed the max");
|
|
|
- }
|
|
|
+ if(id >= bonesNum)
|
|
|
+ {
|
|
|
+ throw EXCEPTION("Incorrect child id");
|
|
|
+ }
|
|
|
|
|
|
- bone.childsNum = token->getValue().getInt();
|
|
|
- for(int j=0; j<bone.childsNum; j++)
|
|
|
- {
|
|
|
- token = &scanner.getNextToken();
|
|
|
- if(token->getCode() != Scanner::TC_NUMBER || token->getDataType() != Scanner::DT_INT)
|
|
|
- {
|
|
|
- throw PARSER_EXCEPTION_EXPECTED("integer");
|
|
|
+ bone.childs[j] = &bones[id];
|
|
|
}
|
|
|
- bone.childs[j] = &bones[token->getValue().getInt()];
|
|
|
}
|
|
|
- } // for all bones
|
|
|
+ }
|
|
|
+ catch(Exception& e)
|
|
|
+ {
|
|
|
+ throw EXCEPTION("File \"" + filename + "\": " + e.what());
|
|
|
+ }
|
|
|
}
|