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);
}
Exemple #2
0
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;
		}
	}
}