예제 #1
0
파일: RenderEfrag.cs 프로젝트: Scrama/Quarp
        /// <summary>
        /// R_StoreEfrags
        /// FIXME: a lot of this goes away with edge-based
        /// </summary>
        static void StoreEfrags(efrag_t ef)
        {
            while (ef != null)
            {
                entity_t pent = ef.entity;
                model_t clmodel = pent.model;

                switch (clmodel.type)
                {
                    case modtype_t.mod_alias:
                    case modtype_t.mod_brush:
                    case modtype_t.mod_sprite:
                        if ((pent.visframe != _FrameCount) && (Client.NumVisEdicts < Client.MAX_VISEDICTS))
                        {
                            Client.VisEdicts[Client.NumVisEdicts++] = pent;

                            // mark that we've recorded this entity for this frame
                            pent.visframe = _FrameCount;
                        }

                        ef = ef.leafnext;
                        break;

                    default:
                        Sys.Error("R_StoreEfrags: Bad entity type {0}\n", clmodel.type);
                        break;
                }
            }
        }
예제 #2
0
        /// <summary>
        /// GL_SubdivideSurface
        /// Breaks a polygon up along axial 64 unit boundaries
        /// so that turbulent and sky warps can be done reasonably.
        /// </summary>
        public static void SubdivideSurface(msurface_t fa)
        {
            _WarpFace = fa;

            //
            // convert edges back to a normal polygon
            //
            int numverts = 0;

            Vector3[] verts     = new Vector3[fa.numedges + 1]; // + 1 for wrap case
            model_t   loadmodel = Mod.Model;

            for (int i = 0; i < fa.numedges; i++)
            {
                int lindex = loadmodel.surfedges[fa.firstedge + i];

                if (lindex > 0)
                {
                    verts[numverts] = loadmodel.vertexes[loadmodel.edges[lindex].v[0]].position;
                }
                else
                {
                    verts[numverts] = loadmodel.vertexes[loadmodel.edges[-lindex].v[1]].position;
                }

                numverts++;
            }

            SubdividePolygon(numverts, verts);
        }
예제 #3
0
 public void Clear()
 {
     this.entity  = 0;
     this.model   = null;
     this.endtime = 0;
     this.start   = Vector3.Zero;
     this.end     = Vector3.Zero;
 }
예제 #4
0
        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);
        }
예제 #5
0
        static void DrawTextureChains()
        {
            if (_glTexSort.Value == 0)
            {
                DisableMultitexture();

                if (_SkyChain != null)
                {
                    DrawSkyChain(_SkyChain);
                    _SkyChain = null;
                }
                return;
            }
            model_t world = Client.cl.worldmodel;

            for (int i = 0; i < world.numtextures; i++)
            {
                texture_t t = world.textures[i];
                if (t == null)
                {
                    continue;
                }

                msurface_t s = t.texturechain;
                if (s == null)
                {
                    continue;
                }

                if (i == _SkyTextureNum)
                {
                    DrawSkyChain(s);
                }
                else if (i == _MirrorTextureNum && _MirrorAlpha.Value != 1.0f)
                {
                    MirrorChain(s);
                    continue;
                }
                else
                {
                    if ((s.flags & Surf.SURF_DRAWTURB) != 0 && _WaterAlpha.Value != 1.0f)
                    {
                        continue;       // draw translucent water later
                    }
                    for (; s != null; s = s.texturechain)
                    {
                        RenderBrushPoly(s);
                    }
                }

                t.texturechain = null;
            }
        }
