/// <summary> /// /// </summary> /// <param name="sphere"></param> /// <param name="energyDissipation" the impact of the energy dissipation on the reflected velocity></param> public void Choc(MonoPhysicalSphere sphere, float energyDissipation = 0f) { //Debug.Log("choc: " + name); if (IsColliding(sphere) == false) { return; } //Debug.Log("Sphere plane collision on: " + name); //Debug.Log("Velocity Error: isVerlet: " + sphere.isVerlet + " " + sphere.ErrorVelocityOnTheGround()); //sphere.Velocity = Vector3.Reflect(sphere.Velocity, Normal); if (IsSphereStaticOnPlane(sphere)) { sphere.transform.position = CorrectedPosition(sphere); sphere.ApplyForce(-sphere.mass * Physics.gravity); } else // sphere is dynamic { sphere.transform.position = CorrectedPosition(sphere); InverseRelativeVelocity(sphere, Reflect(RelativeVelocity(sphere), energyDissipation)); //sphere.Velocity = Reflect(RelativeVelocity(sphere), energyDissipation); } }
private void Collide(MonoPhysicalSphere a, MonoPhysicalSphere b) { //if (a == null || b == null) // return; if (a.IsLastColliderEqual(b) || b.IsLastColliderEqual(a)) { return; } a.SetLastCollider(b); b.SetLastCollider(a); float dot = Vector3.Dot(a.Velocity, b.Velocity); float dist = Vector3.Distance(a.transform.position, b.transform.position); float radiusSum = a.Radius + b.Radius; if (dist > radiusSum) { return; } //Debug.Log("Collision"); Vector3 aToB = (b.transform.position - a.transform.position).normalized; Vector3 pushFromA = radiusSum * aToB; // position correction b.transform.position = a.transform.position + 1f * pushFromA; //a.transform.position = b.transform.position - 0.5f * pushFromA; TwoDimensionReflection(a, b); }
float Distance(MonoPhysicalSphere sphere) { Vector3 sphereToPlane = Position - sphere.transform.position; //Vector3 sphereToPlane = sphere.transform.position - Position; return(Vector3.Dot(sphereToPlane, Normal)); }
bool TouchingThePlane(MonoPhysicalSphere sphere) { // sphere speed // deltaTime float deltaMove = Mathf.Max(deltaMoveCoef * sphere.Radius, RelativeVelocity(sphere).magnitude *Time.fixedDeltaTime); return((CorrectedPosition(sphere) - sphere.transform.position).magnitude <= correctedPostionCoef * deltaMove); }
bool IsColliding(MonoPhysicalSphere sphere) { if (WillBeCollision(sphere) == false) { return(false); } return(Distance(sphere) >= 0f || Mathf.Abs(Distance(sphere)) <= sphere.Radius); // for dynamic ball the WillBeCollision is preventing the multi-collision; //return WillBeCollision(sphere) && TouchingThePlane(sphere); }
private void ManageCollision() { for (int i = 0; i < spheres.Count; i++) { MonoPhysicalSphere a = spheres[i]; for (int j = 0; j < spheres.Count; j++) { MonoPhysicalSphere b = spheres[j]; if (a == b) { continue; } Collide(a, b); } } }
void OnDimensionReflection(MonoPhysicalSphere a, MonoPhysicalSphere b) { float massDiff = a.mass - b.mass; float massSum = a.mass + b.mass; float doubleMassA = a.mass * 2f; float doubleMassB = b.mass * 2f; float diffOverSum = massDiff / massSum; float doubleAOverSum = doubleMassA / massSum; float doubleBOverSum = doubleMassB / massSum; Vector3 diffOverSumTimesVa = diffOverSum * a.Velocity; Vector3 diffOverSumTimesVb = -diffOverSum * b.Velocity; Vector3 doubleAOverSumTimesVa = doubleAOverSum * a.Velocity; Vector3 doubleBOverSumTimesVb = doubleBOverSum * b.Velocity; a.Velocity = diffOverSumTimesVa + doubleBOverSumTimesVb; b.Velocity = doubleAOverSumTimesVa + diffOverSumTimesVb; }
private void Shoot() { if (Input.GetMouseButtonDown(0) == false) { return; } RaycastHit hit; if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit) == false) { return; } MonoPhysicalSphere physicalSphere = Instantiate(shootBall, muzzel.transform.position, muzzel.transform.rotation). GetComponent <MonoPhysicalSphere>(); physicalSphere.Velocity = (hit.point - muzzel.transform.position).normalized * shootBallVelocity; ballFired(); }
private void TwoDimensionReflection(MonoPhysicalSphere a, MonoPhysicalSphere b) { float massSum = a.mass + b.mass; float doubleMassA = a.mass * 2f; float doubleMassB = b.mass * 2f; float doubleAOverSum = doubleMassA / massSum; float doubleBOverSum = doubleMassB / massSum; Vector3 vAMinusVB = a.Velocity - b.Velocity; Vector3 vBMinusVA = -vAMinusVB; Vector3 posAMinusPosB = a.transform.position - b.transform.position; Vector3 posBMinusPosA = -posAMinusPosB; float posesSquare = Vector3.Dot(posAMinusPosB, posAMinusPosB); float dotA = Vector3.Dot(vAMinusVB, posAMinusPosB); float dotB = Vector3.Dot(vBMinusVA, posBMinusPosA); a.Velocity -= doubleBOverSum * (dotA / posesSquare) * posAMinusPosB; b.Velocity -= doubleAOverSum * (dotB / posesSquare) * posBMinusPosA; }
Vector3 CorrectedPosition(MonoPhysicalSphere sphere) { return(Projection(sphere) + Normal * sphere.Radius); }
bool WillBeCollision(MonoPhysicalSphere sphere) { //Debug.Log("WillBeCollision: " + name); //return Vector3.Dot(sphere.Velocity, Normal) < 0f; return(Vector3.Dot(RelativeVelocity(sphere), Normal) < 0f); }
Vector3 Projection(MonoPhysicalSphere sphere) { Vector3 sphereToProjection = Distance(sphere) * Normal; return(sphere.transform.position + sphereToProjection); }
bool IsSphereStaticOnPlane(MonoPhysicalSphere sphere) { bool lowVelocity = RelativeVelocity(sphere).magnitude < staticVelocityLimit; return(lowVelocity && TouchingThePlane(sphere)); }