Refactor Visject Graph nodes data for unlimited size

This commit is contained in:
Wojtek Figat
2024-04-19 12:22:04 +02:00
parent 0845866c4d
commit 71fe280464
7 changed files with 24 additions and 33 deletions

View File

@@ -163,10 +163,12 @@ bool AnimGraphBase::onNodeLoaded(Node* n)
// Animation
case 2:
ADD_BUCKET(AnimationBucketInit);
n->Assets.Resize(1);
n->Assets[0] = (Asset*)Content::LoadAsync<Animation>((Guid)n->Values[0]);
break;
// Blend with Mask
case 11:
n->Assets.Resize(1);
n->Assets[0] = (Asset*)Content::LoadAsync<SkeletonMask>((Guid)n->Values[1]);
break;
// Multi Blend 1D
@@ -174,6 +176,7 @@ bool AnimGraphBase::onNodeLoaded(Node* n)
{
ADD_BUCKET(MultiBlendBucketInit);
n->Data.MultiBlend1D.Length = -1;
n->Assets.Resize(ANIM_GRAPH_MULTI_BLEND_MAX_ANIMS);
for (int32 i = 0; i < ANIM_GRAPH_MULTI_BLEND_MAX_ANIMS; i++)
{
n->Assets[i] = Content::LoadAsync<Animation>((Guid)n->Values[i * 2 + 5]);
@@ -191,6 +194,7 @@ bool AnimGraphBase::onNodeLoaded(Node* n)
// Get blend points locations
Array<Float2, FixedAllocation<ANIM_GRAPH_MULTI_BLEND_MAX_ANIMS + 3>> vertices;
byte vertexIndexToAnimIndex[ANIM_GRAPH_MULTI_BLEND_MAX_ANIMS];
n->Assets.Resize(ANIM_GRAPH_MULTI_BLEND_MAX_ANIMS);
for (int32 i = 0; i < ANIM_GRAPH_MULTI_BLEND_MAX_ANIMS; i++)
{
n->Assets[i] = (Asset*)Content::LoadAsync<Animation>((Guid)n->Values[i * 2 + 5]);
@@ -305,6 +309,7 @@ bool AnimGraphBase::onNodeLoaded(Node* n)
data.Graph = nullptr;
break;
}
n->Assets.Resize(1);
n->Assets[0] = function;
// Load the graph

View File

@@ -427,23 +427,7 @@ struct AnimGraphTransitionData
float Length;
};
class AnimGraphBox : public VisjectGraphBox
{
public:
AnimGraphBox()
{
}
AnimGraphBox(AnimGraphNode* parent, byte id, const VariantType::Types type)
: VisjectGraphBox(parent, id, type)
{
}
AnimGraphBox(AnimGraphNode* parent, byte id, const VariantType& type)
: VisjectGraphBox(parent, id, type)
{
}
};
typedef VisjectGraphBox AnimGraphBox;
class AnimGraphNode : public VisjectGraphNode<AnimGraphBox>
{
@@ -603,7 +587,7 @@ public:
/// Gets the per-node node transformations cache (cached).
/// </summary>
/// <param name="executor">The Graph execution context.</param>
/// <returns>The modes data.</returns>
/// <returns>Nodes data.</returns>
AnimGraphImpulse* GetNodes(AnimGraphExecutor* executor);
};

View File

@@ -673,19 +673,20 @@ void ComputeMultiBlendLength(float& length, AnimGraphNode* node)
// TODO: lock graph or graph asset here? make it thread safe
length = 0.0f;
for (int32 i = 0; i < ARRAY_COUNT(node->Assets); i++)
for (int32 i = 0; i < node->Assets.Count(); i++)
{
if (node->Assets[i])
auto& asset = node->Assets[i];
if (asset)
{
// TODO: maybe don't update if not all anims are loaded? just skip the node with the bind pose?
if (node->Assets[i]->WaitForLoaded())
if (asset->WaitForLoaded())
{
node->Assets[i] = nullptr;
asset = nullptr;
LOG(Warning, "Failed to load one of the animations.");
}
else
{
const auto anim = node->Assets[i].As<Animation>();
const auto anim = asset.As<Animation>();
const auto aData = node->Values[4 + i * 2].AsFloat4();
length = Math::Max(length, anim->GetLength() * Math::Abs(aData.W));
}

View File

@@ -26,7 +26,7 @@ public:
/// <summary>
/// The asset references. Linked resources such as Animation assets are referenced in graph data as ID. We need to keep valid refs to them at runtime to keep data in memory.
/// </summary>
AssetReference<Asset> Assets[14];
Array<AssetReference<Asset>> Assets;
};
/// <summary>

View File

@@ -177,6 +177,7 @@ public:
// Get Gameplay Global
case GRAPH_NODE_MAKE_TYPE(7, 16):
{
node->Assets.Resize(1);
node->Assets[0] = Content::LoadAsync<Asset>((Guid)node->Values[0]);
break;
}
@@ -296,6 +297,7 @@ public:
break;
// Particle Emitter Function
case GRAPH_NODE_MAKE_TYPE(14, 300):
node->Assets.Resize(1);
InitParticleEmitterFunctionCall((Guid)node->Values[0], node->Assets[0], node->UsesParticleData, Layout);
break;
// Particle Index
@@ -447,6 +449,7 @@ public:
// Sprite Rendering
case GRAPH_NODE_MAKE_TYPE(15, 400):
{
node->Assets.Resize(1);
node->Assets[0] = Content::LoadAsync<Asset>((Guid)node->Values[2]);
USE_ATTRIBUTE(Position, Float3, 0);
USE_ATTRIBUTE(Rotation, Float3, 1);
@@ -484,6 +487,7 @@ public:
// Model Rendering
case GRAPH_NODE_MAKE_TYPE(15, 403):
{
node->Assets.Resize(2);
node->Assets[0] = Content::LoadAsync<Asset>((Guid)node->Values[2]);
node->Assets[1] = Content::LoadAsync<Asset>((Guid)node->Values[3]);
USE_ATTRIBUTE(Position, Float3, 0);
@@ -494,6 +498,7 @@ public:
// Ribbon Rendering
case GRAPH_NODE_MAKE_TYPE(15, 404):
{
node->Assets.Resize(1);
node->Assets[0] = Content::LoadAsync<Asset>((Guid)node->Values[2]);
USE_ATTRIBUTE(Position, Float3, 0);
// TODO: add support for custom sorting key - not only by age
@@ -503,6 +508,7 @@ public:
// Volumetric Fog Rendering
case GRAPH_NODE_MAKE_TYPE(15, 405):
{
node->Assets.Resize(1);
node->Assets[0] = Content::LoadAsync<Asset>((Guid)node->Values[2]);
USE_ATTRIBUTE(Position, Float3, 0);
USE_ATTRIBUTE(Radius, Float, 1);

View File

@@ -11,8 +11,6 @@ class GraphNode;
#define GRAPH_NODE_MAKE_TYPE(groupID, typeID) (uint32)((groupID) << 16 | (typeID))
#define GRAPH_NODE_MAX_VALUES 32
/// <summary>
/// Represents single box of the graph node
/// </summary>
@@ -114,14 +112,13 @@ public:
uint16 TypeID;
uint16 GroupID;
};
uint32 Type;
};
/// <summary>
/// List of all node values. Array size and value types are constant over time. Only value data can change.
/// </summary>
Array<Variant, FixedAllocation<GRAPH_NODE_MAX_VALUES>> Values;
Array<Variant, InlinedAllocation<8>> Values;
/// <summary>
/// Node boxes cache. Array index matches the box ID (for fast O(1) lookups).

View File

@@ -6,13 +6,12 @@
#include "Engine/Core/Math/Vector2.h"
#include "Engine/Core/Math/Vector3.h"
#include "Engine/Core/Math/Vector4.h"
#include "Engine/Core/Collections/Array.h"
#include "Engine/Content/Asset.h"
#include "Engine/Content/AssetReference.h"
#include "Engine/Content/AssetsContainer.h"
#include "Engine/Animations/Curve.h"
#define VISJECT_GRAPH_NODE_MAX_ASSETS 14
template<class BoxType>
class VisjectGraphNode;
@@ -94,7 +93,7 @@ public:
/// <summary>
/// The asset references. Linked resources such as Animation assets are referenced in graph data as ID. We need to keep valid refs to them at runtime to keep data in memory.
/// </summary>
AssetReference<Asset> Assets[VISJECT_GRAPH_NODE_MAX_ASSETS];
Array<AssetReference<Asset>> Assets;
};
/// <summary>
@@ -188,11 +187,10 @@ public:
#undef SETUP_CURVE
// Get Gameplay Global
case 16:
{
n->Assets.Resize(1);
n->Assets[0] = ::LoadAsset((Guid)n->Values[0], Asset::TypeInitializer);
break;
}
}
}
// Base