示例#1
0
        public TMat4x4 MulMat(TMat4x4 MatToMul)
        {
            TMat4x4 Result;

            Result.m00 = m00 * MatToMul.m00 + m01 * MatToMul.m10 + m02 * MatToMul.m20 + m03 * MatToMul.m30;
            Result.m01 = m00 * MatToMul.m01 + m01 * MatToMul.m11 + m02 * MatToMul.m21 + m03 * MatToMul.m31;
            Result.m02 = m00 * MatToMul.m02 + m01 * MatToMul.m12 + m02 * MatToMul.m22 + m03 * MatToMul.m32;
            Result.m03 = m00 * MatToMul.m03 + m01 * MatToMul.m13 + m02 * MatToMul.m23 + m03 * MatToMul.m33;

            Result.m10 = m10 * MatToMul.m00 + m11 * MatToMul.m10 + m12 * MatToMul.m20 + m13 * MatToMul.m30;
            Result.m11 = m10 * MatToMul.m01 + m11 * MatToMul.m11 + m12 * MatToMul.m21 + m13 * MatToMul.m31;
            Result.m12 = m10 * MatToMul.m02 + m11 * MatToMul.m12 + m12 * MatToMul.m22 + m13 * MatToMul.m32;
            Result.m13 = m10 * MatToMul.m03 + m11 * MatToMul.m13 + m12 * MatToMul.m23 + m13 * MatToMul.m33;

            Result.m20 = m20 * MatToMul.m00 + m21 * MatToMul.m10 + m22 * MatToMul.m20 + m23 * MatToMul.m30;
            Result.m21 = m20 * MatToMul.m01 + m21 * MatToMul.m11 + m22 * MatToMul.m21 + m23 * MatToMul.m31;
            Result.m22 = m20 * MatToMul.m02 + m21 * MatToMul.m12 + m22 * MatToMul.m22 + m23 * MatToMul.m32;
            Result.m23 = m20 * MatToMul.m03 + m21 * MatToMul.m13 + m22 * MatToMul.m23 + m23 * MatToMul.m33;

            Result.m30 = m30 * MatToMul.m00 + m31 * MatToMul.m10 + m32 * MatToMul.m20 + m33 * MatToMul.m30;
            Result.m31 = m30 * MatToMul.m01 + m31 * MatToMul.m11 + m32 * MatToMul.m21 + m33 * MatToMul.m31;
            Result.m32 = m30 * MatToMul.m02 + m31 * MatToMul.m12 + m32 * MatToMul.m22 + m33 * MatToMul.m32;
            Result.m33 = m30 * MatToMul.m03 + m31 * MatToMul.m13 + m32 * MatToMul.m23 + m33 * MatToMul.m33;

            return(Result);
        }
示例#2
0
        public void RotateOnAxis(float Angle)
        {
            TMat4x4 ArbitraryMat = TMat4x4.ZeroMat();

            ArbitraryMat.SetArbitraryRot(TransformedAxisPointA, TransformedAxisPointB, Angle);
            SetMatrix(ArbitraryMat);
        }
示例#3
0
        private TMat4x4 GetFatherMat()
        {
            if (Father != null)
            {
                return(Father.CombinedMatrix);
            }

            return(TMat4x4.UnitMat());
        }
示例#4
0
        public void SetPos(TVertex NewPos)
        {
            CurrentPos = NewPos;

            TMat4x4 TransMat = TMat4x4.ZeroMat();

            TransMat.SetTrans(NewPos.X, NewPos.Y, NewPos.Z);
            SetMatrix(TransMat);
        }
示例#5
0
        public void SetPos(float X, float Y, float Z)
        {
            CurrentPos.Set(X, Y, Z);

            TMat4x4 TransMat = TMat4x4.ZeroMat();

            TransMat.SetTrans(X, Y, Z);
            SetMatrix(TransMat);
        }
