public virtual void Mod_LoadTexinfo(lump_t l) { texinfo_t in_renamed; mtexinfo_t[] out_renamed; mtexinfo_t step; Int32 i, count; Int32 next; String name; if ((l.filelen % texinfo_t.SIZE) != 0) { Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name); } count = l.filelen / texinfo_t.SIZE; out_renamed = new mtexinfo_t[count]; for (i = 0; i < count; i++) { out_renamed[i] = new mtexinfo_t(); } loadmodel.texinfo = out_renamed; loadmodel.numtexinfo = count; ByteBuffer bb = ByteBuffer.Wrap(mod_base, l.fileofs, l.filelen); bb.Order = ByteOrder.LittleEndian; for (i = 0; i < count; i++) { in_renamed = new texinfo_t(bb); out_renamed[i].vecs = in_renamed.vecs; out_renamed[i].flags = in_renamed.flags; next = in_renamed.nexttexinfo; if (next > 0) { out_renamed[i].next = loadmodel.texinfo[next]; } else { out_renamed[i].next = null; } name = "textures/" + in_renamed.texture + ".wal"; out_renamed[i].image = GL_FindImage(name, it_wall); if (out_renamed[i].image == null) { VID.Printf(Defines.PRINT_ALL, "Couldn't load " + name + '\\'); out_renamed[i].image = r_notexture; } } for (i = 0; i < count; i++) { out_renamed[i].numframes = 1; for (step = out_renamed[i].next; (step != null) && (step != out_renamed[i]); step = step.next) { out_renamed[i].numframes++; } } }
public virtual image_t R_TextureAnimation(mtexinfo_t tex) { if (tex.next == null) { return(tex.image); } var c = currententity.frame % tex.numframes; while (c != 0) { tex = tex.next; c--; } return(tex.image); }
public virtual void CalcSurfaceExtents(msurface_t s) { Single[] mins = new Single[] { 0, 0 }; Single[] maxs = new Single[] { 0, 0 }; Single val; Int32 j, e; mvertex_t v; Int32[] bmins = new[] { 0, 0 }; Int32[] bmaxs = new[] { 0, 0 }; mins[0] = mins[1] = 999999; maxs[0] = maxs[1] = -99999; mtexinfo_t tex = s.texinfo; for (var i = 0; i < s.numedges; i++) { e = loadmodel.surfedges[s.firstedge + i]; if (e >= 0) { v = loadmodel.vertexes[loadmodel.edges[e].v[0]]; } else { v = loadmodel.vertexes[loadmodel.edges[-e].v[1]]; } for (j = 0; j < 2; j++) { val = v.position[0] * tex.vecs[j][0] + v.position[1] * tex.vecs[j][1] + v.position[2] * tex.vecs[j][2] + tex.vecs[j][3]; if (val < mins[j]) { mins[j] = val; } if (val > maxs[j]) { maxs[j] = val; } } } for (var i = 0; i < 2; i++) { bmins[i] = ( Int32 )Math.Floor(mins[i] / 16); bmaxs[i] = ( Int32 )Math.Ceiling(maxs[i] / 16); s.texturemins[i] = ( Int16 )(bmins[i] * 16); s.extents[i] = ( Int16 )((bmaxs[i] - bmins[i]) * 16); } }
public static int RecursiveLightPoint(mnodebase_t node, ref Vector3 start, ref Vector3 end) { if (node.contents < 0) { return(-1); // didn't hit anything } mnode_t n = (mnode_t)node; // calculate mid point // FIXME: optimize for axial mplane_t plane = n.plane; float front = Vector3.Dot(start, plane.normal) - plane.dist; float back = Vector3.Dot(end, plane.normal) - plane.dist; int side = front < 0 ? 1 : 0; if ((back < 0 ? 1 : 0) == side) { return(RecursiveLightPoint(n.children[side], ref start, ref end)); } float frac = front / (front - back); Vector3 mid = start + (end - start) * frac; // go down front side int r = RecursiveLightPoint(n.children[side], ref start, ref mid); if (r >= 0) { return(r); // hit something } if ((back < 0 ? 1 : 0) == side) { return(-1); // didn't hit anuthing } // check for impact on this node lightspot = mid; lightplane = plane; msurface_t[] surf = cl.worldmodel.surfaces; int offset = n.firstsurface; for (int i = 0; i < n.numsurfaces; i++, offset++) { if ((surf[offset].flags & q_shared.SURF_DRAWTILED) != 0) { continue; // no lightmaps } mtexinfo_t tex = surf[offset].texinfo; int s = (int)(Vector3.Dot(mid, tex.vecs[0].Xyz) + tex.vecs[0].W); int t = (int)(Vector3.Dot(mid, tex.vecs[1].Xyz) + tex.vecs[1].W); if (s < surf[offset].texturemins[0] || t < surf[offset].texturemins[1]) { continue; } int ds = s - surf[offset].texturemins[0]; int dt = t - surf[offset].texturemins[1]; if (ds > surf[offset].extents[0] || dt > surf[offset].extents[1]) { continue; } if (surf[offset].sample_base == null) { return(0); } ds >>= 4; dt >>= 4; byte[] lightmap = surf[offset].sample_base; int lmOffset = surf[offset].sampleofs; short[] extents = surf[offset].extents; r = 0; if (lightmap != null) { lmOffset += dt * ((extents[0] >> 4) + 1) + ds; for (int maps = 0; maps < q_shared.MAXLIGHTMAPS && surf[offset].styles[maps] != 255; maps++) { int scale = d_lightstylevalue[surf[offset].styles[maps]]; r += lightmap[lmOffset] * scale; lmOffset += ((extents[0] >> 4) + 1) * ((extents[1] >> 4) + 1); } r >>= 8; } return(r); } // go down back side return(RecursiveLightPoint(n.children[side == 0 ? 1 : 0], ref mid, ref end)); }
public static void R_AddDynamicLights(msurface_t surf) { int smax = (surf.extents[0] >> 4) + 1; int tmax = (surf.extents[1] >> 4) + 1; mtexinfo_t tex = surf.texinfo; dlight_t[] dlights = cl_dlights; for (int lnum = 0; lnum < q_shared.MAX_DLIGHTS; lnum++) { if ((surf.dlightbits & (1 << lnum)) == 0) { continue; // not lit by this light } float rad = dlights[lnum].radius; float dist = Vector3.Dot(dlights[lnum].origin, surf.plane.normal) - surf.plane.dist; rad -= Math.Abs(dist); float minlight = dlights[lnum].minlight; if (rad < minlight) { continue; } minlight = rad - minlight; Vector3 impact = dlights[lnum].origin - surf.plane.normal * dist; float local0 = Vector3.Dot(impact, tex.vecs[0].Xyz) + tex.vecs[0].W; float local1 = Vector3.Dot(impact, tex.vecs[1].Xyz) + tex.vecs[1].W; local0 -= surf.texturemins[0]; local1 -= surf.texturemins[1]; for (int t = 0; t < tmax; t++) { int td = (int)(local1 - t * 16); if (td < 0) { td = -td; } for (int s = 0; s < smax; s++) { int sd = (int)(local0 - s * 16); if (sd < 0) { sd = -sd; } if (sd > td) { dist = sd + (td >> 1); } else { dist = td + (sd >> 1); } if (dist < minlight) { blocklights[t * smax + s] += (uint)((rad - dist) * 256); } } } } }
/* ================= Mod_LoadTexinfo ================= */ static void Mod_LoadTexinfo(bspfile.lump_t l) { bspfile.texinfo_t[] @in; mtexinfo_t[] @out; int i, j, count; int miptex; double len1, len2; if ((l.filelen % bspfile.sizeof_texinfo_t) != 0) sys_linux.Sys_Error ("MOD_LoadBmodel: funny lump size in " + loadmodel.name); count = l.filelen / bspfile.sizeof_texinfo_t; bspfile.ByteBuffer buf = new bspfile.ByteBuffer(mod_base, l.fileofs); @in = new bspfile.texinfo_t[count]; @out = new mtexinfo_t[count]; for (int kk = 0; kk < count; kk++) { @in[kk] = (bspfile.texinfo_t)buf; buf.ofs += bspfile.sizeof_texinfo_t; @out[kk] = new mtexinfo_t(); } loadmodel.texinfo = @out; loadmodel.numtexinfo = count; for ( i=0 ; i<count ; i++) { for(int k = 0; k < 2; k++) for (j=0 ; j<4 ; j++) @out[i].vecs[k][j] = @in[i].vecs[k][j]; len1 = mathlib.Length (@out[i].vecs[0]); len2 = mathlib.Length (@out[i].vecs[1]); len1 = (len1 + len2)/2; if (len1 < 0.32) @out[i].mipadjust = 4; else if (len1 < 0.49) @out[i].mipadjust = 3; else if (len1 < 0.99) @out[i].mipadjust = 2; else @out[i].mipadjust = 1; miptex = @in[i].miptex; @out[i].flags = @in[i].flags; if (loadmodel.textures == null) { @out[i].texture = render.r_notexture_mip; // checkerboard texture @out[i].flags = 0; } else { if (miptex >= loadmodel.numtextures) sys_linux.Sys_Error ("miptex >= loadmodel.numtextures"); @out[i].texture = loadmodel.textures[miptex]; if (@out[i].texture == null) { @out[i].texture = render.r_notexture_mip; // texture not found @out[i].flags = 0; } } } }
public virtual void R_AddDynamicLights(msurface_t surf) { Int32 sd, td; Single fdist, frad, fminlight; Int32 s, t; dlight_t dl; Single[] pfBL; Single fsacc, ftacc; var smax = (surf.extents[0] >> 4) + 1; var tmax = (surf.extents[1] >> 4) + 1; mtexinfo_t tex = surf.texinfo; Single local0, local1; for (var lnum = 0; lnum < r_newrefdef.num_dlights; lnum++) { if ((surf.dlightbits & (1 << lnum)) == 0) { continue; } dl = r_newrefdef.dlights[lnum]; frad = dl.intensity; fdist = Math3D.DotProduct(dl.origin, surf.plane.normal) - surf.plane.dist; frad -= Math.Abs(fdist); fminlight = DLIGHT_CUTOFF; if (frad < fminlight) { continue; } fminlight = frad - fminlight; for (var i = 0; i < 3; i++) { impact[i] = dl.origin[i] - surf.plane.normal[i] * fdist; } local0 = Math3D.DotProduct(impact, tex.vecs[0]) + tex.vecs[0][3] - surf.texturemins[0]; local1 = Math3D.DotProduct(impact, tex.vecs[1]) + tex.vecs[1][3] - surf.texturemins[1]; pfBL = s_blocklights; var pfBLindex = 0; for (t = 0, ftacc = 0; t < tmax; t++, ftacc += 16) { td = ( Int32 )(local1 - ftacc); if (td < 0) { td = -td; } for (s = 0, fsacc = 0; s < smax; s++, fsacc += 16, pfBLindex += 3) { sd = ( Int32 )(local0 - fsacc); if (sd < 0) { sd = -sd; } if (sd > td) { fdist = sd + (td >> 1); } else { fdist = td + (sd >> 1); } if (fdist < fminlight) { pfBL[pfBLindex + 0] += (frad - fdist) * dl.color[0]; pfBL[pfBLindex + 1] += (frad - fdist) * dl.color[1]; pfBL[pfBLindex + 2] += (frad - fdist) * dl.color[2]; } } } } }