Beispiel #1
0
 /// <summary>
 /// Creates a view tranformation from the given vectors.
 /// Transformation from world- into view-space.
 /// </summary>
 /// <param name="location">Origin of the view</param>
 /// <param name="right">Right vector of the view-plane</param>
 /// <param name="up">Up vector of the view-plane</param>
 /// <param name="normal">Normal vector of the view-plane. This vector is suppsoed to point in view-direction for a left-handed view transformation and in opposit direction in the right-handed case.</param>
 /// <returns>The view transformation</returns>
 public static M44f ViewTrafo(V3f location, V3f right, V3f up, V3f normal)
 {
     return(new M44f(
                right.X, right.Y, right.Z, -location.Dot(right),
                up.X, up.Y, up.Z, -location.Dot(up),
                normal.X, normal.Y, normal.Z, -location.Dot(normal),
                0, 0, 0, 1
                ));
 }
 // https://stackoverflow.com/questions/1171849/finding-quaternion-representing-the-rotation-from-one-vector-to-another
 public static Rot3f HalfWayVec(V3f from, V3f into)
 {
     if (from.Dot(into).ApproximateEquals(-1))
     {
         return(new Rot3f(0, from.AxisAlignedNormal()));
     }
     else
     {
         V3f         half = Vec.Normalized(from + into);
         QuaternionF q    = new QuaternionF(Vec.Dot(from, half), Vec.Cross(from, half));
         return(new Rot3f(q.Normalized));
     }
 }
        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();
        }