def processSkeletalAnimation(self, skeletonIdx): skeleton = self.skinning.skeletons[skeletonIdx] framesCount = int((self.stopAnimationTime - self.startAnimationTime) * self.fps + 0.5) + 1 startFrame = int(self.startAnimationTime * self.fps + 0.5) if framesCount == 1: if self.verbose: print ' no skeletal animation' return animationName = self.asset.getAnimationsPath() + '/' + 'SkelAnimation' if skeletonIdx > 0: animationName += '_' + str(skeletonIdx) if self.verbose: print 'Animation:', animationName usdSkelAnim = UsdSkel.Animation.Define(self.usdStage, animationName) translateAttr = usdSkelAnim.CreateTranslationsAttr() rotateAttr = usdSkelAnim.CreateRotationsAttr() scaleAttr = usdSkelAnim.CreateScalesAttr() jointPaths = [] for fbxNode in skeleton.joints: jointPaths.append(skeleton.jointPaths[fbxNode]) fbxAnimEvaluator = self.fbxScene.GetAnimationEvaluator() for frame in range(framesCount): time = frame / self.fps + self.startAnimationTime translations = [] rotations = [] scales = [] for fbxNode in skeleton.joints: fbxTime = fbx.FbxTime() fbxTime.SetSecondDouble(time) fbxMatrix = fbxAnimEvaluator.GetNodeLocalTransform( fbxNode, fbxTime) translation = fbxMatrix.GetT() q = fbxMatrix.GetQ() rotation = Gf.Quatf( float(q[3]), Gf.Vec3f(float(q[0]), float(q[1]), float(q[2]))) scale = fbxMatrix.GetS() translations.append( [translation[0], translation[1], translation[2]]) rotations.append(rotation) scales.append([scale[0], scale[1], scale[2]]) translateAttr.Set(translations, Usd.TimeCode(frame + startFrame)) rotateAttr.Set(rotations, Usd.TimeCode(frame + startFrame)) scaleAttr.Set(scales, Usd.TimeCode(frame + startFrame)) usdSkelAnim.CreateJointsAttr(jointPaths) skeleton.setSkeletalAnimation(usdSkelAnim)
def GetDatafromNode(node, time): ''' Função recebe um nodo fbx.FbxNode, o caminho para o arquivo .fbx, um float com o tempo exato a ser inspecionado. Função retorna um dicionário contendo: Nome de identificação do nodo Tupla com dados da rotação do nodo (x, y, z) Tupla com dados da translação do nodo (x, y, z) Tupla com dados da escala do nodo (x, y, z) Posição temporal destes dados ''' timer = fbx.FbxTime() timer.SetSecondDouble(time) pivot = node.eSourcePivot matrix = node.EvaluateGlobalTransform(timer, pivot) node_rotacao = matrix.GetR() node_translacao = matrix.GetT() node_escala = matrix.GetS() node_dictionary = { 'Name': node.GetName(), 'Rotation': (node_rotacao[0], node_rotacao[1], node_rotacao[2]), 'Translation': (node_translacao[0], node_translacao[1], node_translacao[2]), 'Scaling': (node_escala[0], node_escala[1], node_escala[2]), 'Time': time } return node_dictionary
def processNodeTransformAnimation(self, fbxNode, fbxProperty, fbxAnimCurveNode, usdGeom): fbxTimeSpan = fbx.FbxTimeSpan() fbxAnimCurveNode.GetAnimationInterval(fbxTimeSpan) startTime = fbxTimeSpan.GetStart().GetSecondDouble() stopTime = fbxTimeSpan.GetStop().GetSecondDouble() framesCount = int((stopTime - startTime) * self.fps + 0.5) + 1 if framesCount < 1: return startFrame = int(startTime * self.fps + 0.5) isTranslation = False isRotation = False isScale = False channelName = str(fbxProperty.GetName()).strip() if channelName == 'Lcl Translation': isTranslation = True elif channelName == 'Lcl Rotation': isRotation = True elif channelName == 'Lcl Scaling': isScale = True else: if self.verbose: print 'Warnig: animation channel"', channelName, '"is not supported.' fbxAnimEvaluator = self.fbxScene.GetAnimationEvaluator() # TODO: for linear curves use key frames only for frame in range(startFrame, startFrame + framesCount): time = frame / self.fps + startTime timeCode = self.asset.toTimeCode(time, True) fbxTime = fbx.FbxTime() fbxTime.SetSecondDouble(time) if isTranslation: op = self.getXformOp(usdGeom, UsdGeom.XformOp.TypeTranslate) v = fbxNode.EvaluateLocalTranslation(fbxTime) op.Set(time=timeCode, value=Gf.Vec3f(float(v[0]), float(v[1]), float(v[2]))) elif isRotation: op = self.getXformOp(usdGeom, UsdGeom.XformOp.TypeRotateXYZ) v = fbxNode.EvaluateLocalRotation(fbxTime) op.Set(time=timeCode, value=Gf.Vec3f(float(v[0]), float(v[1]), float(v[2]))) elif isScale: op = self.getXformOp(usdGeom, UsdGeom.XformOp.TypeScale) v = fbxNode.EvaluateLocalScaling(fbxTime) op.Set(time=timeCode, value=Gf.Vec3f(float(v[0]), float(v[1]), float(v[2])))
def print_fbx_contents(f): """Print EVERYTHING in the fbx file, and safely close it when done.""" # if not f: # f = QtWidgets.QFileDialog.getOpenFileName(dir=pmc.workspace(q=True, rd=True), filter="*.json")[0] fbx_file = FBX_Class(f) try: print(fbx_file.scene.GetGlobalSettings()) print(fbx_file.scene.GetAnimationEvaluator()) frame = fbx.FbxTime() frame.SetFrame(24) print_node(fbx_file.root_node, "{}") print("<<------------------- END ------------------->>") except: raise finally: fbx_file.close()
def get_global_transform(layer, nodes): qs = list() # (J, F, fbxQuaternion) translations = list() # (J, F, 3) nkeys = nodes[0].LclRotation.GetCurve(layer, "X", True).KeyGetCount() fps = 30.0 for j in range(len(nodes)): qs_node = list() translations_node = list() for i in range(nkeys): time = fbx.FbxTime() time.SetSecondDouble(i / fps) transform = nodes[j].EvaluateGlobalTransform(time) translations_node.append(fbxVec4ToList(transform.GetT())) qs_node.append(transform.GetQ()) qs.append(qs_node) translations.append(translations_node) qs = np.array(qs) translations = np.array(translations) qs = np.swapaxes(qs, 0, 1) translations = np.swapaxes(translations, 0, 1) return qs, translations
def getNodeCurves(node, animLayer=0, j=0, joints=[]): #Retorna as curvas dos nós. Assume que todas as curvas possui o mesmo número de keys newjoint = Joint(node.GetName()) lclTrans = node.LclTranslation.Get() lclRot = node.LclRotation.Get() newjoint.SetLcl(np.array([lclTrans[0], lclTrans[1], lclTrans[2]]), np.array([lclRot[0], lclRot[1], lclRot[2]])) lclTransX = node.LclTranslation.GetCurve(animLayer, "X", False) lclTransY = node.LclTranslation.GetCurve(animLayer, "Y", False) lclTransZ = node.LclTranslation.GetCurve(animLayer, "Z", False) lclRotX = node.LclRotation.GetCurve(animLayer, "X", False) lclRotY = node.LclRotation.GetCurve(animLayer, "Y", False) lclRotZ = node.LclRotation.GetCurve(animLayer, "Z", False) if lclTransX: keyCount = lclTransX.KeyGetCount() elif lclRotX: keyCount = lclRotX.KeyGetCount() else: keyCount = 0 #if (gbljointpos==None): # gbljointpos = np.empty([keyCount,3, node.GetChildCount(True)]) #else: # if (keyCount > gbljointpos.shape[0]): # gbljointpos.resize([keyCount,3,gbljointpos.shape[2]], refcheck=False) transVector = np.empty(shape=(keyCount, 4)) rotVector = np.empty(shape=(keyCount, 4)) sclVector = np.empty(shape=(keyCount, 4)) time = fbx.FbxTime() for i in range(keyCount): time.SetFrame(i + 1, fbx.FbxTime.eFrames120) glbTransMatrix = node.EvaluateGlobalTransform(time) print(node.GetName()) print(glbTransMatrix.GetColumn(0)) print(glbTransMatrix.GetColumn(1)) print(glbTransMatrix.GetColumn(2)) print(glbTransMatrix.GetColumn(3)) auxVector = glbTransMatrix.GetT() transVector[i, :] = np.array( [auxVector[0], auxVector[1], auxVector[2], auxVector[3]]) auxVector = glbTransMatrix.GetR() rotVector[i, :] = np.array( [auxVector[0], auxVector[1], auxVector[2], auxVector[3]]) auxVector = glbTransMatrix.GetS() sclVector[i, :] = np.array( [auxVector[0], auxVector[1], auxVector[2], auxVector[3]]) newjoint.SetTRS(transVector, rotVector, sclVector) joints.append(newjoint) for i in range(0, node.GetChildCount()): getNodeCurves(node.GetChild(i), animLayer, j + 1) if j == 0: return joints
def get_local_transform(node, time=0.0): t = fbx.FbxTime(time) return node.EvaluateLocalTransform(t)
fbx_eval = scene.GetAnimationEvaluator() # fbx_eval = fbx.FbxAnimEvaluator.Create(fbx_manager, "blah") fbx_eval.Flush(node0.LclTranslation) fbx_eval.Flush(node1.LclTranslation) fbx_eval.Flush(node2.LclTranslation) # fbx_eval.Reset() node0.LclTranslation.Set(fbx.FbxDouble3(6, 7, 8)) node1.LclTranslation.Set(fbx.FbxDouble3(10, 11, 12)) fbx_eval.Reset() time_zero = fbx.FbxTime() time_zero.SetSecondDouble(1.0) print fbx_eval.ValidateTime(time_zero).GetSecondDouble() mat = fbx_eval.GetNodeGlobalTransform(node2, time_zero) print mat.GetT() print fbx_eval.GetNodeLocalTransform(node2, time_zero).GetT() # print fbx_eval.GetPropertyValue(node2.LclTranslation, time_zero).Get( # fbx.eFbxDouble3 # ) fbx_eval.Reset() if False: FbxCommon.SaveScene(fbx_manager, scene, TEST_FILE)
def GetTransformAt(self, t): time = fbx.FbxTime() time.SetSecondDouble(t) trans = self.node_.EvaluateGlobalTransform(time) return trans
def getNodeCurves(scene, node, animLayer=0, j=0, joints=[], file=[], keysCount=[]): #TODO: Mudar nome da função #Prepara os dados para escrever o arquivo BVH #Pega o nome da junta e cadastra ela na classe Joints newjoint = Joint(node.GetName(), j) #Se for a primeira vez passando pela função (recursiva), começa a escrever #o header do bvh if j==0: bvhfile = BVHFile(str.format("File %i" % (len(BVHFile.files)+1))) bvhfile.AddToHeader(str.format("ROOT %s" % node.GetName())) bvhfile.AddJointList(newjoint) #Nos outros casos, continua escrevendo o header else: depth=j bvhfile=file #Verifica se tem pelo menos um filho OU se é o primeiro irmão if (node.GetChildCount() > 0) or (node.GetParent().GetChildCount() > 1): bvhfile.AddToHeader(str.format("%sJOINT %s" % (j*"\t",node.GetName()))) bvhfile.AddJointList(newjoint) else: #Se não tiver filho nem irmão, "vira" End Site bvhfile.AddToHeader(str.format("%sEnd Site" % (j*"\t"))) bvhfile.AddToHeader("%s{" % (j*"\t")) #Pega a translação e rotação inicial (não em função do frame) e cadastra #o OFFSET no BVH lclTrans = node.LclTranslation.Get() lclRot = node.LclRotation.Get() bvhfile.AddToHeader(str.format("%sOFFSET %.5f %.5f %.5f" % ((j+1)*"\t",lclTrans[0],lclTrans[1],lclTrans[2]))) #Se não for End Site, define os canais if (node.GetChildCount() > 0) or (node.GetParent().GetChildCount() > 1): #if node.RotationOrder.Get()==0: # bvhfile.AddToHeader(str.format("%sCHANNELS 6 Xposition Yposition Zposition Xrotation Yrotation Zrotation" % ((j+1)*"\t"))) #else: bvhfile.AddToHeader(str.format("%sCHANNELS 6 Xposition Yposition Zposition Zrotation Xrotation Yrotation" % ((j+1)*"\t"))) #Se não for End Site e não tiver filho, adiciona End Site if (node.GetChildCount() == 0): bvhfile.AddToHeader(str.format("%sEnd Site" % ((j+1)*"\t"))) bvhfile.AddToHeader("%s{" % ((j+1)*"\t")) bvhfile.AddToHeader(str.format("%sOFFSET %i %i %i" % ((j+2)*"\t",0,0,0))) bvhfile.AddToHeader("%s}" % ((j+1)*"\t")) #Cadastra valores de translação e rotação na classe Joints (não em função do frame) newjoint.SetLcl(np.array([lclTrans[0],lclTrans[1],lclTrans[2]]), np.array([lclRot[0],lclRot[1],lclRot[2]])) #Procura a quantidade de keys, usada para descobrir a quantidade de Frames #TODO: Achar um jeito melhor para encontrar a quantidade de Frames keyCount = 0 for axes in ["X","Y","Z"]: transcurve = node.LclTranslation.GetCurve(animLayer,axes ,False) rotcurve = node.LclRotation.GetCurve(animLayer, axes,False) if transcurve: if transcurve.KeyGetCount()>keyCount: keyCount = transcurve.KeyGetCount() if rotcurve: if rotcurve.KeyGetCount()>keyCount: keyCount = rotcurve.KeyGetCount() keysCount.append(keyCount) #Inicia os vetores de translação, rotação e escala para cada frame (quantidade #de keys) transVector = np.empty(shape=(keyCount,4)) rotVector = np.empty(shape=(keyCount,4)) sclVector = np.empty(shape=(keyCount,4)) time = fbx.FbxTime() #Para cada key (frame, supostamente) da animação do nó, pega os valores for i in range(keyCount): time.SetFrame(i, fbx.FbxTime.eFrames120) lclTransMatrix = node.EvaluateLocalTransform(time) auxVector = lclTransMatrix.GetT() transVector[i,:] = np.array([auxVector[0],auxVector[1],auxVector[2],auxVector[3]]) auxVector = lclTransMatrix.GetR() #auxVector = node.EvaluateLocalRotation(time) rotVector[i,:] = np.array([auxVector[0],auxVector[1],auxVector[2],auxVector[3]]) auxVector = lclTransMatrix.GetS() sclVector[i,:] = np.array([auxVector[0],auxVector[1],auxVector[2],auxVector[3]]) # DEBBUG: #if (node.GetName().count('Spine 1') > 0) and i<5: #PARENTW =node.GetParent().EvaluateGlobalTransform (time) #WORLD = node.EvaluateLocalTransform (time) #TESTE = WORLD*PARENTW #quat = PARENTW.GetQ() #print(quat.DecomposeSphericalXYZ()) #print("Parent") # print("%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n" % ( # PARENTW.Get(0,0),PARENTW.Get(1,0),PARENTW.Get(2,0),PARENTW.Get(3,0), # PARENTW.Get(0,1),PARENTW.Get(1,1),PARENTW.Get(2,1),PARENTW.Get(3,1), # PARENTW.Get(0,2),PARENTW.Get(1,2),PARENTW.Get(2,2),PARENTW.Get(3,2), # PARENTW.Get(0,3),PARENTW.Get(1,3),PARENTW.Get(2,3),PARENTW.Get(3,3), # )) # print("Transform") # print("%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n" % ( # WORLD.Get(0,0),WORLD.Get(1,0),WORLD.Get(2,0),WORLD.Get(3,0), # WORLD.Get(0,1),WORLD.Get(1,1),WORLD.Get(2,1),WORLD.Get(3,1), # WORLD.Get(0,2),WORLD.Get(1,2),WORLD.Get(2,2),WORLD.Get(3,2), # WORLD.Get(0,3),WORLD.Get(1,3),WORLD.Get(2,3),WORLD.Get(3,3), # )) # print("Teste") # print("%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n" % ( # TESTE.Get(0,0),TESTE.Get(1,0),TESTE.Get(2,0),TESTE.Get(3,0), # TESTE.Get(0,1),TESTE.Get(1,1),TESTE.Get(2,1),TESTE.Get(3,1), # TESTE.Get(0,2),TESTE.Get(1,2),TESTE.Get(2,2),TESTE.Get(3,2), # TESTE.Get(0,3),TESTE.Get(1,3),TESTE.Get(2,3),TESTE.Get(3,3), # )) # print("Rotation") # print(WORLD.GetR()) # print(node.EvaluateLocalRotation(time)) # print("---------------") #print("%f %f %f"%(TESTE[0],TESTE[1],TESTE[2])) #TESTE = scene.GetAnimationEvaluator().GetNodeLocalRotation(node,time) #TESTE = scene.GetAnimationEvaluator().GetNodeLocalTransform(node,time).GetR() #TESTE = node.EvaluateLocalRotation(time) #print(TESTE) #print("%f %f %f"%(TESTE[0],TESTE[1],TESTE[2])) #Cadas os valores TRS de cada frame do nó na class Joints newjoint.SetTRS(transVector, rotVector, sclVector) joints.append(newjoint) #Recursividade: para cada filho chama a mesma função for i in range(0,node.GetChildCount()): getNodeCurves(scene, node.GetChild(i), animLayer, j+1, file=bvhfile) #Encerra a participação do nó atual na escrita do header do BVH bvhfile.AddToHeader("%s}" % (j*"\t")) #Quando passar por toda a hierarquia, escreve o conteúdo do arquivo if j==0: bvhfile.AddToContent("MOTION") bvhfile.AddToContent(str.format("Frames: %i") % max(keysCount)) time = fbx.FbxTime() #Seta 120 frames por segundo time.SetFrame(1, fbx.FbxTime.eFrames120) bvhfile.AddToContent(str.format("Frame Time: %f" % time.GetSecondDouble())) #Novamente assumo que a quantidade de Key é a mesma de Frame. #Uso a qtd de Key do nó que foi passado para essa função! print(keysCount) for i in range(max(keysCount)): listaAux = [] jointsfromfile = [] for joint in bvhfile.bvhJointList: if joint.rotation.shape[0] == 0: listaAux= listaAux + [joint.lclTrans[0],joint.lclTrans[1],joint.lclTrans[2],0,0,0] else: if i>=joint.rotation.shape[0]: #listaAux=listaAux + [joint.translation[-1][0], joint.translation[-1][1], joint.translation[-1][2],joint.rotation[-1][0], joint.rotation[-1][1], joint.rotation[-1][2]] listaAux=listaAux + [joint.translation[-1][0], joint.translation[-1][1], joint.translation[-1][2], joint.rotation[-1][2], joint.rotation[-1][0], joint.rotation[-1][1]] else: #listaAux=listaAux + [joint.translation[i][0], joint.translation[i][1], joint.translation[i][2],joint.rotation[i][0], joint.rotation[i][1], joint.rotation[i][2]] listaAux=listaAux + [joint.translation[i][0], joint.translation[i][1], joint.translation[i][2], joint.rotation[i][2],joint.rotation[i][0], joint.rotation[i][1]] stringToAdd = " ".join(str.format("%.5f"%number) for number in listaAux) bvhfile.AddToContent(stringToAdd) return joints, bvhfile