/// <summary> /// In order to build a BspTree, you have to supply the /// BspTreeBuilder with index an position arrays that are copies of /// the originals, so that they can be modified during the build /// process. The supplied epsilon parameter specifies the absolute /// tolerance value for coplanar triangles. /// </summary> public BspTreeBuilder(int[] triangleVertexIndexArray, V3d[] vertexPositionArray, double absoluteEpsilon, int[] triangleAttributeIndexArray) : base(null, triangleVertexIndexArray, triangleAttributeIndexArray) { m_weightsArray = new WeightedIndex[0][]; m_positionArray = vertexPositionArray; TriangleCountMul3 = m_triangleVertexIndexArray.Length; int triangleCount = TriangleCountMul3 / 3; VertexCount = m_positionArray.Length; m_absoluteEpsilon = absoluteEpsilon; m_originalVertexCount = VertexCount; // simple shuffle-algorithm (imagine the array as a square // from left->right, top->bottom) // address the array now top->bottom, left->right int stride = (int)Fun.Ceiling(Fun.Sqrt(triangleCount + 1.0)); for (int offset = 0; offset < stride; offset++) { for (int ti = offset; ti < triangleCount; ti += stride) { BspNode.AddTriangle(this, ti * 3, ref m_tree); } } TriangleCountMul3 = m_tree.TriangleCount() * 3; }
public void RasterTest(uint raster) { int iraster = (int)raster; V3fCoder coder = new V3fCoder(raster); uint step = 1; bool large = false; if (iraster > 52) { step = 7; large = true; } if (iraster > 591) { step = 63; } if (iraster > 6688) { step = 2039; } int bits = (int)Fun.Ceiling(Fun.Log2(coder.Count)); Test.Begin("normal coder raster {0} ({1} bits)", iraster, bits); /* * Console.WriteLine(" raster = {0}", m_raster); * Console.WriteLine(" rasterMul2Sub1 = {0}", m_r2Sub1); * Console.WriteLine(" doubleRaster = {0}", m_doubleRaster); * Console.WriteLine(" invDoubleRaster = {0}", m_invDoubleRaster); * Console.WriteLine(" edgeBasis = {0}", m_edgeBasis); * Console.WriteLine(" cornerBasis = {0}", m_cornerBasis); */ Test.Begin("testing {0} of {1} codes", 1 + ((long)coder.Count - 1) / (long)step, coder.Count); for (uint code = 0; code < coder.Count; code += step) { V3f dir = coder.Decode(code); uint newCode = coder.Encode(dir); Test.IsTrue(code == newCode); } Test.End(); double minDot = 1.0; float eps = Constant <float> .PositiveTinyValue; float[] factorTable = { 1.0f - eps, 1.0f, 1.0f + eps }; for (int sign = -1; sign < 2; sign += 2) { for (int axis = 0; axis < 3; axis++) { float factor = factorTable[axis]; for (int xi = -2 * iraster; xi <= 2 * iraster; xi++) { if (large && (xi > 3 - 2 * iraster) && (xi < -3)) { continue; } if (large && (xi < 2 * iraster - 3) && (xi > +3)) { continue; } double x = (double)xi * factor / (2 * iraster); #if (!V3FCODER_NO_WARP) x = V3fCoder.SphericalOfBox(x); #endif for (int yi = -2 * iraster; yi <= 2 * iraster; yi++) { if (large && (yi > 3 - 2 * iraster) && (yi < -3)) { continue; } if (large && (yi < 2 * iraster - 3) && (yi > +3)) { continue; } double y = (double)yi * factor / (2 * iraster); #if (!V3FCODER_NO_WARP) y = V3fCoder.SphericalOfBox(y); #endif V3f n = new V3f(0, 0, 0); // init to make compiler h. n[axis] = sign; n[(axis + 1) % 3] = (float)x; n[(axis + 2) % 3] = (float)y; n.Normalize(); uint code = coder.Encode(n); V3f newN = coder.Decode(code); double newDot = V3f.Dot(n, newN); if (newDot < minDot) { minDot = newDot; } } } } } double maxErr = System.Math.Acos(minDot) * 180.0 / System.Math.PI; Report.Line("maximal error {0:g4} degrees", maxErr); Test.End(); }