Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion GFur.uplugin
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"DocsURL": "gim.studio/animalia/gfur",
"MarketplaceURL": "com.epicgames.launcher://ue/marketplace/content/c657e6d3d6c9467db3e96c828529841b",
"SupportURL": "gfur@gim.studio",
"EngineVersion": "5.5.0",
"EngineVersion": "5.6.0",
"CanContainContent": true,
"Installed": true,
"Modules": [
Expand Down
9 changes: 8 additions & 1 deletion Source/GFur/GFur.Build.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
// Copyright 2023 GiM s.r.o. All Rights Reserved.

using System.IO;
using UnrealBuildTool;

public class GFur : ModuleRules
{
public GFur(ReadOnlyTargetRules Target) : base(Target)
string EnginePath
{
get { return Path.GetFullPath(Target.RelativeEnginePath); }
}
public GFur(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
MinFilesUsingPrecompiledHeaderOverride = 1;
Expand All @@ -14,6 +19,8 @@ public GFur(ReadOnlyTargetRules Target) : base(Target)

PrivateIncludePaths.Add(ModuleDirectory + "/Private");
PrivateIncludePaths.Add(EngineDirectory + "/Shaders/Shared");
PrivateIncludePaths.Add(EnginePath + "Source/Runtime/Engine/Private");
PrivateIncludePaths.Add(EnginePath + "Source/Runtime/Engine/Internal");

PublicDependencyModuleNames.AddRange(
new string[]
Expand Down
30 changes: 14 additions & 16 deletions Source/GFur/Private/FurComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@
#include "FurData.h"
#include "FurMorphObject.h"
#include "Engine/Engine.h"
#include "Runtime/Engine/Classes/PhysicsEngine/BodySetup.h"
#include "Runtime/Engine/Public/DynamicMeshBuilder.h"
#include "Runtime/Engine/Public/GPUSkinVertexFactory.h"
#include "Runtime/Engine/Public/Rendering/SkeletalMeshRenderData.h"
#include "Runtime/Engine/Public/Materials/MaterialRenderProxy.h"
#include "Runtime\Engine\Public\MaterialDomain.h"
#include "PhysicsEngine/BodySetup.h"
#include "DynamicMeshBuilder.h"
#include "GPUSkinVertexFactory.h"
#include "Rendering/SkeletalMeshRenderData.h"
#include "Materials/MaterialRenderProxy.h"
#include "MaterialDomain.h"
#include "MaterialShared.h"
#include "Engine/SkeletalMesh.h"
#include "SceneInterface.h"
#include "Runtime\Engine\Classes\Engine\SkinnedAssetCommon.h"
#include "Runtime/Engine/Classes/Components/SkinnedMeshComponent.h"
#include "Runtime/Engine/Classes/Components/SkeletalMeshComponent.h"
#include "Engine/SkinnedAssetCommon.h"
#include "Components/SkinnedMeshComponent.h"
#include "Components/SkeletalMeshComponent.h"

#include "PrimitiveSceneProxy.h"

Expand Down Expand Up @@ -137,7 +137,7 @@ class FFurSceneProxy : public FPrimitiveSceneProxy
#else
const int32 LODBias = 0;
#endif
NewLodLevel = MasterComp->MeshObject->MinDesiredLODLevel + LODBias;
NewLodLevel = FMath::Max(MasterComp->MeshObject->MinDesiredLODLevel + LODBias, 0);
}
}
else
Expand Down Expand Up @@ -745,7 +745,6 @@ void UGFurComponent::CreateRenderState_Concurrent(FRegisterComponentContext* Con
tmp_material = UMaterial::GetDefaultMaterial(MD_Surface);
}
UMaterialInstanceDynamic* Material = UMaterialInstanceDynamic::Create(tmp_material, this);
Material->AddToRoot();
Material->SetScalarParameterValue(FName(TEXT("FurLength")), FMath::Max(FurLength, 0.001f));
FurMaterials.Add(Material);
}
Expand Down Expand Up @@ -800,21 +799,20 @@ FBoxSphereBounds UGFurComponent::CalcBounds(const FTransform& LocalToWorld) cons
if (MasterPoseComponent.IsValid())
{
FBoxSphereBounds MasterBounds = MasterPoseComponent->CalcBounds(LocalToWorld);
MasterBounds.ExpandBy(FMath::Max(FurLength, 0.001f));
return MasterBounds;
return MasterBounds.ExpandBy(FMath::Max(FurLength, 0.001f));
}
FBoxSphereBounds DummyBounds = SkeletalGrowMesh->GetBounds();
DummyBounds.ExpandBy(FMath::Max(FurLength, 0.001f));
DummyBounds = DummyBounds.ExpandBy(FMath::Max(FurLength, 0.001f));
return DummyBounds.TransformBy(LocalToWorld);
}
else if (StaticGrowMesh)
{
FBoxSphereBounds MeshBounds = StaticGrowMesh->GetBounds();
MeshBounds.ExpandBy(FMath::Max(FurLength, 0.001f));
MeshBounds = MeshBounds.ExpandBy(FMath::Max(FurLength, 0.001f));
return MeshBounds.TransformBy(LocalToWorld);
}
FBoxSphereBounds DummyBounds = FBoxSphereBounds(FVector(0, 0, 0), FVector(0, 0, 0), 0);
DummyBounds.ExpandBy(FMath::Max(FurLength, 0.001f));
DummyBounds = DummyBounds.ExpandBy(FMath::Max(FurLength, 0.001f));
return DummyBounds.TransformBy(LocalToWorld);
}

