/**
* Copyright phenix.pink ( http://wonderfl.net/user/phenix.pink )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/o0zF
*/
// forked from onedayitwillmake's We Will Follow This Road.. forked from: Endless Candy
package
{
//import gs.TweenMax;
//import gs.easing.Sine;
//import com.greensock.TweenMax;
// import com.greensock.easing.*;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.Graphics;
import flash.display.PixelSnapping;
import flash.display.Shape;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.filters.ColorMatrixFilter;
import flash.utils.Timer;
import frocessing.color.ColorHSV;
import org.papervision3d.cameras.SpringCamera3D;
import org.papervision3d.core.geom.Lines3D;
import org.papervision3d.core.geom.Particles;
import org.papervision3d.core.geom.renderables.Line3D;
import org.papervision3d.core.geom.renderables.Particle;
import org.papervision3d.core.geom.renderables.Vertex3D;
import org.papervision3d.core.math.Number2D;
import org.papervision3d.core.math.Number3D;
import org.papervision3d.core.render.data.RenderHitData;
import org.papervision3d.core.utils.Mouse3D;
import org.papervision3d.materials.special.BitmapParticleMaterial;
import org.papervision3d.materials.special.LineMaterial;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.view.BasicView;
/**
* Papervsion Particles step 1
* @author Mario Gonzalez
*/
[SWF(width="465", height="465", backgroundColor="0x000000", frameRate="60")]
public class EndlessCandy extends BasicView
{
//new com.greensock.TweenMax
private var _mouse3D :Mouse3D;
private var _particles :Particles = new Particles();
private var _particlesArray :Array = [];
private var _currentParticle :Particle;
private var _lines :Lines3D;
private var _currentLine :Line3D;
private var _lineMaterial :LineMaterial;
private var PARTICLE_COUNT :int = 80;
private var _extraRotation :Number = 0;
private var _rotationSpeed :Number = 0.01;
private var _springCamera :SpringCamera3D;
private var _currentParticleInArray :int = 0;
private var _camTarget :WanderingTarget = new WanderingTarget();
private var _timer:Timer;
private var image:BitmapData
private var colorHSV:ColorHSV = new ColorHSV(360, 0.8, 1);
private var data:BitmapData;
public function EndlessCandy()
{
Wonderfl.capture_delay(145);
//Mouse3D.enabled = true;
//super.viewport.interactive = true
//_mouse3D = viewport.interactiveSceneManager.mouse3D;
createParticleRing();
_springCamera = new SpringCamera3D(55, 10, 19000, false);
_springCamera.target = _camTarget;
_springCamera.focus = 75;
_springCamera.zoom = 1;
_springCamera.stiffness = 2;
//_springCamera.lookOffset = new Number3D(0, -20,20);
_springCamera.positionOffset = new Number3D(0, 145, -350);
//trace(_springCamera.stiffness, _springCamera.damping)
_springCamera.mass = 600
_springCamera.damping = 30;
// _springCamera.lookAt(
//_springCamera
scene.addChild(_particles);
startRendering();
}
private function createLines3D():void
{
_lines = new Lines3D();
_lineMaterial = new LineMaterial(0xffff);
for (var i:int = 0; i < PARTICLE_COUNT; i++)
{
var startParticle :Particle = Utils.randInArray(_particles.particles);
var endParticle :Particle = Utils.randInArray(_particles.particles);
var line :Line3D = new Line3D(_lines, _lineMaterial, 2, startParticle.vertex3D, endParticle.vertex3D);
line._userData = new LineInfo(startParticle, endParticle);
_lines.addLine(line);
}
scene.addChild(_lines);
}
private function createParticleRing():void
{
// Make the particle example
var shape:Shape = new Shape();
var g:Graphics = shape.graphics;
g.beginFill(0xffffff, 0.5);
g.drawCircle(16,16,16);
g.beginFill(0xffffff);
g.drawCircle(16,16,8);
g.endFill();
data = new BitmapData(shape.width, shape.height, true, 0xFFFFFF);
data.draw(shape);
var material:BitmapParticleMaterial = new BitmapParticleMaterial(data, 1);
//_currentParticle = new Particle(material, 1);
//_particles.addParticle(_currentParticle);
image = new BitmapData(data.width, data.height, true);
}
override protected function onRenderTick(e:Event = null):void
{
_camTarget.wander();
_camTarget.update();
//_camTarget.rotationX += 2;
// /_particles.rotationY += 0.5;
// _springCamera.lookAt(_camTarget);
// Always create one particle, sometimes create more than one
do {
createParticle(null);
} while(Math.random() < 0.3)
//trace(_mouse3D.)
super.renderer.renderScene(scene, _springCamera, viewport);
if(_particlesArray.length > 300)
_particles.removeParticle(_particlesArray.shift() as Particle);
}
protected function createParticle(position:Number3D):Particle
{
// No position given make one up
if(position == null) {
var position:Number3D = new Number3D();
position.x = _camTarget.x + Utils.randRange(-250, 250);
position.y = _camTarget.y;//s+ Utils.randRange(-10, 10);
position.z = _camTarget.z + Utils.randRange(000, 600);
}
colorHSV.h += Math.random() * 0.9;
image = data.clone();
image.applyFilter(image, image.rect, image.rect.topLeft, new ColorMatrixFilter(ColorHelper.colorize(colorHSV.value)))
var material:BitmapParticleMaterial = new BitmapParticleMaterial(image, 1);
_currentParticle = new Particle(material, Math.random() * 2 + 1);
_currentParticle.x = position.x;
_currentParticle.y = position.y;
_currentParticle.z = position.z;
//trace(_currentParticle.size)
// _currentParticle.
_particles.addParticle(_currentParticle);
_particlesArray.push(_currentParticle);
return _currentParticle;
}
}
}
import org.papervision3d.cameras.SpringCamera3D;
import org.papervision3d.core.data.UserData;
import org.papervision3d.core.geom.renderables.Particle;
internal class LineInfo extends UserData
{
public var _startParticle :Particle;
public var _endParticle :Particle;
public function LineInfo(s:Particle, e:Particle)
{
_startParticle = s;
_endParticle = e;
}
}
internal class Utils
{
/**
* Return a random element inside an array
* @param array, The array you want to get a random element from
* @return *, An object in that array
*/
public static function randInArray(array:*):*
{
if (array) return array[randRange(0, array.length - 1)];
}
/**
* Random interger within range.
* @param min
* @param max
* @return
*/
public static function randRange(min:int, max:int):int
{
var fmin:Number = min - .4999;
var fmax:Number = max + .4999;
return int(Math.round(fmin + (fmax - fmin) * Math.random()));
}
}
/**
* Modify the color of an asset without destroying color contrast / shading in the asset.
* Uses hue/saturation/brightness/contrast to modify a color keeping contrast between colors in the asset intact
* @version 1.3
*/
internal class ColorHelper
{
/**
* Colorize an asset based on an RGB value
* @param rgb Hex color value
* @param amount How much of the original color to keep. [0.0-1.0], 1.0 means none. Range can exceed 1.0 for experimental results
*/
public static function colorize(rgb:Number, amount:Number=1):Array
{
var r:Number;
var g:Number;
var b:Number;
var inv_amount:Number;
// Found after some googling - @ http://www.faqs.org/faqs/graphics/colorspace-faq/ (ctrl+f luminance)
var LUMA_R:Number = 0.4086;
var LUMA_G:Number = 0.7094;
var LUMA_B:Number = 0.0920;
r = (((rgb >> 16) & 0xFF) / 0xFF);
g = (((rgb >> 8) & 0xFF) / 0xFF);
b = ((rgb & 0xFF) / 0xFF);
inv_amount = (1 - amount);
return concat([(inv_amount + ((amount * r) * LUMA_R)), ((amount * r) * LUMA_G), ((amount * r) * LUMA_B), 0, 0,
((amount * g) * LUMA_R), (inv_amount + ((amount * g) * LUMA_G)), ((amount * g) * LUMA_B), 0, 0,
((amount * b) * LUMA_R), ((amount * b) * LUMA_G), (inv_amount + ((amount * b) * LUMA_B)), 0, 0,
0, 0, 0, 1, 0]);
}
/**
* Concat two matrices
* Could be used to mix colors, but for now it only concacts with an identy matrix
* @param mat Matrix we want to concact
*/
public static function concat( mat:Array ):Array
{
// Identity matrix
var matrix:Array = [1, 0, 0, 0, 0, // RED
0, 1, 0, 0, 0, // GREEN
0, 0, 1, 0, 0, // BLUE
0, 0, 0, 1, 0]; // ALPHA
var temp:Array = new Array();
var i:int = 0;
var x:int, y:int;
// Loop through the matrice
for (y = 0; y < 4; y++ )
{
for (x = 0; x < 5; x++ )
{
temp[ int( i + x) ] = Number(mat[i]) * Number(matrix[x]) +
Number(mat[int(i + 1)]) * Number(matrix[int(x + 5)]) +
Number(mat[int(i + 2)]) * Number(matrix[int(x + 10)]) +
Number(mat[int(i + 3)]) * Number(matrix[int(x + 15)]) +
(x == 4 ? Number(mat[int(i + 4)]) : 0);
}
i+=5;
}
return temp;
}
}
import flash.display.DisplayObject;
import flash.geom.Matrix3D;
import flash.geom.Point;
import flash.geom.Vector3D;
import org.papervision3d.cameras.Camera3D;
import org.papervision3d.objects.DisplayObject3D;
internal class WanderingTarget extends DisplayObject3D
{
/**
* SEE http://blog.soulwire.co.uk/laboratory/flash/as3-flocking-steering-behaviors
* SOUL WIRE
*/
private var _matrix : Matrix3D;
private var _maxForce : Number;
private var _maxSpeed : Number;
private var _distance : Number;
private var _drawScale : Number;
private var _maxForceSQ : Number;
private var _maxSpeedSQ : Number;
private var _velocity : Vector3D;
private var _position : Vector3D;
private var _oldPosition : Vector3D;
private var _acceleration : Vector3D;
private var _steeringForce : Vector3D;
private var _screenCoords : Point;
private var _renderData : DisplayObject;
private var _edgeBehavior : String;
private var _boundsRadius : Number;
private var _boundsCentre : Vector3D = new Vector3D();
private var _radius : Number = 10.0;
private var _wanderTheta : Number = 0.0;
private var _wanderRadius : Number = 16.0;
private var _wanderDistance : Number = 60.0;
private var _wanderStep : Number = 0.25;
private var _lookAtTarget : Boolean = true;
protected var _config : Object = {
minForce:3.0,
maxForce:6.0,
minSpeed:6.0,
maxSpeed:12.0,
minWanderDistance:10.0,
maxWanderDistance:100.0,
minWanderRadius:5.0,
maxWanderRadius:20.0,
minWanderStep:0.1,
maxWanderStep:0.9,
boundsRadius:250,
numBoids:120
};
public function WanderingTarget()
{
maxForce = 8.0;//random(_config.minForce, _config.maxForce);
maxSpeed = 40.0//;random(_config.minSpeed, _config.maxSpeed);
_wanderDistance = 50.0;//random(_config.minWanderDistance, _config.maxWanderDistance);
_wanderRadius = 30;//random(_config.minWanderRadius, _config.maxWanderRadius);
_wanderStep = 10.5;//random(_config.minWanderStep, _config.maxWanderStep);
super();
reset();
//super(fov, near, far, useCulling, useProjection);
}
/**
* Generates a random wandering force for the Boid.
* The results of this method can be controlled by the
* _wanderDistance, _wanderStep and _wanderRadius parameters
*
* @param multiplier
*
* By multiplying the force generated by this behavior,
* more or less weight can be given to this behavior in
* comparison to other behaviors being calculated by the
* Boid. To increase the weighting of this behavior, use
* a number above 1.0, or to decrease it use a number
* below 1.0
*/
public function wander( multiplier : Number = 1.0 ) : void
{
_wanderTheta += Math.random() * _wanderStep;
if ( Math.random() < 0.5 )
{
_wanderTheta = -_wanderTheta;
}
var pos : Vector3D = _velocity.clone();
//trace(pos)
pos.normalize();
pos.scaleBy(_wanderDistance);
pos.incrementBy(_position);
var offset : Vector3D = new Vector3D();
offset.x = _wanderRadius * Math.cos(_wanderTheta);
offset.y = _wanderRadius * Math.sin(_wanderTheta);
offset.z = _wanderRadius * Math.tan(_wanderTheta);
// trace(offset)
//trace(_wanderRadius, _wanderTheta, pos, offset)
_steeringForce = steer(pos.add(offset));
if ( multiplier != 1.0 )
{
_steeringForce.scaleBy(multiplier);
}
// trace(_steeringForce)
_acceleration.incrementBy(_steeringForce);
}
private function steer( target : Vector3D, ease : Boolean = false, easeDistance : Number = 100 ) : Vector3D
{
//trace(_steeringForce,target.clone());
_steeringForce = target.clone();
_steeringForce.decrementBy(_position);
//trace(_steeringForce,target.clone());
_distance = _steeringForce.normalize();
//trace('ab', _distance)
if ( _distance > 0.00001 )
{
if ( _distance < easeDistance && ease )
{
_steeringForce.scaleBy(_maxSpeed * ( _distance / easeDistance ));
}
else
{
_steeringForce.scaleBy(_maxSpeed);
}
_steeringForce.decrementBy(_velocity);
if ( _steeringForce.lengthSquared > _maxForceSQ )
{
_steeringForce.normalize();
_steeringForce.scaleBy(_maxForce);
}
}
//trace(_steeringForce)
return _steeringForce;
}
public function update() : void
{
_oldPosition.x = _position.x;
_oldPosition.y = _position.y;
_oldPosition.z = _position.z;
_velocity.incrementBy(_acceleration);
if ( _velocity.lengthSquared > _maxSpeedSQ )
{
_velocity.normalize();
_velocity.scaleBy(_maxSpeed);
}
_position.incrementBy(_velocity);
x = _position.x;
y = _position.y;
z = _position.z;
_acceleration.x = 0;
_acceleration.y = 0;
_acceleration.z = 0;
}
/**
* Resets the Boid's position, velocity, acceleration and
* current steering force to zero
*/
public function reset() : void
{
_velocity = new Vector3D();
_position = new Vector3D();
_oldPosition = new Vector3D();
_acceleration = new Vector3D();
_steeringForce = new Vector3D();
_screenCoords = new Point();
}
/**
* The maximum force available to the Boid when
* calculating the steering force produced by
* the Boids steering bahaviors
*/
public function get maxForce() : Number
{
return _maxForce;
}
public function set maxForce( value : Number ) : void
{
if ( value < 0 )
{
value = 0;
}
_maxForce = value;
_maxForceSQ = value * value;
}
/**
* The maximum speed the Boid can reach
*/
public function get maxSpeed() : Number
{
return _maxSpeed;
}
public function set maxSpeed( value : Number ) : void
{
if ( value < 0 )
{
value = 0;
}
_maxSpeed = value;
_maxSpeedSQ = value * value;
}
protected function random( min : Number, max : Number = NaN ) : Number
{
if ( isNaN(max) )
{
max = min;
min = 0;
}
return Math.random() * ( max - min ) + min;
}
}