Esempio n. 1
0
        /// <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();
        }