Fix crash when using curves inside Anim Graph
https://forum.flaxengine.com/t/bug-report-v1-12-using-curves-in-the-animation-graph-causes-a-crash/2594
This commit is contained in:
@@ -61,14 +61,14 @@ void AnimGraphBase::Clear()
|
||||
StateTransitions.Resize(0);
|
||||
|
||||
// Base
|
||||
GraphType::Clear();
|
||||
VisjectGraph::Clear();
|
||||
}
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
void AnimGraphBase::GetReferences(Array<Guid>& output) const
|
||||
{
|
||||
GraphType::GetReferences(output);
|
||||
VisjectGraph::GetReferences(output);
|
||||
|
||||
// Collect references from nested graph (assets used in state machines)
|
||||
for (const auto* subGraph : SubGraphs)
|
||||
|
||||
@@ -163,7 +163,7 @@ VisjectExecutor::Value VisualScriptExecutor::eatBox(Node* caller, Box* box)
|
||||
|
||||
// Add to the calling stack
|
||||
VisualScripting::StackFrame frame = *stack.Stack;
|
||||
frame.Node = parentNode;
|
||||
frame.Node = (VisualScriptGraphNode*)parentNode;
|
||||
frame.Box = box;
|
||||
frame.PreviousFrame = stack.Stack;
|
||||
stack.Stack = &frame;
|
||||
@@ -189,7 +189,7 @@ VisjectExecutor::Value VisualScriptExecutor::eatBox(Node* caller, Box* box)
|
||||
VisjectExecutor::Graph* VisualScriptExecutor::GetCurrentGraph() const
|
||||
{
|
||||
auto& stack = ThreadStacks.Get();
|
||||
return stack.Stack && stack.Stack->Script ? &stack.Stack->Script->Graph : nullptr;
|
||||
return stack.Stack && stack.Stack->Script ? (Graph*)&stack.Stack->Script->Graph : nullptr;
|
||||
}
|
||||
|
||||
void VisualScriptExecutor::ProcessGroupParameters(Box* box, Node* node, Value& value)
|
||||
@@ -432,7 +432,7 @@ void VisualScriptExecutor::ProcessGroupFunction(Box* boxBase, Node* node, Value&
|
||||
// Call Impulse or Pure Method
|
||||
if (boxBase->ID == 0 || (bool)node->Values[3])
|
||||
{
|
||||
auto& cache = node->Data.InvokeMethod;
|
||||
auto& cache = ((VisualScriptGraphNode*)node)->Data.InvokeMethod;
|
||||
if (!cache.Method)
|
||||
{
|
||||
// Load method signature
|
||||
@@ -667,7 +667,7 @@ void VisualScriptExecutor::ProcessGroupFunction(Box* boxBase, Node* node, Value&
|
||||
// Get Field
|
||||
case 7:
|
||||
{
|
||||
auto& cache = node->Data.GetSetField;
|
||||
auto& cache = ((VisualScriptGraphNode*)node)->Data.GetSetField;
|
||||
if (!cache.Field)
|
||||
{
|
||||
const auto typeName = (StringView)node->Values[0];
|
||||
@@ -753,7 +753,7 @@ void VisualScriptExecutor::ProcessGroupFunction(Box* boxBase, Node* node, Value&
|
||||
// Get Field
|
||||
case 8:
|
||||
{
|
||||
auto& cache = node->Data.GetSetField;
|
||||
auto& cache = ((VisualScriptGraphNode*)node)->Data.GetSetField;
|
||||
if (!cache.Field)
|
||||
{
|
||||
const auto typeName = (StringView)node->Values[0];
|
||||
|
||||
@@ -12,11 +12,47 @@
|
||||
#define VISUAL_SCRIPT_GRAPH_MAX_CALL_STACK 250
|
||||
#define VISUAL_SCRIPT_DEBUGGING USE_EDITOR
|
||||
|
||||
#define VisualScriptGraphNode VisjectGraphNode<>
|
||||
|
||||
class VisualScripting;
|
||||
class VisualScriptingBinaryModule;
|
||||
|
||||
/// <summary>
|
||||
/// Visual Script graph node.
|
||||
/// </summary>
|
||||
class VisualScriptGraphNode : public VisjectGraphNode<>
|
||||
{
|
||||
public:
|
||||
struct InvokeMethodData
|
||||
{
|
||||
void* Method;
|
||||
BinaryModule* Module;
|
||||
int32 ParamsCount;
|
||||
uint32 OutParamsMask;
|
||||
bool IsStatic;
|
||||
};
|
||||
|
||||
struct GetSetFieldData
|
||||
{
|
||||
void* Field;
|
||||
BinaryModule* Module;
|
||||
bool IsStatic;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Custom cached data per node type. Compact to use as small amount of memory as possible.
|
||||
/// </summary>
|
||||
struct AdditionalData
|
||||
{
|
||||
union
|
||||
{
|
||||
InvokeMethodData InvokeMethod;
|
||||
GetSetFieldData GetSetField;
|
||||
};
|
||||
};
|
||||
|
||||
// The custom per-node data. Used to cache data for faster usage at runtime.
|
||||
AdditionalData Data;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The Visual Script graph data.
|
||||
/// </summary>
|
||||
|
||||
@@ -167,6 +167,15 @@ public:
|
||||
// Base
|
||||
return Base::onNodeLoaded(n);
|
||||
}
|
||||
void Clear() override
|
||||
{
|
||||
FloatCurves.Clear();
|
||||
Float2Curves.Clear();
|
||||
Float3Curves.Clear();
|
||||
Float4Curves.Clear();
|
||||
|
||||
Base::Clear();
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -952,7 +952,7 @@ void VisjectExecutor::ProcessGroupTools(Box* box, Node* node, Value& value)
|
||||
#define SAMPLE_CURVE(id, curves, type, graphType) \
|
||||
case id: \
|
||||
{ \
|
||||
const auto& curve = GetCurrentGraph()->curves[node->Data.Curve.CurveIndex]; \
|
||||
const auto& curve = GetCurrentGraph()->curves[node->CurveIndex]; \
|
||||
const float time = (float)tryGetValue(node->GetBox(0), Value::Zero); \
|
||||
value.Type = VariantType(VariantType::graphType); \
|
||||
curve.Evaluate(*(type*)value.AsData, time, false); \
|
||||
|
||||
@@ -42,42 +42,6 @@ public:
|
||||
template<class BoxType = VisjectGraphBox>
|
||||
class VisjectGraphNode : public GraphNode<BoxType>
|
||||
{
|
||||
public:
|
||||
struct CurveData
|
||||
{
|
||||
/// <summary>
|
||||
/// The curve index.
|
||||
/// </summary>
|
||||
int32 CurveIndex;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Custom cached data per node type. Compact to use as small amount of memory as possible.
|
||||
/// </summary>
|
||||
struct AdditionalData
|
||||
{
|
||||
union
|
||||
{
|
||||
CurveData Curve;
|
||||
|
||||
struct
|
||||
{
|
||||
void* Method;
|
||||
BinaryModule* Module;
|
||||
int32 ParamsCount;
|
||||
uint32 OutParamsMask;
|
||||
bool IsStatic;
|
||||
} InvokeMethod;
|
||||
|
||||
struct
|
||||
{
|
||||
void* Field;
|
||||
BinaryModule* Module;
|
||||
bool IsStatic;
|
||||
} GetSetField;
|
||||
};
|
||||
};
|
||||
|
||||
public:
|
||||
VisjectGraphNode()
|
||||
: GraphNode<BoxType>()
|
||||
@@ -85,10 +49,7 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// The custom data (depends on node type). Used to cache data for faster usage at runtime.
|
||||
/// </summary>
|
||||
AdditionalData Data;
|
||||
int32 CurveIndex = MAX_uint16;
|
||||
|
||||
/// <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.
|
||||
@@ -148,7 +109,7 @@ public:
|
||||
#define SETUP_CURVE(id, curves, access) \
|
||||
case id: \
|
||||
{ \
|
||||
n->Data.Curve.CurveIndex = curves.Count(); \
|
||||
n->CurveIndex = curves.Count(); \
|
||||
auto& curve = curves.AddOne(); \
|
||||
const int32 keyframesCount = n->Values[0].AsInt; \
|
||||
auto& keyframes = curve.GetKeyframes(); \
|
||||
@@ -177,9 +138,17 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Base
|
||||
return Base::onNodeLoaded(n);
|
||||
}
|
||||
void Clear() override
|
||||
{
|
||||
FloatCurves.Clear();
|
||||
Float2Curves.Clear();
|
||||
Float3Curves.Clear();
|
||||
Float4Curves.Clear();
|
||||
|
||||
Base::Clear();
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user