Beispiel #1
0
        public override void Update(ApplicationTime time)
        {
            IOxRenderPluginAvatar avatar = (IOxRenderPluginAvatar)Ox.Service.Get(typeof(IOxRenderPluginAvatar));
            SceneNode sn = avatar.GetAvatarScneNode(Ox.DataStore.World.Agent.ID);
            if (sn == null || node == null)
                return;

            node.Target = sn.Position + Render.RenderData.AgentHeadPosition;

            Matrix4 rot = new Matrix4();
            //rot.RotationDegrees = Util.ToRotationRH(new float[] {
            //    0,
            //    0,
            //    (float)(Ox.DataStore.World.Agent.Head * NewMath.RADTODEG) + Util.ROTATION_AND_3DS_OFFSET.Z });

            Quaternion q0 = new Quaternion();
            Quaternion q1 = new Quaternion();
            q0.fromAngleAxis(Ox.DataStore.Camera.Angle[0] + NewMath.DEGTORAD * Util.ROTATION_AND_3DS_OFFSET.Z, new Vector3D(0, 0, 1));
            q1.fromAngleAxis(Ox.DataStore.Camera.Angle[1], new Vector3D(1, 0, 0));
            q1 = q1 * q0;
            Vector3D vec = new Vector3D(0, -Ox.DataStore.Camera.Distance, 0);
            node.Position = node.Target + q1.Matrix.RotateVect(ref vec);

            if (Ox.DataStore.Camera.Angle[1] < -MathHelper.PIOver2 || MathHelper.PIOver2 < Ox.DataStore.Camera.Angle[1])
                node.UpVector = new Vector3D(0, 0, -1);
            else
                node.UpVector = new Vector3D(0, 0, 1);

            base.Update(time);
        }
Beispiel #2
0
 // Copy constructor (had to do this because we cannot overload operator "=" in C#
 public Quaternion(Quaternion other)
 {
     m_x = other.X;
     m_y = other.Y;
     m_z = other.Z;
     m_w = other.W;
 }
Beispiel #3
0
        public override void Startup()
        {
            //Create a New Irrlicht Device
            //device.Timer.Stop();
            Device.Timer.Speed   = 1;
            Device.WindowCaption = "IdealistViewer 0.001";
            //   viewerRenderPlane.Device = Device;
            //  viewerRenderPlane.Renderer = this;
            // Device.Resizeable = true;

            // Sets directory to load assets from
            Device.FileSystem.WorkingDirectory = m_viewer.StartupDirectory + "/" + Util.MakePath("media", "materials", "textures", "");  //We set Irrlicht's current directory to %application directory%/media


            Driver       = Device.VideoDriver;
            SceneManager = Device.SceneManager;

            GuiEnvironment = Device.GUIEnvironment;

            // Compose Coordinate space converter quaternion
            IrrlichtNETCP.Matrix4 m4 = new IrrlichtNETCP.Matrix4();
            m4.SetM(0, 0, 1);
            m4.SetM(1, 0, 0);
            m4.SetM(2, 0, 0);
            m4.SetM(3, 0, 0);
            m4.SetM(0, 1, 0);
            m4.SetM(1, 1, 0);
            m4.SetM(2, 1, 1);
            m4.SetM(3, 1, 0);
            m4.SetM(0, 2, 0);
            m4.SetM(1, 2, 1);
            m4.SetM(2, 2, 0);
            m4.SetM(3, 2, 0);
            m4.SetM(0, 3, 0);
            m4.SetM(1, 3, 0);
            m4.SetM(2, 3, 0);
            m4.SetM(3, 3, 1);


            CoordinateConversion_XYZ_XZY = new IrrlichtNETCP.Quaternion(m4);
            CoordinateConversion_XYZ_XZY.makeInverse();
        }
