Beispiel #1
0
    BSPMesh CreateMesh(GEOMETRY_T geometry, face_id_list_t face_ids, MIPTEX_DIRECTORY_ENTRY_T miptex_entry)
    {
        var faces = geometry.faces;

        // get number of triangles required to build model
        var num_tris = 0;

        for (var i = 0; i < face_ids.length; ++i)
        {
            var face = faces[face_ids[i]];
            num_tris += face.num_edges - 2;
        }

        var verts     = new Vector3[num_tris * 3]; // 3 vertices, xyz per tri
        var uvs       = new Vector2[num_tris * 3]; // 3 uvs, uv per tri
        var verts_ofs = 0;

        for (var i = 0; i < face_ids.length; ++i)
        {
            var face = faces[face_ids[i]];
            verts_ofs = this.addFaceVerts(geometry, face, verts, uvs, verts_ofs, miptex_entry);
        }

        return(new BSPMesh(verts, uvs));
    }
Beispiel #2
0
    Hash <UInt32, face_id_list_t> getFaceIdsPerTexture(GEOMETRY_T geometry, dmodel_t model)
    {
        var texinfos = geometry.texinfos;
        var faces    = geometry.faces;

        var face_id_lists = new Hash <UInt32, face_id_list_t>(); // important to note that this is a hash

        var start = model.face_id;
        var end   = start + model.num_faces;

        for (var i = start; i < end; ++i)
        {
            var face     = faces[i];
            var tex_id   = texinfos[face.texinfo_id].tex_id;
            var face_ids = face_id_lists[tex_id];
            if (face_ids == null)
            {
                face_ids = new face_id_list_t();
            }

            face_ids[face_ids.length] = i;
            face_id_lists[tex_id]     = face_ids;
        }

        return(face_id_lists);
    }
Beispiel #3
0
    BSPModel CreateModel(ref GEOMETRY_T geometry, dmodel_t model)
    {
        var face_id_lists = this.getFaceIdsPerTexture(geometry, model);
        var geometries    = new List <BSPModelGeometry>();
        var faces         = new List <BSPFace>();

        foreach (var i in face_id_lists.sortedKeys)
        {
            var miptex_entry = this.miptex_directory[i];
            var face_ids     = face_id_lists[i];

            foreach (var face_id in face_ids)
            {
                faces.Add(this.faces[face_id]);
            }

            var mesh = this.CreateMesh(geometry, face_ids, miptex_entry);
            geometries.Add(new BSPModelGeometry(i, mesh, faces.ToArray()));

            faces.Clear();
        }

        var result = new BSPModel(geometries.ToArray(), faces.ToArray());

        result.origin   = TransformVector(model.origin);
        result.boundbox = TransformBoundbox(model.bbox);
        return(result);
    }
Beispiel #4
0
    int addFaceVerts(GEOMETRY_T geometry, dface_t face, Vector3[] verts, Vector2[] uvs, int verts_ofs, MIPTEX_DIRECTORY_ENTRY_T miptex_entry)
    {
        var edge_list  = geometry.edge_list;
        var edges      = geometry.edges;
        var vertices   = geometry.vertices;
        var texinfo    = geometry.texinfos[face.texinfo_id];
        var tex_width  = miptex_entry.width;
        var tex_height = miptex_entry.height;

        var vert_ids = new DynamicArray <int>();
        var start    = face.edge_id;
        var end      = start + face.num_edges;


        int i;

        for (i = start; i < end; ++i)
        {
            var edge_id = edge_list[i];
            var edge    = edges[Math.Abs(edge_id)];
            if (edge_id > 0)
            {
                vert_ids[vert_ids.length] = edge.v1;
            }
            else
            {
                vert_ids[vert_ids.length] = edge.v2;
            }
        }

        var num_tris = vert_ids.length - 2;

        for (i = 0; i < num_tris; ++i)
        {
            // reverse winding order to have correct normals
            var c = vert_ids[0];
            var b = vert_ids[i + 1];
            var a = vert_ids[i + 2];

            int     vi   = (verts_ofs + i) * 3;
            int     uvi  = (verts_ofs + i) * 3;
            Vector3 vert = vertices[a];
            verts[vi]  = vert;
            uvs[uvi].x = (Vector3.Dot(vert, texinfo.vec_s) + texinfo.dist_s) / tex_width;
            uvs[uvi].y = -(Vector3.Dot(vert, texinfo.vec_t) + texinfo.dist_t) / tex_height;

            vert           = vertices[b];
            verts[vi + 1]  = vert;
            uvs[uvi + 1].x = (Vector3.Dot(vert, texinfo.vec_s) + texinfo.dist_s) / tex_width;
            uvs[uvi + 1].y = -(Vector3.Dot(vert, texinfo.vec_t) + texinfo.dist_t) / tex_height;

            vert           = vertices[c];
            verts[vi + 2]  = vert;
            uvs[uvi + 2].x = (Vector3.Dot(vert, texinfo.vec_s) + texinfo.dist_s) / tex_width;
            uvs[uvi + 2].y = -(Vector3.Dot(vert, texinfo.vec_t) + texinfo.dist_t) / tex_height;
        }

        return(verts_ofs + i); // next position in verts
    }