예제 #6
0
        /// <summary>
        /// SV_HullForEntity
        /// Returns a hull that can be used for testing or clipping an object of mins/maxs size.
        /// Offset is filled in to contain the adjustment that must be added to the
        /// testing object's origin to get a point to use with the returned hull.
        /// </summary>
        static hull_t HullForEntity(edict_t ent, ref Vector3 mins, ref Vector3 maxs, out Vector3 offset)
        {
            hull_t hull = null;

            // decide which clipping hull to use, based on the size
            if (ent.v.solid == Solids.SOLID_BSP)
            {   // explicit hulls in the BSP model
                if (ent.v.movetype != Movetypes.MOVETYPE_PUSH)
                {
                    Sys.Error("SOLID_BSP without MOVETYPE_PUSH");
                }

                model_t model = sv.models[(int)ent.v.modelindex];

                if (model == null || model.type != modtype_t.mod_brush)
                {
                    Sys.Error("MOVETYPE_PUSH with a non bsp model");
                }

                Vector3 size = maxs - mins;
                if (size.X < 3)
                {
                    hull = model.hulls[0];
                }
                else if (size.X <= 32)
                {
                    hull = model.hulls[1];
                }
                else
                {
                    hull = model.hulls[2];
                }

                // calculate an offset value to center the origin
                offset  = hull.clip_mins - mins;
                offset += Common.ToVector(ref ent.v.origin);
            }
            else
            {
                // create a temp hull from bounding box sizes
                Vector3 hullmins = Common.ToVector(ref ent.v.mins) - maxs;
                Vector3 hullmaxs = Common.ToVector(ref ent.v.maxs) - mins;
                hull = HullForBox(ref hullmins, ref hullmaxs);

                offset = Common.ToVector(ref ent.v.origin);
            }

            return(hull);
        }
예제 #7
0
파일: RenderEfrag.cs 프로젝트: Scrama/Quarp
        static object _LastObj; // see comments

        /// <summary>
        /// R_AddEfrags
        /// </summary>
        public static void AddEfrags(entity_t ent)
        {
            if (ent.model == null)
                return;

            _AddEnt = ent;
            _LastObj = ent; //  lastlink = &ent->efrag;
            _EfragTopNode = null;

            model_t entmodel = ent.model;
            _EMins = ent.origin + entmodel.mins;
            _EMaxs = ent.origin + entmodel.maxs;

            SplitEntityOnNode(Client.cl.worldmodel.nodes[0]);
            ent.topnode = _EfragTopNode;
        }
예제 #8
0
        /// <summary>
        /// R_MarkLeaves
        /// </summary>
        private static void MarkLeaves()
        {
            if (_OldViewLeaf == _ViewLeaf && _NoVis.Value == 0)
            {
                return;
            }

            if (_IsMirror)
            {
                return;
            }

            _VisFrameCount++;
            _OldViewLeaf = _ViewLeaf;

            byte[] vis;
            if (_NoVis.Value != 0)
            {
                vis = new byte[4096];
                Common.FillArray <Byte>(vis, 0xff); // todo: add count parameter?
                //memset(solid, 0xff, (cl.worldmodel->numleafs + 7) >> 3);
            }
            else
            {
                vis = Mod.LeafPVS(_ViewLeaf, Client.cl.worldmodel);
            }

            model_t world = Client.cl.worldmodel;

            for (int i = 0; i < world.numleafs; i++)
            {
                if (vis[i >> 3] != 0 & (1 << (i & 7)) != 0)
                {
                    mnodebase_t node = world.leafs[i + 1];
                    do
                    {
                        if (node.visframe == _VisFrameCount)
                        {
                            break;
                        }
                        node.visframe = _VisFrameCount;
                        node          = node.parent;
                    } while (node != null);
                }
            }
        }
예제 #9
0
        /// <summary>
        /// Host_Viewprev_f
        /// </summary>
        static void Viewprev_f()
        {
            edict_t e = FindViewthing();

            if (e == null)
            {
                return;
            }

            model_t m = Client.cl.model_precache[(int)e.v.modelindex];

            e.v.frame = e.v.frame - 1;
            if (e.v.frame < 0)
            {
                e.v.frame = 0;
            }

            PrintFrameName(m, (int)e.v.frame);
        }
예제 #10
0
        /// <summary>
        /// Host_Viewnext_f
        /// </summary>
        static void Viewnext_f()
        {
            edict_t e = FindViewthing();

            if (e == null)
            {
                return;
            }

            model_t m = Client.cl.model_precache[(int)e.v.modelindex];

            e.v.frame = e.v.frame + 1;
            if (e.v.frame >= m.numframes)
            {
                e.v.frame = m.numframes - 1;
            }

            PrintFrameName(m, (int)e.v.frame);
        }
예제 #11
0
        /// <summary>
        /// Host_Viewframe_f
        /// </summary>
        static void Viewframe_f()
        {
            edict_t e = FindViewthing();

            if (e == null)
            {
                return;
            }

            model_t m = Client.cl.model_precache[(int)e.v.modelindex];

            int f = Common.atoi(Cmd.Argv(1));

            if (f >= m.numframes)
            {
                f = m.numframes - 1;
            }

            e.v.frame = f;
        }
