public void Evaluate(int SpreadMax)
        {
            if (this.bodies.IsConnected)
            {
                this.position.SliceCount    = bodies.SliceCount;
                this.orientation.SliceCount = bodies.SliceCount;

                var pos = this.position.Stream.Buffer;
                var rot = this.orientation.Stream.Buffer;

                for (int i = 0; i < SpreadMax; i++)
                {
                    RigidBody body = this.bodies[i];
                    pos[i] = new SlimDX.Vector3(body.MotionState.WorldTransform.M41, body.MotionState.WorldTransform.M42, body.MotionState.WorldTransform.M43);

                    Quaternion r = body.Orientation;
                    rot[i] = new SlimDX.Quaternion(r.X, r.Y, r.Z, r.W);
                }
                this.position.Flush(true);
                this.orientation.Flush(true);
            }
            else
            {
                this.position.SliceCount    = 0;
                this.orientation.SliceCount = 0;
            }
        }
Ejemplo n.º 2
0
 public void Write(SlimDX.Quaternion data)
 {
     unsafe
     {
         SlimDX.Quaternion *pPtr = &data;
         Write((IntPtr)pPtr, sizeof(SlimDX.Quaternion));
     }
 }
Ejemplo n.º 3
0
 public static XElement SerializeQuaternion(SlimDX.Quaternion Quat)
 {
     return(new XElement("Quaternion",
                         new XElement("X", Quat.X),
                         new XElement("Y", Quat.Y),
                         new XElement("Z", Quat.Z),
                         new XElement("W", Quat.W)
                         ));
 }
Ejemplo n.º 4
0
		public ColladaBoneMatrix(string name,
			LowLevel.Math.real_point3d translation,
			LowLevel.Math.real_quaternion rotation,
			float scale)
		{
			Name = name;
			translationVector = new SlimDX.Vector3(translation.X, translation.Y, translation.Z);
			rotationQuaternion = new SlimDX.Quaternion(rotation.Vector.I, rotation.Vector.J, rotation.Vector.K, rotation.W);
			scaleAmount = scale;
		}
 public ColladaBoneMatrix(string name,
                          LowLevel.Math.real_point3d translation,
                          LowLevel.Math.real_quaternion rotation,
                          float scale)
 {
     Name = name;
     translationVector  = new SlimDX.Vector3(translation.X, translation.Y, translation.Z);
     rotationQuaternion = new SlimDX.Quaternion(rotation.Vector.I, rotation.Vector.J, rotation.Vector.K, rotation.W);
     scaleAmount        = scale;
 }
        public void Evaluate(int SpreadMax)
        {
            this.output.SliceCount = SpreadMax;

            fixed(RigidBodyPose *posePtr = &this.output.Stream.Buffer[0])
            {
                for (int i = 0; i < SpreadMax; i++)
                {
                    SlimDX.Vector3    p = position[i];
                    SlimDX.Quaternion q = orientation[i];
                    posePtr[i].Position    = *(BulletSharp.Vector3 *) & p;
                    posePtr[i].Orientation = *(BulletSharp.Quaternion *) & q;
                }
            }

            this.output.Flush(true);
        }
