CelticCraft/Plugins/VoxelFree/Source/Voxel/Public/VoxelSpawners/VoxelBasicSpawner.h

126 lines
4.4 KiB
C
Raw Permalink Normal View History

2023-07-03 16:17:13 +00:00
// Copyright 2020 Phyronnaz
#pragma once
#include "CoreMinimal.h"
#include "VoxelSpawners/VoxelSpawner.h"
#include "VoxelBasicSpawner.generated.h"
UENUM()
enum class EVoxelBasicSpawnerScaling : uint8
{
/** Instances will have uniform X, Y and Z scales */
Uniform,
/** Instances will have random X, Y and Z scales */
Free,
/** X and Y will be the same random scale, Z will be another */
LockXY
};
USTRUCT()
struct FVoxelBasicSpawnerScaleSettings
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, Category = "Config")
EVoxelBasicSpawnerScaling Scaling = EVoxelBasicSpawnerScaling::Uniform;
/** Specifies the range of scale, from minimum to maximum, to apply to an actor instance's X Scale property */
UPROPERTY(EditAnywhere, Category = "Config")
FFloatInterval ScaleX = FFloatInterval(1.0f, 1.0f);
/** Specifies the range of scale, from minimum to maximum, to apply to an actor instance's Y Scale property */
UPROPERTY(EditAnywhere, Category = "Config")
FFloatInterval ScaleY = FFloatInterval(1.0f, 1.0f);
/** Specifies the range of scale, from minimum to maximum, to apply to an actor instance's Z Scale property */
UPROPERTY(EditAnywhere, Category = "Config")
FFloatInterval ScaleZ = FFloatInterval(1.0f, 1.0f);
inline FVector GetScale(const FRandomStream& Stream) const
{
FVector Scale;
switch (Scaling)
{
case EVoxelBasicSpawnerScaling::Uniform:
Scale.X = ScaleX.Interpolate(Stream.GetFraction());
Scale.Y = Scale.X;
Scale.Z = Scale.X;
break;
case EVoxelBasicSpawnerScaling::Free:
Scale.X = ScaleX.Interpolate(Stream.GetFraction());
Scale.Y = ScaleY.Interpolate(Stream.GetFraction());
Scale.Z = ScaleZ.Interpolate(Stream.GetFraction());
break;
case EVoxelBasicSpawnerScaling::LockXY:
Scale.X = ScaleX.Interpolate(Stream.GetFraction());
Scale.Y = Scale.X;
Scale.Z = ScaleZ.Interpolate(Stream.GetFraction());
break;
default:
check(false);
}
return Scale;
}
};
UENUM()
enum class EVoxelBasicSpawnerRotation : uint8
{
AlignToSurface,
AlignToWorldUp,
RandomAlign
};
UCLASS(Abstract)
class VOXEL_API UVoxelBasicSpawner : public UVoxelSpawner
{
GENERATED_BODY()
public:
// Min/max angle between object up vector and generator up vector in degrees
UPROPERTY(EditAnywhere, Category = "Placement", meta = (UIMin = 0, ClampMin = 0, UIMax = 180, ClampMax = 180))
FFloatInterval GroundSlopeAngle = { 0, 90 };
UPROPERTY(EditAnywhere, Category = "Placement", meta = (InlineEditConditionToggle))
bool bEnableHeightRestriction = false;
// In voxels. Only spawn instances if the instance voxel Z position is in this interval.
// TODO: optimize to not generate chunks that do not match this restriction
UPROPERTY(EditAnywhere, Category = "Placement", meta = (EditCondition = "bEnableHeightRestriction"))
FFloatInterval HeightRestriction = { -100.f, 100.f };
// In voxels, the size of the fade on the edges of HeightRestriction
UPROPERTY(EditAnywhere, Category = "Placement", meta = (EditCondition = "bEnableHeightRestriction", UIMin = 0, ClampMin = 0))
float HeightRestrictionFalloff = 0.f;
// Specifies instance scaling type
UPROPERTY(EditAnywhere, Category = "Placement - Scale")
FVoxelBasicSpawnerScaleSettings Scaling;
// Vertical to use for the instances
UPROPERTY(EditAnywhere, Category = "Placement - Rotation")
EVoxelBasicSpawnerRotation RotationAlignment = EVoxelBasicSpawnerRotation::AlignToWorldUp;
// If selected, foliage instances will have a random yaw rotation around their vertical axis applied
UPROPERTY(EditAnywhere, Category = "Placement - Rotation")
bool bRandomYaw = true;
// A random pitch adjustment can be applied to each instance, up to the specified angle in degrees, from the original vertical
UPROPERTY(EditAnywhere, Category = "Placement - Rotation", meta = (UIMin = 0, ClampMin = 0, UIMax = 180, ClampMax = 180))
float RandomPitchAngle = 6;
// Apply an offset to the instance position. Applied before the rotation. In cm
UPROPERTY(EditAnywhere, Category = "Placement - Offset")
FVector LocalPositionOffset = FVector::ZeroVector;
// Apply an offset to the instance rotation. Applied after the local position offset, and before the rotation
UPROPERTY(EditAnywhere, Category = "Placement - Offset")
FRotator LocalRotationOffset = FRotator::ZeroRotator;
// Apply an offset to the instance position. Applied after the rotation. In cm
UPROPERTY(EditAnywhere, Category = "Placement - Offset")
FVector GlobalPositionOffset = FVector::ZeroVector;
};