/**
* Copyright liquid.cow ( http://wonderfl.net/user/liquid.cow )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/pNAF
*/
package {
import alternativ7.engine3d.containers.KDContainer;
import alternativ7.engine3d.core.Camera3D;
import alternativ7.engine3d.core.Face;
import alternativ7.engine3d.core.MouseEvent3D;
import alternativ7.engine3d.core.Object3D;
import alternativ7.engine3d.core.RayIntersectionData;
import alternativ7.engine3d.core.View;
import alternativ7.engine3d.materials.FillMaterial;
import alternativ7.engine3d.primitives.Box;
import gs.*;
import gs.easing.Sine;
import flash.display.Sprite;
import flash.display.Stage;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Matrix3D;
import flash.geom.Vector3D;
import flash.geom.Point;
/**
*
* Alternativa3D 7.6
*
* Camera3D, Matrix3D, pointAt
*
* @author liquid.cow
*/
[SWF(backgroundColor="#FFFFFF", frameRate="100", width="800", height="600")]
public class Test extends Sprite
{
private static const V_CAMERA_INIT : Vector3D = new Vector3D(0, 3000, -4000);
private static const CAM_DISTANCE : Number = 1100;
private static const RAD2DEG : Number = 180 / Math.PI;
private static const DEG2RAD : Number = Math.PI / 180;
private var _container : KDContainer;
private var _camera : Camera3D;
private var _vCam : Vector3D;
private var _vCamTarget : Vector3D;
private var _cameraMatrix : Matrix3D;
private var _camRotationY : Number;
private var _vMouse3D : Vector3D;
private var _clickedFace : Face;
public function Test() : void {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event=null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
_camera = new Camera3D();
_camera.view = new View(stage.stageWidth, stage.stageHeight);
//_camera.view.interactive = true;
addChild(_camera.view);
_container = new KDContainer();
_container.resolveByAABB = true;
_container.resolveByOOBB = true;
_container.addChild(_camera);
_vCamTarget = new Vector3D();
_vCam = V_CAMERA_INIT.clone();
_camRotationY = 0;
var positions:Vector.<Vector3D> = new Vector.<Vector3D>();
positions.push(new Vector3D(-500, 0, -500), new Vector3D(500, 0, -500), new Vector3D(0, 0, 500));
var rotations:Vector.<Number> = new Vector.<Number>();
rotations.push(45 * DEG2RAD, -45 * DEG2RAD, 0);
var material:FillMaterial = new FillMaterial(0xeeeeee, 1, 0, 0x0);
for (var i:int = 0; i<3; i++) {
var box:Box = new Box(200, 100, 300, 1, 1, 1);
box.x = positions[i].x;
box.y = positions[i].y;
box.z = positions[i].z;
box.rotationY = rotations[i];
box.setMaterialToAllFaces(material);
box.addEventListener(MouseEvent3D.CLICK, onClick);
_container.addChild(box);
}
_camera.render();
stage.addEventListener(Event.RESIZE, onResize);
_camera.view.addEventListener(MouseEvent.CLICK, onStageClick);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
addEventListener(Event.ENTER_FRAME, render);
onResize();
}
private function onClick(e:MouseEvent3D):void
{
var camRotationY:Number;
var tempObject:Object3D = e.target as Object3D;
var vPos:Vector3D = new Vector3D(tempObject.x, tempObject.y, tempObject.z);
var data:RayIntersectionData = tempObject.intersectRay(e.localOrigin, e.localDirection);
_clickedFace = data.face;
var distance:Number = 1100;
var v : Vector3D = _clickedFace.normal.clone();
v.scaleBy(distance);
v = v.add(new Vector3D(_clickedFace.normal.x * tempObject.boundMaxX, _clickedFace.normal.y * tempObject.boundMaxY, _clickedFace.normal.z * tempObject.boundMaxZ));
var objectTransform:Matrix3D = tempObject.matrix.clone();
v = objectTransform.transformVector(v);
v.z -= _clickedFace.normal.y != 0 ? .01 : 0; // Hack for parallel view to up vector
camRotationY = _clickedFace.normal.y != 0 ? tempObject.rotationY : 0;
moveCamera(vPos, v, camRotationY);
}
private function moveCamera(vTarget : Vector3D, vCam : Vector3D, camRotationY_:Number) : void
{
TweenLite.killTweensOf(_vCamTarget);
TweenLite.to(_vCamTarget, 1, {x:vTarget.x, y:vTarget.y, z:vTarget.z, ease:Sine.easeInOut});
TweenLite.killTweensOf(this);
TweenLite.to(this, 1, {camRotationY:camRotationY_, ease:Sine.easeInOut});
TweenLite.killTweensOf(_vCam);
TweenLite.to(_vCam, 1, {x:vCam.x, y:vCam.y, z:vCam.z, ease:Sine.easeInOut});
}
private function render( event:Event ) : void
{
_cameraMatrix = new Matrix3D();
_cameraMatrix.identity();
_cameraMatrix.appendTranslation(_vCam.x, _vCam.y, _vCam.z);
_cameraMatrix.appendRotation(_camRotationY * RAD2DEG, Vector3D.Y_AXIS, _vCamTarget);
_cameraMatrix.pointAt(new Vector3D(_vCamTarget.x, _vCamTarget.y, _vCamTarget.z), Vector3D.Z_AXIS, Vector3D.Y_AXIS);
_camera.matrix = _cameraMatrix;
_camera.render();
}
public function onResize(event:Event = null) :void
{
_camera.view.width = stage.stageWidth;
_camera.view.height = stage.stageHeight;
_camera.fov = 2 * Math.atan2(Math.sqrt(_camera.view.width * _camera.view.width + _camera.view.height * _camera.view.height) / 2, 1100);
}
private function onStageClick(event : MouseEvent) : void
{
var a:Array = _camera.view.getObjectsUnderPoint(new Point(_camera.view.mouseX, _camera.view.mouseY));
if (a.length==0) {
_clickedFace = null;
moveCamera(new Vector3D(), V_CAMERA_INIT.clone(), 0);
}
}
private function onMouseMove(event : MouseEvent) : void {
if (event.target is Stage) {
var origin:Vector3D = new Vector3D();
var directionA:Vector3D = new Vector3D();
var directionB:Vector3D = new Vector3D();
_camera.calculateRay(origin, directionA, _camera.view.width / 2, _camera.view.height / 2);
_camera.calculateRay(origin, directionB, stage.mouseX, stage.mouseY);
var pos : Vector3D = intersectionPoint(origin, directionB, new Vector3D(0, 0, 0), new Vector3D(0, 1, 0));
_vMouse3D = new Vector3D(pos.x, pos.y, pos.z);
}
}
public static function intersectionPoint(lineStart:Vector3D, lineDirection:Vector3D, planePosition:Vector3D, planeNormal:Vector3D):Vector3D {
var result:Vector3D = new Vector3D();
var w:Vector3D = lineStart.subtract(planePosition);
var d:Number = planeNormal.dotProduct(lineDirection);
var n:Number = -planeNormal.dotProduct(w);
var sI:Number = n / d;
result.x = lineStart.x + (lineDirection.x * sI);
result.y = lineStart.y + (lineDirection.y * sI);
result.z = lineStart.z + (lineDirection.z * sI);
return result;
}
public function get camRotationY() : Number {
return _camRotationY;
}
public function set camRotationY(camRotationY : Number) : void {
_camRotationY = camRotationY;
}
public function get vCamTarget() : Vector3D {
return _vCamTarget;
}
public function set vCamTarget(vCamTarget : Vector3D) : void {
_vCamTarget = vCamTarget;
}
public function get vCam() : Vector3D {
return _vCam;
}
public function set vCam(vCam : Vector3D) : void {
_vCam = vCam;
}
}
}