Beispiel #4
0
        public override void Startup()
        {
            //Create a New Irrlicht Device
            //device.Timer.Stop();
            Device.Timer.Speed = 1;
            Device.WindowCaption = "IdealistViewer 0.001";
             //   viewerRenderPlane.Device = Device;
              //  viewerRenderPlane.Renderer = this;
               // Device.Resizeable = true;

            // Sets directory to load assets from
            Device.FileSystem.WorkingDirectory = m_viewer.StartupDirectory + "/" + Util.MakePath("media", "materials", "textures", "");  //We set Irrlicht's current directory to %application directory%/media

            Driver = Device.VideoDriver;
            SceneManager = Device.SceneManager;

            GuiEnvironment = Device.GUIEnvironment;

            // Compose Coordinate space converter quaternion
            IrrlichtNETCP.Matrix4 m4 = new IrrlichtNETCP.Matrix4();
            m4.SetM(0, 0, 1);
            m4.SetM(1, 0, 0);
            m4.SetM(2, 0, 0);
            m4.SetM(3, 0, 0);
            m4.SetM(0, 1, 0);
            m4.SetM(1, 1, 0);
            m4.SetM(2, 1, 1);
            m4.SetM(3, 1, 0);
            m4.SetM(0, 2, 0);
            m4.SetM(1, 2, 1);
            m4.SetM(2, 2, 0);
            m4.SetM(3, 2, 0);
            m4.SetM(0, 3, 0);
            m4.SetM(1, 3, 0);
            m4.SetM(2, 3, 0);
            m4.SetM(3, 3, 1);

            CoordinateConversion_XYZ_XZY = new IrrlichtNETCP.Quaternion(m4);
            CoordinateConversion_XYZ_XZY.makeInverse();
        }
        public void UpdateDirection()
        {
            DateTime now = Reference.Viewer.WorldTime;
            TimeSpan span = new DateTime(2009, 1, 1, now.Hour, now.Minute, now.Second) - DateTime.Parse("2009-01-01 07:00:00");
            int sec = span.Hours * 3600 + span.Minutes * 60 + span.Seconds;
            int end = 10 * 3600 + 0 * 60 + 0;
            float amount = (float)sec / end;
            amount = Util.Clamp<float>(amount, 0, 1);
            angle = OpenViewer.Util.Lerp(sunriseAngle, sunsetAngle, amount);

            qx.fromAngleAxis((float)(Math.PI / 1.25f), new Vector3D(1, 0, 0));
            qy.fromAngleAxis(angle, new Vector3D(0, 1, 0));
            qy = qx * qy;
            Vector3D rot;
            qy.toEuler(out rot);
            rotation = new Vector3D(rot.X, rot.Y, rot.Z) * OpenMetaverse.Utils.RAD_TO_DEG;
        }
        private void ProcessObjectQueueUpdateToNode(VObject _obj)
        {
            // Little known fact.  Dead avatar in LibOMV have the word 'dead' in their UUID
            // Skip over this one and move on to the next one if it's dead.
            if (((Avatar)_obj.Prim).ID.ToString().Contains("dead"))
            {
                return;
            }

            if (_obj.Node == null)
            {
                return;
            }

            //If we don't have an avatar representation yet for this avatar or it's a full update
            if (_obj.Requesting == false)
            {
                if ((_obj._3DiIrrfileUUID != _obj.RequestIrrfileUUID) && (_obj.RequestIrrfileUUID != UUID.Zero))
                {
                    if (Reference.Viewer.IrrManager.Contains(_obj.RequestIrrfileUUID) == false)
                    {
                        _obj.requestTexturesDirectlyFromAssetServerWithoutJ2KConversion = true;
                        Reference.Viewer.IrrManager.RequestObject(_obj);
                        Reference.Log.Debug("Request object: UUID:" + _obj.RequestIrrfileUUID.ToString());
                    }
                    else
                    {
                        _obj._3DiIrrfileUUID = _obj.RequestIrrfileUUID;

                        IrrDatas datas = Reference.Viewer.IrrManager.GetObject(_obj._3DiIrrfileUUID, true);
                        if (datas != null)
                        {
                            // Set avatar mesh.
                            lock (entities)
                            {
                                Reference.Viewer.EffectManager.RemoveGhostNode(_obj.Node);
                                _obj.IsGhost = false;

                                AnimatedMeshSceneNode animeNode = Reference.Viewer.IrrManager.IrrFileLoad(datas, Reference.SceneManager, _obj, "tmpmesh_" + _obj.Prim.LocalID.ToString() + "_");
                                if (animeNode != null)
                                {
                                    animeNode.AnimationEnd += animeNode_AnimationEnd;
                                    animeNode.SetTransitionTime(0.1f);

                                    _obj.Mesh = animeNode.AnimatedMesh.GetMesh(0);
                                    SetAnimation(_obj, _obj.Prim.ParentID != 0 ? "sitstart" : "standing");
                                }
                            }
                        }

                        Reference.Log.Debug("Loaded object: UUID:" + _obj.RequestIrrfileUUID.ToString());
                    }
                }
            }

            AnimationFrame(_obj, _obj.Prim.ParentID != 0);

            _obj.TargetPosition = new Vector3D(_obj.Prim.Position.X, _obj.Prim.Position.Z - 0.83f, _obj.Prim.Position.Y);
            _obj.Velocity = new Vector3D(_obj.Prim.Velocity.X, _obj.Prim.Velocity.Z, _obj.Prim.Velocity.Y);

            if (_obj.Prim.ID != userUUID)
            {
                // REVIEW NEEDED: a more general calculation
                //float roll, pitch, yaw;
                //_obj.Prim.Rotation.GetEulerAngles(out roll, out pitch, out yaw);
                //_obj.Node.Rotation = new Vector3D(Utils.ToDegrees(roll), Utils.ToDegrees(pi2 - pitch), Utils.ToDegrees(yaw));
                Vector3 axis;
                float angle;
                _obj.Prim.Rotation.GetAxisAngle(out axis, out angle);
                _obj.Node.Rotation = new Vector3D(0, Utils.ToDegrees((axis.Z > 0 ? 1 : -1) * (pi2 - angle)), 0);
            }

            // If exsit parent prim, set parent.
            uint parentID = _obj.Prim.ParentID;
            if (parentID == 0)
            {
                _obj.ParentPosition = new Vector3();

                if (_obj.IsChildAgent)
                {
                    _obj.IsChildAgent = false;
                    _obj.SmoothingReset = true;
                }
            }
            else
            {
                ulong regionID = Reference.Viewer.ProtocolManager.AvatarConnection.m_user.Network.CurrentSim.Handle;

                if (Reference.Viewer.EntityManager.Entities.ContainsKey(regionID.ToString() + parentID.ToString()))
                {
                    VObject parentObj = Reference.Viewer.EntityManager.Entities[regionID.ToString() + parentID.ToString()];

                    if (parentObj != null)
                    {
                        _obj.ParentPosition = parentObj.Prim.Position;

                        IrrlichtNETCP.Quaternion iquParent = new IrrlichtNETCP.Quaternion
                            (parentObj.Prim.Rotation.X,
                             parentObj.Prim.Rotation.Z,
                             parentObj.Prim.Rotation.Y,
                             parentObj.Prim.Rotation.W);
                        iquParent.makeInverse();
                        IrrlichtNETCP.Quaternion iquAvatar = new IrrlichtNETCP.Quaternion
                            (_obj.Prim.Rotation.X,
                             _obj.Prim.Rotation.Z,
                             _obj.Prim.Rotation.Y,
                             _obj.Prim.Rotation.W);
                        iquAvatar.makeInverse();

                        IrrlichtNETCP.Quaternion finalRotation = iquAvatar * iquParent;
                        _obj.Node.Rotation = finalRotation.Matrix.RotationDegrees;
                        _obj.TargetPosition = parentObj.Node.Position + _obj.TargetPosition * iquParent;
                    }

                    _obj.SmoothingReset = true;
                    _obj.IsChildAgent = true;
                }
                else
                {
                    UpdateObjectToPiplineEnqueue(_obj);
                }
            }
            _obj.SyncToChilds();

            // If avatar's height position is minus, teleport to current sim center.
            if (_obj.Prim.ID == Reference.Viewer.ProtocolManager.AvatarConnection.GetSelfUUID && _obj.Prim.Position.Z < 0)
                Reference.Viewer.ProtocolManager.Teleport(Reference.Viewer.ProtocolManager.GetCurrentSimName(), 128, 128, 128);
        }
