Esempio n. 1
0
        private IEnumerator AnimateCamera(Vector3 position, Quaternion rotation, Vector3 pivot)
        {
            var angle             = rotation.AngleTo(_rotation);
            var totalTimeAngle    = (0.1f * angle) / 90;
            var totalTimeDistance = (pivot - _pivot).Length() * 0.003;

            var totalTime = (float)Math.Max(totalTimeAngle, totalTimeDistance);

            Debug.WriteLine($"time angle: {totalTimeAngle} time dist {totalTimeDistance}");
            var time               = 0.0f;
            var originalPivot      = _pivot;
            var originalRotation   = _rotation;
            var targetRotation     = rotation;
            var distanceFromOrigin = (_position - _pivot).Length();

            while (time < totalTime)
            {
                var lerpFactor = time / totalTime;

                var newPivot    = Vector3.Lerp(originalPivot, pivot, lerpFactor);
                var newRotation = Quaternion.Slerp(originalRotation, targetRotation, lerpFactor);

                var newUnitPosition = Vector3.Transform(-Vector3.UnitZ, newRotation);
                var newPosition     = newPivot + newUnitPosition * distanceFromOrigin;

                MoveCamera(newPosition, newRotation, newPivot);

                time += (float)_coroutines.DeltaTime;

                yield return(null);
            }
            MoveCamera(position, rotation, pivot);
        }
Esempio n. 2
0
        void SetOrientation(SN.Quaternion o, TimeSpan duration, Action completed = null)
        {
            o = Clamp(o);

            var targetOrientation = CameraLocal
                ? SN.Quaternion.Inverse(o)
                : o;

            if (duration.Ticks > 0)
            {
                Animate(
                    rotation,
                    QuaternionRotation3D.QuaternionProperty,
                    new QuaternionAnimation {
                    To             = Convert(targetOrientation),
                    Duration       = duration,
                    EasingFunction = new CubicEase(),
                },
                    completed
                    );
                base.SetOrientation(o);
            }
            else
            {
                base.SetOrientation(o);
                rotation.Quaternion = Convert(targetOrientation);
                completed?.Invoke();
            }
        }
Esempio n. 3
0
        public void Render(Renderer renderer)
        {
            SFMLRenderer sfmlRenderer = renderer as SFMLRenderer;

            System.Numerics.Vector3    Location = GetLocation_WorldSpace();
            System.Numerics.Quaternion Rotation = GetRotation_WorldSpace(); //TODO: Get the rotation out of this quat
            System.Numerics.Vector3    Scale    = GetScale_WorldSpace();


            Transform tf = Transform.Identity;

            tf.Translate(Location.X, Location.Y);
            tf.Scale(Scale.X, Scale.Y);

            RenderStates RS = RenderStates.Default;

            RS.Transform = tf;

            SFMLEngine engine = Engine.Instance as SFMLEngine;

            if (Texture.Loaded)
            {
                //Texture.Get<Sprite>().Position = new Vector2f(Location.X, Location.Y);
                engine?.Window.Draw(Texture.Get <Sprite>(), RS);
            }
        }
Esempio n. 4
0
        public void Draw(Vector3 Position, Vector3 Scale, Quaternion Rotation)
        {
            if (ColorBuffer == null)
            {
                VertexArray.VertexAttrib(COLOR_ATTRIB, Material.DiffuseColor);
            }

            Material.Bind();
            Material.Shader.SetModelMatrix(Camera.CreateModel(Position, Scale, Rotation) * Matrix);

            if (Wireframe)
            {
                Gl.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
            }

            if (!VAO.HasElementBuffer)
            {
                VAO.Draw(0, VertBuffer.ElementCount);
            }
            else
            {
                VAO.DrawElements(ElementType: DrawElementsType.UnsignedInt);
            }

            if (Wireframe)
            {
                Gl.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
            }

            Material.Unbind();
        }
Esempio n. 5
0
 /// <summary>
 /// Convert a system.numerics quaternion to waveengine quaternion
 /// </summary>
 /// <param name="numerics">Numeric quaternion</param>
 /// <param name="result">Wave quaternion</param>
 public static void ToWave(this System.Numerics.Quaternion numerics, out Common.Math.Quaternion result)
 {
     result.X = numerics.X;
     result.Y = numerics.Y;
     result.Z = numerics.Z;
     result.W = numerics.W;
 }
Esempio n. 6
0
 public static void Deconstruct(this System.Numerics.Quaternion Q, out float x, out float y, out float z, out float w)
 {
     x = Q.X;
     y = Q.Y;
     z = Q.Z;
     w = Q.W;
 }
        public void Draw(RenderTarget target, RenderStates states)
        {
            if (VertexArray == null || VertexArray.Length == 0 || VertexArray.Length % 4 != 0)
            {
                return;
            }

            System.Numerics.Vector3    Location = GetLocation_WorldSpace();
            System.Numerics.Quaternion Rotation = GetRotation_WorldSpace(); //TODO: Get the rotation out of this quat
            System.Numerics.Vector3    Scale    = GetScale_WorldSpace();

            Transform tf = Transform.Identity;

            tf.Translate(Location.X, Location.Y);
            //tf.Scale(Scale.X, Scale.Y);

            states.Transform *= tf;

            if (Texture.Loaded)
            {
                states.Texture = Texture.Get <Texture>();
            }

            target.Draw(VertexArray, PrimitiveType, states);
        }