示例#6
0
        public void GotoNewPosXZ(TVertex NewPos)
        {
            TMat4x4 TransMat = TMat4x4.ZeroMat();
            TMat4x4 RotMatY  = TMat4x4.ZeroMat();

            CurrentPos = NewPos;

            TransMat.SetTrans(NewPos.X, NewPos.Y, NewPos.Z);
            RotMatY.SetRotateY(Math3D.Deg2Rad(Orientation + OrientationOffset));

            SetMatrix(RotMatY.MulMat(TransMat));
        }
示例#7
0
        public void SetMatrix(TMat4x4 Mat)
        {
            ObjectMat = Mat;

            // Transform myself
            CombinedMatrix = ObjectMat.MulMat(GetFatherMat());

            TransformAxis(ObjectMat);

            // Transform all child objects
            for (int i = 0; i < Children.Count; i++)
            {
                ((CObject3D)Children[i]).SetMatrix(((CObject3D)Children[i]).ObjectMat);
            }
        }
示例#8
0
        public void SetPosAndAngle(float X, float Y, float Z, float A, float B, float C)
        {
            TMat4x4 TransMat = TMat4x4.ZeroMat();
            TMat4x4 RotMatX  = TMat4x4.ZeroMat();
            TMat4x4 RotMatY  = TMat4x4.ZeroMat();
            TMat4x4 RotMatZ  = TMat4x4.ZeroMat();

            CurrentPos.Set(X, Y, Z);
            CurrentRot.Set(A, B, C);

            TransMat.SetTrans(X, Y, Z);
            RotMatX.SetRotateX(A);
            RotMatY.SetRotateY(B);
            RotMatZ.SetRotateZ(C);

            SetMatrix(RotMatX.MulMat(RotMatY).MulMat(RotMatZ).MulMat(TransMat));
        }
示例#9
0
        // Constructor
        public CRenderContext(int W, int H)
        {
            VScreen = new Bitmap(W, H);
            ZBuffer = new float[W * H];

            // Prepare graphics canvases for the form and for the virtual screen
            VScreenCanvas = Graphics.FromImage(VScreen);

            BackgroundColor = DEFAULT_BACKGROUND_COLOR;
            PenForWireFrame = new Pen(DEFAULT_PEN_COLOR, 1);
            ViewMatrix      = TMat4x4.UnitMat();

            Width  = W;
            Height = H;

            HalfWidth  = Width / 2;
            HalfHeight = Height / 2;
        }
示例#10
0
        public void Assign(CObject3D CopyFrom)
        {
            ObjectMat = CopyFrom.ObjectMat;

            VertexTable = new TVertex[CopyFrom.VertexTable.Length];
            Array.Copy(CopyFrom.VertexTable, VertexTable, VertexTable.Length);

            FaceTable = new TFace3D[CopyFrom.FaceTable.Length];
            Array.Copy(CopyFrom.FaceTable, FaceTable, FaceTable.Length);

            ObjectMat      = CopyFrom.ObjectMat;
            CombinedMatrix = CopyFrom.CombinedMatrix;

            Children           = CopyFrom.Children;
            ChildrenAxes       = CopyFrom.ChildrenAxes;
            Father             = CopyFrom.Father;
            OriginalAxisPointA = CopyFrom.OriginalAxisPointA;
            OriginalAxisPointB = CopyFrom.OriginalAxisPointB;
        }
示例#11
0
 public void SetViewMat(TMat4x4 Mat)
 {
     ViewMatrix = Mat;
 }