Ejemplo n.º 7
0
 public void WritePODObject(System.Object obj)
 {
     System.Type type = obj.GetType();
     if (type == typeof(System.SByte))
     {
         Write(System.Convert.ToSByte(obj));
     }
     else if (type == typeof(System.Int16))
     {
         Write(System.Convert.ToInt16(obj));
     }
     else if (type == typeof(System.Int32))
     {
         Write(System.Convert.ToInt32(obj));
     }
     else if (type == typeof(System.Int64))
     {
         Write(System.Convert.ToInt64(obj));
     }
     else if (type == typeof(System.Byte))
     {
         Write(System.Convert.ToByte(obj));
     }
     else if (type == typeof(System.UInt16))
     {
         Write(System.Convert.ToUInt16(obj));
     }
     else if (type == typeof(System.UInt32))
     {
         Write(System.Convert.ToUInt32(obj));
     }
     else if (type == typeof(System.UInt64))
     {
         Write(System.Convert.ToUInt64(obj));
     }
     else if (type == typeof(System.Single))
     {
         Write(System.Convert.ToSingle(obj));
     }
     else if (type == typeof(System.Double))
     {
         Write(System.Convert.ToDouble(obj));
     }
     else if (type == typeof(System.Guid))
     {
         //Guid id = Guid.Parse(obj.ToString());
         System.Guid id = (System.Guid)(obj);
         Write(id);
     }
     else if (type == typeof(SlimDX.Vector2))
     {
         SlimDX.Vector2 v = (SlimDX.Vector2)(obj);
         Write(v);
     }
     else if (type == typeof(SlimDX.Vector3))
     {
         //Guid id = Guid.Parse(obj.ToString());
         SlimDX.Vector3 v = (SlimDX.Vector3)(obj);
         Write(v);
     }
     else if (type == typeof(SlimDX.Vector4))
     {
         SlimDX.Vector4 v = (SlimDX.Vector4)(obj);
         Write(v);
     }
     else if (type == typeof(SlimDX.Quaternion))
     {
         SlimDX.Quaternion q = (SlimDX.Quaternion)(obj);
         Write(q);
     }
     else if (type == typeof(SlimDX.Matrix))
     {
         SlimDX.Matrix mat = (SlimDX.Matrix)(obj);
         Write(mat);
     }
     else if (type == typeof(System.String))
     {
         System.String str = (System.String)(obj);
         Write(str);
     }
     else if (type == typeof(DataWriter))
     {
         var dr = (DataWriter)(obj);
         Write(dr);
     }
 }
Ejemplo n.º 8
0
 void convert(object F)
 {
     const float v_Scale = 65;
     P.startLoading();
     ManagedWorld.NodeLibrary.AddToOcTree = false;
     bool b = FileManager.NotifyOnPhysicalWatch;
     FileManager.NotifyOnPhysicalWatch = false;
     System.IO.FileInfo f0 = new System.IO.FileInfo((string)F);
     SlimDX.Design.Vector3Converter VC = new SlimDX.Design.Vector3Converter();
     SlimDX.Design.QuaternionConverter QC = new SlimDX.Design.QuaternionConverter();
     string[] T = System.IO.File.ReadAllLines((string)F, Encoding.ASCII);
     int l = 0;
     List<ILrentObject> objs = new List<ILrentObject>();
     while (l < T.Length)
     {
         if (T[l++].StartsWith("<Model>"))
         {
             string n = T[l++];
             SlimDX.Vector3 t = (SlimDX.Vector3)VC.ConvertFrom(T[l++]), t2 = new SlimDX.Vector3(-t.Z, t.Y, t.X) * v_Scale;
             SlimDX.Quaternion o = (SlimDX.Quaternion)QC.ConvertFrom(T[l++]), o2 = new SlimDX.Quaternion(-o.Z, o.Y, o.X, o.W);
             SlimDX.Vector3 s = (SlimDX.Vector3)VC.ConvertFrom(T[l++]);
             string p = T[l++], x = p.ToLower().Replace(".obj", "._xmsh"), c = p.ToLower().Replace(".obj", "_COL._xcom"), pf = System.IO.Path.Combine(f0.DirectoryName, p);
             LevelMeshConverter.Convert(P.Device, pf, v_Scale * s, null, null);
             ILrentObject O = newEntityControl.addXMSH(x, c, P.Device, t2, o, P.CurrFile, false);
             objs.Add(O);
             if (l % 5 == 0)
                 P.setPercentage((int)(((float)l / (float)T.Length) * 100.0f));
         }
     }
     FileManager.NotifyOnPhysicalWatch = b;
     update();
     ManagedWorld.NodeLibrary.AddToOcTree = true;
     ManagedWorld.NodeLibrary.OcTree.Build();
     P.endLoading();
     RisenWorld.OnLoadingFinished();
     RisenWorld.OnEntityAdded(objs.ToArray());
 }
