예제 #1
0
        private static void PrintFrameName(model_t m, int frame)
        {
            aliashdr_t hdr = Mod.GetExtraData(m);

            if (hdr == null)
            {
                return;
            }

            Con.Print("frame {0}: {1}\n", frame, hdr.frames[frame].name);
        }
예제 #2
0
        static int _StripCount;                            // stripcount

        /// <summary>
        /// GL_MakeAliasModelDisplayLists
        /// </summary>
        public static void MakeAliasModelDisplayLists(model_t m, aliashdr_t hdr)
        {
            _AliasModel = m;
            _AliasHdr   = hdr;

            //
            // look for a cached version
            //
            string path = Path.ChangeExtension("glquake/" + Path.GetFileNameWithoutExtension(m.name), ".ms2");

            DisposableWrapper <BinaryReader> file;

            Common.FOpenFile(path, out file);
            if (file != null)
            {
                using (file)
                {
                    BinaryReader reader = file.Object;
                    _NumCommands = reader.ReadInt32();
                    _NumOrder    = reader.ReadInt32();
                    for (int i = 0; i < _NumCommands; i++)
                    {
                        _Commands[i] = reader.ReadInt32();
                    }
                    for (int i = 0; i < _NumOrder; i++)
                    {
                        _VertexOrder[i] = reader.ReadInt32();
                    }
                }
            }
            else
            {
                //
                // build it from scratch
                //
                Con.Print("meshing {0}...\n", m.name);

                BuildTris();            // trifans or lists

                //
                // save out the cached version
                //
                string fullpath = Path.Combine(Common.GameDir, path);
                Stream fs       = Sys.FileOpenWrite(fullpath, true);
                if (fs != null)
                {
                    using (BinaryWriter writer = new BinaryWriter(fs, Encoding.ASCII))
                    {
                        writer.Write(_NumCommands);
                        writer.Write(_NumOrder);
                        for (int i = 0; i < _NumCommands; i++)
                        {
                            writer.Write(_Commands[i]);
                        }
                        for (int i = 0; i < _NumOrder; i++)
                        {
                            writer.Write(_VertexOrder[i]);
                        }
                    }
                }
            }

            //
            // save the data out
            //
            _AliasHdr.poseverts = _NumOrder;

            int[] cmds = new int[_NumCommands];                        //Hunk_Alloc (numcommands * 4);
            _AliasHdr.commands = cmds;                                 // in bytes??? // (byte*)cmds - (byte*)paliashdr;
            Buffer.BlockCopy(_Commands, 0, cmds, 0, _NumCommands * 4); //memcpy (cmds, commands, numcommands * 4);

            trivertx_t[][] poseverts = Mod.PoseVerts;
            trivertx_t[]   verts     = new trivertx_t[_AliasHdr.numposes * _AliasHdr.poseverts]; // Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts * sizeof(trivertx_t) );
            _AliasHdr.posedata = verts;                                                          // (byte*)verts - (byte*)paliashdr;
            int offset = 0;

            for (int i = 0; i < _AliasHdr.numposes; i++)
            {
                for (int j = 0; j < _NumOrder; j++)
                {
                    verts[offset++] = poseverts[i][_VertexOrder[j]];  // *verts++ = poseverts[i][vertexorder[j]];
                }
            }
        }
예제 #3
0
        static int[] _VertexOrder = new int[MAX_COMMANDS]; // vertexorder

        #endregion Fields

        #region Methods

        /// <summary>
        /// GL_MakeAliasModelDisplayLists
        /// </summary>
        public static void MakeAliasModelDisplayLists(model_t m, aliashdr_t hdr)
        {
            _AliasModel = m;
            _AliasHdr = hdr;

            //
            // look for a cached version
            //
            string path = Path.ChangeExtension("glquake/" + Path.GetFileNameWithoutExtension(m.name), ".ms2");

            DisposableWrapper<BinaryReader> file;
            Common.FOpenFile(path, out file);
            if (file != null)
            {
                using (file)
                {
                    BinaryReader reader = file.Object;
                    _NumCommands = reader.ReadInt32();
                    _NumOrder = reader.ReadInt32();
                    for (int i = 0; i < _NumCommands; i++)
                        _Commands[i] = reader.ReadInt32();
                    for (int i = 0; i < _NumOrder; i++)
                        _VertexOrder[i] = reader.ReadInt32();
                }
            }
            else
            {
                //
                // build it from scratch
                //
                Con.Print("meshing {0}...\n", m.name);

                BuildTris();		// trifans or lists

                //
                // save out the cached version
                //
                string fullpath = Path.Combine(Common.GameDir, path);
                Stream fs = Sys.FileOpenWrite(fullpath, true);
                if (fs != null)
                    using (BinaryWriter writer = new BinaryWriter(fs, Encoding.ASCII))
                    {
                        writer.Write(_NumCommands);
                        writer.Write(_NumOrder);
                        for (int i = 0; i < _NumCommands; i++)
                            writer.Write(_Commands[i]);
                        for (int i = 0; i < _NumOrder; i++)
                            writer.Write(_VertexOrder[i]);
                    }
            }

            //
            // save the data out
            //
            _AliasHdr.poseverts = _NumOrder;

            int[] cmds = new int[_NumCommands]; //Hunk_Alloc (numcommands * 4);
            _AliasHdr.commands = cmds; // in bytes??? // (byte*)cmds - (byte*)paliashdr;
            Buffer.BlockCopy(_Commands, 0, cmds, 0, _NumCommands * 4); //memcpy (cmds, commands, numcommands * 4);

            trivertx_t[][] poseverts = Mod.PoseVerts;
            trivertx_t[] verts = new trivertx_t[_AliasHdr.numposes * _AliasHdr.poseverts]; // Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts * sizeof(trivertx_t) );
            _AliasHdr.posedata = verts; // (byte*)verts - (byte*)paliashdr;
            int offset = 0;
            for (int i = 0; i < _AliasHdr.numposes; i++)
                for (int j = 0; j < _NumOrder; j++)
                {
                    verts[offset++] = poseverts[i][_VertexOrder[j]];  // *verts++ = poseverts[i][vertexorder[j]];
                }
        }
