Napisano 11 Grudzień 201212 l 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.
Napisano 11 Grudzień 201212 l 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ń 201212 l przez szczuro
Napisano 11 Grudzień 201212 l 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).
Napisano 15 Grudzień 201212 l Autor 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()
Napisano 15 Grudzień 201212 l 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?:)
Napisano 16 Grudzień 201212 l Autor 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?
Napisano 16 Grudzień 201212 l 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ę.
Napisano 16 Grudzień 201212 l Autor Już ten Addon przeszukałem, on zczytuje rotację otrzymaną przez program, także w żaden sposób nie obrazuje problemu.
Napisano 16 Grudzień 201212 l 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
Napisano 16 Grudzień 201212 l 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.
Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto