Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- @param info collision info on the object object which is influenced by the deflection (or NULL for landscape collision)
- @param normal incident surface normal (normalized)
- @param isect intersection point (place where shot entered the object)
- @param dist distance traveled inside of the object
- @param deltaT time which still needs to be simulated
- returns true when the penetration occurred or false if there was no penetration and the impact should be simulated
- */
- bool ShotShell::SimulatePenetration(const CollisionInfo *info, Vector3Par normal, Vector3Par isect, float dist, float deltaT)
- {
- const AmmoType *ammoType = Type();
- float penetrability = info->BulletPenetrability();
- if ((penetrability <= 0.0f) || (ammoType->explosive >= 0.7f && info->BulletPenetrability() > 100))
- return false;
- // check distance traveled in the object, assume bullet deceleration is linear
- float distInside = info->DistInside();
- Assert(distInside > 0.0f);
- if(info->Thickness()>0)
- { //use thickness only when bullet enters object
- if(info->entry)
- {//bigger the entry angle is, more material we go trough
- float cosAngle = info->dirOutNotNorm.Normalized().DotProduct(FutureVisualState()._speed.Normalized());
- float thick = (cosAngle != 0)? (fabsf(info->Thickness() / cosAngle)) : distInside;
- //collision geometry is not thick enough
- distInside = (info->exit)? distInside = floatMin(thick,distInside) : thick;
- }
- //thickness has already been used
- else penetrability = 0.01f;
- }
- float speed = FutureVisualState()._speed.Size();
- float deceleration = distInside * penetrability / ammoType->caliber;
- if (speed <= deceleration)
- return false;
- Vector3 lDirNorm = FutureVisualState()._speed.Normalized();
- // move the bullet to the point where it goes out of the object
- Vector3 newPos = isect + distInside * lDirNorm;
- // reduce speed, change direction, continue traveling
- float reduceSpeed = deceleration / speed;
- const float changeSize = 0.25f;
- Vector3 changeDir = Vector3(GRandGen.Gauss(-changeSize, 0.0f, changeSize) * reduceSpeed,
- GRandGen.Gauss(-changeSize, 0.0f, changeSize) * reduceSpeed,
- GRandGen.Gauss(-changeSize, 0.0f, changeSize) * reduceSpeed);
- Vector3 dir = lDirNorm + changeDir;
- dir.Normalize();
- Vector3 newSpeed = dir * (speed - deceleration);
- // FIXME RHAL: use _speed or newSpeed here?
- float timeInside = distInside * FutureVisualState()._speed.InvSize();
- // if we did not simulate any time, we have a problem - what can we do? Next iteration will detect collision again
- Assert(timeInside > 0.0f);
- // FIXME RHAL: resolve this case properly
- Assert(timeInside <= deltaT*1.05f);
- if (timeInside > deltaT)
- timeInside = deltaT;
- // handle the in-side object part
- UpdatePosAndSpeed("penetrating", timeInside, newPos, penetrability);
- // revert time back to the moment we went out
- deltaT -= timeInside;
- DebugShotShell(info, timeInside, FutureVisualState()._speed, newSpeed, "P");
- SimulateHit(info, isect, normal, newSpeed);
- FutureVisualState()._speed = newSpeed;
- if (dist > 0.01f)
- // make sure the partial segment is rendered; after penetration we want no more suppression tracing, the trajectory is unpredictable
- TerminateSegment(true);
- SimulateMovement(deltaT, true);
- return true;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement