Ejemplo n.º 1
0
        /// <summary>
        /// 绘制三角形
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="p3"></param>
        /// <param name="mvp"></param>
        private void DrawTriangle(CVertex p1, CVertex p2, CVertex p3, CMatrix4x4 m, CMatrix4x4 v, CMatrix4x4 p)
        {
            //--------------------几何阶段---------------------------
            //变换到齐次裁剪空
            SetMVPTransform(m, v, p, p1);
            SetMVPTransform(m, v, p, p2);
            SetMVPTransform(m, v, p, p3);

            ////裁剪
            if (Clip(p1) == false || Clip(p2) == false || Clip(p3) == false)
            {
                return;
            }
            //背面消隐
            //if (BackFaceCulling(p1, p2, p3) == false)
            //{
            //    return;
            //}
            //变换到屏幕坐标
            TransformToScreen(p1);
            VectorMatrixTestCase.showVector3(p1.point);
            TransformToScreen(p2);
            VectorMatrixTestCase.showVector3(p2.point);
            TransformToScreen(p3);
            VectorMatrixTestCase.showVector3(p3.point);

            //--------------------光栅化阶段---------------------------
            //todo test
            //_frameBuff.SetPixel((int)p1.point.x, (int)p1.point.y, System.Drawing.Color.White);
            //_frameBuff.SetPixel((int)p2.point.x, (int)p2.point.y, System.Drawing.Color.White);
            //_frameBuff.SetPixel((int)p3.point.x, (int)p3.point.y, System.Drawing.Color.White);

            TriangleRasterization(p1, p2, p3);
        }
Ejemplo n.º 2
0
 private void Draw(CMatrix4x4 m, CMatrix4x4 v, CMatrix4x4 p)
 {
     DrawPanel(0, 1, 2, 3, m, v, p);
     DrawPanel(4, 5, 6, 7, m, v, p);
     DrawPanel(0, 4, 5, 1, m, v, p);
     DrawPanel(1, 5, 6, 2, m, v, p);
     DrawPanel(2, 6, 7, 3, m, v, p);
     DrawPanel(3, 7, 4, 0, m, v, p);
 }
Ejemplo n.º 3
0
 public static void showMat(CMatrix4x4 mat)
 {
     if (isEnable)
     {
         for (int i = 0; i < 4; i++)
         {
             Console.WriteLine("[{0},{1},{2},{3}]", mat[i, 0], mat[i, 1], mat[i, 2], mat[i, 3]);
         }
     }
 }
Ejemplo n.º 4
0
        /// <summary>
        /// 绘制平面
        /// </summary>
        /// <param name="vIndex1">顶点索引</param>
        /// <param name="vIndex2">顶点索引</param>
        /// <param name="vIndex3">顶点索引</param>
        /// <param name="vIndex4">顶点索引</param>
        /// <param name="mvp">mvp矩阵</param>
        private void DrawPanel(int vIndex1, int vIndex2, int vIndex3, int vIndex4, CMatrix4x4 m, CMatrix4x4 v, CMatrix4x4 p)
        {
            CVertex p1 = new CVertex(mesh[vIndex1]);
            CVertex p2 = new CVertex(mesh[vIndex2]);
            CVertex p3 = new CVertex(mesh[vIndex3]);

            //
            DrawTriangle(p1, p2, p3, m, v, p);
            p1 = new CVertex(mesh[vIndex1]);
            p3 = new CVertex(mesh[vIndex3]);
            CVertex p4 = new CVertex(mesh[vIndex4]);

            DrawTriangle(p3, p4, p1, m, v, p);
        }
