Files
UnrealEngine/Engine/Plugins/Mutable/Source/MutableRuntime/Private/MuR/Parameters.cpp
2025-05-18 13:04:45 +08:00

1162 lines
31 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "MuR/Parameters.h"
#include "HAL/LowLevelMemTracker.h"
#include "HAL/PlatformMath.h"
#include "HAL/UnrealMemory.h"
#include "Misc/AssertionMacros.h"
#include "MuR/Model.h"
#include "MuR/ModelPrivate.h"
#include "MuR/ParametersPrivate.h"
#include "MuR/Serialisation.h"
#include "MuR/SerialisationPrivate.h"
#include "MuR/System.h"
namespace mu
{
MUTABLE_IMPLEMENT_ENUM_SERIALISABLE(EParameterType)
MUTABLE_IMPLEMENT_ENUM_SERIALISABLE(EProjectorType)
FParameters::FParameters()
{
m_pD = new Private();
}
FParameters::~FParameters()
{
check( m_pD );
delete m_pD;
m_pD = 0;
}
void FParameters::Serialise( const FParameters* p, FOutputArchive& arch )
{
arch << *p->m_pD;
}
TSharedPtr<FParameters> FParameters::StaticUnserialise( FInputArchive& arch )
{
LLM_SCOPE_BYNAME(TEXT("MutableRuntime"));
TSharedPtr<FParameters> pResult = MakeShared<FParameters>();
arch >> *pResult->m_pD;
return pResult;
}
FParameters::Private* FParameters::GetPrivate() const
{
return m_pD;
}
TSharedPtr<FParameters> FParameters::Clone() const
{
LLM_SCOPE_BYNAME(TEXT("MutableRuntime"));
TSharedPtr<FParameters> pRes = MakeShared<FParameters>();
pRes->m_pD->Model = m_pD->Model;
pRes->m_pD->Values = m_pD->Values;
pRes->m_pD->MultiValues = m_pD->MultiValues;
return pRes;
}
int32 FParameters::GetCount() const
{
return (int32)m_pD->Values.Num();
}
const FString& FParameters::GetName( int32 Index ) const
{
const FProgram& Program = m_pD->Model->GetPrivate()->Program;
check( Index>=0 && Index<(int32)Program.Parameters.Num() );
return Program.Parameters[Index].Name;
}
const FGuid& FParameters::GetUid( int32 Index ) const
{
const FProgram& Program = m_pD->Model->GetPrivate()->Program;
check( Index>=0 && Index<Program.Parameters.Num() );
return Program.Parameters[Index].UID;
}
int32 FParameters::Find( const FString& strName ) const
{
return m_pD->Find( strName );
}
EParameterType FParameters::GetType( int32 Index ) const
{
const FProgram& Program = m_pD->Model->GetPrivate()->Program;
check( Index>=0 && Index<Program.Parameters.Num() );
return Program.Parameters[Index].Type;
}
TSharedPtr<FRangeIndex> FParameters::NewRangeIndex( int32 ParamIndex ) const
{
LLM_SCOPE_BYNAME(TEXT("MutableRuntime"));
const FProgram& Program = m_pD->Model->GetPrivate()->Program;
check( ParamIndex>=0 && ParamIndex<Program.Parameters.Num() );
TSharedPtr<FRangeIndex> Range;
if ( ParamIndex>=0 && ParamIndex<int32(Program.Parameters.Num()) )
{
int32 RangeCount = Program.Parameters[ParamIndex].Ranges.Num();
if (RangeCount >0 )
{
Range = MakeShared<FRangeIndex>();
Range->Parameters = this->AsShared();
Range->Parameter = ParamIndex;
Range->Values.SetNumZeroed(RangeCount);
}
}
return Range;
}
int32 FParameters::GetValueCount( int32 ParamIndex ) const
{
if (ParamIndex<0 || ParamIndex >= int32(m_pD->MultiValues.Num()) )
{
return 0;
}
return int32( m_pD->MultiValues[ParamIndex].Num() );
}
TSharedPtr<FRangeIndex> FParameters::GetValueIndex( int32 ParamIndex, int32 ValueIndex ) const
{
if (ParamIndex<0 || ParamIndex >= m_pD->MultiValues.Num() )
{
return nullptr;
}
if (ValueIndex <0 || ValueIndex >= int32(m_pD->MultiValues[ParamIndex].Num()) )
{
return nullptr;
}
TMap< TArray<int32>, FParameterValue >::TRangedForIterator it = m_pD->MultiValues[ParamIndex].begin();
for ( int32 i=0; i< ValueIndex; ++i )
{
++it;
}
TSharedPtr<FRangeIndex> result = NewRangeIndex( ParamIndex );
result->Values = it->Key;
return result;
}
void FParameters::ClearAllValues( int32 ParamIndex )
{
if (ParamIndex<0 || ParamIndex >= int32(m_pD->MultiValues.Num()) )
{
return;
}
m_pD->MultiValues[ParamIndex].Empty();
}
bool FParameters::GetBoolValue( int32 Index, const FRangeIndex* Pos ) const
{
check( Index>=0 && Index<(int32)m_pD->Values.Num() );
check( GetType(Index)==EParameterType::Bool );
// Early out in case of invalid parameters
if ( Index < 0
||
Index >= (int32)m_pD->Values.Num()
||
GetType(Index) != EParameterType::Bool )
{
return false;
}
// Single value case
if (!Pos)
{
// Return the single value
return m_pD->Values[Index].Get<FParamBoolType>();
}
// Multivalue case
check( Pos->Parameter==Index );
if ( Index<int32(m_pD->MultiValues.Num()))
{
const TMap< TArray<int32>, FParameterValue >& m = m_pD->MultiValues[Index];
const FParameterValue* it = m.Find(Pos->Values);
if (it)
{
return it->Get<FParamBoolType>();
}
}
// Multivalue parameter, but no multivalue set. Return single value.
return m_pD->Values[Index].Get<FParamBoolType>();
}
void FParameters::SetBoolValue( int32 Index, bool value,
const FRangeIndex* Pos )
{
check( Index>=0 && Index<(int32)m_pD->Values.Num() );
check( GetType(Index)== EParameterType::Bool );
// Early out in case of invalid parameters
if ( Index < 0
||
Index >= (int32)m_pD->Values.Num()
||
GetType(Index) != EParameterType::Bool )
{
return;
}
// Single value case
if (!Pos)
{
// Clear multivalue, if set.
if (Index<int32(m_pD->MultiValues.Num()))
{
m_pD->MultiValues[Index].Empty();
}
m_pD->Values[Index].Set<FParamBoolType>(value);
}
// Multivalue case
else
{
check( Pos->Parameter==Index );
if ( Index>=int32(m_pD->MultiValues.Num()))
{
m_pD->MultiValues.SetNum(Index+1);
}
TMap< TArray<int32>, FParameterValue >& m = m_pD->MultiValues[Index];
FParameterValue& it = m.FindOrAdd(Pos->Values);
it.Set<FParamBoolType>(value);
}
}
int32 FParameters::GetIntPossibleValueCount( int32 ParamIndex ) const
{
const FProgram& Program = m_pD->Model->GetPrivate()->Program;
check( ParamIndex>=0 && ParamIndex<(int32)Program.Parameters.Num() );
return (int32)Program.Parameters[ParamIndex].PossibleValues.Num();
}
int32 FParameters::GetIntPossibleValue( int32 ParamIndex, int32 valueIndex ) const
{
const FProgram& Program = m_pD->Model->GetPrivate()->Program;
check( ParamIndex>=0
&& ParamIndex<(int32)Program.Parameters.Num() );
check( valueIndex>=0
&& valueIndex<(int32)Program.Parameters[ParamIndex].PossibleValues.Num() );
return (int32)Program.Parameters[ParamIndex].PossibleValues[valueIndex].Value;
}
int32 FParameters::GetIntValueIndex(int32 ParamIndex, const FString& ValueName) const
{
const FProgram& Program = m_pD->Model->GetPrivate()->Program;
check(ParamIndex >= 0
&& ParamIndex < (int32)Program.Parameters.Num());
int32 result = -1;
for (size_t v = 0; v < Program.Parameters[ParamIndex].PossibleValues.Num(); ++v)
{
if (Program.Parameters[ParamIndex].PossibleValues[v].Name == ValueName)
{
result = (int32)v;
break;
}
}
return result;
}
int32 FParameters::GetIntValueIndex(int32 ParamIndex, int32 Value) const
{
const FProgram& Program = m_pD->Model->GetPrivate()->Program;
check(ParamIndex >= 0
&& ParamIndex < (int32)Program.Parameters.Num());
for (size_t v = 0; v < Program.Parameters[ParamIndex].PossibleValues.Num(); ++v)
{
if (Program.Parameters[ParamIndex].PossibleValues[v].Value == Value)
{
return (int32)v;
}
}
return -1;
}
const FString& FParameters::GetIntPossibleValueName( int32 ParamIndex, int32 valueIndex ) const
{
const FProgram& Program = m_pD->Model->GetPrivate()->Program;
check( ParamIndex>=0
&& ParamIndex<(int32)Program.Parameters.Num() );
check( valueIndex>=0
&& valueIndex<(int32)Program.Parameters[ParamIndex].PossibleValues.Num() );
return Program.Parameters[ParamIndex].PossibleValues[valueIndex].Name;
}
int32 FParameters::GetIntValue( int32 Index, const FRangeIndex* Pos ) const
{
check( Index>=0 && Index<(int32)m_pD->Values.Num() );
check( GetType(Index)== EParameterType::Int );
// Early out in case of invalid parameters
if ( Index < 0
||
Index >= (int32)m_pD->Values.Num()
||
GetType(Index) != EParameterType::Int )
{
return 0;
}
// Single value case
if (!Pos)
{
// Return the single value
return m_pD->Values[Index].Get<FParamIntType>();
}
// Multivalue case
check( Pos->Parameter==Index );
if ( Index<int32(m_pD->MultiValues.Num()))
{
const TMap< TArray<int32>, FParameterValue >& m = m_pD->MultiValues[Index];
const FParameterValue* it = m.Find(Pos->Values);
if (it)
{
return it->Get<FParamIntType>();
}
}
// Multivalue parameter, but no multivalue set. Return single value.
return m_pD->Values[Index].Get<FParamIntType>();
}
void FParameters::SetIntValue( int32 Index, int32 value,
const FRangeIndex* Pos )
{
check( Index>=0 && Index<(int32)m_pD->Values.Num() );
check( GetType(Index)== EParameterType::Int );
// Early out in case of invalid parameters
if ( Index < 0
||
Index >= (int32)m_pD->Values.Num()
||
GetType(Index) != EParameterType::Int )
{
return;
}
// Single value case
if (!Pos)
{
// Clear multivalue, if set.
if (Index<int32(m_pD->MultiValues.Num()))
{
m_pD->MultiValues[Index].Empty();
}
m_pD->Values[Index].Set<FParamIntType>(value);
}
// Multivalue case
else
{
check( Pos->Parameter==Index );
if ( Index>=int32(m_pD->MultiValues.Num()))
{
m_pD->MultiValues.SetNum(Index+1);
}
TMap< TArray<int32>, FParameterValue >& m = m_pD->MultiValues[Index];
FParameterValue& it = m.FindOrAdd(Pos->Values);
it.Set<FParamIntType>(value);
}
}
float FParameters::GetFloatValue( int32 Index,
const FRangeIndex* Pos ) const
{
check( Index>=0 && Index<(int32)m_pD->Values.Num() );
check( GetType(Index)== EParameterType::Float );
// Early out in case of invalid parameters
if ( Index < 0
||
Index >= (int32)m_pD->Values.Num()
||
GetType(Index) != EParameterType::Float )
{
return 0.0f;
}
// Single value case
if (!Pos)
{
// Return the single value
return m_pD->Values[Index].Get<FParamFloatType>();
}
// Multivalue case
check( Pos->Parameter==Index );
if ( Index<int32(m_pD->MultiValues.Num()))
{
const TMap< TArray<int32>, FParameterValue >& m = m_pD->MultiValues[Index];
const FParameterValue* it = m.Find(Pos->Values);
if (it)
{
return it->Get<FParamFloatType>();
}
}
// Multivalue parameter, but no multivalue set. Return single value.
return m_pD->Values[Index].Get<FParamFloatType>();
}
void FParameters::SetFloatValue( int32 Index, float value,
const FRangeIndex* Pos )
{
check( Index>=0 && Index<(int32)m_pD->Values.Num() );
check( GetType(Index)== EParameterType::Float );
// Early out in case of invalid parameters
if ( Index < 0
||
Index >= (int32)m_pD->Values.Num()
||
GetType(Index) != EParameterType::Float )
{
return;
}
// Single value case
if (!Pos)
{
// Clear multivalue, if set.
if (Index<int32(m_pD->MultiValues.Num()))
{
m_pD->MultiValues[Index].Empty();
}
m_pD->Values[Index].Set<FParamFloatType>(value);
}
// Multivalue case
else
{
check( Pos->Parameter==Index );
if ( Index>=int32(m_pD->MultiValues.Num()))
{
m_pD->MultiValues.SetNum(Index+1);
}
TMap< TArray<int32>, FParameterValue >& m = m_pD->MultiValues[Index];
FParameterValue& it = m.FindOrAdd(Pos->Values);
it.Set<FParamFloatType>(value);
}
}
void FParameters::GetColourValue( int32 Index, FVector4f& OutValue, const FRangeIndex* Pos ) const
{
check( Index>=0 && Index<(int32)m_pD->Values.Num() );
check( GetType(Index)== EParameterType::Color );
// Early out in case of invalid parameters
if ( Index < 0
||
Index >= (int32)m_pD->Values.Num()
||
GetType(Index) != EParameterType::Color )
{
return;
}
// Single value case
if (!Pos)
{
OutValue = m_pD->Values[Index].Get<FParamColorType>();
return;
}
// Multivalue case
check( Pos->Parameter==Index );
if ( Index<int32(m_pD->MultiValues.Num()))
{
const TMap< TArray<int32>, FParameterValue >& m = m_pD->MultiValues[Index];
const FParameterValue* it = m.Find(Pos->Values);
if (it)
{
OutValue = it->Get<FParamColorType>();
return;
}
}
// Multivalue parameter, but no multivalue set. Return single value.
OutValue = m_pD->Values[Index].Get<FParamColorType>();
return;
}
void FParameters::SetColourValue( int32 Index, FVector4f InValue, const FRangeIndex* Pos )
{
check( Index>=0 && Index<(int32)m_pD->Values.Num() );
check( GetType(Index)== EParameterType::Color );
// Early out in case of invalid parameters
if ( Index < 0
||
Index >= (int32)m_pD->Values.Num()
||
GetType(Index) != EParameterType::Color )
{
return;
}
// Single value case
if (!Pos)
{
// Clear multivalue, if set.
if (Index<int32(m_pD->MultiValues.Num()))
{
m_pD->MultiValues[Index].Empty();
}
m_pD->Values[Index].Set<FParamColorType>(InValue);
}
// Multivalue case
else
{
check( Pos->Parameter==Index );
if ( Index>=int32(m_pD->MultiValues.Num()))
{
m_pD->MultiValues.SetNum(Index+1);
}
TMap< TArray<int32>, FParameterValue >& m = m_pD->MultiValues[Index];
FParameterValue& it = m.FindOrAdd(Pos->Values);
it.Set<FParamColorType>(InValue);
}
}
USkeletalMesh* FParameters::GetMeshValue(int32 Index, const FRangeIndex* Pos) const
{
check(Index >= 0 && Index < (int32)m_pD->Values.Num());
check(GetType(Index) == EParameterType::Mesh);
// Early out in case of invalid parameters
if (Index < 0
||
Index >= (int32)m_pD->Values.Num()
||
GetType(Index) != EParameterType::Mesh)
{
return {};
}
// Single value case
if (!Pos)
{
return m_pD->Values[Index].Get<FParamSkeletalMeshType>().Get();
}
// Multivalue case
check(Pos->Parameter == Index);
if (Index < int32(m_pD->MultiValues.Num()))
{
const TMap< TArray<int32>, FParameterValue >& m = m_pD->MultiValues[Index];
const FParameterValue* it = m.Find(Pos->Values);
if (it)
{
return it->Get<FParamSkeletalMeshType>().Get();
}
}
// Multivalue parameter, but no multivalue set. Return single value.
return m_pD->Values[Index].Get<FParamSkeletalMeshType>().Get();
}
void FParameters::SetMeshValue(int32 Index, USkeletalMesh* Value, const FRangeIndex* Pos)
{
check(Index >= 0 && Index < (int32)m_pD->Values.Num());
check(GetType(Index) == EParameterType::Mesh);
// Single value case
if (!Pos)
{
m_pD->Values[Index].Set<FParamSkeletalMeshType>(TStrongObjectPtr(Value));
}
// Multivalue case
else
{
check(Pos->Parameter == Index);
if (Index >= int32(m_pD->MultiValues.Num()))
{
m_pD->MultiValues.SetNum(Index + 1);
}
TMap< TArray<int32>, FParameterValue >& m = m_pD->MultiValues[Index];
FParameterValue& it = m.FindOrAdd(Pos->Values);
it.Set<FParamSkeletalMeshType>(TStrongObjectPtr(Value));
}
}
UTexture* FParameters::GetImageValue( int32 Index, const FRangeIndex* Pos ) const
{
check( Index >= 0 && Index < (int32)m_pD->Values.Num() );
check( GetType( Index ) == EParameterType::Image );
// Early out in case of invalid parameters
if ( Index < 0
||
Index >= (int32)m_pD->Values.Num()
||
GetType(Index) != EParameterType::Image )
{
return {};
}
// Single value case
if (!Pos)
{
return m_pD->Values[Index].Get<FParamTextureType>().Get();
}
// Multivalue case
check(Pos->Parameter == Index);
if (Index < int32(m_pD->MultiValues.Num()))
{
const TMap< TArray<int32>, FParameterValue >& m = m_pD->MultiValues[Index];
const FParameterValue* it = m.Find(Pos->Values);
if (it)
{
return it->Get<FParamTextureType>().Get();
}
}
// Multivalue parameter, but no multivalue set. Return single value.
return m_pD->Values[Index].Get<FParamTextureType>().Get();
}
void FParameters::SetImageValue( int32 Index, UTexture* Value, const FRangeIndex* Pos )
{
check( Index >= 0 && Index < (int32)m_pD->Values.Num() );
check( GetType( Index ) == EParameterType::Image );
// Single value case
if (!Pos)
{
m_pD->Values[Index].Set<FParamTextureType>(TStrongObjectPtr(Value));
}
// Multivalue case
else
{
check(Pos->Parameter == Index);
if (Index >= int32(m_pD->MultiValues.Num()))
{
m_pD->MultiValues.SetNum(Index + 1);
}
TMap< TArray<int32>, FParameterValue >& m = m_pD->MultiValues[Index];
FParameterValue& it = m.FindOrAdd(Pos->Values);
it.Set<FParamTextureType>(TStrongObjectPtr(Value));
}
}
void FParameters::GetStringValue( int32 Index, FString& OutValue, const FRangeIndex* Pos ) const
{
check( Index >= 0 && Index < (int32)m_pD->Values.Num() );
check( GetType( Index ) == EParameterType::String );
// Early out in case of invalid parameters
if ( Index < 0 || Index >= (int32)m_pD->Values.Num() ||
GetType( Index ) != EParameterType::String )
{
OutValue = TEXT("");
return;
}
// Single value case
if ( !Pos )
{
// Return the single value
OutValue = m_pD->Values[Index].Get<FParamStringType>();
return;
}
// Multivalue case
check( Pos->Parameter == Index );
if ( Index < int32( m_pD->MultiValues.Num() ) )
{
const TMap< TArray<int32>, FParameterValue >& m = m_pD->MultiValues[Index];
const FParameterValue* it = m.Find( Pos->Values );
if ( it )
{
OutValue = it->Get<FParamStringType>();
return;
}
}
// Multivalue parameter, but no multivalue set. Return single value.
OutValue = m_pD->Values[Index].Get<FParamStringType>();
return;
}
void FParameters::SetStringValue( int32 Index, const FString& Value, const FRangeIndex* Pos )
{
LLM_SCOPE_BYNAME(TEXT("MutableRuntime"));
check( Index >= 0 && Index < (int32)m_pD->Values.Num() );
check( GetType( Index ) == EParameterType::Float );
// Early out in case of invalid parameters
if ( Index < 0 || Index >= (int32)m_pD->Values.Num() ||
GetType( Index ) != EParameterType::Float )
{
return;
}
// Single value case
if ( !Pos )
{
// Clear multivalue, if set.
if ( Index < int32( m_pD->MultiValues.Num() ) )
{
m_pD->MultiValues[Index].Empty();
}
m_pD->Values[Index].Set<FParamStringType>(Value);
}
// Multivalue case
else
{
check( Pos->Parameter == Index );
if ( Index >= int32( m_pD->MultiValues.Num() ) )
{
m_pD->MultiValues.SetNum( Index + 1 );
}
TMap< TArray<int32>, FParameterValue >& m = m_pD->MultiValues[Index];
FParameterValue& it = m.FindOrAdd( Pos->Values );
it.Set<FParamStringType>(Value);
}
}
void FParameters::GetMatrixValue(int32 Index, FMatrix44f& OutValue, const FRangeIndex* Pos) const
{
check( Index >= 0 && Index < (int32)m_pD->Values.Num() );
check( GetType( Index ) == EParameterType::Matrix );
// Early out in case of invalid parameters
if ( Index < 0 || Index >= (int32)m_pD->Values.Num() ||
GetType( Index ) != EParameterType::Matrix )
{
OutValue = FMatrix44f::Identity;
return;
}
// Single value case
if ( !Pos )
{
// Return the single value
OutValue = m_pD->Values[Index].Get<FParamMatrixType>();
return;
}
// Multivalue case
check( Pos->Parameter == Index );
if ( Index < int32( m_pD->MultiValues.Num() ) )
{
const TMap< TArray<int32>, FParameterValue >& m = m_pD->MultiValues[Index];
const FParameterValue* it = m.Find( Pos->Values );
if ( it )
{
OutValue = it->Get<FParamMatrixType>();
return;
}
}
// Multivalue parameter, but no multivalue set. Return single value.
OutValue = m_pD->Values[Index].Get<FParamMatrixType>();
}
void FParameters::SetMatrixValue(int32 Index, const FMatrix44f& Value, const FRangeIndex* Pos)
{
LLM_SCOPE_BYNAME(TEXT("MutableRuntime"));
check( Index >= 0 && Index < (int32)m_pD->Values.Num() );
check( GetType( Index ) == EParameterType::Matrix );
// Early out in case of invalid parameters
if ( Index < 0 || Index >= (int32)m_pD->Values.Num() ||
GetType( Index ) != EParameterType::Matrix )
{
return;
}
// Single value case
if ( !Pos )
{
// Clear multivalue, if set.
if ( Index < int32( m_pD->MultiValues.Num() ) )
{
m_pD->MultiValues[Index].Empty();
}
m_pD->Values[Index].Set<FParamMatrixType>(Value);
}
// Multivalue case
else
{
check( Pos->Parameter == Index );
if ( Index >= int32( m_pD->MultiValues.Num() ) )
{
m_pD->MultiValues.SetNum( Index + 1 );
}
TMap< TArray<int32>, FParameterValue >& m = m_pD->MultiValues[Index];
FParameterValue& it = m.FindOrAdd( Pos->Values );
it.Set<FParamMatrixType>(Value);
}
}
FProjector FParameters::Private::GetProjectorValue( int32 Index, const FRangeIndex* Pos ) const
{
const FProgram& Program = Model->GetPrivate()->Program;
// Early out in case of invalid parameters
if ( Index < 0
||
Index >= Values.Num()
||
Index >= Program.Parameters.Num()
||
Program.Parameters[Index].Type != EParameterType::Projector )
{
check(false);
return FProjector();
}
// Single value case
if (!Pos)
{
// Return the single value
return Values[Index].Get<FParamProjectorType>();
}
const FProjector* Result = nullptr;
// Multivalue case
check( Pos->Parameter==Index );
if ( Index<MultiValues.Num())
{
const FParameterValue* it = MultiValues[Index].Find(Pos->Values);
if (it)
{
return it->Get<FParamProjectorType>();
}
}
// Multivalue parameter, but no multivalue set. Return single value.
return Values[Index].Get<FParamProjectorType>();
}
void FParameters::GetProjectorValue( int32 ParameterIndex,
EProjectorType* OutType,
FVector3f* OutPos,
FVector3f* OutDir,
FVector3f* OutUp,
FVector3f* OutScale,
float* OutProjectionAngle,
const FRangeIndex* Pos ) const
{
check(ParameterIndex >=0 && ParameterIndex <m_pD->Values.Num() );
check( GetType(ParameterIndex)== EParameterType::Projector );
// Early out in case of invalid parameters
if (ParameterIndex < 0
||
ParameterIndex >= m_pD->Values.Num()
||
GetType(ParameterIndex) != EParameterType::Projector )
{
return;
}
FProjector result = m_pD->GetProjectorValue(ParameterIndex, Pos );
// Copy results
if (OutType) *OutType = result.type;
if (OutPos) *OutPos = result.position;
if (OutDir) *OutDir = result.direction;
if (OutUp) *OutUp = result.up;
if (OutScale) *OutScale = result.scale;
if (OutProjectionAngle) *OutProjectionAngle = result.projectionAngle;
}
void FParameters::SetProjectorValue( int32 ParameterIndex,
const FVector3f& Pos,
const FVector3f& dir,
const FVector3f& up,
const FVector3f& scale,
float projectionAngle,
const FRangeIndex* RangePosition)
{
check(ParameterIndex >=0 && ParameterIndex <m_pD->Values.Num() );
check( GetType(ParameterIndex)== EParameterType::Projector );
// Early out in case of invalid parameters
if (ParameterIndex < 0
||
ParameterIndex >= m_pD->Values.Num()
||
GetType(ParameterIndex) != EParameterType::Projector )
{
return;
}
// FParameters cannot change the projector type anymore
FProjector Value;
Value.type = EProjectorType::Count;
if (m_pD->Model)
{
const FProgram& Program = m_pD->Model->GetPrivate()->Program;
const FProjector& Projector = Program.Parameters[ParameterIndex].DefaultValue.Get<FParamProjectorType>();
Value.type = Projector.type;
}
Value.position = Pos;
Value.direction = dir;
Value.up = up;
Value.scale = scale;
Value.projectionAngle = projectionAngle;
// Single value case
if (!RangePosition)
{
// Clear multivalue, if set.
if (ParameterIndex<m_pD->MultiValues.Num())
{
m_pD->MultiValues[ParameterIndex].Empty();
}
m_pD->Values[ParameterIndex].Set<FParamProjectorType>(Value);
}
// Multivalue case
else
{
check(RangePosition->Parameter== ParameterIndex);
if (ParameterIndex >=m_pD->MultiValues.Num())
{
m_pD->MultiValues.SetNum(ParameterIndex+1);
}
TMap< TArray<int32>, FParameterValue >& m = m_pD->MultiValues[ParameterIndex];
FParameterValue& it = m.FindOrAdd(RangePosition->Values);
it.Set<FParamProjectorType>(Value);
}
}
bool FParameters::HasSameValue( int32 thisParamIndex,
const TSharedPtr<const FParameters>& other,
int32 otherParamIndex ) const
{
if ( GetType(thisParamIndex) != other->GetType(otherParamIndex) )
{
return false;
}
if ( !(m_pD->Values[thisParamIndex]==other->m_pD->Values[otherParamIndex] ) )
{
return false;
}
size_t thisNumMultiValues = 0;
bool thisHasMultiValues = int32(m_pD->MultiValues.Num()) > thisParamIndex;
if (thisHasMultiValues)
{
thisNumMultiValues = m_pD->MultiValues[thisParamIndex].Num();
}
size_t otherNumMultiValues = 0;
bool otherHasMultiValues = int32(other->m_pD->MultiValues.Num()) > otherParamIndex;
if (otherHasMultiValues)
{
otherNumMultiValues = other->m_pD->MultiValues[otherParamIndex].Num();
}
if ( thisNumMultiValues != otherNumMultiValues )
{
return false;
}
if ( thisHasMultiValues
&&
otherHasMultiValues
&&
!(m_pD->MultiValues[thisParamIndex]==other->m_pD->MultiValues[otherParamIndex] ))
{
return false;
}
return true;
}
int32 FParameters::Private::Find( const FString& Name ) const
{
const FProgram& Program = Model->GetPrivate()->Program;
int32 result = -1;
for( int32 i=0; result<0 && i<(int32)Program.Parameters.Num(); ++i )
{
const FParameterDesc& p = Program.Parameters[i];
if (p.Name == Name)
{
result = i;
}
}
return result;
}
//---------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------
int32 FRangeIndex::GetRangeCount() const
{
return int32( Values.Num() );
}
const FString& FRangeIndex::GetRangeName( int32 Index ) const
{
check( Index >= 0 && Index < GetRangeCount() );
check( Index < int32(Parameters->GetPrivate()->Values.Num()) );
TSharedPtr<const FModel> Model = Parameters->GetPrivate()->Model;
check(Model);
check( Index < int32(Model->GetPrivate()->Program.Ranges.Num()) );
return Model->GetPrivate()->Program.Ranges[Index].Name;
}
const FString& FRangeIndex::GetRangeUid( int32 Index ) const
{
check( Index >= 0 && Index < GetRangeCount() );
check( Index < int32(Parameters->GetPrivate()->Values.Num()) );
TSharedPtr<const FModel> Model = Parameters->GetPrivate()->Model;
check(Model);
check( Index < int32(Model->GetPrivate()->Program.Ranges.Num()) );
return Model->GetPrivate()->Program.Ranges[Index].UID;
}
void FRangeIndex::SetPosition( int32 Index, int32 Position )
{
check( Index >= 0 && Index < GetRangeCount() );
if ( Index >= 0 && Index < GetRangeCount() )
{
Values[Index] = Position;
}
}
int32 FRangeIndex::GetPosition( int32 Index ) const
{
check( Index >= 0 && Index < GetRangeCount() );
if ( Index >= 0 && Index < GetRangeCount() )
{
return Values[Index];
}
return 0;
}
}