示例#12
0
        // Perform rendering on a specific context
        public void Render(CRenderContext Context)
        {
            if (!Visible)
            {
                return;
            }

            // Calculate transform matrix
            TMat4x4 Mat = GetTransformMatrix(Context);

            // Calculate the inverse matrix
            TMat4x4 InverseMat = Mat.FindInverseMat();

            // Clear translation effect
            InverseMat.ClearTranslation();

            // Calculate the viewer position in object coordinates
            TVertex ViewDirection = Context.GetViewDirection();

            TVertex ViewerPosInObjCoords = InverseMat.MulVertex(ViewDirection);

            float PerspectiveFactor = Context.GetPerspectiveFactor();

            Color IlluminatedFaceColor;

            foreach (TFace3D Face in FaceTable)
            {
                bool  FaceVisible;
                float FaceDotProd = 0;

                if (!Context.IsBackfaceCullingMode())
                {
                    // No backface culling, the face is always visible
                    FaceVisible = true;
                }
                else
                {
                    // Do backface culling
                    FaceDotProd = Math3D.DotProduct(ViewerPosInObjCoords, Face.Normal);

                    // Perspective mode
                    if (Context.IsPerspectiveMode())
                    {
                        // Remember if the face is visible
                        FaceVisible = (FaceDotProd > THRESHOLD_FOR_CULLING);
                    }
                    else
                    {
                        FaceVisible = (FaceDotProd > 0);
                    }
                }

                if (FaceVisible)
                {
                    // Get current face vertices and transform to world coordinates
                    TVertex[] FaceVertex = new TVertex[3] {
                        Mat.MulVertex(VertexTable[Face.AIndex]),
                        Mat.MulVertex(VertexTable[Face.BIndex]),
                        Mat.MulVertex(VertexTable[Face.CIndex])
                    };

                    Point[] ScreenCoords = new Point[3];

                    if (TestForBackClipping(FaceVertex[0], FaceVertex[1], FaceVertex[2]))
                    {
                        bool PreventFaceDraw = false;

                        // Perspective mode
                        if (Context.IsPerspectiveMode())
                        {
                            // Transform the from world coordinates to screen coordinates
                            for (int i = 0; i < 3; i++)
                            {
                                if (Math.Abs(FaceVertex[i].Z) < POLYGON_Z_MIN_VALUE)
                                {
                                    PreventFaceDraw = true;
                                    break;
                                }

                                ScreenCoords[i].X = (int)(FaceVertex[i].X * PerspectiveFactor / FaceVertex[i].Z);
                                ScreenCoords[i].Y = (int)(FaceVertex[i].Y * PerspectiveFactor / FaceVertex[i].Z);

                                if ((Math.Abs(ScreenCoords[i].X) > POLYGON_COORD_MAX_VALUE) || (Math.Abs(ScreenCoords[i].Y) > POLYGON_COORD_MAX_VALUE))
                                {
                                    PreventFaceDraw = true;
                                    break;
                                }
                            }
                        }
                        else
                        // Orthogonal projection
                        {
                            PreventFaceDraw = false;

                            // Transform the from world coordinates to screen coordinates
                            for (int i = 0; i < 3; i++)
                            {
                                ScreenCoords[i].X = (int)(FaceVertex[i].X / ORTHO_PROJECTION_SCALING);
                                ScreenCoords[i].Y = (int)(FaceVertex[i].Y / ORTHO_PROJECTION_SCALING);
                            }
                        }

                        if (!PreventFaceDraw)
                        {
                            T2DTriangle ScreenTriangle = new T2DTriangle(ScreenCoords[0], ScreenCoords[1], ScreenCoords[2]);

                            if (Context.IsWireFrameMode())
                            {
                                Context.DrawTriangle(ScreenTriangle);
                            }
                            else
                            // Filled triangles mode
                            {
                                float LightLevel = FaceDotProd + MIN_LIGHT_LEVEL;

                                // Clip to maximum light level
                                if (LightLevel > 1.0)
                                {
                                    LightLevel = 1.0f;
                                }

                                // Calculate face color
                                int ARGBColor = ClipColorChn(Face.Color.R, LightLevel);
                                ARGBColor |= ClipColorChn(Face.Color.G, LightLevel) << 8;
                                ARGBColor |= ClipColorChn(Face.Color.B, LightLevel) << 16;

                                // Set maximum alpha channel value
                                ARGBColor = (int)((uint)ARGBColor | 0xff000000);

                                IlluminatedFaceColor = Color.FromArgb(ARGBColor);

                                // Calculate factors for the polygon filling routine
                                TVertex FaceNormal = Math3D.CalcFaceNormal(FaceVertex[0], FaceVertex[1], FaceVertex[2]);

                                float M, N, K;
                                CalculatePolygonFactors(FaceNormal, FaceVertex[1], PerspectiveFactor, out M, out N, out K);
                                TriangleFiller.DrawFilledTriangle(ScreenTriangle, Context, IlluminatedFaceColor, M, N, K);
                            }
                        }
                    }
                }
            }

            RenderChildObjects(Context);
        }
