Exemple #1
0
    public void Run()
    {
        using (globalLoadMarker.Auto())
        {
            Stopwatch s = Stopwatch.StartNew();
            lightMapPropertyId = Shader.PropertyToID(lightMapProperty);

            // Create a new BSPmap, which is an object that
            // represents the map and all its data as a whole
            using (fileLoadMarker.Auto())
            {
                if (mapIsInsidePK3)
                {
                    map = new BSPMap(mapName, true);
                }
                else
                {
                    string path = Path.Combine(Application.streamingAssetsPath, mapName);
                    map = new BSPMap(path, false);
                }

                s.Stop();
                Debug.Log($"Read map file in {s.ElapsedMilliseconds}ms");
            }

            s.Restart();
            using (facesLoadMarker.Auto())
            {
                // Each face is its own gameobject
                var groups = map.faceLump.faces.GroupBy(x => new { x.type, x.texture, x.lm_index });
                foreach (var group in groups)
                {
                    Face[] faces = group.ToArray();
                    if (faces.Length == 0)
                    {
                        continue;
                    }

                    Material mat = useRippedTextures
                        ? FetchMaterial(map.textureLump.Textures[faces[0].texture].Name, faces[0].lm_index)
                        : fallbackMaterial;

                    switch (group.Key.type)
                    {
                    case 2:
                    {
                        GenerateBezObject(mat, faces);
                        break;
                    }

                    case 1:
                    case 3:
                    {
                        GeneratePolygonObject(mat, faces);
                        break;
                    }

                    default:
                        Debug.Log(
                            $"Skipped face because it was not a polygon, mesh, or bez patch ({group.Key.type}).");
                        break;
                    }
                }

                GC.Collect();
                s.Stop();
                Debug.Log($"Loaded map in {s.ElapsedMilliseconds}ms");
            }


            vertsCache    = new List <Vector3>();
            uvCache       = new List <Vector2>();
            uv2Cache      = new List <Vector2>();
            normalsCache  = new List <Vector3>();
            indiciesCache = new List <int>();
            BezierMesh.ClearCaches();
        }
    }