예제 #12
0
        // Host_Viewmodel_f
        static void Viewmodel_f()
        {
            edict_t e = FindViewthing();

            if (e == null)
            {
                return;
            }

            model_t m = Mod.ForName(Cmd.Argv(1), false);

            if (m == null)
            {
                Con.Print("Can't load {0}\n", Cmd.Argv(1));
                return;
            }

            e.v.frame = 0;
            Client.cl.model_precache[(int)e.v.modelindex] = m;
        }
예제 #13
0
        /*
         * =================
         * PF_setmodel
         *
         * setmodel(entity, model)
         * =================
         */
        static void PF_setmodel()
        {
            edict_t e     = GetEdict(OFS.OFS_PARM0);
            int     m_idx = GetInt(OFS.OFS_PARM1);
            string  m     = Progs.GetString(m_idx);

            // check to see if model was properly precached
            for (int i = 0; i < Server.sv.model_precache.Length; i++)
            {
                string check = Server.sv.model_precache[i];

                if (check == null)
                {
                    break;
                }

                if (check == m)
                {
                    e.v.model      = m_idx; // m - pr_strings;
                    e.v.modelindex = i;

                    model_t mod = Server.sv.models[(int)e.v.modelindex];

                    if (mod != null)
                    {
                        SetMinMaxSize(e, ref mod.mins, ref mod.maxs, true);
                    }
                    else
                    {
                        SetMinMaxSize(e, ref Common.ZeroVector, ref Common.ZeroVector, true);
                    }

                    return;
                }
            }

            Progs.RunError("no precache: {0}\n", m);
        }
예제 #14
0
        /// <summary>
        /// CL_ParseBeam
        /// </summary>
        static void ParseBeam(model_t m)
        {
            int ent = Net.Reader.ReadShort();

            Vector3 start = Net.Reader.ReadCoords();
            Vector3 end   = Net.Reader.ReadCoords();

            // override any beam with the same entity
            for (int i = 0; i < MAX_BEAMS; i++)
            {
                beam_t b = _Beams[i];
                if (b.entity == ent)
                {
                    b.entity  = ent;
                    b.model   = m;
                    b.endtime = (float)(cl.time + 0.2);
                    b.start   = start;
                    b.end     = end;
                    return;
                }
            }

            // find a free beam
            for (int i = 0; i < MAX_BEAMS; i++)
            {
                beam_t b = _Beams[i];
                if (b.model == null || b.endtime < cl.time)
                {
                    b.entity  = ent;
                    b.model   = m;
                    b.endtime = (float)(cl.time + 0.2);
                    b.start   = start;
                    b.end     = end;
                    return;
                }
            }
            Con.Print("beam list overflow!\n");
        }
예제 #15
0
 public void Clear()
 {
     this.active        = false;
     this.paused        = false;
     this.loadgame      = false;
     this.time          = 0;
     this.lastcheck     = 0;
     this.lastchecktime = 0;
     this.name          = null;
     this.modelname     = null;
     this.worldmodel    = null;
     Array.Clear(this.model_precache, 0, this.model_precache.Length);
     Array.Clear(this.models, 0, this.models.Length);
     Array.Clear(this.sound_precache, 0, this.sound_precache.Length);
     Array.Clear(this.lightstyles, 0, this.lightstyles.Length);
     this.num_edicts = 0;
     this.max_edicts = 0;
     this.edicts     = null;
     this.state      = 0;
     this.datagram.Clear();
     this.reliable_datagram.Clear();
     this.signon.Clear();
 }
