/** * @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; }
//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; } } }
//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; } } }
/** * 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 ); }
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(); }