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_contact_cache.h"
\r
20 namespace PhysicsEffects {
\r
22 #define SCE_PFX_CONTACT_SAME_POINT 0.01f
\r
24 int PfxContactCache::findNearestContactPoint(const PfxPoint3 &newPoint,const PfxVector3 &newNormal)
\r
26 int nearestIdx = -1;
\r
27 PfxFloat minDiff = SCE_PFX_CONTACT_SAME_POINT;
\r
28 for(PfxUInt32 i=0;i<m_numContacts;i++) {
\r
29 PfxVector3 dist = m_cachedContactPoints[i].m_localPointA-newPoint;
\r
30 PfxFloat diff = lengthSqr(dist);
\r
31 if(diff < minDiff && dot(newNormal,m_cachedContactPoints[i].m_normal) > 0.99f) {
\r
39 int PfxContactCache::sort4ContactPoints(const PfxPoint3 &newCP,PfxFloat newDistance)
\r
41 int maxPenetrationIndex = -1;
\r
42 PfxFloat maxPenetration = newDistance;
\r
44 // 最も深い衝突点は排除対象からはずす
\r
45 for(int i=0;i<SCE_PFX_MAX_CACHED_CONTACT_POINTS;i++) {
\r
46 if(m_cachedContactPoints[i].m_distance < maxPenetration) {
\r
47 maxPenetrationIndex = i;
\r
48 maxPenetration = m_cachedContactPoints[i].m_distance;
\r
52 PfxFloat res[4] = {0.0f};
\r
54 // 各点を除いたときの衝突点が作る面積のうち、最も大きくなるものを選択
\r
55 PfxVector3 newp(newCP);
\r
57 p[0] = (PfxVector3)m_cachedContactPoints[0].m_localPointA;
\r
58 p[1] = (PfxVector3)m_cachedContactPoints[1].m_localPointA;
\r
59 p[2] = (PfxVector3)m_cachedContactPoints[2].m_localPointA;
\r
60 p[3] = (PfxVector3)m_cachedContactPoints[3].m_localPointA;
\r
62 if(maxPenetrationIndex != 0) {
\r
63 PfxVector3 a0 = newp-p[1];
\r
64 PfxVector3 b0 = p[3]-p[2];
\r
65 res[0] = lengthSqr(cross(a0,b0));
\r
68 if(maxPenetrationIndex != 1) {
\r
69 PfxVector3 a1 = newp-p[0];
\r
70 PfxVector3 b1 = p[3]-p[2];
\r
71 res[1] = lengthSqr(cross(a1,b1));
\r
74 if(maxPenetrationIndex != 2) {
\r
75 PfxVector3 a2 = newp-p[0];
\r
76 PfxVector3 b2 = p[3]-p[1];
\r
77 res[2] = lengthSqr(cross(a2,b2));
\r
80 if(maxPenetrationIndex != 3) {
\r
81 PfxVector3 a3 = newp-p[0];
\r
82 PfxVector3 b3 = p[2]-p[1];
\r
83 res[3] = lengthSqr(cross(a3,b3));
\r
87 PfxFloat maxVal = res[0];
\r
89 if (res[1] > maxVal) {
\r
94 if (res[2] > maxVal) {
\r
99 if (res[3] > maxVal) {
\r
107 void PfxContactCache::addContactPoint(
\r
108 PfxFloat newDistance,
\r
109 const PfxVector3 &newNormal, // world coords
\r
110 const PfxPoint3 &newPointA, // local to the objectA
\r
111 const PfxPoint3 &newPointB, // local to the objectB
\r
112 PfxSubData subData)
\r
114 int id = findNearestContactPoint(newPointA,newNormal);
\r
116 if(id < 0 && m_numContacts < SCE_PFX_MAX_CACHED_CONTACT_POINTS) {
\r
118 id = m_numContacts++;
\r
119 m_cachedContactPoints[id].reset();
\r
123 id = sort4ContactPoints(newPointA,newDistance);
\r
124 m_cachedContactPoints[id].reset();
\r
127 m_cachedContactPoints[id].m_distance = newDistance;
\r
128 m_cachedContactPoints[id].m_subData = subData;
\r
129 m_cachedContactPoints[id].m_normal = newNormal;
\r
130 m_cachedContactPoints[id].m_localPointA = newPointA;
\r
131 m_cachedContactPoints[id].m_localPointB = newPointB;
\r
134 void PfxContactCache::addContactPoint(const PfxCachedContactPoint &cp)
\r
136 PfxPoint3 pA = cp.m_localPointA;
\r
138 int id = findNearestContactPoint(pA,cp.m_normal);
\r
141 if(m_cachedContactPoints[id].m_distance > cp.m_distance) {
\r
143 m_cachedContactPoints[id].m_distance = cp.m_distance;
\r
144 m_cachedContactPoints[id].m_normal = cp.m_normal;
\r
145 m_cachedContactPoints[id].m_localPointA = cp.m_localPointA;
\r
146 m_cachedContactPoints[id].m_localPointB = cp.m_localPointB;
\r
149 else if(m_numContacts < SCE_PFX_MAX_CACHED_CONTACT_POINTS) {
\r
151 m_cachedContactPoints[m_numContacts++] = cp;
\r
155 id = sort4ContactPoints(pA,cp.m_distance);
\r
158 m_cachedContactPoints[id] = cp;
\r
162 } //namespace PhysicsEffects
\r