Esempio n. 8
0
        public static Quaternion ToLookRotation(this Vector3 forward, Vector3 up)
        {
            forward = Vector3.Normalize(forward);

            Vector3 vector  = Vector3.Normalize(forward);
            Vector3 vector2 = Vector3.Normalize(Vector3.Cross(up, vector));
            Vector3 vector3 = Vector3.Cross(vector, vector2);
            var     m00     = vector2.X;
            var     m01     = vector2.Y;
            var     m02     = vector2.Z;
            var     m10     = vector3.X;
            var     m11     = vector3.Y;
            var     m12     = vector3.Z;
            var     m20     = vector.X;
            var     m21     = vector.Y;
            var     m22     = vector.Z;


            float num8       = (m00 + m11) + m22;
            var   quaternion = new Quaternion();

            if (num8 > 0f)
            {
                var num = (float)Math.Sqrt(num8 + 1f);
                quaternion.W = num * 0.5f;
                num          = 0.5f / num;
                quaternion.X = (m12 - m21) * num;
                quaternion.Y = (m20 - m02) * num;
                quaternion.Z = (m01 - m10) * num;
                return(quaternion);
            }
            if ((m00 >= m11) && (m00 >= m22))
            {
                var num7 = (float)Math.Sqrt(((1f + m00) - m11) - m22);
                var num4 = 0.5f / num7;
                quaternion.X = 0.5f * num7;
                quaternion.Y = (m01 + m10) * num4;
                quaternion.Z = (m02 + m20) * num4;
                quaternion.W = (m12 - m21) * num4;
                return(quaternion);
            }
            if (m11 > m22)
            {
                var num6 = (float)Math.Sqrt(((1f + m11) - m00) - m22);
                var num3 = 0.5f / num6;
                quaternion.X = (m10 + m01) * num3;
                quaternion.Y = 0.5f * num6;
                quaternion.Z = (m21 + m12) * num3;
                quaternion.W = (m20 - m02) * num3;
                return(quaternion);
            }
            var num5 = (float)Math.Sqrt(((1f + m22) - m00) - m11);
            var num2 = 0.5f / num5;

            quaternion.X = (m20 + m02) * num2;
            quaternion.Y = (m21 + m12) * num2;
            quaternion.Z = 0.5f * num5;
            quaternion.W = (m01 - m10) * num2;
            return(quaternion);
        }
Esempio n. 9
0
        private void InterpolateKeys(double animationTime, AnimationLayer layer, ref Quaternion rotation, ref Vector3 translation, ref Vector3 scale, PRSKey prsKey, PRSKey nextPrsKey)
        {
            var nextTime = (nextPrsKey.Time < prsKey.Time
                ? (nextPrsKey.Time + Animation.Duration)
                : nextPrsKey.Time);

            var blend = ( float )(animationTime / nextTime);

            if (prsKey.HasRotation)
            {
                rotation = Quaternion.Slerp(prsKey.Rotation, nextPrsKey.Rotation, blend);
            }

            if (prsKey.HasPosition)
            {
                translation = Vector3.Lerp(prsKey.Position * layer.PositionScale,
                                           nextPrsKey.Position * layer.PositionScale,
                                           blend);
            }

            if (prsKey.HasScale)
            {
                scale = Vector3.Lerp(prsKey.Scale * layer.ScaleScale,
                                     nextPrsKey.Scale * layer.ScaleScale,
                                     blend);
            }
        }
Esempio n. 10
0
        public Model()
        {
            MeshList = new List <Mesh>();

            Position = Vector3.Zero;
            Scale    = Vector3.One;
            Rotation = Quaternion.Identity;
        }
Esempio n. 11
0
        private int Instantiate(BodyDescription bodyReference, ref Vector3 position, ref Quaternion orientation)
        {
            bodyReference.Pose.Position    = position;
            bodyReference.Pose.Orientation = orientation;
            var index = Simulation.Bodies.Add(bodyReference);

            _createdObjects.Add(index, BufferPool);
            return(index);
        }
Esempio n. 12
0
    void FixedUpdate()
    {
        var position =
            new System.Numerics.Vector3(_myTransform.position.x, _myTransform.position.y, _myTransform.position.z);
        var rotation = new System.Numerics.Quaternion(_myTransform.rotation.x, _myTransform.rotation.y,
                                                      _myTransform.rotation.z, _myTransform.rotation.w);

        ConnectionInstance.Instance.Client.SendCoordinates(position, rotation);
    }
