void HawkTriangle3D::GetProjection (const HawkVector3D& vAxis,Float& fMin, Float& fMax) const { Float dot[3] = { vAxis.DotProduct(GetPoint(0)), vAxis.DotProduct(GetPoint(1)), vAxis.DotProduct(GetPoint(2)) }; fMin = dot[0]; fMax = fMin; if (dot[1] < fMin) { fMin = dot[1]; } else if (dot[1] > fMax) { fMax = dot[1]; } if (dot[2] < fMin) { fMin = dot[2]; } else if (dot[2] > fMax) { fMax = dot[2]; } }
Bool HawkLine3D::Intersect(const HawkOBB& oBox,Vec3IntrResult* pResult) const { const HawkVector3D* Axis = oBox.GetAxis(); HawkVector3D diff = Point - oBox.Center; HawkVector3D BOrigin( diff.DotProduct(Axis[0]), diff.DotProduct(Axis[1]), diff.DotProduct(Axis[2]) ); HawkVector3D BDirection( Direction.DotProduct(Axis[0]), Direction.DotProduct(Axis[1]), Direction.DotProduct(Axis[2]) ); Float t0 = -FLT_MAX,t1 = FLT_MAX; bool notAllClipped = geoClip(+BDirection.X, -BOrigin.X-oBox.Extent[0], t0, t1) && geoClip(-BDirection.X, +BOrigin.X-oBox.Extent[0], t0, t1) && geoClip(+BDirection.Y, -BOrigin.Y-oBox.Extent[1], t0, t1) && geoClip(-BDirection.Y, +BOrigin.Y-oBox.Extent[1], t0, t1) && geoClip(+BDirection.Z, -BOrigin.Z-oBox.Extent[2], t0, t1) && geoClip(-BDirection.Z, +BOrigin.Z-oBox.Extent[2], t0, t1); if (notAllClipped) { //2交点 if (t1 > t0) { if (pResult) { pResult->Factor = HawkMath::Abs<Float>(t0) < HawkMath::Abs<Float>(t1)? t0 : t1; pResult->Point = Point + Direction * pResult->Factor; } return true; } //1交点 else { if (pResult) { pResult->Factor = t0; pResult->Point = Point + Direction * pResult->Factor; } return true; } } return false; }
//直线和球相交 Bool HawkLine3D::Intersect(const HawkSphere& oSphere,Vec3IntrResult* pResult) const { HawkVector3D vDiff = Point - oSphere.Center; Float a0 = vDiff.DotProduct(vDiff) - oSphere.Radius*oSphere.Radius; Float a1 = Direction.DotProduct(vDiff); Float dis = a1*a1 - a0; if (dis >= 0) { if (pResult) { if (dis >= HawkMath::FLOAT_DIFF) { Float root = HawkMath::Sqrt(dis); Float t0 = -a1 - root; Float t1 = -a1 + root; pResult->Factor = HawkMath::Abs<Float>(t0) < HawkMath::Abs<Float>(t1)?t0:t1; pResult->Point = Point + pResult->Factor*Direction; } else { Float t0 = -a1; pResult->Factor = t0; pResult->Point = Point + t0*Direction; } } return true; } return false; }
////////////////////////////////////////////////////////////////////////// //直线和三角形相交 Bool HawkLine3D::Intersect(const HawkTriangle3D& oTriangle,Vec3IntrResult* pResult) const { HawkVector3D vDiff = Point - oTriangle.GetPoint(0); HawkVector3D edge1 = oTriangle.GetEdge(0); HawkVector3D edge2 = oTriangle.GetEdge(1); HawkVector3D normal = edge1.CrossProduct(edge2); Float DdN = Direction.DotProduct(normal); Float fSign = 0.0f; if (DdN > HawkMath::FLOAT_DIFF) { fSign = 1.0f; } else if (DdN < -HawkMath::FLOAT_DIFF) { fSign = -1.0f; DdN = -DdN; } else { return false; } Float DdQxE2 = fSign*Direction.DotProduct(vDiff.CrossProduct(edge2)); if (DdQxE2 >= 0.0f) { Float DdE1xQ = fSign*Direction.DotProduct(edge1.CrossProduct(vDiff)); if (DdE1xQ >= 0.0f) { if (DdQxE2 + DdE1xQ <= DdN) { if (pResult) { Float QdN = -fSign*vDiff.DotProduct(normal); pResult->Factor = QdN / DdN; pResult->Point = Point + pResult->Factor*Direction; } return true; } } } return false; }
//计算线段上面和oVec相隔最近的点 HawkVector3D HawkLine3D::GetClosestPoint(const HawkVector3D& oVec) const { HawkVector3D oTmp = oVec - Point; return Point + Direction*oTmp.DotProduct(Direction); }
Bool HawkTriangle3D::IsFrontFacing(const HawkVector3D& vVec3) const { HawkVector3D vNormal = GetNormal(); Float fDis = vNormal.DotProduct(vVec3); return fDis >= 0.0f; }