Example #1
0
        public static void TR_GenMesh(World world, int mesh_index, BaseMesh mesh, Level tr)
        {
            var texMask = world.EngineVersion == Loader.Engine.TR4 ? TextureIndexMaskTr4 : TextureIndexMask;

            /* TR WAD FORMAT DOCUMENTATION!
             * tr4_face[3,4]_t:
             * flipped texture & 0x8000 (1 bit  ) - horizontal flipping.
             * shape texture   & 0x7000 (3 bits ) - texture sample shape.
             * index texture   & $0FFF  (12 bits) - texture sample index.
             *
             * if bit [15] is set, as in ( texture and $8000 ), it indicates that the texture
             * sample must be flipped horizontally prior to be used.
             * Bits [14..12] as in ( texture and $7000 ), are used to store the texture
             * shape, given by: ( texture and $7000 ) shr 12.
             * The valid values are: 0, 2, 4, 6, 7, as assigned to a square starting from
             * the top-left corner and going clockwise: 0, 2, 4, 6 represent the positions
             * of the square angle of the triangles, 7 represents a quad.
             */

            var trMesh = tr.Meshes[mesh_index];
            mesh.ID = (uint)mesh_index;
            mesh.Center.X = trMesh.Centre.X;
            mesh.Center.Y = trMesh.Centre.Z;
            mesh.Center.Z = trMesh.Centre.Y;
            mesh.Radius = trMesh.CollisionSize;
            mesh.TexturePageCount = world.TextureAtlas.NumAtlasPages + 1;

            mesh.Vertices.Resize(trMesh.Vertices.Length, () => new Vertex());
            for (var i = 0; i < mesh.Vertices.Count; i++)
            {
                mesh.Vertices[i].Position = trMesh.Vertices[i].ToVector3();
                mesh.Vertices[i].Normal = Vector3.Zero; // paranoid
            }
            
            mesh.FindBB();

            mesh.Polygons.Clear();

            // textured triangles
            foreach (var face3 in trMesh.TexturedTriangles)
            {
                var p = new Polygon();

                var tex = tr.ObjectTextures[face3.Texture & texMask];

                p.DoubleSide = face3.Texture >> 15 != 0; // CORRECT, BUT WRONG IN TR3-5

                SetAnimTexture(p, (uint)face3.Texture & texMask, world);

                p.BlendMode = face3.Lighting.HasFlagUns(0x01) ? BlendingMode.Multiply : tex.TransparencyFlags;

                tr_accumulateNormals(trMesh, mesh, 3, face3.Vertices, p);
                tr_setupTexturedFace(trMesh, mesh, face3.Vertices, p);

                world.TextureAtlas.GetCoordinates((uint) face3.Texture & texMask, false, p);

                mesh.Polygons.Add(p);
            }

            // coloured triangles
            foreach (var face3 in trMesh.ColouredTriangles)
            {
                var p = new Polygon();

                var col = face3.Texture & 0xff;
                p.TexIndex = (ushort)world.TextureAtlas.NumAtlasPages;
                p.BlendMode = BlendingMode.Opaque;
                p.AnimID = 0;

                tr_accumulateNormals(trMesh, mesh, 3, face3.Vertices, p);
                tr_setupColoredFace(trMesh, tr, mesh, face3.Vertices, col, p);

                mesh.Polygons.Add(p);
            }

            // textured rectangles
            foreach (var face4 in trMesh.TexturedRectangles)
            {
                var p = new Polygon();

                var tex = tr.ObjectTextures[face4.Texture & texMask];

                p.DoubleSide = face4.Texture >> 15 != 0; // CORRECT, BUT WRONG IN TR3-5

                SetAnimTexture(p, (uint)face4.Texture & texMask, world);

                p.BlendMode = face4.Lighting.HasFlagUns(0x01) ? BlendingMode.Multiply : tex.TransparencyFlags;

                tr_accumulateNormals(trMesh, mesh, 4, face4.Vertices, p);
                tr_setupTexturedFace(trMesh, mesh, face4.Vertices, p);

                world.TextureAtlas.GetCoordinates((uint)face4.Texture & texMask, false, p);

                mesh.Polygons.Add(p);
            }

            // coloured rectangles
            foreach (var face4 in trMesh.ColouredRectangles)
            {
                var p = new Polygon();

                var col = face4.Texture & 0xff;
                p.TexIndex = (ushort)world.TextureAtlas.NumAtlasPages;
                p.BlendMode = BlendingMode.Opaque;
                p.AnimID = 0;

                tr_accumulateNormals(trMesh, mesh, 4, face4.Vertices, p);
                tr_setupColoredFace(trMesh, tr, mesh, face4.Vertices, col, p);

                mesh.Polygons.Add(p);
            }

            // let us normalise normals %)
            foreach (var v in mesh.Vertices)
            {
                v.Normal = v.Normal.SafeNormalize();
            }

            // triangles
            var j = 0;
            for (var i = 0; i < trMesh.TexturedTriangles.Length; i++, j++)
            {
                tr_copyNormals(mesh.Polygons[j], mesh, trMesh.TexturedTriangles[i].Vertices);
            }

            for (var i = 0; i < trMesh.ColouredTriangles.Length; i++, j++)
            {
                tr_copyNormals(mesh.Polygons[j], mesh, trMesh.ColouredTriangles[i].Vertices);
            }

            // triangles
            for (var i = 0; i < trMesh.TexturedRectangles.Length; i++, j++)
            {
                tr_copyNormals(mesh.Polygons[j], mesh, trMesh.TexturedRectangles[i].Vertices);
            }

            for (var i = 0; i < trMesh.ColouredRectangles.Length; i++, j++)
            {
                tr_copyNormals(mesh.Polygons[j], mesh, trMesh.ColouredRectangles[i].Vertices);
            }

            mesh.Vertices.Clear();
            mesh.GenFaces();
            mesh.PolySortInMesh();
        }
