Example #1
0
        public override bool FindIntersection(Ray ray, out Intersection intersect)
        {
            intersect = new Intersection();
            const float A          = 1.0f;
            Vector3D    viewPosRel = ray.Origin - this.center; // Origin relative to center
            float       udotp      = (ray.Direction * viewPosRel);
            float       B          = (udotp + udotp + udotp + udotp);
            float       RadiiSqSum = this.majorRadius2 + this.minorRadius2;
            float       ucdotp     = (this.axisC * viewPosRel);
            float       ucdotu     = (this.axisC * ray.Direction);
            float       pSq        = (viewPosRel * viewPosRel);
            float       C          = B * udotp + (pSq + pSq) - (RadiiSqSum + RadiiSqSum) + 4.0f * this.majorRadius2 * ucdotu * ucdotu;
            float       D          = 4.0f * ((pSq - RadiiSqSum) * udotp + (this.majorRadius2 + this.majorRadius2) * ucdotp * ucdotu);
            float       E          = (pSq - (RadiiSqSum + RadiiSqSum)) * pSq + 4.0f * this.majorRadius2 * ucdotp * ucdotp +
                                     ((this.majorRadius2 - this.minorRadius2) * (this.majorRadius2 - this.minorRadius2));

            float[] roots    = { 0f, 0f, 0f, 0f };
            int     numRoots = EquationSolver.SolveQuartic(A, B, C, D, E, out roots[0], out roots[1], out roots[2],
                                                           out roots[3]);

            //if (numRoots > 0)
            //{
            //    Debug.WriteLine(ray.Direction.ToString());
            //}
            //if (numRoots > 0)
            //Debug.Write(String.Format("A={0},B={1},C={2},D={3},E={4} - ", A, B, C, D, E));
            //for (int i = 0; i < numRoots; i++)
            //{
            //    Debug.Write(roots[i] + "|");
            //}
            //if (numRoots > 0)
            //    Debug.Write("\r\n");
            if (numRoots > 0)
            {
                if (roots[0] > 0.1f)
                {
                    intersect.TMin     = roots[0];
                    intersect.HitPoint = ray.Origin + intersect.TMin * ray.Direction;
                    // Intersection position (not relative to center)
                    intersect.HitPrimitive = this;
                    // Outward normal
                    Vector3D h      = intersect.HitPoint - this.center; // Now its the relative point
                    float    xCoord = h * this.axisA;                   // forward axis
                    float    yCoord = h * this.axisB;                   // rightward axis
                    float    zCoord = h * this.axisC;                   // upward axis
                    intersect.Normal = this.axisC * -zCoord + h;
                    float outNnorm = intersect.Normal.Length;
                    intersect.Normal.Normalize();
                    intersect.Normal = intersect.Normal * -this.majorRadius + h;
                    // Negative point projected to center path of torus
                    intersect.Normal.Normalize(); // Fix roundoff error problems
                    if (this.material != null && this.material.IsTexturized)
                    {
                        // u - v coordinates
                        double u = Math.Atan2(yCoord, xCoord);
                        u = u * (0.5 / Math.PI) + 0.5;
                        double bVal = outNnorm - this.majorRadius;
                        double v    = Math.Atan2(zCoord, bVal);
                        v = v * (0.5 / Math.PI) + 0.5;
                        //int widthTex = this.material.Texture.Width - 1;
                        //int heightTex = this.material.Texture.Height - 1;
                        //this.material.Color = this.material.Texture.GetPixel((int)(u * widthTex), (int)(v * heightTex));
                        intersect.CurrentTextureCoordinate.U = (float)u;
                        intersect.CurrentTextureCoordinate.V = (float)v;
                    }
                    return(true);
                }
            }
            return(false);
        }