Beispiel #5
0
    BSPModel[] CreateModels(GEOMETRY_T geometry)
    {
        var models = new BSPModel[geometry.models.Length];

        for (var i = 0; i < geometry.models.Length; ++i)
        {
            models[i] = this.CreateModel(ref geometry, geometry.models[i]);
        }
        return(models);
    }
Beispiel #6
0
    Vector3[] getVertices(GEOMETRY_T geometry, dface_t face)
    {
        // get number of triangles required to build model
        var num_tris = face.num_edges - 2;

        var verts = new Vector3[num_tris * 3]; // 3 vertices, xyz per tri

        this.getVertices(geometry, face, verts);

        return(verts);
    }
Beispiel #7
0
    BSPFace[] CreateFaces(GEOMETRY_T geometry)
    {
        var faces = geometry.faces;

        var collisions = new BSPFace[faces.Length];

        for (int i = 0; i < faces.Length; ++i)
        {
            var vertices = getVertices(geometry, faces[i]);
            collisions[i] = new BSPFace(i, vertices);
        }
        return(collisions);
    }
Beispiel #8
0
    void getVertices(GEOMETRY_T geometry, dface_t face, Vector3[] verts)
    {
        var edge_list = geometry.edge_list;
        var edges     = geometry.edges;
        var vertices  = geometry.vertices;

        var vert_ids = new DynamicArray <int>();
        var start    = face.edge_id;
        var end      = start + face.num_edges;

        int i;

        for (i = start; i < end; ++i)
        {
            var edge_id = edge_list[i];
            var edge    = edges[Math.Abs(edge_id)];
            if (edge_id > 0)
            {
                vert_ids[vert_ids.length] = edge.v1;
            }
            else
            {
                vert_ids[vert_ids.length] = edge.v2;
            }
        }

        var num_tris = vert_ids.length - 2;

        for (i = 0; i < num_tris; ++i)
        {
            // reverse winding order to have correct normals
            var c = vert_ids[0];
            var b = vert_ids[i + 1];
            var a = vert_ids[i + 2];

            int vi = i * 3;

            Vector3 vert = vertices[a];
            verts[vi] = vert;

            vert          = vertices[b];
            verts[vi + 1] = vert;

            vert          = vertices[c];
            verts[vi + 2] = vert;
        }
    }
Beispiel #9
0
    MDLGeometry expandGeometry(GEOMETRY_T geometry)
    {
        var   triangles  = geometry.triangles;
        var   skin_verts = geometry.skin_verts;
        var   num_tris   = triangles.Length;
        float sw         = this.header.skin_width;
        float sh         = this.header.skin_height;

        // expand uvs
        var uvs = new Vector2[num_tris * 3]; // 3 per face, size 2 (u, v)

        for (var i = 0; i < num_tris; ++i)
        {
            var t  = triangles[i];
            var ff = t.front_facing != 0;
            var a  = t.vert_indices[0];
            var b  = t.vert_indices[1];
            var c  = t.vert_indices[2];

            var idx = i * 3;
            var uv  = skin_verts[c];
            uvs[idx + 0].x = (!ff && uv.onseam != 0) ? uv.s / sw + 0.5f : uv.s / sw;
            uvs[idx + 0].y = 1 - uv.t / sh; // uvs are upside down so invert
            uv             = skin_verts[b];
            uvs[idx + 1].x = (!ff && uv.onseam != 0) ? uv.s / sw + 0.5f : uv.s / sw;
            uvs[idx + 1].y = 1 - uv.t / sh;
            uv             = skin_verts[a];
            uvs[idx + 2].x = (!ff && uv.onseam != 0) ? uv.s / sw + 0.5f : uv.s / sw;
            uvs[idx + 2].y = 1 - uv.t / sh;
        }

        // expand frames
        var sx = this.header.scale.x;
        var sy = this.header.scale.y;
        var sz = this.header.scale.z;
        var ox = this.header.scale_origin.x;
        var oy = this.header.scale_origin.y;
        var oz = this.header.scale_origin.z;

        var frames     = geometry.frames;
        var new_frames = new DynamicArray <MDLFrame>();

        for (var j = 0; j < frames.Length; ++j)
        {
            var f     = frames[j];
            var verts = new Vector3[num_tris * 3]; // 3 per face, size 3 (x, y, z)

            for (var i = 0; i < num_tris; ++i)
            {
                var t = triangles[i];
                var a = t.vert_indices[0];
                var b = t.vert_indices[1];
                var c = t.vert_indices[2];

                var idx  = i * 3;
                var vert = f.verts[c];
                verts[idx + 0].x = vert.x * sx + ox;
                verts[idx + 0].y = vert.y * sy + oy;
                verts[idx + 0].z = vert.z * sz + oz;
                vert             = f.verts[b];
                verts[idx + 1].x = vert.x * sx + ox;
                verts[idx + 1].y = vert.y * sy + oy;
                verts[idx + 1].z = vert.z * sz + oz;
                vert             = f.verts[a];
                verts[idx + 2].x = vert.x * sx + ox;
                verts[idx + 2].y = vert.y * sy + oy;
                verts[idx + 2].z = vert.z * sz + oz;
            }

            new_frames[j] = new MDLFrame(f.name, verts);
        }

        return(new MDLGeometry(uvs, new_frames.ToArray(), geometry.frame_groups, true));
    }