Can we assign ACE curves from one property to another?

Hi,

I’ve found a workflow that really works well for me – I animate nulls in Houdini, write it out to a GLTF, open the animations in ACE and then save it to a snippet server. From that point on, I get rid of the GLTF loading and simply load animations directly from the snippet server.

What I am trying to figure out is how to take an animation curve that comes out of Houdini – for example, scaling – and then apply it to another property, like, say visibility. I read the ACE documentation and didn’t see anything about copying and pasting curves int the editor, so maybe there is some way in code to load a snippet that is meant to drive scaling property and have it instead drive the visibility property.

If that isn’t possible either in the ACE editor or in code, I guess worst case I can write out my animations as JSON and then manually change the name of the channel in the JSON file.

Thanks!!!

Hey! You should jsut copy the animation groups. If you can give us a repro of what you have in the playground, we can show you how to clone your animation groups (and change the property target)

Sure, here is a playground where I have already converted the Houdini scaling animation into a snippet:

P.S. I tried the manual renaming of a ACE-generated JSON file but it didn’t seem to work – I think because scaling is a Vec3 and visibility is a scalar?

Exactly, the key format is not the same (as you want 3 values for a vector)

If you want to do that you have to have an initial animation that is animating a vec3

Ah, well it was the other way around – I was animating uniform scale in Houdini (which came over as sx sy sz) and I just wanted to grab one of those curves to use for the scalar animation of visibility.

I can’t find any documentation anywhere but I think the only animations that come out of Houdini’s GLTF exporter are vec3 (translation, rotation, scale). I can also export a custom vertex attribute for Alpha (similar to animated COLOR) but I don’t think custom vertex attributes are readable in Babylon.

Anyways, looking forward to seeing how to clone animation groups and change the target! Will start reading up on animation groups now…

(Meanwhile, triple-checking the ACE documentation to see if I can’t just literally copy-and-paste a curve from one channel/property to another and I came across this gem:)

There is no hotkey to play the animation in the reverse direction, because we are not animals.

:slight_smile:

1 Like

LOL!

You can clone any animation group with the clone method:
AnimationGroup | Babylon.js Documentation

Then inside each animation group you have a list of targeted animations. You can take each targeted animation and then change the target property :slight_smile:
TargetedAnimation | Babylon.js Documentation

Great! I do like using ACE curve editor for a quick and dirty workflow but this will allow me to get exactly the animation I need from Hou via just a snippet hash.

Thanks so much!

1 Like

One follow-up question – is there anything special I need to do if I want to assign, say, scale.x to visibility?

That is, if the incoming targeted animation is vec3 but the new target is scalar?

Or should it just work out of the box? I am getting an error when I try (not cloning animation group, just attempted to change target property in-place):

It cannot work as the animation is a vec3 animation and it will try to affect a vec3 to a float.

Only type compatible animations can be retargeted :frowning:

Ah bummer… I dont know what other things from GLTF come out as a single float… I guess maybe I can try running some AWK script on the JSON to delete all but the first channel of one of these Vec3 animations…

Thanks anyways!!!

What happens if you try reassigning the key values? Like near line 30:

animations[0].getKeys().forEach(k=>k.value = k.value.x)

That’s cool to see! Unfortunately no dice… since I am not able to access the x element of a vector3 in this case, I think it might actually be better to write my own exporter… that JSON format doesn’t look toooooo tricky!

Quick question on the JSON if anybody knows… I see this code in the JSON parsing file:

            switch (dataType) {
                case Animation.ANIMATIONTYPE_FLOAT:
                    key.values = [animationKey.value];
                    if (animationKey.inTangent !== undefined) {
                        key.values.push(animationKey.inTangent);
                    }
                    if (animationKey.outTangent !== undefined) {
                        if (animationKey.inTangent === undefined) {
                            key.values.push(undefined);
                        }
                        key.values.push(animationKey.outTangent);
                    }
                    if (animationKey.interpolation !== undefined) {
                        if (animationKey.inTangent === undefined) {
                            key.values.push(undefined);
                        }
                        if (animationKey.outTangent === undefined) {
                            key.values.push(undefined);
                        }
                        key.values.push(animationKey.interpolation);
                    }
                    break;

I’m just wondering why some keys seem to have interpolation method specified and some don’t… here is my test JSON I am using as a model for my exporter, the first two keys have interpolation method specified but the last one doesn’t:

{                                                                                                                                                                                                                                                             
  "animations": [
    {
      "name": "visibilityAnim",
      "property": "visibility",
      "framePerSecond": 60,
      "dataType": 0,
      "loopBehavior": 1,
      "blendingSpeed": 0.01,
      "keys": [
        {
          "frame": 0,
          "values": [
            0,
            0,
            0,
            0
          ]
        },
        {
          "frame": 44.930459786978076,
          "values": [
            0,
            0,
            0,
            0
          ]
        },
        {
          "frame": 100,
          "values": [
            1,
            0,
            0
          ]
        }
      ],
      "ranges": []
    }
  ]
}

The code I offered does in fact access the .x element of the vector3 and assign it to the key value. Afterward, all values of the keys are float. What am I missing?

I did notice many x values are greater than 1, though.

Hmm, let me try your method again, I’m not sure what I did wrong…

I also had to set the dataType.

Changed:

  • dataType to FLOAT
  • max animation value near 1.0 (divided all by 6.15)
  • to arcrotatecamera
  • visibility start 0.00001
  • animation loop
  • animation through key frame 600

Aha! That one thing! Cool cool! Good to know this is possible, thank you very much for showing me how to do that!!!

1 Like