Hey all!
I’ve made a class which inherits from InstancedStaticMeshComponent. I want to overload some of its functions, for example UpdateInstanceTransform(…).
For starters, here is the header and .cpp of the class at the moment.
InstancedGridComponent.h
#pragma once
#include "CoreMinimal.h"
#include "Components/InstancedStaticMeshComponent.h"
#include "InstancedGridComponent.generated.h"
/**
*
*/
UCLASS()
class TRON_3D_API UInstancedGridComponent : public UInstancedStaticMeshComponent
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, Category = "Components|InstancedStaticMesh")
virtual bool UpdateInstanceTransform(int32 InstanceIndex, const FTransform& NewInstanceTransform, bool bWorldSpace = false, bool bMarkRenderStateDirty = false, bool bTeleport = false) override;
};
InstancedGridComponent.cpp
#include "InstancedGridComponent.h"
bool UInstancedGridComponent::UpdateInstanceTransform(int32 InstanceIndex, const FTransform& NewInstanceTransform, bool bWorldSpace, bool bMarkRenderStateDirty, bool bTeleport)
{
if (!PerInstanceSMData.IsValidIndex(InstanceIndex))
{
return false;
}
if (PerInstanceSMData.Num() > 0 && PerInstanceRenderData.IsValid() && PerInstanceRenderData->InstanceBuffer.GetCurrentNumInstances() == 0 && !KeepInstanceBufferCPUAccess)
{
UE_LOG(LogStaticMesh, Warning, TEXT("Trying to change instance buffer for component %s, but we have no CPU copy. Set KeepInstanceBufferCPUAccess to true to keep access at the cost of memory."), *GetPathName());
return false;
}
Modify();
FInstancedStaticMeshInstanceData& InstanceData = PerInstanceSMData[InstanceIndex];
// TODO: Computing LocalTransform is useless when we're updating the world location for the entire mesh.
// Should find some way around this for performance.
// Render data uses local transform of the instance
FTransform LocalTransform = bWorldSpace ? NewInstanceTransform.GetRelativeTransform(GetComponentTransform()) : NewInstanceTransform;
InstanceData.Transform = LocalTransform.ToMatrixWithScale();
if (bPhysicsStateCreated)
{
// Physics uses world transform of the instance
FTransform WorldTransform = bWorldSpace ? NewInstanceTransform : (LocalTransform * GetComponentTransform());
FBodyInstance*& InstanceBodyInstance = InstanceBodies[InstanceIndex];
#if WITH_PHYSX
if (NewInstanceTransform.GetScale3D().IsNearlyZero())
{
if (InstanceBodyInstance)
{
// delete BodyInstance
InstanceBodyInstance->TermBody();
delete InstanceBodyInstance;
InstanceBodyInstance = nullptr;
}
}
else
{
if (InstanceBodyInstance)
{
// Update existing BodyInstance
InstanceBodyInstance->SetBodyTransform(WorldTransform, TeleportFlagToEnum(bTeleport));
InstanceBodyInstance->UpdateBodyScale(WorldTransform.GetScale3D());
}
else
{
// create new BodyInstance
InstanceBodyInstance = new FBodyInstance();
InitInstanceBody(InstanceIndex, InstanceBodyInstance);
}
}
#endif //WITH_PHYSX
}
// Request navigation update
PartialNavigationUpdate(InstanceIndex);
if (PerInstanceRenderData.IsValid())
{
PerInstanceRenderData->UpdateInstanceData(this, InstanceIndex);
}
if (bMarkRenderStateDirty)
{
MarkRenderStateDirty();
}
return true;
}
I’m only testing for now, which is why the overridden function is identical to the original.
This does not compile, because accessing via pointer anything from PerInstanceRenderData throws a compilation error, which reads as follows:
Severity Code Description Project File Line Suppression State
Error (active) pointer to incomplete class type is not allowed game e:\repo\game\Source\game\Private\InstancedGridComponent.cpp 12
Any ideas? PerInstanceRenderData is supposed to be public according to its declaration:
public:
/** Render data will be initialized on PostLoad or on demand. Released on the rendering thread. */
TSharedPtr<FPerInstanceRenderData, ESPMode::ThreadSafe> PerInstanceRenderData;
My best guess is that the issue is that FPerInstanceRenderData is not defined in InstancedStaticMeshComponent, which I inherit from, but in InstancedStaticMesh. However, I am not sure how to setup the include from there.
Any directions or help would be appreciated!