예제 #1
0
        public void SetModelMatrix(string name, XFORM worldMatrix)
        {
            var n = LogicalNodes.FirstOrDefault(item => item.Name == name);

            if (n == null)
            {
                return;
            }
            n.ModelMatrix = worldMatrix;
        }
예제 #2
0
파일: Layer.cs 프로젝트: Jypeli-JYU/Jypeli
 private void DrawEfficientlyInNoParticularOrder(ref Matrix worldMatrix)
 {
     Renderer.LightingEnabled = true;
     DrawSimpleObjectsWithoutImages(worldMatrix);
     DrawObjectsWithImages(worldMatrix);
     DrawCustomDrawables(worldMatrix);
     DrawChildObjects(worldMatrix);
     Graphics.CustomBatch.Flush();
     Renderer.LightingEnabled = false;
 }
예제 #3
0
        public void SetLocalMatrix(string name, XFORM localMatrix)
        {
            var n = LogicalNodes.FirstOrDefault(item => item.Name == name);

            if (n == null)
            {
                return;
            }
            n.LocalMatrix = localMatrix;
        }
예제 #4
0
파일: Layer.cs 프로젝트: Jypeli-JYU/Jypeli
 private void DrawCustomDrawables(Matrix worldMatrix)
 {
     foreach (CustomDrawable o in objectsWithDrawMethod)
     {
         if (o.IsVisible)
         {
             o.Draw(worldMatrix);
         }
     }
 }
예제 #5
0
파일: Matrix.cs 프로젝트: zhuowp/ge
        /// <summary>
        /// Transforms a vector using the transpose of a matrix.
        /// </summary>
        /// <param name="v">Vector to transform.</param>
        /// <param name="matrix">Transform to tranpose and apply to the vector.</param>
        /// <param name="result">Transformed vector.</param>
        public static void TransformNormalTranspose(ref System.Numerics.Vector3 v, ref System.Numerics.Matrix4x4 matrix, out System.Numerics.Vector3 result)
        {
            float vX = v.X;
            float vY = v.Y;
            float vZ = v.Z;

            result.X = vX * matrix.M11 + vY * matrix.M12 + vZ * matrix.M13 + matrix.M14;
            result.Y = vX * matrix.M21 + vY * matrix.M22 + vZ * matrix.M23 + matrix.M24;
            result.Z = vX * matrix.M31 + vY * matrix.M32 + vZ * matrix.M33 + matrix.M34;
        }
예제 #6
0
파일: Matrix.cs 프로젝트: zhuowp/ge
 /// <summary>
 /// Creates a matrix representing the given axis aligned scale.
 /// </summary>
 /// <param name="scale">Scale to be represented by the matrix.</param>
 /// <param name="scaleSystem.Numerics.Matrix4x4">System.Numerics.Matrix4x4 representing the given scale.</param>
 public static void CreateScale(ref System.Numerics.Vector3 scale, out System.Numerics.Matrix4x4 scaleSystemMatrix4x4)
 {
     scaleSystemMatrix4x4 = new System.Numerics.Matrix4x4
     {
         M11 = scale.X,
         M22 = scale.Y,
         M33 = scale.Z,
         M44 = 1
     };
 }
예제 #7
0
파일: Matrix.cs 프로젝트: zhuowp/ge
 /// <summary>
 /// Creates a matrix representing the given axis aligned scale.
 /// </summary>
 /// <param name="x">Scale along the x axis.</param>
 /// <param name="y">Scale along the y axis.</param>
 /// <param name="z">Scale along the z axis.</param>
 /// <param name="scaleSystem.Numerics.Matrix4x4">System.Numerics.Matrix4x4 representing the given scale.</param>
 public static void CreateScale(float x, float y, float z, out System.Numerics.Matrix4x4 scaleSystemMatrix4x4)
 {
     scaleSystemMatrix4x4 = new System.Numerics.Matrix4x4
     {
         M11 = x,
         M22 = y,
         M33 = z,
         M44 = 1
     };
 }
예제 #8
0
        public void Begin(ref Matrix matrix, Image texture, IShader shader = null)
        {
            Debug.Assert(!beginHasBeenCalled);
            beginHasBeenCalled = true;

            this.matrix  = matrix;
            this.texture = texture;
            iTexture     = 0;
            customShader = shader;
        }
        private Matrix4 ConvertToMatrix4(System.Numerics.Matrix4x4 m)
        {
            var row1 = new Vector4(m.M11, m.M12, m.M13, m.M14);
            var row2 = new Vector4(m.M21, m.M22, m.M23, m.M24);
            var row3 = new Vector4(m.M31, m.M32, m.M33, m.M34);
            var row4 = new Vector4(m.M41, m.M42, m.M43, m.M44);
            var m4   = new Matrix4(row1, row2, row3, row4);

            return(m4);
        }
예제 #10
0
        /// <summary>
        /// Sets the matrix of a bone.
        /// </summary>
        /// <param name="name">The name of the node to be set.</param>
        /// <param name="modelMatrix">A matrix relative to the model.</param>
        public void SetModelMatrix(string name, XFORM modelMatrix)
        {
            var n = LogicalNodes.FirstOrDefault(item => item.Name == name);

            if (n == null)
            {
                throw new ArgumentException($"{name} not found", nameof(name));
            }
            n.ModelMatrix = modelMatrix;
        }
예제 #11
0
 /// <summary>
 /// Performs a conversion from <see cref="System.Numerics.Matrix4x4"/> to <see cref="Xenko.Core.Mathematics.Matrix"/>.
 /// </summary>
 /// <param name="value">The value.</param>
 /// <returns>The result of the conversion.</returns>
 public static Matrix ToMatrix(this System.Numerics.Matrix4x4 value)
 {
     return(new Matrix()
     {
         M11 = value.M11, M12 = value.M12, M13 = value.M13, M14 = value.M14,
         M21 = value.M21, M22 = value.M22, M23 = value.M23, M24 = value.M24,
         M31 = value.M31, M32 = value.M32, M33 = value.M33, M34 = value.M34,
         M41 = value.M41, M42 = value.M42, M43 = value.M43, M44 = value.M44
     });
 }
예제 #12
0
 public static Matrix ToXna(this System.Numerics.Matrix4x4 m)
 {
     return(new Matrix
            (
                m.M11, m.M12, m.M13, m.M14,
                m.M21, m.M22, m.M23, m.M24,
                m.M31, m.M32, m.M33, m.M34,
                m.M41, m.M42, m.M43, m.M44
            ));
 }
