bool IsSphereStatic(PhysicsSphere sphere) { bool lowVelocity = sphere.Velocity.magnitude < 0.2f; bool touchingThePlane = (CorrectedPosition(sphere) - sphere.transform.position).magnitude < 0.02f; return(lowVelocity && touchingThePlane); }
/// <summary> /// /// </summary> /// <param name="sphere"></param> /// <param name="energyDissipation" the impact of the energy dissipation on the reflected velocity></param> protected override void Choc(PhysicsSphere 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); } }
protected override void Choc(PhysicsSphere sphere, float energyDissipation = 0f) { //Debug.Log("choc: " + name); if (IsColliding(sphere) == false) { return; } if (spaced) // Yeet the ball { sphere.transform.position = CorrectedPosition(sphere); sphere.Velocity = Normal * ballPushForce; return; } if (IsSphereStaticOnBox(sphere)) { sphere.transform.position = CorrectedPosition(sphere); sphere.ApplyForce(-sphere.mass * Physics.gravity); } else { sphere.transform.position = CorrectedPosition(sphere); InverseRelativeVelocity(sphere, Reflect(RelativeVelocity(sphere))); } }
public bool isColliding(PhysicsSphere sphere) { if (WillBeCollision(sphere) == false) { return(false); } return(Distance(sphere) >= 0 || Mathf.Abs(Distance(sphere)) <= sphere.Radius); }
bool TouchingThePlane(PhysicsSphere sphere) { // sphere speed // deltaTime float deltaMove = Mathf.Max(deltaMoveCoef * sphere.Radius, RelativeVelocity(sphere).magnitude *Time.deltaTime); return((CorrectedPosition(sphere) - sphere.transform.position).magnitude <= correctedPostionCoef * deltaMove); }
private void CounterSlopes(Vector3 groundNormal) { Vector3 carForward = transform.right; Vector3 gravity = Physics.gravity; Vector3 directionOfFlat = Vector3.Cross(-gravity, groundNormal).normalized; //the direction that if you head in you wouldnt change altitude Vector3 directionOfSlope = Vector3.Cross(directionOfFlat, groundNormal); //the direction down the slope float affectOfGravity = Vector3.Dot(gravity, directionOfSlope); // returns 1 on a cliff face, 0 on a plane float affectOfWheelAlignment = Mathf.Abs(Vector3.Dot(carForward, directionOfSlope)); // returns 1 if facing down or up the slope, 0 if 90 degrees to slope PhysicsSphere.AddForce(-directionOfSlope * affectOfWheelAlignment * affectOfGravity, ForceMode.Acceleration); }
// тут просто захардкожено добавление физических моделей к определённым ячейкам public void AddPhysicsModel(IRenderPrimitive initPrimitive) { var cellWithPhysics = new MapObject { Position = initPrimitive.Position, Size = initPrimitive.Size }; var PhysicModel = new PhysicsSphere { IsSatatic = true, Radius = cellWithPhysics.Size.Length() / 2.0f, MapObject = cellWithPhysics }; World.PhysicsManager.Models.Add(PhysicModel); }
private static bool ApplyCollision(PhysicsPlane plane, PhysicsSphere sphere) { Vector3 planeOffset = plane.GetPositionOffset(); Vector3 planePos = plane.physicsObject.state.position + planeOffset; Vector3 planeLastPos = plane.physicsObject.state.lastPosition + planeOffset; Vector3 sphereOffset = sphere.GetPositionOffset(); Vector3 spherePos = sphere.physicsObject.state.position + sphereOffset; Vector3 sphereLastPos = sphere.physicsObject.state.lastPosition + sphereOffset; //Debug.LogError("Object Pos: " + sphere.physicsObject.state.position + " Offset Pos: " + spherePos); float distanceCur = plane.GetDistanceToPoint(spherePos); float distanceLast = plane.GetDistanceToPoint(sphereLastPos); //Check if there could be a collision - fast check if (distanceCur >= sphere.Radius && distanceLast >= sphere.Radius) { float dotCur = Vector3.Dot(plane.Normal, (planePos - spherePos).normalized); float dotLast = Vector3.Dot(plane.Normal, (planeLastPos - sphereLastPos).normalized); if ((dotCur > 0) == (dotLast > 0)) { return false; } } //Now check step by step int steps = 10; Vector3 planePath = planePos - planeLastPos; Vector3 spherePath = spherePos - sphereLastPos; for (int i = 0; i <= steps; i++) { Vector3 planeStepPos = planeLastPos + ((planePath / (float)steps) * i); Vector3 sphereStepPos = sphereLastPos + ((spherePath / (float)steps) * i); //Debug.Log("SpherePos: " + spherePos + "SpereLastPos: " + sphereLastPos); if (plane.GetDistanceToPoint(planeStepPos, sphereStepPos) <= (sphere.Radius + 0.01)) { Vector3 newVelocity = Vector3.Reflect(sphere.physicsObject.state.velocity, plane.Normal); newVelocity *= sphere.GetCombinedBounciness(plane); plane.physicsObject.state.position = planeLastPos - planeOffset; sphere.physicsObject.state.position = sphereLastPos - sphereOffset; sphere.physicsObject.state.velocity = newVelocity; //Debug.LogError("new Velo: " + newVelocity + " Plane: " + plane.name + " Sphere: " + sphere.name); return true; } planeLastPos = planeStepPos; sphereLastPos = sphereStepPos; } return false; }
/// <summary> /// /// </summary> /// <param name="sphere"></param> /// <param name="energyDissipation" the impact of the energy dissapation on the reflected velocity></param> public void Chock(PhysicsSphere sphere, float energyDissipation = 0) { if (isColliding(sphere) == false) { return; } //Debug.Log("Velocity Error: isVerlet " + sphere.isVerlet + " " + sphere.ErrorVelocityOnGround()); if (IsSphereStatic(sphere)) { sphere.transform.position = CorrectedPosition(sphere); sphere.ApplyForce(-sphere.Mass * Physics.gravity); } else //sphere is dynamic { sphere.Velocity = Reflect(sphere.Velocity, energyDissipation); } }
/// <summary> /// /// </summary> /// <param name="sphere"></param> /// <param name="energyDissipation" the impact of the energy dissipation on the reflected velocity></param> protected override void Choc(PhysicsSphere sphere, float energyDissipation = 0f) { if (IsColliding(sphere) == false) { return; } InverseRelativeVelocity(sphere, Reflect(RelativeVelocity(sphere), energyDissipation)); //if (IsSphereStaticOnPlane(sphere)) //{ // //sphere.transform.position = CorrectedPosition(sphere); // sphere.ApplyForce(-sphere.mass * Physics.gravity); //} //else // sphere is dynamic //{ // //sphere.transform.position = CorrectedPosition(sphere); //} }
private void FixedUpdate() { RaycastHit hitOn; RaycastHit hitNear; OnGround = Physics.Raycast(transform.position, Vector3.down, out hitOn, rayMaxDistance); NearGround = Physics.Raycast(transform.position, Vector3.down, out hitNear, rayMaxDistance + 0.8f); VehicleModel.up = Vector3.Lerp(VehicleModel.up, hitNear.normal, Time.deltaTime * 8.0f); VehicleModel.Rotate(0, transform.eulerAngles.y, 0); if (NearGround) { PhysicsSphere.AddForce(transform.forward * speedTarget, ForceMode.Acceleration); PhysicsSphere.AddForce(transform.right * strafeTarget, ForceMode.Acceleration); } else { PhysicsSphere.AddForce(transform.forward * (speedTarget / 10), ForceMode.Acceleration); PhysicsSphere.AddForce(Vector3.down * Gravity, ForceMode.Acceleration); } Vector3 localVelocity = transform.InverseTransformVector(physicsSphere.velocity); localVelocity.x *= 0.9f + (Drift / 10); if (NearGround) { PhysicsSphere.velocity = transform.TransformVector(localVelocity); } if (StopSlopeSlide) { CounterSlopes(hitNear.normal); } }
public float Distance(PhysicsSphere sphere) { Vector3 sphereToPlane = Position - sphere.transform.position; return(Vector3.Dot(sphereToPlane, Normal)); }
public Vector3 CorrectedPosition(PhysicsSphere sphere) { return(Projection(sphere) + Normal * sphere.Radius); }
private bool WillBeCollision(PhysicsSphere sphere) { return(Vector3.Dot(sphere.Velocity, Normal) < 0); }
public Vector3 Projection(PhysicsSphere sphere) { Vector3 sphereToProjection = Distance(sphere) * Normal; return(sphere.transform.position + sphereToProjection); }
bool IsSphereStaticOnBox(PhysicsSphere sphere) { bool lowVelocity = RelativeVelocity(sphere).magnitude < staticVelocityLimit; return(lowVelocity && TouchingThePlane(sphere)); }
private static bool ApplyCollision(PhysicsSphere sphereA, PhysicsSphere sphereB) { Vector3 sphereAOffset = sphereA.GetPositionOffset(); Vector3 sphereAPos = sphereA.physicsObject.state.position + sphereAOffset; Vector3 sphereALastPos = sphereA.physicsObject.state.lastPosition + sphereAOffset; Vector3 sphereBOffset = sphereB.GetPositionOffset(); Vector3 sphereBPos = sphereB.physicsObject.state.position + sphereBOffset; Vector3 sphereBLastPos = sphereB.physicsObject.state.lastPosition + sphereBOffset; float distance = GeometryHelper.DistanceSegmentSegment(sphereAPos, sphereALastPos, sphereBPos, sphereBLastPos); if (distance >= sphereA.Radius + sphereB.Radius) { return false; } Vector3 spherePathA = sphereAPos - sphereALastPos; Vector3 spherePathB = sphereBPos - sphereBLastPos; int steps = 10; for (int i = 0; i <= steps; i++) { Vector3 spherePosA = sphereALastPos + ((spherePathA / (float)steps) * i); Vector3 spherePosB = sphereBLastPos + ((spherePathB / (float)steps) * i); if ((spherePosB - spherePosA).magnitude <= sphereA.Radius + sphereB.Radius) { float massA = 1, massB = 1; Vector3 collisionNormal = spherePosA - spherePosB; collisionNormal.Normalize(); if (Vector3.Dot(collisionNormal, sphereA.physicsObject.state.velocity) < 0 || Vector3.Dot(collisionNormal, sphereB.physicsObject.state.velocity) > 0) { float tempFactorA = Vector3.Dot(sphereA.physicsObject.state.velocity, collisionNormal); float tempFactorB = Vector3.Dot(sphereB.physicsObject.state.velocity, collisionNormal); Vector3 AxisVelocityA = tempFactorA * collisionNormal; Vector3 AxisVelocityB = tempFactorB * collisionNormal; sphereA.physicsObject.state.velocity -= AxisVelocityA; sphereB.physicsObject.state.velocity -= AxisVelocityB; float tempFactor3 = massA + massB; float tempFactor4 = massA - massB; float tempFactor5 = (2.0f * massB * tempFactorB + tempFactorA * tempFactor4) / tempFactor3; float tempFactor6 = (2.0f * massA * tempFactorA - tempFactorB * tempFactor4) / tempFactor3; AxisVelocityA = tempFactor5 * collisionNormal; AxisVelocityB = tempFactor6 * collisionNormal; AxisVelocityA *= sphereA.GetCombinedBounciness(sphereB); AxisVelocityB *= sphereB.GetCombinedBounciness(sphereA); sphereA.physicsObject.state.velocity += AxisVelocityA; sphereB.physicsObject.state.velocity += AxisVelocityB; sphereA.physicsObject.state.position = sphereALastPos - sphereAOffset; sphereB.physicsObject.state.position = sphereBLastPos - sphereBOffset; return true; } } sphereALastPos = spherePosA; sphereBLastPos = spherePosB; } return false; }