Exemple #2
0
    // This forms a mesh from a bez patch of your choice
    // from the face of your choice.
    // It's ready to render with tex coords and all.
    Mesh GenerateBezMesh(Face face, int patchNumber)
    {
        //Calculate how many patches there are using size[]
        //There are n_patchesX by n_patchesY patches in the grid, each of those
        //starts at a vert (i,j) in the overall grid
        //We don't actually need to know how many are on the Y length
        //but the forumla is here for historical/academic purposes
        int n_patchesX = ((face.size [0]) - 1) / 2;
        //int n_patchesY = ((face.size[1]) - 1) / 2;

        //Calculate what [n,m] patch we want by using an index
        //called patchNumber  Think of patchNumber as if you
        //numbered the patches left to right, top to bottom on
        //the grid in a piece of paper.
        int pxStep = 0;
        int pyStep = 0;
        for (int i = 0; i < patchNumber; i++)
        {
            pxStep++;
            if (pxStep == n_patchesX)
            {
                pxStep = 0;
                pyStep++;
            }
        }

        //Create an array the size of the grid, which is given by
        //size[] on the face object.
        Vertex[,] vertGrid = new Vertex[face.size [0], face.size [1]];

        //Read the verts for this face into the grid, making sure
        //that the final shape of the grid matches the size[] of
        //the face.
        int gridXstep = 0;
        int gridYstep = 0;
        int vertStep = face.vertex;
        for (int i = 0; i < face.n_vertexes; i++)
        {
            vertGrid [gridXstep, gridYstep] = map.vertexLump.Verts [vertStep];
            vertStep++;
            gridXstep++;
            if (gridXstep == face.size [0])
            {
                gridXstep = 0;
                gridYstep++;
            }
        }

        //We now need to pluck out exactly nine vertexes to pass to our
        //teselate function, so lets calculate the starting vertex of the
        //3x3 grid of nine vertexes that will make up our patch.
        //we already know how many patches are in the grid, which we have
        //as n and m.  There are n by m patches.  Since this method will
        //create one gameobject at a time, we only need to be able to grab
        //one.  The starting vertex will be called vi,vj think of vi,vj as x,y
        //coords into the grid.
        int vi = 2 * pxStep;
        int vj = 2 * pyStep;
        //Now that we have those, we need to get the vert at [vi,vj] and then
        //the two verts at [vi+1,vj] and [vi+2,vj], and then [vi,vj+1], etc.
        //the ending vert will at [vi+2,vj+2]

        List<Vector3> bverts = new List<Vector3>();

        //read texture/lightmap coords while we're at it
        //they will be tessellated as well.
        List<Vector2> uvs = new List<Vector2>();
        List<Vector2> uv2s = new List<Vector2>();

        //Top row
        bverts.Add(vertGrid [vi, vj].position);
        bverts.Add(vertGrid [vi + 1, vj].position);
        bverts.Add(vertGrid [vi + 2, vj].position);

        uvs.Add(vertGrid [vi, vj].texcoord);
        uvs.Add(vertGrid [vi + 1, vj].texcoord);
        uvs.Add(vertGrid [vi + 2, vj].texcoord);

        uv2s.Add(vertGrid [vi, vj].lmcoord);
        uv2s.Add(vertGrid [vi + 1, vj].lmcoord);
        uv2s.Add(vertGrid [vi + 2, vj].lmcoord);

        //Middle row
        bverts.Add(vertGrid [vi, vj + 1].position);
        bverts.Add(vertGrid [vi + 1, vj + 1].position);
        bverts.Add(vertGrid [vi + 2, vj + 1].position);

        uvs.Add(vertGrid [vi, vj + 1].texcoord);
        uvs.Add(vertGrid [vi + 1, vj + 1].texcoord);
        uvs.Add(vertGrid [vi + 2, vj + 1].texcoord);

        uv2s.Add(vertGrid [vi, vj + 1].lmcoord);
        uv2s.Add(vertGrid [vi + 1, vj + 1].lmcoord);
        uv2s.Add(vertGrid [vi + 2, vj + 1].lmcoord);

        //Bottom row
        bverts.Add(vertGrid [vi, vj + 2].position);
        bverts.Add(vertGrid [vi + 1, vj + 2].position);
        bverts.Add(vertGrid [vi + 2, vj + 2].position);

        uvs.Add(vertGrid [vi, vj + 2].texcoord);
        uvs.Add(vertGrid [vi + 1, vj + 2].texcoord);
        uvs.Add(vertGrid [vi + 2, vj + 2].texcoord);

        uv2s.Add(vertGrid [vi, vj + 2].lmcoord);
        uv2s.Add(vertGrid [vi + 1, vj + 2].lmcoord);
        uv2s.Add(vertGrid [vi + 2, vj + 2].lmcoord);

        //Now that we have our control grid, it's business as usual
        Mesh bezMesh = new Mesh();
        bezMesh.name = "BSPfacemesh (bez)";
        BezierMesh bezPatch = new BezierMesh(tessellations, bverts, uvs, uv2s);
        return bezPatch.Mesh;
    }
