2 Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc.
\r
5 Physics Effects is open software; you can redistribute it and/or
\r
6 modify it under the terms of the BSD License.
\r
8 Physics Effects is distributed in the hope that it will be useful,
\r
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
\r
11 See the BSD License for more details.
\r
13 A copy of the BSD License is distributed with
\r
14 Physics Effects under the filename: physics_effects_license.txt
\r
17 #include "pfx_intersect_common.h"
\r
18 #include "pfx_intersect_ray_capsule.h"
\r
21 namespace PhysicsEffects {
\r
22 PfxBool pfxIntersectRayCapsule(const PfxRayInput &ray,PfxRayOutput &out,const PfxCapsule &capsule,const PfxTransform3 &transform)
\r
24 // レイをCapsuleのローカル座標へ変換
\r
25 PfxTransform3 transformCapsule = orthoInverse(transform);
\r
26 PfxVector3 startPosL = transformCapsule.getUpper3x3() * ray.m_startPosition + transformCapsule.getTranslation();
\r
27 PfxVector3 rayDirL = transformCapsule.getUpper3x3() * ray.m_direction;
\r
29 PfxFloat radSqr = capsule.m_radius * capsule.m_radius;
\r
33 PfxFloat h = fabsf(startPosL[0]);
\r
34 if(h > capsule.m_halfLen) h = capsule.m_halfLen;
\r
35 PfxVector3 Px(out.m_variable,0,0);
\r
36 PfxFloat sqrLen = lengthSqr(startPosL-Px);
\r
37 if(sqrLen <= radSqr) return false;
\r
42 PfxVector3 P(startPosL);
\r
43 PfxVector3 D(rayDirL);
\r
48 PfxFloat a = dot(D,D);
\r
49 PfxFloat b = dot(P,D);
\r
50 PfxFloat c = dot(P,P) - radSqr;
\r
52 PfxFloat d = b * b - a * c;
\r
54 if(d < 0.0f || fabs(a) < 0.00001f) return false;
\r
56 PfxFloat tt = ( -b - sqrtf(d) ) / a;
\r
63 if(tt < out.m_variable) {
\r
64 PfxVector3 cp = startPosL + tt * rayDirL;
\r
66 if(fabsf(cp[0]) <= capsule.m_halfLen) {
\r
67 out.m_contactFlag = true;
\r
68 out.m_variable = tt;
\r
69 out.m_contactPoint = PfxVector3(transform * PfxPoint3(cp));
\r
70 out.m_contactNormal = transform.getUpper3x3() * normalize(cp);
\r
71 out.m_subData.m_type = PfxSubData::NONE;
\r
77 // カプセルの両端にある球体との交差判定
\r
78 PfxFloat a = dot(rayDirL,rayDirL);
\r
79 if(fabs(a) < 0.00001f) return false;
\r
82 PfxVector3 center(capsule.m_halfLen,0.0f,0.0f);
\r
83 PfxVector3 v = startPosL - center;
\r
85 PfxFloat b = dot(v,rayDirL);
\r
86 PfxFloat c = dot(v,v) - radSqr;
\r
88 PfxFloat d = b * b - a * c;
\r
92 PfxFloat tt = ( -b - sqrtf(d) ) / a;
\r
94 if(tt < 0.0f || tt > 1.0f) break;
\r
96 if(tt < out.m_variable) {
\r
97 PfxVector3 cp = startPosL + tt * rayDirL;
\r
98 out.m_contactFlag = true;
\r
99 out.m_variable = tt;
\r
100 out.m_contactPoint = ray.m_startPosition + tt * ray.m_direction;
\r
101 out.m_contactNormal = transform.getUpper3x3() * normalize(cp-center);
\r
102 out.m_subData.m_type = PfxSubData::NONE;
\r
108 PfxVector3 center(-capsule.m_halfLen,0.0f,0.0f);
\r
109 PfxVector3 v = startPosL - center;
\r
111 PfxFloat b = dot(v,rayDirL);
\r
112 PfxFloat c = dot(v,v) - radSqr;
\r
114 PfxFloat d = b * b - a * c;
\r
116 if(d < 0.0f) return false;
\r
118 PfxFloat tt = ( -b - sqrtf(d) ) / a;
\r
120 if(tt < 0.0f || tt > 1.0f) return false;
\r
122 if(tt < out.m_variable) {
\r
123 PfxVector3 cp = startPosL + out.m_variable * rayDirL;
\r
124 out.m_contactFlag = true;
\r
125 out.m_variable = tt;
\r
126 out.m_contactPoint = ray.m_startPosition + tt * ray.m_direction;
\r
127 out.m_contactNormal = transform.getUpper3x3() * normalize(cp-center);
\r
128 out.m_subData.m_type = PfxSubData::NONE;
\r
135 } //namespace PhysicsEffects
\r