Esempio n. 1
0
        /// <summary>
        /// Mod_LoadModel
        /// Loads a model into the cache
        /// </summary>
        private ModelData Load(ModelData mod, Boolean crash, ModelType type)
        {
            var name = mod.Name;

            if (mod.Type != type)
            {
                ModelData newMod = null;

                switch (type)
                {
                case ModelType.Brush:
                    newMod = new BrushModelData(Host.Model.SubdivideSize, Host.RenderContext.NoTextureMip);
                    newMod.CopyFrom(mod);
                    break;

                case ModelType.Alias:
                    newMod = new AliasModelData(Host.RenderContext.NoTextureMip);
                    newMod.CopyFrom(mod);
                    break;

                case ModelType.Sprite:
                    newMod = new SpriteModelData(Host.RenderContext.NoTextureMip);
                    newMod.CopyFrom(mod);
                    break;
                }

                newMod.Name = mod.Name;

                Remove(name);

                mod = newMod;

                Add(mod.Name, mod);
            }

            if (!mod.IsLoadRequired)
            {
                if (mod.Type == ModelType.Alias)
                {
                    if (Host.Cache.Check(mod.cache) != null)
                    {
                        return(mod);
                    }
                }
                else
                {
                    return(mod);         // not cached at all
                }
            }

            // Load the file
            var buf = FileSystem.LoadFile(mod.Name);

            if (buf == null)
            {
                if (crash)
                {
                    Utilities.Error("Mod_NumForName: {0} not found", mod.Name);
                }

                return(null);
            }

            // Allocate a new model
            Allocate(mod, buf);

            return(mod);
        }
Esempio n. 2
0
        private static int FanLength(AliasModelData m, int starttri, int startv)
        {
            mesh._Used[starttri] = 2;

            var triangles = m.Triangles;
            //last = &triangles[starttri];

            var vidx = triangles[starttri].vertindex;

            mesh._StripVerts[0] = vidx[startv % 3];
            mesh._StripVerts[1] = vidx[(startv + 1) % 3];
            mesh._StripVerts[2] = vidx[(startv + 2) % 3];

            mesh._StripTris[0] = starttri;
            mesh._StripCount   = 1;

            var m1             = vidx[(startv + 0) % 3];
            var m2             = vidx[(startv + 2) % 3];
            var lastfacesfront = triangles[starttri].facesfront;

// look for a matching triangle
nexttri:
            for (var j = starttri + 1; j < mesh._AliasHdr.numtris; j++) //, check++)
            {
                vidx = triangles[j].vertindex;
                if (triangles[j].facesfront != lastfacesfront)
                {
                    continue;
                }

                for (var k = 0; k < 3; k++)
                {
                    if (vidx[k] != m1)
                    {
                        continue;
                    }
                    if (vidx[(k + 1) % 3] != m2)
                    {
                        continue;
                    }

                    // this is the next part of the fan

                    // if we can't use this triangle, this tristrip is done
                    if (mesh._Used[j] != 0)
                    {
                        goto done;
                    }

                    // the new edge
                    m2 = vidx[(k + 2) % 3];

                    mesh._StripVerts[mesh._StripCount + 2] = m2;
                    mesh._StripTris[mesh._StripCount]      = j;
                    mesh._StripCount++;

                    mesh._Used[j] = 2;
                    goto nexttri;
                }
            }
done:

// clear the temp used flags
            for (var j = starttri + 1; j < mesh._AliasHdr.numtris; j++)
            {
                if (mesh._Used[j] == 2)
                {
                    mesh._Used[j] = 0;
                }
            }

            return(mesh._StripCount);
        }
