public virtual void SubdividePolygon(int numverts, float[][] verts) { int i, j, k; float m; float[][] front = Lib.CreateJaggedArray <float[][]>(64, 3); float[][] back = Lib.CreateJaggedArray <float[][]>(64, 3); int f, b; float[] dist = new float[64]; float frac; if (numverts > 60) { Com.Error(Defines.ERR_DROP, "numverts = " + numverts); } float[] mins = Vec3Cache.Get(); float[] maxs = Vec3Cache.Get(); BoundPoly(numverts, verts, mins, maxs); float[] v; for (i = 0; i < 3; i++) { m = (mins[i] + maxs[i]) * 0.5F; m = SUBDIVIDE_SIZE * (float)Math.Floor(m / SUBDIVIDE_SIZE + 0.5F); if (maxs[i] - m < 8) { continue; } if (m - mins[i] < 8) { continue; } for (j = 0; j < numverts; j++) { dist[j] = verts[j][i] - m; } dist[j] = dist[0]; Math3D.VectorCopy(verts[0], verts[numverts]); f = b = 0; for (j = 0; j < numverts; j++) { v = verts[j]; if (dist[j] >= 0) { Math3D.VectorCopy(v, front[f]); f++; } if (dist[j] <= 0) { Math3D.VectorCopy(v, back[b]); b++; } if (dist[j] == 0 || dist[j + 1] == 0) { continue; } if ((dist[j] > 0) != (dist[j + 1] > 0)) { frac = dist[j] / (dist[j] - dist[j + 1]); for (k = 0; k < 3; k++) { front[f][k] = back[b][k] = v[k] + frac * (verts[j + 1][k] - v[k]); } f++; b++; } } SubdividePolygon(f, front); SubdividePolygon(b, back); Vec3Cache.Release(2); return; } Vec3Cache.Release(2); glpoly_t poly = Polygon.Create(numverts + 2); poly.next = warpface.polys; warpface.polys = poly; float[] total = Vec3Cache.Get(); Math3D.VectorClear(total); float total_s = 0; float total_t = 0; float s, t; for (i = 0; i < numverts; i++) { poly.X(i + 1, verts[i][0]); poly.Y(i + 1, verts[i][1]); poly.Z(i + 1, verts[i][2]); s = Math3D.DotProduct(verts[i], warpface.texinfo.vecs[0]); t = Math3D.DotProduct(verts[i], warpface.texinfo.vecs[1]); total_s += s; total_t += t; Math3D.VectorAdd(total, verts[i], total); poly.S1(i + 1, s); poly.T1(i + 1, t); } float scale = 1F / numverts; poly.X(0, total[0] * scale); poly.Y(0, total[1] * scale); poly.Z(0, total[2] * scale); poly.S1(0, total_s * scale); poly.T1(0, total_t * scale); poly.X(i + 1, poly.X(1)); poly.Y(i + 1, poly.Y(1)); poly.Z(i + 1, poly.Z(1)); poly.S1(i + 1, poly.S1(1)); poly.T1(i + 1, poly.T1(1)); poly.S2(i + 1, poly.S2(1)); poly.T2(i + 1, poly.T2(1)); Vec3Cache.Release(); }
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); }