Esempio n. 13
0
 System.Numerics.Quaternion CalculateQuaternion(DataPoints datapoints, DataPoints targetpoints)
 {
     System.Numerics.Quaternion q  = new System.Numerics.Quaternion();
     System.Numerics.Vector3    cp = System.Numerics.Vector3.Cross(datapoints.points[0].point, targetpoints.points[0].point);
     q.X = cp.X;
     q.Y = cp.Y;
     q.Z = cp.Z;
     q.W = Mathf.Sqrt(Mathf.Pow(datapoints.points[0].point.Length(), 2) * Mathf.Pow(targetpoints.points[0].point.Length(), 2)) + System.Numerics.Vector3.Dot(datapoints.points[0].point, targetpoints.points[0].point);
     return(q);
 }
Esempio n. 14
0
        public static void DrawImGuiQuaternion(string name, object reference)
        {
            System.Numerics.Quaternion quatValue = (reference as ReflectionRef <System.Numerics.Quaternion>).Value;
            var value = new Vector4(quatValue.X, quatValue.Y, quatValue.Z, quatValue.W);

            ImGui.Text(name);
            ImGui.NextColumn();
            ImGui.DragFloat4($"{name}##hidelabel", ref value, 0.1f);
            ImGui.NextColumn();
            (reference as ReflectionRef <System.Numerics.Quaternion>).Value = new System.Numerics.Quaternion(value.X, value.Y, value.Z, value.W);
        }
Esempio n. 15
0
        /// <summary>
        /// Converts a <see cref="CoordinateSystem"/> in \psi basis to a <see cref="SpatialCoordinateSystem"/> in HoloLens basis.
        /// </summary>
        /// <param name="coordinateSystem">The <see cref="CoordinateSystem"/> in \psi basis.</param>
        /// <returns>The <see cref="SpatialCoordinateSystem"/>.</returns>
        public static SpatialCoordinateSystem TryConvertPsiCoordinateSystemToSpatialCoordinateSystem(this CoordinateSystem coordinateSystem)
        {
            var holoLensMatrix = coordinateSystem.RebaseToHoloLensSystemMatrix();
            var translation    = holoLensMatrix.Translation;

            holoLensMatrix.Translation = Vector3.Zero;
            var rotation      = Quaternion.CreateFromRotationMatrix(holoLensMatrix);
            var spatialAnchor = SpatialAnchor.TryCreateRelativeTo(MixedReality.WorldSpatialCoordinateSystem, translation, rotation);

            return(spatialAnchor?.CoordinateSystem);
        }
Esempio n. 16
0
        public static float AngleTo(this Quaternion q1, Quaternion q2)
        {
            bool IsEqualish(float dot)
            {
                return((double)dot > 0.999998986721039);
            }

            var dot = Quaternion.Dot(q1, q2);

            return(IsEqualish(dot) ? 0.0f : (float)((double)Math.Acos(Math.Min(Math.Abs((float)dot), 1f)) * 2.0 * 57.2957801818848));
        }
Esempio n. 17
0
        public Camera(IRendererCamera rendererCamera, Vector3 initialPivot, Coroutines coroutines, ILight?cameraLight = null)
        {
            _rendererCamera = rendererCamera;
            _cameraLight    = cameraLight;
            _coroutines     = coroutines;
            _originalPivot  = _pivot = initialPivot;
            _position       = _originalPosition = _rendererCamera.Position;
            _rotation       = (_pivot - _position).ToLookRotation(Vector3.UnitY);
            MoveCamera(_position, _rotation, _pivot);

            _originalRotation = _rotation;
        }
Esempio n. 18
0
        public void GetQuaternionFromPose()
        {
            var w = Math.Sqrt(Math.Max(0, 1 + Pose.m0 + Pose.m5 + Pose.m10)) / 2;
            var x = Math.Sqrt(Math.Max(0, 1 + Pose.m0 - Pose.m5 - Pose.m10)) / 2;
            var y = Math.Sqrt(Math.Max(0, 1 - Pose.m0 + Pose.m5 - Pose.m10)) / 2;
            var z = Math.Sqrt(Math.Max(0, 1 - Pose.m0 - Pose.m5 + Pose.m10)) / 2;

            x = Math.Abs(x) * Math.Sign(Pose.m9 - Pose.m6);
            y = Math.Abs(y) * Math.Sign(Pose.m2 - Pose.m8);
            z = Math.Abs(z) * Math.Sign(Pose.m4 - Pose.m1);
            this.Quaternion = new Quaternion((float)x, (float)y, (float)z, (float)w);
        }