Expand Down
26 changes: 24 additions & 2 deletions Source/GFur/Private/FurData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,18 @@ FFurVertexBuffer::~FFurVertexBuffer()

void FFurVertexBuffer::InitRHI(FRHICommandListBase& RHICmdList)
{
#if (ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 6)
FRHIBufferCreateDesc CreateDesc = FRHIBufferCreateDesc::CreateVertex(TEXT("FurVertexBuffer"), Size).AddUsage(BUF_Static).DetermineInitialState();


VertexBufferRHI = RHICmdList.CreateBuffer(CreateDesc);
#else
FRHIResourceCreateInfo CreateInfo(L"FurVertexBuffer");


//VertexBufferRHI = RHICreateVertexBuffer(Size, BUF_Static, CreateInfo); DEPRECATED
VertexBufferRHI = RHICmdList.CreateVertexBuffer(Size, BUF_Static, CreateInfo);

#endif
// Copy the vertex data into the vertex buffer.
//void* VertexBufferData = RHILockBuffer(VertexBufferRHI, 0, Size, RLM_WriteOnly); DEPRECATED
void* VertexBufferData = RHICmdList.LockBuffer(VertexBufferRHI, 0, Size, RLM_WriteOnly);
Expand All @@ -44,10 +50,15 @@ void FFurVertexBuffer::Unlock()

if (Size != VertexBufferRHI->GetSize() || VertexBufferRHI->GetUsage() == BUF_Static)
{
#if (ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 6)
FRHIBufferCreateDesc CreateDesc = FRHIBufferCreateDesc::CreateVertex(TEXT("FurVertexBuffer"), Size).AddUsage(BUF_Dynamic).DetermineInitialState();

VertexBufferRHI = RHICmdList.CreateBuffer(CreateDesc);
#else
FRHIResourceCreateInfo CreateInfo(L"FurVertexBuffer");
//VertexBufferRHI = RHICreateVertexBuffer(Size, BUF_Dynamic, CreateInfo); DEPRECATED
VertexBufferRHI = RHICmdList.CreateVertexBuffer(Size, BUF_Dynamic, CreateInfo);

#endif
}

// Copy the vertex data into the vertex buffer.
Expand All @@ -70,8 +81,14 @@ void FFurIndexBuffer::InitRHI(FRHICommandListBase& RHICmdList)
if (Indices.Num() == 0)
Indices.Add(0);

#if (ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 6)
FRHIBufferCreateDesc CreateDesc = FRHIBufferCreateDesc::CreateIndex(TEXT("FurVertexBuffer"), Indices.Num() * sizeof(int32), sizeof(int32)).AddUsage(BUF_Static).DetermineInitialState();

IndexBufferRHI = RHICmdList.CreateBuffer(CreateDesc);
#else
FRHIResourceCreateInfo CreateInfo(L"FurVertexBuffer");
IndexBufferRHI = RHICmdList.CreateIndexBuffer(sizeof(int32), Indices.Num() * sizeof(int32), BUF_Static, CreateInfo);
#endif
// Write the indices to the index buffer.
void* Buffer = RHICmdList.LockBuffer(IndexBufferRHI, 0, Indices.Num() * sizeof(int32), RLM_WriteOnly);
FMemory::Memcpy(Buffer, Indices.GetData(), Indices.Num() * sizeof(int32));
Expand All @@ -98,8 +115,13 @@ void FFurIndexBuffer::Unlock()
uint32 Size = Indices.Num() * sizeof(int32);
if (Size != IndexBufferRHI->GetSize() || IndexBufferRHI->GetUsage() == BUF_Static)
{
#if (ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 6)
FRHIBufferCreateDesc CreateDesc = FRHIBufferCreateDesc::CreateIndex(TEXT("FurVertexBuffer"), Size, sizeof(int32)).AddUsage(BUF_Dynamic).DetermineInitialState();
IndexBufferRHI = RHICmdList.CreateBuffer(CreateDesc);
#else
FRHIResourceCreateInfo CreateInfo(L"FurVertexBuffer");
IndexBufferRHI = RHICmdList.CreateIndexBuffer(sizeof(int32), Size, BUF_Dynamic, CreateInfo);
#endif
}

void* Buffer = RHICmdList.LockBuffer(IndexBufferRHI, 0, Indices.Num() * sizeof(int32), RLM_WriteOnly);
Expand Down
2 changes: 1 addition & 1 deletion Source/GFur/Private/FurData.h
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ class FFurDataCleanupTask : public FNonAbandonableTask

void DoWork()
{
FPlatformProcess::Sleep(1.0f);
FPlatformProcess::Sleep(0.01f);
Lambda();
}

Expand Down
22 changes: 17 additions & 5 deletions Source/GFur/Private/FurMorphObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,21 @@

#include "FurMorphObject.h"
#include "FurSkinData.h"
#include "Runtime/Engine/Public/Rendering/SkeletalMeshRenderData.h"
#include "Rendering/SkeletalMeshRenderData.h"
#include "Runtime/Engine/Private/SkeletalRenderGPUSkin.h"
#include "Runtime/Engine/Classes/Components/SkinnedMeshComponent.h"
#include "Runtime/Engine/Classes/Animation/MorphTarget.h"
#include "Components/SkinnedMeshComponent.h"
#include "Animation/MorphTarget.h"
#include "ShaderParameterUtils.h"

void FFurMorphVertexBuffer::InitRHI(FRHICommandListBase& RHICmdList)
{
// Create the buffer rendering resource
uint32 Size = NumVertices * sizeof(FMorphGPUSkinVertex);
#if (ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 6)
FRHIBufferCreateDesc CreateDesc = FRHIBufferCreateDesc::CreateVertex(TEXT("FurMorphVertexBuffer"), Size).AddUsage(BUF_Dynamic | BUF_ShaderResource).DetermineInitialState();

VertexBufferRHI = RHICmdList.CreateBuffer(CreateDesc);
#else
FRHIResourceCreateInfo CreateInfo(L"FurMorphVertexBuffer");

EBufferUsageFlags Flags = BUF_Dynamic;
Expand All @@ -20,6 +25,7 @@ void FFurMorphVertexBuffer::InitRHI(FRHICommandListBase& RHICmdList)
Flags = (EBufferUsageFlags)(Flags | BUF_ShaderResource);

VertexBufferRHI = RHICmdList.CreateVertexBuffer(Size, Flags, CreateInfo);
#endif

// Lock the buffer.
void* BufferData = RHICmdList.LockBuffer(VertexBufferRHI, 0, Size, RLM_WriteOnly);
Expand Down Expand Up @@ -84,8 +90,14 @@ void FFurMorphObject::Update_RenderThread(FRHICommandListImmediate& RHICmdList,
//checkSlow(MorphAbsWeight >= MinMorphTargetBlendWeight && MorphAbsWeight <= MaxMorphTargetBlendWeight);

// Get deltas
int32 NumDeltas;
const FMorphTargetDelta* Deltas = ActiveMorphTarget->GetMorphTargetDelta(InMeshLod, NumDeltas);
const TArray<FMorphTargetLODModel>& LODModels = ActiveMorphTarget->GetMorphLODModels();
if (!LODModels.IsValidIndex(InMeshLod))
{
continue;
}
const FMorphTargetLODModel& MorphModel = LODModels[InMeshLod];
int32 NumDeltas = MorphModel.Vertices.Num();
const FMorphTargetDelta* Deltas = MorphModel.Vertices.GetData();

// iterate over the vertices that this lod model has changed
for (int32 MorphVertIdx = 0; MorphVertIdx < NumDeltas; MorphVertIdx++)
Expand Down
Loading