Panagiotis Christopoulos Charitos 15 lat temu
rodzic
commit
33d49e2d6a

+ 57 - 3
blenderscripts/skeleton.py

@@ -1,5 +1,6 @@
 import sys
 import os
+from struct import pack
 from copy import deepcopy
 from Blender import Mathutils
 from Blender.Mathutils import *
@@ -91,7 +92,7 @@ def getBlSkeletonFromBlObj(obj):
 # getAnkiSkeletonScript                                                                                                =
 #=======================================================================================================================
 def getAnkiSkeletonScript(skeleton, flipYZ):	
-	ftxt = "" # file text
+	"""ftxt = "" # file text
 	
 	# write the file
 	boneNames = skeleton.bones.keys()
@@ -145,8 +146,61 @@ def getAnkiSkeletonScript(skeleton, flipYZ):
 		
 		ftxt += "\n"	
 		
-	return ftxt
+	return ftxt"""
+
+	buff = pack("8s", "ANKISKEL")
+	
+	boneNames = skeleton.bones.keys()
+	boneNames.sort() # the bones are written in alpabetical order
+	
+	buff += pack("I", len(boneNames))
 	
+	for boneName in boneNames:	
+		bone = skeleton.bones[boneName]
+		
+		# name
+		str_ = bone.name
+		buff += pack("I" + str(len(str_)) + "s", len(str_), str_)
+		
+		# head
+		co = bone.head["ARMATURESPACE"]
+		if flipYZ:
+			buff += pack("fff", co.x, co.z, -co.y)
+		else:
+			buff += pack("fff", co.x, co.y, co.z)
+		
+		# tail
+		co = bone.tail["ARMATURESPACE"]
+		if flipYZ:
+			buff += pack("fff", co.x, co.z, -co.y)
+		else:
+			buff += pack("fff", co.x, co.y, co.z)
+	
+		# matrix
+		m4 = bone.matrix["ARMATURESPACE"].copy()
+		
+		if flipYZ:
+			m4 = multMatrix(m4, rotMat)
+			
+		for i_ in range(0, 4):
+			for j_ in range(0, 4):
+				buff += pack("f", m4[j_][i_])
+				
+		# write the parent
+		if not bone.parent:
+			buff += pack("I", 0xFFFFFF)
+		else:
+			buff += pack("I", boneNames.index(bone.parent.name))
+			
+		# write the childs
+		buff += pack("I", len(bone.children))
+		
+		for child in bone.children:
+			buff += pack("I", boneNames.index(child.name))
+			
+	# end!
+	return buff
+		
 	
 #=======================================================================================================================
 # export                                                                                                               =
@@ -160,7 +214,7 @@ def export(skeletonInit):
 	print("Trying to export skeleton \"" + skeleton.name + "\"")
 	
 	filename = skeletonInit.saveDir + skeleton.name + ".skel"
-	file = open(filename, "w")
+	file = open(filename, "wb")
 	file.write(getAnkiSkeletonScript(skeleton, skeletonInit.flipYZ))
 	
 	print("Skeleton exported!! \"" + filename + "\"")	

+ 70 - 74
src/Resources/Skeleton.cpp

@@ -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());
+	}
 }

+ 1 - 1
src/Resources/Skeleton.h

@@ -19,7 +19,7 @@
 /// 3 * floats: head
 /// 3 * floats: tail
 /// 16 * floats: armature space matrix
-/// uint: parent id
+/// uint: parent id, if it has no parent then its 0xFFFFFFFF
 /// uint: children number
 /// n * child: children
 /// 

+ 1 - 1
src/Util/BinaryStream.cpp

@@ -72,7 +72,7 @@ std::string BinaryStream::readString()
 	const uint buffSize = 1024;
 	if((size + 1) > buffSize)
 	{
-		throw EXCEPTION("String bigger than default");
+		throw EXCEPTION("String bigger than temp buffer");
 	}
 	char buff[buffSize];
 	read(buff, size);