public override void Update() { if (!Active) { return; } if (_collisionEvents.Count != 0) { VehicleCollision ce = _collisionEvents.Peek(); if (ce.deformationQueue.Count == 0) { _collisionEvents.Dequeue(); if (_collisionEvents.Count != 0) { ce = _collisionEvents.Peek(); } } int vertexCount = 0; while (vertexCount < deformationVerticesPerFrame && ce.deformationQueue.Count > 0) { MeshFilter mf = ce.deformationQueue.Dequeue(); vertexCount += mf.mesh.vertexCount; MeshDeform(ce, mf); } } }
public void Update() { if (collisionEvents.Count != 0) { VehicleCollision ce = collisionEvents.Peek(); if (ce.deformationQueue.Count == 0) { collisionEvents.Dequeue(); if (collisionEvents.Count != 0) { ce = collisionEvents.Peek(); } else { return; } } int vertexCount = 0; while (vertexCount < deformationVerticesPerFrame && ce.deformationQueue.Count > 0) { MeshFilter mf = ce.deformationQueue.Dequeue(); vertexCount += mf.mesh.vertexCount; MeshDeform(ce, mf); } if (DamagePercent >= 1) { vc.engine.Stop(); } } }
public static VehicleCollision CheckCollision(Vehicle v1, Vehicle v2) { VehicleCollision rv = null; if (Dist(v1, v2) < 10.0) { var pos = (v1.avaGo.transform.position + v2.avaGo.transform.position) / 2; rv = new VehicleCollision(v1, v2, pos); } return(rv); }
/// <summary> /// Add collision to the queue of collisions waiting to be processed. /// </summary> public void Enqueue(Collision collision, float accelerationMagnitude) { foreach (string tag in ignoreTags) { if (collision.collider.gameObject.CompareTag(tag)) { return; } } VehicleCollision vehicleCollision = new VehicleCollision(); vehicleCollision.collision = collision; vehicleCollision.decelerationMagnitude = accelerationMagnitude; vc.damage.damage += accelerationMagnitude; Vector3 collisionPoint = AverageCollisionPoint(collision.contacts); foreach (MeshFilter deformableMeshFilter in deformableMeshFilters) { if (deformableMeshFilter.gameObject.tag != "Wheel") { //Debug.Log("Enqueue " + deformableMeshFilter.name); vehicleCollision.deformationQueue.Enqueue(deformableMeshFilter); } // If crash happened around wheel do not deform it but rather detoriate it's handling else { foreach (Wheel wheel in vc.Wheels) { if (Vector3.Distance(collisionPoint, wheel.VisualTransform.position) < wheel.Radius * 1.2f) { wheel.Damage += accelerationMagnitude; } } } } collisionEvents.Enqueue(vehicleCollision); }
/// <summary> /// Deforms a mesh using data from collision event. /// </summary> public void MeshDeform(VehicleCollision collisionEvent, MeshFilter deformableMeshFilter) { foreach (ContactPoint contactPoint in collisionEvent.collision.contacts) { Vector3 collisionPoint = contactPoint.point; Vector3 direction = contactPoint.normal; float vertexDistanceThreshold = Mathf.Clamp(collisionEvent.decelerationMagnitude * deformationStrength / 2000f, 0f, deformationRadius); Vector3[] vertices = deformableMeshFilter.mesh.vertices; int vertLength = vertices.Length; for (int i = 0; i < vertLength; i++) { Vector3 globalVertex = deformableMeshFilter.transform.TransformPoint(vertices[i]); float distance = Mathf.Sqrt( (collisionPoint.x - globalVertex.x) * (collisionPoint.x - globalVertex.x) + (collisionPoint.z - globalVertex.z) * (collisionPoint.z - globalVertex.z) + (collisionPoint.y - globalVertex.y) * (collisionPoint.y - globalVertex.y)); distance *= Random.Range(1f - deformationRandomness, 1f + deformationRandomness); if (distance < vertexDistanceThreshold) { globalVertex = globalVertex + direction * (vertexDistanceThreshold - distance); vertices[i] = deformableMeshFilter.transform.InverseTransformPoint(globalVertex); } } deformableMeshFilter.mesh.vertices = vertices; deformableMeshFilter.mesh.RecalculateNormals(); deformableMeshFilter.mesh.RecalculateTangents(); } }
/// <summary> /// Deforms a mesh using data from collision event. /// </summary> public void MeshDeform(VehicleCollision collisionEvent, MeshFilter deformableMeshFilter) { //Debug.Log("Deforming " + deformableMeshFilter.name); Vector3 collisionPoint = AverageCollisionPoint(collisionEvent.collision.contacts); Vector3 direction = Vector3.Normalize(deformableMeshFilter.transform.position - collisionPoint); float xDot = Mathf.Abs(Vector3.Dot(direction, Vector3.right)); float yDot = Mathf.Abs(Vector3.Dot(direction, Vector3.up)); float zDot = Mathf.Abs(Vector3.Dot(direction, Vector3.forward)); float vertexDistanceThreshold = Mathf.Clamp((collisionEvent.decelerationMagnitude * deformationStrength) / (1000f), 0f, deformationRadius); Vector3[] vertices = deformableMeshFilter.mesh.vertices; for (int i = 0; i < vertices.Length; i++) { Vector3 globalVertex = deformableMeshFilter.transform.TransformPoint(vertices[i]); float distance = Mathf.Sqrt( (collisionPoint.x - globalVertex.x) * (collisionPoint.x - globalVertex.x) * xDot + (collisionPoint.z - globalVertex.z) * (collisionPoint.z - globalVertex.z) * zDot + (collisionPoint.y - globalVertex.y) * (collisionPoint.y - globalVertex.y) * yDot); distance *= Random.Range(1f - deformationRandomness, 1f + deformationRandomness); if (distance < vertexDistanceThreshold) { globalVertex = globalVertex + direction * (vertexDistanceThreshold - distance); vertices[i] = deformableMeshFilter.transform.InverseTransformPoint(globalVertex); } } deformableMeshFilter.mesh.vertices = vertices; deformableMeshFilter.mesh.RecalculateNormals(); deformableMeshFilter.mesh.RecalculateTangents(); }
/// <summary> /// Add collision to the queue of collisions waiting to be processed. /// </summary> public bool Enqueue(Collision collision, float accelerationMagnitude) { for (int index = 0; index < collisionIgnoreTags.Count; index++) { string tag = collisionIgnoreTags[index]; if (collision.collider.CompareTag(tag)) { return(false); } } VehicleCollision vehicleCollision = new VehicleCollision(); vehicleCollision.collision = collision; vehicleCollision.decelerationMagnitude = accelerationMagnitude; Vector3 collisionPoint = AverageCollisionPoint(collision.contacts); if (!visualOnly && damageIntensity > 0) { damageIntensity = damageIntensity <0 ? 0 : damageIntensity> 0.99f ? 0.99f : damageIntensity; float damage = collision.impulse.magnitude / (Time.fixedDeltaTime * vc.mass * 10f) * damageIntensity * 2e-03f; Damage += damage; Damage = Damage < 0 ? 0 : Damage > 1 ? 1 : Damage; // Apply damage to wheels foreach (WheelComponent wc in vc.Wheels) { if (Vector3.Distance(collisionPoint, wc.wheelController.worldCenter) < wc.Radius * 1.5f) { wc.Damage += damage; } } // Apply damage to powertrain components float dimensionsMagnitude = vc.vehicleDimensions.magnitude; if (Vector3.Distance(vc.WorldEnginePosition, collisionPoint) < dimensionsMagnitude * 0.25f) { vc.powertrain.engine.ComponentDamage += damage; } if (Vector3.Distance(vc.WorldTransmissionPosition, collisionPoint) < dimensionsMagnitude * 0.25f) { vc.powertrain.transmission.ComponentDamage += damage; } } if (!meshDeform) { return(true); } // Deform meshes foreach (MeshFilter deformableMeshFilter in _deformableMeshFilters) { string meshTag = deformableMeshFilter.gameObject.tag; if (meshTag == null) { vehicleCollision.deformationQueue.Enqueue(deformableMeshFilter); } else { bool ignoreTag = false; for (int index = 0; index < deformationIgnoreTags.Count; index++) { if (meshTag == deformationIgnoreTags[index]) { ignoreTag = true; break; } } if (!ignoreTag) { vehicleCollision.deformationQueue.Enqueue(deformableMeshFilter); } } } _collisionEvents.Enqueue(vehicleCollision); return(true); }