text: //
  // butterflies.js
  // 
  //
  // Created by Adrian McCarlie on August 2, 2014
  // Modified by Brad Hefta-Gaub to use Entities on Sept. 3, 2014
  // Copyright 2014 High Fidelity, Inc.
  //
  // This sample script creates a swarm of  butterfly entities that fly around the avatar.
  //
  // Distributed under the Apache License, Version 2.0.
  // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
  //
  
  
  var numButterflies = 20;
  
  
  function getRandomFloat(min, max) {
      return Math.random() * (max - min) + min;
  }
  
  // Multiply vector by scalar
  function vScalarMult(v, s) {
      var rval = { x: v.x * s, y: v.y * s, z: v.z * s };
      return rval;
  }
  
  // Create a random vector with individual lengths between a,b
  function randVector(a, b) {
      var rval = { x: a + Math.random() * (b - a), y: a + Math.random() * (b - a), z: a + Math.random() * (b - a) };
      return rval;
  }
  
  // Returns a vector which is fraction of the way between a and b
  function vInterpolate(a, b, fraction) {
      var rval = { x: a.x + (b.x - a.x) * fraction, y: a.y + (b.y - a.y) * fraction, z: a.z + (b.z - a.z) * fraction };
      return rval;
  }
  
  var startTimeInSeconds = new Date().getTime() / 1000;
  
  var NATURAL_SIZE_OF_BUTTERFLY = { x: 9.512, y: 4.427, z: 1.169 };
  var lifeTime = 600; // lifetime of the butterflies in seconds
  var range = 1.0; // Over what distance in meters do you want the flock to fly around
  var frame = 0;
  
  var CHANCE_OF_MOVING = 0.9;
  var BUTTERFLY_GRAVITY = 0;//-0.06;
  var BUTTERFLY_FLAP_SPEED = 1.0;
  var BUTTERFLY_VELOCITY = 0.55;
  var DISTANCE_IN_FRONT_OF_ME = 1.5;
  var DISTANCE_ABOVE_ME = 1.0;
  var flockPosition = Vec3.sum(MyAvatar.position,Vec3.sum(
                          Vec3.multiply(Quat.getFront(MyAvatar.orientation), DISTANCE_ABOVE_ME), 
                          Vec3.multiply(Quat.getFront(MyAvatar.orientation), DISTANCE_IN_FRONT_OF_ME)));
          
  
  // set these pitch, yaw, roll to the needed values to orient the model as you want it
  var	pitchInDegrees = 270.0;
  var	yawInDegrees = 0.0;
  var	rollInDegrees = 0.0;
  var	pitchInRadians = pitchInDegrees / 180.0 * Math.PI;
  var	yawInRadians = yawInDegrees / 180.0 * Math.PI;
  var	rollInRadians = rollInDegrees / 180.0 * Math.PI;
  
  var rotation = Quat.fromPitchYawRollDegrees(pitchInDegrees, yawInDegrees, rollInDegrees);//experimental
  	
  // This is our butterfly object
  function defineButterfly(entityID, targetPosition) {
      this.entityID = entityID;
      this.previousFlapOffset = 0;
      this.targetPosition = targetPosition;
      this.moving = false;
  }
  
  // Array of butterflies
  var butterflies = [];
  function addButterfly() {
      // Decide the size of butterfly 
      var color = { red: 100, green: 100, blue: 100 };
      var size = 0;
  
      var minSize = 0.06;
      var randomSize = 0.2;
      var maxSize = minSize + randomSize;
      
      size = 0.06 + Math.random() * 0.2;
      
      var dimensions = Vec3.multiply(NATURAL_SIZE_OF_BUTTERFLY, (size / maxSize));
  	
      flockPosition = Vec3.sum(MyAvatar.position,Vec3.sum(
                          Vec3.multiply(Quat.getFront(MyAvatar.orientation), DISTANCE_ABOVE_ME), 
                          Vec3.multiply(Quat.getFront(MyAvatar.orientation), DISTANCE_IN_FRONT_OF_ME)));
  	
      var properties = {
          type: "Model",
          lifetime: lifeTime,
          position: Vec3.sum(randVector(-range, range), flockPosition),
          velocity: { x: 0, y: 0.0, z: 0 },
          gravity: { x: 0, y: 1.0, z: 0 },
  		damping: 0.1,
  		dimensions: dimensions,
          color: color,
  		rotation: rotation,
  		animationURL: "http://business.ozblog.me/objects/butterfly/newButterfly2.fbx",
  		animationIsPlaying: true,
  		modelURL: "http://business.ozblog.me/objects/butterfly/newButterfly2.fbx"
      };
      properties.position.z = properties.position.z+1;
      butterflies.push(new defineButterfly(Entities.addEntity(properties), properties.position));
  }
  
  // Generate the butterflies
  for (var i = 0; i < numButterflies; i++) {
      addButterfly();
  }
  
  // Main update function
  function updateButterflies(deltaTime) {
      // Check to see if we've been running long enough that our butterflies are dead
      var nowTimeInSeconds = new Date().getTime() / 1000;
      if ((nowTimeInSeconds - startTimeInSeconds) >= lifeTime) {
          //  print("our butterflies are dying, stop our script");
          Script.stop();
          return;
      }
    
      frame++;
      // Only update every third frame
      if ((frame % 3) == 0) {
          flockPosition = Vec3.sum(MyAvatar.position,Vec3.sum(
                          Vec3.multiply(Quat.getFront(MyAvatar.orientation), DISTANCE_ABOVE_ME), 
                          Vec3.multiply(Quat.getFront(MyAvatar.orientation), DISTANCE_IN_FRONT_OF_ME)));
          
          // Update all the butterflies
          for (var i = 0; i < numButterflies; i++) {
              entityID = Entities.identifyEntity(butterflies[i].entityID);
              butterflies[i].entityID = entityID;
              var properties = Entities.getEntityProperties(entityID);
  			
      		if (properties.position.y > flockPosition.y + getRandomFloat(0.0,0.3)){ //0.3  //ceiling
                  properties.gravity.y = - 3.0;
                  properties.damping.y = 1.0;
                  properties.velocity.y = 0;
                  properties.velocity.x = properties.velocity.x;
                  properties.velocity.z = properties.velocity.z;	
                  if (properties.velocity.x < 0.5){ 
                      butterflies[i].moving = false;
                  }
                  if (properties.velocity.z < 0.5){ 
                      butterflies[i].moving = false;
                  }				
  			}
  			
  			if (properties.velocity.y <= -0.2) {
                  properties.velocity.y = 0.22;		
                  properties.velocity.x = properties.velocity.x;
                  properties.velocity.z = properties.velocity.z;
  			}
  			
  			if (properties.position.y < flockPosition.y - getRandomFloat(0.0,0.3)) { //-0.3   // floor
                  properties.velocity.y = 0.9;
                  properties.gravity.y = - 4.0;
                  properties.velocity.x = properties.velocity.x;
                  properties.velocity.z = properties.velocity.z;
                  if (properties.velocity.x < 0.5){ 
                      butterflies[i].moving = false;
  				}
                  if (properties.velocity.z < 0.5){ 
                      butterflies[i].moving = false;
  				}			
  			}
  
  
              // Begin movement by getting a target
              if (butterflies[i].moving == false) {
                  if (Math.random() < CHANCE_OF_MOVING) {
                      var targetPosition = Vec3.sum(randVector(-range, range), flockPosition);
                      if (targetPosition.x < 0) {
                          targetPosition.x = 0;
                      }
                      if (targetPosition.y < 0) {
                          targetPosition.y = 0;
                      }
                      if (targetPosition.z < 0) {
                          targetPosition.z = 0;
                      }
                      if (targetPosition.x > TREE_SCALE) {
                          targetPosition.x = TREE_SCALE;
                      }
                      if (targetPosition.y > TREE_SCALE) {
                          targetPosition.y = TREE_SCALE;
                      }
                      if (targetPosition.z > TREE_SCALE) {
                          targetPosition.z = TREE_SCALE;
                      }
                      butterflies[i].targetPosition = targetPosition;
                      butterflies[i].moving = true;
                  }
              }
  			  
              // If we are moving, move towards the target
              if (butterflies[i].moving) {	
  			
  				var	holding = properties.velocity.y;
  			
                  var desiredVelocity = Vec3.subtract(butterflies[i].targetPosition, properties.position);
                  desiredVelocity = vScalarMult(Vec3.normalize(desiredVelocity), BUTTERFLY_VELOCITY);
  		   
  				properties.velocity = vInterpolate(properties.velocity, desiredVelocity, 0.5);
  				properties.velocity.y = holding ;
  			
  			
                  // If we are near the target, we should get a new target
                  var halfLargestDimension = Vec3.length(properties.dimensions) / 2.0;
                  if (Vec3.length(Vec3.subtract(properties.position, butterflies[i].targetPosition)) < (halfLargestDimension)) {
                      butterflies[i].moving = false;
                  }
  				
  				var yawRads = Math.atan2(properties.velocity.z, properties.velocity.x); 
  				yawRads = yawRads + Math.PI / 2.0;
  				var	newOrientation = Quat.fromPitchYawRollRadians(pitchInRadians, yawRads, rollInRadians);
  				properties.rotation = newOrientation;
  			}
  
              // Use a cosine wave offset to make it look like its flapping.
              var offset = Math.cos(nowTimeInSeconds * BUTTERFLY_FLAP_SPEED) * (halfLargestDimension);
              properties.position.y = properties.position.y + (offset - butterflies[i].previousFlapOffset);
              // Change position relative to previous offset.
              butterflies[i].previousFlapOffset = offset;
              Entities.editEntity(entityID, properties);
          }
      }
  }
  
  // register the call back so it fires before each data send
  Script.update.connect(updateButterflies);
  
  //  Delete our little friends if script is stopped
  Script.scriptEnding.connect(function() {
      for (var i = 0; i < numButterflies; i++) {
          Entities.deleteEntity(butterflies[i].entityID);
      }
  });