[#25270] X3D Export generates incorrect location for Lamp

was actually incorrect location for everything!

- x3d's global scene rotation value wasnt converted from deg to radians.
- camera viewport was also incorrectly exported.

use mathutils rather then inline math for rotations.
This commit is contained in:
Campbell Barton
2010-12-17 18:38:44 +00:00
parent f01672fde0
commit b48f7901d2

View File

@@ -42,7 +42,8 @@ import mathutils
from io_utils import create_derived_objects, free_derived_objects
DEG2RAD=0.017453292519943295
MATWORLD= mathutils.Matrix.Rotation(-90, 4, 'X')
RAD_90D = -(math.pi / 2.0)
MATWORLD= mathutils.Matrix.Rotation(RAD_90D, 4, 'X')
def round_color(col, cp):
return tuple([round(max(min(c, 1.0), 0.0), cp) for c in col])
@@ -190,32 +191,15 @@ class x3d_class:
def writeViewpoint(self, ob, mat, scene):
context = scene.render
# context = scene.render
ratio = float(context.resolution_x)/float(context.resolution_y)
# ratio = float(context.imageSizeY())/float(context.imageSizeX())
lens = (360* (math.atan(ratio *16 / ob.data.lens) / math.pi))*(math.pi/180)
# lens = (360* (math.atan(ratio *16 / ob.data.getLens()) / math.pi))*(math.pi/180)
lens = min(lens, math.pi)
# get the camera location, subtract 90 degress from X to orient like X3D does
# mat = ob.matrix_world - mat is now passed!
loc = self.rotatePointForVRML(mat.translation_part())
rot = mat.to_euler()
rot = (((rot[0]-90)), rot[1], rot[2])
# rot = (((rot[0]-90)*DEG2RAD), rot[1]*DEG2RAD, rot[2]*DEG2RAD)
nRot = self.rotatePointForVRML( rot )
# convert to Quaternion and to Angle Axis
Q = self.eulerToQuaternions(*nRot)
Q1 = self.multiplyQuaternions(Q[0], Q[1])
Qf = self.multiplyQuaternions(Q1, Q[2])
angleAxis = self.quaternionToAngleAxis(Qf)
loc, quat, scale = (MATWORLD * mat).decompose()
angleAxis = tuple(quat.axis) + (quat.angle, )
self.file.write("<Viewpoint DEF=\"%s\" " % (self.cleanStr(ob.name)))
self.file.write("description=\"%s\" " % (ob.name))
self.file.write("centerOfRotation=\"0 0 0\" ")
self.file.write("position=\"%3.2f %3.2f %3.2f\" " % loc)
self.file.write("orientation=\"%3.2f %3.2f %3.2f %3.2f\" " % (angleAxis[0], angleAxis[1], -angleAxis[2], angleAxis[3]))
self.file.write("fieldOfView=\"%.3f\" />\n\n" % (lens))
self.file.write("position=\"%3.2f %3.2f %3.2f\" " % tuple(loc))
self.file.write("orientation=\"%3.2f %3.2f %3.2f %3.2f\" " % angleAxis)
self.file.write("fieldOfView=\"%.3f\" />\n\n" % ob.data.angle)
def writeFog(self, world):
if world:
@@ -940,31 +924,7 @@ class x3d_class:
return s
def computeDirection(self, mtx):
x,y,z=(0,-1.0,0) # point down
ax,ay,az = (MATWORLD * mtx).to_euler()
# ax *= DEG2RAD
# ay *= DEG2RAD
# az *= DEG2RAD
# rot X
x1=x
y1=y*math.cos(ax)-z*math.sin(ax)
z1=y*math.sin(ax)+z*math.cos(ax)
# rot Y
x2=x1*math.cos(ay)+z1*math.sin(ay)
y2=y1
z2=z1*math.cos(ay)-x1*math.sin(ay)
# rot Z
x3=x2*math.cos(az)-y2*math.sin(az)
y3=x2*math.sin(az)+y2*math.cos(az)
z3=z2
return [x3,y3,z3]
return (mathutils.Vector((0, -1, 0)) * (MATWORLD * mtx).rotation_part())[:]
# swap Y and Z to handle axis difference between Blender and VRML
#------------------------------------------------------------------------
@@ -985,46 +945,6 @@ class x3d_class:
if inc > 0:
self.indentLevel = self.indentLevel + inc
# Converts a Euler to three new Quaternions
# Angles of Euler are passed in as radians
#------------------------------------------------------------------------
def eulerToQuaternions(self, x, y, z):
Qx = [math.cos(x/2), math.sin(x/2), 0, 0]
Qy = [math.cos(y/2), 0, math.sin(y/2), 0]
Qz = [math.cos(z/2), 0, 0, math.sin(z/2)]
quaternionVec=[Qx,Qy,Qz]
return quaternionVec
# Multiply two Quaternions together to get a new Quaternion
#------------------------------------------------------------------------
def multiplyQuaternions(self, Q1, Q2):
result = [((Q1[0] * Q2[0]) - (Q1[1] * Q2[1]) - (Q1[2] * Q2[2]) - (Q1[3] * Q2[3])),
((Q1[0] * Q2[1]) + (Q1[1] * Q2[0]) + (Q1[2] * Q2[3]) - (Q1[3] * Q2[2])),
((Q1[0] * Q2[2]) + (Q1[2] * Q2[0]) + (Q1[3] * Q2[1]) - (Q1[1] * Q2[3])),
((Q1[0] * Q2[3]) + (Q1[3] * Q2[0]) + (Q1[1] * Q2[2]) - (Q1[2] * Q2[1]))]
return result
# Convert a Quaternion to an Angle Axis (ax, ay, az, angle)
# angle is in radians
#------------------------------------------------------------------------
def quaternionToAngleAxis(self, Qf):
scale = math.pow(Qf[1],2) + math.pow(Qf[2],2) + math.pow(Qf[3],2)
ax = Qf[1]
ay = Qf[2]
az = Qf[3]
if scale > .0001:
ax/=scale
ay/=scale
az/=scale
angle = 2 * math.acos(Qf[0])
result = [ax, ay, az, angle]
return result
##########################################################
# Callbacks, needed before Main
##########################################################