Esempio n. 19
0
        public static Quaternion LookIn(Vector3 dir, Vector3 up)
        {
            dir = Vector3.Normalize(dir);
            var right = Vector3.Normalize(Vector3.Cross(up, dir));

            up = Vector3.Cross(dir, right);
            var matrix = new Matrix4x4(
                right.X, right.Y, right.Z, 0f,
                up.X, up.Y, up.Z, 0f,
                dir.X, dir.Y, dir.Z, 0f,
                0f, 0f, 0f, 1f);

            return(Quaternion.CreateFromRotationMatrix(matrix));
        }
    private void InterpolationFunction(GameObject rotObj, System.Numerics.Quaternion[] rotations)
    {
        //turn the quaternion into a rotation matrix.
        System.Numerics.Matrix4x4 rotationMatrixFirstPose  = System.Numerics.Matrix4x4.CreateFromQuaternion(rotations[0]);
        System.Numerics.Matrix4x4 rotationMatrixSecondPose = System.Numerics.Matrix4x4.CreateFromQuaternion(rotations[1]);


        //System.Numerics.Matrix4x4 rotationMatrixThirdPose = System.Numerics.Matrix4x4.CreateFromQuaternion(rotations[2]);


        //find the interpolated entry for each entry of the matrix.
        System.Numerics.Matrix4x4 interpolatedMat = new System.Numerics.Matrix4x4();
        Vector3 position = gameObject.transform.position;


        interpolatedMat.M11 = interpolate(rotationMatrixFirstPose.M11, rotationMatrixSecondPose.M11, 0f, position);
        interpolatedMat.M12 = interpolate(rotationMatrixFirstPose.M12, rotationMatrixSecondPose.M12, 0f, position);
        interpolatedMat.M13 = interpolate(rotationMatrixFirstPose.M13, rotationMatrixSecondPose.M13, 0f, position);
        interpolatedMat.M21 = interpolate(rotationMatrixFirstPose.M21, rotationMatrixSecondPose.M21, 0f, position);
        interpolatedMat.M22 = interpolate(rotationMatrixFirstPose.M22, rotationMatrixSecondPose.M22, 0f, position);
        interpolatedMat.M23 = interpolate(rotationMatrixFirstPose.M23, rotationMatrixSecondPose.M23, 0f, position);
        interpolatedMat.M31 = interpolate(rotationMatrixFirstPose.M31, rotationMatrixSecondPose.M31, 0f, position);
        interpolatedMat.M32 = interpolate(rotationMatrixFirstPose.M32, rotationMatrixSecondPose.M32, 0f, position);
        interpolatedMat.M33 = interpolate(rotationMatrixFirstPose.M33, rotationMatrixSecondPose.M33, 0f, position);


        Debug.Log(interpolatedMat.ToString());

        Debug.Log("Cursor" + " " + position);

        //orthonormalize the interpolated Matrix

        System.Numerics.Matrix4x4 orthogonalMatrix = matrixOrthogonal(interpolatedMat);

        //Convert the matrix to quaternion.

        System.Numerics.Quaternion newPose = System.Numerics.Quaternion.CreateFromRotationMatrix(orthogonalMatrix);

        //apply the transformation to the joints

        UnityEngine.Quaternion newPoseQuaternion = new UnityEngine.Quaternion();
        newPoseQuaternion.x = newPose.X;
        newPoseQuaternion.y = newPose.Y;
        newPoseQuaternion.z = newPose.Z;
        newPoseQuaternion.w = newPose.W;


        rotObj.transform.rotation = Quaternion.Lerp(rotObj.transform.rotation, newPoseQuaternion, Time.deltaTime);
    }
Esempio n. 21
0
        public override void Initialize(ContentArchive content, Camera camera)
        {
            _orientations[0] = Quaternion.Identity;
            _orientations[1] = Quaternion.CreateFromYawPitchRoll(-(float)Math.PI * 0.5f, 0, 0);
            _orientations[2] = Quaternion.CreateFromYawPitchRoll(-(float)Math.PI * 1.0f, 0, 0);
            _orientations[3] = Quaternion.CreateFromYawPitchRoll(-(float)Math.PI * 1.5f, 0, 0);

            camera.Position = new Vector3(-30, 8, -60);
            camera.Yaw      = MathHelper.Pi * 3f / 4;
            camera.Pitch    = 0;

            Simulation = Simulation.Create(BufferPool, new DemoNarrowPhaseCallbacks(), new DemoPoseIntegratorCallbacks(new Vector3(0f, -9.81f, 0f))
                                           , new CustomPositionLastTimestepper()
                                           );

            _createdObjects = new QuickList <int>(_numberOfLevels * _numberOfLevels * 10, BufferPool);
            _movingObjects  = new QuickList <Movable>(_numberOfLevels * _numberOfLevels, BufferPool);

            _boxDescription = CreateBoxDescription(1, 1, 1);
            _horizontalConveyorDescription = CreateConveyorDescription(_horizontalHalfLenght);
            _verticalConveyorDescription   = CreateConveyorDescription(_verticalHalfLenght);
            _movingObject = CreateBoxDescription(4, 3, 2);
            _movingObject.LocalInertia = new BodyInertia();


            var angle      = _rampDegrees * (float)(Math.PI / 180f);
            var rampLenght = _floorHeight / (float)Math.Sin(angle);

            _rampConveyorDescription = CreateConveyorDescription(rampLenght);
            _rampConveyorDescription.Pose.Orientation = Quaternion.CreateFromYawPitchRoll((float)Math.PI * 0.5f, 0, angle);
            _rampConveyorDescription.ConveyorSettings.ConveyorVelocity *= 2f;


            for (int i = 0; i < _numberOfLevels; i++)
            {
                var position = new Vector3(0, _floorHeight * i, 0 /* _verticalHalfLenght * i*/);

                for (int j = 0; j < _numberOfLoops; j++)
                {
                    CreateLoop(ref position);
                }

                // if (i < _numberOfLevels - 1)
                {
                    CreateRamp(ref position);
                }
            }
        }