예제 #16
0
        /// <summary>
        /// R_DrawBrushModel
        /// </summary>
        private static void DrawBrushModel(entity_t e)
        {
            _CurrentEntity        = e;
            Drawer.CurrentTexture = -1;

            model_t clmodel = e.model;
            bool    rotated = false;
            Vector3 mins, maxs;

            if (e.angles.X != 0 || e.angles.Y != 0 || e.angles.Z != 0)
            {
                rotated = true;
                mins    = e.origin;
                mins.X -= clmodel.radius;
                mins.Y -= clmodel.radius;
                mins.Z -= clmodel.radius;
                maxs    = e.origin;
                maxs.X += clmodel.radius;
                maxs.Y += clmodel.radius;
                maxs.Z += clmodel.radius;
            }
            else
            {
                mins = e.origin + clmodel.mins;
                maxs = e.origin + clmodel.maxs;
            }

            if (CullBox(ref mins, ref maxs))
            {
                return;
            }

            GL.Color3(1f, 1, 1);
            Array.Clear(_LightMapPolys, 0, _LightMapPolys.Length);
            _ModelOrg = _RefDef.vieworg - e.origin;
            if (rotated)
            {
                Vector3 temp = _ModelOrg;
                Vector3 forward, right, up;
                Mathlib.AngleVectors(ref e.angles, out forward, out right, out up);
                _ModelOrg.X = Vector3.Dot(temp, forward);
                _ModelOrg.Y = -Vector3.Dot(temp, right);
                _ModelOrg.Z = Vector3.Dot(temp, up);
            }

            // calculate dynamic lighting for bmodel if it's not an
            // instanced model
            if (clmodel.firstmodelsurface != 0 && _glFlashBlend.Value == 0)
            {
                for (int k = 0; k < Client.MAX_DLIGHTS; k++)
                {
                    if ((Client.DLights[k].die < Client.cl.time) || (Client.DLights[k].radius == 0))
                    {
                        continue;
                    }

                    MarkLights(Client.DLights[k], 1 << k, clmodel.nodes[clmodel.hulls[0].firstclipnode]);
                }
            }

            GL.PushMatrix();
            e.angles.X = -e.angles.X;   // stupid quake bug
            RotateForEntity(e);
            e.angles.X = -e.angles.X;   // stupid quake bug

            int surfOffset = clmodel.firstmodelsurface;

            msurface_t[] psurf = clmodel.surfaces; //[clmodel.firstmodelsurface];

            //
            // draw texture
            //
            for (int i = 0; i < clmodel.nummodelsurfaces; i++, surfOffset++)
            {
                // find which side of the node we are on
                mplane_t pplane = psurf[surfOffset].plane;

                float dot = Vector3.Dot(_ModelOrg, pplane.normal) - pplane.dist;

                // draw the polygon
                bool planeBack = (psurf[surfOffset].flags & Surf.SURF_PLANEBACK) != 0;
                if ((planeBack && (dot < -QDef.BACKFACE_EPSILON)) || (!planeBack && (dot > QDef.BACKFACE_EPSILON)))
                {
                    if (_glTexSort.Value != 0)
                    {
                        RenderBrushPoly(psurf[surfOffset]);
                    }
                    else
                    {
                        DrawSequentialPoly(psurf[surfOffset]);
                    }
                }
            }

            BlendLightmaps();

            GL.PopMatrix();
        }
예제 #17
0
        public void Clear()
        {
            this.movemessages = 0;
            this.cmd.Clear();
            Array.Clear(this.stats, 0, this.stats.Length);
            this.items = 0;
            Array.Clear(this.item_gettime, 0, this.item_gettime.Length);
            this.faceanimtime = 0;

            foreach (cshift_t cs in this.cshifts)
            {
                cs.Clear();
            }
            foreach (cshift_t cs in this.prev_cshifts)
            {
                cs.Clear();
            }

            this.mviewangles[0] = Vector3.Zero;
            this.mviewangles[1] = Vector3.Zero;
            this.viewangles     = Vector3.Zero;
            this.mvelocity[0]   = Vector3.Zero;
            this.mvelocity[1]   = Vector3.Zero;
            this.velocity       = Vector3.Zero;
            this.punchangle     = Vector3.Zero;

            this.idealpitch = 0;
            this.pitchvel   = 0;
            this.nodrift    = false;
            this.driftmove  = 0;
            this.laststop   = 0;

            this.viewheight = 0;
            this.crouch     = 0;

            this.paused   = false;
            this.onground = false;
            this.inwater  = false;

            this.intermission   = 0;
            this.completed_time = 0;

            this.mtime[0] = 0;
            this.mtime[1] = 0;
            this.time     = 0;
            this.oldtime  = 0;
            this.last_received_message = 0;

            Array.Clear(this.model_precache, 0, this.model_precache.Length);
            Array.Clear(this.sound_precache, 0, this.sound_precache.Length);

            this.levelname  = null;
            this.viewentity = 0;
            this.maxclients = 0;
            this.gametype   = 0;

            this.worldmodel   = null;
            this.free_efrags  = null;
            this.num_entities = 0;
            this.num_statics  = 0;
            this.viewent.Clear();

            this.cdtrack   = 0;
            this.looptrack = 0;

            this.scores = null;
        }
