From 7ffd94270de7fb4be7d6d2747ad387e7598d6139 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Espeute?= Date: Fri, 31 Jan 2025 17:30:51 +0100 Subject: [PATCH] [animGraph] Added prototype event handling for blendSpace2D --- hrt/animgraph/AnimGraph.hx | 4 ++-- hrt/animgraph/AnimGraphInstance.hx | 9 ++++++--- hrt/animgraph/Resource.hx | 4 ++-- hrt/animgraph/nodes/AnimNode.hx | 3 +++ hrt/animgraph/nodes/BlendSpace2D.hx | 27 +++++++++++++++++++++++++-- 5 files changed, 38 insertions(+), 9 deletions(-) diff --git a/hrt/animgraph/AnimGraph.hx b/hrt/animgraph/AnimGraph.hx index 51923d9c..8ef1de96 100644 --- a/hrt/animgraph/AnimGraph.hx +++ b/hrt/animgraph/AnimGraph.hx @@ -42,11 +42,11 @@ class AnimGraph extends hrt.prefab.Prefab { Get the animation "template" for this AnimGraph. This anim should be instanciated using getInstance() after that (or use the h3d.scene.Object.playAnimation() function that does this for you) **/ - public function getAnimation(previewNode: hrt.animgraph.nodes.AnimNode = null, resolver: hrt.animgraph.AnimGraphInstance.AnimResolver = null) : AnimGraphInstance { + public function getAnimation(previewNode: hrt.animgraph.nodes.AnimNode = null, modelCache: h3d.prim.ModelCache = null, resolver: hrt.animgraph.AnimGraphInstance.AnimResolver = null) : AnimGraphInstance { if (resolver == null && customResolverProvider != null) { resolver = customResolverProvider(this); } - return AnimGraphInstance.fromAnimGraph(this, previewNode, resolver); + return AnimGraphInstance.fromAnimGraph(this, previewNode, modelCache, resolver); } override function save() { diff --git a/hrt/animgraph/AnimGraphInstance.hx b/hrt/animgraph/AnimGraphInstance.hx index 11df671b..b719321a 100644 --- a/hrt/animgraph/AnimGraphInstance.hx +++ b/hrt/animgraph/AnimGraphInstance.hx @@ -28,6 +28,7 @@ class AnimGraphInstance extends h3d.anim.Animation { var defaultPoseNode = new hrt.animgraph.nodes.DefaultPose(); var resolver : AnimResolver = null; + var modelCache: h3d.prim.ModelCache; var tmpMatrix : h3d.Matrix = new h3d.Matrix(); @@ -35,20 +36,21 @@ class AnimGraphInstance extends h3d.anim.Animation { var editorSkipClone : Bool = false; #end - static function fromAnimGraph(animGraph:AnimGraph, outputNode: hrt.animgraph.nodes.AnimNode = null, resolver: AnimResolver) : AnimGraphInstance { + static function fromAnimGraph(animGraph:AnimGraph, outputNode: hrt.animgraph.nodes.AnimNode = null, modelCache: h3d.prim.ModelCache = null, resolver: AnimResolver) : AnimGraphInstance { outputNode ??= cast animGraph.nodes.find((node) -> Std.downcast(node, hrt.animgraph.nodes.Output) != null); if (outputNode == null) throw "Animgraph has no output node"; - var inst = new AnimGraphInstance(outputNode, resolver, animGraph.name, 1000, 1/60.0); + var inst = new AnimGraphInstance(outputNode, modelCache, resolver, animGraph.name, 1000, 1/60.0); return inst; } - public function new(rootNode: hrt.animgraph.nodes.AnimNode, resolver: AnimResolver = null, name: String, framesCount: Int, sampling: Float) { + public function new(rootNode: hrt.animgraph.nodes.AnimNode, modelCache: h3d.prim.ModelCache = null, resolver: AnimResolver = null, name: String, framesCount: Int, sampling: Float) { // Todo : Define a true length for the animation OR make so animations can have an undefined length super(name, framesCount, sampling); this.rootNode = rootNode; this.resolver = resolver ?? defaultResolver; + this.modelCache = modelCache ?? new h3d.prim.ModelCache(); defaultPoseNode = new hrt.animgraph.nodes.DefaultPose(); } @@ -149,6 +151,7 @@ class AnimGraphInstance extends h3d.anim.Animation { var ctx = new hrt.animgraph.nodes.AnimNode.GetBoneContext(); ctx.targetObject = base; ctx.resolver = resolver.bind(this, base); + ctx.modelCache = this.modelCache; var bones = getBones(ctx); if (bones != null) { diff --git a/hrt/animgraph/Resource.hx b/hrt/animgraph/Resource.hx index d5bbe818..6d0d9dc5 100644 --- a/hrt/animgraph/Resource.hx +++ b/hrt/animgraph/Resource.hx @@ -40,8 +40,8 @@ class Resource extends hxd.res.Resource { return animGraph; } - public function loadAnim(resolver: hrt.animgraph.AnimGraphInstance.AnimResolver = null) : AnimGraphInstance { - return load().getAnimation(resolver); + public function loadAnim(modelCache: h3d.prim.ModelCache = null, resolver: hrt.animgraph.AnimGraphInstance.AnimResolver = null) : AnimGraphInstance { + return load().getAnimation(modelCache, resolver); } public static var CACHE_VERSION = 0; diff --git a/hrt/animgraph/nodes/AnimNode.hx b/hrt/animgraph/nodes/AnimNode.hx index 77498acf..dd182977 100644 --- a/hrt/animgraph/nodes/AnimNode.hx +++ b/hrt/animgraph/nodes/AnimNode.hx @@ -10,6 +10,7 @@ class GetBoneContext { public var targetObject:h3d.scene.Object; public var resolver : (path: String) -> Null; + public var modelCache : h3d.prim.ModelCache; } class GetBoneTransformContext { @@ -52,6 +53,8 @@ class AnimNode extends Node { var numAnimInput : Int; var boneIdToAnimInputBone : Array; + var onEvent : (String) -> Void; + inline function getInputBoneId(boneId: Int, inputId: Int) { return boneId * numAnimInput + inputId; } diff --git a/hrt/animgraph/nodes/BlendSpace2D.hx b/hrt/animgraph/nodes/BlendSpace2D.hx index 8a5661fa..05c9fd8e 100644 --- a/hrt/animgraph/nodes/BlendSpace2D.hx +++ b/hrt/animgraph/nodes/BlendSpace2D.hx @@ -31,6 +31,8 @@ class BlendSpace2D extends AnimNode { var dirtyPos: Bool = true; + var prevAnimEventBind : h3d.anim.Animation; + function set_bsX(v: Float) : Float { if (v != bsX) currentTriangle = -1; @@ -118,8 +120,8 @@ class BlendSpace2D extends AnimNode { function makeAnim() : Int { // Create a new animation var index = animInfos.length; - var animBase = hxd.res.Loader.currentInstance.load(path).toModel().toHmd().loadAnimation(); - + var animModel = hxd.res.Loader.currentInstance.load(path).toModel(); + var animBase = ctx.modelCache.loadAnimation(animModel); var proxy = new hrt.animgraph.nodes.Input.AnimProxy(null); var animInstance = animBase.createInstance(proxy); @@ -272,6 +274,20 @@ class BlendSpace2D extends AnimNode { if (currentTriangle == -1) throw "assert"; + var max = 0; + for (i in 1...3) { + if (weights[i] > weights[max]) { + max = i; + } + } + + var strongestAnim = triangles[currentTriangle][max].animInfo?.anim; + if (prevAnimEventBind != strongestAnim) { + prevAnimEventBind?.onEvent = null; + strongestAnim?.onEvent = animEventHander; + prevAnimEventBind = strongestAnim; + } + currentAnimLenght = 0.0; // Compensate for null animations that don't have length @@ -349,6 +365,13 @@ class BlendSpace2D extends AnimNode { outMatrix._23 = workQuat.w; } + function animEventHander(name: String) { + trace("event", name); + if (onEvent != null) { + onEvent(name); + } + } + #if editor override function getPropertiesHTML(width:Float):Array { var elts = super.getPropertiesHTML(width);