diff --git a/Source/glTFRuntime/Private/glTFRuntimeAsset.cpp b/Source/glTFRuntime/Private/glTFRuntimeAsset.cpp index d5561d2e..8e9c9ff8 100644 --- a/Source/glTFRuntime/Private/glTFRuntimeAsset.cpp +++ b/Source/glTFRuntime/Private/glTFRuntimeAsset.cpp @@ -835,11 +835,11 @@ bool UglTFRuntimeAsset::LoadEmitterIntoAudioComponent(const FglTFRuntimeAudioEmi return Parser->LoadEmitterIntoAudioComponent(Emitter, AudioComponent); } -void UglTFRuntimeAsset::LoadStaticMeshAsync(const int32 MeshIndex, const FglTFRuntimeStaticMeshAsync& AsyncCallback, const FglTFRuntimeStaticMeshConfig& StaticMeshConfig) +void UglTFRuntimeAsset::LoadStaticMeshAsync(const int32 MeshIndex, const FglTFRuntimeStaticMeshAsyncCustom& AsyncCallback, const FglTFRuntimeStaticMeshConfig& StaticMeshConfig, UStaticMeshComponent* StaticMeshComponent) { GLTF_CHECK_PARSER_VOID(); - Parser->LoadStaticMeshAsync(MeshIndex, AsyncCallback, StaticMeshConfig); + Parser->LoadStaticMeshAsync(MeshIndex, AsyncCallback, StaticMeshConfig, StaticMeshComponent); } void UglTFRuntimeAsset::LoadMeshAsRuntimeLODAsync(const int32 MeshIndex, const FglTFRuntimeMeshLODAsync& AsyncCallback, const FglTFRuntimeMaterialsConfig& MaterialsConfig) diff --git a/Source/glTFRuntime/Private/glTFRuntimeAssetActorAsync.cpp b/Source/glTFRuntime/Private/glTFRuntimeAssetActorAsync.cpp index 008a8af5..a8bb39e8 100644 --- a/Source/glTFRuntime/Private/glTFRuntimeAssetActorAsync.cpp +++ b/Source/glTFRuntime/Private/glTFRuntimeAssetActorAsync.cpp @@ -17,6 +17,9 @@ AglTFRuntimeAssetActorAsync::AglTFRuntimeAssetActorAsync() bShowWhileLoading = true; bStaticMeshesAsSkeletal = false; + bSkeletalMeshesAsStatic = false; + LoadedMeshNum = 0; + TotalVerticesNum = 0; } // Called when the game starts or when spawned @@ -49,6 +52,7 @@ void AglTFRuntimeAssetActorAsync::BeginPlay() } } + TotalMeshNum = MeshesToLoad.Num(); LoadNextMeshAsync(); } @@ -80,7 +84,7 @@ void AglTFRuntimeAssetActorAsync::ProcessNode(USceneComponent* NodeParentCompone } else { - if (Node.SkinIndex < 0 && !bStaticMeshesAsSkeletal) + if (Node.SkinIndex < 0 && !bStaticMeshesAsSkeletal || bSkeletalMeshesAsStatic) { UStaticMeshComponent* StaticMeshComponent = NewObject(this, GetSafeNodeName(Node)); StaticMeshComponent->SetupAttachment(NodeParentComponent); @@ -135,61 +139,67 @@ void AglTFRuntimeAssetActorAsync::LoadNextMeshAsync() return; } - auto It = MeshesToLoad.CreateIterator(); - if (UStaticMeshComponent* StaticMeshComponent = Cast(It->Key)) + auto begin = MeshesToLoad.begin(); + auto end = MeshesToLoad.end(); + + for (auto It = begin; It != end; ++It) { - CurrentPrimitiveComponent = StaticMeshComponent; - if (StaticMeshConfig.Outer == nullptr) + if (UStaticMeshComponent* StaticMeshComponent = Cast(It->Key)) + { + CurrentPrimitiveComponent = StaticMeshComponent; + + if (StaticMeshConfig.Outer == nullptr) + { + StaticMeshConfig.Outer = StaticMeshComponent; + } + FglTFRuntimeStaticMeshAsyncCustom Delegate; + Delegate.BindDynamic(this, &AglTFRuntimeAssetActorAsync::LoadStaticMeshAsync); + Asset->LoadStaticMeshAsync(It->Value.MeshIndex, Delegate, StaticMeshConfig, StaticMeshComponent); + } + else if (USkeletalMeshComponent* SkeletalMeshComponent = Cast(It->Key)) { - StaticMeshConfig.Outer = StaticMeshComponent; + CurrentPrimitiveComponent = SkeletalMeshComponent; + FglTFRuntimeSkeletalMeshAsync Delegate; + Delegate.BindDynamic(this, &AglTFRuntimeAssetActorAsync::LoadSkeletalMeshAsync); + Asset->LoadSkeletalMeshAsync(It->Value.MeshIndex, It->Value.SkinIndex, Delegate, SkeletalMeshConfig); } - FglTFRuntimeStaticMeshAsync Delegate; - Delegate.BindDynamic(this, &AglTFRuntimeAssetActorAsync::LoadStaticMeshAsync); - Asset->LoadStaticMeshAsync(It->Value.MeshIndex, Delegate, StaticMeshConfig); - } - else if (USkeletalMeshComponent* SkeletalMeshComponent = Cast(It->Key)) - { - CurrentPrimitiveComponent = SkeletalMeshComponent; - FglTFRuntimeSkeletalMeshAsync Delegate; - Delegate.BindDynamic(this, &AglTFRuntimeAssetActorAsync::LoadSkeletalMeshAsync); - Asset->LoadSkeletalMeshAsync(It->Value.MeshIndex, It->Value.SkinIndex, Delegate, SkeletalMeshConfig); } } -void AglTFRuntimeAssetActorAsync::LoadStaticMeshAsync(UStaticMesh* StaticMesh) +void AglTFRuntimeAssetActorAsync::LoadStaticMeshAsync(UStaticMesh* StaticMesh, UStaticMeshComponent* StaticMeshComponent) { - if (UStaticMeshComponent* StaticMeshComponent = Cast(CurrentPrimitiveComponent)) + Mutex.Lock(); + StaticMeshComponent->SetCastShadow(bIsCastShadowEnabled); + TotalVerticesNum += StaticMesh->GetNumVertices(0); + DiscoveredStaticMeshComponents.Add(StaticMeshComponent, StaticMesh); + Mutex.Unlock(); + + if (bShowWhileLoading) { - DiscoveredStaticMeshComponents.Add(StaticMeshComponent, StaticMesh); - if (bShowWhileLoading) - { - StaticMeshComponent->SetStaticMesh(StaticMesh); - } + StaticMeshComponent->SetStaticMesh(StaticMesh); + } - if (StaticMesh && !StaticMeshConfig.ExportOriginalPivotToSocket.IsEmpty()) + if (StaticMesh && !StaticMeshConfig.ExportOriginalPivotToSocket.IsEmpty()) + { + UStaticMeshSocket* DeltaSocket = StaticMesh->FindSocket(FName(StaticMeshConfig.ExportOriginalPivotToSocket)); + if (DeltaSocket) { - UStaticMeshSocket* DeltaSocket = StaticMesh->FindSocket(FName(StaticMeshConfig.ExportOriginalPivotToSocket)); - if (DeltaSocket) - { - FTransform NewTransform = StaticMeshComponent->GetRelativeTransform(); - FVector DeltaLocation = -DeltaSocket->RelativeLocation * NewTransform.GetScale3D(); - DeltaLocation = NewTransform.GetRotation().RotateVector(DeltaLocation); - NewTransform.AddToTranslation(DeltaLocation); - StaticMeshComponent->SetRelativeTransform(NewTransform); - } + FTransform NewTransform = StaticMeshComponent->GetRelativeTransform(); + FVector DeltaLocation = -DeltaSocket->RelativeLocation * NewTransform.GetScale3D(); + DeltaLocation = NewTransform.GetRotation().RotateVector(DeltaLocation); + NewTransform.AddToTranslation(DeltaLocation); + StaticMeshComponent->SetRelativeTransform(NewTransform); } - } - MeshesToLoad.Remove(CurrentPrimitiveComponent); - if (MeshesToLoad.Num() > 0) - { - LoadNextMeshAsync(); - } - // trigger event - else + LoadedMeshNum++; + OnProgress.Broadcast(LoadedMeshNum / TotalMeshNum); + + if (TotalMeshNum - LoadedMeshNum == 0) { + Mutex.Lock(); ScenesLoaded(); + Mutex.Unlock(); } } @@ -262,3 +272,13 @@ void AglTFRuntimeAssetActorAsync::PostUnregisterAllComponents() } Super::PostUnregisterAllComponents(); } + +int AglTFRuntimeAssetActorAsync::GetTotalMeshNum() const +{ + return (int)TotalMeshNum; +} + +int AglTFRuntimeAssetActorAsync::GetTotalVerticesNum() const +{ + return TotalVerticesNum; +} diff --git a/Source/glTFRuntime/Private/glTFRuntimeParserStaticMeshes.cpp b/Source/glTFRuntime/Private/glTFRuntimeParserStaticMeshes.cpp index baec7ee1..9c04dc69 100644 --- a/Source/glTFRuntime/Private/glTFRuntimeParserStaticMeshes.cpp +++ b/Source/glTFRuntime/Private/glTFRuntimeParserStaticMeshes.cpp @@ -47,34 +47,34 @@ FglTFRuntimeStaticMeshContext::FglTFRuntimeStaticMeshContext(TSharedRef StaticMeshContext = MakeShared(AsShared(), StaticMeshConfig); - Async(EAsyncExecution::Thread, [this, StaticMeshContext, MeshIndex, AsyncCallback]() + Async(EAsyncExecution::ThreadPool, [this, StaticMeshContext, MeshIndex, AsyncCallback, StaticMeshComponent, StaticMeshConfig]() { TSharedPtr JsonMeshObject = GetJsonObjectFromRootIndex("meshes", MeshIndex); if (JsonMeshObject) { - FglTFRuntimeMeshLOD* LOD = nullptr; + Mutex.Lock(); if (LoadMeshIntoMeshLOD(JsonMeshObject.ToSharedRef(), LOD, StaticMeshContext->StaticMeshConfig.MaterialsConfig)) { StaticMeshContext->LODs.Add(LOD); - StaticMeshContext->StaticMesh = LoadStaticMesh_Internal(StaticMeshContext); } + Mutex.Unlock(); } - FGraphEventRef Task = FFunctionGraphTask::CreateAndDispatchWhenReady([MeshIndex, StaticMeshContext, AsyncCallback]() + FGraphEventRef Task = FFunctionGraphTask::CreateAndDispatchWhenReady([MeshIndex, StaticMeshContext, AsyncCallback, StaticMeshComponent]() { if (StaticMeshContext->StaticMesh) { @@ -89,9 +89,8 @@ void FglTFRuntimeParser::LoadStaticMeshAsync(const int32 MeshIndex, const FglTFR } } - AsyncCallback.ExecuteIfBound(StaticMeshContext->StaticMesh); + AsyncCallback.ExecuteIfBound(StaticMeshContext->StaticMesh, StaticMeshComponent); }, TStatId(), nullptr, ENamedThreads::GameThread); - FTaskGraphInterface::Get().WaitUntilTaskCompletes(Task); }); } @@ -135,9 +134,18 @@ UStaticMesh* FglTFRuntimeParser::LoadStaticMesh_Internal(TSharedRefPrimitives) { - if (Primitive.UVs.Num() > NumUVs) + if (&Primitive == nullptr) + { + UE_LOG(LogGLTFRuntime, Log, TEXT("Primitive is invalid")); + continue; + } + + if (Primitive.UVs.GetData()) { - NumUVs = Primitive.UVs.Num(); + if (Primitive.UVs.Num() > NumUVs) + { + NumUVs = Primitive.UVs.Num(); + } } if (Primitive.Colors.Num() > 0) @@ -219,75 +227,75 @@ UStaticMesh* FglTFRuntimeParser::LoadStaticMesh_Internal(TSharedRef 4 - StaticMeshVertex.Position = FVector3f(GetSafeValue(Primitive.Positions, VertexIndex, FVector::ZeroVector, bMissingIgnore)); + StaticMeshVertex.Position = FVector3f(GetSafeValue(Primitive.Positions, VertexIndex, FVector::ZeroVector, bMissingIgnore)); #else - StaticMeshVertex.Position = GetSafeValue(Primitive.Positions, VertexIndex, FVector::ZeroVector, bMissingIgnore); + StaticMeshVertex.Position = GetSafeValue(Primitive.Positions, VertexIndex, FVector::ZeroVector, bMissingIgnore); #endif - FVector4 TangentX = GetSafeValue(Primitive.Tangents, VertexIndex, FVector4(0, 0, 0, 1), bMissingTangents); + FVector4 TangentX = GetSafeValue(Primitive.Tangents, VertexIndex, FVector4(0, 0, 0, 1), bMissingTangents); #if ENGINE_MAJOR_VERSION > 4 - StaticMeshVertex.TangentX = FVector4f(TangentX); - StaticMeshVertex.TangentZ = FVector3f(GetSafeValue(Primitive.Normals, VertexIndex, FVector::ZeroVector, bMissingNormals)); - StaticMeshVertex.TangentY = FVector3f(ComputeTangentYWithW(FVector(StaticMeshVertex.TangentZ), FVector(StaticMeshVertex.TangentX), TangentX.W * TangentsDirection)); + StaticMeshVertex.TangentX = FVector4f(TangentX); + StaticMeshVertex.TangentZ = FVector3f(GetSafeValue(Primitive.Normals, VertexIndex, FVector::ZeroVector, bMissingNormals)); + StaticMeshVertex.TangentY = FVector3f(ComputeTangentYWithW(FVector(StaticMeshVertex.TangentZ), FVector(StaticMeshVertex.TangentX), TangentX.W * TangentsDirection)); #else - StaticMeshVertex.TangentX = TangentX; - StaticMeshVertex.TangentZ = GetSafeValue(Primitive.Normals, VertexIndex, FVector::ZeroVector, bMissingNormals); - StaticMeshVertex.TangentY = ComputeTangentYWithW(StaticMeshVertex.TangentZ, StaticMeshVertex.TangentX, TangentX.W * TangentsDirection); + StaticMeshVertex.TangentX = TangentX; + StaticMeshVertex.TangentZ = GetSafeValue(Primitive.Normals, VertexIndex, FVector::ZeroVector, bMissingNormals); + StaticMeshVertex.TangentY = ComputeTangentYWithW(StaticMeshVertex.TangentZ, StaticMeshVertex.TangentX, TangentX.W * TangentsDirection); #endif - for (int32 UVIndex = 0; UVIndex < NumUVs; UVIndex++) + for (int32 UVIndex = 0; UVIndex < NumUVs; UVIndex++) + { + if (UVIndex < Primitive.UVs.Num()) { - if (UVIndex < Primitive.UVs.Num()) - { #if ENGINE_MAJOR_VERSION > 4 - StaticMeshVertex.UVs[UVIndex] = FVector2f(GetSafeValue(Primitive.UVs[UVIndex], VertexIndex, FVector2D::ZeroVector, bMissingIgnore)); + StaticMeshVertex.UVs[UVIndex] = FVector2f(GetSafeValue(Primitive.UVs[UVIndex], VertexIndex, FVector2D::ZeroVector, bMissingIgnore)); #else - StaticMeshVertex.UVs[UVIndex] = GetSafeValue(Primitive.UVs[UVIndex], VertexIndex, FVector2D::ZeroVector, bMissingIgnore); + StaticMeshVertex.UVs[UVIndex] = GetSafeValue(Primitive.UVs[UVIndex], VertexIndex, FVector2D::ZeroVector, bMissingIgnore); #endif - } } + } - if (bHasVertexColors) + if (bHasVertexColors) + { + if (VertexIndex < static_cast(Primitive.Colors.Num())) { - if (VertexIndex < static_cast(Primitive.Colors.Num())) - { - StaticMeshVertex.Color = FLinearColor(Primitive.Colors[VertexIndex]).ToFColor(true); - } - else - { - StaticMeshVertex.Color = FColor::White; - } + StaticMeshVertex.Color = FLinearColor(Primitive.Colors[VertexIndex]).ToFColor(true); } - - if (bApplyAdditionalTransforms) + else { + StaticMeshVertex.Color = FColor::White; + } + } + + if (bApplyAdditionalTransforms) + { #if ENGINE_MAJOR_VERSION > 4 - StaticMeshVertex.Position = FVector3f(LOD->AdditionalTransforms[AdditionalTransformsPrimitiveIndex].TransformPosition(FVector3d(StaticMeshVertex.Position))); - StaticMeshVertex.TangentX = FVector3f(LOD->AdditionalTransforms[AdditionalTransformsPrimitiveIndex].TransformVectorNoScale(FVector3d(StaticMeshVertex.TangentX))); - StaticMeshVertex.TangentY = FVector3f(LOD->AdditionalTransforms[AdditionalTransformsPrimitiveIndex].TransformVectorNoScale(FVector3d(StaticMeshVertex.TangentY))); - StaticMeshVertex.TangentZ = FVector3f(LOD->AdditionalTransforms[AdditionalTransformsPrimitiveIndex].TransformVectorNoScale(FVector3d(StaticMeshVertex.TangentZ))); + StaticMeshVertex.Position = FVector3f(LOD->AdditionalTransforms[AdditionalTransformsPrimitiveIndex].TransformPosition(FVector3d(StaticMeshVertex.Position))); + StaticMeshVertex.TangentX = FVector3f(LOD->AdditionalTransforms[AdditionalTransformsPrimitiveIndex].TransformVectorNoScale(FVector3d(StaticMeshVertex.TangentX))); + StaticMeshVertex.TangentY = FVector3f(LOD->AdditionalTransforms[AdditionalTransformsPrimitiveIndex].TransformVectorNoScale(FVector3d(StaticMeshVertex.TangentY))); + StaticMeshVertex.TangentZ = FVector3f(LOD->AdditionalTransforms[AdditionalTransformsPrimitiveIndex].TransformVectorNoScale(FVector3d(StaticMeshVertex.TangentZ))); #else - StaticMeshVertex.Position = LOD->AdditionalTransforms[AdditionalTransformsPrimitiveIndex].TransformPosition(StaticMeshVertex.Position); - StaticMeshVertex.TangentX = LOD->AdditionalTransforms[AdditionalTransformsPrimitiveIndex].TransformVectorNoScale(StaticMeshVertex.TangentX); - StaticMeshVertex.TangentY = LOD->AdditionalTransforms[AdditionalTransformsPrimitiveIndex].TransformVectorNoScale(StaticMeshVertex.TangentY); - StaticMeshVertex.TangentZ = LOD->AdditionalTransforms[AdditionalTransformsPrimitiveIndex].TransformVectorNoScale(StaticMeshVertex.TangentZ); + StaticMeshVertex.Position = LOD->AdditionalTransforms[AdditionalTransformsPrimitiveIndex].TransformPosition(StaticMeshVertex.Position); + StaticMeshVertex.TangentX = LOD->AdditionalTransforms[AdditionalTransformsPrimitiveIndex].TransformVectorNoScale(StaticMeshVertex.TangentX); + StaticMeshVertex.TangentY = LOD->AdditionalTransforms[AdditionalTransformsPrimitiveIndex].TransformVectorNoScale(StaticMeshVertex.TangentY); + StaticMeshVertex.TangentZ = LOD->AdditionalTransforms[AdditionalTransformsPrimitiveIndex].TransformVectorNoScale(StaticMeshVertex.TangentZ); #endif - } + } #if ENGINE_MAJOR_VERSION > 4 - BoundingBox += FVector(StaticMeshVertex.Position); + BoundingBox += FVector(StaticMeshVertex.Position); #else - BoundingBox += StaticMeshVertex.Position; + BoundingBox += StaticMeshVertex.Position; #endif - }); + }; // this is way more fast than doing it in the ParalellFor with a lock for (const FStaticMeshBuildVertex& StaticMeshVertex : StaticMeshBuildVertices) @@ -318,31 +326,30 @@ UStaticMesh* FglTFRuntimeParser::LoadStaticMesh_Internal(TSharedRef 4 - FVector SideA = FVector(StaticMeshVertex1.Position - StaticMeshVertex0.Position); - FVector SideB = FVector(StaticMeshVertex2.Position - StaticMeshVertex0.Position); - FVector NormalFromCross = FVector::CrossProduct(SideB, SideA).GetSafeNormal(); + FVector SideA = FVector(StaticMeshVertex1.Position - StaticMeshVertex0.Position); + FVector SideB = FVector(StaticMeshVertex2.Position - StaticMeshVertex0.Position); + FVector NormalFromCross = FVector::CrossProduct(SideB, SideA).GetSafeNormal(); - StaticMeshVertex0.TangentZ = FVector3f(NormalFromCross); - StaticMeshVertex1.TangentZ = FVector3f(NormalFromCross); - StaticMeshVertex2.TangentZ = FVector3f(NormalFromCross); + StaticMeshVertex0.TangentZ = FVector3f(NormalFromCross); + StaticMeshVertex1.TangentZ = FVector3f(NormalFromCross); + StaticMeshVertex2.TangentZ = FVector3f(NormalFromCross); #else - FVector SideA = StaticMeshVertex1.Position - StaticMeshVertex0.Position; - FVector SideB = StaticMeshVertex2.Position - StaticMeshVertex0.Position; - FVector NormalFromCross = FVector::CrossProduct(SideB, SideA).GetSafeNormal(); + FVector SideA = StaticMeshVertex1.Position - StaticMeshVertex0.Position; + FVector SideB = StaticMeshVertex2.Position - StaticMeshVertex0.Position; + FVector NormalFromCross = FVector::CrossProduct(SideB, SideA).GetSafeNormal(); - StaticMeshVertex0.TangentZ = NormalFromCross; - StaticMeshVertex1.TangentZ = NormalFromCross; - StaticMeshVertex2.TangentZ = NormalFromCross; + StaticMeshVertex0.TangentZ = NormalFromCross; + StaticMeshVertex1.TangentZ = NormalFromCross; + StaticMeshVertex2.TangentZ = NormalFromCross; #endif - }); + }; bMissingNormals = false; } @@ -351,90 +358,89 @@ UStaticMesh* FglTFRuntimeParser::LoadStaticMesh_Internal(TSharedRef 0 && (NumVertexInstancesPerSection % 3) == 0) { - ParallelFor(NumVertexInstancesPerSection / 3, [&](const int32 VertexInstanceSectionTriangleIndex) - { - const int32 VertexInstanceSectionIndex = VertexInstanceSectionTriangleIndex * 3; - FStaticMeshBuildVertex& StaticMeshVertex0 = StaticMeshBuildVertices[VertexInstanceBaseIndex + VertexInstanceSectionIndex]; - FStaticMeshBuildVertex& StaticMeshVertex1 = StaticMeshBuildVertices[VertexInstanceBaseIndex + VertexInstanceSectionIndex + 1]; - FStaticMeshBuildVertex& StaticMeshVertex2 = StaticMeshBuildVertices[VertexInstanceBaseIndex + VertexInstanceSectionIndex + 2]; + for (int32 VertexInstanceSectionIndex = 0; VertexInstanceSectionIndex < NumVertexInstancesPerSection; VertexInstanceSectionIndex += 3) + { + FStaticMeshBuildVertex& StaticMeshVertex0 = StaticMeshBuildVertices[VertexInstanceBaseIndex + VertexInstanceSectionIndex]; + FStaticMeshBuildVertex& StaticMeshVertex1 = StaticMeshBuildVertices[VertexInstanceBaseIndex + VertexInstanceSectionIndex + 1]; + FStaticMeshBuildVertex& StaticMeshVertex2 = StaticMeshBuildVertices[VertexInstanceBaseIndex + VertexInstanceSectionIndex + 2]; #if ENGINE_MAJOR_VERSION > 4 - FVector Position0 = FVector(StaticMeshVertex0.Position); - FVector4 TangentZ0 = FVector(StaticMeshVertex0.TangentZ); - FVector2D UV0 = FVector2D(StaticMeshVertex0.UVs[0]); + FVector Position0 = FVector(StaticMeshVertex0.Position); + FVector4 TangentZ0 = FVector(StaticMeshVertex0.TangentZ); + FVector2D UV0 = FVector2D(StaticMeshVertex0.UVs[0]); #else - FVector Position0 = StaticMeshVertex0.Position; - FVector4 TangentZ0 = StaticMeshVertex0.TangentZ; - FVector2D UV0 = StaticMeshVertex0.UVs[0]; + FVector Position0 = StaticMeshVertex0.Position; + FVector4 TangentZ0 = StaticMeshVertex0.TangentZ; + FVector2D UV0 = StaticMeshVertex0.UVs[0]; #endif #if ENGINE_MAJOR_VERSION > 4 - FVector Position1 = FVector(StaticMeshVertex1.Position); - FVector4 TangentZ1 = FVector(StaticMeshVertex1.TangentZ); - FVector2D UV1 = FVector2D(StaticMeshVertex1.UVs[0]); + FVector Position1 = FVector(StaticMeshVertex1.Position); + FVector4 TangentZ1 = FVector(StaticMeshVertex1.TangentZ); + FVector2D UV1 = FVector2D(StaticMeshVertex1.UVs[0]); #else - FVector Position1 = StaticMeshVertex1.Position; - FVector4 TangentZ1 = StaticMeshVertex1.TangentZ; - FVector2D UV1 = StaticMeshVertex1.UVs[0]; + FVector Position1 = StaticMeshVertex1.Position; + FVector4 TangentZ1 = StaticMeshVertex1.TangentZ; + FVector2D UV1 = StaticMeshVertex1.UVs[0]; #endif #if ENGINE_MAJOR_VERSION > 4 - FVector Position2 = FVector(StaticMeshVertex2.Position); - FVector4 TangentZ2 = FVector(StaticMeshVertex2.TangentZ); - FVector2D UV2 = FVector2D(StaticMeshVertex2.UVs[0]); + FVector Position2 = FVector(StaticMeshVertex2.Position); + FVector4 TangentZ2 = FVector(StaticMeshVertex2.TangentZ); + FVector2D UV2 = FVector2D(StaticMeshVertex2.UVs[0]); #else - FVector Position2 = StaticMeshVertex2.Position; - FVector4 TangentZ2 = StaticMeshVertex2.TangentZ; - FVector2D UV2 = StaticMeshVertex2.UVs[0]; + FVector Position2 = StaticMeshVertex2.Position; + FVector4 TangentZ2 = StaticMeshVertex2.TangentZ; + FVector2D UV2 = StaticMeshVertex2.UVs[0]; #endif - FVector DeltaPosition0 = Position1 - Position0; - FVector DeltaPosition1 = Position2 - Position0; + FVector DeltaPosition0 = Position1 - Position0; + FVector DeltaPosition1 = Position2 - Position0; - FVector2D DeltaUV0 = UV1 - UV0; - FVector2D DeltaUV1 = UV2 - UV0; + FVector2D DeltaUV0 = UV1 - UV0; + FVector2D DeltaUV1 = UV2 - UV0; - float Factor = 1.0f / (DeltaUV0.X * DeltaUV1.Y - DeltaUV0.Y * DeltaUV1.X); + float Factor = 1.0f / (DeltaUV0.X * DeltaUV1.Y - DeltaUV0.Y * DeltaUV1.X); - FVector TriangleTangentX = ((DeltaPosition0 * DeltaUV1.Y) - (DeltaPosition1 * DeltaUV0.Y)) * Factor; - FVector TriangleTangentY = ((DeltaPosition0 * DeltaUV1.X) - (DeltaPosition1 * DeltaUV0.X)) * Factor; + FVector TriangleTangentX = ((DeltaPosition0 * DeltaUV1.Y) - (DeltaPosition1 * DeltaUV0.Y)) * Factor; + FVector TriangleTangentY = ((DeltaPosition0 * DeltaUV1.X) - (DeltaPosition1 * DeltaUV0.X)) * Factor; - FVector TangentX0 = TriangleTangentX - (TangentZ0 * FVector::DotProduct(TangentZ0, TriangleTangentX)); - TangentX0.Normalize(); + FVector TangentX0 = TriangleTangentX - (TangentZ0 * FVector::DotProduct(TangentZ0, TriangleTangentX)); + TangentX0.Normalize(); - FVector TangentX1 = TriangleTangentX - (TangentZ1 * FVector::DotProduct(TangentZ1, TriangleTangentX)); - TangentX1.Normalize(); + FVector TangentX1 = TriangleTangentX - (TangentZ1 * FVector::DotProduct(TangentZ1, TriangleTangentX)); + TangentX1.Normalize(); - FVector TangentX2 = TriangleTangentX - (TangentZ2 * FVector::DotProduct(TangentZ2, TriangleTangentX)); - TangentX2.Normalize(); + FVector TangentX2 = TriangleTangentX - (TangentZ2 * FVector::DotProduct(TangentZ2, TriangleTangentX)); + TangentX2.Normalize(); #if ENGINE_MAJOR_VERSION > 4 - StaticMeshVertex0.TangentX = FVector3f(TangentX0); - StaticMeshVertex0.TangentY = FVector3f(ComputeTangentY(FVector(StaticMeshVertex0.TangentZ), FVector(StaticMeshVertex0.TangentX)) * TangentsDirection); + StaticMeshVertex0.TangentX = FVector3f(TangentX0); + StaticMeshVertex0.TangentY = FVector3f(ComputeTangentY(FVector(StaticMeshVertex0.TangentZ), FVector(StaticMeshVertex0.TangentX)) * TangentsDirection); - StaticMeshVertex1.TangentX = FVector3f(TangentX1); - StaticMeshVertex1.TangentY = FVector3f(ComputeTangentY(FVector(StaticMeshVertex1.TangentZ), FVector(StaticMeshVertex1.TangentX)) * TangentsDirection); + StaticMeshVertex1.TangentX = FVector3f(TangentX1); + StaticMeshVertex1.TangentY = FVector3f(ComputeTangentY(FVector(StaticMeshVertex1.TangentZ), FVector(StaticMeshVertex1.TangentX)) * TangentsDirection); - StaticMeshVertex2.TangentX = FVector3f(TangentX2); - StaticMeshVertex2.TangentY = FVector3f(ComputeTangentY(FVector(StaticMeshVertex2.TangentZ), FVector(StaticMeshVertex2.TangentX)) * TangentsDirection); + StaticMeshVertex2.TangentX = FVector3f(TangentX2); + StaticMeshVertex2.TangentY = FVector3f(ComputeTangentY(FVector(StaticMeshVertex2.TangentZ), FVector(StaticMeshVertex2.TangentX)) * TangentsDirection); #else - StaticMeshVertex0.TangentX = TangentX0; - StaticMeshVertex0.TangentY = ComputeTangentY(StaticMeshVertex0.TangentZ, StaticMeshVertex0.TangentX) * TangentsDirection; + StaticMeshVertex0.TangentX = TangentX0; + StaticMeshVertex0.TangentY = ComputeTangentY(StaticMeshVertex0.TangentZ, StaticMeshVertex0.TangentX) * TangentsDirection; - StaticMeshVertex1.TangentX = TangentX1; - StaticMeshVertex1.TangentY = ComputeTangentY(StaticMeshVertex1.TangentZ, StaticMeshVertex1.TangentX) * TangentsDirection; + StaticMeshVertex1.TangentX = TangentX1; + StaticMeshVertex1.TangentY = ComputeTangentY(StaticMeshVertex1.TangentZ, StaticMeshVertex1.TangentX) * TangentsDirection; - StaticMeshVertex2.TangentX = TangentX2; - StaticMeshVertex2.TangentY = ComputeTangentY(StaticMeshVertex2.TangentZ, StaticMeshVertex2.TangentX) * TangentsDirection; + StaticMeshVertex2.TangentX = TangentX2; + StaticMeshVertex2.TangentY = ComputeTangentY(StaticMeshVertex2.TangentZ, StaticMeshVertex2.TangentX) * TangentsDirection; #endif - }); + }; } VertexInstanceBaseIndex += NumVertexInstancesPerSection; diff --git a/Source/glTFRuntime/Public/glTFRuntimeAsset.h b/Source/glTFRuntime/Public/glTFRuntimeAsset.h index 3c0a8db9..48667414 100644 --- a/Source/glTFRuntime/Public/glTFRuntimeAsset.h +++ b/Source/glTFRuntime/Public/glTFRuntimeAsset.h @@ -220,7 +220,7 @@ class GLTFRUNTIME_API UglTFRuntimeAsset : public UObject bool LoadEmitterIntoAudioComponent(const FglTFRuntimeAudioEmitter& Emitter, UAudioComponent* AudioComponent); UFUNCTION(BlueprintCallable, meta = (AdvancedDisplay = "StaticMeshConfig", AutoCreateRefTerm = "StaticMeshConfig"), Category = "glTFRuntime") - void LoadStaticMeshAsync(const int32 MeshIndex, const FglTFRuntimeStaticMeshAsync& AsyncCallback, const FglTFRuntimeStaticMeshConfig& StaticMeshConfig); + void LoadStaticMeshAsync(const int32 MeshIndex, const FglTFRuntimeStaticMeshAsyncCustom& AsyncCallback, const FglTFRuntimeStaticMeshConfig& StaticMeshConfig, UStaticMeshComponent* StaticMeshComponent); UFUNCTION(BlueprintCallable, meta = (AdvancedDisplay = "StaticMeshConfig", AutoCreateRefTerm = "StaticMeshConfig"), Category = "glTFRuntime") void LoadStaticMeshLODsAsync(const TArray& MeshIndices, const FglTFRuntimeStaticMeshAsync& AsyncCallback, const FglTFRuntimeStaticMeshConfig& StaticMeshConfig); diff --git a/Source/glTFRuntime/Public/glTFRuntimeAssetActorAsync.h b/Source/glTFRuntime/Public/glTFRuntimeAssetActorAsync.h index bfa01f7e..a051a048 100644 --- a/Source/glTFRuntime/Public/glTFRuntimeAssetActorAsync.h +++ b/Source/glTFRuntime/Public/glTFRuntimeAssetActorAsync.h @@ -7,6 +7,7 @@ #include "glTFRuntimeAsset.h" #include "glTFRuntimeAssetActorAsync.generated.h" +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FglTFRuntimeProgressDispatcher, float, progress); UCLASS() class GLTFRUNTIME_API AglTFRuntimeAssetActorAsync : public AActor { @@ -54,8 +55,29 @@ class GLTFRUNTIME_API AglTFRuntimeAssetActorAsync : public AActor UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (ExposeOnSpawn = true), Category = "glTFRuntime") bool bStaticMeshesAsSkeletal; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (ExposeOnSpawn = true), Category = "glTFRuntime") + bool bSkeletalMeshesAsStatic; + virtual void PostUnregisterAllComponents() override; + UPROPERTY(BlueprintAssignable, Category = "glTFRuntime") + FglTFRuntimeProgressDispatcher OnProgress; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (ExposeOnSpawn = true), Category = "glTFRuntime") + bool bIsCastShadowEnabled; + + UFUNCTION(BlueprintCallable, Category = "glTFRuntime") + int GetTotalMeshNum() const; + + UFUNCTION(BlueprintCallable, Category = "glTFRuntime") + int GetTotalVerticesNum() const; + + int TotalVerticesNum; + + float TotalMeshNum; + + int LoadedMeshNum; + private: UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"), Category="glTFRuntime") USceneComponent* AssetRoot; @@ -65,7 +87,7 @@ class GLTFRUNTIME_API AglTFRuntimeAssetActorAsync : public AActor void LoadNextMeshAsync(); UFUNCTION() - void LoadStaticMeshAsync(UStaticMesh* StaticMesh); + void LoadStaticMeshAsync(UStaticMesh* StaticMesh, UStaticMeshComponent* StaticMeshComponent); UFUNCTION() void LoadSkeletalMeshAsync(USkeletalMesh* SkeletalMesh); @@ -75,4 +97,6 @@ class GLTFRUNTIME_API AglTFRuntimeAssetActorAsync : public AActor double LoadingStartTime; + FCriticalSection Mutex; + }; diff --git a/Source/glTFRuntime/Public/glTFRuntimeParser.h b/Source/glTFRuntime/Public/glTFRuntimeParser.h index 38fb190d..3e985080 100644 --- a/Source/glTFRuntime/Public/glTFRuntimeParser.h +++ b/Source/glTFRuntime/Public/glTFRuntimeParser.h @@ -2030,6 +2030,7 @@ struct FglTFRuntimePluginCacheData }; DECLARE_DYNAMIC_DELEGATE_OneParam(FglTFRuntimeStaticMeshAsync, UStaticMesh*, StaticMesh); +DECLARE_DYNAMIC_DELEGATE_TwoParams(FglTFRuntimeStaticMeshAsyncCustom, UStaticMesh*, StaticMesh, UStaticMeshComponent*, StaticMeshComponent); DECLARE_DYNAMIC_DELEGATE_OneParam(FglTFRuntimeSkeletalMeshAsync, USkeletalMesh*, SkeletalMesh); DECLARE_DYNAMIC_DELEGATE_TwoParams(FglTFRuntimeMeshLODAsync, const bool, bValid, const FglTFRuntimeMeshLOD&, MeshLOD); DECLARE_DYNAMIC_DELEGATE_OneParam(FglTFRuntimeTextureCubeAsync, UTextureCube*, TextureCube); @@ -2112,7 +2113,7 @@ class GLTFRUNTIME_API FglTFRuntimeParser : public FGCObject, public TSharedFromT UAnimSequence* LoadSkeletalAnimationFromTracksAndMorphTargets(USkeletalMesh* SkeletalMesh, TMap& Tracks, TMap>>& MorphTargetCurves, const float Duration, const FglTFRuntimeSkeletalAnimationConfig& SkeletalAnimationConfig); void LoadSkeletalMeshAsync(const int32 MeshIndex, const int32 SkinIndex, const FglTFRuntimeSkeletalMeshAsync& AsyncCallback, const FglTFRuntimeSkeletalMeshConfig& SkeletalMeshConfig); - void LoadStaticMeshAsync(const int32 MeshIndex, const FglTFRuntimeStaticMeshAsync& AsyncCallback, const FglTFRuntimeStaticMeshConfig& StaticMeshConfig); + void LoadStaticMeshAsync(const int32 MeshIndex, const FglTFRuntimeStaticMeshAsyncCustom& AsyncCallback, const FglTFRuntimeStaticMeshConfig& StaticMeshConfig, UStaticMeshComponent* StaticMeshComponent); void LoadStaticMeshLODsAsync(const TArray& MeshIndices, const FglTFRuntimeStaticMeshAsync& AsyncCallback, const FglTFRuntimeStaticMeshConfig& StaticMeshConfig); @@ -2767,4 +2768,7 @@ class GLTFRUNTIME_API FglTFRuntimeParser : public FGCObject, public TSharedFromT void SetDownloadTime(const float Value); float GetDownloadTime() const; +private: + FCriticalSection Mutex; + };