Jump to content

Skrypt zapisujący pozycje kości itp w całym zakresie animacji


Pan Placek

Recommended Posts

Hej, jak w temacie, piszę skrypt, który zapisuje pozycję kości a dokładnie head, tail i rotation_euler.

Męczę się z tym dość długo i niestety nie mogę przebrnąć przez pewien etap.

 

Oto kod który napisałem:

 

def getPosition(a_name):
   bones=bpy.data.armatures[a_name].bones
   bone_struct=[]

   for bone in bones:
       bone_ends=[]
       bpy.context.active_object.data.bones[bone].select=True
       bone_ends.append(bone.name)
       bone_ends.append(bpy.context.active_pose_bone.head)
       bone_ends.append(bpy.context.active_pose_bone.tail)
       bone_ends.append(bpy.context.active_pose_bone.rotation_euler)
       bone_struct.append(bone_ends)
   return(bone_struct)

#zapisywanie animacji do pliku
def saveAnimation(a_name, file_name):
scene=bpy.context.scene
frames=scene.frame_end - scene.frame_start + 1
myFile=open(file_name,"w")
scene.frame_current=0
i=0
j=0

for i in range(scene.frame_start, scene.frame_end + 1):
	myFile.write("Frame: %d;\n" % scene.frame_current)
	scene.frame_current=i
	scene.frame_set(scene.frame_current)

	#korzystam z wczeniej utworzonej funkcji getPosition
	myData=getPosition(a_name)
	for line in myData:
		 myFile.write(str(line))
		 myFile.write("\n")
myFile.close()
return

saveAnimation('Armature', 'animation.txt')

 

W wyniku otrzymuje plik w którym w każdej klatce i przy każdej kości mam wartości obecnie aktywnej kości z klatki 0.

Stosując w konsoli komendę bpy.context.active_pose_bone.head dostaję poprawne wyniki przy zmianie klatki.

Więc sądzę, że kieruje się w dobrym kierunku, ale problem tkwi właśnie z aktywacją kości, której nie potrafie zaimplementować.

 

Wcześniej próbowałem zapisać pozycję nieco inaczej:

def getPosition(a_name):
bones=bpy.data.armatures[a_name].bones
bone_struct=[]
i=0
for bone in bones:
	bone_ends=[]
	bone_ends.append(bone.name)
	bone_ends.append(bones[i].head)
	bone_ends.append(bones[i].tail)
	bone_struct.append(bone_ends)
	i=i+1

return(bone_struct)

 

W wyniku otrzymywałem pozycję każdej kości, ale wyłącznie w pierwszej klatce.

 

Także drodzy koledzy proszę was o pomoc.

Link to comment
Share on other sites

  • Replies 10
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

jak juz pisałem u mnie działa w ten sposób :) żywcem z konsoli pythona

>>> bpy.context.active_bone
[color=#008080]bpy.data.armatures['Armature'].bones["Bone.001"][/color]

>>> bone=bpy.context.active_object.data.bones['Bone']
>>> bpy.context.active_object.data.bones.active=bone
>>> bpy.context.active_bone
[color=#008080]bpy.data.armatures['Armature'].bones["Bone"][/color]

>>> bpy.context.active_pose_bone
[color=#008080]bpy.data.objects['Armature'].pose.bones["Bone"][/color]

>>> bone=bpy.context.active_object.data.bones[1]
>>> bpy.context.active_object.data.bones.active=bone
>>> bpy.context.active_pose_bone
[color=#008080]bpy.data.objects['Armature'].pose.bones["Bone.001"][/color]

active_pose_bone jest read only (tylko do odczytu)

>>> bpy.context.active_pose_bone= bone
[color=#800000]Traceback (most recent call last):
 File "", line 1, in 
AttributeError: bpy_struct: Context property [b]"active_pose_bone" is read-only[/b][/color]

 

ps. może później sie wgryzę w twój kod i spróbuje coś wiecej wykombinować

Edited by szczuro
Link to comment
Share on other sites

Jest jedna rzecz, o której trzeba pamiętać:

Miałem ten problem przy pisaniu eksportera do After Effects.

 

Jeżeli zmieniasz klatkę za pomocą frame_current = foo to skrypt wprawdzie ustawia klatkę na foo, ale nie updatuje sceny. Jeżeli Twoje kości są animowane, to dla każdej klatki zapisze Ci jej dane z klatki w której byłeś w momencie odpalenia skryptu.

Żeby wszystko się zupdatowało musisz użyć frame_set(foo).

Link to comment
Share on other sites

Zrobiłem w calości ten skrypt oraz skrypt wczytujący dane. Ale mam kolejny problemik. Działa on wyłącznie w trybie pose mode.

Odpalając go np. trybie object wyskakuje błąd.

 

Tak więc moje pytanie brzmi: jak przy uruchomieniu skryptu sprawdzić czy jest zaznaczony obiekt 'Armatura' i jaki tryb jest obecnie włączony?

Tutaj wiem tylko tyle, że przejście do trybu posemode to posemode_toggle()

Link to comment
Share on other sites

W blenderze.

 

Teraz mam MEGA problem. W swoim projekcie muszę wczytać dane motion capture wykorzystując zmiany pozycji punktów.

Myk polega na tym, że z pozycji trzeba przejść na rotację. Znalazłem coś takiego jak macierze rotacji:

http://pl.wikipedia.org/wiki/Elementarne_macierze_transformacji

http://en.wikipedia.org/wiki/Rotation_matrix

 

Ale nie za bardzo umiem z tego skorzystać, czy miał ktoś z tym już do czynienia i wie jak rozwiązać problem?

Link to comment
Share on other sites

Macierze i vektory to dalej moja pięta achillesowa, ale podpowiem, że macierze do rotacji (w blenderze) wykorzystują system Quaternion (WXYZ), działa on trochę jak maski pozycji, w zależności od wartości W, X, Y albo Z przyjmuje odpowiednią pozycje i blenduje je między sobą.

 

Musisz poczytać na necie i przeanalizować przykładowe listingi kodu. Sprawdź czy któryś Addon nie robi czegoś z rotacją, na pewno Addon od Motion Capture coś będzie miał.

 

Sam jeszcze tego nie robiłem więc więcej ni pomogę.

Link to comment
Share on other sites

Z tego co ja się orientuje Quaterniony to tylko sposób zapisu danych(1 rzeczywista 3 urojone?). W blenderze masz dostęp do rotacja [w,x,y,z,] i dostęp do zwykłych eulera rot x, rot y, rot z. W 3ds max jest identycznie. W maxie jest gotowa funkcja do przeliczania jednych na drugą,w blenderze chyba nie ma tak dobrze...

n-pigeon dobrze mówi szukaj czegoś gotowego... Operacje na macierzach nie są takie łatwe

Link to comment
Share on other sites

Quaternion i Euler to systemy przedstawiania rotacji, w przypadku Q nie sugerowałbym się oznaczeniami XYZ ma coś wspólnego z XYZ obiektu, ale nie przedstawia o ile stopni jest obrót tylko ile % w końcowej rotacji jest poszczególnych rotacji. Trudno mi to wytłumaczyć, sam to ledwo rozumiem :D Euler jest łatwiejszy do ogarnięcia, ale jest ryzyko utworzenia Gimbal Lock co powoduje czasem błędy przy interpolacji animacji.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now



×
×
  • Create New...

Important Information

We are using cookies. Read about our Privacy Policy