예제 #4
0
        /// <summary>
        /// GL_DrawAliasShadow
        /// </summary>
        static void DrawAliasShadow(aliashdr_t paliashdr, int posenum)
        {
            float lheight = _CurrentEntity.origin.Z - _LightSpot.Z;
            float height = 0;
            trivertx_t[] verts = paliashdr.posedata;
            int voffset = posenum * paliashdr.poseverts;
            int[] order = paliashdr.commands;

            height = -lheight + 1.0f;
            int orderOffset = 0;

            while (true)
            {
                // get the vertex count and primitive type
                int count = order[orderOffset++];
                if (count == 0)
                    break;		// done

                if (count < 0)
                {
                    count = -count;
                    GL.Begin(BeginMode.TriangleFan);
                }
                else
                    GL.Begin(BeginMode.TriangleStrip);

                do
                {
                    // texture coordinates come from the draw list
                    // (skipped for shadows) glTexCoord2fv ((float *)order);
                    orderOffset += 2;

                    // normals and vertexes come from the frame list
                    Vector3 point = new Vector3(
                        verts[voffset].v[0] * paliashdr.scale.X + paliashdr.scale_origin.X,
                        verts[voffset].v[1] * paliashdr.scale.Y + paliashdr.scale_origin.Y,
                        verts[voffset].v[2] * paliashdr.scale.Z + paliashdr.scale_origin.Z
                    );

                    point.X -= _ShadeVector.X * (point.Z + lheight);
                    point.Y -= _ShadeVector.Y * (point.Z + lheight);
                    point.Z = height;

                    GL.Vertex3(point);

                    voffset++;
                } while (--count > 0);

                GL.End();
            }
        }
예제 #5
0
        /// <summary>
        /// GL_DrawAliasFrame
        /// </summary>
        static void DrawAliasFrame(aliashdr_t paliashdr, int posenum)
        {
            _LastPoseNum = posenum;

            trivertx_t[] verts = paliashdr.posedata;
            int vertsOffset = posenum * paliashdr.poseverts;
            int[] order = paliashdr.commands;
            int orderOffset = 0;

            while (true)
            {
                // get the vertex count and primitive type
                int count = order[orderOffset++];
                if (count == 0)
                    break;		// done

                if (count < 0)
                {
                    count = -count;
                    GL.Begin(BeginMode.TriangleFan);
                }
                else
                    GL.Begin(BeginMode.TriangleStrip);

                Union4b u1 = Union4b.Empty, u2 = Union4b.Empty;
                do
                {
                    // texture coordinates come from the draw list
                    u1.i0 = order[orderOffset + 0];
                    u2.i0 = order[orderOffset + 1];
                    orderOffset += 2;
                    GL.TexCoord2(u1.f0, u2.f0);

                    // normals and vertexes come from the frame list
                    float l = _ShadeDots[verts[vertsOffset].lightnormalindex] * _ShadeLight;
                    GL.Color3(l, l, l);
                    GL.Vertex3((float)verts[vertsOffset].v[0], verts[vertsOffset].v[1], verts[vertsOffset].v[2]);
                    vertsOffset++;
                } while (--count > 0);
                GL.End();
            }
        }
예제 #6
0
        /// <summary>
        /// R_SetupAliasFrame
        /// </summary>
        static void SetupAliasFrame(int frame, aliashdr_t paliashdr)
        {
            if ((frame >= paliashdr.numframes) || (frame < 0))
            {
                Con.DPrint("R_AliasSetupFrame: no such frame {0}\n", frame);
                frame = 0;
            }

            int pose = paliashdr.frames[frame].firstpose;
            int numposes = paliashdr.frames[frame].numposes;

            if (numposes > 1)
            {
                float interval = paliashdr.frames[frame].interval;
                pose += (int)(Client.cl.time / interval) % numposes;
            }

            DrawAliasFrame(paliashdr, pose);
        }