예제 #18
0
        static byte[] _LightMaps = new byte[4 * MAX_LIGHTMAPS * BLOCK_WIDTH * BLOCK_HEIGHT]; // lightmaps

        /// <summary>
        /// GL_BuildLightmaps
        /// Builds the lightmap texture with all the surfaces from all brush models
        /// </summary>
        static void BuildLightMaps()
        {
            Array.Clear(_Allocated, 0, _Allocated.Length);
            //memset (allocated, 0, sizeof(allocated));

            _FrameCount = 1;            // no dlightcache

            if (_LightMapTextures == 0)
            {
                _LightMapTextures = Drawer.GenerateTextureNumberRange(MAX_LIGHTMAPS);
            }

            Drawer.LightMapFormat = PixelFormat.Luminance;// GL_LUMINANCE;

            // default differently on the Permedia
            if (Scr.IsPermedia)
            {
                Drawer.LightMapFormat = PixelFormat.Rgba;
            }

            if (Common.HasParam("-lm_1"))
            {
                Drawer.LightMapFormat = PixelFormat.Luminance;
            }

            if (Common.HasParam("-lm_a"))
            {
                Drawer.LightMapFormat = PixelFormat.Alpha;
            }

            //if (Common.HasParam("-lm_i"))
            //    Drawer.LightMapFormat = PixelFormat.Intensity;

            //if (Common.HasParam("-lm_2"))
            //    Drawer.LightMapFormat = PixelFormat.Rgba4;

            if (Common.HasParam("-lm_4"))
            {
                Drawer.LightMapFormat = PixelFormat.Rgba;
            }

            switch (Drawer.LightMapFormat)
            {
            case PixelFormat.Rgba:
                _LightMapBytes = 4;
                break;

            //case PixelFormat.Rgba4:
            //_LightMapBytes = 2;
            //break;

            case PixelFormat.Luminance:
            //case PixelFormat.Intensity:
            case PixelFormat.Alpha:
                _LightMapBytes = 1;
                break;
            }

            for (int j = 1; j < QDef.MAX_MODELS; j++)
            {
                model_t m = Client.cl.model_precache[j];
                if (m == null)
                {
                    break;
                }

                if (m.name != null && m.name.StartsWith("*"))
                {
                    continue;
                }

                _CurrentVertBase = m.vertexes;
                _CurrentModel    = m;
                for (int i = 0; i < m.numsurfaces; i++)
                {
                    CreateSurfaceLightmap(m.surfaces[i]);
                    if ((m.surfaces[i].flags & Surf.SURF_DRAWTURB) != 0)
                    {
                        continue;
                    }

                    if ((m.surfaces[i].flags & Surf.SURF_DRAWSKY) != 0)
                    {
                        continue;
                    }

                    BuildSurfaceDisplayList(m.surfaces[i]);
                }
            }

            if (_glTexSort.Value == 0)
            {
                Drawer.SelectTexture(MTexTarget.TEXTURE1_SGIS);
            }

            //
            // upload all lightmaps that were filled
            //
            GCHandle handle = GCHandle.Alloc(_LightMaps, GCHandleType.Pinned);

            try
            {
                IntPtr ptr    = handle.AddrOfPinnedObject();
                long   lmAddr = ptr.ToInt64();

                for (int i = 0; i < MAX_LIGHTMAPS; i++)
                {
                    if (_Allocated[i, 0] == 0)
                    {
                        break;          // no more used
                    }
                    _LightMapModified[i]     = false;
                    _LightMapRectChange[i].l = BLOCK_WIDTH;
                    _LightMapRectChange[i].t = BLOCK_HEIGHT;
                    _LightMapRectChange[i].w = 0;
                    _LightMapRectChange[i].h = 0;
                    Drawer.Bind(_LightMapTextures + i);
                    Drawer.SetTextureFilters(TextureMinFilter.Linear, TextureMagFilter.Linear);

                    long addr = lmAddr + i * BLOCK_WIDTH * BLOCK_HEIGHT * _LightMapBytes;
                    GL.TexImage2D(TextureTarget.Texture2D, 0, (PixelInternalFormat)_LightMapBytes,
                                  BLOCK_WIDTH, BLOCK_HEIGHT, 0, Drawer.LightMapFormat, PixelType.UnsignedByte, new IntPtr(addr));
                }
            }
            finally
            {
                handle.Free();
            }

            if (_glTexSort.Value == 0)
            {
                Drawer.SelectTexture(MTexTarget.TEXTURE0_SGIS);
            }
        }
