public void CollisionStay(PhysXCollision collision) { // float penCoefficientA = (penForMaxImpulseScale - penForUnitImpulseScale * maxImpulseScale) / (penForUnitImpulseScale * penForUnitImpulseScale * penForMaxImpulseScale - penForUnitImpulseScale * penForMaxImpulseScale * penForMaxImpulseScale); // float penCoefficientB = maxImpulseScale / penForMaxImpulseScale - penCoefficientA * penForMaxImpulseScale; if (collision.rigidBody != null) { velocity = (rigidBody.velocity - collision.rigidBody.velocity).magnitude; } else { velocity = rigidBody.velocity.magnitude; } velocity -= velocityOffset; if (velocity < 0) { velocity = 0; } float penExp = velocityScale / velocity; if (penExp > maxPenExp) { penExp = maxPenExp; } float penCoefficient = 1 / Mathf.Pow(penForUnitImpulseScale, penExp); for (int i = 0; i < collision.contactCount; i++) { PhysXContactPoint contactPoint = collision.GetContact(i); if (contactPoint.ownShape == collider.shape) { float penetration = -contactPoint.separation; if (penetration < 0) { penetration = 0; } //Debug.Log("penetration: " + penetration); Vector3 impulse = contactPoint.impulse; // float impulseScale = penCoefficientA * penetration * penetration + penCoefficientB * penetration; float impulseScale = penCoefficient * Mathf.Pow(penetration, penExp); if (impulseScale > maxImpulseScale) { impulseScale = maxImpulseScale; } impulse *= impulseScale; rigidBody.AddGhostImpulse(impulse, contactPoint.point); } } }
public void CollisionStay(PhysXCollision collision) { if (collision.contactCount > 0 && collision.GetContact(0).separation < -minPenetration) { if ((collision.rigidBody == null || collision.rigidBody.mass >= minDeformationMass) && !collision.collider.gameObject.CompareTag("DustGround")) { meshDeformationMarker.Begin(); bool isInconvenient = collision.collider is PhysXMeshCollider && !((PhysXMeshCollider)collision.collider).convex; Vector3 collisionSurfaceNormal = Vector3.zero; Vector3 collisionSurfacePoint = Vector3.zero; for (int i = 0; i < collision.contactCount; i++) { PhysXContactPoint contactPoint = collision.GetContact(i); float impulseMagnitude = contactPoint.impulse.magnitude; collisionSurfaceNormal += contactPoint.normal; collisionSurfacePoint += contactPoint.point; } collisionSurfaceNormal /= collision.contactCount; collisionSurfacePoint /= collision.contactCount; collisionSurfaceNormal = transform.InverseTransformDirection(collisionSurfaceNormal); collisionSurfacePoint = transform.InverseTransformPoint(collisionSurfacePoint); gizmoSurfaceNormal = collisionSurfaceNormal; gizmoSurfacePoint = collisionSurfacePoint; Vector3 oldPosition = collision.body.position; Quaternion oldRotation = collision.body.rotation; collision.body.position = transform.InverseTransformPoint(collision.body.position); collision.body.rotation = Quaternion.Inverse(transform.rotation) * collision.body.rotation; VertexGroup[] groups = meshGraph.groups; for (int i = 0; i < groups.Length; i++) { VertexGroup current = groups[i]; Vector3 vertex = current.pos; if (IsBeyondCollisionSurface(collisionSurfaceNormal, collisionSurfacePoint, vertex)) { if (isInconvenient || collision.collider.ClosestPoint(vertex) == vertex) { Vector3 deformation = DeformationFromCollisionSurface(collisionSurfaceNormal, collisionSurfacePoint, vertex); // if (addNoise) deformation *= Random.value * multiplier + addition; current.MoveBy(vertices, deformation, false); current.SetWasMoved(teamId, true); if (!current.GetEnqueued(teamId)) { vertexQueue.Enqueue(current); current.SetEnqueued(teamId, true); // Debug.Log("Vertex group " + current.vertexIndices[0] + " enqueued due to collision"); } } } } collision.body.position = oldPosition; collision.body.rotation = oldRotation; dissipationNeeded = true; meshDeformationMarker.End(); } } }