Skip to content

Commit

Permalink
[animgraph] Added smooth blending option to blendSpace2d
Browse files Browse the repository at this point in the history
  • Loading branch information
EspeuteClement committed Jan 31, 2025
1 parent b9ea44d commit f178f50
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 1 deletion.
5 changes: 5 additions & 0 deletions bin/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -4512,6 +4512,11 @@ blend-space-2d-root main-panel graph-container svg .preview-axis {
stroke: #008a00;
stroke-width: 2;
}
blend-space-2d-root main-panel graph-container svg .preview-axis-real {
fill: none;
stroke: #008a00;
stroke-width: 1;
}
blend-space-2d-root main-panel graph-container drag-handler {
z-index: 1;
position: absolute;
Expand Down
6 changes: 6 additions & 0 deletions bin/style.less
Original file line number Diff line number Diff line change
Expand Up @@ -5354,6 +5354,12 @@ blend-space-2d-root {
stroke: #008a00;
stroke-width: 2;
}

.preview-axis-real {
fill: none;
stroke: #008a00;
stroke-width: 1;
}
}

drag-handler {
Expand Down
36 changes: 36 additions & 0 deletions hide/view/animgraph/BlendSpace2DEditor.hx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ class BlendSpace2DEditor extends hide.view.FileView {

var animPreview : hrt.animgraph.AnimGraphInstance;

var previewBlendPos : hide.Element;

inline function getPointPos(clientX : Float, clientY : Float, snap: Bool) : h2d.col.Point {
var x = hxd.Math.clamp(graphXToLocal(clientX), blendSpace2D.minX, blendSpace2D.maxX);
var y = hxd.Math.clamp(graphYToLocal(clientY), blendSpace2D.minY, blendSpace2D.maxY);
Expand Down Expand Up @@ -418,7 +420,9 @@ class BlendSpace2DEditor extends hide.view.FileView {
<div class="group" name="BlendSpace">
<dl>
<dt>Min/MaxX</dt><dd><input type="number" field="minX"/><input type="number" field="maxX"/></dd>
<dt>Smooth X</dt><dd><input type="range" min="0.0" max="1.0" field="smoothX"/></dd>
<dt>Min/MaxY</dt><dd><input type="number" field="minY"/><input type="number" field="maxY"/></dd>
<dt>Smooth Y</dt><dd><input type="range" min="0.0" max="1.0" field="smoothY"/></dd>
</dl>
</div>
'), blendSpace2D, (_) -> {
Expand Down Expand Up @@ -552,6 +556,21 @@ class BlendSpace2DEditor extends hide.view.FileView {

}

var queuedRequest : Int = -1;
function onRequestAnimationFrame(dt: Float) {
if (previewBlendPos != null && animPreview != null) {
var root : hrt.animgraph.nodes.BlendSpace2D.BlendSpace2D = cast @:privateAccess animPreview.rootNode;
var rx = @:privateAccess root.realX;
var ry = @:privateAccess root.realY;
previewBlendPos.attr("transform", 'translate(${localXToGraph(rx)}, ${localYToGraph(ry)})');

queuedRequest = js.Browser.window.requestAnimationFrame(onRequestAnimationFrame);
trace(haxe.Timer.stamp());
return;
}
queuedRequest = -1;
}

function createPoint() {

}
Expand Down Expand Up @@ -669,6 +688,23 @@ class BlendSpace2DEditor extends hide.view.FileView {
final size = 10;
graph.line(g, -size, -size, size, size).addClass("preview-axis");
graph.line(g, -size, size, size, -size).addClass("preview-axis");

if (animPreview != null) {
var root : hrt.animgraph.nodes.BlendSpace2D.BlendSpace2D = cast @:privateAccess animPreview.rootNode;
var rx = @:privateAccess root.realX;
var ry = @:privateAccess root.realY;

previewBlendPos = graph.group(graph.element);
previewBlendPos.attr("transform", 'translate(${localXToGraph(rx)}, ${localYToGraph(ry)})');
final size = 10;
graph.line(previewBlendPos, -size, -size, size, size).addClass("preview-axis-real");
graph.line(previewBlendPos, -size, size, size, -size).addClass("preview-axis-real");

if (queuedRequest < 0) {
queuedRequest = js.Browser.window.requestAnimationFrame(onRequestAnimationFrame);
}
}

}
}

Expand Down
4 changes: 4 additions & 0 deletions hrt/animgraph/BlendSpace2D.hx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@ class BlendSpace2D extends hrt.prefab.Prefab {

@:s var minX = 0.0;
@:s var maxX = 1.0;
@:s var smoothX = 0.0;

@:s var minY = 0.0;
@:s var maxY = 1.0;
@:s var smoothY = 0.0;


var instance : BlendSpace2DInstance;

Expand Down
54 changes: 53 additions & 1 deletion hrt/animgraph/nodes/BlendSpace2D.hx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ typedef AnimInfo = {
@:access(hrt.animgraph.BlendSpace2D)
class BlendSpace2D extends AnimNode {
@:input var bsX(default, set): Float = 0.5;
var realX : Float = 0.5;
var vX : Float = 0.0;

@:input var bsY(default, set): Float = 0.5;
var realY : Float = 0.5;
var vY : Float = 0.0;


@:s var path : String = "";

Expand Down Expand Up @@ -50,13 +56,39 @@ class BlendSpace2D extends AnimNode {
var workQuats : Array<h3d.Quat> = [new h3d.Quat(), new h3d.Quat(), new h3d.Quat()];
var refQuat = new h3d.Quat();


static function halfLifeToDamping(halfLife: Float) {
return (4.0 * 0.69314718056) / (halfLife + 1e-5);
}

static function fastNegexp(x: Float) : Float
{
return 1.0 / (1.0 + x + 0.48*x*x + 0.235*x*x*x);
}


inline static function criticalSpringDamper(x: Float, v: Float, xGloal: Float, vGoal: Float, halfLife: Float, dt: Float) : {x: Float, v: Float} {
final damping = halfLifeToDamping(halfLife);
final c = xGloal + (damping * vGoal) / (damping * damping ) / 4.0;
final half_damping = damping / 2.0;
final j0 = x - c;
final j1 = v + j0 * half_damping;
final eydt = fastNegexp(half_damping * dt);

return {x: eydt * (j0 + j1 * dt) + c, v: eydt *(v - j1*half_damping*dt)};
}


override function getBones(ctx: hrt.animgraph.nodes.AnimNode.GetBoneContext):Map<String, Int> {
var boneMap : Map<String, Int> = [];
animInfos = [];
points = [];
triangles = [];
currentTriangle = -1;

realX = bsX;
realY = bsY;

var curOurBoneId = 0;

if (blendSpace == null) {
Expand Down Expand Up @@ -137,6 +169,26 @@ class BlendSpace2D extends AnimNode {
override function tick(dt:Float) {
super.tick(dt);

if (blendSpace.smoothX > 0) {
var r = criticalSpringDamper(realX, vX, bsX, 0, blendSpace.smoothX, dt);
realX = r.x;
vX = r.v;

currentTriangle = -1;
} else {
realX = bsX;
}

if (blendSpace.smoothX > 0) {
var r = criticalSpringDamper(realY, vY, bsY, 0, blendSpace.smoothY, dt);
realY = r.x;
vY = r.v;

currentTriangle = -1;
} else {
realY = bsY;
}

for (animInfo in animInfos) {
// keep all the animations in sync
var scale = animInfo.selfSpeed;
Expand All @@ -159,7 +211,7 @@ class BlendSpace2D extends AnimNode {
return;

if (currentTriangle == -1) {
var curPos = inline new h2d.col.Point(bsX, bsY);
var curPos = inline new h2d.col.Point(realX, realY);

// find the triangle our curPos resides in
var collided = false;
Expand Down

0 comments on commit f178f50

Please sign in to comment.