Example #2
0
        public void GenMesh(World world, uint roomID, Level tr)
        {
            var texMask = world.EngineVersion == Loader.Engine.TR4 ? TextureIndexMaskTr4 : TextureIndexMask;

            var trRoom = tr.Rooms[roomID];

            if(trRoom.Triangles.Length == 0 && trRoom.Rectangles.Length == 0)
            {
                Mesh = null;
                return;
            }

            Mesh = new BaseMesh
            {
                ID = roomID,
                TexturePageCount = world.TextureAtlas.NumAtlasPages + 1,
                UsesVertexColors = true // This is implicitly true on room meshes
            };

            Mesh.Vertices.Resize(trRoom.Vertices.Length, () => new Vertex());
            for (var i = 0; i < Mesh.Vertices.Count; i++)
            {
                Mesh.Vertices[i].Position = trRoom.Vertices[i].Vertex.ToVector3();
                Mesh.Vertices[i].Normal = Vector3.Zero; // paranoid
            }

            Mesh.FindBB();

            Mesh.Polygons.Resize(trRoom.Triangles.Length + trRoom.Rectangles.Length, () => new Polygon());
            var p = 0;

            // triangles
            for (var i = 0; i < trRoom.Triangles.Length; i++, p++)
            {
                tr_setupRoomVertices(world, tr, trRoom, Mesh, 3, trRoom.Triangles[i].Vertices,
                    (ushort)(trRoom.Triangles[i].Texture & texMask), Mesh.Polygons[p]);
                Mesh.Polygons[p].DoubleSide = (trRoom.Triangles[i].Texture & 0x8000) != 0;
            }

            // rectangles
            for (var i = 0; i < trRoom.Rectangles.Length; i++, p++)
            {
                tr_setupRoomVertices(world, tr, trRoom, Mesh, 4, trRoom.Rectangles[i].Vertices,
                    (ushort)(trRoom.Rectangles[i].Texture & texMask), Mesh.Polygons[p]);
                Mesh.Polygons[p].DoubleSide = (trRoom.Rectangles[i].Texture & 0x8000) != 0;
            }

            // let us normalise normals %)
            foreach (var v in Mesh.Vertices)
            {
                v.Normal = v.Normal.SafeNormalize();
            }

            p = 0;
            // triangles
            for (var i = 0; i < trRoom.Triangles.Length; i++, p++)
            {
                tr_copyNormals(Mesh.Polygons[p], Mesh, trRoom.Triangles[i].Vertices);
            }

            // rectangles
            for (var i = 0; i < trRoom.Rectangles.Length; i++, p++)
            {
                tr_copyNormals(Mesh.Polygons[p], Mesh, trRoom.Rectangles[i].Vertices);
            }

            Mesh.Vertices.Clear();
            Mesh.GenFaces();
            Mesh.PolySortInMesh();
        }