Browse Source

add rotation interpolation

Nikolay Suslov 6 years ago
parent
commit
f477f5eb5b

+ 11 - 0
public/defaults/proxy/vwf.example.com/aframe/aentity.vwf.yaml

@@ -18,6 +18,16 @@ properties:
     get: |
       return this.position || goog.vec.Vec3.create();
   rotation:
+    set: |
+      var rotation = this.translationFromValue( value ); // parse incoming value
+      if(!rotation || !this.rotation){
+        this.rotation = goog.vec.Vec3.create();
+      } else if ( ! goog.vec.Vec3.equals( this.rotation || goog.vec.Vec3.create(), rotation ) ) {
+        this.rotation = rotation;
+        this.rotationChanged( rotation);
+      }  
+    get: |
+      return this.rotation || goog.vec.Vec3.create();
   scale:
   clickable:
   displayName:
@@ -26,6 +36,7 @@ properties:
   osc:
 events:
   positionChanged:
+  rotationChanged:  
 methods:
   setGizmoMode:
     parameters:

+ 18 - 6
public/defaults/proxy/vwf.example.com/aframe/avatar.js

@@ -72,7 +72,7 @@ this.createAvatarBody = function (nodeDef, modelSrc) {
                         "extends": "http://vwf.example.com/aframe/interpolation-component.vwf",
                         "type": "component",
                         "properties": {
-                            "enabled": false
+                            "enabled": true
                         }
                     },
                     "visual": {
@@ -271,11 +271,22 @@ this.followAvatarControl = function (position, rotation) {
    // this.position = AFRAME.utils.coordinates.stringify(position);
     this.position = goog.vec.Vec3.createFromValues(position.x, position.y, position.z);
 
-    let myRot = AFRAME.utils.coordinates.parse(this.rotation);
-    let myHeadRot = AFRAME.utils.coordinates.parse(this.avatarNode.myHead.rotation);
-    let myBodyRot = AFRAME.utils.coordinates.parse(this.avatarNode.myBody.rotation);
+    let myRot = goog.vec.Vec3.clone(this.rotation);
+    let myHeadRot = goog.vec.Vec3.clone(this.avatarNode.myHead.rotation);
+    let myBodyRot = goog.vec.Vec3.clone(this.avatarNode.myBody.rotation);
+
+    //let myRot = AFRAME.utils.coordinates.parse(this.rotation);
+    //let myHeadRot = AFRAME.utils.coordinates.parse(this.avatarNode.myHead.rotation);
+    //let myBodyRot = AFRAME.utils.coordinates.parse(this.avatarNode.myBody.rotation);
+
+    //   if(myRot[0] == null || myRot[2] == null) {
+    //     debugger
+    // }
+
+    this.rotation = [myRot[0], rotation.y, myRot[2]];
+    //this.rotation = [myRot.x, rotation.y, myRot.z];
+
 
-    this.rotation = [myRot.x, rotation.y, myRot.z];
 
     // let myRot = this.avatarBodyModel.rotation;
     // this.avatarBodyModel.rotation = [myRot.x, -rotation.y, myRot.z];
@@ -284,7 +295,8 @@ this.followAvatarControl = function (position, rotation) {
 
     //this.avatarNameNode.rotation = [myRot.x, myRot.y, rotation.z]; 
 
-    this.avatarNode.myHead.rotation = [rotation.x, myHeadRot.y, rotation.z];
+    this.avatarNode.myHead.rotation = [rotation.x, myHeadRot[1], rotation.z];
+    //this.avatarNode.myHead.rotation = [rotation.x, myHeadRot.y, rotation.z];
     
     // this.avatarNode.myCursor.rotation = [rotation.x, myHeadRot.y, rotation.z];
 

+ 6 - 6
public/defaults/worlds/aframe/index.vwf.yaml

@@ -69,12 +69,12 @@ children:
       intersectEventMethod:
         body: |
           if (this.clickable) {
-          this.rotation = "0 -90 0"
+          this.rotation = [0, -90, 0]
             }
       clearIntersectEventMethod:
         body: |
           if (this.clickable) {
-          this.rotation = "0 -30 0"
+          this.rotation = [0, -30, 0]
             }
       generateColor:
         body: |
@@ -123,10 +123,10 @@ children:
           run:
             body: |
               var time = vwf.now;
-              let rot = AFRAME.utils.coordinates.parse(this.rotation);
-              let pos = AFRAME.utils.coordinates.parse(this.position);
-              this.position = [pos.x, pos.y, Math.sin(time)];
-              this.rotation = [rot.x, rot.y, Math.sin(time)*100];
+              let rot = this.rotation; //AFRAME.utils.coordinates.parse(this.rotation);
+              let pos = this.position; //AFRAME.utils.coordinates.parse(this.position);
+              this.position = [pos[0], pos[1], Math.sin(time)];
+              this.rotation = [rot[0], rot[1], Math.sin(time)*100];
               this.future( 0.01 ).run();  // schedule the next step
 methods:
   initialize:

+ 4 - 4
public/defaults/worlds/aframe2/index.vwf.yaml

@@ -120,12 +120,12 @@ children:
       intersectEventMethod:
         body: |
           if (this.clickable) {
-          this.rotation = "0 -90 0"
+          this.rotation = [0, -90, 0]
             }
       clearIntersectEventMethod:
         body: |
           if (this.clickable) {
-          this.rotation = "0 -30 0"
+          this.rotation = [0, -30, 0]
             }
       generateColor:
         body: |
@@ -181,8 +181,8 @@ children:
           run:
             body: |
               var time = vwf.now;
-              let pos = AFRAME.utils.coordinates.parse(this.position);
-              this.position = [pos.x, pos.y, Math.sin(time)]
+              let pos = this.position; //AFRAME.utils.coordinates.parse(this.position);
+              this.position = [pos[0], pos[1], Math.sin(time)]
               this.future( 0.01 ).run();  // schedule the next step
   sky:
     extends: http://vwf.example.com/aframe/asky.vwf

+ 10 - 6
public/defaults/worlds/ohmlang-lsys/index.vwf.yaml

@@ -43,6 +43,10 @@ children:
             lsys: ''
             readyForDraw: true
         children:
+            interpolation:
+                extends: http://vwf.example.com/aframe/interpolation-component.vwf
+                properties:
+                    enabled: true
             material:
                 extends: http://vwf.example.com/aframe/aMaterialComponent.vwf
                 properties:
@@ -180,18 +184,18 @@ children:
                 parameters:
                     - step
                 body: |
-                    let pos = Object.assign({}, this.drawNode.position);
-                    var x0 = pos.x;
-                    var y0 = pos.y;
+                    let pos = this.drawNode.position;
+                    var x0 = pos[0];
+                    var y0 = pos[1];
                     var xx = Math.sin(this.angleInRadians);
                     var yy = Math.cos(this.angleInRadians);
-                    let startPosition = Object.assign({}, this.drawNode.position);
-                    let endPosition = {x: x0 + step * xx, y: y0 + step * yy, z: pos.z};
+                    let startPosition = {x: pos[0], y: pos[1], z:pos[2]};
+                    let endPosition = {x: x0 + step * xx, y: y0 + step * yy, z: pos[2]};
                     var drawPath = this.drawNode.linepath.path;
                     drawPath.push(startPosition);
                     drawPath.push(endPosition);
                     vwf_view.kernel.setProperty(this.drawNode.linepath.id, 'path', drawPath);
-                    this.drawNode.position = endPosition;
+                    this.drawNode.position = [endPosition.x, endPosition.y, endPosition.z];
             setTurtleParams:
                 parameters:
                     - val

+ 72 - 15
public/vwf/model/aframe.js

@@ -195,8 +195,11 @@ define(["module", "vwf/model", "vwf/utility"], function (module, model, utility)
                 node.aframeObj = createAFrameObject(node);
                 addNodeToHierarchy(node);
 
-                if (isAEntityDefinition(node.prototypes))
-                    updateStoredTransform( node );
+                if (isAEntityDefinition(node.prototypes)) {
+                    //updateStoredTransform( node );
+                    updateStoredTransformFor(node,'position');
+                    updateStoredTransformFor(node,'rotation');
+                }
 
                 //notifyDriverOfPrototypeAndBehaviorProps();
                 //  }
@@ -357,16 +360,22 @@ define(["module", "vwf/model", "vwf/utility"], function (module, model, utility)
 
                         case "position":
 
-                        var position = translationFromValue(propertyValue || []); //goog.vec.Vec3.createFromArray( propertyValue || [] );
+                        var position = setFromValue(propertyValue || []); //goog.vec.Vec3.createFromArray( propertyValue || [] );
                             node.transform.position = goog.vec.Vec3.clone(position);
                             //value = propertyValue;
-                            node.storedTransformDirty = true; 
+                            node.transform.storedPositionDirty = true; 
                             //setTransformsDirty( threeObject );
                             //this.state.setAFrameProperty('position', propertyValue, aframeObject);
                             break;
 
                         case "rotation":
-                            this.state.setAFrameProperty('rotation', propertyValue, aframeObject);
+
+                            var rotation = setFromValue(propertyValue || []); //goog.vec.Vec3.createFromArray( propertyValue || [] );
+                            node.transform.rotation = goog.vec.Vec3.clone(rotation);
+                            //value = propertyValue;
+                            node.transform.storedRotationDirty = true; 
+
+                            //this.state.setAFrameProperty('rotation', propertyValue, aframeObject);
                             break;
 
                         case "scale":
@@ -375,7 +384,11 @@ define(["module", "vwf/model", "vwf/utility"], function (module, model, utility)
 
 
                         case "animationTimeUpdated":
-                                node.storedTransformDirty = true; 
+                                if (node.transform) {
+                                    node.transform.storedPositionDirty = true; 
+                                    node.transform.storedRotationDirty = true;
+                                }
+                                
                         break;
 
                         case "clickable":
@@ -841,8 +854,8 @@ define(["module", "vwf/model", "vwf/utility"], function (module, model, utility)
 
                             if (node.transform.position) {
 
-                            if ( node.storedTransformDirty ) {
-                                updateStoredTransform( node );
+                            if ( node.transform.storedPositionDirty ) {
+                                updateStoredTransformFor( node, 'position' );
                             }
 
                             value = goog.vec.Vec3.clone(node.transform.position);
@@ -850,6 +863,25 @@ define(["module", "vwf/model", "vwf/utility"], function (module, model, utility)
                         }
                             break;
 
+                        case "rotation":
+
+                        if (node.transform.rotation) {
+
+                            if ( node.transform.storedRotationDirty ) {
+                                updateStoredTransformFor( node, 'rotation' );
+                            }
+
+                            value = goog.vec.Vec3.clone(node.transform.rotation);
+
+                            // var rot = aframeObject.getAttribute('rotation');
+                            // if (rot !== undefined) {
+                            //     value = rot//AFRAME.utils.coordinates.stringify(rot);
+                            // }
+                        }
+
+                            break;
+
+
                         case "scale":
                             var scale = aframeObject.getAttribute('scale');
                             if (scale !== undefined) {
@@ -857,12 +889,7 @@ define(["module", "vwf/model", "vwf/utility"], function (module, model, utility)
                             }
                             break;
 
-                        case "rotation":
-                            var rot = aframeObject.getAttribute('rotation');
-                            if (rot !== undefined) {
-                                value = rot//AFRAME.utils.coordinates.stringify(rot);
-                            }
-                            break;
+                      
 
                         case "clickable":
                             value = node.events.clickable;
@@ -1340,7 +1367,7 @@ define(["module", "vwf/model", "vwf/utility"], function (module, model, utility)
     }
 
 
-    function translationFromValue ( propertyValue ) {
+    function setFromValue ( propertyValue ) {
 
         var value = goog.vec.Vec3.create();
       if (propertyValue.hasOwnProperty('x')) {
@@ -1376,6 +1403,36 @@ define(["module", "vwf/model", "vwf/utility"], function (module, model, utility)
     }    
 
 
+    function updateStoredTransformFor( node, propertyName ) {
+        
+        if ( node && node.aframeObj) {
+            // Add a local model-side transform that can stay pure even if the view changes the
+            // transform on the threeObject - this already happened in creatingNode for those nodes that
+            // didn't need to load a model
+            if(!node.transform)
+                node.transform = {};
+
+            if (propertyName == 'position'){
+                let pos = (new THREE.Vector3()).copy(node.aframeObj.object3D.position);
+                node.transform.position = goog.vec.Vec3.createFromValues(pos.x, pos.y, pos.z);
+                node.transform.storedPositionDirty = false; 
+            }
+           
+            if (propertyName == 'rotation'){
+               // let rot = (new THREE.Vector3()).copy(node.aframeObj.object3D.rotation);
+               let rot = node.aframeObj.getAttribute('rotation');
+                node.transform.rotation = goog.vec.Vec3.createFromValues(rot.x, rot.y, rot.z);
+                node.transform.storedRotationDirty = false;   
+            }
+
+            //node.transform.position = AFRAME.utils.coordinates.stringify(node.aframeObj.object3D.position);
+
+            // node.transform.rotation = AFRAME.utils.coordinates.stringify(node.aframeObj.object3D.rotation);
+            // node.storedTransformDirty = false;             
+        }
+      
+    }   
+
 
 
     function getPrototypes(kernel, extendsID) {

+ 39 - 19
public/vwf/model/aframe/addon/aframe-interpolation.js

@@ -60,7 +60,8 @@ AFRAME.registerComponent('interpolation', {
 
     if (this.enabled && this.node && this.node.interpolate) {
       this.setInterpolatedTransforms(timepassed);
-      //this.restoreTransforms();
+
+     // this.restoreTransforms();
 
     }
     this.lastTime = now;
@@ -78,14 +79,16 @@ AFRAME.registerComponent('interpolation', {
     }
   },
 
-  matCmp: function (a,b,delta) {
-    for(var i =0; i < 2; i++) {
-        if(Math.abs(a[i] - b[i]) > delta)
-            return false;
-    }
-    
-    return true;
-},
+  vecCmpThreeJS: function (a, b, delta) {
+
+    let distance = a.distanceTo(b);
+    //let distance = goog.vec.Vec3.distance(a,b);
+     if (distance > delta) {
+       return false;
+     }
+ 
+     return true;
+   },
 
   vecCmp: function (a, b, delta) {
 
@@ -102,10 +105,21 @@ AFRAME.registerComponent('interpolation', {
 
     var now = this.node.interpolate.position.selfTick;
 
-    if (now && this.node.needTransformRestore) {
+    if (now && this.node.needPositionRestore) {
       let pos = goog.vec.Vec3.clone(now);
       this.el.object3D.position.set(pos[0], pos[1], pos[2]);
-      this.node.needTransformRestore = false;
+      this.node.needPositionRestore = false;
+    }
+
+    var rNow = this.node.interpolate.rotation.selfTick;
+
+    if(rNow && this.node.needRotationRestore) {
+      let r = new THREE.Euler();
+      let rot = r.copy(rNow);
+
+      this.el.object3D.rotation.set(rot.x, rot.y, rot.z)
+      this.node.needRotationRestore = false;
+
     }
 
 
@@ -140,7 +154,7 @@ AFRAME.registerComponent('interpolation', {
 
     
     this.interpolatePosition(step);
-    //this.interpolateRotation(step);
+    this.interpolateRotation(step);
 
     // if (this.node.tickTime == 0){
     //   this.restoreTransforms();
@@ -159,7 +173,7 @@ AFRAME.registerComponent('interpolation', {
 
     if (last && now) {
 
-      let comp = this.vecCmp(last.toVector3(), now.toVector3(), this.deltaRot);
+      let comp = this.vecCmpThreeJS(last.toVector3(), now.toVector3(), this.deltaRot);
 
       if (!comp) {
 
@@ -183,8 +197,9 @@ AFRAME.registerComponent('interpolation', {
         THREE.Quaternion.slerp(lastV, nowV, q, step || 0);
         let interp = e.setFromQuaternion(q, 'YXZ');
 
-        this.el.object3D.rotation.set(interp.x, interp.y, interp.z);
-        this.node.needTransformRestore = true;
+        //this.el.object3D.rotation.set(interp.x, interp.y, interp.z);
+        this.setRotation(interp);
+        this.node.needRotationRestore = true;
       }
     }
   },
@@ -218,18 +233,23 @@ AFRAME.registerComponent('interpolation', {
 
         //this.el.object3D.position.set(interp.x, interp.y, interp.z);
        
-        this.setTransform(interp);
-        
-        this.node.needTransformRestore = true;
+        this.setPosition(interp);
+        this.node.needPositionRestore = true;
       }
     }
   },
 
-  setTransform: function (interp) {
+  setPosition: function (interp) {
     let vec = goog.vec.Vec3.clone(interp);
     this.el.object3D.position.set(vec[0], vec[1], vec[2]);
 },
 
+setRotation: function (interp) {
+  let vec = (new THREE.Euler()).copy(interp);
+  this.el.object3D.rotation.set(vec.x, vec.y, vec.z);
+},
+
+
   pause: function () { },
   play: function () { }
 });

+ 43 - 4
public/vwf/view/aframe.js

@@ -156,8 +156,13 @@ define(["module", "vwf/view"], function (module, view) {
             }
 
             if (propertyName == 'position')
+            {
+                receiveModelTransformChanges( nodeId, 'position', propertyValue );
+            }
+            
+            if (propertyName == 'rotation')
                {
-                receiveModelTransformChanges( nodeId, propertyValue );
+                receiveModelTransformChanges( nodeId, 'rotation', propertyValue );
                }
 
             // if (node.aframeObj.nodeName == "AUDIO" && propertyName == 'itemSrc') {
@@ -472,7 +477,7 @@ define(["module", "vwf/view"], function (module, view) {
     // 1.1 Elseif (other external changes and no outstanding own view changes) then ADOPT
     // 1.2 Else Interpolate to the model’s transform (conflict b/w own view and external sourced model changes)
 
-    function receiveModelTransformChanges(nodeID, propertyValue ) {
+    function receiveModelTransformChanges(nodeID, propertyName, propertyValue ) {
 
         var node = self.state.nodes[ nodeID ];
 
@@ -488,8 +493,22 @@ define(["module", "vwf/view"], function (module, view) {
             node.ignoreNextTransformUpdate = false;
         } else {
            // adoptTransform( node, transformMatrix );
-           var pos = goog.vec.Vec3.clone( propertyValue );
-           node.aframeObj.object3D.position.set(pos[0], pos[1], pos[2]);
+
+           if(propertyName == 'position') {
+            let pos = goog.vec.Vec3.clone( propertyValue );
+            node.aframeObj.object3D.position.set(pos[0], pos[1], pos[2]);
+           } else if (propertyName == 'rotation') {
+            let rot = goog.vec.Vec3.clone( propertyValue );
+
+            node.aframeObj.object3D.rotation.set(
+                THREE.Math.degToRad(rot[0]),
+                THREE.Math.degToRad(rot[1]),
+                THREE.Math.degToRad(rot[2])
+            )
+            //node.aframeObj.object3D.rotation.set(rot[0], rot[1], rot[2]);
+           }
+
+          
            
            //setAFrameProperty ('position', propertyValue, node.aframeObj)
         }
@@ -536,6 +555,26 @@ define(["module", "vwf/view"], function (module, view) {
     }
 
 
+    // function updateAvatarPosition() {
+    //     let avatarName = 'avatar-' + self.kernel.moniker();
+    //     var node = self.state.nodes[avatarName];
+    //     if (!node) return;
+    //     if (!node.aframeObj) return;
+
+    //     let el = document.querySelector('#avatarControl');
+    //     if (el) {
+    //         //let position = el.object3D.getWorldPosition(); //el.getAttribute('position');
+
+    //         let position = new THREE.Vector3();
+    //         el.object3D.getWorldPosition(position);
+
+    //         let rotation = getWorldRotation(el);
+    //         vwf_view.kernel.callMethod(avatarName, "followAvatarControl", [position, rotation]);
+    //     }
+
+
+    // }
+
     function updateAvatarPosition() {
 
         let delta = 0.0001;

+ 9 - 5
public/vwf/view/aframeComponent.js

@@ -52,14 +52,18 @@ define(["module", "vwf/view"], function (module, view) {
 
 
             if(this.state.nodes[childID]) {
-                this.nodes[childID] = {id:childID,extends:childExtendsID};
-            } 
-            else if (this.state.nodes[childID] && this.state.nodes[childID].aframeObj) {
                 this.nodes[childID] = {
                     id:childID,
-                    extends:childExtendsID
+                    extends:childExtendsID,
+                    entityID: this.state.nodes[childID].parentID
                 };
-            }
+            } 
+            // else if (this.state.nodes[childID] && this.state.nodes[childID].aframeObj) {
+            //     this.nodes[childID] = {
+            //         id:childID,
+            //         extends:childExtendsID
+            //     };
+            // }
           
         },