Esempio n. 22
0
 private void MoveCamera(Vector3 position, Quaternion rotation, Vector3 pivot, bool animate = false)
 {
     if (!animate)
     {
         _position = position;
         _rotation = rotation;
         _pivot    = pivot;
         _rendererCamera.Move(position, _rotation.Forward(), _rotation.Up());
         if (_cameraLight != null)
         {
             _cameraLight.Position = position;
         }
     }
     else
     {
         _coroutines.StartCoroutine(AnimateCamera(position, rotation, pivot));
     }
 }
Esempio n. 23
0
        public override void Reset(
            SN.Quaternion orientation,
            SN.Vector3 position,
            SN.Vector3 scale,
            Action completed = null,
            double duration  = 1.0)
        {
            if (duration <= 0)
            {
                base.Reset(orientation, position, scale, completed, duration);
                return;
            }

            var span = TimeSpan.FromSeconds(duration);

            SetOrientation(orientation, span, completed);
            SetPosition(position, span);
            SetScale(scale, span);
        }
    public static void PlayerMovement(bool[] _inputs)
    {
        using (Packet _packet = new Packet((int)ClientPackets.playerMovement))
        {
            _packet.Write(_inputs.Length);

            foreach (bool _input in _inputs)
            {
                _packet.Write(_input);
            }

            UnityEngine.Quaternion UEQuat = NGameManager.players[Client.Instance.myId].transform.rotation;

            System.Numerics.Quaternion NumQuat = new System.Numerics.Quaternion(UEQuat.x, UEQuat.y, UEQuat.z, UEQuat.w);
            _packet.Write(NumQuat);

            SendUDPData(_packet);
        }
    }
Esempio n. 25
0
        // from https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles
        public static Vector3 ToEuler(this Quaternion q)
        {
            var    euler     = Vector3.Zero;
            double sinr_cosp = 2 * (q.W * q.X + q.Y * q.Z);
            double cosr_cosp = 1 - 2 * (q.X * q.X + q.Y * q.Y);

            euler.Z = (float)Math.Atan2(sinr_cosp, cosr_cosp);

            double sinp = 2 * (q.W * q.Y - q.Z * q.X);

            euler.X = Math.Abs(sinp) >= 1
                ? (float)Math.CopySign(Math.PI / 2, sinp) // use 90 degrees if out of range
                : (float)Math.Asin(sinp);

            double siny_cosp = 2 * (q.W * q.Z + q.X * q.Y);
            double cosy_cosp = 1 - 2 * (q.Y * q.Y + q.Z * q.Z);

            euler.Y = (float)Math.Atan2(siny_cosp, cosy_cosp);

            return(euler);
        }
Esempio n. 26
0
        /// <summary>Adds a Quaternion 3B to the packet.</summary>
        /// <param name="value">The Quaternion to add.</param>
        ///
        /// Smallest 3, find the largest absolute of the floats, don't send it, send the smallest 3,
        /// and give the index for the largest using 2 bits  [00, 01, 10, 11] 00 = x, 01 = y, 10 = z, 11 = w
        /// Use formula x^2 + y^2 + z^2 + w^2 = 1
        ///
        /// Also can use less precise floating point value, instead of 4 bytes per component, use 1 byte
        ///
        /// This should decrease the packet size from 16 bytes = 128 bits
        /// To 2 bit (largest component index) + 3 * 7 bits (smallest 3 components) + 1 bit for negating all components = 24 bits - will send 3 bytes = 24 bits
        /// only 18.75% of the original packet
        public void Write(System.Numerics.Quaternion value)
        {
            float[] componentsAbs = new float[] { Math.Abs(value.X), Math.Abs(value.Y), Math.Abs(value.Z), Math.Abs(value.W) };
            float[] components    = new float[] { value.X, value.Y, value.Z, value.W };

            int  largestAbsIndex     = GetLargestComponentIndex(componentsAbs);
            bool largestCompNegative = components[largestAbsIndex] < 0;

            bool[] largestAbsIndexBin = ConvertIntMax4ToBin2(largestAbsIndex);

            byte[] bytesToSend = new byte[3];
            byte   byteCounter = 0;

            for (int count = 0; count < 4; count++)
            {
                if (count == largestAbsIndex)
                {
                    continue;
                }
                // Writes the 7 bit representation of the float instead of the 32 bit
                bytesToSend[byteCounter++] = Get7BitFractionalFrom32BitFloat(componentsAbs[count], components[count] < 0);
            }

            //Writes the bit indexes of which component not to read fragmented amongst the bits
            if (largestAbsIndexBin[0])
            {
                bytesToSend[0] += 128;
            }
            if (largestAbsIndexBin[1])
            {
                bytesToSend[1] += 128;
            }

            if (largestCompNegative) //Should negate the smallest 3 (*-1) components
            {
                bytesToSend[2] += 128;
            }

            Write(bytesToSend);
        }
