Pan Placek Napisano 11 Grudzień 2012 Napisano 11 Grudzień 2012 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.
szczuro Napisano 11 Grudzień 2012 Napisano 11 Grudzień 2012 (edytowane) 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 11 Grudzień 2012 przez szczuro
BartekSkorupa Napisano 11 Grudzień 2012 Napisano 11 Grudzień 2012 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).
Pan Placek Napisano 15 Grudzień 2012 Autor Napisano 15 Grudzień 2012 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()
alexx600 Napisano 15 Grudzień 2012 Napisano 15 Grudzień 2012 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?:)
Pan Placek Napisano 16 Grudzień 2012 Autor Napisano 16 Grudzień 2012 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?
n-pigeon Napisano 16 Grudzień 2012 Napisano 16 Grudzień 2012 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ę.
Pan Placek Napisano 16 Grudzień 2012 Autor Napisano 16 Grudzień 2012 Już ten Addon przeszukałem, on zczytuje rotację otrzymaną przez program, także w żaden sposób nie obrazuje problemu.
alexx600 Napisano 16 Grudzień 2012 Napisano 16 Grudzień 2012 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
n-pigeon Napisano 16 Grudzień 2012 Napisano 16 Grudzień 2012 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.
Rekomendowane odpowiedzi
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ę