예제 #13
0
        public void Draw(Image img, Vector2 position, System.Drawing.Rectangle?sourceRectangle, System.Drawing.Color color, Vector2 scale, float angle, Vector2 origin)
        {
            Debug.Assert(beginHasBeenCalled);

            if (iTexture >= BufferSize)
            {
                Flush();
            }

            texture = img;
            float iw = img.Width;
            float ih = img.Height;

            System.Drawing.Rectangle rect = sourceRectangle.Value;

            Vector transf = new Vector(position.X - origin.X * scale.X + (float)rect.Width / 2 * scale.X, position.Y + origin.Y * scale.Y - (float)rect.Height / 2 * scale.Y);

            Matrix matrix =
                Matrix.CreateScale(scale.X * rect.Width, scale.Y * rect.Height, 1f)
                * Matrix.CreateRotationZ(angle)
                * Matrix.CreateTranslation((float)transf.X, (float)transf.Y, 0);

            Vector3[] transformedPoints = new Vector3[VerticesPerTexture];
            for (int i = 0; i < transformedPoints.Length; i++)
            {
                transformedPoints[i] = Vector3.Transform(Vertices[i], matrix);
            }

            uint startIndex = (iTexture * VerticesPerTexture);

            for (int i = 0; i < VerticesPerTexture; i++)
            {
                uint bi = (uint)((iTexture * VerticesPerTexture) + i);
                vertexBuffer[bi].Position = transformedPoints[i];
            }

            // Triangle 1
            vertexBuffer[startIndex + 0].TexCoords = new Vector2(rect.Left / iw, rect.Top / ih);
            vertexBuffer[startIndex + 0].SetColor(color);
            vertexBuffer[startIndex + 1].TexCoords = new Vector2(rect.Left / iw, rect.Bottom / ih);
            vertexBuffer[startIndex + 1].SetColor(color);
            vertexBuffer[startIndex + 2].TexCoords = new Vector2(rect.Right / iw, rect.Top / ih);
            vertexBuffer[startIndex + 2].SetColor(color);

            // Triangle 2
            vertexBuffer[startIndex + 3].TexCoords = new Vector2(rect.Left / iw, rect.Bottom / ih);
            vertexBuffer[startIndex + 3].SetColor(color);
            vertexBuffer[startIndex + 4].TexCoords = new Vector2(rect.Right / iw, rect.Bottom / ih);
            vertexBuffer[startIndex + 4].SetColor(color);
            vertexBuffer[startIndex + 5].TexCoords = new Vector2(rect.Right / iw, rect.Top / ih);
            vertexBuffer[startIndex + 5].SetColor(color);

            iTexture++;
        }
예제 #14
0
        public void Begin(ref Matrix matrix, PrimitiveType p = PrimitiveType.OpenGlTriangles, IShader shader = null)
        {
            Debug.Assert(!beginHasBeenCalled);
            beginHasBeenCalled = true;

            primitivetype = p;
            this.matrix   = matrix;
            iVertexBuffer = 0;
            iIndexBuffer  = 0;
            customShader  = shader;
        }
예제 #15
0
 public static void Validate(this System.Numerics.Matrix4x4 m)
 {
     m.GetRight().Validate();
     m.GetUp().Validate();
     m.GetBackward().Validate();
     m.Translation.Validate();
     if (IsInvalid(m.M14) || IsInvalid(m.M24) || IsInvalid(m.M34) || IsInvalid(m.M44))
     {
         throw new NotFiniteNumberException("Invalid value.");
     }
 }
예제 #16
0
파일: Layer.cs 프로젝트: Jypeli-JYU/Jypeli
        private static void DrawTexture(IGameObject o, ref Matrix parentTransformation)
        {
            Vector position = new Vector((float)o.Position.X, (float)o.Position.Y);
            Vector scale    = new Vector((float)o.Size.X, (float)o.Size.Y);
            float  rotation = o.RotateImage ? (float)o.Angle.Radians : 0;

            if (o.IsVisible)
            {
                if (o.TextureWrapSize == Vector.Diagonal)
                {
                    Graphics.ImageBatch.Draw(defaultCoords, position, scale, rotation);
                }
                else
                {
                    float wx     = (float)(Math.Sign(o.TextureWrapSize.X));
                    float wy     = (float)(Math.Sign(o.TextureWrapSize.Y));
                    float left   = (float)(-wx / 2 + 0.5);
                    float right  = (float)(wx / 2 + 0.5);
                    float top    = (float)(-wy / 2 + 0.5);
                    float bottom = (float)(wy / 2 + 0.5);

                    TextureCoordinates customCoords = new TextureCoordinates()
                    {
                        TopLeft     = new Vector(left, top),
                        TopRight    = new Vector(right, top),
                        BottomLeft  = new Vector(left, bottom),
                        BottomRight = new Vector(right, bottom),
                    };

                    if (o.TextureWrapSize.X == wx && o.TextureWrapSize.Y == wy)
                    {
                        // Draw only once
                        Graphics.ImageBatch.Draw(customCoords, position, scale, rotation);
                        return;
                    }

                    float topLeftX = -(float)(o.TextureWrapSize.X - 1) / 2;
                    float topLeftY = -(float)(o.TextureWrapSize.Y - 1) / 2;

                    Vector newScale = new Vector(
                        scale.X / (wx * (float)o.TextureWrapSize.X),
                        scale.Y / (wy * (float)o.TextureWrapSize.Y));

                    for (int y = 0; y < o.TextureWrapSize.Y; y++)
                    {
                        for (int x = 0; x < o.TextureWrapSize.X; x++)
                        {
                            Vector newPosition = position + new Vector((topLeftX + x) * newScale.X, (topLeftY + y) * newScale.Y);
                            Graphics.ImageBatch.Draw(customCoords, newPosition, newScale, rotation);
                        }
                    }
                }
            }
        }
예제 #17
0
 /// <inheritdoc/>
 public override void Draw(Matrix parentTransformation, Matrix transformation)
 {
     if (!IsTruncated)
     {
         base.Draw(parentTransformation, transformation, Text);
     }
     else
     {
         base.Draw(parentTransformation, transformation, ShownText());
     }
 }
예제 #18
0
        // derived from:
        // https://math.stackexchange.com/questions/180418/calculate-rotation-matrix-to-align-vector-a-to-vector-b-in-3d //
        public static EuclideanTransform ComputeInitialTransformation(Point3D q1, Point3D p1)
        {
            // p2 and q2 are anchors and we map p1 to q1 vector

            var p2 = new Point3D(0, 0, 0);
            var q2 = new Point3D(0, 0, 0);

            var vectorP     = p1 - p2;
            var vectorQ     = q1 - q2;
            var vectorPQ    = q2 - p2; // Translate anchor points according to map
            var vectorPQNum = new System.Numerics.Vector3((float)vectorPQ.X, (float)vectorPQ.Y, (float)vectorPQ.Z);

            vectorP.Normalize();
            vectorQ.Normalize();

            var cross = Vector3D.CrossProduct(vectorQ, vectorP);
            var s     = cross.Length;
            var c     = Vector3D.DotProduct(vectorP, vectorQ);

            // compute skew-symmetric cross-product matrix of v
            var skewSymmetricMatrix = new System.Numerics.Matrix4x4(
                0, (float)-cross.Z, (float)cross.Y, 0,
                (float)cross.Z, 0, (float)-cross.X, 0,
                (float)-cross.Y, (float)cross.X, 0, 0,
                0, 0, 0, 1);

            var squaredSkewMatrix = System.Numerics.Matrix4x4.Multiply(skewSymmetricMatrix, skewSymmetricMatrix);
            var lastFraction      = (1 - c) / (1 - (c * c));

            var R = System.Numerics.Matrix4x4.Identity + skewSymmetricMatrix + (squaredSkewMatrix * (float)lastFraction);


            var m = new EuclideanTransform
            {
                translation = new System.Numerics.Vector3(0, 0, 0),
                rotation    = System.Numerics.Quaternion.CreateFromRotationMatrix(R),
            };

            //only rotate p1 and translate both p values
            var rotateP   = ConvertPoint3DToVector3(p1);
            var rotatedP1 = m.Apply(rotateP);

            var vectorTranslation = (ConvertPoint3DToVector3(q1) - rotatedP1);

            m.translation = vectorTranslation;

            // Check that p1 is going to be transformed to q1
            var pNum   = new System.Numerics.Vector3((float)p1.X, (float)p1.Y, (float)p1.Z);
            var result = m.Apply(pNum);


            return(m);
        }
