public void RunVeh2VehCollision() { // Reset for (int i2 = 0; i2 < impactPairs.Length; i2 += 1) { impactPairs[i2] = false; } for (int i2 = 0; i2 < rect.Length; i2 += 1) { rect[i2] = null; } // Optimisation (previously generated a lot of garbage) //bool[] impactPairs = new bool[MAX_RACING_CARS_SQUARED]; //VectorF[] rect = new VectorF[4]; int i = 0; for (i = 0; i < MAX_RACING_CARS; i += 1) { if (!Cars[i].IsInit) { continue; } int j = 0; for (j = 0; j < MAX_RACING_CARS; j += 1) { if (j == i) { continue; } if (!Cars[j].IsInit) { continue; } if (i > j && impactPairs[i * MAX_RACING_CARS + j]) { continue; } rect[0] = Cars[j].collPoint[0]; rect[1] = Cars[j].collPoint[1]; rect[2] = Cars[j].collPoint[2]; rect[3] = Cars[j].collPoint[3]; VectorF impact = Cars[i].DetectCollision(rect, Cars[j].velocity, j); if (impact != null) { impactPairs[i * MAX_RACING_CARS + j] = true; Cars[i].velocity.add(impact); impact.negate(); Cars[j].velocity.add(impact); } } } }
public VectorF DetectCollision(VectorF[] rect, VectorF otherVelocity, int otherIndex) { this.numCarHits = 0; VectorF p21 = VectorF.subtract(rect[1], rect[0]); VectorF p41 = VectorF.subtract(rect[3], rect[0]); float p21magnitude_squared = p21.x * p21.x + p21.y * p21.y; float p41magnitude_squared = p41.x * p41.x + p41.y * p41.y; int i = 0; for (i = 0; i < NUM_COLLISION_POINTS; i += 1) { this.collPtCarHit[i] = -1; VectorF p = VectorF.subtract(this.collPoint[i], rect[0]); float pp21 = p.x * p21.x + p.y * p21.y; if (pp21 >= 0.0 && pp21 <= p21magnitude_squared) { float pp41 = p.x * p41.x + p.y * p41.y; if (pp41 >= 0.0 && pp41 <= p41magnitude_squared) { this.collPtCarHit[i] = otherIndex; this.numCarHits += 1; } } } if (this.numCarHits == 0) { return(null); } VectorF impactVelocity = new VectorF(); VectorF posImpact = VectorF.zero(); VectorF negImpact = VectorF.zero(); for (i = 0; i < NUM_COLLISION_POINTS; i += 1) { if (this.collPtCarHit[i] < 0) { continue; } if (this.oldCollPtCarHit[i] == this.collPtCarHit[i]) { continue; } VectorF impact = VectorF.subtract(this.collPoint[i], this.oldCollPt[i]); if (impact.isZero()) { continue; } impact.normalize(); float velProjection = VectorF.projection(this.velocity, impact); if (velProjection > 0.0f) { impact.scale(-velProjection * (1.0f - this.softImpactLossFactor)); posImpact.max(impact); negImpact.min(impact); impact.negate(); impact.normalize(); } float otherProjection = VectorF.projection(otherVelocity, impact); if (otherProjection < 0.0f) { impact.scale(otherProjection * (1.0f - this.softImpactLossFactor)); posImpact.max(impact); negImpact.min(impact); } } impactVelocity.add(posImpact); impactVelocity.add(negImpact); return(impactVelocity); }