예제 #7
0
        /// <summary>
        /// Mod_LoadAliasModel
        /// </summary>
        public static void LoadAliasModel(model_t mod, byte[] buffer)
        {
            mdl_t pinmodel = Sys.BytesToStructure<mdl_t>(buffer, 0);

            int version = Common.LittleLong(pinmodel.version);
            if (version != ALIAS_VERSION)
                Sys.Error("{0} has wrong version number ({1} should be {2})",
                    mod.name, version, ALIAS_VERSION);

            //
            // allocate space for a working header, plus all the data except the frames,
            // skin and group info
            //
            _Header = new aliashdr_t();

            mod.flags = Common.LittleLong(pinmodel.flags);

            //
            // endian-adjust and copy the data, starting with the alias model header
            //
            _Header.boundingradius = Common.LittleFloat(pinmodel.boundingradius);
            _Header.numskins = Common.LittleLong(pinmodel.numskins);
            _Header.skinwidth = Common.LittleLong(pinmodel.skinwidth);
            _Header.skinheight = Common.LittleLong(pinmodel.skinheight);

            if (_Header.skinheight > MAX_LBM_HEIGHT)
                Sys.Error("model {0} has a skin taller than {1}", mod.name, MAX_LBM_HEIGHT);

            _Header.numverts = Common.LittleLong(pinmodel.numverts);

            if (_Header.numverts <= 0)
                Sys.Error("model {0} has no vertices", mod.name);

            if (_Header.numverts > MAXALIASVERTS)
                Sys.Error("model {0} has too many vertices", mod.name);

            _Header.numtris = Common.LittleLong(pinmodel.numtris);

            if (_Header.numtris <= 0)
                Sys.Error("model {0} has no triangles", mod.name);

            _Header.numframes = Common.LittleLong(pinmodel.numframes);
            int numframes = _Header.numframes;
            if (numframes < 1)
                Sys.Error("Mod_LoadAliasModel: Invalid # of frames: {0}\n", numframes);

            _Header.size = Common.LittleFloat(pinmodel.size) * ALIAS_BASE_SIZE_RATIO;
            mod.synctype = (synctype_t)Common.LittleLong((int)pinmodel.synctype);
            mod.numframes = _Header.numframes;

            _Header.scale = Common.LittleVector(Common.ToVector(ref pinmodel.scale));
            _Header.scale_origin = Common.LittleVector(Common.ToVector(ref pinmodel.scale_origin));
            _Header.eyeposition = Common.LittleVector(Common.ToVector(ref pinmodel.eyeposition));

            //
            // load the skins
            //
            int offset = LoadAllSkins(_Header.numskins, new ByteArraySegment(buffer, mdl_t.SizeInBytes));

            //
            // load base s and t vertices
            //
            int stvOffset = offset; // in bytes
            for (int i = 0; i < _Header.numverts; i++, offset += stvert_t.SizeInBytes)
            {
                _STVerts[i] = Sys.BytesToStructure<stvert_t>(buffer, offset);

                _STVerts[i].onseam = Common.LittleLong(_STVerts[i].onseam);
                _STVerts[i].s = Common.LittleLong(_STVerts[i].s);
                _STVerts[i].t = Common.LittleLong(_STVerts[i].t);
            }

            //
            // load triangle lists
            //
            int triOffset = stvOffset + _Header.numverts * stvert_t.SizeInBytes;
            offset = triOffset;
            for (int i = 0; i < _Header.numtris; i++, offset += dtriangle_t.SizeInBytes)
            {
                _Triangles[i] = Sys.BytesToStructure<dtriangle_t>(buffer, offset);
                _Triangles[i].facesfront = Common.LittleLong(_Triangles[i].facesfront);

                for (int j = 0; j < 3; j++)
                    _Triangles[i].vertindex[j] = Common.LittleLong(_Triangles[i].vertindex[j]);
            }

            //
            // load the frames
            //
            _PoseNum = 0;
            int framesOffset = triOffset + _Header.numtris * dtriangle_t.SizeInBytes;

            _Header.frames = new maliasframedesc_t[_Header.numframes];

            for (int i = 0; i < numframes; i++)
            {
                aliasframetype_t frametype = (aliasframetype_t)BitConverter.ToInt32(buffer, framesOffset);
                framesOffset += 4;

                if (frametype == aliasframetype_t.ALIAS_SINGLE)
                {
                    framesOffset = LoadAliasFrame(new ByteArraySegment(buffer, framesOffset), ref _Header.frames[i]);
                }
                else
                {
                    framesOffset = LoadAliasGroup(new ByteArraySegment(buffer, framesOffset), ref _Header.frames[i]);
                }
            }

            _Header.numposes = _PoseNum;

            mod.type = modtype_t.mod_alias;

            // FIXME: do this right
            mod.mins = -Vector3.One * 16.0f;
            mod.maxs = -mod.mins;

            //
            // build the draw lists
            //
            Mesh.MakeAliasModelDisplayLists(mod, _Header);

            //
            // move the complete, relocatable alias model to the cache
            //
            mod.cache = Cache.Alloc(aliashdr_t.SizeInBytes * _Header.frames.Length * maliasframedesc_t.SizeInBytes, null);
            if (mod.cache == null)
                return;
            mod.cache.data = _Header;
        }