Esempio n. 27
0
        private static bool _TryCastValue(JsonReader reader, Type vtype, out Object value)
        {
            value = null;

            if (reader.TokenType == JsonToken.EndArray)
            {
                return(false);
            }
            if (reader.TokenType == JsonToken.EndObject)
            {
                return(false);
            }
            if (reader.TokenType == JsonToken.EndConstructor)
            {
                return(false);
            }

            if (reader.TokenType == JsonToken.PropertyName)
            {
                reader.Read();
            }

            // untangle nullable
            var ntype = Nullable.GetUnderlyingType(vtype);

            if (ntype != null)
            {
                vtype = ntype;
            }

            if (vtype == typeof(String) ||
                vtype == typeof(Boolean) ||
                vtype == typeof(Int16) ||
                vtype == typeof(Int32) ||
                vtype == typeof(Int64) ||
                vtype == typeof(UInt16) ||
                vtype == typeof(UInt32) ||
                vtype == typeof(UInt64) ||
                vtype == typeof(Single) ||
                vtype == typeof(Double))
            {
                value = Convert.ChangeType(reader.Value, vtype, System.Globalization.CultureInfo.InvariantCulture);
                return(true);
            }

            if (vtype.IsEnum)
            {
                if (reader.Value is String xstrVal)
                {
                    value = Enum.Parse(vtype, xstrVal, true); return(true);
                }
                if (reader.Value is Int32 int32Val)
                {
                    value = Enum.ToObject(vtype, int32Val); return(true);
                }
                if (reader.Value is Int64 int64Val)
                {
                    value = Enum.ToObject(vtype, int64Val); return(true);
                }

                throw new NotImplementedException();
            }

            if (vtype == typeof(Vector2))
            {
                var l = new List <float>();
                DeserializePropertyList <float>(reader, l);
                value = new Vector2(l[0], l[1]);
                return(true);
            }

            if (vtype == typeof(Vector3))
            {
                var l = new List <float>();
                DeserializePropertyList <float>(reader, l);
                value = new Vector3(l[0], l[1], l[2]);
                return(true);
            }

            if (vtype == typeof(Vector4))
            {
                var l = new List <float>();
                DeserializePropertyList <float>(reader, l);
                value = new Vector4(l[0], l[1], l[2], l[3]);
                return(true);
            }

            if (vtype == typeof(Quaternion))
            {
                var l = new List <float>();
                DeserializePropertyList <float>(reader, l);
                value = new System.Numerics.Quaternion(l[0], l[1], l[2], l[3]);
                return(true);
            }

            if (vtype == typeof(Matrix4x4))
            {
                var l = new List <float>();
                DeserializePropertyList <float>(reader, l);
                value = new Matrix4x4
                        (
                    l[0], l[1], l[2], l[3],
                    l[4], l[5], l[6], l[7],
                    l[8], l[9], l[10], l[11],
                    l[12], l[13], l[14], l[15]
                        );
                return(true);
            }

            if (typeof(JsonSerializable).IsAssignableFrom(vtype))
            {
                var item = Activator.CreateInstance(vtype, true) as JsonSerializable;

                System.Diagnostics.Debug.Assert(reader.TokenType == JsonToken.StartObject);
                item.Deserialize(reader);
                System.Diagnostics.Debug.Assert(reader.TokenType == JsonToken.EndObject);

                value = item;

                return(true);
            }

            if (vtype.IsGenericType)
            {
                if (vtype.GetGenericTypeDefinition() == typeof(Dictionary <,>))
                {
                    var valType = vtype.GetGenericArguments()[1];

                    if (valType == typeof(Int32))
                    {
                        var dict = new Dictionary <string, Int32>();
                        DeserializePropertyDictionary(reader, dict);
                        value = dict;
                        return(true);
                    }
                }

                throw new NotImplementedException($"Can't deserialize {vtype}");
            }

            throw new NotImplementedException($"Can't deserialize {vtype}");
        }
        protected override void Initialize()
        {
            AddExportHandler <ObjectSet>(filePath =>
            {
                if (filePath.EndsWith(".fbx", StringComparison.OrdinalIgnoreCase))
                {
                    Data.TryFixParentBoneInfos(SourceConfiguration?.BoneDatabase);
                    FbxExporter.ExportToFile(Data, filePath);
                }

                else
                {
                    var configuration = ConfigurationList.Instance.CurrentConfiguration;

                    var objectDatabase  = configuration?.ObjectDatabase;
                    var textureDatabase = configuration?.TextureDatabase;
                    var boneDatabase    = configuration?.BoneDatabase;

                    Data.Save(filePath, objectDatabase, textureDatabase, boneDatabase);
                }
            });
            AddExportHandler <Scene>(filePath =>
            {
                Data.TryFixParentBoneInfos(SourceConfiguration?.BoneDatabase);
                AssimpExporter.ExportToFile(Data, filePath);
            });
            AddReplaceHandler <ObjectSet>(filePath =>
            {
                var configuration = ConfigurationList.Instance.CurrentConfiguration;

                var objectDatabase  = configuration?.ObjectDatabase;
                var textureDatabase = configuration?.TextureDatabase;

                var objectSet = new ObjectSet();
                objectSet.Load(filePath, objectDatabase, textureDatabase);
                return(objectSet);
            });
            AddReplaceHandler <Scene>(filePath =>
            {
                if (Data.Objects.Count > 1)
                {
                    return(AssimpImporter.ImportFromFile(filePath));
                }

                return(AssimpImporter.ImportFromFileWithSingleObject(filePath));
            });

            AddCustomHandler("Copy object set info to clipboard", () =>
            {
                uint objectSetId = 39;
                uint objectId    = 0xFFFFFFFF;

                var objectDatabase = ConfigurationList.Instance.CurrentConfiguration?.ObjectDatabase;

                if (objectDatabase != null && objectDatabase.ObjectSets.Count > 0)
                {
                    objectSetId = objectDatabase.ObjectSets.Max(x => x.Id) + 1;
                    objectId    = objectDatabase.ObjectSets.SelectMany(x => x.Objects).Max(x => x.Id) + 1;
                }

                else
                {
                    using (var inputDialog = new InputDialog
                    {
                        WindowTitle = "Enter base id for objects",
                        Input = Math.Max(0, Data.Objects.Max(x => x.Id) + 1).ToString()
                    })
                    {
                        while (inputDialog.ShowDialog() == DialogResult.OK)
                        {
                            bool result = uint.TryParse(inputDialog.Input, out objectId);

                            if (!result || objectId == 0xFFFFFFFF)
                            {
                                MessageBox.Show("Please enter a correct id number.", Program.Name, MessageBoxButtons.OK, MessageBoxIcon.Error);
                            }

                            else
                            {
                                break;
                            }
                        }
                    }
                }

                if (objectId == 0xFFFFFFFF)
                {
                    return;
                }

                string baseName = Path.ChangeExtension(Name, null);
                if (Data.Format.IsClassic() && baseName.EndsWith("_obj", StringComparison.OrdinalIgnoreCase))
                {
                    baseName = baseName.Substring(0, baseName.Length - 4);
                }

                var objectSetInfo = new ObjectSetInfo
                {
                    Name            = baseName.ToUpperInvariant(),
                    Id              = objectSetId,
                    FileName        = Name,
                    TextureFileName = baseName + (Data.Format.IsClassic() ? "_tex.bin" : ".txd"),
                    ArchiveFileName = Parent is FarcArchiveNode ? Parent.Name : baseName + ".farc"
                };

                foreach (var obj in Data.Objects)
                {
                    objectSetInfo.Objects.Add(new ObjectInfo
                    {
                        Id   = objectId++,
                        Name = obj.Name.ToUpperInvariant()
                    });
                }

                using (var stringWriter = new StringWriter())
                    using (var xmlWriter = XmlWriter.Create(stringWriter,
                                                            new XmlWriterSettings {
                        Indent = true, OmitXmlDeclaration = true
                    }))
                    {
                        sObjectSetInfoSerializer.Serialize(xmlWriter, objectSetInfo,
                                                           new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty }));

                        Clipboard.SetText(stringWriter.ToString());
                    }
            });

            AddCustomHandlerSeparator();

            AddDirtyCustomHandler("Combine all objects into one", () =>
            {
                if (Data.Objects.Count <= 1)
                {
                    return(false);
                }

                var combinedObject = new Object {
                    Name = "Combined object"
                };
                var indexMap = new Dictionary <int, int>();

                foreach (var obj in Data.Objects)
                {
                    if (obj.Skin != null)
                    {
                        if (combinedObject.Skin == null)
                        {
                            combinedObject.Skin = new Skin();
                            combinedObject.Skin.Bones.AddRange(obj.Skin.Bones);
                        }

                        else
                        {
                            for (int i = 0; i < obj.Skin.Bones.Count; i++)
                            {
                                var bone      = obj.Skin.Bones[i];
                                int boneIndex = combinedObject.Skin.Bones.FindIndex(
                                    x => x.Name.Equals(bone.Name, StringComparison.OrdinalIgnoreCase));

                                if (boneIndex == -1)
                                {
                                    indexMap[i] = combinedObject.Skin.Bones.Count;
                                    combinedObject.Skin.Bones.Add(bone);
                                }

                                else
                                {
                                    indexMap[i] = boneIndex;
                                }
                            }

                            foreach (var subMesh in obj.Meshes.SelectMany(x => x.SubMeshes))
                            {
                                if (subMesh.BoneIndices?.Length >= 1)
                                {
                                    for (int i = 0; i < subMesh.BoneIndices.Length; i++)
                                    {
                                        subMesh.BoneIndices[i] = ( ushort )indexMap[subMesh.BoneIndices[i]];
                                    }
                                }
                            }
                        }

                        combinedObject.Skin.Blocks.AddRange(obj.Skin.Blocks);
                    }

                    foreach (var subMesh in obj.Meshes.SelectMany(x => x.SubMeshes))
                    {
                        subMesh.MaterialIndex += ( uint )combinedObject.Materials.Count;
                    }

                    combinedObject.Meshes.AddRange(obj.Meshes);
                    combinedObject.Materials.AddRange(obj.Materials);
                }

                Data.Objects.Clear();
                Data.Objects.Add(combinedObject);

                return(true);
            }, Keys.None, CustomHandlerFlags.Repopulate | CustomHandlerFlags.ClearMementos);

            AddCustomHandlerSeparator();

            AddDirtyCustomHandler("Convert all bones to osage", () =>
            {
                foreach (var obj in Data.Objects)
                {
                    var movingBone = obj.Skin?.Bones.FirstOrDefault(x => x.Name == "kl_mune_b_wj");
                    if (movingBone == null)
                    {
                        continue;
                    }

                    var nameMap       = new Dictionary <string, string>();
                    var stringBuilder = new StringBuilder();

                    foreach (var bone in obj.Skin.Bones)
                    {
                        // Ignore bones if they are already OSG or EXP.
                        // Also ignore the moving bone and its parents.

                        // Ignore j_kao_wj for now because it f***s miku's headphones up
                        if (bone.Name == "j_kao_wj")
                        {
                            continue;
                        }

                        var boneToCompare = movingBone;

                        do
                        {
                            if (boneToCompare == bone)
                            {
                                break;
                            }

                            boneToCompare = boneToCompare.Parent;
                        } while (boneToCompare != null);

                        if (boneToCompare == bone)
                        {
                            continue;
                        }

                        if (obj.Skin.Blocks.Any(x =>
                        {
                            switch (x)
                            {
                            case OsageBlock osgBlock:
                                return(osgBlock.Nodes.Any(y => y.Name == bone.Name));

                            case ExpressionBlock expBlock:
                                return(expBlock.Name == bone.Name);

                            default:
                                return(false);
                            }
                        }))
                        {
                            continue;
                        }

                        if (bone.Parent == null)
                        {
                            bone.Parent = movingBone;
                        }

                        Matrix4x4.Invert(bone.InverseBindPoseMatrix, out var bindPoseMatrix);
                        var matrix = Matrix4x4.Multiply(bindPoseMatrix, bone.Parent.InverseBindPoseMatrix);

                        Matrix4x4.Decompose(matrix, out var scale, out var rotation, out var translation);

                        rotation = Quaternion.Normalize(rotation);

                        string newName = bone.Name;

                        if (newName.EndsWith("_wj", StringComparison.OrdinalIgnoreCase))
                        {
                            newName = newName.Remove(newName.Length - 3);
                        }

                        newName += "_ragdoll";

                        nameMap.Add(bone.Name, newName);

                        bone.Name = newName;

                        string baseName = newName;

                        var osageBlock = new OsageBlock
                        {
                            ExternalName = $"c_{baseName}_osg",
                            Name         = $"e_{baseName}",
                            ParentName   = bone.Parent.Name,
                            Position     = translation,
                            Rotation     = rotation.ToEulerAngles(),
                            Scale        = scale
                        };

                        osageBlock.Nodes.Add(new OsageNode {
                            Name = bone.Name, Length = 0.08f
                        });
                        obj.Skin.Blocks.Add(osageBlock);

                        stringBuilder.AppendFormat(
                            "{0}.node.0.coli_r=0.030000\r\n" +
                            "{0}.node.0.hinge_ymax=179.000000\r\n" +
                            "{0}.node.0.hinge_ymin=-179.000000\r\n" +
                            "{0}.node.0.hinge_zmax=179.000000\r\n" +
                            "{0}.node.0.hinge_zmin=-179.000000\r\n" +
                            "{0}.node.0.inertial_cancel=1.000000\r\n" +
                            "{0}.node.0.weight=3.000000\r\n" +
                            "{0}.node.length=1\r\n" +
                            "{0}.root.force=0.010000\r\n" +
                            "{0}.root.force_gain=0.300000\r\n" +
                            "{0}.root.friction=1.000000\r\n" +
                            "{0}.root.init_rot_y=0.000000\r\n" +
                            "{0}.root.init_rot_z=0.000000\r\n" +
                            "{0}.root.rot_y=0.000000\r\n" +
                            "{0}.root.rot_z=0.000000\r\n" +
                            "{0}.root.stiffness=0.100000\r\n" +
                            "{0}.root.wind_afc=0.500000\r\n",
                            osageBlock.ExternalName);
                    }
Esempio n. 29
0
 public static Vector3 Right(this Quaternion self)
 {
     return(Vector3.Transform(Vector3.UnitX, self));
 }
Esempio n. 30
0
 public static Vector3 Up(this Quaternion self)
 {
     return(Vector3.Transform(Vector3.UnitY, self));
 }