0
votes

I am attempting to animate a material property that is buried inside of a gltf-model (that has many objects). I can find the parameter and animate it with a tick event, and it looks like this

https://glitch.com/~uv-reveal-wave

It almost works, but animating with formulas is a nightmare. Instead I want to control it with the animation component. Unfortunately, exposing the parameter directly seems impossible, as I have to use getObject3D.traverse() just to locate the object, and then get the parameter.

Instead I have made a custom attribute (in schema) and and animating that attribute. And in the update function, I'm using that attribute to drive the buried parameter. It should work, but I can't seem to get a response in the update function. Iow, my custom attribute is not animating.

AFRAME.registerComponent('matclipplane', { // attached to gltf-model tree
      schema:{
          clipHeightA:{type: 'number', default: 0}
      },
      init: function () {
       let el = this.el;
       let comp = this;
       comp.treeModels = [];
       el.addEventListener('model-loaded', function(ev){
          let mesh = el.getObject3D('mesh'); 
          mesh.traverse(function(node){
             if (node.isMesh){
               comp.treeModels.push(node);
             }
          comp.modelLoaded = true;
         });
...
 update: function(){  
        console.log("update");  // returns nothing. no update from 
                                   animating attributes clipHeightA          
        let comp = this;
        if (comp.modelLoaded){          
          comp.treeModels[1].material.map.offset.y = 
                             this.data.clipHeightA;
        }
     }
...
AFRAME.registerComponent("click-listener", { // attached to box button
        schema:{
            dir:{type:"boolean", default: false}
        },
        init: function(){
            let el=this.el;
            let data = this.data;
            el.addEventListener("click", function(evt){
                let tree = document.querySelector('#tree');

               data.dir = !data.dir;
               if(data.dir){
                   el.setAttribute("material",'color', 'orange');
                   tree.emit("grow");
               } else {
                   el.setAttribute('material','color','#332211');
                   tree.emit('shrink');
               }
            });
        }
    });
<a-entity id="tree" gltf-model="#tree" scale="5 5 5" 
        animation__grow="property: clipHeightA; from: 0; to: 1; 
startEvents: grow; dur: 500"
        matclipplane></a-entity>

<a-entity id="button" geometry="primitive: box" material="color:orange;  
metalness: 0.5" scale="0.2 0.2 0.2" class="clickable" click-listener></a- 
entity>

<a-entity id="mouseCursor" cursor="rayOrigin: mouse" raycaster="objects: 
.clickable"></a-entity>

here is the glitch in progress https://glitch.com/~uv-reveal

Clicking on the orange cube should launch the uv reveal animation. I expect that calling a custom component attribute should trigger an update event, but the update does not log in the console. Not sure how to animate a parameter inside a gltf. Do I have to implement the animejs component directly inside my custom component? Or can this be done with the animate component?

1

1 Answers

0
votes

According to the docs you can animate properties through

  • object3D like animation="property: object3D.x"
  • components like animation="property: components.myComp.myProp"


animation__grow="property: matclipplane.clipHeightA;"

glitch here. You can see update is being called.


treegrow