Skocz do zawartości

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


Pan Placek

Rekomendowane odpowiedzi

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.

Odnośnik do komentarza
Udostępnij na innych stronach

  • Odpowiedzi 10
  • Created
  • Ostatniej odpowiedzi

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ć

Edytowane przez szczuro
Odnośnik do komentarza
Udostępnij na innych stronach

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).

Odnośnik do komentarza
Udostępnij na innych stronach

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()

Odnośnik do komentarza
Udostępnij na innych stronach

W założeniu,że masz jeden wybrany obiekt

obj=bpy.context.selected_objects[0]
name=obj.name
print(name)  

 

Jeżeli chodzi o pose mode

if bpy.context.mode != 'POSE':
           bpy.ops.object.posemode_toggle() 

Tak z ciekawości w czym chcesz importować te dane?:)

Odnośnik do komentarza
Udostępnij na innych stronach

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?

Odnośnik do komentarza
Udostępnij na innych stronach

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ę.

Odnośnik do komentarza
Udostępnij na innych stronach

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

Odnośnik do komentarza
Udostępnij na innych stronach

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.

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się



×
×
  • Dodaj nową pozycję...

Powiadomienie o plikach cookie

Wykorzystujemy cookies. Przeczytaj więcej Polityka prywatności