예제 #19
0
        /// <summary>
        /// Retrieves the translation, rotation and scale components from a 4x4 transformation matrix.
        /// </summary>
        /// <param name="transformationMatrix">4x4 transformation matrix.</param>
        /// <param name="translation">Translation vector.</param>
        /// <param name="rotation">Rotation quaternion.</param>
        /// <param name="scale">Scale vector.</param>
        public static void GetTRSFromMatrix4x4(System.Numerics.Matrix4x4 transformationMatrix, out Vector3 translation, out Quaternion rotation, out Vector3 scale)
        {
            System.Numerics.Vector3    t;
            System.Numerics.Vector3    s;
            System.Numerics.Quaternion r;

            System.Numerics.Matrix4x4.Decompose(transformationMatrix, out s, out r, out t);

            translation = new Vector3(t.X, t.Y, t.Z);
            rotation    = new Quaternion(r.X, r.Y, r.Z, r.W);
            scale       = new Vector3(s.X, s.Y, s.Z);
        }
예제 #20
0
파일: Matrix.cs 프로젝트: zhuowp/ge
        /// <summary>
        /// Transforms a vector using the transpose of a matrix.
        /// </summary>
        /// <param name="v">Vector to transform.</param>
        /// <param name="matrix">Transform to tranpose and apply to the vector.</param>
        /// <param name="result">Transformed vector.</param>
        public static void TransformTranspose(ref System.Numerics.Vector4 v, ref System.Numerics.Matrix4x4 matrix, out System.Numerics.Vector4 result)
        {
            float vX = v.X;
            float vY = v.Y;
            float vZ = v.Z;
            float vW = v.W;

            result.X = vX * matrix.M11 + vY * matrix.M12 + vZ * matrix.M13 + vW * matrix.M14;
            result.Y = vX * matrix.M21 + vY * matrix.M22 + vZ * matrix.M23 + vW * matrix.M24;
            result.Z = vX * matrix.M31 + vY * matrix.M32 + vZ * matrix.M33 + vW * matrix.M34;
            result.W = vX * matrix.M41 + vY * matrix.M42 + vZ * matrix.M43 + vW * matrix.M44;
        }
예제 #21
0
        /// <summary>
        /// Helper to convert from Right hand to Left hand coordinates using <see cref="System.Numerics.Matrix4x4"/>.
        /// https://docs.microsoft.com/en-us/windows/mixed-reality/unity-xrdevice-advanced#converting-between-coordinate-systems
        /// </summary>
        /// <param name="matrix">The Right handed <see cref="System.Numerics.Matrix4x4"/>.</param>
        /// <returns>The <see cref="System.Numerics.Matrix4x4"/> in left hand form.</returns>
        public static System.Numerics.Matrix4x4 RightToLeftHanded(System.Numerics.Matrix4x4 matrix)
        {
            matrix.M13 = -matrix.M13;
            matrix.M23 = -matrix.M23;
            matrix.M43 = -matrix.M43;

            matrix.M31 = -matrix.M31;
            matrix.M32 = -matrix.M32;
            matrix.M34 = -matrix.M34;

            return(matrix);
        }
예제 #22
0
파일: Matrix.cs 프로젝트: zhuowp/ge
        /// <summary>
        /// Inverts the matrix.
        /// </summary>
        /// <param name="m">System.Numerics.Matrix4x4 to invert.</param>
        /// <param name="inverted">Inverted version of the matrix.</param>
        public static void Invert(ref System.Numerics.Matrix4x4 m, out System.Numerics.Matrix4x4 inverted)
        {
            float s0 = m.M11 * m.M22 - m.M21 * m.M12;
            float s1 = m.M11 * m.M23 - m.M21 * m.M13;
            float s2 = m.M11 * m.M24 - m.M21 * m.M14;
            float s3 = m.M12 * m.M23 - m.M22 * m.M13;
            float s4 = m.M12 * m.M24 - m.M22 * m.M14;
            float s5 = m.M13 * m.M24 - m.M23 * m.M14;

            float c5 = m.M33 * m.M44 - m.M43 * m.M34;
            float c4 = m.M32 * m.M44 - m.M42 * m.M34;
            float c3 = m.M32 * m.M43 - m.M42 * m.M33;
            float c2 = m.M31 * m.M44 - m.M41 * m.M34;
            float c1 = m.M31 * m.M43 - m.M41 * m.M33;
            float c0 = m.M31 * m.M42 - m.M41 * m.M32;

            float inverseDeterminant = 1.0f / (s0 * c5 - s1 * c4 + s2 * c3 + s3 * c2 - s4 * c1 + s5 * c0);

            float m11 = m.M11;
            float m12 = m.M12;
            float m13 = m.M13;
            float m14 = m.M14;
            float m21 = m.M21;
            float m22 = m.M22;
            float m23 = m.M23;
            float m31 = m.M31;
            float m32 = m.M32;
            float m33 = m.M33;

            float m41 = m.M41;
            float m42 = m.M42;

            inverted.M11 = (m.M22 * c5 - m.M23 * c4 + m.M24 * c3) * inverseDeterminant;
            inverted.M12 = (-m.M12 * c5 + m.M13 * c4 - m.M14 * c3) * inverseDeterminant;
            inverted.M13 = (m.M42 * s5 - m.M43 * s4 + m.M44 * s3) * inverseDeterminant;
            inverted.M14 = (-m.M32 * s5 + m.M33 * s4 - m.M34 * s3) * inverseDeterminant;

            inverted.M21 = (-m.M21 * c5 + m.M23 * c2 - m.M24 * c1) * inverseDeterminant;
            inverted.M22 = (m11 * c5 - m13 * c2 + m14 * c1) * inverseDeterminant;
            inverted.M23 = (-m.M41 * s5 + m.M43 * s2 - m.M44 * s1) * inverseDeterminant;
            inverted.M24 = (m.M31 * s5 - m.M33 * s2 + m.M34 * s1) * inverseDeterminant;

            inverted.M31 = (m21 * c4 - m22 * c2 + m.M24 * c0) * inverseDeterminant;
            inverted.M32 = (-m11 * c4 + m12 * c2 - m14 * c0) * inverseDeterminant;
            inverted.M33 = (m.M41 * s4 - m.M42 * s2 + m.M44 * s0) * inverseDeterminant;
            inverted.M34 = (-m31 * s4 + m32 * s2 - m.M34 * s0) * inverseDeterminant;

            inverted.M41 = (-m21 * c3 + m22 * c1 - m23 * c0) * inverseDeterminant;
            inverted.M42 = (m11 * c3 - m12 * c1 + m13 * c0) * inverseDeterminant;
            inverted.M43 = (-m41 * s3 + m42 * s1 - m.M43 * s0) * inverseDeterminant;
            inverted.M44 = (m31 * s3 - m32 * s1 + m33 * s0) * inverseDeterminant;
        }
