コード例 #1
0
        /// <summary>
        /// Adaptar mesh de DirectX a mesh de TGC
        /// </summary>
        public TgcMesh CreateTgcMesh(BspMap bspMap, Mesh mesh, int surfaceId)
        {
            QSurface surface = bspMap.Data.drawSurfaces[surfaceId];

            TgcTexture lightmap = surface.lightmapNum >= 0 ? lightMaps[surface.lightmapNum] : null;

            var texture = textures[surface.shaderNum];

            //asigno el shader si es que tiene
            bspMap.Data.shaderXSurface[surfaceId] = shaderXTextura[surface.shaderNum];
            if (bspMap.Data.shaderXSurface[surfaceId] != null)
            {
                bspMap.Data.shaderXSurface[surfaceId].BuildFx();
            }

            if (texture == null && bspMap.Data.shaderXSurface[surfaceId] != null)
            {
                foreach (QShaderStage stage in bspMap.Data.shaderXSurface[surfaceId].Stages)
                {
                    if (stage.Textures.Count > 0)
                    {
                        texture = stage.Textures[0];
                        break;
                    }
                }
            }


            //Cargar lightMap
            TgcTexture tgcLightMap = lightmap;

            if (lightmap == null)
            {
                tgcLightMap = emptyLightMap;
            }

            TgcTexture[] meshTextures = new TgcTexture[1];
            if (texture != null)
            {
                meshTextures[0] = texture;
            }
            else
            {
                meshTextures[0] = emptyTexture;
            }

            TgcMesh.MeshRenderType renderType = TgcMesh.MeshRenderType.DIFFUSE_MAP_AND_LIGHTMAP;

            Material mat = new Material();

            mat.Ambient = Color.White;

            //Crear mesh de TGC
            TgcMesh tgcMesh = new TgcMesh(mesh, "mesh" + surfaceId, renderType);

            tgcMesh.Materials   = new Material[] { mat };
            tgcMesh.DiffuseMaps = meshTextures;
            tgcMesh.LightMap    = tgcLightMap;
            tgcMesh.Enabled     = true;
            tgcMesh.createBoundingBox();

            return(tgcMesh);
        }