示例#13
0
 private void TransformAxis(TMat4x4 Mat)
 {
     TransformedAxisPointA = Mat.MulVertex(OriginalAxisPointA);
     TransformedAxisPointB = Mat.MulVertex(OriginalAxisPointB);
 }
示例#14
0
        public TMat4x4 FindInverseMat()
        {
            float Det;

            float[,] C = new float[4, 4];

            C[0, 0] = m11 * (m22 * m33 - m23 * m32) -
                      m12 * (m21 * m33 - m23 * m31) +
                      m13 * (m21 * m32 - m22 * m31);

            C[0, 1] = -(m10 * (m22 * m33 - m23 * m32) -
                        m12 * (m20 * m33 - m23 * m30) +
                        m13 * (m20 * m32 - m22 * m30));

            C[0, 2] = m10 * (m21 * m33 - m23 * m31) -
                      m11 * (m20 * m33 - m23 * m30) +
                      m13 * (m20 * m31 - m21 * m30);

            C[0, 3] = 0;
            C[1, 0] = -(m01 * (m22 * m33 - m23 * m32) -
                        m02 * (m21 * m33 - m23 * m31) +
                        m03 * (m21 * m32 - m22 * m31));

            C[1, 1] = m00 * (m22 * m33 - m23 * m32) -
                      m02 * (m20 * m33 - m23 * m30) +
                      m03 * (m20 * m32 - m22 * m30);

            C[1, 2] = -(m00 * (m21 * m33 - m23 * m31) -
                        m01 * (m20 * m33 - m23 * m30) +
                        m03 * (m20 * m31 - m21 * m30));

            C[1, 3] = 0;
            C[2, 0] = m01 * (m12 * m33 - m13 * m32) -
                      m02 * (m11 * m33 - m13 * m31) +
                      m03 * (m11 * m32 - m12 * m31);

            C[2, 1] = -(m00 * (m12 * m33 - m13 * m32) -
                        m02 * (m10 * m33 - m13 * m30) +
                        m03 * (m10 * m32 - m12 * m30));

            C[2, 2] = m00 * (m11 * m33 - m13 * m31) -
                      m01 * (m10 * m33 - m13 * m30) +
                      m03 * (m10 * m31 - m11 * m30);

            C[2, 3] = 0;
            C[3, 0] = -(m01 * (m12 * m23 - m13 * m22) -
                        m02 * (m11 * m23 - m13 * m21) +
                        m03 * (m11 * m22 - m12 * m21));

            C[3, 1] = m00 * (m12 * m23 - m13 * m22) -
                      m02 * (m10 * m23 - m13 * m20) +
                      m03 * (m10 * m22 - m12 * m20);

            C[3, 2] = -(m00 * (m11 * m23 - m13 * m21) -
                        m01 * (m10 * m23 - m13 * m20) +
                        m03 * (m10 * m21 - m11 * m20));

            C[3, 3] = m00 * (m11 * m22 - m12 * m21) -
                      m01 * (m10 * m22 - m12 * m20) +
                      m02 * (m10 * m21 - m11 * m20);

            Det = 0;

            // Create a temporary array in order to ease calculations
            float[,] TmpM = ConvertToArray();

            for (int i = 0; i < 4; i++)
            {
                Det += TmpM[0, i] * C[0, i];
            }

            float[,] Result = new float[4, 4];

            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    Result[i, j] = C[j, i] / Det;
                }
            }

            Result[3, 3] = 1;

            for (int i = 0; i < 4; i++)
            {
                Result[i, 3] = 0;
                Result[3, i] = 0;

                for (int j = 0; j < 4; j++)
                {
                    Result[3, i] = Result[3, i] + TmpM[3, j] * Result[j, i];
                }

                Result[3, i] = -Result[3, i];
            }

            TMat4x4 InverseMat = ZeroMat();

            InverseMat.ConvertFromArray(Result);

            return(InverseMat);
        }