Ejemplo n.º 5
0
        public static void Test()
        {
            CVector3D a = new CVector3D(1, 2, 1, 1);
            CVector3D b = new CVector3D(5, 6, 0, 1);
            CVector3D c = new CVector3D(1, 2, 3, 1);

            float     r1 = CVector3D.Dot(a, b);
            CVector3D r2 = a - b;
            CVector3D r3 = CVector3D.Cross(a, b);

            Console.WriteLine("a dot b:{0}", r1);
            Console.WriteLine("a - b:({0},{1},{2},{3})", r2.x, r2.y, r2.z, r2.w);
            Console.WriteLine("a X b:({0},{1},{2},{3})", r3.x, r3.y, r3.z, r3.w);
            //
            CMatrix4x4 mat1 = new CMatrix4x4(1, 2, 3, 4,
                                             1, 2, 3, 4,
                                             1, 2, 3, 4,
                                             0, 0, 0, 1);
            CMatrix4x4 mat2 = new CMatrix4x4(1, 2, 3, 4,
                                             1, 2, 3, 4,
                                             1, 2, 3, 4,
                                             1, 2, 3, 4);
            CMatrix4x4 mat3 = new CMatrix4x4();

            mat3.Identity();
            CMatrix4x4 mat4 = new CMatrix4x4(1, 0, 0, 0,
                                             0, 1, 0, 0,
                                             0, 0, 1, 0,
                                             1, 2, 3, 1);
            CMatrix4x4 matr1 = mat1 * mat3;

            Console.WriteLine("mat1 * mat3:");
            showMat(matr1);
            CMatrix4x4 matr2 = mat1 * mat2;

            Console.WriteLine("mat1 * mat2:");
            showMat(matr2);
            CVector3D r4 = a * mat1;

            Console.WriteLine("a * mat1:({0},{1},{2},{3})", r4.x, r4.y, r4.z, r4.w);

            CVector3D r5 = a * mat4;

            Console.WriteLine("a * mat4:({0},{1},{2},{3})", r5.x, r5.y, r5.z, r5.w);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// 进行mvp矩阵变换,将顶点变换到齐次裁剪空间
        /// </summary>
        private void SetMVPTransform(CMatrix4x4 m, CMatrix4x4 v, CMatrix4x4 p, CVertex vertex)
        {
            vertex.point = vertex.point * m;
            VectorMatrixTestCase.showVector3(vertex.point);
            vertex.point = vertex.point * v;
            VectorMatrixTestCase.showVector3(vertex.point);
            vertex.point = vertex.point * p;
            VectorMatrixTestCase.showVector3(vertex.point);

            //得到齐次裁剪空间的点 v.point.w 中保存着原来的z(具体是z还是-z要看使用的投影矩阵,我们使用投影矩阵是让w中保存着z)


            //onePerZ 保存1/z,方便之后对1/z关于x’、y’插值得到1/z’
            vertex.onePerZ = 1 / vertex.point.w;
            //校正的推论: s/z、t/z和x’、y’也是线性关系。而我们之前知道1/z和x’、y’是线性关系。则我们得出新的思路:对1/z关于x’、y’插值得到1/z’,然后对s/z、t/z关于x’、y’进行插值得到s’/z’、t’/z’,然后用s’/z’和t’/z’分别除以1/z’,就得到了插值s’和t’
            //这里将需要插值的信息都乘以1/z 得到 s/z和t/z等,方便光栅化阶段进行插值
            vertex.u *= vertex.onePerZ;
            vertex.v *= vertex.onePerZ;
            //
            vertex.color.r *= vertex.onePerZ;
            vertex.color.g *= vertex.onePerZ;
            vertex.color.b *= vertex.onePerZ;
        }
Ejemplo n.º 7
0
 private void timer1_Tick(object sender, EventArgs e)
 {
     lock (_frameBuff)
     {
         ClearBuff();
         CMatrix4x4 m = new CMatrix4x4();
         m.Identity();
         m[3, 2] = 5;
         rot    += 0.1f;
         m       = MathUntil.GetRotateY(rot) * m;
         CMatrix4x4 v = MathUntil.GetView(new CVector3D(0, 0, 0, 1), new CVector3D(0, 0, 1, 1), new CVector3D(0, 1, 0, 1));
         CMatrix4x4 p = MathUntil.GetProjection((float)System.Math.PI / 4, this.MaximumSize.Width / (float)this.MaximumSize.Height, 1f, 500f);
         //
         Draw(m, v, p);
         //
         if (g1 == null)
         {
             g1 = this.CreateGraphics();
         }
         g1.Clear(System.Drawing.Color.Black);
         g1.DrawImage(_frameBuff, 0, 0);
     }
     this.Invalidate();
 }
Ejemplo n.º 8
0
        /// <summary>
        /// Read mesh chunk and buffer infos.
        /// </summary>
        public void LoadData(CR2WFile meshFile)
        {
            // IMPLEMENTED FROM jlouis' witcherconverter
            // http://jlouisb.users.sourceforge.net/
            // https://bitbucket.org/jlouis/witcherconverter

            SBufferInfos bufferInfos = new SBufferInfos();

            // *************** READ CHUNK INFOS ***************
            foreach (var chunk in meshFile.Chunks)
            {
                if (chunk.REDType == "CMesh" && chunk.data is CMesh cmesh)
                {
                    List <SVertexBufferInfos> vertexBufferInfos = new List <SVertexBufferInfos>();
                    SMeshCookedData           meshCookedData    = cmesh.CookedData;


                    var bytes = meshCookedData.RenderChunks.Bytes;
                    using (MemoryStream ms = new MemoryStream(bytes))
                        using (BinaryReader br = new BinaryReader(ms))
                        {
                            var nbBuffers = br.ReadByte();
                            for (uint i = 0; i < nbBuffers; i++)
                            {
                                SVertexBufferInfos buffInfo = new SVertexBufferInfos();

                                br.BaseStream.Position       += 1; // Unknown
                                buffInfo.verticesCoordsOffset = br.ReadUInt32();
                                buffInfo.uvOffset             = br.ReadUInt32();
                                buffInfo.normalsOffset        = br.ReadUInt32();

                                br.BaseStream.Position += 9; // Unknown
                                buffInfo.indicesOffset  = br.ReadUInt32();
                                br.BaseStream.Position += 1; // 0x1D

                                buffInfo.nbVertices     = br.ReadUInt16();
                                buffInfo.nbIndices      = br.ReadUInt32();
                                buffInfo.materialID     = br.ReadByte();
                                br.BaseStream.Position += 2;             // Unknown
                                buffInfo.lod            = br.ReadByte(); // lod ?

                                vertexBufferInfos.Add(buffInfo);
                            }
                        }

                    bufferInfos.indexBufferOffset = meshCookedData.IndexBufferOffset.val;
                    bufferInfos.indexBufferSize   = meshCookedData.IndexBufferSize.val;
                    //bufferInfos.vertexBufferOffset = meshCookedData.vertexBufferOffset.val; //FIXME
                    bufferInfos.vertexBufferSize     = meshCookedData.VertexBufferSize.val;
                    bufferInfos.quantizationOffset.X = meshCookedData.QuantizationOffset.X.val;
                    bufferInfos.quantizationOffset.Y = meshCookedData.QuantizationOffset.Y.val;
                    bufferInfos.quantizationOffset.Z = meshCookedData.QuantizationOffset.Z.val;
                    bufferInfos.quantizationScale.X  = meshCookedData.QuantizationScale.X.val;
                    bufferInfos.quantizationScale.Y  = meshCookedData.QuantizationScale.Y.val;
                    bufferInfos.quantizationScale.Z  = meshCookedData.QuantizationScale.Z.val;

                    if (meshCookedData.BonePositions != null)
                    {
                        foreach (var item in meshCookedData.BonePositions)
                        {
                            Vector3Df pos = new Vector3Df();
                            pos.X = item.X.val;
                            pos.Y = item.Y.val;
                            pos.Z = item.Z.val;
                            bonePositions.Add(pos);
                        }
                    }


                    bufferInfos.verticesBuffer = vertexBufferInfos;
                    CArray <SMeshChunkPacked> meshChunks = cmesh.Chunks;
                    foreach (SMeshChunkPacked meshChunk in meshChunks.Elements)
                    {
                        SMeshInfos meshInfo = new SMeshInfos();

                        meshInfo.numVertices       = meshChunk.NumVertices == null ? 0 : meshChunk.NumVertices.val;
                        meshInfo.numIndices        = meshChunk.NumIndices == null ? 0 : meshChunk.NumIndices.val;
                        meshInfo.numBonesPerVertex = meshChunk.NumBonesPerVertex == null ? (uint)0 : meshChunk.NumBonesPerVertex.val;
                        meshInfo.firstVertex       = meshChunk.FirstVertex == null ? 0 : meshChunk.FirstVertex.val;
                        meshInfo.firstIndex        = meshChunk.FirstIndex == null ? 0 : meshChunk.FirstIndex.val;
                        meshInfo.materialID        = meshChunk.MaterialID == null ? 0 : meshChunk.MaterialID.val;

                        if (meshChunk.VertexType != null)
                        {
                            if (meshChunk.VertexType.WrappedEnum == Enums.EMeshVertexType.MVT_StaticMesh)
                            {
                                meshInfo.vertexType = SMeshInfos.EMeshVertexType.EMVT_STATIC;
                            }
                            else if (meshChunk.VertexType.WrappedEnum == Enums.EMeshVertexType.MVT_SkinnedMesh)
                            {
                                meshInfo.vertexType = SMeshInfos.EMeshVertexType.EMVT_SKINNED;
                            }
                        }

                        CData.meshInfos.Add(meshInfo);
                    }

                    // bone names and matrices
                    CBufferVLQInt32 <CName>      boneNames    = cmesh.BoneNames;
                    CBufferVLQInt32 <CMatrix4x4> bonematrices = cmesh.Bonematrices;
                    CData.boneData.nbBones = (uint)boneNames.elements.Count;
                    for (int i = 0; i < CData.boneData.nbBones; i++)
                    {
                        CName name = boneNames.elements[i];
                        CData.boneData.jointNames.Add(name.Value);

                        CMatrix4x4 cmatrix = bonematrices.elements[i];
                        Matrix     matrix  = new Matrix();
                        for (int j = 0; j < 16; j++)
                        {
                            float value = (cmatrix.fields[j] as CFloat).val;
                            matrix.SetElement(j, value);
                        }
                        CData.boneData.boneMatrices.Add(matrix);
                    }
                }

                else if (chunk.REDType == "CMaterialInstance")
                {
                    CData.materialInstances.Add(chunk.data as CMaterialInstance);
                }
            }

            // *************** READ MESH BUFFER INFOS ***************
            foreach (var meshInfo in CData.meshInfos)
            {
                SVertexBufferInfos vBufferInf = new SVertexBufferInfos();
                uint nbVertices        = 0;
                uint firstVertexOffset = 0;
                uint nbIndices         = 0;
                uint firstIndiceOffset = 0;
                for (int i = 0; i < bufferInfos.verticesBuffer.Count; i++)
                {
                    nbVertices += bufferInfos.verticesBuffer[i].nbVertices;
                    if (nbVertices > meshInfo.firstVertex)
                    {
                        vBufferInf = bufferInfos.verticesBuffer[i];
                        // the index of the first vertex in the buffer
                        firstVertexOffset = meshInfo.firstVertex - (nbVertices - vBufferInf.nbVertices);
                        break;
                    }
                }
                for (int i = 0; i < bufferInfos.verticesBuffer.Count; i++)
                {
                    nbIndices += bufferInfos.verticesBuffer[i].nbIndices;
                    if (nbIndices > meshInfo.firstIndex)
                    {
                        vBufferInf        = bufferInfos.verticesBuffer[i];
                        firstIndiceOffset = meshInfo.firstIndex - (nbIndices - vBufferInf.nbIndices);
                        break;
                    }
                }

                // Load only best LOD
                if (vBufferInf.lod == 1)
                {
                    using (BinaryReader br = new BinaryReader(File.Open(meshFile.FileName + ".1.buffer", FileMode.Open)))
                    {
                        uint vertexSize = 8;
                        if (meshInfo.vertexType == SMeshInfos.EMeshVertexType.EMVT_SKINNED)
                        {
                            vertexSize += meshInfo.numBonesPerVertex * 2;
                        }

                        br.BaseStream.Seek(vBufferInf.verticesCoordsOffset + firstVertexOffset * vertexSize, SeekOrigin.Begin);

                        List <Vertex3D> vertex3DCoords = new List <Vertex3D>();
                        Color           defaultColor   = new Color(255, 255, 255, 255);
                        for (uint i = 0; i < meshInfo.numVertices; i++)
                        {
                            ushort x = br.ReadUInt16();
                            ushort y = br.ReadUInt16();
                            ushort z = br.ReadUInt16();
                            ushort w = br.ReadUInt16();

                            if (meshInfo.vertexType == SMeshInfos.EMeshVertexType.EMVT_SKINNED)
                            {
                                //sr.BaseStream.Seek(meshInfo.numBonesPerVertex * 2, SeekOrigin.Current);
                                byte[] skinningData = new byte[meshInfo.numBonesPerVertex * 2];
                                br.BaseStream.Read(skinningData, 0, (int)meshInfo.numBonesPerVertex * 2);

                                for (uint j = 0; j < meshInfo.numBonesPerVertex; ++j)
                                {
                                    uint  boneId  = skinningData[j];
                                    uint  weight  = skinningData[j + meshInfo.numBonesPerVertex];
                                    float fweight = weight / 255.0f;

                                    if (weight != 0)
                                    {
                                        var vertexSkinningEntry = new W3_DataCache.VertexSkinningEntry();
                                        vertexSkinningEntry.boneId       = boneId;
                                        vertexSkinningEntry.meshBufferId = 0;
                                        vertexSkinningEntry.vertexId     = i;
                                        vertexSkinningEntry.strength     = fweight;
                                        CData.w3_DataCache.vertices.Add(vertexSkinningEntry);
                                    }
                                }
                            }

                            Vertex3D vertex3DCoord = new Vertex3D();
                            vertex3DCoord.Position = new Vector3Df(x, y, z) / 65535f * bufferInfos.quantizationScale + bufferInfos.quantizationOffset;
                            vertex3DCoord.Color    = defaultColor;
                            vertex3DCoords.Add(vertex3DCoord);
                        }

                        br.BaseStream.Seek(vBufferInf.uvOffset + firstVertexOffset * 4, SeekOrigin.Begin);

                        for (int i = 0; i < meshInfo.numVertices; i++)
                        {
                            float uf = br.ReadHalfFloat();
                            float vf = br.ReadHalfFloat();

                            Vertex3D vertex3DCoord = vertex3DCoords[i];
                            vertex3DCoord.TCoords = new Vector2Df(uf, vf);
                            vertex3DCoords[i]     = vertex3DCoord;
                        }

                        // Indices -------------------------------------------------------------------
                        br.BaseStream.Seek(bufferInfos.indexBufferOffset + vBufferInf.indicesOffset + firstIndiceOffset * 2, SeekOrigin.Begin);

                        List <ushort> indices = new List <ushort>();
                        for (int i = 0; i < meshInfo.numIndices; i++)
                        {
                            indices.Add(0);
                        }

                        for (int i = 0; i < meshInfo.numIndices; i++)
                        {
                            ushort index = br.ReadUInt16();

                            // Indice need to be inversed for the normals
                            if (i % 3 == 0)
                            {
                                indices[i] = index;
                            }
                            else if (i % 3 == 1)
                            {
                                indices[i + 1] = index;
                            }
                            else if (i % 3 == 2)
                            {
                                indices[i - 1] = index;
                            }
                        }

                        MeshBuffer meshBuff = MeshBuffer.Create(VertexType.Standard, IndexType._16Bit);
                        meshBuff.Append(vertex3DCoords.ToArray(), indices.ToArray());
                        meshBuff.RecalculateBoundingBox();
                        CData.staticMesh.AddMeshBuffer(meshBuff);
                        meshBuff.Drop();
                    }
                }
            }
        }
Ejemplo n.º 9
0
        static void Main(string[] args)
        {
            CMatrix4x4 temp = new CMatrix4x4(
                new CVector4(10, 5, 3, 7),
                new CVector4(-2, 7, -10, 1),
                new CVector4(0, 3, 1, 6),
                new CVector4(2, -3, 0, -1));

            CMatrix4x4 inv = temp.inverse();

            CMatrix buff = new CMatrix(3, false);

            buff[0][0] = 8.0 / 9; buff[0][1] = 1.0 / 2; buff[0][2] = 1.0 / 3;
            buff[1][0] = 1.0 / 2; buff[1][1] = 1.0 / 3; buff[1][2] = 1.0 / 4;
            buff[2][0] = 1.0 / 3; buff[2][1] = 1.0 / 4; buff[2][2] = 1.0 / 5;

            CEigen res = CEigen.calculate(buff);

            System.Console.WriteLine("T");
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    System.Console.Write(res.vectors[i, j] + " ");
                }
                System.Console.WriteLine();
            }

            System.Console.WriteLine("d");
            for (int i = 0; i < 3; i++)
            {
                System.Console.WriteLine(res.values[i]);
            }

            CVector dx = new CVector(10);

            dx[0] = 3.369;
            dx[1] = 9.999;
            dx[2] = 12;
            dx[3] = 0.00458;
            dx[4] = 398;
            dx[5] = 0.0782;
            dx[6] = 1.596;
            dx[7] = 4.2118;
            dx[8] = 6.2258;
            dx[9] = 0.0795;

            CMatrix ret = dx.multiplyMatrix(dx);

            System.Console.WriteLine("dxdxT");
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    System.Console.Write(ret[i, j] + " ");
                }
                System.Console.WriteLine();
            }

            System.Console.In.ReadToEnd();
        }