Пример #1
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CRecastMgr::Update( float dt )
{
	VPROF_BUDGET( "CRecastMgr::Update", "RecastNav" );

#ifndef CLIENT_DLL
	UpdateRebuildPartial();
#endif // CLIENT_DLL

	for ( int i = m_Meshes.First(); i != m_Meshes.InvalidIndex(); i = m_Meshes.Next(i ) )
	{
		CRecastMesh *pMesh = m_Meshes[ i ];
		pMesh->Update( dt );
	}
}
Пример #2
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
bool CRecastMgr::InsertMesh( const char *name, float agentRadius, float agentHeight, float agentMaxClimb, float agentMaxSlope )
{
	CRecastMesh *pMesh = GetMesh( name );
	if( pMesh )
	{
		Warning( "CRecastMgr::InsertMesh: %s already exists!\n", name );
		return false;
	}

	pMesh = new CRecastMesh();
	pMesh->Init( name, agentRadius, agentHeight, agentMaxClimb, agentMaxSlope );
	m_Meshes.Insert( pMesh->GetName(), pMesh );
	return true;
}
Пример #3
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
bool CRecastMgr::BuildMesh( CMapMesh *pMapMesh, const char *name )
{
	CRecastMesh *pMesh = GetMesh( name );
	if( !pMesh )
	{
		pMesh = new CRecastMesh();
		pMesh->Init( name );
		m_Meshes.Insert( pMesh->GetName(), pMesh );
	}
	if( pMesh->Build( pMapMesh ) )
	{
		return true;
	}
	return false;
}
Пример #4
0
bool CRecastMgr::InitDefaultMeshes()
{
	// Ensures default meshes exists, even if they don't have a mesh loaded.
	for( int i = 0; i < ARRAYSIZE( s_DefaultMeshNames ); i++ )
	{
		CRecastMesh *pMesh = GetMesh( s_DefaultMeshNames[i] );
		if( !pMesh )
		{
			pMesh = new CRecastMesh();
			pMesh->Init( s_DefaultMeshNames[i] );
			m_Meshes.Insert( pMesh->GetName(), pMesh );
		}
	}

	return true;
}
Пример #5
0
//-----------------------------------------------------------------------------
// Purpose: Adds an obstacle based on bounds and height for entity
// TODO: 
//-----------------------------------------------------------------------------
bool CRecastMgr::AddEntBoxObstacle( CBaseEntity *pEntity, const Vector &mins, const Vector &maxs, float height )
{
	if( !pEntity )
		return false;

	matrix3x4_t transform; // model to world transformation
	AngleMatrix( QAngle(0, pEntity->GetAbsAngles()[YAW], 0), pEntity->GetAbsOrigin(), transform );
	//AngleMatrix( pEntity->GetAbsAngles(), pEntity->GetAbsOrigin(), transform );

	Vector convexHull[4];

	NavObstacleArray_t &obstacle = FindOrCreateObstacle( pEntity );

	bool bSuccess = true;
	for ( int i = m_Meshes.First(); i != m_Meshes.InvalidIndex(); i = m_Meshes.Next(i ) )
	{
		CRecastMesh *pMesh = m_Meshes[ i ];
		// TODO: better check. Needs to filter out obstacles for air mesh
		if( pMesh->GetAgentHeight() - 50.0f > height )
			continue;

		float erodeDist = pMesh->GetAgentRadius() + 8.0f;

		VectorTransform( mins + Vector(-erodeDist, -erodeDist, 0), transform, convexHull[0] );
		VectorTransform( Vector(mins.x, maxs.y, mins.z) + Vector(-erodeDist, erodeDist, 0), transform, convexHull[1] );
		VectorTransform( Vector(maxs.x, maxs.y, mins.z) + Vector(erodeDist, erodeDist, 0), transform, convexHull[2] );
		VectorTransform( Vector(maxs.x, mins.y, mins.z) + Vector(erodeDist, -erodeDist, 0), transform, convexHull[3] );

		/*for( int j = 0; j < 4; j++ )
		{
			int next = (j+1) == 4 ? 0 : j + 1;
			NDebugOverlay::Line( convexHull[j], convexHull[next], 0, 255, 0, true, 10.0f );
		}*/

		obstacle.obs.AddToTail();
		obstacle.obs.Tail().meshIndex = i;
		obstacle.obs.Tail().ref = pMesh->AddTempObstacle( pEntity->GetAbsOrigin(), convexHull, 4, height );

		if( obstacle.obs.Tail().ref == 0 )
			bSuccess = false;
	}
	return bSuccess;
}
Пример #6
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CRecastMgr::Reset()
{
	m_bLoaded = false;

	for ( int i = m_Meshes.First(); i != m_Meshes.InvalidIndex(); i = m_Meshes.Next(i ) )
	{
		CRecastMesh *pMesh = m_Meshes[ i ];
		pMesh->Reset();
	}
	m_Meshes.PurgeAndDeleteElements();

#ifndef CLIENT_DLL
	m_pendingPartialMeshUpdates.Purge();

	if( m_pMapMesh )
	{
		delete m_pMapMesh;
		m_pMapMesh = NULL;
	}
#endif // CLIENT_DLL
}
Пример #7
0
//-----------------------------------------------------------------------------
// Purpose: Saves the generated navigation meshes
//-----------------------------------------------------------------------------
void CRecastMgr::DebugRender()
{
	int idx = m_Meshes.Find( recast_debug_mesh.GetString() );
	if( idx == m_Meshes.InvalidIndex() )
	{
		// Might be visualizing a server mesh that does not exist on the client
		// Insert dummy mesh on the fly.
		IRecastMgr *pRecastMgr = warsextension->GetRecastMgr();
		if( pRecastMgr->GetNavMesh( recast_debug_mesh.GetString() ) )
		{
			CRecastMesh *pMesh = new CRecastMesh();
			pMesh->Init( recast_debug_mesh.GetString() );
			idx = m_Meshes.Insert( pMesh->GetName(), pMesh );
		}
	}

	if( m_Meshes.IsValidIndex( idx ) )
	{
		m_Meshes[idx]->DebugRender();
	}
}
Пример #8
0
//-----------------------------------------------------------------------------
// Purpose: Determines best nav mesh radius/height
//-----------------------------------------------------------------------------
int CRecastMgr::FindBestMeshForRadiusHeight( float radius, float height )
{
	int bestIdx = -1;
	float fBestRadiusDiff = 0;
	float fBestHeightDiff = 0;
	for ( int i = m_Meshes.First(); i != m_Meshes.InvalidIndex(); i = m_Meshes.Next(i ) )
	{
		CRecastMesh *pMesh = m_Meshes[ i ];
		if( !pMesh->IsLoaded() )
		{
			continue;
		}

		// Only consider fitting meshes
		if( radius > pMesh->GetAgentRadius() || height > pMesh->GetAgentHeight() )
		{
			continue;
		}

		// From these meshes, pick the best fitting one
		float fRadiusDiff = fabs( pMesh->GetAgentRadius() - radius );
		float fHeightDiff = fabs( pMesh->GetAgentHeight() - height );
		if( bestIdx == -1 || (fRadiusDiff + fHeightDiff <= fBestRadiusDiff + fBestHeightDiff) )
		{
			bestIdx = i;
			fBestRadiusDiff = fRadiusDiff;
			fBestHeightDiff = fHeightDiff;
		}
	}
	return bestIdx;
}
Пример #9
0
//-----------------------------------------------------------------------------
// Purpose: Adds an obstacle with radius and height for entity
//-----------------------------------------------------------------------------
bool CRecastMgr::AddEntRadiusObstacle( CBaseEntity *pEntity, float radius, float height )
{
	if( !pEntity )
		return false;

	NavObstacleArray_t &obstacle = FindOrCreateObstacle( pEntity );

	bool bSuccess = true;
	for ( int i = m_Meshes.First(); i != m_Meshes.InvalidIndex(); i = m_Meshes.Next(i ) )
	{
		CRecastMesh *pMesh = m_Meshes[ i ];
		// TODO: better check. Needs to filter out obstacles for air mesh
		if( pMesh->GetAgentHeight() - 50.0f > height )
			continue;

		obstacle.obs.AddToTail();
		obstacle.obs.Tail().meshIndex = i;
		obstacle.obs.Tail().ref = pMesh->AddTempObstacle( pEntity->GetAbsOrigin(), radius + 1.0f, height );
		if( obstacle.obs.Tail().ref == 0 )
			bSuccess = false;
	}
	return bSuccess;
}
Пример #10
0
//-----------------------------------------------------------------------------
// Purpose: Removes any obstacle associated with the entity
//-----------------------------------------------------------------------------
bool CRecastMgr::RemoveEntObstacles( CBaseEntity *pEntity )
{
	if( !pEntity )
		return false;

	bool bSuccess = true;
	int idx = m_Obstacles.Find( pEntity );
	if( m_Obstacles.IsValidIndex( idx ) )
	{
		for( int i = 0; i < m_Obstacles[idx].obs.Count(); i++ )
		{
			if( m_Meshes.IsValidIndex( m_Obstacles[idx].obs[i].meshIndex ) )
			{
				CRecastMesh *pMesh = m_Meshes[ m_Obstacles[idx].obs[i].meshIndex ];
				if( !pMesh->RemoveObstacle( m_Obstacles[idx].obs[i].ref ) )
					bSuccess = false;
			}
		}

		m_Obstacles.RemoveAt( idx );
		pEntity->SetNavObstacleRef( m_Obstacles.InvalidIndex() );
	}
	return true;
}
Пример #11
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
const char *CRecastMgr::FindBestMeshNameForEntity( CBaseEntity *pEntity )
{
	int idx = FindBestMeshForEntity( pEntity );
	CRecastMesh *pMesh = GetMesh( idx );
	return pMesh ? pMesh->GetName() : NULL;
}
Пример #12
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
const char *CRecastMgr::FindBestMeshNameForRadiusHeight( float radius, float height )
{
	int idx = FindBestMeshForRadiusHeight( radius, height );
	CRecastMesh *pMesh = GetMesh( idx );
	return pMesh ? pMesh->GetName() : NULL;
}
Пример #13
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
bool CRecastMgr::IsMeshLoaded( const char *name )
{
	CRecastMesh *pMesh = GetMesh( name );
	return pMesh != NULL && pMesh->IsLoaded();
}