Esempio n. 3
0
        /// <summary>
        /// Mod_LoadModel
        /// Loads a model into the cache
        /// </summary>
        public ModelData LoadModel(ModelData mod, Boolean crash, ModelType type)
        {
            var name = mod.Name;

            if (mod.Type != type)
            {
                ModelData newMod = null;

                switch (type)
                {
                case ModelType.mod_brush:
                    newMod = new BrushModelData(Host.Model.SubdivideSize, Host.RenderContext.NoTextureMip);
                    newMod.CopyFrom(mod);
                    break;

                case ModelType.mod_alias:
                    newMod = new AliasModelData(Host.RenderContext.NoTextureMip);
                    newMod.CopyFrom(mod);
                    break;

                case ModelType.mod_sprite:
                    newMod = new SpriteModelData(Host.RenderContext.NoTextureMip);
                    newMod.CopyFrom(mod);
                    break;
                }

                newMod.Name = mod.Name;

                ModelCache.RemoveAll(k => k.Name == name);

                mod = newMod;

                ModelCache.Add(mod);
            }

            if (!mod.IsLoadRequired)
            {
                if (mod.Type == ModelType.mod_alias)
                {
                    if (Host.Cache.Check(mod.cache) != null)
                    {
                        return(mod);
                    }
                }
                else
                {
                    return(mod);         // not cached at all
                }
            }

            //
            // load the file
            //
            var buf = FileSystem.LoadFile(mod.Name);

            if (buf == null)
            {
                if (crash)
                {
                    Utilities.Error("Mod_NumForName: {0} not found", mod.Name);
                }
                return(null);
            }

            //
            // allocate a new model
            //
            CurrentModel = mod;

            mod.IsLoadRequired = false;

            switch (BitConverter.ToUInt32(buf, 0))    // LittleLong(*(unsigned *)buf))
            {
            case ModelDef.IDPOLYHEADER:
                LoadAliasModel(( AliasModelData )mod, buf);
                break;

            case ModelDef.IDSPRITEHEADER:
                LoadSpriteModel(( SpriteModelData )mod, buf);
                break;

            default:
                LoadBrushModel(( BrushModelData )mod, buf);
                break;
            }

            return(mod);
        }
Esempio n. 4
0
        /// <summary>
        /// BuildTris
        /// Generate a list of trifans or strips for the model, which holds for all frames
        /// </summary>
        private static void BuildTris(AliasModelData m)
        {
            var bestverts = new int[1024];
            var besttris  = new int[1024];

            // Uze
            // All references to pheader from model.c changed to _AliasHdr (former paliashdr)

            //
            // build tristrips
            //
            var stverts   = m.STVerts;
            var triangles = m.Triangles;

            mesh._NumOrder    = 0;
            mesh._NumCommands = 0;
            Array.Clear(mesh._Used, 0, mesh._Used.Length);   // memset (used, 0, sizeof(used));
            int besttype = 0, len;

            for (var i = 0; i < mesh._AliasHdr.numtris; i++)
            {
                // pick an unused triangle and start the trifan
                if (mesh._Used[i] != 0)
                {
                    continue;
                }

                var bestlen = 0;
                for (var type = 0; type < 2; type++)
                {
                    for (var startv = 0; startv < 3; startv++)
                    {
                        if (type == 1)
                        {
                            len = mesh.StripLength(m, i, startv);
                        }
                        else
                        {
                            len = mesh.FanLength(m, i, startv);
                        }
                        if (len > bestlen)
                        {
                            besttype = type;
                            bestlen  = len;
                            for (var j = 0; j < bestlen + 2; j++)
                            {
                                bestverts[j] = mesh._StripVerts[j];
                            }
                            for (var j = 0; j < bestlen; j++)
                            {
                                besttris[j] = mesh._StripTris[j];
                            }
                        }
                    }
                }

                // mark the tris on the best strip as used
                for (var j = 0; j < bestlen; j++)
                {
                    mesh._Used[besttris[j]] = 1;
                }

                if (besttype == 1)
                {
                    mesh._Commands[mesh._NumCommands++] = bestlen + 2;
                }
                else
                {
                    mesh._Commands[mesh._NumCommands++] = -(bestlen + 2);
                }

                var uval = Union4b.Empty;
                for (var j = 0; j < bestlen + 2; j++)
                {
                    // emit a vertex into the reorder buffer
                    var k = bestverts[j];
                    mesh._VertexOrder[mesh._NumOrder++] = k;

                    // emit s/t coords into the commands stream
                    float s = stverts[k].s;
                    float t = stverts[k].t;
                    if (triangles[besttris[0]].facesfront == 0 && stverts[k].onseam != 0)
                    {
                        s += mesh._AliasHdr.skinwidth / 2;      // on back side
                    }
                    s = (s + 0.5f) / mesh._AliasHdr.skinwidth;
                    t = (t + 0.5f) / mesh._AliasHdr.skinheight;

                    uval.f0 = s;
                    mesh._Commands[mesh._NumCommands++] = uval.i0;
                    uval.f0 = t;
                    mesh._Commands[mesh._NumCommands++] = uval.i0;
                }
            }

            mesh._Commands[mesh._NumCommands++] = 0;            // end of list marker

            ConsoleWrapper.DPrint("{0,3} tri {1,3} vert {2,3} cmd\n", mesh._AliasHdr.numtris, mesh._NumOrder, mesh._NumCommands);

            mesh._AllVerts += mesh._NumOrder;
            mesh._AllTris  += mesh._AliasHdr.numtris;
        }