vault backup: 2025-06-27 11:02:45

This commit is contained in:
2025-06-27 11:02:45 +08:00
parent 009d92252b
commit b57516268a
2 changed files with 128 additions and 25 deletions

View File

@@ -311,12 +311,16 @@ bool AShaderWorldActor::SetupCollisions()
```
#### CollisionFinalizeWork()
结束碰撞生成任务true为完成false为任务超时未完成。
- TMap<FName,FCollisionMeshElement> CollisionMesh碰撞Name => 碰撞Mesh Map。
- FCollisionMeshElement管理单个碰撞数据的结构体。
```c++
bool AShaderWorldActor::CollisionFinalizeWork()
{
SCOPED_NAMED_EVENT_TEXT("AShaderWorldActor::CollisionFinalizeWork()", FColor::Magenta);
SW_FCT_CYCLE()
if (!CollisionReadToProcess.IsEmpty())
return true;
@@ -324,6 +328,7 @@ bool AShaderWorldActor::CollisionFinalizeWork()
double TimeStart = FPlatformTime::Seconds();
//判断处理队列是否为空
if(CollisionWorkQueue.Num()<=0)
return true;
@@ -331,24 +336,117 @@ bool AShaderWorldActor::CollisionFinalizeWork()
FScopeLock CollisionMeshArrayAccess(&CollisionMeshAccessLock);
for (int i = CollisionWorkQueue.Num() - 1; i >= 0; i--)
{
//判断生成时间是否是否超过预设数值如果超过就直接返回。默认为1 ms。
if ((FPlatformTime::Seconds() - TimeStart) * 1000.0 > GameThreadBudget_ms)
return false;
//将生成的碰撞数据赋予给对应的碰撞Mesh最后移除任务队列中的任务。
FCollisionProcessingWork& Work = CollisionWorkQueue[i];
ensure(CollisionMesh.Find(Work.MeshID));
FCollisionMeshElement& Mesh = CollisionMesh[Work.MeshID];
Mesh.Mesh->UpdateSectionTriMesh(Work.DestB);
CollisionWorkQueue.RemoveAt(i);
}
}
CollisionWorkQueue.Empty();
return true;
}
void UShaderWorldCollisionComponent::UpdateSectionTriMesh(TSharedPtr<FSWShareableVerticePositionBuffer, ESPMode::ThreadSafe>& Positions)
{
//UBodySetup
if (AsyncBodySetupQueue.Num() > 0)
{
#if SWDEBUG
SW_LOG("Collision Update received during alreayd occuring computation %s",*GetName())
#endif
UpdatesReceivedDuringCompute.Add(Positions);
return;
}
UpdatesReceivedDuringCompute.Empty();
bool EnsureSameBuffers = ProcMeshSections.Num() > 0 && ProcMeshSections[0].PositionBuffer.IsValid() && (ProcMeshSections[0].PositionBuffer->Positions3f.Num() == 0 || ProcMeshSections[0].PositionBuffer->Positions3f.Num() == Positions->Positions.Num());
if(!EnsureSameBuffers)
{
#if SWDEBUG
UE_LOG(LogTemp,Warning,TEXT("Error UpdateSectionTriMesh : buffers incompatible"));
#endif
}
else
{
ProcMeshSections[0].PositionBuffer.Reset();
ProcMeshSections[0].Normals.Reset();
ProcMeshSections[0].PositionBuffer = Positions;
ProcMeshSections[0].SectionLocalBox = Positions->Bound;
ProcMeshSections[0].bEnableCollision = true;
Async(EAsyncExecution::TaskGraph, [WeakThis = MakeWeakObjectPtr(this), PBuffer = Positions, IndexB = ProcMeshSections[0].IndexBuffer]
{
TSharedPtr<TArray<FVector>, ESPMode::ThreadSafe> Normals = SWComputeNormalsForPatch(PBuffer, IndexB);
AsyncTask(ENamedThreads::GameThread, [WeakThis,PBuffer, Normals]()
{
if (WeakThis.IsValid())
{
if (UShaderWorldCollisionComponent* Comp = Cast<UShaderWorldCollisionComponent>(WeakThis.Get()))
{
if(IsValid(Comp))
Comp->ReceiveComputedNormals(PBuffer, Normals);
}
}
});
});
}
//Materials
// Pass new positions to trimesh
UpdateCollision();
UpdateLocalBounds(); // Update overall bounds
UpdateNavigation();
if (ProcMeshSections.Num() > 0 && (ProcMeshSections[0].bSectionVisible || (GetWorld() && !GetWorld()->IsGameWorld())))
{
// If we have a valid proxy and it is not pending recreation
if (SceneProxy && !IsRenderStateDirty())
{
//SW_LOG("Update trimesh SceneProxy && !IsRenderStateDirty()")
// Create data to update section
FShaderWColProcMeshSectionUpdateData* SectionData = new FShaderWColProcMeshSectionUpdateData;
SectionData->TargetSection = 0;
SectionData->NewPositionBuffer = ProcMeshSections[0].PositionBuffer;
if(AShaderWorldActor* owner = Cast<AShaderWorldActor>(GetOwner()))
{
{
// Enqueue command to send to render thread
FShaderWProceduralMeshSceneProxy* ProcMeshSceneProxy = (FShaderWProceduralMeshSceneProxy*)(SceneProxy && !IsRenderStateDirty() ? SceneProxy : nullptr);
ENQUEUE_RENDER_COMMAND(FGeoCProcMeshSectionUpdate)
([ProcMeshSceneProxy, SectionData](FRHICommandListImmediate& RHICmdList)
{
if(ProcMeshSceneProxy)
ProcMeshSceneProxy->UpdateSection_RenderThread(SectionData);
});
}
}
else
{
//SW_LOG("Update trimesh !owner")
}
}
else
{
//SW_LOG("Update trimesh !(SceneProxy && !IsRenderStateDirty())")
}
MarkRenderTransformDirty();
}
}
```
### SpawnablesManagement()