quaternion для armature.

Тут я дернул арматуру. Теперь другая задача - нужно двигать кости в арматуре. Буду идту по протоптанной дорожке. Буду дописывать проект с арматурой. Надо дернуть кватернионы для текущего фрема. Надо сначала сделать фреймы. А что? Взял в режиме pose mode подвигал кости, нажал 'a' они выделились, нажал 'i' выбрал loc rot и вот
поза в блендере
первый фрейм

Небольшой питон скриптик get-animation.py поможет дернуть quaternion для костей в позе.
import Blender
from Blender import *
from Blender.Mathutils import *

from multiprocessing import Process, Lock
from multiprocessing.sharedctypes import Value, Array
from ctypes import Structure, c_double
import math

#вытягиваемая арматура
myArmatureName = 'Armature'

#Экранное имя арматуры
myScrArmatureName = 'Armature'

#путь к экспорту
exportPathStr = 'D:\\FLEX\\3D\\proj-3d-engine\\pose-port\\animation.txt';

#число кадров
frameBeginIndex = 1;
frameEndIndex = 2;










boneQuat = '';

for frameCount in range(frameEndIndex - frameBeginIndex):
	currentFrame = frameCount + frameBeginIndex
	Blender.Set('curframe',currentFrame)
	Blender.Redraw()
	
	scn= Scene.GetCurrent()
	
	for a in scn.objects:
		print a.name
		if a.name==myScrArmatureName: 
			armOb = a
			pose = armOb.getPose()
	
	print 'frame '+str(currentFrame)
	pbones = pose.bones.values()
	boneQuat+='{'
	i=0;
	for pbone in pbones:
		q = pbone.quat[:]
		boneQuat+=pbone.name+':[%f,%f,%f,%f]'%(q[0],q[1],q[2],q[3])
		i+=1
		if i!=len(pbones):
			#последний элемент
			boneQuat+=','
	boneQuat+='}'
	if currentFrame != frameEndIndex - frameBeginIndex:
		#последний элемент фрейма
		boneQuat+=','
	boneQuat+='\n'

outFile = open(exportPathStr, 'w')

outFile.write('animObjAr = ['+boneQuat+'];\n')



Выдает
animObjAr = [{sArmL:[0.999206,0.039788,-0.000215,-0.002157],head:[1.000000,0.000000,0.000000,0.000000],legL:[0.975661,0.218267,0.017558,-0.011712],neck:[1.000000,0.000000,0.000000,0.000000],boneL:[0.989382,0.145211,-0.005604,-0.002268],sLegR:[1.000000,0.000000,0.000000,0.000000],fLegL:[0.977195,-0.201136,0.054589,0.040680],armR:[0.895740,-0.444142,-0.014938,0.012814],sLegL:[0.968993,0.081530,0.002762,-0.233235],armL:[0.995347,0.095550,-0.001316,-0.012353],sArmR:[0.623257,0.780979,0.026264,0.030552],fLegR:[1.000000,0.000000,0.000000,0.000000],boneR:[0.999780,-0.020124,0.000035,-0.005978],legR:[1.000000,0.000000,0.000000,0.000000],bone:[0.985580,-0.011813,-0.015635,-0.168072]}
];


Счас попробую применить для моей флеш арматуры
Блин... Надо ж еще в арматуре указать парент кости и childen кости для каждой кости, прийдется арматурный экспорт дописывать.
Тяну children и получаю
children = [sArmL:[Null],head:[Null],legL:["sLegL"],neck:["head"],boneL:["armL"],sLegR:["fLegR"],fLegL:[Null],armR:["sArmR"],sLegL:["fLegL"],armL:["sArmL"],sArmR:[Null],fLegR:[Null],boneR:["armR"],legR:["sLegR"],bone:["boneL","boneR","neck"]];

Что не есть True, получается, что ноги саи по себе, а мне надо, что-бы они прикреплялись к Bone. Прийдется теперь и скелет перерисовывать. Что-бы к началу главной кости не прикреплялись другие кости.
Правильная позв в блендере
Вот теперь к началу главной кости не прикрепляются другие кости.

По поводу сборки скелета (захотелось слово скелет употребить, на самом деле арматуры) вобщем берем кость, пусть это будет bone, применяем к ней кватернион, вернее преобразованный каватернион от блендера в флешевскую матрицы, дальше children кость от bone - pelvis, так кодил, что кости уже наизусть знаю, а левая кнопка alt западает, и неудобно переключать с ру на ен, можно конечно купить, новую клаву, но я не ищу простых путей. Итак собираем сборщик скелета. Метод в классе арматуре будет называться компилате. По аналогии с анимированный шланг. Кстати, нормальный тутор, после него я сражу же сделал фак. И было классно., я думал, вот она костная 3Д анимация, однако, больше ниче кроме фака на тот момент сделать не удалось. Объясняю, если использовать только кватернионы для сборки арматуры, то получится вот, что:
		public function compilate(b:Bone):void {
			var i:int;
			
			b.globalM3d.identity();
				if (b.parent != null) {
					
					
					b.globalM3d.append(b.boneMat);
					
					b.globalM3d.append(b.parent.globalM3d);
					
					
				} else {
					b.globalM3d.append(b.boneMat);
					b.tempHead = b.head;
				}
			
			b.localMat = b.globalM3d.clone();
			
			//выключил компонент перемещения
			//b.localMat.appendTranslation(b.tempHead.x, b.tempHead.y, b.tempHead.z);
			
			
			if (b.children != null) for (i = 0; i < b.children.length; i++) {
				b.children[i].tempHead = b.localMat.transformVector(new Vector3D(0, Vector3D.distance(b.head, b.tail), 0));
				compilate(b.children[i]);
			}
			
		}

использованы только кватернионы
только кватернионы

Вы видите, все в принципе правильно, они повернуты правильно, если же переместить начала костей детей к концу родителя (тупая философия) раскомментировав строку
//b.localMat.appendTranslation(b.tempHead.x, b.tempHead.y, b.tempHead.z);
Получится в итоге вот, что
компилированныя арматура
Собранная арматура из кватернионов

Отсюда вывод: Мне не нужны для работы head и tail костей, тк. я собираю арматуру из кватернионов и они образуются сами собой. Однако head и tail используются для расчета длины кости, длину кости можно получить из блендерного экспорта, - потом дооптимизирую.
Все теперь можно и анимацию зарядить.
Класс простенький написал
package lex.d3 
{
	/**
	 * ...
	 * @author Alex Lexcuk http://www.murmadillo.tut.su
	 */
	public class AnimationObj
	{
		public var animObjAr:Array;
		public function AnimationObj() 
		{
			
		}
		
	}

}

А я еще добавил сюда-же перемещение главной кости в порт get-animation.py.
В общем вот 10 кадр блендера
десятый кадр анимашки

Длинный рассказик получился
Однако настало время компиляции по ctrl+enter

Классно пляшет, рульно мягко выражаясь.

Теперь надо меш прикрутить. Ну эт легко, зафиксирую результат в виде архива с файлами проекта.