def _rotateEachEntWithQuaternion(self, q, ents, angle): """ Rotate each object along selected axis """ for ent in ents: ort = ent.placeable.Orientation v1 = ort.rotatedVector(QVector3D(1,0,0)) v2 = ort.rotatedVector(QVector3D(0,1,0)) v3 = ort.rotatedVector(QVector3D(0,0,1)) # rotated unit vectors are equals of objects unit vectors in objects perspective # this gives equation M * x = x' (x=(i,j,k) & x'=(i',j',k')) # ( M = conversion matrix, x = world unit vector, x' = object unit vector) # multiply each sides of equation with inverted matrix of M^-1 gives us: # I * x = M^-1 *x' => x = M^-1 * x' # => we can now express world unit vectors i,j,k with i',j',k' # with help of inverted matrix, and use objects quaternion to rotate # along world unit vectors i, j, k m = ((v1.x(),v1.y(),v1.z()),(v2.x(),v2.y(),v2.z()),(v3.x(),v3.y(),v3.z())) inv = mu.invert_3x3_matrix(m) if self.grabbed_axis == self.AXIS_RED: #rotate around x-axis axis = QVector3D(inv[0][0],inv[0][1],inv[0][2]) elif self.grabbed_axis == self.AXIS_GREEN: #rotate around y-axis axis = QVector3D(inv[1][0],inv[1][1],inv[1][2]) elif self.grabbed_axis == self.AXIS_BLUE: #rotate around z-axis axis = QVector3D(inv[2][0],inv[2][1],inv[2][2]) q = QQuaternion.fromAxisAndAngle(axis, angle) q.normalize() ent.placeable.Orientation = ort*q
def __init__(self, entity=None, comp=None, changetype=None): circuits.BaseComponent.__init__(self) self.entity = entity self.comp = comp if self.comp is not None: # normal run, check for nonEC run now # Todo: OnChanged() is deprecated comp.connect("OnChanged()", self.onChanged) self.rot = Quat.fromAxisAndAngle(Vec(0, 1, 0), 1)
def __init__(self, entity=None, comp=None, changetype=None): circuits.BaseComponent.__init__(self) self.entity = entity self.comp = comp if self.comp is not None: #normal run, check for nonEC run now # Todo: OnChanged() is deprecated comp.connect("OnChanged()", self.onChanged) self.rot = Quat.fromAxisAndAngle(Vec(0, 1, 0), 1)
def euler_to_quat(euler): ang = euler[0] * 0.5 sr = math.sin(ang) cr = math.cos(ang) ang = euler[1] * 0.5 sp = math.sin(ang) cp = math.cos(ang) ang = euler[2] * 0.5 sy = math.sin(ang) cy = math.cos(ang) cpcy = cp * cy spcy = sp * cy cpsy = cp * sy spsy = sp * sy quat = Quat(cr*cpcy + sr*spsy, sr * cpcy - cr*spsy, cr*spcy + sr * cpsy, cr * cpsy - sr * spcy) quat.normalize() return quat
def euler_to_quat(euler): ang = euler[0] * 0.5 sr = math.sin(ang) cr = math.cos(ang) ang = euler[1] * 0.5 sp = math.sin(ang) cp = math.cos(ang) ang = euler[2] * 0.5 sy = math.sin(ang) cy = math.cos(ang) cpcy = cp * cy spcy = sp * cy cpsy = cp * sy spsy = sp * sy quat = QQuaternion(cr * cpcy + sr * spsy, sr * cpcy - cr * spsy, cr * spcy + sr * cpsy, cr * cpsy - sr * spcy) quat.normalize() return quat
def _manipulate2(self, ents, amountx, amounty, changevec, centervecs, centerpoint): # calculate quaternion for rotation # get axis # print "amountx %s"%amountx # print "amounty %s"%amounty # print "changevec %s"%changevec if self.grabbed and self.grabbed_axis is not None: local = False # self.controller.useLocalTransform mov = changevec.length() * 30 axis = None #angle = 90 # just do 90 degrees rotations #angle = 15 # just do 15 degrees rotations angle = 5 # just do 5 degrees rotations if amountx < 0 and amounty < 0: dir = -1 elif amountx < 0 and amounty >= 0: dir = 1 if self.grabbed_axis == self.AXIS_BLUE: dir *= -1 elif amountx >= 0 and amounty < 0: dir = -1 elif amountx >= 0 and amounty >= 0: dir = 1 mov *= dir angle *= dir q = None euler = None if self.grabbed_axis == self.AXIS_RED: #rotate around x-axis axis = QVector3D(1, 0, 0) # disable this for now # return elif self.grabbed_axis == self.AXIS_GREEN: #rotate around y-axis axis = QVector3D(0, 1, 0) # disable this for now # return elif self.grabbed_axis == self.AXIS_BLUE: #rotate around z-axis axis = QVector3D(0, 0, 1) q = QQuaternion.fromAxisAndAngle(axis, angle) q.normalize() self._rotateEntsWithQuaternion(q, ents, amountx, amounty, changevec, centervecs, centerpoint) self._rotateEachEntWithQuaternion(q, ents, angle) pass
def _manipulate2(self, ents, amountx, amounty, changevec, centervecs, centerpoint): # calculate quaternion for rotation # get axis # print "amountx %s"%amountx # print "amounty %s"%amounty # print "changevec %s"%changevec if self.grabbed and self.grabbed_axis is not None: local = False # self.controller.useLocalTransform mov = changevec.length() * 30 axis = None #angle = 90 # just do 90 degrees rotations #angle = 15 # just do 15 degrees rotations angle = 5 # just do 5 degrees rotations if amountx < 0 and amounty < 0: dir = -1 elif amountx < 0 and amounty >= 0: dir = 1 if self.grabbed_axis == self.AXIS_BLUE: dir *= -1 elif amountx >= 0 and amounty < 0: dir = -1 elif amountx >= 0 and amounty >= 0: dir = 1 mov *= dir angle *= dir q = None euler = None if self.grabbed_axis == self.AXIS_RED: #rotate around x-axis axis = QVector3D(1,0,0) # disable this for now # return elif self.grabbed_axis == self.AXIS_GREEN: #rotate around y-axis axis = QVector3D(0,1,0) # disable this for now # return elif self.grabbed_axis == self.AXIS_BLUE: #rotate around z-axis axis = QVector3D(0,0,1) q = QQuaternion.fromAxisAndAngle(axis, angle) q.normalize() self._rotateEntsWithQuaternion(q, ents, amountx, amounty, changevec, centervecs, centerpoint) self._rotateEachEntWithQuaternion(q, ents, angle) pass
def _manipulate(self, ent, amountx, amounty, changevec): if self.grabbed and self.grabbed_axis is not None: local = self.controller.useLocalTransform mov = changevec.length() * 30 ort = ent.placeable.Orientation if amountx < 0 and amounty < 0: dir = -1 elif amountx < 0 and amounty >= 0: dir = 1 if not local and self.grabbed_axis == self.AXIS_BLUE: dir *= -1 elif amountx >= 0 and amounty < 0: dir = -1 elif amountx >= 0 and amounty >= 0: dir = 1 mov *= dir if local: if self.grabbed_axis == self.AXIS_RED: axis = Vec(1, 0, 0) elif self.grabbed_axis == self.AXIS_GREEN: axis = Vec(0, 1, 0) elif self.grabbed_axis == self.AXIS_BLUE: axis = Vec(0, 0, 1) ort = ort * Quat.fromAxisAndAngle(axis, mov) else: euler = quat_to_euler(ort) if self.grabbed_axis == self.AXIS_RED: #rotate around x-axis euler[0] -= math.radians(mov) elif self.grabbed_axis == self.AXIS_GREEN: #rotate around y-axis euler[1] += math.radians(mov) elif self.grabbed_axis == self.AXIS_BLUE: #rotate around z-axis euler[2] += math.radians(mov) ort = euler_to_quat(euler) ent.placeable.Orientation = ort ent.network.Orientation = ort
def camcontrol(self, rotate=None, move=None): cament = naali.getCamera() p = cament.placeable #print p.Position, p.Orientation if rotate is not None: ort = p.Orientation rot = Quat.fromAxisAndAngle(Vec(0, 1, 0), float(rotate)) ort *= rot p.Orientation = ort if move is not None: pos = p.Position pos += Vec(float(move), 0, 0) p.Position = pos baseurl, imgname = save_screenshot() imgurl = baseurl + imgname #return "%s, %s" % (p.Position, p.Orientation) return relhtml % imgurl
def render(self, camposx=None, camposy=None, camposz=None, camang=None): #, camortx=None, camorty=None, camortz=None, camortw=None): cament = naali.getCamera() p = cament.placeable if camposx is not None: pos = Vec(*(float(v) for v in [camposx, camposy, camposz])) p.Position = pos if camang is not None: ort = p.Orientation start = Quat(0, 0, -0.707, -0.707) rot = Quat.fromAxisAndAngle(Vec(0, 1, 0), -float(camang)) new = start * rot p.Orientation = new #if camortx is not None: # ort = Quat(*(float(v) for v in [camortw, camortx, camorty, camortz])) # p.Orientation = ort #return str(p.Position), str(p.Orientation) #self.render1() baseurl, imgname = save_screenshot() imgurl = baseurl + imgname pos = p.Position ort = p.Orientation #vec, ang = toAngleAxis(p.Orientation) #print vec, ang euler = quat_to_euler([ort.scalar(), ort.x(), ort.y(), ort.z()]) ang = euler[0] if ang < 0: ang = 360 + ang return abshtml % (imgurl, ang, pos.x(), pos.y(), pos.z() #ort.scalar(), ort.x(), ort.y(), ort.z(), )
def render(self, camposx=None, camposy=None, camposz=None, camang=None): #, camortx=None, camorty=None, camortz=None, camortw=None): cament = naali.getCamera() p = cament.placeable if camposx is not None: pos = Vec(*(float(v) for v in [camposx, camposy, camposz])) p.position = pos if camang is not None: ort = p.orientation start = Quat(0, 0, -0.707, -0.707) rot = Quat.fromAxisAndAngle(Vec(0, 1, 0), -float(camang)) new = start * rot p.orientation = new #if camortx is not None: # ort = Quat(*(float(v) for v in [camortw, camortx, camorty, camortz])) # p.orientation = ort #return str(p.position), str(p.orientation) #self.render1() baseurl, imgname = save_screenshot() imgurl = baseurl + imgname pos = p.position ort = p.orientation #vec, ang = toAngleAxis(p.orientation) #print vec, ang euler = mu.quat_to_euler(ort) ang = euler[0] if ang < 0: ang = 360 + ang return abshtml % (imgurl, ang, pos.x(), pos.y(), pos.z() #ort.scalar(), ort.x(), ort.y(), ort.z(), )
def onChanged(self): y = self.comp.GetAttribute('y') self.rot = Quat.fromAxisAndAngle(Vec(0, y, 0), 1)
def do_api_calls(self): yield "createMeshEntity" e = naali.createMeshEntity("axes.mesh") from PythonQt.QtGui import QVector3D, QQuaternion e.placeable.position = QVector3D(128, 128, 60) e.placeable.Scale = QVector3D(5, 5, 5) e.placeable.Orientation = QQuaternion(0, 0, 0, 1) r.removeEntity(e.Id) yield "EC_Touchable & EC_Highlight" for longname, shortname in [("EC_Touchable", 'touchable'), ("EC_Highlight", 'highlight')]: e = naali.getUserAvatar() e.GetOrCreateComponentRaw(longname) x = getattr(e, shortname) x.Show() x.Hide() assert x.IsVisible() == False yield "naali.createEntity" ent = naali.createEntity() print "new entity created:", ent yield "get camera FOV" fov = naali.getCamera().camera.GetVerticalFov() yield "avatar position" p = naali.getUserAvatar().placeable.position yield "avatar animation controller" naali.getUserAvatar().animationcontroller.EnableAnimation("Walk") yield "test sendChat" r.sendChat("test chat") yield "test logInfo" r.logInfo("test log message") #XXX deprecate yield "test camera yaw/itch" r.setCameraYawPitch(.1, .5) r.getCameraYawPitch() yield "test webview" import PythonQt wv = PythonQt.QtWebKit.QWebView() wv.show() yield "test dotscene loading" from localscene import loader loader.load_dotscene("pymodules/localscene/test.scene") yield "test dynamic component" ent = naali.getUserAvatar() ent.GetOrCreateComponentRaw("EC_DynamicComponent") print ent, type(ent) d = ent.EC_DynamicComponent d.CreateAttribute("real", 42.0) d.ComponentChanged(0) d.SetAttribute("real", 8.5) d.ComponentChanged(0) d.RemoveAttribute("real") d.ComponentChanged(0) yield "test javascript" cam = naali.getCamera() naali.runjs('print("Hello from JS! " + x)', {'x': naali.renderer}) naali.runjs('print("Another hello from JS! " + x)', {'x': naali.inputcontext}) naali.runjs('print("Some camera! " + x)', {'x': cam.camera}) #py objects are not qobjects. naali.runjs('print("Some camera, using naali :O ! " + x.getCamera())', {'x': naali}) naali.runjs('print("Camera Entity " + x)', {'x': cam}) naali.runjs('print("Camera placeable pos: " + pos)', {'pos': cam.placeable.position}) #not exposed yet. naali.runjs('print("QVector3D: " + new QVector3D())', {}) #naali.runjs('var a = {"a": true, "b": 2};') #naali.runjs('print(a.a + ", " + a.b)') #naali.runjs('print(JSON.stringify(a))') #naali.runjs('print("1 + 1 == " + 1 + 1)') #naali.runjs('print("1 - 1 == " + 1 - 1)') print ", done." if 0: runjs('var b = new QPushButton;') runjs('b.text = "hep";') runjs('b.show();')
if 0: #camera entity - it is an entity nowadays, and there is EC cam even try: cament = naali.getCamera() print "CAM:", cament.id except ValueError: print "no CAM" else: p = cament.placeable print p.position, p.orientation import PythonQt.QtGui from PythonQt.QtGui import QQuaternion as Quat from PythonQt.QtGui import QVector3D as Vec ort = p.orientation rot = Quat.fromAxisAndAngle(Vec(0, 1, 0), 10) #ort *= Quat(0, -.707, 0, .707) ort *= rot p.orientation = ort #ec cam stuff: print "FOV:", cament.camera.GetVerticalFov() if 0: #calcing the camera angle around up axis for web ui import PythonQt.QtGui from PythonQt.QtGui import QQuaternion from PythonQt.QtGui import QVector3D import mathutils as mu
if 0: #camera entity - it is an entity nowadays, and there is EC cam even try: cament = naali.getCamera() print "CAM:", cament.id except ValueError: print "no CAM" else: p = cament.placeable print p.Position, p.Orientation import PythonQt.QtGui from PythonQt.QtGui import QQuaternion as Quat from PythonQt.QtGui import QVector3D as Vec ort = p.Orientation rot = Quat.fromAxisAndAngle(Vec(0, 1, 0), 10) #ort *= Quat(0, -.707, 0, .707) ort *= rot p.Orientation = ort #ec cam stuff: print "FOV:", cament.camera.GetVerticalFov() if 0: #calcing the camera angle around up axis for web ui import PythonQt.QtGui from PythonQt.QtGui import QQuaternion as Quat from PythonQt.QtGui import QVector3D as Vec from objectedit.conversions import quat_to_euler#, euler_to_quat
if 0: #camera entity - it is an entity nowadays, and there is EC cam even try: cament = naali.getCamera() print "CAM:", cament.id except ValueError: print "no CAM" else: p = cament.placeable print p.Position, p.Orientation import PythonQt.QtGui from PythonQt.QtGui import QQuaternion as Quat from PythonQt.QtGui import QVector3D as Vec ort = p.Orientation rot = Quat.fromAxisAndAngle(Vec(0, 1, 0), 10) #ort *= Quat(0, -.707, 0, .707) ort *= rot p.Orientation = ort #ec cam stuff: print "FOV:", cament.camera.GetVerticalFov() if 0: #calcing the camera angle around up axis for web ui import PythonQt.QtGui from PythonQt.QtGui import QQuaternion as Quat from PythonQt.QtGui import QVector3D as Vec from objectedit.conversions import quat_to_euler #, euler_to_quat def toAngleAxis(quat):
# Math utils for Naali import math import PythonQt.QtGui from PythonQt.QtGui import QQuaternion from PythonQt.QtGui import QVector3D # some handy shortcut rotations for quats ninty_around_x = QQuaternion(math.sqrt(0.5), math.sqrt(0.5), 0, 0) ninty_around_y = QQuaternion(math.sqrt(0.5), 0, math.sqrt(0.5), 0) ninty_around_z = QQuaternion(math.sqrt(0.5), 0, 0, math.sqrt(0.5)) # To be used with Qt QQuaternion and QVector3D # according Quaternion*Vector from irrlicht (see Core\Quaternion.h) def quat_mult_vec(quat, v): qvec = quat.vector() uv = QVector3D.crossProduct(qvec, v) uuv = QVector3D.crossProduct(qvec, uv) uv = uv * 2.0 * quat.scalar() uuv = uuv * 2.0 return v + uv + uuv # QQuaternion to euler [x,y,z] def quat_to_euler(quat): euler = [0, 0, 0] sqw = quat.scalar() * quat.scalar() sqx = quat.x() * quat.x() sqy = quat.y() * quat.y() sqz = quat.z() * quat.z()
class Manipulator: NAME = "Manipulator" MANIPULATOR_MESH_NAME = "axes.mesh" USES_MANIPULATOR = True CURSOR_HOVER_SHAPE = Qt.OpenHandCursor CURSOR_HOLD_SHAPE = Qt.ClosedHandCursor MANIPULATORORIENTATION = QQuaternion(1, 1, 0, 0) MANIPULATORSCALE = QVector3D(1, 1, 1) MANIPULATOR_RULER_TYPE = EC_Ruler.Rotation MATERIALNAMES = None AXIS_RED = 0 AXIS_GREEN = 1 AXIS_BLUE = 2 def __init__(self): #self.controller = creator self.manipulator = None self.grabbed_axis = None self.grabbed = False self.usesManipulator = self.USES_MANIPULATOR self.highlightedSubMesh = None self.axisSubmesh = None self.entCenterVectors = {} self.centerPoint = None def compareIds(self, id): if self.usesManipulator: if self.manipulator.id == id: return True return False def moveTo(self, ents): if self.manipulator: pos = self.getPivotPos(ents) self.manipulator.placeable.position = pos def getManipulatorPosition(self): if self.manipulator: return self.manipulator.placeable.position return None def createManipulator(self): if self.manipulator is None and self.usesManipulator: # create a local temporary entity, we dont want to sync this at least for now # as there is no deletion code when you leave the server! ent = naali.createMeshEntity(self.MANIPULATOR_MESH_NAME, 606847240, ["EC_Gizmo", "EC_Ruler"], localonly=True, temporary=True) ent.SetName(self.NAME) ent.ruler.SetVisible(False) ent.ruler.SetType(self.MANIPULATOR_RULER_TYPE) ent.ruler.UpdateRuler() return ent def stopManipulating(self): self.grabbed_axis = None self.grabbed = False remove_custom_cursor(self.CURSOR_HOLD_SHAPE) try: self.manipulator.ruler.EndDrag() except: # TODO fix stopManipulating usage so it isn't called when manipulators aren't initialised properly yet pass def initVisuals(self): if self.manipulator is None: self.manipulator = self.createManipulator() self.hideManipulator() def showManipulator(self, ents): if self.usesManipulator and len(ents) > 0: self.moveTo(ents) self.setManipulatorScale(ents) try: ruler = self.manipulator.ruler except: ruler = self.manipulator.GetOrCreateComponentRaw("EC_Ruler") ruler.SetType(self.MANIPULATOR_RULER_TYPE) ruler.SetVisible(True) #r.logInfo("showing ruler showManipulator") ruler.UpdateRuler() if False: # self.controller.useLocalTransform: # first according object, then manipulator orientation - otherwise they go wrong order self.manipulator.placeable.orientation = ents[ 0].placeable.orientation * self.MANIPULATORORIENTATION else: self.manipulator.placeable.orientation = self.MANIPULATORORIENTATION def getPivotPos(self, ents): '''Median position used as pivot point''' xs = [e.placeable.position.x() for e in ents] ys = [e.placeable.position.y() for e in ents] zs = [e.placeable.position.z() for e in ents] minpos = QVector3D(min(xs), min(ys), min(zs)) maxpos = QVector3D(max(xs), max(ys), max(zs)) median = (minpos + maxpos) / 2 return median def hideManipulator(self): #r.logInfo("hiding manipulator") if self.usesManipulator: try: #XXX! without this try-except, if something is selected, the viewer will crash on exit #print "Hiding arrows!" if self.manipulator is not None: self.manipulator.placeable.scale = QVector3D( 0.0, 0.0, 0.0) #ugly hack self.manipulator.placeable.position = QVector3D( 0.0, 0.0, 0.0) #another ugly hack self.manipulator.ruler.SetVisible(False) #r.logInfo("hiding ruler hideManipulator") self.manipulator.ruler.UpdateRuler() self.grabbed_axis = None self.grabbed = False remove_custom_cursors() except RuntimeError, e: r.logDebug("hideManipulator failed") except AttributeError, e: # this will happend on_exit() -> hideManipulator # the manipulator entitys components has been destroyed pass
def onChanged(self): y = self.comp.GetAttribute("y") self.rot = Quat.fromAxisAndAngle(Vec(0, y, 0), 1)
def save(self, filename, nodes): from PythonQt.QtGui import QQuaternion newdoc = self.impl.createDocument(None, "scene formatVersion=\"\"", None) top_element = newdoc.documentElement nodesNode = newdoc.createElement('nodes') top_element.appendChild(nodesNode) if (nodes != None): for k, oNode in nodes.iteritems(): nodeNode = newdoc.createElement('node') nodeNode.setAttribute("name", k) nodeNode.setAttribute("id", oNode.id) position = newdoc.createElement('position') position.setAttribute( "x", str(oNode.naali_ent.placeable.Position.x())) position.setAttribute( "y", str(oNode.naali_ent.placeable.Position.y())) position.setAttribute( "z", str(oNode.naali_ent.placeable.Position.z())) nodeNode.appendChild(position) rotation = newdoc.createElement('rotation') # XXX counter the 'fix' done in loading the scene # loader.py in def create_naali_meshentity() #ort = oNode.naali_ent.placeable.Orientation * QQuaternion(1, 0, 0, -1) * QQuaternion(1, 0, 0, -1) #ort = oNode.naali_ent.placeable.Orientation * QQuaternion(math.sqrt(0.5),0,0,math.sqrt(0.5)) * QQuaternion(math.sqrt(0.5),0,0,math.sqrt(0.5)) rotate90z = QQuaternion(1, 0, 0, -1) rotate90z.normalize() ort = oNode.naali_ent.placeable.Orientation * rotate90z * rotate90z rotation.setAttribute("qx", str(ort.x())) rotation.setAttribute("qy", str(ort.y())) rotation.setAttribute("qz", str(ort.z())) rotation.setAttribute("qw", str(ort.scalar())) nodeNode.appendChild(rotation) scale = newdoc.createElement('scale') scale.setAttribute("x", str(oNode.naali_ent.placeable.Scale.x())) scale.setAttribute("y", str(oNode.naali_ent.placeable.Scale.y())) scale.setAttribute("z", str(oNode.naali_ent.placeable.Scale.z())) nodeNode.appendChild(scale) entity = newdoc.createElement('entity') entity.setAttribute("name", oNode.entityNode.getAttribute("name")) entity.setAttribute("meshFile", oNode.entityNode.getAttribute("meshFile")) if oNode.entityNode.hasAttribute("collisionFile"): entity.setAttribute( "collisionFile", oNode.entityNode.getAttribute("collisionFile")) if oNode.entityNode.hasAttribute("collisionPrim"): entity.setAttribute( "collisionPrim", oNode.entityNode.getAttribute("collisionPrim")) entity.setAttribute("static", oNode.entityNode.getAttribute("static")) nodeNode.appendChild(entity) nodesNode.appendChild(nodeNode) f = open(filename, 'w') # remove first line + change ending tag from </scene formatVersion=""> to </scene> contents = newdoc.toprettyxml() lines = contents.split('\n') lines = lines[1:] lines = lines[:-1] lines.remove("</scene formatVersion=\"\">") lines.append("</scene>") contents = '\n'.join(lines) f.write(contents) f.close()
def save(self, filename, nodes): from PythonQt.QtGui import QQuaternion newdoc = self.impl.createDocument(None, "scene formatVersion=\"\"", None) top_element = newdoc.documentElement nodesNode = newdoc.createElement('nodes') top_element.appendChild(nodesNode) if(nodes != None): for k, oNode in nodes.iteritems(): nodeNode = newdoc.createElement('node') nodeNode.setAttribute("name", k) nodeNode.setAttribute("id", oNode.id) position = newdoc.createElement('position') position.setAttribute("x", str(oNode.naali_ent.placeable.Position.x())) position.setAttribute("y", str(oNode.naali_ent.placeable.Position.y())) position.setAttribute("z", str(oNode.naali_ent.placeable.Position.z())) nodeNode.appendChild(position) rotation = newdoc.createElement('rotation') # XXX counter the 'fix' done in loading the scene # loader.py in def create_naali_meshentity() #ort = oNode.naali_ent.placeable.Orientation * QQuaternion(1, 0, 0, -1) * QQuaternion(1, 0, 0, -1) #ort = oNode.naali_ent.placeable.Orientation * QQuaternion(math.sqrt(0.5),0,0,math.sqrt(0.5)) * QQuaternion(math.sqrt(0.5),0,0,math.sqrt(0.5)) rotate90z = QQuaternion(1,0,0,-1) rotate90z.normalize() ort = oNode.naali_ent.placeable.Orientation * rotate90z * rotate90z rotation.setAttribute("qx", str(ort.x())) rotation.setAttribute("qy", str(ort.y())) rotation.setAttribute("qz", str(ort.z())) rotation.setAttribute("qw", str(ort.scalar())) nodeNode.appendChild(rotation) scale = newdoc.createElement('scale') scale.setAttribute("x", str(oNode.naali_ent.placeable.Scale.x())) scale.setAttribute("y", str(oNode.naali_ent.placeable.Scale.y())) scale.setAttribute("z", str(oNode.naali_ent.placeable.Scale.z())) nodeNode.appendChild(scale) entity = newdoc.createElement('entity') entity.setAttribute("name", oNode.entityNode.getAttribute("name")) entity.setAttribute("meshFile", oNode.entityNode.getAttribute("meshFile")) if oNode.entityNode.hasAttribute("collisionFile"): entity.setAttribute("collisionFile", oNode.entityNode.getAttribute("collisionFile")) if oNode.entityNode.hasAttribute("collisionPrim"): entity.setAttribute("collisionPrim", oNode.entityNode.getAttribute("collisionPrim")) entity.setAttribute("static", oNode.entityNode.getAttribute("static")) nodeNode.appendChild(entity) nodesNode.appendChild(nodeNode) f = open(filename, 'w') # remove first line + change ending tag from </scene formatVersion=""> to </scene> contents = newdoc.toprettyxml() lines = contents.split('\n') lines = lines[1:] lines = lines[:-1] lines.remove("</scene formatVersion=\"\">") lines.append("</scene>") contents = '\n'.join(lines) f.write(contents) f.close()