vault backup: 2025-06-27 18:34:16
This commit is contained in:
parent
5def299315
commit
3908e2854f
@ -16,9 +16,6 @@ rating: ⭐
|
|||||||
- ShaderWorldActor.h:[[#AShaderWorldActor]]
|
- ShaderWorldActor.h:[[#AShaderWorldActor]]
|
||||||
- SWorld.h:[[#ASWorld]]
|
- SWorld.h:[[#ASWorld]]
|
||||||
|
|
||||||
## FRenderCommandFence
|
|
||||||
|
|
||||||
|
|
||||||
# USWorldSubsystem
|
# USWorldSubsystem
|
||||||
主要管理:
|
主要管理:
|
||||||
- TArray<USWContextBase*> SW_Contexts
|
- TArray<USWContextBase*> SW_Contexts
|
||||||
@ -168,8 +165,10 @@ void AShaderWorldActor::ReadbacksManagement()
|
|||||||
- bool
|
- bool
|
||||||
- RedbuildCollisionContext
|
- RedbuildCollisionContext
|
||||||
- Array
|
- Array
|
||||||
- CollisionWorkQueue:类型为FCollisionProcessingWork。
|
- CollisionReadToProcess:
|
||||||
- CollisionReadToProcess
|
- CollisionWorkQueue:类型为FCollisionProcessingWork,碰撞处理任务队列,将回读的
|
||||||
|
- FCollisionMeshElement
|
||||||
|
- ReadBackCompletion:碰撞数据GPU回读是否完成。
|
||||||
|
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
@ -230,6 +229,7 @@ void AShaderWorldActor::CollisionManagement(float& DeltaT)
|
|||||||
```
|
```
|
||||||
|
|
||||||
#### SetupCollisions()
|
#### SetupCollisions()
|
||||||
|
设置相关变量。
|
||||||
```c++
|
```c++
|
||||||
bool AShaderWorldActor::SetupCollisions()
|
bool AShaderWorldActor::SetupCollisions()
|
||||||
{
|
{
|
||||||
@ -356,7 +356,7 @@ bool AShaderWorldActor::CollisionFinalizeWork()
|
|||||||
|
|
||||||
void UShaderWorldCollisionComponent::UpdateSectionTriMesh(TSharedPtr<FSWShareableVerticePositionBuffer, ESPMode::ThreadSafe>& Positions)
|
void UShaderWorldCollisionComponent::UpdateSectionTriMesh(TSharedPtr<FSWShareableVerticePositionBuffer, ESPMode::ThreadSafe>& Positions)
|
||||||
{
|
{
|
||||||
//UBodySetup
|
//当UBodySetup更新队列还有任务时,执行改函数会将FSWShareableVerticePositionBuffer加入到UpdatesReceivedDuringCompute数组中并且退出。
|
||||||
if (AsyncBodySetupQueue.Num() > 0)
|
if (AsyncBodySetupQueue.Num() > 0)
|
||||||
{
|
{
|
||||||
#if SWDEBUG
|
#if SWDEBUG
|
||||||
@ -370,7 +370,7 @@ void UShaderWorldCollisionComponent::UpdateSectionTriMesh(TSharedPtr<FSWShareabl
|
|||||||
|
|
||||||
UpdatesReceivedDuringCompute.Empty();
|
UpdatesReceivedDuringCompute.Empty();
|
||||||
|
|
||||||
|
//使用FSWShareableVerticePositionBuffer数据来更新当前UShaderWorldCollisionComponent
|
||||||
bool EnsureSameBuffers = ProcMeshSections.Num() > 0 && ProcMeshSections[0].PositionBuffer.IsValid() && (ProcMeshSections[0].PositionBuffer->Positions3f.Num() == 0 || ProcMeshSections[0].PositionBuffer->Positions3f.Num() == Positions->Positions.Num());
|
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(!EnsureSameBuffers)
|
||||||
{
|
{
|
||||||
@ -398,6 +398,7 @@ void UShaderWorldCollisionComponent::UpdateSectionTriMesh(TSharedPtr<FSWShareabl
|
|||||||
{
|
{
|
||||||
if (UShaderWorldCollisionComponent* Comp = Cast<UShaderWorldCollisionComponent>(WeakThis.Get()))
|
if (UShaderWorldCollisionComponent* Comp = Cast<UShaderWorldCollisionComponent>(WeakThis.Get()))
|
||||||
{
|
{
|
||||||
|
//塞入Normal
|
||||||
if(IsValid(Comp))
|
if(IsValid(Comp))
|
||||||
Comp->ReceiveComputedNormals(PBuffer, Normals);
|
Comp->ReceiveComputedNormals(PBuffer, Normals);
|
||||||
}
|
}
|
||||||
@ -408,8 +409,8 @@ void UShaderWorldCollisionComponent::UpdateSectionTriMesh(TSharedPtr<FSWShareabl
|
|||||||
|
|
||||||
//Materials
|
//Materials
|
||||||
// Pass new positions to trimesh
|
// Pass new positions to trimesh
|
||||||
UpdateCollision();
|
UpdateCollision();//1. 异步Cook UBodySetup 2. 删除原本的碰撞 3. UseBodySetup->CreatePhysicsMeshesAsync(),使用UBodySetup异步创建新的碰撞网格。
|
||||||
UpdateLocalBounds(); // Update overall bounds
|
UpdateLocalBounds();//更新UShaderWorldCollisionComponent的LocalBoundingBox
|
||||||
UpdateNavigation();
|
UpdateNavigation();
|
||||||
|
|
||||||
if (ProcMeshSections.Num() > 0 && (ProcMeshSections[0].bSectionVisible || (GetWorld() && !GetWorld()->IsGameWorld())))
|
if (ProcMeshSections.Num() > 0 && (ProcMeshSections[0].bSectionVisible || (GetWorld() && !GetWorld()->IsGameWorld())))
|
||||||
@ -423,6 +424,7 @@ void UShaderWorldCollisionComponent::UpdateSectionTriMesh(TSharedPtr<FSWShareabl
|
|||||||
SectionData->TargetSection = 0;
|
SectionData->TargetSection = 0;
|
||||||
SectionData->NewPositionBuffer = ProcMeshSections[0].PositionBuffer;
|
SectionData->NewPositionBuffer = ProcMeshSections[0].PositionBuffer;
|
||||||
|
|
||||||
|
//更新SceneProxy FShaderWProceduralMeshSceneProxy的NewPositionBuffer,也就是UpdateSection
|
||||||
if(AShaderWorldActor* owner = Cast<AShaderWorldActor>(GetOwner()))
|
if(AShaderWorldActor* owner = Cast<AShaderWorldActor>(GetOwner()))
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
@ -450,6 +452,192 @@ void UShaderWorldCollisionComponent::UpdateSectionTriMesh(TSharedPtr<FSWShareabl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### CollisionPreprocessGPU()
|
||||||
|
GPU生成碰撞 的预处理阶段。
|
||||||
|
```c++
|
||||||
|
bool AShaderWorldActor::CollisionPreprocessGPU()
|
||||||
|
{
|
||||||
|
SCOPED_NAMED_EVENT_TEXT("AShaderWorldActor::CollisionPreprocessGPU()", FColor::Magenta);
|
||||||
|
SW_FCT_CYCLE()
|
||||||
|
|
||||||
|
for (int32 CollID = CollisionReadToProcess.Num() - 1; CollID >= 0; CollID--)
|
||||||
|
{
|
||||||
|
const FName& ElID = CollisionReadToProcess[CollID];
|
||||||
|
|
||||||
|
|
||||||
|
if (!CollisionMesh.Find(ElID))
|
||||||
|
{
|
||||||
|
CollisionWorkQueue.Empty();
|
||||||
|
CollisionReadToProcess.RemoveAt(CollID);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//判断FCollisionMeshElement是否有效,以及是否将碰撞数据回读完成,如果完成,则将数据添加到碰撞处理队列CollisionWorkQueue,并且从碰撞回读队列CollisionReadToProcess
|
||||||
|
FCollisionMeshElement& Mesh = *CollisionMesh.Find(ElID);
|
||||||
|
if ((*Mesh.ReadBackCompletion.Get()))
|
||||||
|
{
|
||||||
|
ensure(Mesh.Mesh);
|
||||||
|
|
||||||
|
if(FGeoCProcMeshSection* Section = Mesh.Mesh->GetProcMeshSection(0))
|
||||||
|
{
|
||||||
|
if(CollisionMesh.Contains(CollisionBufferHolder))
|
||||||
|
{
|
||||||
|
CollisionWorkQueue.Emplace(
|
||||||
|
ElID
|
||||||
|
, Mesh.HeightData
|
||||||
|
, (*CollisionMesh.Find(CollisionBufferHolder)).Mesh->VerticesTemplate
|
||||||
|
, (*CollisionMesh.Find(CollisionBufferHolder)).Mesh->TrianglesTemplate);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SW_LOG("!CollisionMesh.Contains(CollisionBufferHolder)")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SW_LOG("CollisionPreprocessGPU :: Mesh.Mesh->GetProcMeshSection(0) = nullptr")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CollisionReadToProcess.RemoveAt(CollID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CollisionReadToProcess.IsEmpty())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CollisionReadToProcess.Empty();
|
||||||
|
|
||||||
|
if (CollisionWorkQueue.Num() > 0)
|
||||||
|
{
|
||||||
|
(*bProcessingGroundCollision.Get()) = true;
|
||||||
|
|
||||||
|
AShaderWorldActor* SWContext = this;
|
||||||
|
|
||||||
|
Async(EAsyncExecution::TaskGraph, [Completion = bProcessingGroundCollision, RenderAPI = RendererAPI, VerticesPerPatch = CollisionVerticesPerPatch, Work = CollisionWorkQueue]
|
||||||
|
{
|
||||||
|
|
||||||
|
ParallelFor(Work.Num(), [&](int32 WorkIndex)
|
||||||
|
{
|
||||||
|
|
||||||
|
const FCollisionProcessingWork& WorkEl = Work[WorkIndex];
|
||||||
|
|
||||||
|
|
||||||
|
if (!WorkEl.Read.IsValid() || !WorkEl.SourceB.IsValid() || !WorkEl.DestB.IsValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const int NumOfVertex = WorkEl.SourceB->Positions.Num();
|
||||||
|
|
||||||
|
WorkEl.DestB->Positions.SetNum(NumOfVertex);
|
||||||
|
WorkEl.DestB->Positions3f.SetNum(NumOfVertex);
|
||||||
|
WorkEl.DestB->MaterialIndices.SetNum(NumOfVertex);
|
||||||
|
WorkEl.DestB->Bound = FBox(EForceInit::ForceInit);
|
||||||
|
|
||||||
|
FVector LocationfVertice_WS(0);
|
||||||
|
uint16 MaterialIndice = 0;
|
||||||
|
|
||||||
|
uint8* ReadData8 = (uint8*)WorkEl.Read->ReadData.GetData();
|
||||||
|
|
||||||
|
TSet<int32>& TrianglesAffectedByHoles = WorkEl.DestB->TrianglesAffectedByHoles;
|
||||||
|
TrianglesAffectedByHoles.Empty();
|
||||||
|
|
||||||
|
//#TODO ISPC slower ?
|
||||||
|
#if 0 // INTEL_ISPC
|
||||||
|
if (RenderAPI == EGeoRenderingAPI::OpenGL)
|
||||||
|
{
|
||||||
|
ispc::ShaderWorld_HeightFromGPUReadOpenGL(NumOfVertex, VerticesPerPatch, ReadData8,(ispc::FVector*)WorkEl.SourceB->Positions.GetData(), (ispc::FVector*)WorkEl.DestB->Positions.GetData(), (ispc::FVector3f*)WorkEl.DestB->Positions3f.GetData(), WorkEl.DestB->MaterialIndices.GetData());
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ispc::ShaderWorld_HeightFromGPURead(NumOfVertex, VerticesPerPatch, ReadData8, (ispc::FVector3f*)WorkEl.SourceB->Positions3f.GetData(), (ispc::FVector*)WorkEl.DestB->Positions.GetData(), (ispc::FVector3f*)WorkEl.DestB->Positions3f.GetData(), WorkEl.DestB->MaterialIndices.GetData());
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
|
||||||
|
for (int32 k = 0; k < NumOfVertex; k++)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (RenderAPI == EGeoRenderingAPI::OpenGL)
|
||||||
|
{
|
||||||
|
const int index = k % VerticesPerPatch + (VerticesPerPatch - 1 - (k / VerticesPerPatch)) * VerticesPerPatch;
|
||||||
|
|
||||||
|
LocationfVertice_WS = FVector(WorkEl.SourceB->Positions[k].X, WorkEl.SourceB->Positions[k].Y, GetHeightFromGPURead(&ReadData8[4 * index], MaterialIndice));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LocationfVertice_WS = FVector(WorkEl.SourceB->Positions[k].X, WorkEl.SourceB->Positions[k].Y, GetHeightFromGPURead(&ReadData8[4 * k], MaterialIndice));
|
||||||
|
|
||||||
|
WorkEl.DestB->Positions[k] = LocationfVertice_WS;
|
||||||
|
WorkEl.DestB->Positions3f[k] = FVector3f(LocationfVertice_WS);
|
||||||
|
WorkEl.DestB->MaterialIndices[k] = MaterialIndice;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Height below -7km means terrain hole
|
||||||
|
*/
|
||||||
|
if(WorkEl.DestB->Positions[k].Z < -700000.0)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Find triangles including this vertex and add them to removed triangles
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(WorkEl.SourceB->PositionToTriangle.Contains(k))
|
||||||
|
{
|
||||||
|
TrianglesAffectedByHoles.Append(*WorkEl.SourceB->PositionToTriangle.Find(k));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WorkEl.DestB->Bound += WorkEl.DestB->Positions[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* If the terrain has holes, create a custom index buffer with the related triangles removed
|
||||||
|
*/
|
||||||
|
if(TrianglesAffectedByHoles.Num() > 0)
|
||||||
|
{
|
||||||
|
WorkEl.DestB->FilteredTriangles = MakeShared<FSWShareableIndexBuffer, ESPMode::ThreadSafe>();
|
||||||
|
|
||||||
|
for(int32 Triangle = 0; Triangle < WorkEl.TriangleTemplate->Indices.Num()/3; Triangle++)
|
||||||
|
{
|
||||||
|
if(!TrianglesAffectedByHoles.Contains(Triangle))
|
||||||
|
{
|
||||||
|
WorkEl.DestB->FilteredTriangles->Indices.Add(WorkEl.TriangleTemplate->Indices[Triangle * 3]);
|
||||||
|
WorkEl.DestB->FilteredTriangles->Indices.Add(WorkEl.TriangleTemplate->Indices[Triangle * 3 + 1]);
|
||||||
|
WorkEl.DestB->FilteredTriangles->Indices.Add(WorkEl.TriangleTemplate->Indices[Triangle * 3 + 2]);
|
||||||
|
|
||||||
|
WorkEl.DestB->FilteredTriangles->Triangles_CollisionOnly.Add(WorkEl.TriangleTemplate->Triangles_CollisionOnly[Triangle]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WorkEl.DestB->FilteredTriangles.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//WorkEl.DestB->Bound = FBox(WorkEl.DestB->Positions);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (Completion.IsValid())
|
||||||
|
Completion->AtomicSet(false);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### SpawnablesManagement()
|
### SpawnablesManagement()
|
||||||
|
|
||||||
### TerrainAndSpawnablesManagement()
|
### TerrainAndSpawnablesManagement()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user