Example #1
0
/**
 * @implementation
 * Adapted from:
 * <cite>'Fast, Minimum Storage Ray-Triangle Intersection';
 * Moller, Trumbore;
 * Journal Of Graphics Tools, v2n1p21; 1997.
 * http://www.acm.org/jgt/papers/MollerTrumbore97/</cite>
 */
bool TriangleIntersection
(
   const Triangle* pT,
   const Vector3f* pRayOrigin,
   const Vector3f* pRayDirection,
   real64*         pHitDistance_o
)
{
   /* make vectors for two edges sharing vert0 */
   const Vector3f edge1 = Vector3fSub( &pT->aVertexs[1], &pT->aVertexs[0] );
   const Vector3f edge2 = Vector3fSub( &pT->aVertexs[2], &pT->aVertexs[0] );

   /* begin calculating determinant - also used to calculate U parameter */
   const Vector3f pvec = Vector3fCross( pRayDirection, &edge2 );

   /* if determinant is near zero, ray lies in plane of triangle */
   const real64 det = Vector3fDot( &edge1, &pvec );

   bool isHit = false;
   if( (det <= -EPSILON) | (det >= EPSILON) )
   {
      const real64 inv_det = 1.0 / det;

      /* calculate distance from vertex 0 to ray origin */
      const Vector3f tvec = Vector3fSub( pRayOrigin, &pT->aVertexs[0] );

      /* calculate U parameter and test bounds */
      const real64 u = Vector3fDot( &tvec, &pvec ) * inv_det;
      if( (u >= 0.0) & (u <= 1.0) )
      {
         /* prepare to test V parameter */
         const Vector3f qvec = Vector3fCross( &tvec, &edge1 );

         /* calculate V parameter and test bounds */
         const real64 v = Vector3fDot( pRayDirection, &qvec ) * inv_det;
         if( (v >= 0.0) & (u + v <= 1.0) )
         {
            /* calculate t, ray intersects triangle */
            *pHitDistance_o = Vector3fDot( &edge2, &qvec ) * inv_det;

            /* only allow intersections in the forward ray direction */
            isHit = (*pHitDistance_o >= 0.0);
         }
      }
   }

   return isHit;
}
Example #2
0
//Mouse drag, calculate rotation
void    ArcBall_t::drag(const Point2fT* NewPt, Quat4fT* NewRot)
{
    //Map the point to the sphere
    this->_mapToSphere(NewPt, &this->EnVec);

    //Return the quaternion equivalent to the rotation
    if (NewRot)
    {
        Vector3fT  Perp;

        //Compute the vector perpendicular to the begin and end vectors
        Vector3fCross(&Perp, &this->StVec, &this->EnVec);

        //Compute the length of the perpendicular vector
        if (Vector3fLength(&Perp) > Epsilon)    //if its non-zero
        {
            //We're ok, so return the perpendicular vector as the transform after all
            NewRot->s.X = Perp.s.X;
            NewRot->s.Y = Perp.s.Y;
            NewRot->s.Z = Perp.s.Z;
            //In the quaternion values, w is cosine (theta / 2), where theta is rotation angle
            NewRot->s.W= Vector3fDot(&this->StVec, &this->EnVec);
        }
        else                                    //if its zero
        {
            //The begin and end vectors coincide, so return an identity transform
            NewRot->s.X = 
            NewRot->s.Y = 
            NewRot->s.Z = 
            NewRot->s.W = 0.0f;
        }
    }
}
Example #3
0
//Mouse drag, calculate rotation
inline void ArcBallDrag(ArcBall_t *a, double x, double y, Quat4fT* NewRot) {
    //Map the point to the sphere
    ArcBallMapToSphere(a, x, y, &(a->EnVec));

    //Return the quaternion equivalent to the rotation
    if (NewRot) {
        Vector3fT  Perp;

        //Compute the vector perpendicular to the begin and end vectors
        Vector3fCross(&Perp, &(a->StVec), &(a->EnVec));

        //Compute the length of the perpendicular vector
        if (Vector3fLength(&Perp) > ArcBallEpsilon) {    //if its non-zero
            //We're ok, so return the perpendicular vector as the transform after all
            NewRot->s.X = Perp.s.X;
            NewRot->s.Y = Perp.s.Y;
            NewRot->s.Z = Perp.s.Z;
            //In the quaternion values, w is cosine (theta / 2), where theta is rotation angle
            NewRot->s.W= Vector3fDot(&(a->StVec), &(a->EnVec));
        } else {                                    //if its zero
            //The begin and end vectors coincide, so return an identity transform
            NewRot->s.X = 0.0f;
            NewRot->s.Y = 0.0f;
            NewRot->s.Z = 0.0f;
            NewRot->s.W = 0.0f;
        }
    }
}
Example #4
0
real64 TriangleArea
(
   const Triangle* pT
)
{
   /* half area of parallelogram (area = magnitude of cross of two edges) */
   const Vector3f normalV = TriangleNormalV( pT );
   return sqrt( Vector3fDot( &normalV, &normalV ) ) * 0.5;
}
Example #5
0
static real64 ImageCalculateToneMapping
(
   const Image* pI,
   const int32u displayLumMax
)
{
   /* calculate estimate of world-adaptation luminance
      as log mean luminance of scene */
   real64 adaptLuminance = 1e-4;
   {
      real64 sumOfLogs = 0.0;
      int32 i;
      for( i = (pI->width * pI->height);  i-- > 0; )
      {
         const real64 Y = Vector3fDot( &pI->aPixels[i], &RGB_LUMINANCE );
         /* clamp luminance to a perceptual minimum */
         sumOfLogs += log10( Y > 1e-4 ? Y : 1e-4 );
      }

      adaptLuminance = pow( 10.0, sumOfLogs /
         (real64)(pI->width * pI->height) );
   }

   /* make scale-factor from:
      ratio of minimum visible differences in luminance, in display-adapted
      and world-adapted perception (discluding the constant that cancelled),
      divided by display max to yield a [0,1] range */
   {
      const real64 displayLuminanceMax = displayLumMax ?
         (real64)displayLumMax : DISPLAY_LUMINANCE_MAX;

      const real64 a = 1.219 + pow( displayLuminanceMax * 0.25, 0.4 );
      const real64 b = 1.219 + pow( adaptLuminance, 0.4 );

      return pow( a / b, 2.5 ) / DISPLAY_LUMINANCE_MAX;
   }
}