Exemple #3
0
    // This forms a mesh from a bez patch of your choice
    // from the face of your choice.
    // It's ready to render with tex coords and all.
    private Mesh GenerateBezMesh(Face face, int patchNumber)
    {
        using (generateBezMeshMarker.Auto())
        {
            //Calculate how many patches there are using size[]
            //There are n_patchesX by n_patchesY patches in the grid, each of those
            //starts at a vert (i,j) in the overall grid
            //We don't actually need to know how many are on the Y length
            //but the forumla is here for historical/academic purposes
            int n_patchesX = (face.size[0] - 1) / 2;
            //int n_patchesY = ((face.size[1]) - 1) / 2;


            //Calculate what [n,m] patch we want by using an index
            //called patchNumber  Think of patchNumber as if you
            //numbered the patches left to right, top to bottom on
            //the grid in a piece of paper.
            int pxStep = 0;
            int pyStep = 0;
            for (int i = 0; i < patchNumber; i++)
            {
                pxStep++;
                if (pxStep == n_patchesX)
                {
                    pxStep = 0;
                    pyStep++;
                }
            }

            //Create an array the size of the grid, which is given by
            //size[] on the face object.
            Vertex[,] vertGrid = new Vertex[face.size[0], face.size[1]];

            //Read the verts for this face into the grid, making sure
            //that the final shape of the grid matches the size[] of
            //the face.
            int gridXstep = 0;
            int gridYstep = 0;
            int vertStep  = face.vertex;
            for (int i = 0; i < face.n_vertexes; i++)
            {
                vertGrid[gridXstep, gridYstep] = map.vertexLump.verts[vertStep];
                vertStep++;
                gridXstep++;
                if (gridXstep == face.size[0])
                {
                    gridXstep = 0;
                    gridYstep++;
                }
            }

            //We now need to pluck out exactly nine vertexes to pass to our
            //teselate function, so lets calculate the starting vertex of the
            //3x3 grid of nine vertexes that will make up our patch.
            //we already know how many patches are in the grid, which we have
            //as n and m.  There are n by m patches.  Since this method will
            //create one gameobject at a time, we only need to be able to grab
            //one.  The starting vertex will be called vi,vj think of vi,vj as x,y
            //coords into the grid.
            int vi = 2 * pxStep;
            int vj = 2 * pyStep;
            //Now that we have those, we need to get the vert at [vi,vj] and then
            //the two verts at [vi+1,vj] and [vi+2,vj], and then [vi,vj+1], etc.
            //the ending vert will at [vi+2,vj+2]

            int            capacity = 3 * 3;
            List <Vector3> bverts   = new List <Vector3>(capacity);

            //read texture/lightmap coords while we're at it
            //they will be tessellated as well.
            List <Vector2> uv  = new List <Vector2>(capacity);
            List <Vector2> uv2 = new List <Vector2>(capacity);

            //Top row
            bverts.Add(vertGrid[vi, vj].position);
            bverts.Add(vertGrid[vi + 1, vj].position);
            bverts.Add(vertGrid[vi + 2, vj].position);

            uv.Add(vertGrid[vi, vj].texcoord);
            uv.Add(vertGrid[vi + 1, vj].texcoord);
            uv.Add(vertGrid[vi + 2, vj].texcoord);

            uv2.Add(vertGrid[vi, vj].lmcoord);
            uv2.Add(vertGrid[vi + 1, vj].lmcoord);
            uv2.Add(vertGrid[vi + 2, vj].lmcoord);

            //Middle row
            bverts.Add(vertGrid[vi, vj + 1].position);
            bverts.Add(vertGrid[vi + 1, vj + 1].position);
            bverts.Add(vertGrid[vi + 2, vj + 1].position);

            uv.Add(vertGrid[vi, vj + 1].texcoord);
            uv.Add(vertGrid[vi + 1, vj + 1].texcoord);
            uv.Add(vertGrid[vi + 2, vj + 1].texcoord);

            uv2.Add(vertGrid[vi, vj + 1].lmcoord);
            uv2.Add(vertGrid[vi + 1, vj + 1].lmcoord);
            uv2.Add(vertGrid[vi + 2, vj + 1].lmcoord);

            //Bottom row
            bverts.Add(vertGrid[vi, vj + 2].position);
            bverts.Add(vertGrid[vi + 1, vj + 2].position);
            bverts.Add(vertGrid[vi + 2, vj + 2].position);

            uv.Add(vertGrid[vi, vj + 2].texcoord);
            uv.Add(vertGrid[vi + 1, vj + 2].texcoord);
            uv.Add(vertGrid[vi + 2, vj + 2].texcoord);

            uv2.Add(vertGrid[vi, vj + 2].lmcoord);
            uv2.Add(vertGrid[vi + 1, vj + 2].lmcoord);
            uv2.Add(vertGrid[vi + 2, vj + 2].lmcoord);

            //Now that we have our control grid, it's business as usual
            Mesh bezMesh = new Mesh();
            bezMesh.name = "BSPfacemesh (bez)";
            BezierMesh bezPatch = new BezierMesh(tessellations, bverts, uv, uv2);
            return(bezPatch.Mesh);
        }
    }