123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 |
- # Copyright 2012 United States Government, as represented by the Secretary of Defense, Under
- # Secretary of Defense (Personnel & Readiness).
- #
- # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- # in compliance with the License. You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software distributed under the License
- # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- # or implied. See the License for the specific language governing permissions and limitations under
- # the License.
- ## The component representation of a fly behavior
- ##
- ## @name fly.vwf
- ## @namespace
- ---
- extends:
- http://vwf.example.com/node3.vwf
- properties:
- ## Whether the component is flying
- ##
- ## @name fly.vwf#fly-flying
- ## @property
- fly-flying:
- set: |
- if ( value && ! this["fly-flying"] ) { // starting
- this["fly-flying"] = true; // set the internal value
- this.fly(); // run the first step and schedule the next one
- } else if ( ! value && this["spin-spinning"] ) { // stopping
- this["fly-flying"] = false; // set the internal value
- }
- value: false
- ## Distance on ground
- ##
- ## @name fly.vwf#fly-distanceOnGround
- ## @property
- fly-distanceOnGround: 1000
- ## Maximum speed on the ground
- ##
- ## @name fly.vwf#fly-speedOnGroundMax
- ## @property
- fly-speedOnGroundMax: 200
- ## Elevation
- ##
- ## @name fly.vwf#fly-elevation
- ## @property
- fly-elevation: 2500
- ## Speed in the air
- ##
- ## @name fly.vwf#fly-speedInAir
- ## @property
- fly-speedInAir: 250
- ## Flying radius
- ##
- ## @name fly.vwf#fly-radius
- ## @property
- fly-radius: 8000
- ## Flying speed
- ##
- ## @name fly.vwf#fly-speed
- ## @property
- fly-speed: 62.5
- ## Point index
- ##
- ## @name fly.vwf#fly-pointIndex
- ## @property
- fly-pointIndex: 0
- methods:
- ## Animation function. Updates component positions and calls vwf future fly call
- ##
- ## @name fly.vwf#fly
- ## @function
- ##
- ## @returns undefined
- fly:
- ## Updates speed based on whether the component is on the ground or in the air.
- ##
- ## @name fly.vwf#updateSpeed
- ## @function
- ##
- ## @returns undefined
- updateSpeed:
- ## Returns whether component is on the ground
- ##
- ## @name fly.vwf#isOnGround
- ## @function
- ##
- ## @returns undefined
- isOnGround:
- ## Returns whether component is rising
- ##
- ## @name fly.vwf#isRising
- ## @function
- ##
- ## @returns undefined
- isRising:
- ## Initialization function
- ##
- ## @name fly.vwf#initialize
- ## @function
- ##
- ## @returns undefined
- initializePoints:
- ## Calculates new interpolated positions
- ##
- ## @name fly.vwf#isOnGround
- ## @function
- ##
- ## @param {Array} beforeCoord
- ## @param {Array} afterCoord
- ## @param {Number} percent
- ##
- ## @returns new position
- interpolate:
- scripts:
- - |
- var index = 0;
- var lastTime = undefined;
- var onGround = true;
- this.isOnGround = function() {
- if ( this.points[ this["fly-pointIndex"] ].place == "ground" ) {
- return true;
- }
- return false;
- }
- this.isRising = function() {
- if ( this.points[ this["fly-pointIndex"] ].place == "rising" ) {a
- return true;
- }
- return false;
- }
- this.updateSpeed = function() {
- if ( this.isOnGround() ) {
- if ( this["fly-speed"] < this["fly-speedOnGroundMax"] ) {
- this["fly-speed"] = this["fly-speed"] + this["fly-speedOnGroundMax"] / this.pointsOnGround;
- }
- if ( this["fly-speed"] >= this["fly-speedOnGroundMax"] ) {
- this["fly-speed"] = this["fly-speedOnGroundMax"];
- }
- } else {
- this["fly-speed"] = this["fly-speedInAir"];
- }
- }
- this.initializePoints = function(){
- var trans = this.transform;
- if ( trans ) {
- var initPt = this.translation;
- var newPoint;
- var distance = 0;
- var prevPt = undefined;
- this.points = [];
- this["fly-pointIndex"] = 0;
- this.pointsOnGround = 16.0;
- this.pointsClimbing = 24.0;
- this.pointsOnCircle = 36.0;
- this.lastTime = 0;
- var diffX, diffY, diffZ;
- var at = goog.vec.Vec3.createFromValues( trans[4], trans[5], 0 );
- goog.vec.Vec3.normalize( at, at );
-
- for ( var i = 0; i < this.pointsOnGround; i++ ) {
- newPoint = [];
- newPoint[0] = initPt[0] + at[0] * i * this["fly-distanceOnGround"] / this.pointsOnGround;
- newPoint[1] = initPt[1] + at[1] * i * this["fly-distanceOnGround"] / this.pointsOnGround;
- newPoint[2] = initPt[2];
-
- if ( prevPt ) {
- diffX = prevPt[0] - newPoint[0];
- diffY = prevPt[1] - newPoint[1];
- diffZ = prevPt[2] - newPoint[2];
- distance = Math.sqrt( diffX*diffX + diffY*diffY + diffZ*diffZ );
- }
- this.points.push( { point: newPoint, distance: distance, place: "ground" } );
- prevPt = newPoint;
-
- }
- var heightToTravel = this["fly-elevation"];
- var hypLength = heightToTravel / Math.sin( Math.PI/6 );
- var adjLength = Math.cos( Math.PI/6 ) * hypLength;
- initPt = this.points[ this.points.length-1 ].point;
- for ( var i = 1; i <= this.pointsClimbing; i++ ) {
- newPoint = [];
- newPoint[0] = initPt[0] + at[0] * i * adjLength / this.pointsClimbing;
- newPoint[1] = initPt[1] + at[1] * i * adjLength / this.pointsClimbing;
- newPoint[2] = initPt[2] + i * heightToTravel / this.pointsClimbing;
- if ( prevPt ) {
- diffX = prevPt[0] - newPoint[0];
- diffY = prevPt[1] - newPoint[1];
- diffZ = prevPt[2] - newPoint[2];
- distance = Math.sqrt( diffX*diffX + diffY*diffY + diffZ*diffZ );
- }
- this.points.push( { point: newPoint, distance: distance, place: "rising" } );
- prevPt = newPoint;
- }
- //prevPt = this.points[ this.points.length-1 ].point;
- var inc = ( 2.0 * Math.PI ) / this.pointsOnCircle;
- var currentAngle = Math.PI + inc;
- var center = [];
- center[0] = prevPt[0] + this["fly-radius"];;
- center[1] = prevPt[1];
- center[2] = prevPt[2];
- this.firstCiclePoint = this.points.length-1;
- for ( var i = 0; i < this.pointsOnCircle; i++ ) {
- newPoint = [];
- newPoint[0] = center[0] + this["fly-radius"] * Math.cos( currentAngle );
- newPoint[1] = center[1] + this["fly-radius"] * Math.sin( currentAngle );
- newPoint[2] = center[2];
- currentAngle += inc;
-
- if ( prevPt ) {
- diffX = prevPt[0] - newPoint[0];
- diffY = prevPt[1] - newPoint[1];
- diffZ = prevPt[2] - newPoint[2];
- distance = Math.sqrt( diffX*diffX + diffY*diffY + diffZ*diffZ );
- }
- this.points.push( { point: newPoint, distance: distance, place: "circling" } );
- prevPt = newPoint;
- }
-
- //var pt;
- //for ( var i = 0; i < this.points.length; i++ ) {
- // pt = this.points[i];
- //}
- }
- }
- this.interpolate = function( beforeCoord, afterCoord, percent ) {
- var newPos = [];
- newPos.push( beforeCoord[0] + percent * (afterCoord[0] - beforeCoord[0]) );
- newPos.push( beforeCoord[1] + percent * (afterCoord[1] - beforeCoord[1]) );
- newPos.push( beforeCoord[2] + percent * (afterCoord[2] - beforeCoord[2]) );
- return newPos;
- }
- this.fly = function() {
- if ( this["fly-flying"] ) { // if enabled
- if ( this["fly-speed"] < 63 ) {
- if ( !this.points ) {
- this.initializePoints();
- }
- this.updateSpeed();
- this.timeToNext = this.points[ this["fly-pointIndex"]+1 ].distance / this["fly-speed"];
- this.timeAtLastPoint = this.time;
- } else {
- var elapsedTime = this.time - this.timeAtLastPoint;
- var currentPoint = this.points[ this["fly-pointIndex"] ].point;
- var nextPoint = this.points[ this["fly-pointIndex"]+1 ].point;
- var percent = elapsedTime / this.timeToNext;
- var newPos = this.interpolate( currentPoint, nextPoint, percent );
- this.translation = newPos;
- if ( percent > 0.9875 ) {
- this["fly-pointIndex"]++;
- if ( this["fly-pointIndex"]+1 >= this.points.length ) {
- this["fly-pointIndex"] = this.firstCiclePoint;
- }
- // update rotation
- var goalPathPoint = this.points[ this["fly-pointIndex"]+1 ].point;
- var zRot = [ goalPathPoint[0] - newPos[0], goalPathPoint[1] - newPos[1], 0 ];
- this.rotation = [ 0, 0, 1, (Math.atan2( zRot[1], zRot[0] )-(Math.PI*0.5))*180/Math.PI ];
- this.updateSpeed();
- this.timeToNext = this.points[ this["fly-pointIndex"]+1 ].distance / this["fly-speed"];
- this.timeAtLastPoint = this.time;
- }
- }
- this.future( 0.05 ).fly(); // schedule the next step
- }
- }
- this.pointerClick = function() { // when clicked ...
- this["fly-flying"] = ! this["fly-flying"]; // ... toggle the enabled flag
- } //@ sourceURL=fly.vwf
|