public override bool getSample(RayContext rayContext, double ru, double rv, out Vector3 wi, out double invPdf)
        {
            Vector3 viewDir = rayContext.ray.dir;
            Vector3 normal = rayContext.hitData.hitNormal;

            Vector3 reflectDir = viewDir - (normal * (normal * viewDir) * 2.0);
            reflectDir.normalize();

            Matrix3 shadingMatrix = new Matrix3();
            shadingMatrix.computeTangentBasis(reflectDir);

            double pdf = 1;
            invPdf = 1;

            wi = MathUtils.getSpecularDir(ru, rv, glossy, out pdf);

            wi = shadingMatrix.transformVector(wi);
            wi.normalize();

            if (pdf < 0.0001)
                return false;

            invPdf = 1.0 / pdf;

            double cosT = rayContext.hitData.hitNormal * wi;
            if (cosT < 0.0)
                return false;

            return true;
        }
        public Matrix3 getInverted()
        {
            Matrix3 res = new Matrix3();
            double det = m[0] * ( m[1] ^ m[2] );
            //if(det==0.0f) //error

            res.setRow(0, (m[1]^m[2]) / det);
            res.setRow(1, (m[2]^m[0]) / det);
            res.setRow(2, (m[0]^m[1]) / det);
            return res;
        }