static void PF_checkclient() { // find a new check if on a new frame if (sv.time - sv.lastchecktime >= 0.1) { sv.lastcheck = PF_newcheckclient(sv.lastcheck); sv.lastchecktime = sv.time; } // return check if it might be visible edict_t ent = EDICT_NUM(sv.lastcheck); if (ent.free || ent.v.health <= 0) { RETURN_EDICT(sv.edicts[0]); return; } // if current entity can't possibly see the check entity, return 0 edict_t self = PROG_TO_EDICT(pr_global_struct.self); Vector3 view = ToVector(ref self.v.origin) + ToVector(ref self.v.view_ofs); mleaf_t leaf = Mod_PointInLeaf(ref view, sv.worldmodel); int l = Array.IndexOf(sv.worldmodel.leafs, leaf) - 1; if ((l < 0) || (checkpvs[l >> 3] & (1 << (l & 7))) == 0) { c_notvis++; RETURN_EDICT(sv.edicts[0]); return; } // might be able to see it c_invis++; RETURN_EDICT(ent); }
public virtual void Mod_LoadLeafs(lump_t l) { qfiles.dleaf_t in_renamed; mleaf_t[] out_renamed; Int32 i, j, count; if ((l.filelen % qfiles.dleaf_t.SIZE) != 0) { Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name); } count = l.filelen / qfiles.dleaf_t.SIZE; out_renamed = new mleaf_t[count]; loadmodel.leafs = out_renamed; loadmodel.numleafs = count; ByteBuffer bb = ByteBuffer.Wrap(mod_base, l.fileofs, l.filelen); bb.Order = ByteOrder.LittleEndian; for (i = 0; i < count; i++) { in_renamed = new dleaf_t(bb); out_renamed[i] = new mleaf_t(); for (j = 0; j < 3; j++) { out_renamed[i].mins[j] = in_renamed.mins[j]; out_renamed[i].maxs[j] = in_renamed.maxs[j]; } out_renamed[i].contents = in_renamed.contents; out_renamed[i].cluster = in_renamed.cluster; out_renamed[i].area = in_renamed.area; out_renamed[i].SetMarkSurface(in_renamed.firstleafface, loadmodel.marksurfaces); out_renamed[i].nummarksurfaces = in_renamed.numleaffaces; } }
public static void R_SetupFrame() { // don't allow cheats in multiplayer if (cl.maxclients > 1) { Cvar.Cvar_Set("r_fullbright", "0"); } R_AnimateLight(); r_framecount++; // build the transformation matrix for the given view angles r_origin = r_refdef.vieworg; Mathlib.AngleVectors(ref r_refdef.viewangles, out vpn, out vright, out vup); // current viewleaf r_oldviewleaf = r_viewleaf; r_viewleaf = Mod_PointInLeaf(ref r_origin, cl.worldmodel); game_engine.V_SetContentsColor(r_viewleaf.contents); game_engine.V_CalcBlend(); r_cache_thrash = false; c_brush_polys = 0; c_alias_polys = 0; }
static void S_UpdateAmbientSounds() { if (!snd_ambient) { return; } // calc ambient sound levels if (cl.worldmodel == null) { return; } mleaf_t l = Mod_PointInLeaf(ref listener_origin, cl.worldmodel); if (l == null || ambient_level.value == 0) { for (int i = 0; i < q_shared.NUM_AMBIENTS; i++) { channels[i].sfx = null; } return; } for (int i = 0; i < q_shared.NUM_AMBIENTS; i++) { channel_t chan = channels[i]; chan.sfx = ambient_sfx[i]; float vol = ambient_level.value * l.ambient_sound_level[i]; if (vol < 8) { vol = 0; } // don't adjust volume too fast if (chan.master_vol < vol) { chan.master_vol += (int)(host_framtime * ambient_fade.value); if (chan.master_vol > vol) { chan.master_vol = (int)vol; } } else if (chan.master_vol > vol) { chan.master_vol -= (int)(host_framtime * ambient_fade.value); if (chan.master_vol < vol) { chan.master_vol = (int)vol; } } chan.leftvol = chan.rightvol = chan.master_vol; } }
public static void R_NewMap() { for (int i = 0; i < 256; i++) { d_lightstylevalue[i] = 264; // normal light value } r_worldentity.Clear(); r_worldentity.model = cl.worldmodel; // clear out efrags in case the level hasn't been reloaded // FIXME: is this one short? for (int i = 0; i < cl.worldmodel.numleafs; i++) { cl.worldmodel.leafs[i].efrags = null; } r_viewleaf = null; R_ClearParticles(); GL_BuildLightmaps(); // identify sky texture skytexturenum = -1; mirrortexturenum = -1; model_t world = cl.worldmodel; for (int i = 0; i < world.numtextures; i++) { if (world.textures[i] == null) { continue; } if (world.textures[i].name != null) { if (world.textures[i].name.StartsWith("sky")) { skytexturenum = i; } if (world.textures[i].name.StartsWith("window02_1")) { mirrortexturenum = i; } } world.textures[i].texturechain = null; } }
public static void SV_FindTouchedLeafs(edict_t ent, mnodebase_t node) { if (node.contents == q_shared.CONTENTS_SOLID) { return; } // add an efrag if the node is a leaf if (node.contents < 0) { if (ent.num_leafs == q_shared.MAX_ENT_LEAFS) { return; } mleaf_t leaf = (mleaf_t)node; int leafnum = Array.IndexOf(sv.worldmodel.leafs, leaf) - 1; ent.leafnums[ent.num_leafs] = (short)leafnum; ent.num_leafs++; return; } // NODE_MIXED mnode_t n = (mnode_t)node; mplane_t splitplane = n.plane; int sides = Mathlib.BoxOnPlaneSide(ref ent.v.absmin, ref ent.v.absmax, splitplane); // recurse down the contacted sides if ((sides & 1) != 0) { SV_FindTouchedLeafs(ent, n.children[0]); } if ((sides & 2) != 0) { SV_FindTouchedLeafs(ent, n.children[1]); } }
public static void R_RemoveEfrags(entity_t ent) { efrag_t ef = ent.efrag; while (ef != null) { mleaf_t leaf = ef.leaf; while (true) { efrag_t walk = leaf.efrags; if (walk == null) { break; } if (walk == ef) { // remove this fragment leaf.efrags = ef.leafnext; break; } else { leaf = (mleaf_t)(object)walk.leafnext; } } efrag_t old = ef; ef = ef.entnext; // put it on the free list old.entnext = cl.free_efrags; cl.free_efrags = old; } ent.efrag = null; }
static int PF_newcheckclient(int check) { // cycle to the next one if (check < 1) { check = 1; } if (check > svs.maxclients) { check = svs.maxclients; } int i = check + 1; if (check == svs.maxclients) { i = 1; } edict_t ent; for (; ; i++) { if (i == svs.maxclients + 1) { i = 1; } ent = EDICT_NUM(i); if (i == check) { break; // didn't find anything else } if (ent.free) { continue; } if (ent.v.health <= 0) { continue; } if (((int)ent.v.flags & q_shared.FL_NOTARGET) != 0) { continue; } // anything that is a client, or has a client as an enemy break; } // get the PVS for the entity Vector3 org = ToVector(ref ent.v.origin) + ToVector(ref ent.v.view_ofs); mleaf_t leaf = Mod_PointInLeaf(ref org, sv.worldmodel); byte[] pvs = Mod_LeafPVS(leaf, sv.worldmodel); Buffer.BlockCopy(pvs, 0, checkpvs, 0, pvs.Length); return(i); }
public static void R_RecursiveWorldNode(mnodebase_t node) { if (node.contents == q_shared.CONTENTS_SOLID) { return; // solid } if (node.visframe != r_visframecount) { return; } if (R_CullBox(ref node.mins, ref node.maxs)) { return; } int c; // if a leaf node, draw stuff if (node.contents < 0) { mleaf_t pleaf = (mleaf_t)node; msurface_t[] marks = pleaf.marksurfaces; int mark = pleaf.firstmarksurface; c = pleaf.nummarksurfaces; if (c != 0) { do { marks[mark].visframe = r_framecount; mark++; } while (--c != 0); } // deal with model fragments in this leaf if (pleaf.efrags != null) { R_StoreEfrags(pleaf.efrags); } return; } // node is just a decision point, so go down the apropriate sides mnode_t n = (mnode_t)node; // find which side of the node we are on mplane_t plane = n.plane; double dot; switch (plane.type) { case q_shared.PLANE_X: dot = modelorg.X - plane.dist; break; case q_shared.PLANE_Y: dot = modelorg.Y - plane.dist; break; case q_shared.PLANE_Z: dot = modelorg.Z - plane.dist; break; default: dot = Vector3.Dot(modelorg, plane.normal) - plane.dist; break; } int side = (dot >= 0 ? 0 : 1); // recurse down the children, front side first R_RecursiveWorldNode(n.children[side]); // draw stuff c = n.numsurfaces; if (c != 0) { msurface_t[] surf = cl.worldmodel.surfaces; int offset = n.firstsurface; if (dot < 0 - q_shared.BACKFACE_EPSILON) { side = q_shared.SURF_PLANEBACK; } else if (dot > q_shared.BACKFACE_EPSILON) { side = 0; } for (; c != 0; c--, offset++) { if (surf[offset].visframe != r_framecount) { continue; } // don't backface underwater surfaces, because they warp if ((surf[offset].flags & q_shared.SURF_UNDERWATER) == 0 && ((dot < 0) ^ ((surf[offset].flags & q_shared.SURF_PLANEBACK) != 0))) { continue; // wrong side } // if sorting by texture, just store it out if (gl_texsort.value != 0) { if (!mirror || surf[offset].texinfo.texture != cl.worldmodel.textures[mirrortexturenum]) { surf[offset].texturechain = surf[offset].texinfo.texture.texturechain; surf[offset].texinfo.texture.texturechain = surf[offset]; } } else if ((surf[offset].flags & q_shared.SURF_DRAWSKY) != 0) { surf[offset].texturechain = skychain; skychain = surf[offset]; } else if ((surf[offset].flags & q_shared.SURF_DRAWTURB) != 0) { surf[offset].texturechain = waterchain; waterchain = surf[offset]; } else { R_DrawSequentialPoly(surf[offset]); } } } // recurse down the back side R_RecursiveWorldNode(n.children[side == 0 ? 1 : 0]); }
public static byte[] Mod_LeafPVS(mleaf_t leaf, model_t model) { if (leaf == model.leafs[0]) return mod_novis; return Mod_DecompressVis (leaf.compressed_vis, model); }
/* ================= Mod_LoadLeafs ================= */ static void Mod_LoadLeafs(bspfile.lump_t l) { bspfile.dleaf_t[] @in; mleaf_t[] @out; int i, j, count, p; if ((l.filelen % bspfile.sizeof_dleaf_t) != 0) sys_linux.Sys_Error ("MOD_LoadBmodel: funny lump size in " + loadmodel.name); count = l.filelen / bspfile.sizeof_dleaf_t; bspfile.ByteBuffer buf = new bspfile.ByteBuffer(mod_base, l.fileofs); @in = new bspfile.dleaf_t[count]; @out = new mleaf_t[count]; for (int kk = 0; kk < count; kk++) { @in[kk] = (bspfile.dleaf_t)buf; buf.ofs += bspfile.sizeof_dleaf_t; @out[kk] = new mleaf_t(); } loadmodel.leafs = @out; loadmodel.numleafs = count; for ( i=0 ; i<count ; i++) { for (j=0 ; j<3 ; j++) { @out[i].minmaxs[j] = @in[i].mins[j]; @out[i].minmaxs[3+j] = @in[i].maxs[j]; } p = @in[i].contents; @out[i].contents = p; @out[i].firstmarksurface = new helper.ObjectBuffer(loadmodel.marksurfaces, @in[i].firstmarksurface); @out[i].nummarksurfaces = @in[i].nummarksurfaces; p = @in[i].visofs; if (p == -1) @out[i].compressed_vis = null; else @out[i].compressed_vis = new bspfile.ByteBuffer(loadmodel.visdata, p); @out[i].efrags = null; for (j=0 ; j<4 ; j++) @out[i].ambient_sound_level[j] = @in[i].ambient_level[j]; } }
public virtual void R_RecursiveWorldNode(mnode_t node) { if (node.contents == Defines.CONTENTS_SOLID) { return; } if (node.visframe != r_visframecount) { return; } if (R_CullBox(node.mins, node.maxs)) { return; } Int32 c; msurface_t mark; if (node.contents != -1) { mleaf_t pleaf = ( mleaf_t )node; if (r_newrefdef.areabits != null) { if (((r_newrefdef.areabits[pleaf.area >> 3] & 0xFF) & (1 << (pleaf.area & 7))) == 0) { return; } } var markp = 0; mark = pleaf.GetMarkSurface(markp); c = pleaf.nummarksurfaces; if (c != 0) { do { mark.visframe = r_framecount; mark = pleaf.GetMarkSurface(++markp); }while (--c != 0); } return; } cplane_t plane = node.plane; Single dot; switch (plane.type) { case Defines.PLANE_X: dot = modelorg[0] - plane.dist; break; case Defines.PLANE_Y: dot = modelorg[1] - plane.dist; break; case Defines.PLANE_Z: dot = modelorg[2] - plane.dist; break; default: dot = Math3D.DotProduct(modelorg, plane.normal) - plane.dist; break; } Int32 side, sidebit; if (dot >= 0F) { side = 0; sidebit = 0; } else { side = 1; sidebit = Defines.SURF_PLANEBACK; } R_RecursiveWorldNode(node.children[side]); msurface_t surf; image_t image; for (c = 0; c < node.numsurfaces; c++) { surf = r_worldmodel.surfaces[node.firstsurface + c]; if (surf.visframe != r_framecount) { continue; } if ((surf.flags & Defines.SURF_PLANEBACK) != sidebit) { continue; } if ((surf.texinfo.flags & Defines.SURF_SKY) != 0) { R_AddSkySurface(surf); } else if ((surf.texinfo.flags & (Defines.SURF_TRANS33 | Defines.SURF_TRANS66)) != 0) { surf.texturechain = r_alpha_surfaces; r_alpha_surfaces = surf; } else { if ((surf.flags & Defines.SURF_DRAWTURB) == 0) { GL_RenderLightmappedPoly(surf); } else { image = R_TextureAnimation(surf.texinfo); surf.texturechain = image.texturechain; image.texturechain = surf; } } } R_RecursiveWorldNode(node.children[1 - side]); }
public static void R_SplitEntityOnNode(mnodebase_t node) { if (node.contents == q_shared.CONTENTS_SOLID) { return; } // add an efrag if the node is a leaf if (node.contents < 0) { if (r_pefragtopnode == null) { r_pefragtopnode = node as mnode_t; } mleaf_t leaf = (mleaf_t)(object)node; // grab an efrag off the free list efrag_t ef = cl.free_efrags; if (ef == null) { Con_Printf("Too many efrags!\n"); return; // no free fragments... } cl.free_efrags = cl.free_efrags.entnext; ef.entity = r_addent; // add the entity link // *lastlink = ef; if (_LastObj is entity_t) { ((entity_t)_LastObj).efrag = ef; } else { ((efrag_t)_LastObj).entnext = ef; } _LastObj = ef; // lastlink = &ef->entnext; ef.entnext = null; // set the leaf links ef.leaf = leaf; ef.leafnext = leaf.efrags; leaf.efrags = ef; return; } // NODE_MIXED mnode_t n = node as mnode_t; if (n == null) { return; } mplane_t splitplane = n.plane; int sides = Mathlib.BoxOnPlaneSide(ref r_emins, ref r_emaxs, splitplane); if (sides == 3) { // split on this plane // if this is the first splitter of this bmodel, remember it if (r_pefragtopnode == null) { r_pefragtopnode = n; } } // recurse down the contacted sides if ((sides & 1) != 0) { R_SplitEntityOnNode(n.children[0]); } if ((sides & 2) != 0) { R_SplitEntityOnNode(n.children[1]); } }