int RayIntersectTriangle( triangle *thisTriangle, line *l, float *u, float *v, float *t) { return IntersectTriangleRay(thisTriangle->vertices[0], thisTriangle->vertices[1], thisTriangle->vertices[2], thisTriangle->vertices[3], thisTriangle->vertices[4], thisTriangle->vertices[5], thisTriangle->vertices[6], thisTriangle->vertices[7], thisTriangle->vertices[8], l, u, v, t); }
bool CCollision::CollisionTriangleCapsule(const CVector3D &v0,const CVector3D &v1,const CVector3D &v2,const CVector3D &top,const CVector3D &bottom,float radius,CVector3D *cross,float *length ){ CVector3D V(top-bottom); CVector3D VP; float Dist = 1e10; //ポリゴンの法線を求める CVector3D N(CVector3D::Cross(v1 - v0, v2 - v0).GetNormalize()); //始点からポリゴン上のある地点(どこでもいい)へのベクトル CVector3D PV1 = top-v0; //終点からポリゴン上のある地点(どこでもいい)へのベクトル CVector3D PV2 = bottom-v0; //ポリゴンの法線との内積を求める float d1 = CVector3D::Dot(PV1,N); float d2 = CVector3D::Dot(PV2,N); if(d1*d2<0) { //貫通している場合は線とポリゴンの判定を行う if(IntersectTriangleRay(cross,top+CVector3D(0,radius,0),bottom+CVector3D(0,-radius,0),v0,v1,v2,&Dist)) { if(length) { //貫通点までの距離を求める float lt = (*cross - top).LengthSq(); float lb = (*cross - bottom).LengthSq(); if(lt<lb) *length = sqrt(lt); else *length = sqrt(lb); } return true; } } d1=abs(d1); d2=abs(d2); //平面上の点との最短地点を求める CVector3D C1(top-N*d1); CVector3D C2(bottom-N*d2); //点が平面上にない場合は無効、後の辺との接触で調べる if(!TriangleIntersect(C1,v0,v1,v2,N)) d1=1e10; if(!TriangleIntersect(C2,v0,v1,v2,N)) d2=1e10; //面との距離が近い点の距離を選択 Dist = (d1<d2) ? d1:d2; if(Dist<=radius) { //追加 if(length) *length = Dist; return true; } //各辺との距離を求める Dist = min(min(DistanceLine(v0,v1,top,bottom),DistanceLine(v1,v2,top,bottom)),DistanceLine(v2,v0,top,bottom)); if(length) *length = Dist; return (Dist<=radius); }