Ejemplo n.º 9
0
        private static Curves.QuaternionCurve CreateQuaternionCurve(BinaryReaderEx reader, short count)
        {
            var result = new Curves.QuaternionCurve();

            bool flag = (count & 0x80) != 0;
            int numLengths = count & 0xFF7F;

            var lengths = reader.ReadBytes(numLengths);

            // Lengths section is always a multiple of 4-bytes in length, so advance the stream past the unused bytes
            var unusedBytes = ((numLengths + 3) & 0x7FFFFFFC) - numLengths;

            reader.BaseStream.Position += unusedBytes;

            for (var i = 0; i < numLengths; i++)
            {
                byte len = lengths[i];
                for (var j = 0; j < len; j++)
                {
                    long data = 0;
                    data = (long)reader.ReadUInt16(Endianness.BigEndian) << 32;
                    data |= (long)reader.ReadUInt16(Endianness.BigEndian) << 16;
                    data |= (long)reader.ReadUInt16(Endianness.BigEndian);

                    int index = (int)(data >> 43) & 0x1F; // 5-bit index of this quaternion
                    int signFlags = (int)(data >> 39) & 0x0F; // 4-bit sign Flags
                    int val = (int)(data >> 17) & 0x3FFFFF; // 22-bit integer
                    int wVal = (int)(data & 0x1FFFF); // 17-bit integer

                    int globalIdx = index + 32 * i;

                    float w = (float)wVal / 131071.0f;
                    if (flag)
                    {
                        w = 1 - w * w;
                    }

                    double halfPi = Math.PI * 0.5;

                    double dVal = (double)val;
                    double sqrtVal = Math.Sqrt(dVal);
                    double sqrtValWholePart = Math.Truncate(sqrtVal);

                    double v44 = halfPi * (1 - (sqrtValWholePart / 2047));
                    double tmp = (sqrtValWholePart < 0.001) ? 0 : halfPi * (dVal - sqrtValWholePart * sqrtValWholePart) / (2 * sqrtValWholePart);

                    double tmp6 = Math.Sqrt(1 - w * w);
                    double tX = Math.Sin(-tmp);
                    double tY = Math.Sin(halfPi - tmp);
                    double tZ = Math.Sin(v44);
                    double tW = Math.Sin(v44 - halfPi);

                    float rX = (float)(tY * -tW * tmp6);
                    float rY = (float)(tZ * tmp6);
                    float rZ = (float)(-tX * -tW * tmp6);

                    SlimDX.Quaternion qValue = new SlimDX.Quaternion();
                    if ((signFlags & 0x8) != 0)
                    {
                        signFlags ^= 0xF; // Switch all the bits
                        qValue.W = -w;
                    }
                    else
                    {
                        qValue.W = w;
                    }

                    // Flag Set means Negate
                    qValue.X = ((signFlags & 0x4) != 0) ? -rX : rX;
                    qValue.Y = ((signFlags & 0x2) != 0) ? -rY : rY;
                    qValue.Z = ((signFlags & 0x1) != 0) ? -rZ : rZ;

                    qValue.Normalize();

                    var curveValue = new Curves.QuaternionCurveValue()
                    {
                        Time = (float)globalIdx,
                        Value = qValue
                    };

                    result.Values.Add(curveValue);
                }
            }

            return result;
        }
 public static Microsoft.Xna.Framework.Quaternion xna(this SlimDX.Quaternion v)
 {
     return(new Microsoft.Xna.Framework.Quaternion(v.X, v.Y, v.Z, v.W));
 }