예제 #23
0
파일: Matrix.cs 프로젝트: zhuowp/ge
 /// <summary>
 /// Creates a matrix representing a translation.
 /// </summary>
 /// <param name="translation">Translation to be represented by the matrix.</param>
 /// <param name="translationSystem.Numerics.Matrix4x4">System.Numerics.Matrix4x4 representing the given translation.</param>
 public static void CreateTranslation(ref System.Numerics.Vector3 translation, out System.Numerics.Matrix4x4 translationSystemMatrix4x4)
 {
     translationSystemMatrix4x4 = new System.Numerics.Matrix4x4
     {
         M11 = 1,
         M22 = 1,
         M33 = 1,
         M44 = 1,
         M41 = translation.X,
         M42 = translation.Y,
         M43 = translation.Z
     };
 }
예제 #24
0
        public static NMatrix GetAbsoluteNMatrix(this FLVER.Bone b, List <FLVER.Bone> bones)
        {
            NMatrix result     = NMatrix.Identity;
            var     parentBone = b;

            while (parentBone != null)
            {
                var m = parentBone.GetNMatrix();
                result    *= m;
                parentBone = parentBone.GetParent(bones);
            }
            return(result);
        }
예제 #25
0
 /// <inheritdoc/>
 public override void Draw(Matrix parentTransformation, Matrix transformation)
 {
     if (messages.Count == 0)
     {
         return;
     }
     Graphics.FontRenderer.Begin();
     for (int i = 0; i < Math.Min(messages.Count, MaxMessageCount); i++)
     {
         Font.SpriteFont.DrawText(Graphics.FontRenderer, messages[i].Text, Position - new Vector(Width / 2, i * fontHeight - Height / 2), messages[i].Color.ToSystemDrawing());
     }
     base.Draw(parentTransformation, transformation);
 }
예제 #26
0
        /// <summary>
        /// Adds the two matrices together on a per-element basis.
        /// </summary>
        /// <param name="a">First matrix to add.</param>
        /// <param name="b">Second matrix to add.</param>
        /// <param name="result">Sum of the two matrices.</param>
        public static void Add(ref Matrix2x2 a, ref System.Numerics.Matrix4x4 b, out Matrix2x2 result)
        {
            float m11 = a.M11 + b.M11;
            float m12 = a.M12 + b.M12;

            float m21 = a.M21 + b.M21;
            float m22 = a.M22 + b.M22;

            result.M11 = m11;
            result.M12 = m12;

            result.M21 = m21;
            result.M22 = m22;
        }
예제 #27
0
        /// <summary>
        /// Multiplies the two matrices.
        /// </summary>
        /// <param name="a">First matrix to multiply.</param>
        /// <param name="b">Second matrix to multiply.</param>
        /// <param name="result">Product of the multiplication.</param>
        public static void Multiply(ref System.Numerics.Matrix4x4 a, ref Matrix2x2 b, out Matrix2x2 result)
        {
            float resultM11 = a.M11 * b.M11 + a.M12 * b.M21;
            float resultM12 = a.M11 * b.M12 + a.M12 * b.M22;

            float resultM21 = a.M21 * b.M11 + a.M22 * b.M21;
            float resultM22 = a.M21 * b.M12 + a.M22 * b.M22;

            result.M11 = resultM11;
            result.M12 = resultM12;

            result.M21 = resultM21;
            result.M22 = resultM22;
        }
        private void SetTransformToTimeWithinCurrentLoop(float localTime)
        {
            // Get sample at specified time.
            var sampleAtTime = SampleRootMotionData(localTime);

            // Rotate sample translation to be relative to loop start transform rotation.
            var translation = NVector3.Transform(sampleAtTime.XYZ(), NMatrix.CreateRotationY(LoopStartTransform.W));

            sampleAtTime.X = translation.X;
            sampleAtTime.Y = translation.Y;
            sampleAtTime.Z = translation.Z;

            CurrentTransform = LoopStartTransform + sampleAtTime;
        }
예제 #29
0
        protected void ProjectLayerOntoSurface(IImageProcessingContext <Rgba32> context, Matrix <float> transformMatrix)
        {
            var matrix4x4 = new System.Numerics.Matrix4x4(
                transformMatrix[0, 0], transformMatrix[1, 0], 0, transformMatrix[2, 0],
                transformMatrix[0, 1], transformMatrix[1, 1], 0, transformMatrix[2, 1],
                0, 0, 1, 0,
                transformMatrix[0, 2], transformMatrix[1, 2], 0, transformMatrix[2, 2]
                );

            context.Transform(matrix4x4, KnownResamplers.Lanczos3);
            foreach (var mask in Masks)
            {
                context.Opacity(0, mask);
            }
        }
예제 #30
0
        public void RotationMatrix_ToQuaternion_VsSystemNumerics()
        {
            RotationMatrix m;
            Quaternion     q;
            SysMatrix44    m44, m44bis;
            SysQuat        sq;
            Vector         vecX, vecY;
            int            dir;

            int runs = 500;

            for (var i = 0; i < runs; i++)
            {
                if (i < 0.5 * runs)
                {
                    vecX = Vector.RandomFromDoubles(-100, 100);
                    vecY = Vector.RandomFromDoubles(-100, 100);
                }
                else
                {
                    vecX = Vector.RandomFromInts(-1, 1);
                    vecY = Vector.RandomFromInts(-1, 1);
                }

                dir = Vector.CompareDirections(vecX, vecY);
                m   = new RotationMatrix(vecX, vecY);
                q   = m.ToQuaternion();

                Trace.WriteLine("");
                Trace.WriteLine(vecX + " " + vecY + " dir:" + dir);
                Trace.WriteLine(m);
                Trace.WriteLine(q);

                // Use the matrix's orthogonal values to create a M44 matrix with just rotation values:
                m44 = new SysMatrix44((float)m.m00, (float)m.m01, (float)m.m02, 0,
                                      (float)m.m10, (float)m.m11, (float)m.m12, 0,
                                      (float)m.m20, (float)m.m21, (float)m.m22, 0,
                                      0, 0, 0, 1);
                m44    = SysMatrix44.Transpose(m44); // Numerics.Matrix4x4 uses a transposed convention, meaning the translation vector is horizontal in m41-42-43 instead of vertical in m14-24-34
                sq     = SysQuat.CreateFromRotationMatrix(m44);
                m44bis = SysMatrix44.CreateFromQuaternion(sq);
                Trace.WriteLine(m44);
                Trace.WriteLine(sq);
                Trace.WriteLine(m44bis);

                Assert.IsTrue(q.IsEquivalent(new Quaternion(sq.W, sq.X, sq.Y, sq.Z)), "Quaternions are not equivalent!");
            }
        }