Beispiel #7
0
        //! Interpolates the Quaternion between to Quaternions based on time
        public Quaternion Slerp(Quaternion q1, Quaternion q2, float time)
        {
            float angle = q1.GetDotProduct(q2);

            if (angle < 0.0f)
            {
                q1 *= -1.0f;
                angle *= -1.0f;
            }

            float scale;
            float invscale;

            if ((angle + 1.0f) > 0.05f)
            {
                if ((1.0f - angle) >= 0.05f)  // spherical interpolation
                {
                    float theta = (float)Math.Acos(angle);
                    float invsintheta = 1.0f / (float)Math.Sin(theta);
                    scale = (float)Math.Sin(theta * (1.0f - time)) * invsintheta;
                    invscale = (float)Math.Sin(theta * time) * invsintheta;
                }
                else // linear interploation
                {
                    scale = 1.0f - time;
                    invscale = time;
                }
            }
            else
            {
                q2 = new Quaternion(-q1.Y, q1.X, -q1.W, q1.Z);
                scale = (float)Math.Sin(Math.PI * (0.5f - time));
                invscale = (float)Math.Sin(Math.PI * time);
            }

            Quaternion t_tmp= (q1 * scale) + (q2 * invscale);
            this.m_x = t_tmp.X;
            this.m_y = t_tmp.Y;
            this.m_z = t_tmp.Z;
            this.m_w = t_tmp.W;
            return this;
        }