Ejemplo n.º 11
0
        protected bool WritePkg(PackageWriter pkg, System.Reflection.PropertyInfo i)
        {
            var propType = i.PropertyType;

            if (propType == typeof(System.SByte))
            {
                pkg.Write(System.Convert.ToSByte(i.GetValue(this, null)));
            }
            else if (propType == typeof(System.Int16))
            {
                pkg.Write(System.Convert.ToInt16(i.GetValue(this, null)));
            }
            else if (propType == typeof(System.Int32))
            {
                pkg.Write(System.Convert.ToInt32(i.GetValue(this, null)));
            }
            else if (propType == typeof(System.Int64))
            {
                pkg.Write(System.Convert.ToInt64(i.GetValue(this, null)));
            }
            else if (propType == typeof(System.Byte))
            {
                pkg.Write(System.Convert.ToByte(i.GetValue(this, null)));
            }
            else if (propType == typeof(System.UInt16))
            {
                pkg.Write(System.Convert.ToUInt16(i.GetValue(this, null)));
            }
            else if (propType == typeof(System.UInt32))
            {
                pkg.Write(System.Convert.ToUInt32(i.GetValue(this, null)));
            }
            else if (propType == typeof(System.UInt64))
            {
                pkg.Write(System.Convert.ToUInt64(i.GetValue(this, null)));
            }
            else if (propType == typeof(System.Single))
            {
                pkg.Write(System.Convert.ToSingle(i.GetValue(this, null)));
            }
            else if (propType == typeof(System.Double))
            {
                pkg.Write(System.Convert.ToDouble(i.GetValue(this, null)));
            }
            else if (propType == typeof(System.Guid))
            {
                System.Guid id = (System.Guid)(i.GetValue(this, null));
                pkg.Write(id);
            }
            else if (propType == typeof(SlimDX.Vector2))
            {
                SlimDX.Vector2 id = (SlimDX.Vector2)(i.GetValue(this, null));
                pkg.Write(id);
            }
            else if (propType == typeof(SlimDX.Vector3))
            {
                SlimDX.Vector3 id = (SlimDX.Vector3)(i.GetValue(this, null));
                pkg.Write(id);
            }
            else if (propType == typeof(SlimDX.Vector4))
            {
                SlimDX.Vector4 id = (SlimDX.Vector4)(i.GetValue(this, null));
                pkg.Write(id);
            }
            else if (propType == typeof(SlimDX.Quaternion))
            {
                SlimDX.Quaternion id = (SlimDX.Quaternion)(i.GetValue(this, null));
                pkg.Write(id);
            }
            else if (propType == typeof(SlimDX.Matrix))
            {
                SlimDX.Matrix id = (SlimDX.Matrix)(i.GetValue(this, null));
                pkg.Write(id);
            }
            else if (propType == typeof(System.DateTime))
            {
                System.DateTime id = (System.DateTime)(i.GetValue(this, null));
                pkg.Write(id);
            }
            else if (propType == typeof(System.String))
            {
                System.String str = (System.String)(i.GetValue(this, null));
                pkg.Write(str);
            }
            else if (propType == typeof(System.Byte[]))
            {
                System.Byte[] str = (System.Byte[])(i.GetValue(this, null));
                pkg.Write(str);
            }
            else
            {
                return(false);
            }
            return(true);
        }
Ejemplo n.º 12
0
        private void CreateBone(ModelBone i, int no)
        {
            var boneid  = i.Name.Replace(" ", "_");
            var bone    = new Bone()       { ID= "Bone-"+boneid, Name= i.Name, };
            var bonenode= new VisualNode() { ID= "Node-"+boneid, Name= i.Name, Instance= bone };
            var trn     = new SlimDX.Vector3(i.Params[0], i.Params[1], i.Params[2]);
            var rot     = new SlimDX.Quaternion(i.Params[3], i.Params[4], i.Params[5], -i.Params[6]);
            var mat     = SlimDX.Matrix.RotationQuaternion(rot)
                        * SlimDX.Matrix.Translation(trn);

            bonenode.SID            = "joint" + no;
            bonenode.LocalTransform = mat;

            Bones.Add(bonenode);
            Root.Instances.Add(bone);

            if(i.ParentID < 0)
            {
                bonenode.GlobalTransform= mat;

                Scene.Nodes.Add(bonenode);
            } else
            {
                var parent              = Bones[i.ParentID];
                bonenode.GlobalTransform= mat * parent.GlobalTransform;
                //bonenode.GlobalTransform= parent.GlobalTransform * mat;

                parent.Nodes.Add(bonenode);
            }
        }