예제 #31
0
        /// <summary>
        /// Creates a 4x4 matrix from a 3x3 matrix.
        /// </summary>
        /// <param name="a">3x3 matrix.</param>
        /// <returns>Created 4x4 matrix.</returns>
        public static System.Numerics.Matrix4x4 ToMatrix4X4(Matrix3x3 a)
        {
            #if !WINDOWS
            System.Numerics.Matrix4x4 b = new System.Numerics.Matrix4x4();
            #else
            System.Numerics.Matrix4x4 b;
            #endif
            b.M11 = a.M11;
            b.M12 = a.M12;
            b.M13 = a.M13;

            b.M21 = a.M21;
            b.M22 = a.M22;
            b.M23 = a.M23;

            b.M31 = a.M31;
            b.M32 = a.M32;
            b.M33 = a.M33;

            b.M44 = 1;
            b.M14 = 0;
            b.M24 = 0;
            b.M34 = 0;
            b.M41 = 0;
            b.M42 = 0;
            b.M43 = 0;
            return b;
        }
예제 #32
0
        /// <summary>
        /// Creates a 4x4 matrix from a 3x3 matrix.
        /// </summary>
        /// <param name="a">3x3 matrix.</param>
        /// <param name="b">Created 4x4 matrix.</param>
        public static void ToMatrix4X4(ref Matrix3x3 a, out System.Numerics.Matrix4x4 b)
        {
            #if !WINDOWS
            b = new System.Numerics.Matrix4x4();
            #endif
            b.M11 = a.M11;
            b.M12 = a.M12;
            b.M13 = a.M13;

            b.M21 = a.M21;
            b.M22 = a.M22;
            b.M23 = a.M23;

            b.M31 = a.M31;
            b.M32 = a.M32;
            b.M33 = a.M33;

            b.M44 = 1;
            b.M14 = 0;
            b.M24 = 0;
            b.M34 = 0;
            b.M41 = 0;
            b.M42 = 0;
            b.M43 = 0;
        }
예제 #33
0
 /// <summary>
 /// Creates a matrix representing a translation.
 /// </summary>
 /// <param name="translation">Translation to be represented by the matrix.</param>
 /// <param name="translationSystem.Numerics.Matrix4x4">System.Numerics.Matrix4x4 representing the given translation.</param>
 public static void CreateTranslation(ref System.Numerics.Vector3 translation, out System.Numerics.Matrix4x4 translationSystemMatrix4x4)
 {
     translationSystemMatrix4x4 = new System.Numerics.Matrix4x4
     {
         M11 = 1,
         M22 = 1,
         M33 = 1,
         M44 = 1,
         M41 = translation.X,
         M42 = translation.Y,
         M43 = translation.Z
     };
 }
예제 #34
0
 /// <summary>
 /// Creates a matrix representing the given axis aligned scale.
 /// </summary>
 /// <param name="x">Scale along the x axis.</param>
 /// <param name="y">Scale along the y axis.</param>
 /// <param name="z">Scale along the z axis.</param>
 /// <param name="scaleSystem.Numerics.Matrix4x4">System.Numerics.Matrix4x4 representing the given scale.</param>
 public static void CreateScale(float x, float y, float z, out System.Numerics.Matrix4x4 scaleSystemMatrix4x4)
 {
     scaleSystemMatrix4x4 = new System.Numerics.Matrix4x4
     {
         M11 = x,
         M22 = y,
         M33 = z,
         M44 = 1
     };
 }
예제 #35
0
 /// <summary>
 /// Creates a matrix representing the given axis aligned scale.
 /// </summary>
 /// <param name="scale">Scale to be represented by the matrix.</param>
 /// <param name="scaleSystem.Numerics.Matrix4x4">System.Numerics.Matrix4x4 representing the given scale.</param>
 public static void CreateScale(ref System.Numerics.Vector3 scale, out System.Numerics.Matrix4x4 scaleSystemMatrix4x4)
 {
     scaleSystemMatrix4x4 = new System.Numerics.Matrix4x4
         {
             M11 = scale.X,
             M22 = scale.Y,
             M33 = scale.Z,
             M44 = 1
         };
 }
