Beispiel #1
0
    /// <summary>
    /// Defines the view matrix with an eye position, a look at point and an up vector.
    /// This method is equivalent to the OpenGL function gluLookAt.
    /// If Up is a zero vector a default up vector is calculated with a default
    /// look-right vector (VZ) that lies in the x-z plane.
    /// </summary>
    /// <param name="Eye">Eye Vector to the position of the eye (view point)</param>
    /// <param name="At">At Vector to the target point</param>
    /// <param name="Up">Up Vector that points from the viewpoint upwards.</param>
    public void LookAt(SLVec3f Eye, SLVec3f At, SLVec3f Up)
    {
        SLVec3f VX, VY, VZ, VT, ZERO;

        //SLMat3<T> xz(0.0, 0.0, 1.0,         // matrix that transforms YZ into a
        //             0.0, 0.0, 0.0,         // vector that is perpendicular to YZ and
        //            -1.0, 0.0, 0.0);        // lies in the x-z plane

        VZ = Eye - At;
        VZ.Normalize();
        VX   = new SLVec3f();
        ZERO = new SLVec3f();

        if (Up == ZERO)
        {
            VX.x = VZ.z;
            VX.y = 0;
            VX.z = -1 * VZ.x;
        }
        else
        {
            VX = Up.Cross(VZ);
        }
        VY = SLVec3f.CrossProduct(VZ, VX);
        VX.Normalize();
        VY.Normalize();
        VZ.Normalize();
        VT = -Eye;

        Set(VX.x, VX.y, VX.z, SLVec3f.DotProduct(VX, VT),
            VY.x, VY.y, VY.z, SLVec3f.DotProduct(VY, VT),
            VZ.x, VZ.y, VZ.z, SLVec3f.DotProduct(VZ, VT),
            0.0f, 0.0f, 0.0f, 1.0f);
    }
Beispiel #2
0
    private SLVec3f trackBallVec(float x, float y)
    {
        SLVec3f vec = new SLVec3f();
        float   r;

        if (ClientRectangle.Width < ClientRectangle.Height)
        {
            r = (float)(ClientRectangle.Width / 2) * 0.88f;
        }
        else
        {
            r = (float)(ClientRectangle.Height / 2) * 0.88f;
        }
        vec.x = (x - ClientRectangle.Width / 2) / r;
        vec.y = (y - ClientRectangle.Height / 2) / r * -1;

        float d2 = vec.x * vec.x + vec.y * vec.y;

        if (d2 < 1f)
        {
            vec.z = (float)Math.Sqrt(1f - d2);
        }
        else
        {
            vec.z = 0f;
            vec.Normalize();
        }
        return(vec);
    }
Beispiel #3
0
        /// <summary>
        /// calculates mirror effect from normale relative to the light
        /// </summary>
        /// <param name="light"></param>
        /// <returns></returns>
        public SLVec3f spiegel(SLLight light)
        {
            SLVec3f R = 2 * (SLVec3f.DotProduct(light.direction, this.normale)) * this.normale - light.direction;
            SLVec3f E = -(this.posInView);

            E.Normalize();
            float RsE = (float)Math.Pow(Math.Max(SLVec3f.DotProduct(R, E), 0), 5);

            return((light.mirror) * RsE);
        }
Beispiel #4
0
    /// <summary>
    /// Conversion to axis and angle in radians
    /// The matrix must be a rotation matrix for this functions to be valid. The last
    /// function uses Gram-Schmidt orthonormalization applied to the columns of the
    /// rotation matrix. The angle must be in radians, not degrees.
    /// </summary>
    /// <param name="angleDEG"></param>
    /// <param name="axis"></param>
    public void ToAngleAxis(out float angleDEG, out SLVec3f axis)
    {
        // Let (x,y,z) be the unit-length axis and let A be an angle of rotation.
        // The rotation matrix is R = I + sin(A)*P + (1-cos(A))*P^2 where
        // I is the identity and
        //
        //       +-        -+
        //       |  0 -z +y |
        //   P = | +z  0 -x |
        //       | -y +x  0 |
        //       +-        -+
        //
        // If A > 0, R represents a counterclockwise rotation about the axis in
        // the sense of looking from the tip of the axis vector towards the
        // origin.  Some algebra will show that
        //
        //   cos(A) = (trace(R)-1)/2  and  R - R^t = 2*sin(A)*P
        //
        // In the event that A = pi, R-R^t = 0 which prevents us from extracting
        // the axis through P.  Instead note that R = I+2*P^2 when A = pi, so
        // P^2 = (R-I)/2.  The diagonal entries of P^2 are x^2-1, y^2-1, and
        // z^2-1.  We can solve these for axis (x,y,z).  Because the angle is pi,
        // it does not matter which sign you choose on the square roots.

        float  tr       = Trace();
        float  cs       = 0.5f * (tr - 1.0f);
        double angleRAD = Math.Acos(cs); // in [0,PI]

        // Init axis
        axis = SLVec3f.XAxis;

        if (angleRAD > 0)
        {
            if (angleRAD < Math.PI)
            {
                axis.x = m[5] - m[7];
                axis.y = m[6] - m[2];
                axis.z = m[1] - m[3];
                axis.Normalize();
            }
            else
            {
                // angle is PI
                float halfInverse;
                if (m[0] >= m[4])
                {
                    // r00 >= r11
                    if (m[0] >= m[8])
                    { // r00 is maximum diagonal term
                        axis.x      = 0.5f * (float)Math.Sqrt(1 + m[0] - m[4] - m[8]);
                        halfInverse = 0.5f / axis.x;
                        axis.y      = halfInverse * m[3];
                        axis.z      = halfInverse * m[6];
                    }
                    else
                    { // r22 is maximum diagonal term
                        axis.z      = 0.5f * (float)Math.Sqrt(1 + m[8] - m[0] - m[4]);
                        halfInverse = 0.5f / axis.z;
                        axis.x      = halfInverse * m[6];
                        axis.y      = halfInverse * m[7];
                    }
                }
                else
                {
                    // r11 > r00
                    if (m[4] >= m[8])
                    { // r11 is maximum diagonal term
                        axis.y      = 0.5f * (float)Math.Sqrt(1 + m[4] - m[0] - m[8]);
                        halfInverse = 0.5f / axis.y;
                        axis.x      = halfInverse * m[3];
                        axis.z      = halfInverse * m[7];
                    }
                    else
                    { // r22 is maximum diagonal term
                        axis.z      = 0.5f * (float)Math.Sqrt(1 + m[8] - m[0] - m[4]);
                        halfInverse = 0.5f / axis.z;
                        axis.x      = halfInverse * m[6];
                        axis.y      = halfInverse * m[7];
                    }
                }
            }
        }
        angleDEG = (float)(angleRAD * SLUtils.RAD2DEG);
    }