Ejemplo n.º 13
0
        private static Curves.QuaternionCurve CreateQuaternionCurve(BinaryReaderEx reader, short count)
        {
            var result = new Curves.QuaternionCurve();

            bool flag       = (count & 0x80) != 0;
            int  numLengths = count & 0xFF7F;

            var lengths = reader.ReadBytes(numLengths);

            // Lengths section is always a multiple of 4-bytes in length, so advance the stream past the unused bytes
            var unusedBytes = ((numLengths + 3) & 0x7FFFFFFC) - numLengths;

            reader.BaseStream.Position += unusedBytes;

            for (var i = 0; i < numLengths; i++)
            {
                byte len = lengths[i];
                for (var j = 0; j < len; j++)
                {
                    long data = 0;
                    data  = (long)reader.ReadUInt16(Endianness.BigEndian) << 32;
                    data |= (long)reader.ReadUInt16(Endianness.BigEndian) << 16;
                    data |= (long)reader.ReadUInt16(Endianness.BigEndian);

                    int index     = (int)(data >> 43) & 0x1F;     // 5-bit index of this quaternion
                    int signFlags = (int)(data >> 39) & 0x0F;     // 4-bit sign Flags
                    int val       = (int)(data >> 17) & 0x3FFFFF; // 22-bit integer
                    int wVal      = (int)(data & 0x1FFFF);        // 17-bit integer

                    int globalIdx = index + 32 * i;

                    float w = (float)wVal / 131071.0f;
                    if (flag)
                    {
                        w = 1 - w * w;
                    }

                    double halfPi = Math.PI * 0.5;

                    double dVal             = (double)val;
                    double sqrtVal          = Math.Sqrt(dVal);
                    double sqrtValWholePart = Math.Truncate(sqrtVal);

                    double v44 = halfPi * (1 - (sqrtValWholePart / 2047));
                    double tmp = (sqrtValWholePart < 0.001) ? 0 : halfPi * (dVal - sqrtValWholePart * sqrtValWholePart) / (2 * sqrtValWholePart);

                    double tmp6 = Math.Sqrt(1 - w * w);
                    double tX   = Math.Sin(-tmp);
                    double tY   = Math.Sin(halfPi - tmp);
                    double tZ   = Math.Sin(v44);
                    double tW   = Math.Sin(v44 - halfPi);

                    float rX = (float)(tY * -tW * tmp6);
                    float rY = (float)(tZ * tmp6);
                    float rZ = (float)(-tX * -tW * tmp6);

                    SlimDX.Quaternion qValue = new SlimDX.Quaternion();
                    if ((signFlags & 0x8) != 0)
                    {
                        signFlags ^= 0xF; // Switch all the bits
                        qValue.W   = -w;
                    }
                    else
                    {
                        qValue.W = w;
                    }

                    // Flag Set means Negate
                    qValue.X = ((signFlags & 0x4) != 0) ? -rX : rX;
                    qValue.Y = ((signFlags & 0x2) != 0) ? -rY : rY;
                    qValue.Z = ((signFlags & 0x1) != 0) ? -rZ : rZ;

                    qValue.Normalize();

                    var curveValue = new Curves.QuaternionCurveValue()
                    {
                        Time  = (float)globalIdx,
                        Value = qValue
                    };

                    result.Values.Add(curveValue);
                }
            }

            return(result);
        }