示例#15
0
        // Set rotation matrix around arbitrary axis
        public void SetArbitraryRot(TVertex P1, TVertex P2, float Angle)
        {
            TMat4x4 MTra = ZeroMat(), MRo_X = ZeroMat(), MRo_Y = ZeroMat(), MRo_Z = ZeroMat(), TempM = ZeroMat();
            float   D;

            // Find the direction cosines of the arbitrary axis P1-->P2 .
            // The direction cosines will be in C
            TVertex C = Math3D.CalcNormalizedVec(P1, P2);

            D = (float)Math.Sqrt(Math3D.Sqr(C.Y) + Math3D.Sqr(C.Z));

            // Special case for the X axis
            if (D == 0)
            {
                MTra.SetTrans(-P1.X, -P1.Y, -P1.Z);
                MRo_X.SetRotateX(Angle);

                TempM = MTra.MulMat(MRo_X);

                MTra.SetTrans(P1.X, P1.Y, P1.Z);

                this = TempM.MulMat(MTra);
            }
            else
            {
                MTra.SetTrans(-P1.X, -P1.Y, -P1.Z);

                // Prepare matrix rotation about axis X with angle Alfa Cos(Alfa) = C.z / D Sin(Alfa) = C.y / D }
                MRo_X.SetUnit();
                MRo_X.m11 = C.Z / D;
                MRo_X.m22 = MRo_X.m11;
                MRo_X.m12 = C.Y / D;
                MRo_X.m21 = -MRo_X.m12;

                // prepare matrix rotation about axis Y with angle Beta Cos(Beta) =  D     Sin(Beta) = -C.x
                MRo_Y.SetUnit();
                MRo_Y.m00 = D;
                MRo_Y.m22 = MRo_Y.m00;
                MRo_Y.m02 = C.X;
                MRo_Y.m20 = -MRo_Y.m02;

                TMat4x4 M;

                // M= Trans * Rot about axis X * Rot about axis Y
                TempM = MTra.MulMat(MRo_X);
                M     = TempM.MulMat(MRo_Y);

                // prepare matrix rotation about axis Z with angle Angle
                MRo_Z.SetRotateZ(Angle);

                // TempM= Trans * Rot axis X * Rot axis Y * Rot about axis Z by angle Angle
                TempM = M.MulMat(MRo_Z);

                // Find inverse Y matrix
                MRo_Y.m00 = D;
                MRo_Y.m22 = D;
                MRo_Y.m02 = -C.X;
                MRo_Y.m20 = C.X;

                M = TempM.MulMat(MRo_Y);

                // Find inverse x matrix
                MRo_X.m11 = C.Z / D;
                MRo_X.m22 = MRo_X.m11;
                MRo_X.m21 = C.Y / D;
                MRo_X.m12 = -MRo_X.m21;

                TempM = M.MulMat(MRo_X);

                // Find inverse translation matrix
                MTra.SetTrans(P1.X, P1.Y, P1.Z);

                this = TempM.MulMat(MTra);
            }
        }