/**
* Copyright hosepens ( http://wonderfl.net/user/hosepens )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/fumE
*/
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Rectangle;
import flash.geom.Vector3D;
import flash.media.Video;
import flash.net.Responder;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import flash.text.TextField;
import flash.utils.getTimer;
[SWF(width="465",height="465",backgroundColor="#000000",frameRate="60")]
public class FlashTest extends Sprite
{
public function FlashTest()
{
const DEPTH: Number = 400;
const W: uint = stage.stageWidth;
const H: uint = stage.stageHeight;
//bitmap
var bmpData: BitmapData = new BitmapData(W, H, true, 0xFF000000);
stage.addChild(new Bitmap(bmpData));
//fps counter
var tf: TextField = new TextField();
tf.x = 0;
tf.y = 0;
tf.width = W;
tf.height = 20;
tf.autoSize = "right";
tf.textColor = 0xFFFFFF;
stage.addChild(tf);
var time: uint = getTimer();
//loader
var loader: Loader = new Loader();
var request: URLRequest = new URLRequest("http://assets.wonderfl.net/images/related_images/1/17/17ff/17ff7803f96ff381574fd1af294df35dab548cd9");
var context: LoaderContext = new LoaderContext(true);
loader.load(request, context);
var img: BitmapData = new BitmapData(600, 600, true);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, complete);
//light
var light: Light = new Light(new Vector3D(0, 0, 0), new Vector3D(- 1, 3, 2));
//glass
var glass: BallGlass = new BallGlass(new Vector3D(0, 0, 400));
glass.radius = 100;
glass.refractiveIndex = 1.6;
//picture
var picture: Picture = new Picture(new Vector3D(0, 0, 800));
picture.image = img;
picture.width = 600;
picture.height = 600;
function complete(e: Event): void {
img.draw(loader);
addEventListener(Event.ENTER_FRAME, ef);
}
var i: uint, j: uint, n: uint;
i = j = 0;
var ray: Ray = new Ray();
var point: Vector3D;
function ef(e: Event): void {
for (n = 0; n < 465 * 10 && i < W; n ++) {
ray.position = new Vector3D();
ray.vector = new Vector3D(i - W / 2, j - H / 2, DEPTH);
point = glass.intersection(ray, 0);
if (point.z) {
ray.position = point;
ray.refract(point.subtract(glass.position), 1, glass.refractiveIndex);
point = glass.intersection(ray, 1);
if (point.z) {
ray.position = point;
ray.refract(glass.position.subtract(point), glass.refractiveIndex, 1);
}
}
point = picture.intersection(ray);
if (point.z) {
bmpData.setPixel32(i, j, picture.image.getPixel32(Math.round(point.x + picture.width / 2 - picture.position.x), Math.round(point.y + picture.height / 2 - picture.position.y)));
}else {
bmpData.setPixel32(i, j, 0xFF000000);
}
j ++;
if (j == H) {
i ++;
if (i == W) {
i = 0;
picture.position.x -= 10;
glass.position.z -= 5;
}
j = 0;
}
}
tf.text = Math.floor(1000 / (getTimer() - time)) + "fps";
time = getTimer();
}
}
}
}
class Light
{
private var _position: Vector3D;
private var _vector: Vector3D;
public function Light(_position: Vector3D, _vector: Vector3D) {
position = _position;
vector = _vector;
}
public function get position():Vector3D { return _position; }
public function set position(value:Vector3D):void
{
_position = value;
}
public function get vector():Vector3D { return _vector; }
public function set vector(value:Vector3D):void
{
_vector = value;
_vector.normalize();
}
}
import flash.geom.Vector3D;
class Model
{
private var _position: Vector3D;
public function Model(_position: Vector3D = null) {
if(_position) {
position = _position;
}else {
position = new Vector3D();
}
}
public function get position():Vector3D { return _position; }
public function set position(value:Vector3D):void
{
_position = value;
}
}
import flash.geom.Vector3D;
class Glass extends Model
{
private var _refractiveIndex: Number;
public function Glass(_position: Vector3D = null) {
super(_position);
}
public function get refractiveIndex():Number { return _refractiveIndex; }
public function set refractiveIndex(value:Number):void
{
_refractiveIndex = value;
}
}
import flash.geom.Vector3D;
import flash.sampler.NewObjectSample;
class BallGlass extends Glass
{
private var _radius: Number;
public function BallGlass(_position: Vector3D = null) {
super(_position);
}
public function get radius():Number { return _radius; }
public function set radius(value:Number):void
{
_radius = value;
}
public function intersection(ray: Ray, number: Number): Vector3D {
var point: Vector3D;
var p: Vector3D = ray.position;
var v: Vector3D = ray.vector;
var o: Vector3D = position;
var r: Number = radius;
var a: Number = v.lengthSquared;
var b: Number = p.dotProduct(v) - o.dotProduct(v);
var c: Number = p.subtract(o).lengthSquared - r * r;
var t: Number = - b;
if (!number) {
t -= Math.sqrt(b * b - a * c);
}else {
t += Math.sqrt(b * b - a * c);
}
point = v.clone();
point.scaleBy(t);
point.incrementBy(p);
point.w = t;
if (!t || t < 0) {
point = new Vector3D();
}
return point;
}
}
import flash.display.BitmapData;
import flash.geom.Vector3D;
class Picture extends Model
{
private var _image: BitmapData;
private var _width: uint;
private var _height: uint;
public function Picture(_position: Vector3D = null) {
super(_position);
}
public function get image():BitmapData { return _image; }
public function set image(value:BitmapData):void
{
_image = value;
width = _image.width;
height = _image.height;
}
public function get width():uint { return _width; }
public function set width(value:uint):void
{
_width = value;
}
public function get height():uint { return _height; }
public function set height(value:uint):void
{
_height = value;
}
public function intersection(ray: Ray): Vector3D {
var point: Vector3D;
var p: Vector3D = ray.position;
var v: Vector3D = ray.vector.clone();
var q: Vector3D = position;
var t: Number = (q.z - p.z) / v.z;
point = v.clone();
point.scaleBy(t);
point.incrementBy(p);
if (!(point.x >= q.x - width / 2 && point.x < q.x + width / 2 && point.y >= q.y - height / 2 && point.y < q.y + height / 2)) {
point = new Vector3D();
}
return point;
}
}
import flash.geom.Vector3D;
class Ray
{
private var _position: Vector3D;
private var _vector: Vector3D;
private var _strength: Number;
public function Ray(_position: Vector3D = null, _vector: Vector3D = null, _strength: Number = 1.) {
if(_position) {
position = _position;
}else {
position = new Vector3D();
}
if(_vector) {
vector = _vector;
}else {
vector = new Vector3D();
}
strength = _strength;
}
public function clone(): Ray {
return new Ray(position, vector);
}
public function get position():Vector3D { return _position; }
public function set position(value:Vector3D):void
{
_position = value;
}
public function get vector():Vector3D { return _vector; }
public function set vector(value:Vector3D):void
{
_vector = value;
_vector.normalize();
}
public function get strength():Number { return _strength; }
public function set strength(value:Number):void
{
_strength = value;
}
public function reflect(_normal: Vector3D): void {
var normal: Vector3D = _normal.clone();
normal.normalize();
var rvector: Vector3D = normal.clone();
rvector.scaleBy(normal.dotProduct(vector) * - 2);
vector.incrementBy(rvector);
}
public function refract(_normal: Vector3D, refractiveIndex1: Number, refractiveIndex2: Number): void {
var normal: Vector3D = _normal.clone();
normal.normalize();
var cosI: Number = normal.dotProduct(vector);
var sinI: Number = Math.sqrt(1 - cosI * cosI);
var sinR: Number = (refractiveIndex1 / refractiveIndex2) * sinI;
var cosR: Number = Math.sqrt(1 - sinR * sinR);
var direction: Vector3D = normal.clone();
var vvv: Vector3D = vector.clone();
direction.scaleBy(- cosI);
direction.incrementBy(vector);
direction.normalize();
//if (sinI < refractiveIndex1 / refractiveIndex2) {
vector = normal.clone();
vector.scaleBy( - cosR);
direction.scaleBy(sinR);
vector.incrementBy(direction);
//}
}
}