Ejemplo n.º 14
0
        public void Evaluate(int SpreadMax)
        {
            if (FDeltaIn.IsConnected)
            {
                FCamDelta.SliceCount = FDeltaIn.SliceCount + 1;
                for (int i = 0; i < FDeltaIn.SliceCount; i++)
                {
                    FCamDelta[i] = FDeltaIn[i];
                }
                FCamDelta[-1] = Delta;
            }
            else
            {
                FCamDelta[0] = Delta;
            }
            Delta.LockCursor = false;
            Delta.ResetSignals();
            if (Delta.InputMouse != null)
            {
                if (Init)
                {
                    Init             = false;
                    MouseObserver    = new AccumulatingMouseObserver();
                    KeyboardObserver = new AccumulatingKeyboardObserver();
                    MouseObserver.SubscribeTo(Delta.InputMouse.MouseNotifications);
                    KeyboardObserver.SubscribeTo(Delta.InputKeyboard.KeyNotifications);
                    PrevFrameTime = FHDEHost.FrameTime;
                }
                var dt         = FHDEHost.FrameTime - PrevFrameTime;
                var smoothness = FSmooth[0] > 0.00001 ? Math.Min(1.0f / (((float)FSmooth[0] / 6.0f) / (float)dt), 1.0f) : 1;

                //var carea = MouseObserver?.LastNotification?.ClientArea ?? new Size(1, 1);
                //var aspx = Math.Min(1, (double)carea.Height / (double)carea.Width);
                //var aspy = Math.Min(1, (double)carea.Width / (double)carea.Height);
                var mousepos = new Vector2D(
                    MouseObserver.AccumulatedXDelta /* aspx*/,
                    MouseObserver.AccumulatedYDelta /* aspy*/);
                var mousewheel = new Vector2D(
                    (double)MouseObserver.AccumulatedWheelDelta / 120,
                    (double)MouseObserver.AccumulatedHorizontalWheelDelta / 120);
                try
                {
                    if (Delta.InteractUpstream)
                    {
                        if (MouseObserver.MouseClicks[FRotationButton[0]].DoubleClick)
                        {
                            Delta.ResetRotation = true;
                        }
                        if (MouseObserver.MouseClicks[FTranslationXYButton[0]].DoubleClick)
                        {
                            Delta.ResetTranslation = true;
                        }
                        if (MouseObserver.MouseClicks[FPivotDistanceButton[0]].DoubleClick)
                        {
                            Delta.ResetPivotDistance = true;
                        }
                        if (MouseObserver.MouseClicks[FZoomButton[0]].DoubleClick)
                        {
                            Delta.ResetFov = true;
                        }
                    }
                }
                catch { }
                //FMousePos[0] = new Vector4D(mousepos, mousewheel);
                //FMouseButtons[0] = (uint) Delta.InputMouse.PressedButtons;

                var translxykey = FTranslationXYKey[0] == Keys.None;
                var translzkey  = FTranslationZKey[0] == Keys.None;

                var forw  = false;
                var left  = false;
                var backw = false;
                var right = false;
                var up    = false;
                var down  = false;

                var rotkey  = FRotationKey[0] == Keys.None;
                var rollkey = FRollKey[0] == Keys.None;

                var pdkey   = FPivotDistanceKey[0] == Keys.None;
                var zoomkey = FZoomKey[0] == Keys.None;

                var keyboard = from kp in KeyboardObserver.Keypresses.Values select kp.KeyCode;

                foreach (var key in keyboard)
                {
                    translxykey = translxykey || key == FTranslationXYKey[0];
                    translzkey  = translzkey || key == FTranslationZKey[0];

                    if (FWASDSpeed[0] > 0.0)
                    {
                        forw  = forw || key == FForwardKey[0];
                        left  = left || key == FStrafeLeftKey[0];
                        backw = backw || key == FBackwardKey[0];
                        right = right || key == FStrafeRightKey[0];
                        up    = up || key == FStrafeUpKey[0];
                        down  = down || key == FStrafeDownKey[0];
                    }

                    rotkey  = rotkey || key == FRotationKey[0];
                    rollkey = rollkey || key == FRollKey[0];

                    pdkey   = pdkey || key == FPivotDistanceKey[0];
                    zoomkey = zoomkey || key == FZoomKey[0];
                }

                if (Delta.InteractUpstream)
                {
                    //// Translation
                    var transl    = new Vector3D(0, 0, 0);
                    var crot      = new Vector3D(0, 0, 0);
                    var translinf = VMath.Lerp(1.0, Math.Max(Delta.ConnectedCamera.Properties.PivotDistance * 0.25, 0.1), FTranslDistInf[0]);
                    if (MouseObserver.MouseClicks[FTranslationXYButton[0]].Pressed && translxykey)
                    {
                        if (!translzkey || FTranslationZKey[0] == Keys.None)
                        {
                            transl.x        += mousepos.x;
                            transl.y        -= mousepos.y;
                            Delta.LockCursor = true;
                        }
                    }
                    if (MouseObserver.MouseClicks[FTranslationZButton[0]].Pressed && translzkey)
                    {
                        if (!translxykey || FTranslationXYKey[0] == Keys.None)
                        {
                            transl.z        += mousepos.y;
                            Delta.LockCursor = true;
                        }
                    }
                    transl *= FTranslSpeed[0] * translinf;

                    // WASD Transl
                    if (forw)
                    {
                        transl.z -= FWASDSpeed[0];
                    }
                    if (backw)
                    {
                        transl.z += FWASDSpeed[0];
                    }
                    if (left)
                    {
                        transl.x += FWASDSpeed[0];
                    }
                    if (right)
                    {
                        transl.x -= FWASDSpeed[0];
                    }
                    if (up)
                    {
                        transl.y -= FWASDSpeed[0];
                    }
                    if (down)
                    {
                        transl.y += FWASDSpeed[0];
                    }

                    Delta.Translation = Filters.Lowpass(Delta.Translation.AsSystemVector(), transl.AsSystemVector(), new Vector3(smoothness)).AsVVector();

                    //// Rotation
                    bool rotate   = false;
                    var  mouserot = new Vector2D(mousepos * FRotSpeed[0]);
                    if (FInvY[0])
                    {
                        mouserot.y *= -1;
                    }
                    if (Delta.ConnectedCamera.Properties.PivotDistance < 0.1)
                    {
                        mouserot *= -1;
                    }
                    if (MouseObserver.MouseClicks[FRotationButton[0]].Pressed && rotkey || forw || backw || left || right || up || down)
                    {
                        if (!rollkey || FRollKey[0] == Keys.None)
                        {
                            Delta.LockCursor = true;

                            // Prepare
                            mouserot.x = Math.Min(Math.Abs(mouserot.x) * 0.1, 0.499) * Math.Sign(mouserot.x);
                            mouserot.y = Math.Min(Math.Abs(mouserot.y) * 0.1, 0.499) * Math.Sign(mouserot.y);

                            // Trackball
                            var trackbpos = new Vector2D(
                                Math.Pow(Math.Abs(FTrackballScreenPos[0].x), 2) * Math.Sign(FTrackballScreenPos[0].x),
                                Math.Pow(Math.Abs(FTrackballScreenPos[0].y), 2) * Math.Sign(FTrackballScreenPos[0].y));
                            trackbpos *= -0.25;
                            var trackbtr = VMath.Rotate(trackbpos.y * Math.PI * 2, trackbpos.x * Math.PI * -2, 0);
                            var trackxv  = trackbtr * new Vector3D(-1, 0, 0);
                            var trackyv  = trackbtr * new Vector3D(0, -1, 0);
                            crot = VMath.QuaternionToEulerYawPitchRoll(
                                (Quaternion.RotationAxis(trackxv.ToSlimDXVector(), (float)(mouserot.y * Math.PI * -2)) *
                                 Quaternion.RotationAxis(trackyv.ToSlimDXVector(), (float)(mouserot.x * Math.PI * -2))
                                ).ToVector4D());
                            //crot = new Vector3D(mouserot.y, mouserot.x, 0);
                            crot *= 10;

                            rotate = true;
                        }
                    }
                    if (MouseObserver.MouseClicks[FRollButton[0]].Pressed && rollkey)
                    {
                        if (!rotkey || FRotationKey[0] == Keys.None)
                        {
                            Delta.LockCursor = true;
                            crot            += new Vector3D(0, 0, mouserot.x * Math.PI * 2);
                            rotate           = true;
                        }
                    }
                    if (rotate)
                    {
                        Delta.LockCursor = true;
                    }
                    Delta.PitchYawRoll = Filters.Lowpass(Delta.PitchYawRoll.AsSystemVector(), crot.AsSystemVector(), new Vector3(smoothness)).AsVVector();

                    double pivotd = 0;
                    double zoom   = mousewheel.y * FScrollMul[0] * FZoomSpeed[0];
                    if (zoomkey && (!pdkey || FPivotDistanceKey[0] == Keys.None))
                    {
                        zoom -= mousewheel.x * FScrollMul[0] * FZoomSpeed[0];
                        if (MouseObserver.MouseClicks[FZoomButton[0]].Pressed && zoomkey)
                        {
                            Delta.LockCursor = true;
                            zoom            -= mousepos.y * FZoomSpeed[0];
                        }
                    }
                    if (pdkey && (!zoomkey || FZoomKey[0] == Keys.None))
                    {
                        pivotd -= mousewheel.x * FScrollMul[0] * FTranslSpeed[0];
                        if (MouseObserver.MouseClicks[FPivotDistanceButton[0]].Pressed && pdkey)
                        {
                            Delta.LockCursor = true;
                            pivotd          -= mousepos.y * FTranslSpeed[0];
                        }
                    }
                    Delta.PivotDistance = Filters.Lowpass((float)Delta.PivotDistance, (float)pivotd, smoothness);
                    Delta.Fov           = Filters.Lowpass((float)Delta.Fov, (float)zoom, smoothness);
                }
                MouseObserver.ResetAccumulation();
                KeyboardObserver.ResetAccumulation();
            }
            else
            {
                MouseObserver?.Unsubscribe();
                KeyboardObserver?.Unsubscribe();
                Init = true;
            }
            PrevFrameTime = FHDEHost.FrameTime;
        }