dimanche 26 juin 2016

get global equivilent of local euler angles


I'm working on a mod for an old game and it has a nasty little bug that I'm trying to overcome. In this game items can be rotated via inputting ZYX euler angles. Unfortunately though, after reloading the game your rotations will always be screwed up. With a little bit of testing I figured out the cause - all rotations the user inputs are done on relative axis, but when reloading the engine displays these rotations as if they were done using global axis. So, the solution I thought of should be fairly simple. I need to, once the user is done rotating their objects, run a "finalize" script that will figure out what global angles would make the same rotations as the local inputs, then apply those globals locally before reloading. That way when the game then reads these values as globals it'll rotate the object as originally intended. I've made a python script that seems to work (see below), but my math knowledge is limited and the only way I know how to do this involves matrices, which are very cumbersome/inefficient to work with in the games scripting language. I was hoping someone on here may know how to do this with quaternions which would probably be more efficient. Or, even better if it's possible, how to do the whole thing without any conversions. import math import numpy as np np.set_printoptions(precision=3,suppress=True) def e2p(arr): # euler to product arr = [math.radians(d) for d in arr] cz, cy, cx = [math.cos(r) for r in arr] sz, sy, sx = [math.sin(r) for r in arr] x = np.array([[ cz , -sz , 0 ], [ sz , cz , 0 ], [ 0 , 0 , 1 ]]) y = np.array([[ cy , 0 , sy ], [ 0 , 1 , 0 ], [ -sy , 0 , cy ]]) z = np.array([[ 1 , 0 , 0 ], [ 0 , cx , -sx ], [ 0 , sx , cx ]]) # xyz changes from local to global return reduce(np.dot, [x,y,z]) def p2e(arr): # product to euler ( r11, r12, r13, r21, r22, r23, r31, r32, r33, ) = arr.flat z = math.atan2(-r12, r11) y = math.atan2( r13, math.sqrt(r33*r33 + r23*r23)) x = math.atan2(-r23, r33) return ["%.3f" % math.degrees(r) for r in [z, y, x]] start = [45,45,0] print "starting angles (ZYX euler, relative)n",start,"n" matri = e2p(start) print "to dot product of its 'global' matrixn",matri,"n" final = p2e(matri) print "back into eulers as global equivilentn",final,"n"

Aucun commentaire:

Enregistrer un commentaire