コード例 #2
0
        /// <summary>
        /// Toma una curva de Quake 3 y la convierte a un TgcMesh, mediante el proceso de Tessellation
        /// </summary>
        private void tessellatePatch(BspMap bspMap, int surfaceId)
        {
            // los patch de quake 3 estan formados por curvas de bezier
            // todos los patch tienen 9 puntos que son los puntos de control para la curva
            // Esos puntos hay que tesselarlos para conseguir los triangulos

            int L = 5;

            QSurface surface = bspMap.Data.drawSurfaces[surfaceId];
            int      offVert = surface.firstVert;

            // coeficientes de bezier
            float[,] B = new float[L + 1, 3];

            //Numero de patches de 3x3 en cada direccion
            int num1         = (surface.patchHeight - 1) / 2;
            int num2         = (surface.patchWidth - 1) / 2;
            int cantVertices = (L * num1 + 1) * (L * num2 + 1);
            int cantIndices  = 2 * (L * num2 + 2) * (L * num1);

            //aloco el espacio para los vertices y los indices
            Vector3[] vertices   = new Vector3[cantVertices];
            Vector3[] normals    = new Vector3[cantVertices];
            Vector2[] textCords  = new Vector2[cantVertices];
            Vector2[] textCords2 = new Vector2[cantVertices];
            int[]     indices    = new int[cantIndices];
            {
                //se cargan las constantes de bezier
                float dt = 1.0f / L;
                float t  = 0;
                for (int i = 0; i < L + 1; i++)
                {
                    if (i == L)
                    {
                        t = 1.0f;
                    }
                    float mt = 1 - t;

                    B[i, 0] = mt * mt;
                    B[i, 1] = 2 * mt * t;
                    B[i, 2] = t * t;

                    t += dt;
                }
            }

            //Calculo de los bicubic bezier patch para cada strip
            int pointsXStrip = L * num2 + 1;
            int pointsXPatch = pointsXStrip * L;
            int indexCount   = 0;
            int vertexNum    = 0;

            int[] controls = new int[3]; // subindices a los vertices de puntos de control
            // por cada patch
            for (int i = 0, Li = L; i < num1; i++)
            {
                if (i == num1 - 1)
                {
                    Li = L + 1;
                }

                // seteo los indices
                for (int j = 0; j < L; j++)
                {
                    for (int k = 0; k < pointsXStrip; k++)
                    {
                        indices[indexCount++] = i * pointsXPatch + j * pointsXStrip + k;
                        indices[indexCount++] = i * pointsXPatch + (j + 1) * pointsXStrip + k;
                    }

                    //repito primer y ultimo indice
                    indices[indexCount++] = i * pointsXPatch + (j + 2) * pointsXStrip - 1;
                    indices[indexCount++] = i * pointsXPatch + (j + 1) * pointsXStrip;
                }


                //Ahora van los puntos de control y los vertices
                for (int j = 0, Lj = L; j < num2; j++)
                {
                    if (j == num2 - 1)
                    {
                        Lj = L + 1;
                    }

                    // calculo de los puntos de control para este patch
                    // controls[fila] = indice del primer vertice de la fila de este patch

                    controls[0] = offVert + (i * 2) * (2 * num2 + 1) + (j * 2);
                    controls[1] = offVert + (i * 2 + 1) * (2 * num2 + 1) + (j * 2);
                    controls[2] = offVert + (i * 2 + 2) * (2 * num2 + 1) + (j * 2);

                    //por cada punto en el patch
                    for (int i2 = 0; i2 < Li; i2++)
                    {
                        vertexNum = i * pointsXPatch + i2 * pointsXStrip + j * L;

                        for (int j2 = 0; j2 < Lj; j2++, vertexNum++)
                        {
                            vertices[vertexNum]   = new Vector3();
                            normals[vertexNum]    = new Vector3();
                            textCords[vertexNum]  = new Vector2();
                            textCords2[vertexNum] = new Vector2();

                            for (int i3 = 0; i3 < 3; i3++)
                            {
                                for (int j3 = 0; j3 < 3; j3++)
                                {
                                    float blendFactor = B[i2, i3] * B[j2, j3];
                                    vertices[vertexNum]   += bspMap.Data.drawVerts[controls[i3] + j3].xyz * blendFactor;
                                    normals[vertexNum]    += bspMap.Data.drawVerts[controls[i3] + j3].normal * blendFactor;
                                    textCords[vertexNum]  += bspMap.Data.drawVerts[controls[i3] + j3].st * blendFactor;
                                    textCords2[vertexNum] += bspMap.Data.drawVerts[controls[i3] + j3].lightmap * blendFactor;
                                }
                            }
                        }
                    }
                }
            }


            short[] indexBuffer  = new short[3 * cantIndices - 6];
            int     cant_ibuffer = 0;

            for (int i = 2; i < cantIndices; i++)
            {
                if (i % 2 == 0)
                {
                    indexBuffer[cant_ibuffer++] = (short)indices[i - 2];
                    indexBuffer[cant_ibuffer++] = (short)indices[i - 1];
                    indexBuffer[cant_ibuffer++] = (short)indices[i];
                }
                else
                {
                    indexBuffer[cant_ibuffer++] = (short)indices[i];
                    indexBuffer[cant_ibuffer++] = (short)indices[i - 1];
                    indexBuffer[cant_ibuffer++] = (short)indices[i - 2];
                }
            }

            //Mesh de DirectX
            Mesh mesh = new Mesh(indexBuffer.Length / 3, vertices.Length, MeshFlags.Managed,
                                 TgcSceneLoader.DiffuseMapAndLightmapVertexElements,
                                 GuiController.Instance.D3dDevice);

            //Cargar vertexBuffer
            using (VertexBuffer vb = mesh.VertexBuffer)
            {
                TgcSceneLoader.DiffuseMapAndLightmapVertex[] vertex =
                    new TgcSceneLoader.DiffuseMapAndLightmapVertex[vertices.Length];

                for (int i = 0; i < vertices.Length; i++)
                {
                    vertex[i] = new TgcSceneLoader.DiffuseMapAndLightmapVertex();

                    vertex[i].Position = vertices[i];
                    vertex[i].Normal   = normals[i];           //drawVerts[offVert].normal;
                    vertex[i].Tu0      = textCords[i].X;       //drawVerts[offVert].st.X;
                    vertex[i].Tv0      = textCords[i].Y;       //drawVerts[offVert].st.Y;
                    vertex[i].Tu1      = textCords2[i].X;      //drawVerts[offVert].lightmap.X;
                    vertex[i].Tv1      = textCords2[i].Y;      //drawVerts[offVert].lightmap.Y;
                    vertex[i].Color    = Color.White.ToArgb(); //drawVerts[i].color;

                    vb.SetData(vertex, 0, LockFlags.None);
                }
            }

            //IndexBuffer
            using (IndexBuffer ib = mesh.IndexBuffer)
            {
                ib.SetData(indexBuffer, 0, LockFlags.None);
            }

            //Crea el tgcMesh
            TgcMesh tgcMesh = CreateTgcMesh(bspMap, mesh, surfaceId);

            bspMap.Meshes.Add(tgcMesh);
        }