Beispiel #8
0
 //! calculates the dot product
 public float GetDotProduct( Quaternion q2)
 {
     return (m_x * q2.X) + (m_y * q2.Y) + (m_z * q2.Z) + (m_w * q2.W);
 }
Beispiel #9
0
        //! sets new Quaternion based on euler angles
        public static Quaternion FromEulerAngles(float x, float y, float z)
        {
            Quaternion t_tmp = new Quaternion();
            //TODO Duplicated code (Method Set(x,y,z))
            double angle;

            angle = x * 0.5;
            double sr = (float)Math.Sin(angle);
            double cr = (float)Math.Cos(angle);

            angle = y * 0.5;
            double sp = (float)Math.Sin(angle);
            double cp = (float)Math.Cos(angle);

            angle = z * 0.5;
            double sy = (float)Math.Sin(angle);
            double cy = (float)Math.Cos(angle);

            double cpcy = cp * cy;
            double spcy = sp * cy;
            double cpsy = cp * sy;
            double spsy = sp * sy;

            t_tmp.X = (float)(sr * cpcy - cr * spsy);
            t_tmp.Y = (float)(cr * spcy + sr * cpsy);
            t_tmp.Z = (float)(cr * cpsy - sr * spcy);
            t_tmp.W = (float)(cr * cpcy + sr * spsy);

            t_tmp.Normalize();
            return t_tmp;
        }
Beispiel #10
0
        //! multiplication by a quaternion operator
        public static Quaternion operator *(Quaternion lhs, Quaternion rhs)
        {
            Quaternion tmp=new Quaternion();

            tmp.W = (rhs.W * lhs.W) - (rhs.X * lhs.X) - (rhs.Y * lhs.Y) - (rhs.Z * lhs.Z);
            tmp.X = (rhs.W * lhs.X) + (rhs.X * lhs.W) + (rhs.Y * lhs.Z) - (rhs.Z * lhs.Y);
            tmp.Y = (rhs.W * lhs.Y) + (rhs.Y * lhs.W) + (rhs.Z * lhs.X) - (rhs.X * lhs.Z);
            tmp.Z = (rhs.W * lhs.Z) + (rhs.Z * lhs.W) + (rhs.X * lhs.Y) - (rhs.Y * lhs.X);

            return tmp;
        }