예제 #19
0
파일: Mesh.cs 프로젝트: Scrama/Quarp
        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]];
                }
            }
        }
예제 #20
0
        /// <summary>
        /// CL_ParseUpdate
        ///
        /// Parse an entity update message from the server
        /// If an entities model or origin changes from frame to frame, it must be
        /// relinked.  Other attributes can change without relinking.
        /// </summary>
        static void ParseUpdate(int bits)
        {
            int i;

            if (cls.signon == SIGNONS - 1)
            {
                // first update is the final signon stage
                cls.signon = SIGNONS;
                SignonReply();
            }

            if ((bits & Protocol.U_MOREBITS) != 0)
            {
                i     = Net.Reader.ReadByte();
                bits |= (i << 8);
            }

            int num;

            if ((bits & Protocol.U_LONGENTITY) != 0)
            {
                num = Net.Reader.ReadShort();
            }
            else
            {
                num = Net.Reader.ReadByte();
            }

            entity_t ent = EntityNum(num);

            for (i = 0; i < 16; i++)
            {
                if ((bits & (1 << i)) != 0)
                {
                    _BitCounts[i]++;
                }
            }

            bool forcelink = false;

            if (ent.msgtime != cl.mtime[1])
            {
                forcelink = true;       // no previous frame to lerp from
            }
            ent.msgtime = cl.mtime[0];
            int modnum;

            if ((bits & Protocol.U_MODEL) != 0)
            {
                modnum = Net.Reader.ReadByte();
                if (modnum >= QDef.MAX_MODELS)
                {
                    Host.Error("CL_ParseModel: bad modnum");
                }
            }
            else
            {
                modnum = ent.baseline.modelindex;
            }

            model_t model = cl.model_precache[modnum];

            if (model != ent.model)
            {
                ent.model = model;
                // automatic animation (torches, etc) can be either all together
                // or randomized
                if (model != null)
                {
                    if (model.synctype == synctype_t.ST_RAND)
                    {
                        ent.syncbase = (float)(Sys.Random() & 0x7fff) / 0x7fff;
                    }
                    else
                    {
                        ent.syncbase = 0;
                    }

                    if (model.numframes < ent.Pose1)
                    {
                        ent.Pose1 = 0;
                        ent.Pose2 = 0;
                    }
                }
                else
                {
                    forcelink = true;   // hack to make null model players work
                    ent.Pose1 = 0;
                }

                if (num > 0 && num <= cl.maxclients)
                {
                    Render.TranslatePlayerSkin(num - 1);
                }
            }

            if ((bits & Protocol.U_FRAME) != 0)
            {
                ent.frame = Net.Reader.ReadByte();
            }
            else
            {
                ent.frame = ent.baseline.frame;
            }

            if ((bits & Protocol.U_COLORMAP) != 0)
            {
                i = Net.Reader.ReadByte();
            }
            else
            {
                i = ent.baseline.colormap;
            }
            if (i == 0)
            {
                ent.colormap = Scr.vid.colormap;
            }
            else
            {
                if (i > cl.maxclients)
                {
                    Sys.Error("i >= cl.maxclients");
                }
                ent.colormap = cl.scores[i - 1].translations;
            }

            int skin;

            if ((bits & Protocol.U_SKIN) != 0)
            {
                skin = Net.Reader.ReadByte();
            }
            else
            {
                skin = ent.baseline.skin;
            }
            if (skin != ent.skinnum)
            {
                ent.skinnum = skin;
                if (num > 0 && num <= cl.maxclients)
                {
                    Render.TranslatePlayerSkin(num - 1);
                }
            }

            if ((bits & Protocol.U_EFFECTS) != 0)
            {
                ent.effects = Net.Reader.ReadByte();
            }
            else
            {
                ent.effects = ent.baseline.effects;
            }

            // shift the known values for interpolation
            ent.msg_origins[1] = ent.msg_origins[0];
            ent.msg_angles[1]  = ent.msg_angles[0];

            if ((bits & Protocol.U_ORIGIN1) != 0)
            {
                ent.msg_origins[0].X = Net.Reader.ReadCoord();
            }
            else
            {
                ent.msg_origins[0].X = ent.baseline.origin.x;
            }
            if ((bits & Protocol.U_ANGLE1) != 0)
            {
                ent.msg_angles[0].X = Net.Reader.ReadAngle();
            }
            else
            {
                ent.msg_angles[0].X = ent.baseline.angles.x;
            }

            if ((bits & Protocol.U_ORIGIN2) != 0)
            {
                ent.msg_origins[0].Y = Net.Reader.ReadCoord();
            }
            else
            {
                ent.msg_origins[0].Y = ent.baseline.origin.y;
            }
            if ((bits & Protocol.U_ANGLE2) != 0)
            {
                ent.msg_angles[0].Y = Net.Reader.ReadAngle();
            }
            else
            {
                ent.msg_angles[0].Y = ent.baseline.angles.y;
            }

            if ((bits & Protocol.U_ORIGIN3) != 0)
            {
                ent.msg_origins[0].Z = Net.Reader.ReadCoord();
            }
            else
            {
                ent.msg_origins[0].Z = ent.baseline.origin.z;
            }
            if ((bits & Protocol.U_ANGLE3) != 0)
            {
                ent.msg_angles[0].Z = Net.Reader.ReadAngle();
            }
            else
            {
                ent.msg_angles[0].Z = ent.baseline.angles.z;
            }

            if ((bits & Protocol.U_NOLERP) != 0)
            {
                ent.forcelink = true;
            }

            if (forcelink)
            {   // didn't have an update last message
                ent.msg_origins[1] = ent.msg_origins[0];
                ent.origin         = ent.msg_origins[0];
                ent.msg_angles[1]  = ent.msg_angles[0];
                ent.angles         = ent.msg_angles[0];
                ent.forcelink      = true;
            }
        }
