/**
* Copyright zahir ( http://wonderfl.net/user/zahir )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/xrbr
*/
package
{
import com.adobe.utils.AGALMiniAssembler;
import flash.display.Sprite;
import flash.display.Stage3D;
import flash.display3D.Context3D;
import flash.display3D.Context3DProgramType;
import flash.display3D.Context3DRenderMode;
import flash.display3D.Context3DVertexBufferFormat;
import flash.display3D.IndexBuffer3D;
import flash.display3D.Program3D;
import flash.display3D.VertexBuffer3D;
import flash.events.Event;
import flash.geom.Matrix;
import flash.geom.Matrix3D;
import flash.geom.PerspectiveProjection;
import flash.geom.Rectangle;
import flash.geom.Vector3D;
[SWF(width="640", height="480", frameRate="60")]
public class molehillTest2 extends Sprite
{
private var world:Stage3D;
private var context:Context3D;
private var program:Program3D;
private var indexBuffer:IndexBuffer3D;
private var vertexBuffer:VertexBuffer3D;
private var rot:Number = 0;
private var mtx:Matrix3D;
private var m_identity:Vector.<Number>;
private const Z_Axis:Vector3D = Vector3D.Z_AXIS;
private var cam:Camera3D;
public function molehillTest2()
{
// init stage3D
world = stage.stage3Ds[0];
world.addEventListener( Event.CONTEXT3D_CREATE, onCreateStage3D );
world.requestContext3D( Context3DRenderMode.AUTO );
}
private function onCreateStage3D( e:Event ):void
{
trace("create");
world.removeEventListener( Event.CONTEXT3D_CREATE, onCreateStage3D );
// set Context3D
context = world.context3D;
if(context == null ) return;
context.configureBackBuffer( stage.stageWidth, stage.stageHeight, 8 );
// create vertices
vertexBuffer = context.createVertexBuffer( 3, 6 );
vertexBuffer.uploadFromVector( new <Number>[
0, 1, 0, 1, 0, 0,
-1, -1, 0, 0, 1, 0,
1, -1, 0, 0, 0, 1
], 0, 3 );
// create indices
indexBuffer = context.createIndexBuffer( 3 );
indexBuffer.uploadFromVector( new <uint>[0, 1, 2], 0, 3 );
// create program & shader's
var vertexShader:AGALMiniAssembler = new AGALMiniAssembler();
vertexShader.assemble( Context3DProgramType.VERTEX,
"m44 op va0, vc0 \n" +
"mov v0, va1"
);
var fragmentShader:AGALMiniAssembler = new AGALMiniAssembler();
fragmentShader.assemble( Context3DProgramType.FRAGMENT,
"mov oc, v0"
);
program = context.createProgram();
program.upload( vertexShader.agalcode, fragmentShader.agalcode );
context.setProgram( program );
// create Matrix3D
mtx = new Matrix3D();
m_identity = mtx.rawData;
cam = new Camera3D(45,4/3,0.1,1000);
cam.x = 2;
cam.y = -1;
cam.z = -10;
cam.lookAt = new Vector3D();
rot = 0;
addEventListener( Event.ENTER_FRAME, onEnter );
}
private var proj:PerspectiveProjection = new PerspectiveProjection();
private function onEnter( e:Event ):void
{
mtx.rawData = m_identity;
//mtx.appendRotation( rot, Z_Axis );
mtx.appendTranslation(0,0, -10);
cam.x = Math.sin( 0.01745 * rot ) * 5;
var m:Matrix3D = cam.getViewMatrix();
m.invert();
mtx.append( m );
mtx.append( cam.getProjectionMatrix() );
context.setProgramConstantsFromMatrix( Context3DProgramType.VERTEX, 0, mtx, true);
context.setVertexBufferAt(0, vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
context.setVertexBufferAt(1, vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_3);
context.clear( 0, 0, 0, 1 );
context.drawTriangles( indexBuffer, 0, 1 );
context.present();
rot++;
}
}
}
import flash.geom.Matrix3D;
import flash.geom.Vector3D;
class Camera3D
{
//*
private var _fov:Number;
private var _near:Number;
private var _far:Number;
private var _aspectRatio:Number;
private var _lookAt:Vector3D;
private var _up:Vector3D;
private var _pos:Vector3D;
protected var dir:Vector3D;
protected var view:Vector.<Number>;
protected var proj:Vector.<Number>;
protected var calculated:Boolean = false;
public function Camera3D( fov:Number = 45, aspectRatio:Number = 1.3333, near:Number = 0.1, far:Number = 100)
{
this.fov = fov;
this.aspectRatio = aspectRatio;
this.near = near;
this.far = far;
up = new Vector3D(0,1,0);
_pos = new Vector3D();
dir = new Vector3D();
lookAt = new Vector3D();
view = new Vector.<Number>(16, false);
proj = new Vector.<Number>(16, false);
calc();
}
public function getProjectionMatrix():Matrix3D
{
if( calculated == false ) calc();
return new Matrix3D( proj );
}
public function getViewMatrix():Matrix3D
{
if( calculated == false ) calc();
return new Matrix3D( view );
}
public function projectionRawData():Vector.<Number>
{
if( calculated == false ) calc();
return proj.slice();
}
public function viewRawData():Vector.<Number>
{
if( calculated == false ) calc();
return view.slice();
}
protected function calc():void
{
calcView();
calcProj();
calculated = true;
}
protected function calcView():void
{
var Z:Vector3D = direction;
var X:Vector3D = up.crossProduct( Z );
var Y:Vector3D = Z.crossProduct( X );
var v:Vector.<Number> = view;
v[3] = v[7] = v[11] = 0;
v[0] = X.x; v[1] = Y.x; v[2] = Z.x;
v[4] = X.y; v[5] = Y.y; v[6] = Z.y;
v[8] = X.z; v[9] = Y.z; v[10] = Z.z;
v[12] = position.dotProduct( X ) * -1;
v[13] = position.dotProduct( Y ) * -1;
v[14] = position.dotProduct( Z ) * -1;
v[15] = 1;
}
protected function calcProj():void
{
var ymax:Number = near * Math.tan( fov * Math.PI / 360 );
var xmax:Number = ymax * aspectRatio;
var left:Number = -xmax;
var right:Number = xmax;
var top:Number = ymax;
var bottom:Number = -ymax;
var t1:Number = 2 * near;
var t2:Number = right - left;
var t3:Number = top - bottom;
var t4:Number = far - near;
var v:Vector.<Number> = proj;
v[0] = t1 / t2;
v[1] = v[2] = v[3] = v[4] = v[6] = v[7] = v[12] = v[13] = v[15] = 0;
v[5] = t1 / t3;
v[8] = (right + left) / t2;
v[9] = (top + bottom) / t3;
v[10] = (-far - near) / t4;
v[11] = -1.0;
v[14] = (-t1 * far) / t4;
}
public function get direction():Vector3D
{
if( calculated == true ) return dir;
dir.x = lookAt.x - _pos.x;
dir.y = lookAt.y - _pos.y;
dir.z = lookAt.z - _pos.z;
dir.normalize();
return dir;
}
public function get x():Number
{
return -_pos.x;
}
public function set x( value:Number ):void
{
_pos.x = -value;
calculated = false;
}
public function get y():Number
{
return -_pos.y;
}
public function set y( value:Number ):void
{
_pos.y = -value;
calculated = false;
}
public function get z():Number
{
return _pos.z;
}
public function set z( value:Number ):void
{
_pos.z = value;
calculated = false;
}
public function get position():Vector3D
{
return _pos;
}
public function set position(value:Vector3D):void
{
x = value.x;
y = value.y;
z = value.z;
calculated = false;
}
public function get up():Vector3D
{
return _up;
}
public function set up(value:Vector3D):void
{
_up = value;
calculated = false;
}
public function get lookAt():Vector3D
{
return _lookAt;
}
public function set lookAt(value:Vector3D):void
{
_lookAt = value;
calculated = false;
}
public function get fov():Number
{
return _fov;
}
public function set fov(value:Number):void
{
value = value < 1 ? 1 : value >= 180 ? 179 : value;
_fov = value;
calculated = false;
}
/*
public function get zoom():Number
{
return 1 / Math.tan( fov / 2 );
}
public function set zoom( value:Number ):void
{
fov = 2 * Math.atan( 1 / value );
calculated = false;
}
*/
public function get near():Number
{
return _near;
}
public function set near(value:Number):void
{
_near = value;
calculated = false;
}
public function get far():Number
{
return _far;
}
public function set far(value:Number):void
{
_far = value;
calculated = false;
}
public function get aspectRatio():Number
{
return _aspectRatio;
}
public function set aspectRatio(value:Number):void
{
_aspectRatio = value;
calculated = false;
}//*/
}