public static int BoxOnPlaneSide2(float[] emins, float[] emaxs, cplane_t p) { for (var i = 0; i < 3; i++) { if (p.normal[i] < 0) { Math3D.corners[0][i] = emins[i]; Math3D.corners[1][i] = emaxs[i]; } else { Math3D.corners[1][i] = emins[i]; Math3D.corners[0][i] = emaxs[i]; } } var dist1 = Math3D.DotProduct(p.normal, Math3D.corners[0]) - p.dist; var dist2 = Math3D.DotProduct(p.normal, Math3D.corners[1]) - p.dist; var sides = 0; if (dist1 >= 0) { sides = 1; } if (dist2 < 0) { sides |= 2; } return(sides); }
public ViewParams() { for (int i = 0; i < 4; i++) { frustum[i] = new cplane_t(); } }
public static int BoxOnPlaneSide2(float[] emins, float[] emaxs, cplane_t p) { for (int i = 0; i < 3; i++) { if (p.normal[i] < 0) { corners[0][i] = emins[i]; corners[1][i] = emaxs[i]; } else { corners[1][i] = emins[i]; corners[0][i] = emaxs[i]; } } float dist1 = DotProduct(p.normal, corners[0]) - p.dist; float dist2 = DotProduct(p.normal, corners[1]) - p.dist; int sides = 0; if (dist1 >= 0) { sides = 1; } if (dist2 < 0) { sides |= 2; } return(sides); }
public Frustrum() { for (int i = 0; i < 4; i++) { frustum[i] = new cplane_t(); } for (int i = 0; i < 3; i++) { axis[i] = Vector3.Zero; } }
public virtual Int32 SignbitsForPlane(cplane_t out_renamed) { var bits = 0; for (var j = 0; j < 3; j++) { if (out_renamed.normal[j] < 0) { bits |= (1 << j); } } return(bits); }
public override void R_MarkLights(dlight_t light, Int32 bit, mnode_t node) { if (node.contents != -1) { return; } cplane_t splitplane = node.plane; var dist = Math3D.DotProduct(light.origin, splitplane.normal) - splitplane.dist; if (dist > light.intensity - DLIGHT_CUTOFF) { R_MarkLights(light, bit, node.children[0]); return; } if (dist < -light.intensity + DLIGHT_CUTOFF) { R_MarkLights(light, bit, node.children[1]); return; } msurface_t surf; Int32 sidebit; for (var i = 0; i < node.numsurfaces; i++) { surf = r_worldmodel.surfaces[node.firstsurface + i]; dist = Math3D.DotProduct(light.origin, surf.plane.normal) - surf.plane.dist; sidebit = (dist >= 0) ? 0 : Defines.SURF_PLANEBACK; if ((surf.flags & Defines.SURF_PLANEBACK) != sidebit) { continue; } if (surf.dlightframe != r_dlightframecount) { surf.dlightbits = 0; surf.dlightframe = r_dlightframecount; } surf.dlightbits |= bit; } R_MarkLights(light, bit, node.children[0]); R_MarkLights(light, bit, node.children[1]); }
public virtual void Mod_LoadPlanes(lump_t l) { Int32 i, j; cplane_t[] out_renamed; qfiles.dplane_t in_renamed; Int32 count; Int32 bits; if ((l.filelen % qfiles.dplane_t.SIZE) != 0) { Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name); } count = l.filelen / qfiles.dplane_t.SIZE; out_renamed = new cplane_t[count * 2]; for (i = 0; i < count; i++) { out_renamed[i] = new cplane_t(); } loadmodel.planes = out_renamed; loadmodel.numplanes = count; ByteBuffer bb = ByteBuffer.Wrap(mod_base, l.fileofs, l.filelen); bb.Order = ByteOrder.LittleEndian; for (i = 0; i < count; i++) { bits = 0; in_renamed = new dplane_t(bb); for (j = 0; j < 3; j++) { out_renamed[i].normal[j] = in_renamed.normal[j]; if (out_renamed[i].normal[j] < 0) { bits |= (1 << j); } } out_renamed[i].dist = in_renamed.dist; out_renamed[i].type = ( Byte )in_renamed.type; out_renamed[i].signbits = ( Byte )bits; } }
public override void Touch(edict_t self, edict_t other, cplane_t plane, csurface_t surf) { if (self.health <= 0) { self.touch = null; return; } if (other.takedamage != 0) { if (Math3D.VectorLength(self.velocity) > 400) { float[] point = new float[] { 0, 0, 0 }; float[] normal = new float[] { 0, 0, 0 }; int damage; Math3D.VectorCopy(self.velocity, normal); Math3D.VectorNormalize(normal); Math3D.VectorMA(self.s.origin, self.maxs[0], normal, point); damage = (int)(40 + 10 * Lib.Random()); GameCombat.T_Damage(other, self, self, self.velocity, point, normal, damage, damage, 0, Defines.MOD_UNKNOWN); } } if (!M.M_CheckBottom(self)) { if (self.groundentity != null) { self.monsterinfo.nextframe = FRAME_attack02; self.touch = null; } return; } self.touch = null; }
/* =================== CM_InitBoxHull Set up the planes and nodes so that the six floats of a bounding box can just be stored out and get a proper clipping hull structure. =================== */ void InitHullBox() { //box_planes = dbrush_t boxbrush = new dbrush_t(); boxbrush.numsides = 6; boxbrush.contents = brushflags.CONTENTS_PLAYERCLIP; brushes.Add(boxbrush); box_brush = boxbrush; box_model = new cmodel_t(); box_model.leaf = new dleaf_t(); box_model.leaf.numleafbrushes = 1; box_model.leaf.firstleafbrush = (ushort)leafbrushes.Count; leafbrushes.Add(brushes.Count); cplane_t[] plan = new cplane_t[6*2]; for (int i = 0; i < 12; i++) { plan[i] = new cplane_t(); } dbrushside_t[] sides = new dbrushside_t[6]; for (int i = 0; i < 6; i++) { sides[i] = new dbrushside_t(); } int numBrushSides = brushsides.Count; for (int i = 0; i < 6; i++) { int side = i & 1; dbrushside_t s = sides[i]; s.plane = plan[i * 2 + side]; // planes cplane_t p = plan[i * 2]; p.type = i >> 1; p.signbits = 0; p.normal = Vector3.Zero; p.normal[i >> 1] = 1; p = planes[i * 2 + 1]; p.type = 3 + (i >> 1); p.signbits = 0; p.normal = Vector3.Zero; p.normal[i >> 1] = -1; Common.SetPlaneSignbits(p); } box_planes.AddRange(plan); planes.AddRange(plan); brushsides.AddRange(sides); }
static void LoadPlanes(BinaryReader br, Header header) { // Read planes br.BaseStream.Seek(header.lumps[1].fileofs, SeekOrigin.Begin); int numPlanes = header.lumps[1].filelen / 20; if (header.lumps[1].filelen % 20 > 0) { Common.Instance.Error("LoadPlanes: Weird plane lumpsize"); } for (int i = 0; i < numPlanes; i++) { cplane_t plane = new cplane_t(); plane.normal = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); plane.dist = br.ReadSingle(); plane.type = br.ReadInt32(); int bits = 0; for (int j = 0; j < 3; j++) { if (plane.normal[j] < 0.0f) bits |= 1 << j; } plane.signbits = (byte)bits; world.planes.Add(plane); } }
public static void SetPlaneSignbits(cplane_t plane) { int bits, j; // for fast box on planeside test bits = 0; for (j = 0; j < 3; j++) { if (plane.normal[j] < 0) { bits |= 1 << j; } } plane.signbits = (byte)bits; }
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]); }
/* ================== BoxOnPlaneSide Returns 1, 2, or 1 + 2 ================== */ public int BoxOnPlaneSide(ref Vector3 mins, ref Vector3 maxs, cplane_t frustum) { // fast axial cases if (frustum.type < 3) { if (frustum.dist <= mins[frustum.type]) return 1; if (frustum.dist >= maxs[frustum.type]) return 2; return 3; } // general case float[] dist = new float[2]; dist[0] = dist[1] = 0f; int b; if (frustum.signbits < 8) { for (int i = 0; i < 3; i++) { b = (frustum.signbits >> i) & 1; dist[(b == 1 ? 1 : 0)] += frustum.normal[i] * maxs[i]; dist[(b != 1 ? 1 : 0)] += frustum.normal[i] * mins[i]; } } int sides = 0; if (dist[0] >= frustum.dist) sides = 1; else if (dist[1] < frustum.dist) sides |= 2; return sides; }
//===================================================================== /** * stellt fest, auf welcher Seite sich die Kiste befindet, wenn die Ebene * durch Entfernung und Senkrechten-Normale gegeben ist. * erste Version mit vec3_t... */ public static int BoxOnPlaneSide(float[] emins, float[] emaxs, cplane_t p) { if (!(emins.Length == 3 && emaxs.Length == 3)) { throw new("vec3_t bug"); } float dist1, dist2; int sides; // fast axial cases if (p.type < 3) { if (p.dist <= emins[p.type]) { return(1); } if (p.dist >= emaxs[p.type]) { return(2); } return(3); } // general case switch (p.signbits) { case 0: dist1 = p.normal[0] * emaxs[0] + p.normal[1] * emaxs[1] + p.normal[2] * emaxs[2]; dist2 = p.normal[0] * emins[0] + p.normal[1] * emins[1] + p.normal[2] * emins[2]; break; case 1: dist1 = p.normal[0] * emins[0] + p.normal[1] * emaxs[1] + p.normal[2] * emaxs[2]; dist2 = p.normal[0] * emaxs[0] + p.normal[1] * emins[1] + p.normal[2] * emins[2]; break; case 2: dist1 = p.normal[0] * emaxs[0] + p.normal[1] * emins[1] + p.normal[2] * emaxs[2]; dist2 = p.normal[0] * emins[0] + p.normal[1] * emaxs[1] + p.normal[2] * emins[2]; break; case 3: dist1 = p.normal[0] * emins[0] + p.normal[1] * emins[1] + p.normal[2] * emaxs[2]; dist2 = p.normal[0] * emaxs[0] + p.normal[1] * emaxs[1] + p.normal[2] * emins[2]; break; case 4: dist1 = p.normal[0] * emaxs[0] + p.normal[1] * emaxs[1] + p.normal[2] * emins[2]; dist2 = p.normal[0] * emins[0] + p.normal[1] * emins[1] + p.normal[2] * emaxs[2]; break; case 5: dist1 = p.normal[0] * emins[0] + p.normal[1] * emaxs[1] + p.normal[2] * emins[2]; dist2 = p.normal[0] * emaxs[0] + p.normal[1] * emins[1] + p.normal[2] * emaxs[2]; break; case 6: dist1 = p.normal[0] * emaxs[0] + p.normal[1] * emins[1] + p.normal[2] * emins[2]; dist2 = p.normal[0] * emins[0] + p.normal[1] * emaxs[1] + p.normal[2] * emaxs[2]; break; case 7: dist1 = p.normal[0] * emins[0] + p.normal[1] * emins[1] + p.normal[2] * emins[2]; dist2 = p.normal[0] * emaxs[0] + p.normal[1] * emaxs[1] + p.normal[2] * emaxs[2]; break; default: dist1 = dist2 = 0; throw new("BoxOnPlaneSide bug"); } sides = 0; if (dist1 >= p.dist) { sides = 1; } if (dist2 < p.dist) { sides |= 2; } if (!(sides != 0)) { throw new("BoxOnPlaneSide(): sides == 0 bug"); } return(sides); }
public virtual Int32 RecursiveLightPoint(mnode_t node, Single[] start, Single[] end) { if (node.contents != -1) { return(-1); } cplane_t plane = node.plane; var front = Math3D.DotProduct(start, plane.normal) - plane.dist; var back = Math3D.DotProduct(end, plane.normal) - plane.dist; var side = (front < 0); var sideIndex = (side) ? 1 : 0; if ((back < 0) == side) { return(RecursiveLightPoint(node.children[sideIndex], start, end)); } var frac = front / (front - back); Single[] mid = Vec3Cache.Get(); mid[0] = start[0] + (end[0] - start[0]) * frac; mid[1] = start[1] + (end[1] - start[1]) * frac; mid[2] = start[2] + (end[2] - start[2]) * frac; var r = RecursiveLightPoint(node.children[sideIndex], start, mid); if (r >= 0) { Vec3Cache.Release(); return(r); } if ((back < 0) == side) { Vec3Cache.Release(); return(-1); } Math3D.VectorCopy(mid, lightspot); lightplane = plane; var surfIndex = node.firstsurface; msurface_t surf; Int32 s, t, ds, dt; mtexinfo_t tex; ByteBuffer lightmap; Int32 maps; for (var i = 0; i < node.numsurfaces; i++, surfIndex++) { surf = r_worldmodel.surfaces[surfIndex]; if ((surf.flags & (Defines.SURF_DRAWTURB | Defines.SURF_DRAWSKY)) != 0) { continue; } tex = surf.texinfo; s = ( Int32 )(Math3D.DotProduct(mid, tex.vecs[0]) + tex.vecs[0][3]); t = ( Int32 )(Math3D.DotProduct(mid, tex.vecs[1]) + tex.vecs[1][3]); if (s < surf.texturemins[0] || t < surf.texturemins[1]) { continue; } ds = s - surf.texturemins[0]; dt = t - surf.texturemins[1]; if (ds > surf.extents[0] || dt > surf.extents[1]) { continue; } if (surf.samples == null) { return(0); } ds >>= 4; dt >>= 4; lightmap = surf.samples; var lightmapIndex = 0; Math3D.VectorCopy(Globals.vec3_origin, pointcolor); if (lightmap != null) { Single[] rgb; lightmapIndex += 3 * (dt * ((surf.extents[0] >> 4) + 1) + ds); Single scale0, scale1, scale2; for (maps = 0; maps < Defines.MAXLIGHTMAPS && surf.styles[maps] != ( Byte )255; maps++) { rgb = r_newrefdef.lightstyles[surf.styles[maps] & 0xFF].rgb; scale0 = gl_modulate.value * rgb[0]; scale1 = gl_modulate.value * rgb[1]; scale2 = gl_modulate.value * rgb[2]; pointcolor[0] += (lightmap.Get(lightmapIndex + 0) & 0xFF) * scale0 * (1F / 255); pointcolor[1] += (lightmap.Get(lightmapIndex + 1) & 0xFF) * scale1 * (1F / 255); pointcolor[2] += (lightmap.Get(lightmapIndex + 2) & 0xFF) * scale2 * (1F / 255); lightmapIndex += 3 * ((surf.extents[0] >> 4) + 1) * ((surf.extents[1] >> 4) + 1); } } Vec3Cache.Release(); return(1); } r = RecursiveLightPoint(node.children[1 - sideIndex], mid, end); Vec3Cache.Release(); return(r); }
void ReadPlanes(Header header, BinaryReader br) { // Read planes br.BaseStream.Seek(header.lumps[1].fileofs, SeekOrigin.Begin); int numPlanes = header.lumps[1].filelen / 20; for (int i = 0; i < numPlanes; i++) { cplane_t plane = new cplane_t(); plane.normal = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); plane.dist = br.ReadSingle(); plane.type = br.ReadInt32(); int bits = 0; for (int j = 0; j < 3; j++) { if (plane.normal[j] < 0) bits |= 1 << j; } plane.signbits = (byte)bits; planes.Add(plane); } }
public static int BoxOnPlaneSide(float[] emins, float[] emaxs, cplane_t p) { float dist1, dist2; int sides; if (p.type < 3) { if (p.dist <= emins[p.type]) { return(1); } if (p.dist >= emaxs[p.type]) { return(2); } return(3); } switch (p.signbits) { case 0: dist1 = p.normal[0] * emaxs[0] + p.normal[1] * emaxs[1] + p.normal[2] * emaxs[2]; dist2 = p.normal[0] * emins[0] + p.normal[1] * emins[1] + p.normal[2] * emins[2]; break; case 1: dist1 = p.normal[0] * emins[0] + p.normal[1] * emaxs[1] + p.normal[2] * emaxs[2]; dist2 = p.normal[0] * emaxs[0] + p.normal[1] * emins[1] + p.normal[2] * emins[2]; break; case 2: dist1 = p.normal[0] * emaxs[0] + p.normal[1] * emins[1] + p.normal[2] * emaxs[2]; dist2 = p.normal[0] * emins[0] + p.normal[1] * emaxs[1] + p.normal[2] * emins[2]; break; case 3: dist1 = p.normal[0] * emins[0] + p.normal[1] * emins[1] + p.normal[2] * emaxs[2]; dist2 = p.normal[0] * emaxs[0] + p.normal[1] * emaxs[1] + p.normal[2] * emins[2]; break; case 4: dist1 = p.normal[0] * emaxs[0] + p.normal[1] * emaxs[1] + p.normal[2] * emins[2]; dist2 = p.normal[0] * emins[0] + p.normal[1] * emins[1] + p.normal[2] * emaxs[2]; break; case 5: dist1 = p.normal[0] * emins[0] + p.normal[1] * emaxs[1] + p.normal[2] * emins[2]; dist2 = p.normal[0] * emaxs[0] + p.normal[1] * emins[1] + p.normal[2] * emaxs[2]; break; case 6: dist1 = p.normal[0] * emaxs[0] + p.normal[1] * emins[1] + p.normal[2] * emins[2]; dist2 = p.normal[0] * emins[0] + p.normal[1] * emaxs[1] + p.normal[2] * emaxs[2]; break; case 7: dist1 = p.normal[0] * emins[0] + p.normal[1] * emins[1] + p.normal[2] * emins[2]; dist2 = p.normal[0] * emaxs[0] + p.normal[1] * emaxs[1] + p.normal[2] * emaxs[2]; break; default: dist1 = dist2 = 0; break; } sides = 0; if (dist1 >= p.dist) { sides = 1; } if (dist2 < p.dist) { sides |= 2; } return(sides); }
protected float[] lightspot = { 0, 0, 0 }; // vec3_t private int RecursiveLightPoint(mnode_t node, float[] start, float[] end) { if (node.contents != -1) { return(-1); // didn't hit anything } msurface_t surf; int s, t, ds, dt; int i; mtexinfo_t tex; int maps; float[] mid = { 0, 0, 0 }; // calculate mid point // FIXME: optimize for axial var plane = node.plane; var front = Math3D.DotProduct(start, plane.normal) - plane.dist; var back = Math3D.DotProduct(end, plane.normal) - plane.dist; var side = front < 0; var sideIndex = side ? 1 : 0; if (back < 0 == side) { return(this.RecursiveLightPoint(node.children[sideIndex], start, end)); } var frac = front / (front - back); mid[0] = start[0] + (end[0] - start[0]) * frac; mid[1] = start[1] + (end[1] - start[1]) * frac; mid[2] = start[2] + (end[2] - start[2]) * frac; // go down front side var r = this.RecursiveLightPoint(node.children[sideIndex], start, mid); if (r >= 0) { return(r); // hit something } if (back < 0 == side) { return(-1); // didn't hit anuthing } // check for impact on this node Math3D.VectorCopy(mid, this.lightspot); this.lightplane = plane; var surfIndex = node.firstsurface; float[] scale = { 0, 0, 0 }; for (i = 0; i < node.numsurfaces; i++, surfIndex++) { surf = this.r_worldmodel.surfaces[surfIndex]; if ((surf.flags & (Defines.SURF_DRAWTURB | Defines.SURF_DRAWSKY)) != 0) { continue; // no lightmaps } tex = surf.texinfo; s = (int)(Math3D.DotProduct(mid, tex.vecs[0]) + tex.vecs[0][3]); t = (int)(Math3D.DotProduct(mid, tex.vecs[1]) + tex.vecs[1][3]); if (s < surf.texturemins[0] || t < surf.texturemins[1]) { continue; } ds = s - surf.texturemins[0]; dt = t - surf.texturemins[1]; if (ds > surf.extents[0] || dt > surf.extents[1]) { continue; } if (surf.samples == null) { return(0); } ds >>= 4; dt >>= 4; var lightmapIndex = 0; Math3D.VectorCopy(Globals.vec3_origin, this.pointcolor); if (surf.samples != null) { //float[] scale = {0, 0, 0}; float[] rgb; lightmapIndex += 3 * (dt * ((surf.extents[0] >> 4) + 1) + ds); for (maps = 0; maps < Defines.MAXLIGHTMAPS && surf.styles[maps] != (byte)255; maps++) { rgb = this.r_newrefdef.lightstyles[surf.styles[maps] & 0xFF].rgb; scale[0] = this.gl_modulate.value * rgb[0]; scale[1] = this.gl_modulate.value * rgb[1]; scale[2] = this.gl_modulate.value * rgb[2]; this.pointcolor[0] += surf.samples[surf.samplesOffset + lightmapIndex + 0] * scale[0] * (1.0f / 255); this.pointcolor[1] += surf.samples[surf.samplesOffset + lightmapIndex + 1] * scale[1] * (1.0f / 255); this.pointcolor[2] += surf.samples[surf.samplesOffset + lightmapIndex + 2] * scale[2] * (1.0f / 255); lightmapIndex += 3 * ((surf.extents[0] >> 4) + 1) * ((surf.extents[1] >> 4) + 1); } } return(1); } // go down back side return(this.RecursiveLightPoint(node.children[1 - sideIndex], mid, end)); }
public static double CurrentDistFromPlane(cplane_t plane) { return Math.Abs(Vector3.Dot(Renderer.Instance.Camera.position, plane.normal) - plane.dist); }
private byte SignbitsForPlane(cplane_t plane) { int bits = 0; // for fast box on planeside test for (int j = 0; j < 3; j++) { if (plane.normal[j] < 0) bits |= 1 << j; } return (byte)bits; }