예제 #21
0
        public void CopyFrom(model_t src)
        {
            this.name              = src.name;
            this.needload          = src.needload;
            this.type              = src.type;
            this.numframes         = src.numframes;
            this.synctype          = src.synctype;
            this.flags             = src.flags;
            this.mins              = src.mins;
            this.maxs              = src.maxs;
            this.radius            = src.radius;
            this.clipbox           = src.clipbox;
            this.clipmins          = src.clipmins;
            this.clipmaxs          = src.clipmaxs;
            this.firstmodelsurface = src.firstmodelsurface;
            this.nummodelsurfaces  = src.nummodelsurfaces;

            this.numsubmodels = src.numsubmodels;
            this.submodels    = src.submodels;

            this.numplanes = src.numplanes;
            this.planes    = src.planes;

            this.numleafs = src.numleafs;
            this.leafs    = src.leafs;

            this.numvertexes = src.numvertexes;
            this.vertexes    = src.vertexes;

            this.numedges = src.numedges;
            this.edges    = src.edges;

            this.numnodes = src.numnodes;
            this.nodes    = src.nodes;

            this.numtexinfo = src.numtexinfo;
            this.texinfo    = src.texinfo;

            this.numsurfaces = src.numsurfaces;
            this.surfaces    = src.surfaces;

            this.numsurfedges = src.numsurfedges;
            this.surfedges    = src.surfedges;

            this.numclipnodes = src.numclipnodes;
            this.clipnodes    = src.clipnodes;

            this.nummarksurfaces = src.nummarksurfaces;
            this.marksurfaces    = src.marksurfaces;

            for (int i = 0; i < src.hulls.Length; i++)
            {
                this.hulls[i].CopyFrom(src.hulls[i]);
            }

            this.numtextures = src.numtextures;
            this.textures    = src.textures;

            this.visdata   = src.visdata;
            this.lightdata = src.lightdata;
            this.entities  = src.entities;

            this.cache = src.cache;
        }