| 4533 | } |
| 4534 | |
| 4535 | void b2ParticleSystem::RayCast(b2RayCastCallback* callback, |
| 4536 | const b2Vec2& point1, |
| 4537 | const b2Vec2& point2) const |
| 4538 | { |
| 4539 | if (m_proxyBuffer.GetCount() == 0) |
| 4540 | { |
| 4541 | return; |
| 4542 | } |
| 4543 | b2AABB aabb; |
| 4544 | aabb.lowerBound = b2Min(point1, point2); |
| 4545 | aabb.upperBound = b2Max(point1, point2); |
| 4546 | float32 fraction = 1; |
| 4547 | // solving the following equation: |
| 4548 | // ((1-t)*point1+t*point2-position)^2=diameter^2 |
| 4549 | // where t is a potential fraction |
| 4550 | b2Vec2 v = point2 - point1; |
| 4551 | float32 v2 = b2Dot(v, v); |
| 4552 | InsideBoundsEnumerator enumerator = GetInsideBoundsEnumerator(aabb); |
| 4553 | int32 i; |
| 4554 | while ((i = enumerator.GetNext()) >= 0) |
| 4555 | { |
| 4556 | b2Vec2 p = point1 - m_positionBuffer.data[i]; |
| 4557 | float32 pv = b2Dot(p, v); |
| 4558 | float32 p2 = b2Dot(p, p); |
| 4559 | float32 determinant = pv * pv - v2 * (p2 - m_squaredDiameter); |
| 4560 | if (determinant >= 0) |
| 4561 | { |
| 4562 | float32 sqrtDeterminant = b2Sqrt(determinant); |
| 4563 | // find a solution between 0 and fraction |
| 4564 | float32 t = (-pv - sqrtDeterminant) / v2; |
| 4565 | if (t > fraction) |
| 4566 | { |
| 4567 | continue; |
| 4568 | } |
| 4569 | if (t < 0) |
| 4570 | { |
| 4571 | t = (-pv + sqrtDeterminant) / v2; |
| 4572 | if (t < 0 || t > fraction) |
| 4573 | { |
| 4574 | continue; |
| 4575 | } |
| 4576 | } |
| 4577 | b2Vec2 n = p + t * v; |
| 4578 | n.Normalize(); |
| 4579 | float32 f = callback->ReportParticle(this, i, point1 + t * v, n, t); |
| 4580 | fraction = b2Min(fraction, f); |
| 4581 | if (fraction <= 0) |
| 4582 | { |
| 4583 | break; |
| 4584 | } |
| 4585 | } |
| 4586 | } |
| 4587 | } |
| 4588 | |
| 4589 | float32 b2ParticleSystem::ComputeCollisionEnergy() const |
| 4590 | { |
no test coverage detected