//----------------------------------------------------------------// bool USSurface2D::GetHit ( ZLVec2D& sphereLoc, ZLVec2D& move, SurfaceHit2D& hit ) { // The usual stuff... ZLVec2D unitMove = move; unitMove.Norm (); if ( unitMove.Dot ( this->mNorm ) >= -0.001f ) return false; if ( ZLDist::PointToPlane2D ( sphereLoc, *this ) <= 0.0f ) return false; // Get the point of first contact on the polygon... ZLVec2D pofcop = this->mNorm; pofcop.Reverse (); pofcop.Add ( sphereLoc ); this->ClampPoint ( pofcop ); // Send a ray from the point on the surface to intersect the circle. // The ray is the inverse of the move vec. ZLVec2D inverseMove = move; inverseMove.Reverse (); float t0, t1; u32 sectType; sectType = ZLSect::VecToCircle ( t0, t1, pofcop, inverseMove, sphereLoc, 1.0f ); // Bail if the point will not intersect the sphere. if ( sectType == ZLSect::SECT_PARALLEL ) return false; if ( t0 >= hit.mTime ) return false; // Bail if the point will graze the sphere. if ( sectType == ZLSect::SECT_TANGENT ) return false; // Bail if the point will stay outside of the sphere. if (( t0 > 1.0f ) || ( t1 < 0.0f )) return false; // OMG! We hit something! float time = t0; hit.mTime = time; inverseMove.Scale ( t0 ); hit.mPoint = pofcop; hit.mPoint.Add ( inverseMove ); hit.mNorm = sphereLoc; hit.mNorm.Sub ( hit.mPoint ); hit.mNorm.Norm (); if ( unitMove.Dot ( hit.mNorm ) >= -0.001f ) return false; return true; }
//----------------------------------------------------------------// bool USSurface2D::GetTouch ( ZLVec2D& sphereLoc, ZLSurfaceTouch2D& touch ) { // The usual stuff... float dist = ZLDist::PointToPlane2D ( sphereLoc, *this ); if ( dist <= 0.0f ) return false; if ( dist > 1.001f ) return false; // Get the point of first contact on the polygon... ZLVec2D pofcop = this->mNorm; pofcop.Reverse (); pofcop.Add ( sphereLoc ); this->ClampPoint ( pofcop ); ZLVec2D ray = pofcop; ray.Sub ( sphereLoc ); dist = ray.NormSafe (); if ( dist >= touch.mDist ) return false; float dot = ray.Dot ( touch.mFinger ); if ( dot < 0.85f ) return false; // we have a touch... touch.mDist = dist; touch.mPoint = pofcop; touch.mTouch = true; touch.mHit = !touch.mPrevTouch; //touch.mNorm = this->GetNorm (); return true; }
//----------------------------------------------------------------// float USSurface2D::GetDepthAlongRay ( ZLVec2D& sphereLoc, ZLVec2D& ray ) { // Get the point of first contact on the polygon... ZLVec2D pofcop = this->mNorm; pofcop.Reverse (); pofcop.Add ( sphereLoc ); this->ClampPoint ( pofcop ); float t0, t1; u32 sectType; sectType = ZLSect::VecToCircle ( t0, t1, pofcop, ray, sphereLoc, 1.0f ); // Bail if the point will not intersect the sphere. if ( sectType == ZLSect::SECT_PARALLEL ) return 0.0f; if ( sectType == ZLSect::SECT_TANGENT ) return 0.0f; return t0; }
//----------------------------------------------------------------// bool USSurface2D::GetContact ( ZLVec2D& sphereLoc, ZLVec2D& contact, ZLVec2D& norm ) { // The usual stuff... float dist = ZLDist::PointToPlane2D ( sphereLoc, *this ); if ( dist <= 0.0f ) return false; if ( dist > 1.001f ) return false; // Get the point of first contact on the polygon... contact = this->mNorm; contact.Reverse (); contact.Add ( sphereLoc ); this->ClampPoint ( contact ); norm = sphereLoc; norm.Sub ( contact ); dist = norm.NormSafe (); if ( dist > 1.001f ) return false; return true; }