vault backup: 2025-06-27 11:02:45
This commit is contained in:
@@ -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()
|
||||
|
Reference in New Issue
Block a user