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_cylinder.h"
\r
21 namespace PhysicsEffects {
\r
23 PfxBool pfxIntersectRayCylinder(const PfxRayInput &ray,PfxRayOutput &out,const PfxCylinder &cylinder,const PfxTransform3 &transform)
\r
26 PfxTransform3 transformCapsule = orthoInverse(transform);
\r
27 PfxVector3 startPosL = transformCapsule.getUpper3x3() * ray.m_startPosition + transformCapsule.getTranslation();
\r
28 PfxVector3 rayDirL = transformCapsule.getUpper3x3() * ray.m_direction;
\r
30 PfxFloat radSqr = cylinder.m_radius * cylinder.m_radius;
\r
34 PfxFloat h = fabsf(startPosL[0]);
\r
35 if(h > cylinder.m_halfLen) h = cylinder.m_halfLen;
\r
36 PfxVector3 Px(out.m_variable,0,0);
\r
37 PfxFloat sqrLen = lengthSqr(startPosL-Px);
\r
38 if(sqrLen <= radSqr) return false;
\r
43 PfxVector3 P(startPosL);
\r
44 PfxVector3 D(rayDirL);
\r
49 PfxFloat a = dot(D,D);
\r
50 PfxFloat b = dot(P,D);
\r
51 PfxFloat c = dot(P,P) - radSqr;
\r
53 PfxFloat d = b * b - a * c;
\r
55 if(d < 0.0f || fabs(a) < 0.00001f) return false;
\r
57 PfxFloat tt = ( -b - sqrtf(d) ) / a;
\r
64 if(tt < out.m_variable) {
\r
65 PfxVector3 cp = startPosL + tt * rayDirL;
\r
67 if(fabsf(cp[0]) <= cylinder.m_halfLen) {
\r
68 out.m_contactFlag = true;
\r
69 out.m_variable = tt;
\r
70 out.m_contactPoint = PfxVector3(transform * PfxPoint3(cp));
\r
71 out.m_contactNormal = transform.getUpper3x3() * normalize(cp);
\r
72 out.m_subData.m_type = PfxSubData::NONE;
\r
80 if(fabsf(rayDirL[0]) < 0.00001f) return false;
\r
82 PfxFloat t1 = ( cylinder.m_halfLen - startPosL[0] ) / rayDirL[0];
\r
83 PfxFloat t2 = ( - cylinder.m_halfLen - startPosL[0] ) / rayDirL[0];
\r
85 PfxFloat tt = SCE_PFX_MIN(t1,t2);
\r
87 if(tt < 0.0f || tt > 1.0f) return false;
\r
89 PfxVector3 p = startPosL + tt * rayDirL;
\r
92 if(lengthSqr(p) < radSqr && tt < out.m_variable) {
\r
93 PfxVector3 cp = startPosL + tt * rayDirL;
\r
94 out.m_contactFlag = true;
\r
95 out.m_variable = tt;
\r
96 out.m_contactPoint = ray.m_startPosition + tt * ray.m_direction;
\r
97 out.m_contactNormal = transform.getUpper3x3() * ((cp[0]>0.0f)?PfxVector3(1.0,0.0,0.0):PfxVector3(-1.0,0.0,0.0));
\r
98 out.m_subData.m_type = PfxSubData::NONE;
\r
105 } //namespace PhysicsEffects
\r