@@ -1220,40 +1220,43 @@ float AtomGroup::Travel(Vector &position,
1220
1220
{
1221
1221
somethingPenetrated = false ;
1222
1222
1223
- distMass = mass / static_cast <float >(hitTerrAtoms.size () * (m_Resolution ? m_Resolution : 1 ));
1224
- distMI = m_MomInertia / static_cast <float >(hitTerrAtoms.size () * (m_Resolution ? m_Resolution : 1 ));
1223
+ distMass = mass / static_cast <float >(( hitTerrAtoms.size () - penetratingAtoms. size () ) * (m_Resolution ? m_Resolution : 1 ));
1224
+ distMI = m_MomInertia / static_cast <float >(( hitTerrAtoms.size () - penetratingAtoms. size () ) * (m_Resolution ? m_Resolution : 1 ));
1225
1225
1226
1226
for (std::list<Atom*>::iterator aItr = hitTerrAtoms.begin (); aItr != hitTerrAtoms.end (); )
1227
1227
{
1228
- // Calc and store the accurate hit radius of the Atom in relation to the CoM
1229
- tempVec = (*aItr)->GetOffset ().GetXFlipped (hFlipped);
1230
- hitData.HitRadius [HITOR] = tempVec.RadRotate (rotation.GetRadAngle ()) *= c_MPP;
1231
- // Figure out the pre-collision velocity of the hitting atom due to body translation and rotation.
1232
- hitData.HitVel [HITOR] = velocity + tempVec.Perpendicularize () * angVel;
1233
-
1234
- radMag = hitData.HitRadius [HITOR].GetMagnitude ();
1235
- // These are set temporarily here, will be re-set later when the normal of the hit terrain bitmap (ortho pixel side) is known.
1236
- hitData.HitDenominator = (1 .0F / distMass) + ((radMag * radMag) / distMI);
1237
- hitData.PreImpulse [HITOR] = hitData.HitVel [HITOR] / hitData.HitDenominator ;
1238
- // Set the atom with the hit data with all the info we have so far.
1239
- (*aItr)->SetHitData (hitData);
1240
-
1241
- if (g_SceneMan.WillPenetrate ((*aItr)->GetCurrentPos ().GetFloorIntX (), (*aItr)->GetCurrentPos ().GetFloorIntY (), hitData.PreImpulse [HITOR]))
1242
- {
1243
- // Move the penetrating atom to the pen. list from the coll. list.
1244
- penetratingAtoms.push_back (*aItr);
1245
- aItr = hitTerrAtoms.erase (aItr);
1246
- somethingPenetrated = true ;
1228
+ const std::list<Atom *>::iterator duplicateAtomItr = std::find (penetratingAtoms.begin (), penetratingAtoms.end (), *aItr);
1229
+ if (duplicateAtomItr == penetratingAtoms.end ()) {
1230
+ // Calc and store the accurate hit radius of the Atom in relation to the CoM
1231
+ tempVec = (*aItr)->GetOffset ().GetXFlipped (hFlipped);
1232
+ hitData.HitRadius [HITOR] = tempVec.RadRotate (rotation.GetRadAngle ()) *= c_MPP;
1233
+ // Figure out the pre-collision velocity of the hitting atom due to body translation and rotation.
1234
+ hitData.HitVel [HITOR] = velocity + tempVec.Perpendicularize () * angVel;
1235
+
1236
+ radMag = hitData.HitRadius [HITOR].GetMagnitude ();
1237
+ // These are set temporarily here, will be re-set later when the normal of the hit terrain bitmap (ortho pixel side) is known.
1238
+ hitData.HitDenominator = (1 .0F / distMass) + ((radMag * radMag) / distMI);
1239
+ hitData.PreImpulse [HITOR] = hitData.HitVel [HITOR] / hitData.HitDenominator ;
1240
+ // Set the atom with the hit data with all the info we have so far.
1241
+ (*aItr)->SetHitData (hitData);
1242
+
1243
+ if (g_SceneMan.WillPenetrate ((*aItr)->GetCurrentPos ().GetFloorIntX (), (*aItr)->GetCurrentPos ().GetFloorIntY (), hitData.PreImpulse [HITOR]))
1244
+ {
1245
+ // Move the penetrating atom to the pen. list from the coll. list.
1246
+ penetratingAtoms.push_back (*aItr);
1247
+ somethingPenetrated = true ;
1248
+ } else
1249
+ ++aItr;
1247
1250
} else
1248
1251
++aItr;
1249
1252
}
1250
1253
}
1251
- while (!hitTerrAtoms. empty () && somethingPenetrated);
1254
+ while (somethingPenetrated);
1252
1255
1253
1256
// TERRAIN BOUNCE //////////////////////////////////////////////////////////////////
1254
1257
// If some Atoms could not penetrate even though all the impulse was on them,
1255
1258
// gather the bounce results and apply them to the owner.
1256
- if (! hitTerrAtoms.empty ())
1259
+ if (hitTerrAtoms.size () != penetratingAtoms. size ())
1257
1260
{
1258
1261
newDir = true ;
1259
1262
@@ -1943,29 +1946,31 @@ before adding them to the MovableMan.
1943
1946
do {
1944
1947
somethingPenetrated = false ;
1945
1948
1946
- massDist = mass / static_cast <float >(hitTerrAtoms.size () * (m_Resolution ? m_Resolution : 1 ));
1949
+ massDist = mass / static_cast <float >(( hitTerrAtoms.size () - penetratingAtoms. size () ) * (m_Resolution ? m_Resolution : 1 ));
1947
1950
1948
1951
for (deque<pair<Atom *, Vector> >::iterator aoItr = hitTerrAtoms.begin (); aoItr != hitTerrAtoms.end (); )
1949
1952
{
1950
- if (g_SceneMan.WillPenetrate (intPos[X] + (*aoItr).second .GetFloorIntX (),
1951
- intPos[Y] + (*aoItr).second .GetFloorIntY (),
1952
- forceVel,
1953
- massDist))
1954
- {
1955
- // Move the penetrating atom to the pen. list from the coll. list.
1956
- penetratingAtoms.push_back (pair<Atom *, Vector>((*aoItr).first , (*aoItr).second ));
1957
- aoItr = hitTerrAtoms.erase (aoItr);
1958
- somethingPenetrated = true ;
1959
- }
1960
- else
1961
- ++aoItr;
1953
+ const deque<pair<Atom *, Vector> >::iterator duplicateAtomItr = std::find (penetratingAtoms.begin (), penetratingAtoms.end (), *aoItr);
1954
+ if (duplicateAtomItr == penetratingAtoms.end ()) {
1955
+ if (g_SceneMan.WillPenetrate (intPos[X] + (*aoItr).second .GetFloorIntX (),
1956
+ intPos[Y] + (*aoItr).second .GetFloorIntY (),
1957
+ forceVel,
1958
+ massDist))
1959
+ {
1960
+ // Move the penetrating atom to the pen. list from the coll. list.
1961
+ penetratingAtoms.push_back (pair<Atom *, Vector>((*aoItr).first , (*aoItr).second ));
1962
+ somethingPenetrated = true ;
1963
+ } else
1964
+ ++aoItr;
1965
+ } else
1966
+ ++aoItr;
1962
1967
}
1963
- } while (!hitTerrAtoms. empty () && somethingPenetrated);
1968
+ } while (somethingPenetrated);
1964
1969
1965
1970
// TERRAIN BOUNCE //////////////////////////////////////////////////////////////////
1966
1971
// If some Atom:s could not penetrate even though all the mass was on them,
1967
1972
// gather the bounce results and apply them to the owner.
1968
- if (! hitTerrAtoms.empty ())
1973
+ if (hitTerrAtoms.size () != penetratingAtoms. size ())
1969
1974
{
1970
1975
newDir = true ;
1971
1976
prevError = error;
0 commit comments