예제 #36
0
        /// <summary>
        /// This is a javascript application.
        /// </summary>
        /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param>
        public Application(IDefault page = null)
        {
            var size = 600;
            var gl = new WebGLRenderingContext();

            var canvas = gl.canvas.AttachToDocument();

            Native.document.body.style.overflow = IStyle.OverflowEnum.hidden;
            canvas.style.SetLocation(0, 0, size, size);

            canvas.width = size;
            canvas.height = size;


            var gl_viewportWidth = size;
            var gl_viewportHeight = size;


            // can AssetLibrary create a special type
            // and define the variables
            // for it we need to parse glsl?

            // Geometry
            var shaderProgram = gl.createProgram(
                new GeometryVertexShader(),
                new GeometryFragmentShader()
           );



            gl.linkProgram(shaderProgram);
            gl.useProgram(shaderProgram);

            var shaderProgram_vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");

            gl.enableVertexAttribArray((uint)shaderProgram_vertexPositionAttribute);

            // new in lesson 02
            var shaderProgram_vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor");
            gl.enableVertexAttribArray((uint)shaderProgram_vertexColorAttribute);

            var shaderProgram_pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
            var shaderProgram_mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");

            // https://hacks.mozilla.org/2014/10/introducing-simd-js/
            // https://github.com/toji/gl-matrix/blob/master/src/gl-matrix/mat4.js
            // http://www.i-programmer.info/news/167-javascript/8578-chrome-to-support-simdjs.html

            // https://code.google.com/p/v8/issues/detail?id=2228
            var SIMD_mat4 = new System.Numerics.Matrix4x4();
            var SIMD_mat4s = new  Stack<System.Numerics.Matrix4x4>();
            

            // can we convert this code to NDK friendly non GC library?
            // for gearVR 90FOV and cardboard wearality 150FOV
            #region __mat4
            var __mat4 = new
            {
                // X:\jsc.svn\examples\javascript\Test\TestFloatArray\TestFloatArray\Application.cs
                // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/20150706/20150708

                // generic in the sens of caller choosing is the return type a new struct or out ref?
                perspective = new Func<float[], float, float, float, float, float[]>(
                    (that, fovy, aspect, near, far) =>
                    {
                        var f = 1.0f / (float)Math.Tan(fovy / 2f);
                        var nf = 1f / (near - far);

                        that[0] = f / aspect;
                        that[1] = 0;
                        that[2] = 0;
                        that[3] = 0;
                        that[4] = 0;
                        that[5] = f;
                        that[6] = 0;
                        that[7] = 0;
                        that[8] = 0;
                        that[9] = 0;
                        that[10] = (far + near) * nf;
                        that[11] = -1;
                        that[12] = 0;
                        that[13] = 0;
                        that[14] = (2 * far * near) * nf;
                        that[15] = 0;

                        return that;
                    }),

                // reset content of mat4
                identity = new Func<float[], float[]>(
                    that =>
                    {
                        //Array.Copy()

                        //var xx =&that;
                        var x = new float[]
                        {
                            1, 0, 0, 0,
                            0, 1, 0, 0,
                            0, 0, 1, 0,
                            0, 0, 0, 1,
                        };

                        //is this the best way to update array contents?
                        x.CopyTo(that, 0);

                        return x;
                    }
                ),

                create = new Func<float[]>(
                    () =>
                    //new mat4()
                    new float[]
                    {
                        1, 0, 0, 0,
                        0, 1, 0, 0,
                        0, 0, 1, 0,
                        0, 0, 0, 1,
                    }
                ),

                #region not used?
                clone = new Func<float[], float[]>(
                    smat4 =>
                    //new mat4()
                    new float[]
                    {
                        smat4[0], smat4[1], smat4[2], smat4[3],
                        smat4[4], smat4[5], smat4[6], smat4[7],
                        smat4[8], smat4[9], smat4[10], smat4[11],
                        smat4[12], smat4[13], smat4[14], smat4[15],
                    }
                )
                #endregion

                ,
                // X:\jsc.svn\examples\java\android\vr\OVRWindWheelNDK\OVRWindWheelNDK\References\VrApi.ovrMatrix4f.cs
                translate = new Func<float[], float[], float[], float[]>(
                    (float[] that, float[] output, float[]  xyz) =>
                    {
                        float x = xyz[0], y = xyz[1], z = xyz[2];

                        if (output == that)
                        {
                            that[12] = output[0] * x + output[4] * y + output[8] * z + output[12];
                            that[13] = output[1] * x + output[5] * y + output[9] * z + output[13];
                            that[14] = output[2] * x + output[6] * y + output[10] * z + output[14];
                            that[15] = output[3] * x + output[7] * y + output[11] * z + output[15];

                            return that;
                        }

                        float a00, a01, a02, a03,
                            a10, a11, a12, a13,
                            a20, a21, a22, a23;


                        a00 = output[0]; a01 = output[1]; a02 = output[2]; a03 = output[3];
                        a10 = output[4]; a11 = output[5]; a12 = output[6]; a13 = output[7];
                        a20 = output[8]; a21 = output[9]; a22 = output[10]; a23 = output[11];

                        that[0] = a00; that[1] = a01; that[2] = a02; that[3] = a03;
                        that[4] = a10; that[5] = a11; that[6] = a12; that[7] = a13;
                        that[8] = a20; that[9] = a21; that[10] = a22; that[11] = a23;

                        that[12] = a00 * x + a10 * y + a20 * z + output[12];
                        that[13] = a01 * x + a11 * y + a21 * z + output[13];
                        that[14] = a02 * x + a12 * y + a22 * z + output[14];
                        that[15] = a03 * x + a13 * y + a23 * z + output[15];


                        return that;
                    }
                ),

                rotate = new Func<float[], float[], float, float[], float[]>(
                    (that, a, rad, axis) =>
                    {
                        float x = axis[0], y = axis[1], z = axis[2];
                        float len = (float)Math.Sqrt(x * x + y * y + z * z),
                        s, c, t,
                        a00, a01, a02, a03,
                        a10, a11, a12, a13,
                        a20, a21, a22, a23,
                        b00, b01, b02,
                        b10, b11, b12,
                        b20, b21, b22;


                        if (Math.Abs(len) < float.Epsilon)
                            return that;

                        len = 1f / len;
                        x *= len;
                        y *= len;
                        z *= len;

                        s = (float)Math.Sin(rad);
                        c = (float)Math.Cos(rad);
                        t = 1 - c;

                        a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];
                        a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];
                        a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];

                        // Construct the elements of the rotation matrix
                        b00 = x * x * t + c; b01 = y * x * t + z * s; b02 = z * x * t - y * s;
                        b10 = x * y * t - z * s; b11 = y * y * t + c; b12 = z * y * t + x * s;
                        b20 = x * z * t + y * s; b21 = y * z * t - x * s; b22 = z * z * t + c;

                        // Perform rotation-specific matrix multiplication
                        that[0] = a00 * b00 + a10 * b01 + a20 * b02;
                        that[1] = a01 * b00 + a11 * b01 + a21 * b02;
                        that[2] = a02 * b00 + a12 * b01 + a22 * b02;
                        that[3] = a03 * b00 + a13 * b01 + a23 * b02;
                        that[4] = a00 * b10 + a10 * b11 + a20 * b12;
                        that[5] = a01 * b10 + a11 * b11 + a21 * b12;
                        that[6] = a02 * b10 + a12 * b11 + a22 * b12;
                        that[7] = a03 * b10 + a13 * b11 + a23 * b12;
                        that[8] = a00 * b20 + a10 * b21 + a20 * b22;
                        that[9] = a01 * b20 + a11 * b21 + a21 * b22;
                        that[10] = a02 * b20 + a12 * b21 + a22 * b22;
                        that[11] = a03 * b20 + a13 * b21 + a23 * b22;

                        if (a != that)
                        { // If the source and destination differ, copy the unchanged last row
                            that[12] = a[12];
                            that[13] = a[13];
                            that[14] = a[14];
                            that[15] = a[15];
                        }


                        return that;
                    }
                )
            };
            #endregion



            // set to identity
            var mvMatrix = __mat4.create();
            var mvMatrixStack = new Stack<float[]>();

            // set to perspective
            var pMatrix = __mat4.create();

            #region new in lesson 03
            // how would this translate to non GC, NDK?
            Action mvPushMatrix = delegate
            {
                var copy = __mat4.create();

                mvMatrix.CopyTo(copy, 0);

                //glMatrix.mat4.set(mvMatrix, copy);
                mvMatrixStack.Push(copy);
            };

            Action mvPopMatrix = delegate
            {
                mvMatrix = mvMatrixStack.Pop();
            };
            #endregion


            #region setMatrixUniforms
            Action setMatrixUniforms =
                delegate
                {
                    gl.uniformMatrix4fv(shaderProgram_pMatrixUniform, false, pMatrix);
                    gl.uniformMatrix4fv(shaderProgram_mvMatrixUniform, false, mvMatrix);
                };
            #endregion




            #region init buffers


            #region cube
            var cubeVertexPositionBuffer = new WebGLBuffer(gl);
            gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);

            var cubesize = 1.0f * 0.05f;
            var vertices = new[]{
                // Front face
                -cubesize, -cubesize,  cubesize,
                 cubesize, -cubesize,  cubesize,
                 cubesize,  cubesize,  cubesize,
                -cubesize,  cubesize,  cubesize,

                // Back face
                -cubesize, -cubesize, -cubesize,
                -cubesize,  cubesize, -cubesize,
                 cubesize,  cubesize, -cubesize,
                 cubesize, -cubesize, -cubesize,

                // Top face
                -cubesize,  cubesize, -cubesize,
                -cubesize,  cubesize,  cubesize,
                 cubesize,  cubesize,  cubesize,
                 cubesize,  cubesize, -cubesize,

                // Bottom face
                -cubesize, -cubesize, -cubesize,
                 cubesize, -cubesize, -cubesize,
                 cubesize, -cubesize,  cubesize,
                -cubesize, -cubesize,  cubesize,

                // Right face
                cubesize, -cubesize, -cubesize,
                 cubesize,  cubesize, -cubesize,
                 cubesize,  cubesize,  cubesize,
                 cubesize, -cubesize,  cubesize,

                // Left face
                -cubesize, -cubesize, -cubesize,
                -cubesize, -cubesize,  cubesize,
                -cubesize,  cubesize,  cubesize,
                -cubesize,  cubesize, -cubesize
            };


            gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

            var cubeVertexPositionBuffer_itemSize = 3;
            var cubeVertexPositionBuffer_numItems = 6 * 6;

            var squareVertexColorBuffer = new WebGLBuffer(gl);
            gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer);

            // 216, 191, 18
            var colors = new[]{
                1.0f, 0.6f, 0.0f, 1.0f, // Front face
                1.0f, 0.6f, 0.0f, 1.0f, // Front face
                1.0f, 0.6f, 0.0f, 1.0f, // Front face
                1.0f, 0.6f, 0.0f, 1.0f, // Front face

                0.8f, 0.4f, 0.0f, 1.0f, // Back face
                0.8f, 0.4f, 0.0f, 1.0f, // Back face
                0.8f, 0.4f, 0.0f, 1.0f, // Back face
                0.8f, 0.4f, 0.0f, 1.0f, // Back face

                0.9f, 0.5f, 0.0f, 1.0f, // Top face
                0.9f, 0.5f, 0.0f, 1.0f, // Top face
                0.9f, 0.5f, 0.0f, 1.0f, // Top face
                0.9f, 0.5f, 0.0f, 1.0f, // Top face

                1.0f, 0.5f, 0.0f, 1.0f, // Bottom face
                1.0f, 0.5f, 0.0f, 1.0f, // Bottom face
                1.0f, 0.5f, 0.0f, 1.0f, // Bottom face
                1.0f, 0.5f, 0.0f, 1.0f, // Bottom face


                1.0f, 0.8f, 0.0f, 1.0f, // Right face
                1.0f, 0.8f, 0.0f, 1.0f, // Right face
                1.0f, 0.8f, 0.0f, 1.0f, // Right face
                1.0f, 0.8f, 0.0f, 1.0f, // Right face

                1.0f, 0.8f, 0.0f, 1.0f,  // Left face
                1.0f, 0.8f, 0.0f, 1.0f,  // Left face
                1.0f, 0.8f, 0.0f, 1.0f,  // Left face
                1.0f, 0.8f, 0.0f, 1.0f  // Left face
            };



            gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
            var cubeVertexColorBuffer_itemSize = 4;
            var cubeVertexColorBuffer_numItems = 24;

            // ELEMENT_ARRAY_BUFFER : WebGLBuffer?
            // drawElements
            var cubeVertexIndexBuffer = new WebGLBuffer(gl);
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer);
            //var cubeVertexIndices = new UInt16[]{
            var cubeVertexIndices = new byte[]{
                0, 1, 2,      0, 2, 3,    // Front face
                4, 5, 6,      4, 6, 7,    // Back face
                8, 9, 10,     8, 10, 11,  // Top face
                12, 13, 14,   12, 14, 15, // Bottom face
                16, 17, 18,   16, 18, 19, // Right face
                20, 21, 22,   20, 22, 23  // Left face
            };

            // ushort[]?
            //gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW);
            gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndices, gl.STATIC_DRAW);
            var cubeVertexIndexBuffer_itemSize = 1;
            var cubeVertexIndexBuffer_numItems = 36;

            #endregion

            #endregion




            gl.clearColor(0.0f, 0.0f, 0.0f, alpha: 1.0f);
            gl.enable(gl.DEPTH_TEST);


            var rWindDelta = 0.0f;
            var rCubeDelta = 1.0f;

            if (page != null)
            {

                #region WindLeft
                page.WindLeft.onmousedown +=
                    delegate
                    {
                        rWindDelta = -2.0f;
                    };
                page.WindLeft.onmouseup +=
                 delegate
                 {
                     rWindDelta = 0.0f;
                 };
                #endregion

                #region WindRight
                page.WindRight.onmousedown +=
                    delegate
                    {
                        rWindDelta = 2.0f;
                    };
                page.WindRight.onmouseup +=
                 delegate
                 {
                     rWindDelta = 0.0f;
                 };
                #endregion


                #region SpeedSlow
                page.SpeedSlow.onmousedown +=
                    delegate
                    {
                        rCubeDelta = 0.1f;
                    };
                page.SpeedSlow.onmouseup +=
                 delegate
                 {
                     rCubeDelta = 1.0f;
                 };
                #endregion

                #region SpeedFast
                page.SpeedFast.onmousedown +=
                  delegate
                  {
                      rCubeDelta = 4.0f;
                  };
                page.SpeedFast.onmouseup +=
                 delegate
                 {
                     rCubeDelta = 1.0f;
                 };
                #endregion
            }


            #region animate
            var rCube = 0f;
            var rWind = 0f;

            var lastTime = 0L;
            Action animate = delegate
            {
                var timeNow = new IDate().getTime();
                if (lastTime != 0)
                {
                    var elapsed = timeNow - lastTime;

                    rCube -= ((75 * elapsed) / 1000.0f) * rCubeDelta;
                    rWind -= ((75 * elapsed) / 1000.0f) * rWindDelta;
                }
                lastTime = timeNow;
            };
            #endregion

            #region degToRad
            Func<float, float> degToRad = (degrees) =>
            {
                return degrees * (f)Math.PI / 180f;
            };
            #endregion


            #region drawScene
            Action drawScene = delegate
            {
                gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight);
                gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

                // glMatrix.mat4.perspective(
                //     45f,
                //     (float)gl_viewportWidth / (float)gl_viewportHeight,
                //     0.1f,
                //     100.0f,
                //     pMatrix
                //);

                __mat4.perspective(
                    pMatrix,

                    45f,
                    (float)gl_viewportWidth / (float)gl_viewportHeight,
                    0.1f,
                    100.0f
                    );

                __mat4.identity(mvMatrix);
                //glMatrix.mat4.identity(mvMatrix);

                __mat4.translate(mvMatrix, mvMatrix, new float[] { -1.5f, 0.0f, -7.0f });
                //glMatrix.mat4.translate(mvMatrix, new float[] { -1.5f, 0.0f, -7.0f });

                mvPushMatrix();
                //glMatrix.mat4.rotate(mvMatrix, degToRad(rWind), new float[] { 0f, 1f, 0f });
                __mat4.rotate(mvMatrix, mvMatrix, degToRad(rWind), new float[] { 0, 1f, 0f });


                #region DrawFrameworkWingAtX
                Action<float, float> DrawFrameworkWingAtX =
            (WingX, WingY) =>
            {
                #region draw center cube
                mvPushMatrix();

                __mat4.translate(mvMatrix, mvMatrix, new float[] { cubesize * WingX, cubesize * WingY, 0 });
                //glMatrix.mat4.translate(mvMatrix, new float[] { cubesize * WingX, cubesize * WingY, 0 });

                gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);
                gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0);

                gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer);
                gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0);

                gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer);
                setMatrixUniforms();
                //gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_SHORT, 0);
                gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_BYTE, 0);

                mvPopMatrix();
                #endregion
            };
                #endregion

                #region DrawWingAtX
                Action<int, int, float, float> DrawWingAtX =
            (WingX, WingSize, WingRotationMultiplier, WingRotationOffset) =>
            {
                mvPushMatrix();

                __mat4.translate(mvMatrix, mvMatrix, new float[] { cubesize * WingX, 0, 0 });
                //glMatrix.mat4.translate(mvMatrix, new float[] { cubesize * WingX, 0, 0 });

                if (WingRotationOffset == 0)
                {
                    DrawFrameworkWingAtX(0, 0);
                }

                #region DrawWingPart
                Action<float> DrawWingPart =
            PartIndex =>
            {
                mvPushMatrix();
                //glMatrix.mat4.rotate(mvMatrix, degToRad(WingRotationOffset + (rCube * WingRotationMultiplier)), new float[] { 1f, 0f, 0f });
                __mat4.rotate(mvMatrix, mvMatrix, degToRad(WingRotationOffset + (rCube * WingRotationMultiplier)), new float[] { 1f, 0f, 0f });
                //glMatrix.mat4.translate(mvMatrix, new float[] { 0f, cubesize * PartIndex * 2, 0 });
                __mat4.translate(mvMatrix, mvMatrix, new float[] { 0f, cubesize * PartIndex * 2, 0 });

                gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);
                gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0);

                gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer);
                gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0);

                gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer);
                setMatrixUniforms();
                //gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_SHORT, 0);
                gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_BYTE, 0);

                mvPopMatrix();
            };
                #endregion

                #region DrawWingWithSize
                Action<int> DrawWingWithSize =
            length =>
            {
                for (int i = 4; i < length; i++)
                {
                    DrawWingPart(i * 1.0f);
                    DrawWingPart(-i * 1.0f);

                }
            };
                #endregion

                DrawWingWithSize(WingSize);

                mvPopMatrix();

            };
                #endregion

                var x = 8;

                DrawFrameworkWingAtX(x - 8, 0);

                for (int i = 0; i < 24; i++)
                {
                    DrawFrameworkWingAtX(x - 8, -2.0f * i);

                }

                DrawWingAtX(x - 6, 0, 1f, 0);
                DrawWingAtX(x - 4, 0, 1f, 0);
                DrawWingAtX(x - 2, 0, 1f, 0);

                DrawWingAtX(x + 0, 16, 1f, 0);
                DrawWingAtX(x + 0, 16, 1f, 30);
                DrawWingAtX(x + 0, 16, 1f, 60);
                DrawWingAtX(x + 0, 16, 1f, 90);
                DrawWingAtX(x + 0, 16, 1f, 120);
                DrawWingAtX(x + 0, 16, 1f, 150);

                DrawWingAtX(x + 2, 0, 1f, 0);
                DrawWingAtX(x + 4, 0, 1f, 0);
                DrawWingAtX(x + 6, 0, 1f, 0);

                DrawWingAtX(x + 8, 12, 0.4f, 0);
                DrawWingAtX(x + 8, 12, 0.4f, 60);
                DrawWingAtX(x + 8, 12, 0.4f, 120);


                DrawWingAtX(x + 8 + 2, 0, 1f, 0);
                DrawWingAtX(x + 8 + 4, 0, 1f, 0);
                DrawWingAtX(x + 8 + 6, 0, 1f, 0);

                DrawWingAtX(x + 16, 8, 0.3f, 0);
                DrawWingAtX(x + 16, 8, 0.3f, 90);




                mvPopMatrix();


                #region draw cube on the right to remind where we started
                //glMatrix.mat4.translate(mvMatrix, new float[] { 3.0f, 2.0f, 0.0f });
                __mat4.translate(mvMatrix, mvMatrix, new float[] { 3.0f, 2.0f, 0.0f });

                mvPushMatrix();
                //glMatrix.mat4.rotate(mvMatrix, degToRad(rCube), new float[] { 1f, 1f, 1f });
                __mat4.rotate(mvMatrix, mvMatrix, degToRad(rCube), new float[] { 1f, 1f, 1f });



                gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);
                gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0);

                gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer);
                gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0);

                gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer);
                setMatrixUniforms();
                //gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_SHORT, 0);
                gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_BYTE, 0);

                mvPopMatrix();
                #endregion

            };
            drawScene();
            #endregion



            #region AtResize
            Action AtResize =
                delegate
                {
                    gl_viewportWidth = Native.window.Width;
                    gl_viewportHeight = Native.window.Height;

                    canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight);

                    canvas.width = gl_viewportWidth;
                    canvas.height = gl_viewportHeight;
                };

            Native.window.onresize +=
                            e =>
                            {
                                AtResize();
                            };
            AtResize();
            #endregion

            #region IsDisposed
            var IsDisposed = false;

            this.Dispose = delegate
            {
                if (IsDisposed)
                    return;

                IsDisposed = true;

                canvas.Orphanize();
            };
            #endregion

            #region requestFullscreen
            Native.document.body.ondblclick +=
                delegate
                {
                    if (IsDisposed)
                        return;

                    // http://tutorialzine.com/2012/02/enhance-your-website-fullscreen-api/

                    Native.document.body.requestFullscreen();


                };
            #endregion




            //var c = 0;

            #region tick

            Native.window.onframe += e =>
                        {
                            if (IsDisposed)
                                return;

                            //c++;

                            // frameID
                            Native.document.title = "" + e.counter;

                            drawScene();
                            animate();

                        };

            #endregion

            if (page != null)
                page.Mission.Orphanize().AttachToDocument().style.SetLocation(left: size - 56, top: 16);
        }