コード例 #3
0
        /// <summary>
        /// Carga todos los meshes
        /// </summary>
        private void CreateMeshes(BspMap bspMap)
        {
            Device device = GuiController.Instance.D3dDevice;

            for (int id = 0; id < bspMap.Data.drawSurfaces.Length; id++)
            {
                QSurface surface = bspMap.Data.drawSurfaces[id];

                //Crear Patch (curva=
                if (surface.surfaceType == QMapSurfaceType.Patch)
                {
                    tessellatePatch(bspMap, id);
                    continue;
                }

                /* billboards, no soportados actualmente
                 * if (surface.surfaceType == QMapSurfaceType.Flare)
                 * {
                 *
                 * }
                 */

                //Superficies no soportadas
                if (surface.surfaceType != QMapSurfaceType.Planar && surface.surfaceType != QMapSurfaceType.TriangleSoup)
                {
                    //Agregar null para no mover todos los índices
                    bspMap.Meshes.Add(null);
                    continue;
                }

                //Cargar superficies soportadas: de tipo QMapSurfaceType.Planar o QMapSurfaceType.TriangleSoup

                int cant_indices  = surface.numIndexes;
                int cant_vertices = surface.numVerts;


                if (cant_vertices <= 0)
                {
                    continue;
                }

                //Mesh de DirectX
                Mesh mesh = new Mesh(cant_indices / 3, cant_vertices, MeshFlags.Managed, TgcSceneLoader.DiffuseMapAndLightmapVertexElements, device);

                //Cargar vertexBuffer
                using (VertexBuffer vb = mesh.VertexBuffer)
                {
                    TgcSceneLoader.DiffuseMapAndLightmapVertex[] vertices = new TgcSceneLoader.DiffuseMapAndLightmapVertex[cant_vertices];

                    int j = 0;
                    for (int i = surface.firstVert; i < surface.firstVert + surface.numVerts; i++, j++)
                    {
                        vertices[j] = new TgcSceneLoader.DiffuseMapAndLightmapVertex();

                        vertices[j].Position = bspMap.Data.drawVerts[i].xyz;
                        vertices[j].Normal   = bspMap.Data.drawVerts[i].normal;
                        vertices[j].Tu0      = bspMap.Data.drawVerts[i].st.X;
                        vertices[j].Tv0      = bspMap.Data.drawVerts[i].st.Y;
                        vertices[j].Tu1      = bspMap.Data.drawVerts[i].lightmap.X;
                        vertices[j].Tv1      = bspMap.Data.drawVerts[i].lightmap.Y;
                        vertices[j].Color    = Color.White.ToArgb();//drawVerts[i].color;
                    }

                    vb.SetData(vertices, 0, LockFlags.None);
                }

                using (IndexBuffer ib = mesh.IndexBuffer)
                {
                    short[] indices = new short[cant_indices];
                    int     j       = 0;
                    for (int i = surface.firstIndex; i < surface.firstIndex + surface.numIndexes; i++, j++)
                    {
                        indices[j] = (short)bspMap.Data.drawIndexes[i];
                    }
                    ib.SetData(indices, 0, LockFlags.None);
                }


                //Crea el tgcMesh
                TgcMesh tgcMesh = CreateTgcMesh(bspMap, mesh, id);
                bspMap.Meshes.Add(tgcMesh);
            }
        }