private VolumeIntegrals GetVolumeIntegrals() { VolumeIntegrals integrals = new VolumeIntegrals(); int polyCount = _polygons.Length; for (int i = 0; i < polyCount; i++) { TraceModelPolygon poly = _polygons[i]; float nx = idMath.Abs(poly.Normal.X); float ny = idMath.Abs(poly.Normal.Y); float nz = idMath.Abs(poly.Normal.Z); int c = 0; if ((nx > ny) && (nx > nz)) { c = 0; } else { c = (ny > nz) ? 1 : 2; } int a = (c + 1) % 3; int b = (a + 1) % 3; PolygonIntegrals pi = GetPolygonIntegrals(i, a, b, c); integrals.T0 += poly.Normal.X * ((a == 0) ? pi.Fa : ((b == 0) ? pi.Fb : pi.Fc)); if (a == 0) { integrals.T1.X += poly.Normal.X * pi.Faa; integrals.T2.X += poly.Normal.X * pi.Faaa; integrals.TP.X += poly.Normal.X * pi.Faab; } else if (a == 1) { integrals.T1.Y += poly.Normal.Y * pi.Faa; integrals.T2.Y += poly.Normal.Y * pi.Faaa; integrals.TP.Y += poly.Normal.Y * pi.Faab; } else if (a == 2) { integrals.T1.Z += poly.Normal.Z * pi.Faa; integrals.T2.Z += poly.Normal.Z * pi.Faaa; integrals.TP.Z += poly.Normal.Z * pi.Faab; } if (b == 0) { integrals.T1.X += poly.Normal.X * pi.Fbb; integrals.T2.X += poly.Normal.X * pi.Fbbb; integrals.TP.X += poly.Normal.X * pi.Fbbc; } else if (b == 1) { integrals.T1.Y += poly.Normal.Y * pi.Fbb; integrals.T2.Y += poly.Normal.Y * pi.Fbbb; integrals.TP.Y += poly.Normal.Y * pi.Fbbc; } else if (b == 2) { integrals.T1.Z += poly.Normal.Z * pi.Fbb; integrals.T2.Z += poly.Normal.Z * pi.Fbbb; integrals.TP.Z += poly.Normal.Z * pi.Fbbc; } if (c == 0) { integrals.T1.X += poly.Normal.X * pi.Fcc; integrals.T2.X += poly.Normal.X * pi.Fccc; integrals.TP.X += poly.Normal.X * pi.Fcca; } else if (c == 1) { integrals.T1.Y += poly.Normal.Y * pi.Fcc; integrals.T2.Y += poly.Normal.Y * pi.Fccc; integrals.TP.Y += poly.Normal.Y * pi.Fcca; } else if (c == 2) { integrals.T1.Z += poly.Normal.Z * pi.Fcc; integrals.T2.Z += poly.Normal.Z * pi.Fccc; integrals.TP.Z += poly.Normal.Z * pi.Fcca; } } integrals.T1 *= 0.5f; integrals.T2 *= (1.0f / 3.0f); integrals.TP *= 0.5f; return(integrals); }
private ProjectionIntegrals GetProjectionIntegrals(int polyNumber, int a, int b) { ProjectionIntegrals integrals = new ProjectionIntegrals(); TraceModelPolygon polygon = _polygons[polyNumber]; int count = polygon.Edges.Length; for (int i = 0; i < count; i++) { int edgeNumber = polygon.Edges[i]; Vector3 v1 = _vertices[_edges[(int)idMath.Abs(edgeNumber)].V[(edgeNumber < 0) ? 1 : 0]]; Vector3 v2 = _vertices[_edges[(int)idMath.Abs(edgeNumber)].V[(edgeNumber > 0) ? 1 : 0]]; float a0 = v1.Get(a); float b0 = v1.Get(b); float a1 = v2.Get(a); float b1 = v2.Get(b); float da = a1 - a0; float db = b1 - b0; float a0_2 = a0 * a0; float a0_3 = a0_2 * a0; float a0_4 = a0_3 * a0; float b0_2 = b0 * b0; float b0_3 = b0_2 * b0; float b0_4 = b0_3 * b0; float a1_2 = a1 * a1; float a1_3 = a1_2 * a1; float b1_2 = b1 * b1; float b1_3 = b1_2 * b1; float C1 = a1 + a0; float Ca = a1 * C1 + a0_2; float Caa = a1 * Ca + a0_3; float Caaa = a1 * Caa + a0_4; float Cb = b1 * (b1 + b0) + b0_2; float Cbb = b1 * Cb + b0_3; float Cbbb = b1 * Cbb + b0_4; float Cab = 3 * a1_2 + 2 * a1 * a0 + a0_2; float Kab = a1_2 + 2 * a1 * a0 + 3 * a0_2; float Caab = a0 * Cab + 4 * a1_3; float Kaab = a1 * Kab + 4 * a0_3; float Cabb = 4 * b1_3 + 3 * b1_2 * b0 + 2 * b1 * b0_2 + b0_3; float Kabb = b1_3 + 2 * b1_2 * b0 + 3 * b1 * b0_2 + 4 * b0_3; integrals.P1 += db * C1; integrals.Pa += db * Ca; integrals.Paa += db * Caa; integrals.Paaa += db * Caaa; integrals.Pb += da * Cb; integrals.Pbb += da * Cbb; integrals.Pbbb += da * Cbbb; integrals.Pab += db * (b1 * Cab + b0 * Kab); integrals.Paab += db * (b1 * Caab + b0 * Kaab); integrals.Pabb += da * (a1 * Cabb + a0 * Kabb); } integrals.P1 *= (1.0f / 2.0f); integrals.Pa *= (1.0f / 6.0f); integrals.Paa *= (1.0f / 12.0f); integrals.Paaa *= (1.0f / 20.0f); integrals.Pb *= (1.0f / -6.0f); integrals.Pbb *= (1.0f / -12.0f); integrals.Pbbb *= (1.0f / -20.0f); integrals.Pab *= (1.0f / 24.0f); integrals.Paab *= (1.0f / 60.0f); integrals.Pabb *= (1.0f / -60.0f); return(integrals); }