Пример #1
0
void FNavMeshPath::DescribeSelfToVisLog(FVisualLogEntry* Snapshot) const
{
	if (IsStringPulled())
	{
		// draw path points only for string pulled paths
		Super::DescribeSelfToVisLog(Snapshot);
	}

	// draw corridor
#if WITH_RECAST
	FVisualLogShapeElement CorridorPoly(EVisualLoggerShapeElement::Polygon);
	CorridorPoly.SetColor(FColorList::Cyan);
	CorridorPoly.Category = LogNavigation.GetCategoryName();
	CorridorPoly.Points.Reserve(PathCorridor.Num() * 6);

	const FVector CorridorOffset = NavigationDebugDrawing::PathOffset * 1.25f;
	int32 NumAreaMark = 1;

	ARecastNavMesh* NavMesh = Cast<ARecastNavMesh>(GetNavigationDataUsed());
	NavMesh->BeginBatchQuery();

	TArray<FVector> Verts;
	for (int32 Idx = 0; Idx < PathCorridor.Num(); Idx++)
	{
		Verts.Reset();
		NavMesh->GetPolyVerts(PathCorridor[Idx], Verts);
		CorridorPoly.Points.Reset();
		CorridorPoly.Points.Append(Verts);
		Snapshot->ElementsToDraw.Add(CorridorPoly);

		const uint8 AreaID = NavMesh->GetPolyAreaID(PathCorridor[Idx]);
		const UClass* AreaClass = NavMesh->GetAreaClass(AreaID);
		if (AreaClass && AreaClass != UNavigationSystem::GetDefaultWalkableArea())
		{
			FVector CenterPt = FVector::ZeroVector;
			for (int32 VIdx = 0; VIdx < Verts.Num(); VIdx++)
			{
				CenterPt += Verts[VIdx];
			}
			CenterPt /= Verts.Num();

			FVisualLogShapeElement AreaMarkElem(EVisualLoggerShapeElement::Segment);
			AreaMarkElem.SetColor(FColorList::Orange);
			AreaMarkElem.Category = LogNavigation.GetCategoryName();
			AreaMarkElem.Thicknes = 2;
			AreaMarkElem.Description = AreaClass->GetName();

			AreaMarkElem.Points.Add(CenterPt + CorridorOffset);
			AreaMarkElem.Points.Add(CenterPt + CorridorOffset + FVector(0,0,100.0f + NumAreaMark * 50.0f));
			Snapshot->ElementsToDraw.Add(AreaMarkElem);

			NumAreaMark = (NumAreaMark + 1) % 5;
		}
	}

	NavMesh->FinishBatchQuery();
	//Snapshot->ElementsToDraw.Add(CorridorElem);
#endif
}
void LogPathPartHelper(AActor* LogOwner, FNavMeshPath* NavMeshPath, int32 StartIdx, int32 EndIdx)
{
#if ENABLE_VISUAL_LOG && WITH_RECAST
	ARecastNavMesh* NavMesh = Cast<ARecastNavMesh>(NavMeshPath->GetNavigationDataUsed());
	if (NavMesh == NULL ||
		!NavMeshPath->PathCorridor.IsValidIndex(StartIdx) ||
		!NavMeshPath->PathCorridor.IsValidIndex(EndIdx))
	{
		return;
	}

	NavMesh->BeginBatchQuery();
	
	FVector SegmentStart = NavMeshPath->GetPathPoints()[0].Location;
	FVector SegmentEnd(FVector::ZeroVector);

	if (StartIdx > 0)
	{
		NavMesh->GetPolyCenter(NavMeshPath->PathCorridor[StartIdx], SegmentStart);
	}

	for (int32 Idx = StartIdx + 1; Idx < EndIdx; Idx++)
	{
		NavMesh->GetPolyCenter(NavMeshPath->PathCorridor[Idx], SegmentEnd);
		UE_VLOG_SEGMENT_THICK(LogOwner, LogCrowdFollowing, Log, SegmentStart, SegmentEnd, FColor::Yellow, 2, TEXT_EMPTY);

		SegmentStart = SegmentEnd;
	}

	if (EndIdx == (NavMeshPath->PathCorridor.Num() - 1))
	{
		SegmentEnd = NavMeshPath->GetPathPoints()[1].Location;
	}
	else
	{
		NavMesh->GetPolyCenter(NavMeshPath->PathCorridor[EndIdx], SegmentEnd);
	}

	UE_VLOG_SEGMENT_THICK(LogOwner, LogCrowdFollowing, Log, SegmentStart, SegmentEnd, FColor::Yellow, 2, TEXT_EMPTY);
	NavMesh->FinishBatchQuery();
#endif // ENABLE_VISUAL_LOG && WITH_RECAST
}
Пример #3
0
void UCrowdManager::DrawDebugPath(const dtCrowdAgent* CrowdAgent) const
{
	ARecastNavMesh* NavMesh = Cast<ARecastNavMesh>(MyNavData);
	if (NavMesh == NULL)
	{
		return;
	}

	NavMesh->BeginBatchQuery();
	
	const dtPolyRef* Path = CrowdAgent->corridor.getPath();
	TArray<FVector> Verts;

	for (int32 Idx = 0; Idx < CrowdAgent->corridor.getPathCount(); Idx++)
	{
		Verts.Reset();
		NavMesh->GetPolyVerts(Path[Idx], Verts);

		uint16 PolyFlags = 0;
		uint16 AreaFlags = 0;
		NavMesh->GetPolyFlags(Path[Idx], PolyFlags, AreaFlags);
		const FColor PolyColor = AreaFlags != 1 ? CrowdDebugDrawing::Path : CrowdDebugDrawing::PathSpecial;

		for (int32 VertIdx = 0; VertIdx < Verts.Num(); VertIdx++)
		{
			const FVector Pt0 = Verts[VertIdx];
			const FVector Pt1 = Verts[(VertIdx + 1) % Verts.Num()];

			DrawDebugLine(GetWorld(), Pt0 + CrowdDebugDrawing::Offset * 0.5f, Pt1 + CrowdDebugDrawing::Offset * 0.5f, PolyColor, false
				, /*LifeTime*/-1.f, /*DepthPriority*/0
				, /*Thickness*/CrowdDebugDrawing::LineThickness);
		}
	}

	NavMesh->FinishBatchQuery();
}
void UGameplayDebuggingComponent::ServerCollectNavmeshData_Implementation(FVector_NetQuantize10 TargetLocation)
{
#if WITH_RECAST
    UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(GetWorld());
    ARecastNavMesh* NavData = GetNavData();
    if (NavData == NULL)
    {
        NavmeshRepData.Empty();
        return;
    }

    const double Timer1 = FPlatformTime::Seconds();

    TArray<int32> Indices;
    int32 TileX = 0;
    int32 TileY = 0;
    const int32 DeltaX[] = { 0, 1, 1, 0, -1, -1, -1,  0,  1 };
    const int32 DeltaY[] = { 0, 0, 1, 1,  1,  0, -1, -1, -1 };

    NavData->BeginBatchQuery();

    // add 3x3 neighborhood of target
    int32 TargetTileX = 0;
    int32 TargetTileY = 0;
    NavData->GetNavMeshTileXY(TargetLocation, TargetTileX, TargetTileY);
    for (int32 i = 0; i < ARRAY_COUNT(DeltaX); i++)
    {
        const int32 NeiX = TargetTileX + DeltaX[i];
        const int32 NeiY = TargetTileY + DeltaY[i];
        if (FMath::Abs(NeiX - TileX) > 1 || FMath::Abs(NeiY - TileY) > 1)
        {
            NavData->GetNavMeshTilesAt(NeiX, NeiY, Indices);
        }
    }

    const FNavDataConfig& NavConfig = NavData->GetConfig();
    FColor NavMeshColors[RECAST_MAX_AREAS];
    NavMeshColors[RECAST_DEFAULT_AREA] = NavConfig.Color.DWColor() > 0 ? NavConfig.Color : NavMeshRenderColor_RecastMesh;
    for (uint8 i = 0; i < RECAST_DEFAULT_AREA; ++i)
    {
        NavMeshColors[i] = NavData->GetAreaIDColor(i);
    }

    TArray<uint8> UncompressedBuffer;
    FMemoryWriter ArWriter(UncompressedBuffer);

    int32 NumIndices = Indices.Num();
    ArWriter << NumIndices;

    for (int32 i = 0; i < NumIndices; i++)
    {
        FRecastDebugGeometry NavMeshGeometry;
        NavMeshGeometry.bGatherPolyEdges = false;
        NavMeshGeometry.bGatherNavMeshEdges = false;
        NavData->GetDebugGeometry(NavMeshGeometry, Indices[i]);

        NavMeshDebug::FTileData TileData;
        const FBox TileBoundingBox = NavData->GetNavMeshTileBounds(Indices[i]);
        TileData.Location = TileBoundingBox.GetCenter();
        for (int32 VertIndex = 0; VertIndex < NavMeshGeometry.MeshVerts.Num(); ++VertIndex)
        {
            const NavMeshDebug::FShortVector SV = NavMeshGeometry.MeshVerts[VertIndex] - TileData.Location;
            TileData.Verts.Add(SV);
        }

        for (int32 iArea = 0; iArea < RECAST_MAX_AREAS; iArea++)
        {
            const int32 NumTris = NavMeshGeometry.AreaIndices[iArea].Num();
            if (NumTris)
            {
                NavMeshDebug::FAreaPolys AreaPolys;
                for (int32 AreaIndicesIndex = 0; AreaIndicesIndex < NavMeshGeometry.AreaIndices[iArea].Num(); ++AreaIndicesIndex)
                {
                    AreaPolys.Indices.Add(NavMeshGeometry.AreaIndices[iArea][AreaIndicesIndex]);
                }
                AreaPolys.Color = NavMeshColors[iArea];
                TileData.Areas.Add(AreaPolys);
            }
        }

        TileData.Links.Reserve(NavMeshGeometry.OffMeshLinks.Num());
        for (int32 iLink = 0; iLink < NavMeshGeometry.OffMeshLinks.Num(); iLink++)
        {
            const FRecastDebugGeometry::FOffMeshLink& SrcLink = NavMeshGeometry.OffMeshLinks[iLink];
            NavMeshDebug::FOffMeshLink Link;
            Link.Left = SrcLink.Left - TileData.Location;
            Link.Right = SrcLink.Right - TileData.Location;
            Link.Color = ((SrcLink.Direction && SrcLink.ValidEnds) || (SrcLink.ValidEnds & FRecastDebugGeometry::OMLE_Left)) ? DarkenColor(NavMeshColors[SrcLink.AreaID]) : NavMeshRenderColor_OffMeshConnectionInvalid;
            Link.PackedFlags.Radius = (int8)SrcLink.Radius;
            Link.PackedFlags.Direction = SrcLink.Direction;
            Link.PackedFlags.ValidEnds = SrcLink.ValidEnds;
            TileData.Links.Add(Link);
        }

        ArWriter << TileData;
    }
    NavData->FinishBatchQuery();

    const double Timer2 = FPlatformTime::Seconds();

    const int32 HeaderSize = sizeof(int32);
    NavmeshRepData.Init(0, HeaderSize + FMath::TruncToInt(1.1f * UncompressedBuffer.Num()));

    const int32 UncompressedSize = UncompressedBuffer.Num();
    int32 CompressedSize = NavmeshRepData.Num() - HeaderSize;
    uint8* DestBuffer = NavmeshRepData.GetData();
    FMemory::Memcpy(DestBuffer, &UncompressedSize, HeaderSize);
    DestBuffer += HeaderSize;

    FCompression::CompressMemory((ECompressionFlags)(COMPRESS_ZLIB | COMPRESS_BiasMemory),
                                 (void*)DestBuffer, CompressedSize, (void*)UncompressedBuffer.GetData(), UncompressedSize);

    NavmeshRepData.SetNum(CompressedSize + HeaderSize, false);

    const double Timer3 = FPlatformTime::Seconds();
    UE_LOG(LogGDT, Log, TEXT("Preparing navmesh data: %.1fkB took %.3fms (collect: %.3fms + compress %d%%: %.3fms)"),
           NavmeshRepData.Num() / 1024.0f, 1000.0f * (Timer3 - Timer1),
           1000.0f * (Timer2 - Timer1),
           FMath::TruncToInt(100.0f * NavmeshRepData.Num() / UncompressedBuffer.Num()), 1000.0f * (Timer3 - Timer2));
#endif

    if (World && World->GetNetMode() != NM_DedicatedServer)
    {
        OnRep_UpdateNavmesh();
    }
}