/**
* Copyright Kay ( http://wonderfl.net/user/Kay )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/feNT
*/
// forked from Kay's Rotation Cubes #2-2
// forked from Kay's Rotation Cubes #2
// forked from Kay's Rotation Cubes
/*
* addChildやrotationXなど2Dインスタンスで使い慣れたメソッドを用いて
* 3Dオブジェクトやカメラをコントロールする3Dエンジン
* カメラでいろいろ遊んでみるTEST
*/
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.utils.getTimer;
import net.hires.debug.Stats;
[ SWF (width = '465', height = '465', backgroundColor = '0xFFFFFF', frameRate = '60') ]
public class Main extends Sprite {
private var scene:Scene3D;
private var canvas:Sprite;
private var core:Joint3D;
private var head:Cube3D;
private var shoulder:Cube3D;
private var waist:Cube3D;
private var upperArmL:Cube3D;
private var upperArmR:Cube3D;
private var armL:Cube3D;
private var armR:Cube3D;
private var upperLegL:Cube3D;
private var upperLegR:Cube3D;
private var legL:Cube3D;
private var legR:Cube3D;
public function Main():void {
addChild( new Stats() );
canvas = new Sprite();
canvas.x=stage.stageWidth/2;
canvas.y=stage.stageHeight/2;
addChild(canvas);
scene = new Scene3D(canvas);
core = new Joint3D();
core.rotationY = 90;
scene.addChild(core);
waist = new Cube3D(50,25,25);
waist.color = 0xcc3333;
core.addChild(waist);
var jointShoulder:Joint3D = new Joint3D();
jointShoulder.y = -35;
waist.addChild(jointShoulder);
shoulder = new Cube3D(60,50,25);
shoulder.color = 0x33cc66;
shoulder.offsetV(0,-50,0);
shoulder.rotationX = 10;
jointShoulder.addChild(shoulder);
var jointHead:Joint3D = new Joint3D();
jointHead.y = -110;
shoulder.addChild(jointHead);
head = new Cube3D(30,30,30);
head.color = 0xcc9966;
head.offsetV(0,-30,0);
head.rotationX = -5;
jointHead.addChild(head);
var jointUpperArmL:Joint3D = new Joint3D();
jointUpperArmL.x = 90;
jointUpperArmL.y = -90;
shoulder.addChild(jointUpperArmL);
upperArmL = new Cube3D(20,40,20);
upperArmL.color = 0xcc9966;
upperArmL.offsetV(0,40,0);
jointUpperArmL.addChild(upperArmL);
var jointUpperArmR:Joint3D = new Joint3D();
jointUpperArmR.x = -90;
jointUpperArmR.y = -90;
shoulder.addChild(jointUpperArmR);
upperArmR = new Cube3D(20,40,20);
upperArmR.color = 0xcc9966;
upperArmR.offsetV(0,40,0);
jointUpperArmR.addChild(upperArmR);
var jointArmL:Joint3D = new Joint3D();
jointArmL.y = 80;
upperArmL.addChild(jointArmL);
armL = new Cube3D(20,40,20);
armL.color = 0xcc9966;
armL.offsetV(0,40,0);
jointArmL.addChild(armL);
var jointArmR:Joint3D = new Joint3D();
jointArmR.y = 80;
upperArmR.addChild(jointArmR);
armR = new Cube3D(20,40,20);
armR.color = 0xcc9966;
armR.offsetV(0,40,0);
jointArmR.addChild(armR);
var jointUpperLegL:Joint3D = new Joint3D();
jointUpperLegL.x = 30;
jointUpperLegL.y = 35;
waist.addChild(jointUpperLegL);
upperLegL = new Cube3D(20,40,20);
upperLegL.color = 0xcc9966;
upperLegL.offsetV(0,40,0);
jointUpperLegL.addChild(upperLegL);
var jointUpperLegR:Joint3D = new Joint3D();
jointUpperLegR.x = -30;
jointUpperLegR.y = 35;
waist.addChild(jointUpperLegR);
upperLegR = new Cube3D(20,40,20);
upperLegR.color = 0xcc9966;
upperLegR.offsetV(0,40,0);
jointUpperLegR.addChild(upperLegR);
var jointLegL:Joint3D = new Joint3D();
jointLegL.y = 90;
upperLegL.addChild(jointLegL);
legL = new Cube3D(20,40,20);
legL.color = 0xcc9966;
legL.offsetV(0,40,0);
jointLegL.addChild(legL);
var jointLegR:Joint3D = new Joint3D();
jointLegR.y = 90;
upperLegR.addChild(jointLegR);
legR = new Cube3D(20,40,20);
legR.color = 0xcc9966;
legR.offsetV(0,40,0);
jointLegR.addChild(legR);
addEventListener(Event.ENTER_FRAME,xRunning);
}
private function xRunning(e:Event):void {
var t:Number = getTimer()/400;
var sin:Number = Math.sin(t);
core.y = Math.abs(sin) * 35;
waist.rotationY = sin * -5;
waist.rotationZ = sin * 5;
shoulder.rotationY = sin * 10;
shoulder.rotationZ = sin * -5;
upperArmL.rotationX = sin * -50 + 10;
upperArmR.rotationX = sin * 50 + 10;
armL.rotationX = sin * -50 - 55;
armR.rotationX = sin * 50 - 55;
upperLegL.rotationX = sin * 50 - 10;
upperLegR.rotationX = sin * -50 - 10;
legL.rotationX = sin * 50 + 40;
legR.rotationX = sin * -50 + 40;
scene.camera.rotationX = canvas.mouseY/4;
scene.camera.rotationY = -canvas.mouseX/4;
scene.render();
}
}
}
import flash.display.Sprite;
import flash.geom.Point;
import flash.geom.Matrix3D;
import flash.geom.Vector3D;
import flash.geom.Utils3D;
import flash.geom.PerspectiveProjection;
import flash.display.TriangleCulling;
import frocessing.color.ColorHSL;
class Scene3D extends Sprite {
public var camera:Camera3D;
public var position:Vector3D;
public var canvas:Sprite;
public var objects:Array;
public var matrix3D:Matrix3D;
public function Scene3D(sprite:Sprite):void {
camera=new Camera3D();
canvas=sprite;
matrix3D = new Matrix3D();
}
public function render():void {
objects = new Array();
getAllChildren(this);
canvas.graphics.clear();
matrix3D = new Matrix3D();
matrix3D.appendRotation(camera.rotationX, Vector3D.X_AXIS);
matrix3D.appendRotation(camera.rotationY, Vector3D.Y_AXIS);
matrix3D.appendRotation(camera.rotationZ, Vector3D.Z_AXIS);
var cameraAngle:Vector3D = new Vector3D(camera.x,camera.y,camera.z+camera.proj.focalLength);
cameraAngle = matrix3D.transformVector(cameraAngle);
matrix3D.appendTranslation(cameraAngle.x, cameraAngle.y, cameraAngle.z);
var viewPoint:Vector3D = new Vector3D(cameraAngle.x, cameraAngle.y, -cameraAngle.z);
var lite3D:Vector3D = new Vector3D(-20,50,50);
lite3D.normalize();
var dispParts:Array = new Array();
for each (var object:Object in objects) {
object.matrix3D = new Matrix3D();
object.matrix3D.appendRotation(object.rotationX,Vector3D.X_AXIS);
object.matrix3D.appendRotation(object.rotationY,Vector3D.Y_AXIS);
object.matrix3D.appendRotation(object.rotationZ,Vector3D.Z_AXIS);
object.matrix3D.prependTranslation(object.x,object.y,object.z);
object.matrix3D.append(object.parent.matrix3D);
if (object.verts.length) {
object.projVerts2D = new Vector.<Number>();
var realVerts3D:Vector.<Number> = new Vector.<Number>();
var uvts:Vector.<Number> = new Vector.<Number>();
object.matrix3D.transformVectors(object.verts, realVerts3D);
Utils3D.projectVectors(camera.matrix3D, realVerts3D, object.projVerts2D, uvts);
var numParts:uint = object.indices.length/3;
for (var i:uint = 0; i < numParts; i++) {
var part:Part = new Part(object);
part.indices.push(object.indices[i*3+0],object.indices[i*3+1],object.indices[i*3+2]);
part.verts = new Vector.<Number>();
var vectors:Array = new Array();
var nX:Number = 0;
var nY:Number = 0;
var nZ:Number = 0;
for (var j:uint = 0; j < 3; j++) {
var vector:Vector3D = new Vector3D(realVerts3D[part.indices[j]*3+0],
realVerts3D[part.indices[j]*3+1],
realVerts3D[part.indices[j]*3+2]);
vectors.push(vector);
nX += vector.x;
nY += vector.y;
nZ += vector.z;
part.verts.push(object.projVerts2D[part.indices[j]*2+0]);
part.verts.push(object.projVerts2D[part.indices[j]*2+1]);
}
part.z = nZ/3;
part.distance = Vector3D.distance(viewPoint, new Vector3D(nX/3,nY/3,nZ/3));
var vA:Vector3D = vectors[0].subtract(vectors[1]);
var vB:Vector3D = vectors[0].subtract(vectors[2]);
part.normal = vA.crossProduct(vB);
part.normal.normalize();
var vV:Vector3D = vectors[0].subtract(new Vector3D(0,0,-camera.focalLength));
var dotProduct:Number = vV.dotProduct(part.normal);
if (dotProduct > 0) {
part.shadowRatio = lite3D.dotProduct(part.normal);
dispParts.push(part);
}
}
}
}
dispParts.sortOn(["z","distance"], [Array.NUMERIC|Array.DESCENDING,Array.NUMERIC|Array.DESCENDING]);
var numDispParts:uint = dispParts.length;
for (i = 0; i < numDispParts; i++) {
var hsl:ColorHSL = dispParts[i].object.colorHSL.clone();
var l:Number = hsl.l;
hsl.l = l + dispParts[i].shadowRatio/10;
var color:int = hsl.value;
canvas.graphics.beginFill(color);
canvas.graphics.drawTriangles(dispParts[i].verts);//, null, null, TriangleCulling.NEGATIVE);
canvas.graphics.endFill();
}
}
public function getAllChildren(container:Object):void {
var numChild:uint = container.numChildren;
for (var i:uint = 0; i < numChild; i++) {
var child:Object = container.getChildAt(i);
objects.push(child);
if (child.numChildren > 0) {
getAllChildren(child);
}
}
}
public function getNormal(verts:Vector.<Number>):Vector3D {
var normal:Vector3D = new Vector3D();
return normal;
}
}
class Part {
public var indices:Vector.<Number>;
public var verts:Vector.<Number>;
public var distance:Number;
public var object:Object;
public var z:Number;
public var normal:Vector3D;
public var shadowRatio:Number;
public function Part(obj:Object):void {
object = obj;
indices = new Vector.<Number>();
}
}
class Camera3D extends Sprite {
public var nDistance:Number;
public var matrix3D:Matrix3D;
public var fllow:Boolean=false;
public var proj:PerspectiveProjection;
public var normal:Vector3D;
public function Camera3D(nNum:Number = 55):void {
proj = new PerspectiveProjection();
fieldOfView = nNum;
}
public function set focalLength(nNum:Number):void {
proj.focalLength = nNum;
setting();
}
public function get focalLength():Number {
return proj.focalLength;
}
public function set fieldOfView(nNum:Number):void {
proj.fieldOfView = nNum;
setting();
}
public function get fieldOfView():Number {
return proj.fieldOfView;
}
public function set projectionCenter(nP:Point):void {
proj.projectionCenter = nP;
setting();
}
public function get projectionCenter():Point {
return proj.projectionCenter;
}
public function setting():void {
matrix3D = new Matrix3D();
matrix3D.appendTranslation(0,0,focalLength);
matrix3D.append(proj.toMatrix3D());
normal = Vector3D.Z_AXIS;
}
}
class Object3D extends Sprite {
public var matrix3D:Matrix3D = new Matrix3D();
public var verts:Vector.<Number> = new Vector.<Number>();
public var indices:Vector.<int> = new Vector.<int>();
public var parts:Array;
public var realVerts3D:Vector.<Number>;
public var projVerts2D:Vector.<Number>;
public var colorHSL:ColorHSL = new ColorHSL(0,0,0.5);
public function Object3D():void {
}
public function set color(nRGB:int):void {
colorHSL.r = nRGB >> 16 & 0xff;
colorHSL.g = nRGB >> 8 & 0xff;
colorHSL.b = nRGB & 0xff;
}
public function get color():int {
return colorHSL.value;
}
public function offsetV(nX:Number, nY:Number, nZ:Number):void {
var matrix3D:Matrix3D = new Matrix3D();
matrix3D.prependTranslation(nX,nY,nZ);
matrix3D.transformVectors(verts,verts);
}
}
class Joint3D extends Object3D {
public function Joint3D():void {
}
}
class Cube3D extends Object3D {
public function Cube3D(nWidth:Number=100, nHeight:Number=100, nDepth:Number=100):void {
verts.push(-nWidth,-nHeight,-nDepth);
verts.push( nWidth,-nHeight,-nDepth);
verts.push(-nWidth, nHeight,-nDepth);
verts.push( nWidth, nHeight,-nDepth);
verts.push(-nWidth,-nHeight, nDepth);
verts.push( nWidth,-nHeight, nDepth);
verts.push(-nWidth, nHeight, nDepth);
verts.push( nWidth, nHeight, nDepth);
indices.push(0,1,2,3,2,1);
indices.push(1,5,3,7,3,5);
indices.push(5,4,7,6,7,4);
indices.push(4,0,6,2,6,0);
indices.push(4,5,0,1,0,5);
indices.push(7,6,3,2,3,6);
}
}