Exemplo n.º 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;
}
Exemplo n.º 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;
        }
    }
}
Exemplo n.º 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;
        }
    }
}
Exemplo n.º 4
0
/**
 * The normal vector, unnormalised.
 */
static Vector3f TriangleNormalV
(
   const Triangle* pT
)
{
   const Vector3f edge1 = Vector3fSub( &pT->aVertexs[1], &pT->aVertexs[0] );
   const Vector3f edge3 = Vector3fSub( &pT->aVertexs[2], &pT->aVertexs[1] );
   return Vector3fCross( &edge1, &edge3 );
}
Exemplo n.º 5
0
void Objects::timber4(float width, float fromX, float fromY, float toX, float toY) {
	float ir=width/(float)2;
	Tuple3fT a; a.s.X=fromX-toX; a.s.Y=fromY-toY; a.s.Z=0;
	Tuple3fT b; b.s.X=0; b.s.Y=0; b.s.Z=-1;
	Tuple3fT normal, dir;
	Vector3fCross(&normal, &a, &b);
	GLfloat l=Vector3fLength(&normal);
	normal.s.X=normal.s.X/l; normal.s.Y=normal.s.Y/l; normal.s.Z=normal.s.Z/l;
	dir.s.X=normal.s.X*ir; dir.s.Y=normal.s.Y*ir; dir.s.Z=normal.s.Z*ir;
	l=Vector3fLength(&a);
	a.s.X=a.s.X/l; a.s.Y=a.s.Y/l; a.s.Z=a.s.Z/l;

	glBegin(GL_TRIANGLES);
		// If it's too slow, leave these 4 triangles away
		// 4 triangles to model the two caps
		glNormal3f(a.s.X,a.s.Y,a.s.Z);
		glVertex3f(fromX+dir.s.X,fromY+dir.s.Y,-ir);
		glNormal3f(a.s.X,a.s.Y,a.s.Z);
		glVertex3f(fromX+dir.s.X,fromY+dir.s.Y,ir);
		glNormal3f(a.s.X,a.s.Y,a.s.Z);
		glVertex3f(fromX-dir.s.X,fromY-dir.s.Y,ir);

		glNormal3f(a.s.X,a.s.Y,a.s.Z);
		glVertex3f(fromX+dir.s.X,fromY+dir.s.Y,-ir);
		glNormal3f(a.s.X,a.s.Y,a.s.Z);
		glVertex3f(fromX-dir.s.X,fromY-dir.s.Y,-ir);
		glNormal3f(a.s.X,a.s.Y,a.s.Z);
		glVertex3f(fromX-dir.s.X,fromY-dir.s.Y,ir);

		glNormal3f(-a.s.X,-a.s.Y,-a.s.Z);
		glVertex3f(toX+dir.s.X,toY+dir.s.Y,-ir);
		glNormal3f(-a.s.X,-a.s.Y,-a.s.Z);
		glVertex3f(toX+dir.s.X,toY+dir.s.Y,ir);
		glNormal3f(-a.s.X,-a.s.Y,-a.s.Z);
		glVertex3f(toX-dir.s.X,toY-dir.s.Y,ir);

		glNormal3f(-a.s.X,-a.s.Y,-a.s.Z);
		glVertex3f(toX-dir.s.X,toY-dir.s.Y,ir);
		glNormal3f(-a.s.X,-a.s.Y,-a.s.Z);
		glVertex3f(toX-dir.s.X,toY-dir.s.Y,-ir);
		glNormal3f(-a.s.X,-a.s.Y,-a.s.Z);
		glVertex3f(toX+dir.s.X,toY+dir.s.Y,-ir);

		// 4 triangles for 2 sides
		glNormal3f(0,0,1);
		glVertex3f(fromX+dir.s.X,fromY+dir.s.Y,ir);
		glNormal3f(0,0,1);
		glVertex3f(fromX-dir.s.X,fromY-dir.s.Y,ir);
		glNormal3f(0,0,1);
		glVertex3f(toX+dir.s.X,toY+dir.s.Y,ir);

		glNormal3f(0,0,1);
		glVertex3f(fromX-dir.s.X,fromY-dir.s.Y,ir);
		glNormal3f(0,0,1);
		glVertex3f(toX+dir.s.X,toY+dir.s.Y,ir);
		glNormal3f(0,0,1);
		glVertex3f(toX-dir.s.X,toY-dir.s.Y,ir);

		glNormal3f(0,0,-1);
		glVertex3f(fromX+dir.s.X,fromY+dir.s.Y,-ir);
		glNormal3f(0,0,-1);
		glVertex3f(fromX-dir.s.X,fromY-dir.s.Y,-ir);
		glNormal3f(0,0,-1);
		glVertex3f(toX+dir.s.X,toY+dir.s.Y,-ir);

		glNormal3f(0,0,-1);
		glVertex3f(fromX-dir.s.X,fromY-dir.s.Y,-ir);
		glNormal3f(0,0,-1);
		glVertex3f(toX+dir.s.X,toY+dir.s.Y,-ir);
		glNormal3f(0,0,-1);
		glVertex3f(toX-dir.s.X,toY-dir.s.Y,-ir);

		// Schiefe Ebene
		glNormal3f(-normal.s.X,-normal.s.Y,-normal.s.Z);
		glVertex3f(fromX-dir.s.X,fromY-dir.s.Y,-ir);
		glNormal3f(-normal.s.X,-normal.s.Y,-normal.s.Z);
		glVertex3f(fromX-dir.s.X,fromY-dir.s.Y,ir);
		glNormal3f(-normal.s.X,-normal.s.Y,-normal.s.Z);
		glVertex3f(toX-dir.s.X,toY-dir.s.Y,ir);

		glNormal3f(-normal.s.X,-normal.s.Y,-normal.s.Z);
		glVertex3f(fromX-dir.s.X,fromY-dir.s.Y,-ir);
		glNormal3f(-normal.s.X,-normal.s.Y,-normal.s.Z);
		glVertex3f(toX-dir.s.X,toY-dir.s.Y,ir);
		glNormal3f(-normal.s.X,-normal.s.Y,-normal.s.Z);
		glVertex3f(toX-dir.s.X,toY-dir.s.Y,-ir);

		glNormal3f(normal.s.X,normal.s.Y,normal.s.Z);
		glVertex3f(fromX+dir.s.X,fromY+dir.s.Y,-ir);
		glNormal3f(normal.s.X,normal.s.Y,normal.s.Z);
		glVertex3f(fromX+dir.s.X,fromY+dir.s.Y,ir);
		glNormal3f(normal.s.X,normal.s.Y,normal.s.Z);
		glVertex3f(toX+dir.s.X,toY+dir.s.Y,ir);

		glNormal3f(normal.s.X,normal.s.Y,normal.s.Z);
		glVertex3f(fromX+dir.s.X,fromY+dir.s.Y,-ir);
		glNormal3f(normal.s.X,normal.s.Y,normal.s.Z);
		glVertex3f(toX+dir.s.X,toY+dir.s.Y,ir);
		glNormal3f(normal.s.X,normal.s.Y,normal.s.Z);
		glVertex3f(toX+dir.s.X,toY+dir.s.Y,-ir);
	glEnd();
}