Beispiel #11
0
        /// <summary>
        /// Update camera position based on it's current PHI, Theta, and mouse offset.
        /// </summary>
        public void UpdateCameraPosition()
        {
            Vector3D newpos = new Vector3D();
            Vector3D oldTarget = targetTarget;
            switch (CameraMode)
            {
                case ECameraMode.ThirdWithArbitraryOffset:
                case ECameraMode.Build:
                    {
                        newpos.X = oldTarget.X + (nowDistance * (float)Math.Cos(Reference.Viewer.CamRotationAngleTHETA + loMouseOffsetTHETA) * (float)Math.Sin(Reference.Viewer.CamRotationAnglePHI + loMouseOffsetPHI));
                        newpos.Y = oldTarget.Y + nowDistance * (float)Math.Cos(Reference.Viewer.CamRotationAnglePHI + loMouseOffsetPHI);
                        newpos.Z = oldTarget.Z + nowDistance * (float)Math.Sin(Reference.Viewer.CamRotationAngleTHETA + loMouseOffsetTHETA) * (float)Math.Sin(Reference.Viewer.CamRotationAnglePHI + loMouseOffsetPHI);

                        targetPosition = newpos;
                        targetTarget = oldTarget;
                    }

                    break;

                case ECameraMode.Third:
                    if (VOtarget != null)
                    {
                        // in 3rd person camera mode, default setting is 5 meter distance, 10 degree phi elevation, behind avatar.
                        // the "behind" avatar part is tricky. we need to calculate the heading (theta) of the avatar in spherical
                        // cam coordinates and use that theta to compute the final camera position.

                        nowDistance = Reference.Viewer.CameraKeyWalkingDistance;
                        Reference.Viewer.CamRotationAnglePHI = ((90.0f - 10.0f) / 180.0f) * (float)Math.PI; // 10 degree elevation. 0 deg=straight overhead

                        // calculate avatar heading based on its prim's orientation.
                        // this calculation here works, but is pretty confusing because of all the coordinate
                        // system transformations going on. This code should be cleaned up to be more
                        // understandable when there is time. In particular, we need to consider the coordinate
                        // system of the world, the spherical camera coordinate system, and the avatar's orientation.

                        OpenMetaverse.Quaternion primRot = VOtarget.Prim.Rotation;
                        IrrlichtNETCP.Quaternion q = new IrrlichtNETCP.Quaternion(primRot.X, primRot.Y, primRot.Z, primRot.W);
                        IrrlichtNETCP.Matrix4 avMatrix = q.Matrix;
                        Vector3D heading = new Vector3D(avMatrix.GetM(1, 0), avMatrix.GetM(1, 1), avMatrix.GetM(1, 2));
                        heading.Y *= -1.0f; // convert avatar coords to IV cam spherical coords

                        float headingAngle;
                        // calculate heading (theta) in IV cam spherical coords
                        if (Math.Abs(heading.X) > 0.0)
                        {
                            headingAngle = (float)Math.Atan((double)(heading.Y / heading.X));
                            if (heading.X < 0.0f)
                            {
                                headingAngle += (float)Math.PI;
                            }
                            if (headingAngle < 0.0)
                            {
                                headingAngle += 2.0f * (float)Math.PI;
                            }
                        }
                        else
                        {
                            if (heading.Y > 0)
                            {
                                headingAngle = 0.5f * (float)Math.PI; // 90 deg
                            }
                            else
                            {
                                headingAngle = 1.5f * (float)Math.PI; // 270 deg
                            }
                        }

                        //Console.WriteLine("avatar heading seems to be " + heading + " angle " + headingAngle * 360.0f / (2.0f*(float)Math.PI));
                        //Console.WriteLine("avatar matrix seems to be " + avMatrix);
                        Reference.Viewer.CamRotationAngleTHETA = headingAngle - 0.5f * (float)Math.PI; // position camera behind avatar. This calculation is a little strange, but it works; no time to make it cleaner right now.

                        {
                            newpos.X = oldTarget.X + (nowDistance * (float)Math.Cos(Reference.Viewer.CamRotationAngleTHETA + loMouseOffsetTHETA) * (float)Math.Sin(Reference.Viewer.CamDefaultRotationAnglePHI + loMouseOffsetPHI));
                            newpos.Y = oldTarget.Y + nowDistance * (float)Math.Cos(Reference.Viewer.CamDefaultRotationAnglePHI + loMouseOffsetPHI);
                            newpos.Z = oldTarget.Z + nowDistance * (float)Math.Sin(Reference.Viewer.CamRotationAngleTHETA + loMouseOffsetTHETA) * (float)Math.Sin(Reference.Viewer.CamDefaultRotationAnglePHI + loMouseOffsetPHI);

                            targetPosition = newpos;
                            targetTarget = oldTarget;
                        }
                    }
                    break;

            }
        }