void DestructibleWallsDemo::posOnGround(hkpWorld* world, const hkVector4& pos, hkVector4& newPos) const { // cast a ray to find exact position hkpWorldRayCastInput ray; ray.m_from = pos; ray.m_to = pos; ray.m_from(1) += 20.0f; ray.m_to(1) -= 20.0f; hkpWorldRayCastOutput rayOutput; world->castRay(ray,rayOutput); newPos.setInterpolate4(ray.m_from, ray.m_to, rayOutput.m_hitFraction); }
void AabbSpawnUtil::getNewSpawnPosition(const hkVector4& aabbDims, hkVector4& positionOut) { // Try each volume in turn while (1) { hkVector4 avaliableDiag; avaliableDiag.setSub4( m_spawnVolumes[m_currentSpawnVolume].m_max, m_spawnVolumes[m_currentSpawnVolume].m_min ); avaliableDiag.sub4(aabbDims); if ( avaliableDiag(0) < 0 || avaliableDiag(2) < 0 ) { HK_ASSERT2(0, 0, "No spawn space large enough for requested aabb"); return; } // Try 100 random positions in the volume int numTries = m_allowOverlaps ? 1 : 100; for (int j = 0; j < numTries; ++j) { hkVector4 minPos(m_pseudoRandomGenerator.getRandReal01(), m_pseudoRandomGenerator.getRandReal01(), m_pseudoRandomGenerator.getRandReal01() ); if (avaliableDiag(1) < 0) { minPos(1) = 0; } minPos.mul4(avaliableDiag); minPos.add4(m_spawnVolumes[m_currentSpawnVolume].m_min); hkVector4 maxPos; maxPos.setAdd4( minPos, aabbDims ); hkAabb candidate( minPos, maxPos ); bool aabbCollides = false; if (!m_allowOverlaps) { for ( int k = 0; k < m_spawnedAabbs[m_currentSpawnVolume].getSize(); k++ ) { if ( m_spawnedAabbs[m_currentSpawnVolume][k].overlaps(candidate)) { aabbCollides = true; break; } } } if ( !aabbCollides ) { m_spawnedAabbs[m_currentSpawnVolume].pushBack(candidate); hkVector4 position; positionOut.setInterpolate4( candidate.m_min, candidate.m_max, .5f ); // If we allow penetrations, take each spawn volume in turn if ( m_allowOverlaps ) { m_currentSpawnVolume++; if (m_currentSpawnVolume == m_spawnVolumes.getSize()) { m_currentSpawnVolume = 0; } } return; } } // If we couldn't find a space, try the next volume m_currentSpawnVolume++; if (m_currentSpawnVolume == m_spawnVolumes.getSize()) { m_currentSpawnVolume = 0; m_allowOverlaps = true; } } }