//[MethodImpl(MethodImplOptions.AggressiveInlining)] private Vector3 ParticleCollision(Vector3d pPos, Vector3d pVel, int mask) { RaycastHit hit; if (Physics.Raycast( pPos, pVel, out hit, (float)pVel.magnitude * Time.deltaTime * physicsPass * TimeWarp.CurrentRate, mask)) { //// collidersName[hit.collider.name] = true; if (hit.collider.name != SmokeScreenUtil.LaunchPadGrateColliderName) { Vector3 unitTangent = (hit.normal.x == 0 && hit.normal.y == 0) ? new Vector3(1, 0, 0) : Vector3.ProjectOnPlane(new Vector3(0, 0, 1), hit.normal).normalized; Vector3 hVel = Vector3.ProjectOnPlane(pVel, hit.normal); Vector3 reflectedNormalVelocity = hVel - pVel; float residualFlow = reflectedNormalVelocity.magnitude * (1 - collideRatio); // An attempt at a better velocity change; the blob collides with some // restitution coefficient collideRatio << 1 and we add a random tangential term // for outflowing particles---randomness handwaved in through fluid dynamics: float randomAngle = Random.value * 360.0f; Vector3d outflow = Quaternion.AngleAxis(randomAngle, hit.normal) * unitTangent * residualFlow; pVel = hVel + collideRatio * reflectedNormalVelocity + outflow * (1 - stickiness); } else { // Don't collide with the launch pad grid and add colliders under it if (!addedLaunchPadCollider) { addedLaunchPadCollider = SmokeScreenUtil.AddLaunchPadColliders(hit); } } } return(pVel); }