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 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()
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 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();')
# 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()
invlen = lensq ** 0.5 vec = PythonQt.QtGui.QVector3D(quat.x() * invlen, quat.y() * invlen, quat.z() * invlen) return vec, ang cament = naali.getCamera() p = cament.placeable #print toAngleAxis(p.orientation) ort = p.orientation euler = mu.quat_to_euler(ort) #print euler start = QQuaternion(0, 0, -0.707, -0.707) #print start rot = QQuaternion.fromAxisAndAngle(QVector3D(0, 1, 0), -10) new = start * rot print ort print new #p.orientation = new #print mu.euler_to_quat(euler), ort if 0: #avatar set yaw (turn) #a = -1.0 a = 0 print "setting avatar yaw with %f" % a r.setAvatarYaw(a) if 0: #avatar rotation #XXX crashes when the avatar is not there! XXX