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
def quat_mult_vec(quat, v): qvec = quat.vector() uv = Vec.crossProduct(qvec, v) uuv = Vec.crossProduct(qvec, uv) uv = uv * 2.0 * quat.scalar() uuv = uuv * 2.0 return v + uv + uuv
def updateScene(): global mesh global shader global angle global t dt = time() - t - t0 t += dt angle = t*math.pi/2 camera.lookAt(QVector3D(math.cos(angle), math.sin(angle), 1), QVector3D(0,0,0), QVector3D(0,0,1))
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 _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 getPivotPos(self, ents): 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 = Vec(min(xs), min(ys), min(zs)) maxpos = Vec(max(xs), max(ys), max(zs)) #median = (minpos + maxpos) / 2 #there is some type prob with pythonqt and operator overloads, so this workaround is needed: median = minpos.__add__(maxpos).__div__(2) #print "Min:", minpos #print "Max:", minpos #print "Median:", median return median
def calibrateVec(self, r, v): if (self.vectorLen(r) != 0): factor = self.vectorLen(v) / self.vectorLen(r) rx = factor * r.x() ry = factor * r.y() rz = factor * r.z() return QVector3D(rx, ry, rz) else: # if original vector is zero length, the rotated one must be too, just return r return r
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")
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 = QVector3D(1, 0, 0) elif self.grabbed_axis == self.AXIS_GREEN: axis = QVector3D(0, 1, 0) elif self.grabbed_axis == self.AXIS_BLUE: axis = QVector3D(0, 0, 1) ort = ort * QQuaternion.fromAxisAndAngle(axis, mov) else: euler = mu.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 = mu.euler_to_quat(euler) ent.placeable.Orientation = ort ent.network.Orientation = ort
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 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 setManipulatorScale(self, ents): if ents is None or len(ents) == 0: return campos = naali.getCamera().placeable.position ent = ents[-1] entpos = ent.placeable.position length = (campos - entpos).length() v = self.MANIPULATORSCALE factor = length * .1 newv = QVector3D(v) * factor try: self.manipulator.placeable.scale = newv except AttributeError: pass
def changepos(self, i, v): #XXX NOTE / API TODO: exceptions in qt slots (like this) are now eaten silently #.. apparently they get shown upon viewer exit. must add some qt exc thing somewhere ent = self.active if ent is not None: qpos = QVector3D(ent.placeable.Position) if i == 0: qpos.setX(v) elif i == 1: qpos.setY(v) elif i == 2: qpos.setZ(v) ent.placeable.Position = qpos ent.network.Position = qpos self.manipulator.moveTo(self.sels) if not self.dragging: r.networkUpdate(ent.id) self.modified = True
def changescale(self, i, v): ent = self.active if ent is not None: qscale = ent.placeable.Scale #oldscale = list((qscale.x(), qscale.y(), qscale.z())) scale = list((qscale.x(), qscale.y(), qscale.z())) if not self.float_equal(scale[i], v): scale[i] = v # if self.window.mainTab.scale_lock.checked: # #XXX BUG does wrong thing - the idea was to maintain aspect ratio # diff = scale[i] - oldscale[i] # for index in range(len(scale)): # #print index, scale[index], index == i # if index != i: # scale[index] += diff ent.placeable.Scale = QVector3D(scale[0], scale[1], scale[2]) if not self.dragging: r.networkUpdate(ent.id) self.modified = True
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 x = 0 y = 0
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 vectorAdd(self, v1, v2): """ rotations stopped working when using v1-v2 and v1+v2, so currently this method remains here """ x = v1.x()+v2.x() y = v1.y()+v2.y() z = v1.z()+v2.z() return QVector3D(x, y, z)
def get_right(entity): v = QVector3D(1.0, 0.0, 0.0) return quat_mult_vec(entity.placeable.orientation, v)
def vectorAdd(self, v1, v2): x = v1.x() + v2.x() y = v1.y() + v2.y() z = v1.z() + v2.z() return QVector3D(x, y, z)
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();')
def vectorDifference(self, v1, v2): x = v1.x() - v2.x() y = v1.y() - v2.y() z = v1.z() - v2.z() return QVector3D(x, y, z)
#~ #print keys, mats.keys(), mats[keys[0]] if 0: #qplaceable id = 2138143966 #qplace = r.getQPlaceable(id) e = e.getEntity(id) qplace = e.placeable print qplace, qplace.Position oldz = qplace.Position.z() print oldz, "==>", import PythonQt.QtGui from PythonQt.QtGui import QVector3D change_v = QVector3D(0, 0, 0.1) #dir shows __add__ but for some reason doesn't work out of the box :( #"unsupported operand type(s) for +=: 'QVector3D' and 'QVector3D'" #qplace.Position += change_v #qplace.Position + change_v #bleh and this changes the val in the vec, but doesn't trigger the *vec* setter, #so no actual change in Naali internals #qplace.Position.setZ(oldz + 0.1) newpos = qplace.Position newpos.setZ(oldz + 0.1) qplace.Position = newpos print qplace.Position.z(), "." if 0: