Jelajahi Sumber

interpolation

Nikolay Suslov 7 tahun lalu
induk
melakukan
15bec7297c

+ 9 - 1
public/aframe2/index.vwf.yaml

@@ -87,7 +87,15 @@ children:
           position: [2, -0.75, 0]
           color: "#2167a5"
           depth: 1
-          interpolation: "50ms"
+        children:
+          interpolation:
+            extends: http://vwf.example.com/aframe/interpolation-component.vwf
+            type: "component"
+            properties:
+              enabled: true
+              duration: 50
+              deltaPos: 0.1
+              deltaRot: 1
         methods:
           run:
             body: |

+ 71 - 10
support/client/lib/vwf/model/aframe.js

@@ -225,7 +225,39 @@ define(["module", "vwf/model", "vwf/utility"], function (module, model, utility)
                     
                 }
 
-                var componentName = "wasd-controls";
+                var componentName = "interpolation";
+
+                if ( value === undefined && aframeObject.attributes.hasOwnProperty(componentName)) {
+                   value = propertyValue;
+                   
+                   switch ( propertyName ) { 
+
+                        case "enabled":
+                           aframeObject.setAttribute(componentName, 'enabled', propertyValue);
+                               break;
+                    
+                        case "duration":
+                               aframeObject.setAttribute(componentName, 'duration', propertyValue);
+                                   break;
+
+                            case "deltaPos":
+                                   aframeObject.setAttribute(componentName, 'deltaPos', propertyValue);
+                                       break;
+                        case "deltaRot":
+                                       aframeObject.setAttribute(componentName, 'deltaRot', propertyValue);
+                                           break;
+
+                       default:
+                           value = undefined;
+                           break; 
+
+
+                   }
+
+                }
+
+
+                componentName = "wasd-controls";
                  if ( value === undefined && aframeObject.attributes.hasOwnProperty(componentName)) {
                     value = propertyValue;
                     
@@ -265,9 +297,9 @@ define(["module", "vwf/model", "vwf/utility"], function (module, model, utility)
                     
                     switch ( propertyName ) { 
 
-                            case "interpolation":
-                                aframeObject.setAttribute('interpolation', { duration: propertyValue});
-                                    break;
+                            // case "interpolation":
+                            //     aframeObject.setAttribute('interpolation', { duration: propertyValue});
+                            //         break;
 
                          case "position":
                                     aframeObject.setAttribute('position', { x: propertyValue[0], y: propertyValue[1], z: propertyValue[2] });
@@ -602,17 +634,42 @@ define(["module", "vwf/model", "vwf/utility"], function (module, model, utility)
                  }
 
 
+                 if ( value === undefined && aframeObject.attributes.hasOwnProperty("interpolation")) {
+                    value = propertyValue;
+                    
+                    switch ( propertyName ) { 
+
+                         case "enabled":
+                                        aframeObject.getAttribute('interpolation').enabled;
+                                        break;
+
+                                        case "duration":
+                                        aframeObject.getAttribute('interpolation').duration;
+                                        break;
+                                        case "posDelta":
+                                        aframeObject.getAttribute('interpolation').posDelta;
+                                        break;
+                                        case "rotDelta":
+                                        aframeObject.getAttribute('interpolation').rotDelta;
+                                        break;
+
+                    }
+
+                 }
+
+
+
 
                 if ( value === undefined && isAEntityDefinition( node.prototypes ) ) {
                     
                     switch ( propertyName ) { 
 
-                        case "interpolation":
-                            var interpolation = aframeObject.getAttribute('interpolation');
-                            if (interpolation !== null && interpolation !== undefined) {
-                                value = interpolation.duration;
-                            }
-                            break;
+                        // case "interpolation":
+                        //     var interpolation = aframeObject.getAttribute('interpolation');
+                        //     if (interpolation !== null && interpolation !== undefined) {
+                        //         value = interpolation.duration;
+                        //     }
+                        //     break;
 
                         case "position":
                                 var pos = aframeObject.getAttribute('position');
@@ -854,6 +911,10 @@ function setAFrameObjectComponents(node, config) {
         parentNode.aframeObj.setAttribute('wasd-controls', {});
     }
 
+    if (self.state.isAFrameClass(protos, "http://vwf.example.com/aframe/interpolation-component.vwf")) {
+        parentNode.aframeObj.setAttribute('interpolation', {});
+    }
+
     node.aframeObj = parentNode.aframeObj;
 }
 

+ 129 - 87
support/client/lib/vwf/model/aframe/addon/aframe-interpolation.js

@@ -1,4 +1,9 @@
-/* Interpolate component for A-Frame VR. https://github.com/scenevr/aframe-interpolate-component.git
+/* 
+The MIT License (MIT)
+Copyright (c) 2017 Nikolai Suslov
+Updated for using in LiveCoding.space and A-Frame 0.6.x
+
+Interpolate component for A-Frame VR. https://github.com/scenevr/aframe-interpolate-component.git
 
 The MIT License (MIT)
 
@@ -30,93 +35,121 @@ if (typeof AFRAME === 'undefined') {
 }
 
 
-function radians(degrees) {
-  // return degrees * Math.PI / 180.0;
-  return THREE.Math.degToRad(degrees)
-}
+class Interpolator {
+  constructor(comp) {
+    this.component = comp;
+    this.time = this.getMillis();
+  }
 
-function RotationInterpolator(timestep, entity) {
-  var time = getMillis();
-  var previous;
-  var next;
-  var e = new THREE.Euler();
-  var q = new THREE.Quaternion();
+  active() {
+    return this.previous && this.next && (this.getTime() < 1);
+  }
 
-  entity.el.addEventListener('componentchanged', function (event) {
-    if (getTime() < 0.5 || getTime() == 0) {
-      // fixme - ignore multiple calls
-      return;
-    }
+  getMillis() {
+    return new Date().getTime();
+  }
 
-    if (event.detail.name === 'rotation') {
-      if (!previous) {
-        previous = new THREE.Quaternion();
-        next = new THREE.Quaternion();
-      }
+  getTime() {
+    return (this.getMillis() - this.time) / this.component.timestep;
+  }
 
-      time = getMillis();
-      previous.copy(next);
-      next.setFromEuler(new THREE.Euler(
-        radians(event.detail.newData.x),
-        radians(event.detail.newData.y),
-        radians(event.detail.newData.z), 'YXZ'
-      ));
+  vecCmp(a, b, delta) {
+
+    let distance = a.distanceTo(b);
+    if (distance > delta) {
+      return false;
     }
-  });
+    return true;
+  }
+
+}
+
+class RotationInterpolator extends Interpolator {
 
-  // var data = this.data;
-  // var object3D = this.el.object3D;
-  // object3D.rotation.set(degToRad(data.x), degToRad(data.y), degToRad(data.z));
-  // object3D.rotation.order = 'YXZ';
+  constructor(comp) {
+    super(comp);
 
+    this.lastRotation = this.component.el.getAttribute('rotation');
+    this.previous = (new THREE.Quaternion()).setFromEuler(new THREE.Euler(
+      this.radians(this.lastRotation.x),
+      this.radians(this.lastRotation.y),
+      this.radians(this.lastRotation.z), 'YXZ'
+    ));
+    this.next = (new THREE.Quaternion()).setFromEuler(new THREE.Euler(
+      this.radians(this.lastRotation.x),
+      this.radians(this.lastRotation.y),
+      this.radians(this.lastRotation.z), 'YXZ'
+    ));
 
 
-  function getTime() {
-    return (getMillis() - time) / timestep;
   }
 
-  this.active = function () {
-    return previous && next && (getTime() < 1);
-  };
+  radians(degrees) {
+    // return degrees * Math.PI / 180.0;
+    return THREE.Math.degToRad(degrees)
+  }
 
+  makeInterpolation() {
+    let q = new THREE.Quaternion();
+    let e = new THREE.Euler();
 
-  this.get = function () {
-    THREE.Quaternion.slerp(previous, next, q, getTime());
+    THREE.Quaternion.slerp(this.previous, this.next, q, this.getTime());
     return e.setFromQuaternion(q);
-  };
-}
-
-class Interpolator {
-  constructor(comp) {
-    this.component = comp;
-    this.time = this.getMillis();
   }
 
-  active() {
-    return this.previous && this.next && (this.getTime() < 1);
-  }
+  testForLerp() {
 
-  getMillis() {
-    return new Date().getTime();
-  }
+    if (this.component.deltaRot == 0) {
+      return true
+    }
 
-  getTime() {
-    return (this.getMillis() - this.time) / this.component.timestep;
+    let prev = (new THREE.Euler()).setFromQuaternion(this.previous).toVector3();
+    let next = (new THREE.Euler()).setFromQuaternion(this.next).toVector3();
+
+    if (prev && next && this.vecCmp(prev, next, this.component.deltaRot)) {
+      return true
+    }
+    return false
   }
 
-}
 
-// class RotationInterpolator extends Interpolator {
-  
-//     constructor(comp) {
-//       super(comp);
+  inTick(currentRotation) {
+
+    if (this.getTime() < 0.5) {
+      // fixme - ignore multiple calls
+      return;
+    }
+
+
+    if (!this.previous) {
+      // this.previous = new THREE.Quaternion();
+      // this.next = new THREE.Quaternion();
+      this.previous = (new THREE.Quaternion()).setFromEuler(new THREE.Euler(
+        this.radians(this.lastRotation.x),
+        this.radians(this.lastRotation.y),
+        this.radians(this.lastRotation.z), 'YXZ'
+      ));
+
+      this.next = (new THREE.Quaternion()).setFromEuler(new THREE.Euler(
+        this.radians(currentRotation.x),
+        this.radians(currentRotation.y),
+        this.radians(currentRotation.z), 'YXZ'
+      ));
+    }
 
-//       this.previous = new THREE.Quaternion();
-//       this.next = new THREE.Quaternion();
+    this.time = this.getMillis();
+    this.previous.copy(this.next);
+    this.next.setFromEuler(new THREE.Euler(
+      this.radians(currentRotation.x),
+      this.radians(currentRotation.y),
+      this.radians(currentRotation.z), 'YXZ'
+    ));
 
-  
-//     }
-//   }
+    this.lastRotation = currentRotation;
+
+  }
+
+}
 
 
 class PositionInterpolator extends Interpolator {
@@ -129,27 +162,24 @@ class PositionInterpolator extends Interpolator {
 
   }
 
-  vecCmp(a, b, delta) {
 
-    let distance = a.distanceTo(b);
-    if (distance > delta) {
-      return false;
+  testForLerp() {
+
+    if (this.component.deltaPos == 0) {
+      return true
     }
-    return true;
-  }
 
-  testForLerp() {
-    if (this.previous && this.next && this.vecCmp(this.previous, this.next, this.component.delta)) {
+    if (this.previous && this.next && this.vecCmp(this.previous, this.next, this.component.deltaPos)) {
       return true
     }
     return false
   }
 
-  get() {
+  makeInterpolation() {
     return this.previous.lerp(this.next, this.getTime());
   }
 
-  tick(currentPosition) {
+  inTick(currentPosition) {
 
     if (this.getTime() < 0.5) {
       // fixme - ignore multiple calls
@@ -178,7 +208,8 @@ AFRAME.registerComponent('interpolation', {
   schema: {
     duration: { default: 50 },
     enabled: { default: true },
-    delta: { default: 0.5 }
+    deltaPos: { default: 0 },
+    deltaRot: { default: 0 }
   },
 
 
@@ -214,10 +245,15 @@ AFRAME.registerComponent('interpolation', {
 
     if (!this.interpolation) {
       this.timestep = parseInt(this.data.duration, 10);
-      this.delta = parseFloat(this.data.delta);
+      this.deltaPos = parseFloat(this.data.deltaPos);
+      this.deltaRot = THREE.Math.degToRad(parseFloat(this.data.deltaRot));
 
-      this.posInterpolator = new PositionInterpolator(this);
+      this.enabled = JSON.parse(this.data.enabled);
 
+      if (this.enabled) {
+        this.posInterpolator = new PositionInterpolator(this);
+        this.rotInterpolator = new RotationInterpolator(this);
+      }
     }
 
     // if (!this.interpolation) {
@@ -240,20 +276,26 @@ AFRAME.registerComponent('interpolation', {
   tick: function (t, dt) {
 
     let currentPosition = this.el.getAttribute('position');
+    let currentRotation = this.el.getAttribute('rotation');
 
-    //if (this.checkForLerp(this.lastPosition, currentPosition)) {
-
-    if (this.posInterpolator.lastPosition != currentPosition) {
-      this.posInterpolator.tick(currentPosition)
-    }
-
+    if (this.enabled) {
 
-    if (this.posInterpolator.active() && this.posInterpolator.testForLerp()) {
-      this.el.object3D.position.copy(this.posInterpolator.get());
-    }
+      if (this.posInterpolator.lastPosition != currentPosition) {
+        this.posInterpolator.inTick(currentPosition)
+      }
+      if (this.posInterpolator.active() && this.posInterpolator.testForLerp()) {
+        this.el.object3D.position.copy(this.posInterpolator.makeInterpolation());
+      }
 
 
+      if (this.rotInterpolator.lastRotation != currentRotation) {
+        this.rotInterpolator.inTick(currentRotation)
+      }
+      if (this.rotInterpolator.active() && this.rotInterpolator.testForLerp()) {
+        this.el.object3D.rotation.copy(this.rotInterpolator.makeInterpolation());
+      }
 
+    }
 
     // if (this.positionInterpolator && this.positionInterpolator.active()) {
     //   this.el.object3D.position.copy(this.positionInterpolator.get());

+ 3 - 1
support/client/lib/vwf/view/aframe.js

@@ -142,12 +142,14 @@ define(["module", "vwf/view", "jquery", "jquery-ui"], function (module, view, $)
 
         let avatarName = 'avatar-' + self.kernel.moniker();
         let el = document.querySelector('#avatarControl');
-        if (el !== undefined) {
+        if (el) {
             let postion = el.getAttribute('position');
             let rotation = el.getAttribute('rotation');
 
+            if ( postion && rotation) {
             vwf_view.kernel.setProperty(avatarName, "position", [postion.x, postion.y, postion.z]);
             vwf_view.kernel.setProperty(avatarName, "rotation", [rotation.x, rotation.y, rotation.z]);
+            }
         }
     }
 

+ 0 - 1
support/proxy/vwf.example.com/aframe/aentity.vwf.yaml

@@ -15,5 +15,4 @@ properties:
   src:
   repeat:
   fog:
-  interpolation:
   displayName:

+ 15 - 1
support/proxy/vwf.example.com/aframe/avatar.vwf.yaml

@@ -62,7 +62,21 @@ methods:
                     }
               }
 
-              this.interpolation = "50ms";
+            let interpolation =
+             {
+                "id": 'interpolation-' + this.id,
+                 "extends": "http://vwf.example.com/aframe/interpolation-component.vwf",
+                 "type": "component",
+                 "properties": {
+                        "enabled": true,
+                        "duration": 50,
+                        "deltaPos": 0,
+                        "deltaRot": 0
+                    }
+             }
+
+              //this.interpolation = "50ms";
+            this.children.create( "interpolation", interpolation );
               this.children.create( "avatarBody", newNode );
               this.children.create( "avatarCursor", cursorVis );
               this.children.create( "avatarCamera", camera );

+ 9 - 0
support/proxy/vwf.example.com/aframe/interpolation-component.vwf.yaml

@@ -0,0 +1,9 @@
+# Interpolation
+---
+extends: http://vwf.example.com/aframe/aentityComponent.vwf
+type: "component"
+properties:
+  enabled:
+  duration:
+  deltaPos:
+  deltaRot: