forked from: Alternativa3D next one
Alternativa3D を簡単に扱うためのベーシックテンプレート
@author Yasu (clockmaker)
/**
* Copyright grover_FD ( http://wonderfl.net/user/grover_FD )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/uCVk
*/
// forked from narutohyper's Alternativa3D next one
package {
import alternativ5.engine3d.materials.TextureMaterial;
import alternativ5.engine3d.materials.MovieClipMaterial
import alternativ5.engine3d.materials.WireMaterial;
import alternativ5.engine3d.materials.FillMaterial;
import alternativ5.engine3d.primitives.Box;
import alternativ5.engine3d.core.Object3D;
import alternativ5.engine3d.primitives.Plane;
import alternativ5.engine3d.core.Vertex;
import alternativ5.utils.MathUtils
import alternativ5.engine3d.events.MouseEvent3D
import alternativ5.types.Point3D;
import alternativ5.types.Texture;
import flash.display.Sprite;
import flash.display.MovieClip;
import flash.filters.BitmapFilterQuality;
import flash.filters.BlurFilter;
import flash.display.BlendMode;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.display.GradientType;
import flash.events.MouseEvent;
import flash.geom.Matrix;
import flash.geom.Point;
import caurina.transitions.Tweener;
[SWF(width = 465, height = 465, frameRate = 60,backgroundColor=0xFFFFFF)]
/**
* Alternativa3D を簡単に扱うためのベーシックテンプレート
* @author Yasu (clockmaker)
*/
public class SimpleDemo extends Sprite {
private var base:Object3D
public function SimpleDemo():void {
// テンプレートを作成します
var template:BasicTemplate = new BasicTemplate();
addChild(template);
template.camera.z=-1200
// それっぽいマテリアルを作成します
//お絵かき用Sprite
var tempSprite:Sprite=new Sprite();
var colors:Array=new Array(0xCCCCCC,0xEEEEEE)
var alphas:Array=new Array(1,1)
var ratios:Array=new Array(0,255)
var mtx:Matrix=new Matrix()
mtx.createGradientBox(300,300,Math.PI/4,0,0)
tempSprite.graphics.beginGradientFill(GradientType.LINEAR,colors, alphas, ratios, mtx)
tempSprite.graphics.drawRect(0,0,300,300)
var bmd:BitmapData=new BitmapData(300,300,false,0xFFFFFFFF)
bmd.draw(tempSprite)
var material:TextureMaterial = new TextureMaterial(new Texture(bmd),1,false,true);
//var material:FillMaterial = new FillMaterial(0xFF0000);
//var material:WireMaterial = new WireMaterial();
// ベースを作成します
base=new Object3D()
template.scene.root.addChild(base);
// プリミティブを作成します
var box:Array=[];
box[0] = new Box(500, 300, 100,1,1,2);
box[0].cloneMaterialToAllSurfaces(material);
//先を少し尖らせる
box[0].getVertexById('0_1_1').x=-300
box[0].getVertexById('0_0_1').x=-300
// 不要な面を削除(TOP、FRONTが方向逆なんで注意・・・alternativa3Dの座標系、Z上下=がデフォルトなんで。。。orz)
//front 上面
//back 下面
//top 後面
//bottom 前面
//left とがった方
//right その逆
box[0].removeSurface(box[0].getSurfaceById('top'))
box[0].removeSurface(box[0].getSurfaceById('bottom'));
//適当にUVを調整
box[0].setUVsToFace(new Point(0, 0), new Point(1, 0), new Point(1, 1), box[0].getFaceById("left_0_0"));
box[0].setUVsToFace(new Point(0, 0), new Point(1, 0), new Point(1, 1), box[0].getFaceById("left_0_1"));
//2分割されてる平面はUV設定が面倒なので、Textureを回転させて、個別に設定
mtx=new Matrix()
mtx.translate(0,-300)
mtx.rotate(MathUtils.toRadian(90))
var bmd2:BitmapData=new BitmapData(300,300,false,0xFFFF0000)
bmd2.draw(tempSprite,mtx)
var material2:TextureMaterial = new TextureMaterial(new Texture(bmd2),1,false,true);
box[0].setMaterialToSurface(material2,'right');
//影を作る
//影用のTextureを描画
tempSprite.graphics.clear()
tempSprite.graphics.beginFill(0x000000)
tempSprite.graphics.moveTo(50,0)
tempSprite.graphics.lineTo(0,50)
tempSprite.graphics.lineTo(50,100)
tempSprite.graphics.lineTo(550,100)
tempSprite.graphics.lineTo(550,0)
tempSprite.graphics.endFill()
var filter:BlurFilter = new BlurFilter(50, 50, BitmapFilterQuality.HIGH);
var myFilters:Array = [filter]
tempSprite.filters = myFilters;
//addChild(tempSprite)
var bmd3:BitmapData=new BitmapData(650,200,true,0x00000000)
mtx=new Matrix()
mtx.translate(50,50)
bmd3.draw(tempSprite,mtx)
var shadow:Plane = new Plane(640,170,1,1,false,true)
//shadow.cloneMaterialToAllSurfaces(new WireMaterial(0x000000));
shadow.cloneMaterialToAllSurfaces(new TextureMaterial(new Texture(bmd3),0.3,false,true));
//shadow.getVertexById('0_1').x=-300
shadow.x=-25
shadow.y=200
shadow.rotationX=MathUtils.toRadian(-90)
box[0].addChild(shadow)
//Faseの確認
/*
var item:String
for (item in box[0].faces) {
trace(item)
}
*/
//Vertexの確認
/*
for (item in box[0].vertices) {
trace(item,box[0].getVertexById(item).coords)
//この2つをいじる
//0_1_1 [Point3D X: -300.000 Y:150.000 Z:0.000]
//0_0_1 [Point3D X: -300.000 Y:-150.000 Z:0.000]
}
*/
box[1]=box[0].clone()
box[2]=box[0].clone()
box[3]=box[0].clone()
box[0].x=-370
box[0].rotationY=MathUtils.toRadian(-180)
box[1].z=-370
box[1].rotationY=MathUtils.toRadian(90)
box[2].x=370
box[3].z=370
box[3].rotationY=MathUtils.toRadian(-90)
//削除した、面にそれぞれ、アクセスできるよう&アニメできるように、MovieClipTextureをplaneにして貼り付ける
//配列とかDictionaryとか使うとBetterだけど、こんかいは、そのまま
//1ページ目、表
var pl0_0_0:MovieClipPlane=new MovieClipPlane(true,0x999999)
box[0].addChild(pl0_0_0)
//1ページ目、裏
var pl0_1_0:MovieClipPlane=new MovieClipPlane(false,0x999999)
box[0].addChild(pl0_1_0)
//2ページ目、表
var pl1_0_0:MovieClipPlane=new MovieClipPlane(true,0xFF00FF)
box[1].addChild(pl1_0_0)
//2ページ目、裏
var pl1_1_0:MovieClipPlane=new MovieClipPlane(false,0xFFFF00)
box[1].addChild(pl1_1_0)
//3ページ目、表
var pl2_0_0:MovieClipPlane=new MovieClipPlane(true,0x999999)
box[2].addChild(pl2_0_0)
var pl2_1_0:MovieClipPlane=new MovieClipPlane(false,0x999999)
box[2].addChild(pl2_1_0)
//4ページ目、表
var pl3_0_0:MovieClipPlane=new MovieClipPlane(true,0xFF00FF,166,100, 0-(250-(166/2)),0-100)
var pl3_0_1:MovieClipPlane=new MovieClipPlane(true,0xFF00FF,167,100,166-(250-(166/2)),0-100)
var pl3_0_2:MovieClipPlane=new MovieClipPlane(true,0xFF00FF,167,100,333-(250-(166/2)),0-100)
var pl3_0_3:MovieClipPlane=new MovieClipPlane(true,0xFF00FF,166,100, 0-(250-(167/2)),100-100)
var pl3_0_4:MovieClipPlane=new MovieClipPlane(true,0xFF00FF,167,100,166-(250-(167/2)),100-100)
var pl3_0_5:MovieClipPlane=new MovieClipPlane(true,0xFF00FF,167,100,333-(250-(167/2)),100-100)
var pl3_0_6:MovieClipPlane=new MovieClipPlane(true,0xFF00FF,166,100, 0-(250-(167/2)),200-100)
var pl3_0_7:MovieClipPlane=new MovieClipPlane(true,0xFF00FF,167,100,166-(250-(167/2)),200-100)
var pl3_0_8:MovieClipPlane=new MovieClipPlane(true,0xFF00FF,167,100,333-(250-(167/2)),200-100)
box[3].addChild(pl3_0_0)
box[3].addChild(pl3_0_1)
box[3].addChild(pl3_0_2)
box[3].addChild(pl3_0_3)
box[3].addChild(pl3_0_4)
box[3].addChild(pl3_0_5)
box[3].addChild(pl3_0_6)
box[3].addChild(pl3_0_7)
box[3].addChild(pl3_0_8)
//4ページ目、裏
var pl3_1_0:MovieClipPlane=new MovieClipPlane(false,0xFFFF00)
box[3].addChild(pl3_1_0)
base.addChild(box[0]);
base.addChild(box[1]);
base.addChild(box[2]);
base.addChild(box[3]);
//プリミティブのロールオーバー、クリックを有効にする為
template.view.buttonMode = true;
template.view.interactive = true;
//送りButtonと戻りButtonの作成
makeInterface()
base.rotationY=MathUtils.toRadian(45)
// Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
// レンダリング前に実行したい処理を記述します。
template.onPreRender = function():void {
// 立方体を回転させます (角度はラジアン)
//base.rotationY += 1 * Math.PI / 180;
// マウスがステージの高さ何%の位置にあるか算出
var rateY:Number = mouseY / stage.stageHeight;
// カメラの高さの座標を調整
// イージングの公式 対象の値 += (目標値 - 現在の値) * 減速率
template.camera.y += ( - 1000 * rateY - template.camera.y) * 0.1;
// カメラの座標を中央に向かせる
template.cameraContoller.lookAt(new Point3D());
}
}
private function makeInterface():void {
var trans:String="linear";
var action:Boolean= true;
//送りButtonと戻りButtonの作成
var goBt:Sprite=new Sprite()
var backBt:Sprite=new Sprite()
var goArrow:Sprite=new Sprite()
var backArrow:Sprite=new Sprite()
goArrow.graphics.beginFill(0x666666,1)
goArrow.graphics.moveTo(-10,-10)
goArrow.graphics.lineTo(10,0)
goArrow.graphics.lineTo(-10,10)
goArrow.graphics.endFill()
backArrow.graphics.beginFill(0x666666,1)
backArrow.graphics.moveTo(10,-10)
backArrow.graphics.lineTo(-10,0)
backArrow.graphics.lineTo(10,10)
backArrow.graphics.endFill()
goBt.addChild(goArrow)
goArrow.x=25
goArrow.y=300;
backBt.addChild(backArrow)
backArrow.x=25
backArrow.y=300
goBt.buttonMode=true
backBt.buttonMode=true
goBt.mouseChildren=false
backBt.mouseChildren=false
goBt.graphics.beginFill(0xFFFFFF,1)
goBt.graphics.drawRect(0,0,50,50)
this.addChild(goBt)
goBt.x=this.stage.stageWidth-50;
backBt.graphics.beginFill(0xFFFFFF,1)
backBt.graphics.drawRect(0,0,50,50)
this.addChild(backBt)
goBt.addEventListener(MouseEvent.CLICK, onGoClick);
goBt.addEventListener(MouseEvent.MOUSE_OVER, onGoMouseOver);
goBt.addEventListener(MouseEvent.MOUSE_OUT, onGoMouseOut);
backBt.addEventListener(MouseEvent.CLICK, onBackClick);
backBt.addEventListener(MouseEvent.MOUSE_OVER, onBackMouseOver);
backBt.addEventListener(MouseEvent.MOUSE_OUT, onBackMouseOut);
var nextR:Number=MathUtils.toRadian(45)
function onGoClick(e:MouseEvent):void {
if (action) {
nextR+=MathUtils.toRadian(90)
Tweener.addTween(base, {rotationY:nextR,time:1,transition:trans,onComplete:actionEnd});
Tweener.addTween(base, {z:150,time:0.5,transition:trans});
Tweener.addTween(base, {z:0,time:0.5,delay:0.5,transition:trans});
action=false
}
}
function actionEnd():void {
action=true
}
function onGoMouseOver(e:MouseEvent):void {
Tweener.addTween(goArrow, {x:30,time:0.5,transition:trans});
}
function onGoMouseOut(e:MouseEvent):void {
goArrow.x=25
}
function onBackClick(e:MouseEvent):void {
if (action) {
nextR+=MathUtils.toRadian(-90)
Tweener.addTween(base, {rotationY:nextR,time:1,transition:trans,onComplete:actionEnd});
Tweener.addTween(base, {z:150,time:0.2,transition:trans});
Tweener.addTween(base, {z:0,time:0.5,delay:0.5,transition:trans});
action=false
}
}
function onBackMouseOver(e:MouseEvent):void {
Tweener.addTween(backArrow, {x:20,time:0.2,transition:trans});
}
function onBackMouseOut(e:MouseEvent):void {
backArrow.x=25
}
}
}
}
import alternativ5.engine3d.primitives.Plane;
import alternativ5.engine3d.materials.MovieClipMaterial
import alternativ5.utils.MathUtils
import flash.display.MovieClip;
import flash.filters.BitmapFilterQuality;
import flash.filters.BlurFilter;
import flash.display.BlendMode;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.display.GradientType;
import flash.geom.Matrix;
import flash.geom.Point;
import alternativ5.engine3d.events.MouseEvent3D
import caurina.transitions.Tweener;
//とりあえずのMovieClipMaterialなPlaneを作るクラス
class MovieClipPlane extends Plane {
private var trans:String="linear";
private var effect:Sprite
private var light:Sprite
//引数の並びちょっと変ですが・・・w
public function MovieClipPlane(side:Boolean=false,color:uint=0x666666,planeWidth:Number=500,planeHeight:Number=300,_x:Number=0,_y:Number=0) {
var mc:MovieClip=new MovieClip()
effect=new Sprite();
light=new Sprite();
effect.graphics.beginFill(0xFF0000,1)
effect.graphics.drawRect(0,0,planeWidth,planeHeight)
effect.alpha=0
light.graphics.beginFill(0xFFFFFF,1)
light.graphics.drawRect(0,0,planeWidth,planeHeight)
light.alpha=0
var colors:Array=new Array(0xFFFFFF,color)
var alphas:Array=new Array(1,1)
var ratios:Array=new Array(0,255)
var mtx:Matrix=new Matrix()
mtx.createGradientBox(planeWidth,planeHeight,Math.PI/4,0,0)
mc.graphics.beginGradientFill(GradientType.LINEAR,colors, alphas, ratios, mtx)
mc.graphics.drawRect(0,0,planeWidth,300)
mtx=new Matrix()
mtx.translate(0,-planeHeight)
mtx.rotate(MathUtils.toRadian(90))
mc.addChild(effect);
mc.addChild(light);
var mt:MovieClipMaterial = new MovieClipMaterial(mc,planeHeight,planeWidth,null,mtx);
super(planeHeight,planeWidth,1,1,false,side)
if (side) {
this.setMaterialToSurface(mt,'back');
this.rotationZ=(MathUtils.toRadian(-90))
this.z=-50
} else {
this.setMaterialToSurface(mt,'front');
this.rotationZ=(MathUtils.toRadian(-90))
this.z=50
}
this.x=_x
this.y=_y
this.addEventListener(MouseEvent3D.CLICK, onClick);
this.addEventListener(MouseEvent3D.MOUSE_OVER, onMouseOver);
this.addEventListener(MouseEvent3D.MOUSE_OUT, onMouseOut);
}
private function onClick(e:MouseEvent3D):void {
effect.alpha=1
Tweener.removeTweens(light)
Tweener.addTween(effect, {alpha:0,time:0.5,transition:trans});
}
private function onMouseOver(e:MouseEvent3D):void {
effect.alpha=0
Tweener.removeTweens(effect)
Tweener.addTween(light, {alpha:0.5,time:0.5,transition:trans});
}
private function onMouseOut(e:MouseEvent3D):void {
effect.alpha=0
Tweener.removeTweens(effect)
Tweener.addTween(light, {alpha:0,time:0.5,transition:trans});
}
}
import alternativ5.engine3d.controllers.CameraController;
import alternativ5.engine3d.core.Camera3D;
import alternativ5.engine3d.core.Object3D;
import alternativ5.engine3d.core.Scene3D;
import alternativ5.engine3d.display.View;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageQuality;
import flash.display.StageScaleMode;
import flash.events.Event;
/**
* BasicTemplate for Alternativa3D
* Alternativa3Dを扱いやすくするためのテンプレートです
* @author Yasu
*/
class BasicTemplate extends Sprite{
/**
* シーンインスタンスです。
*/
public var scene:Scene3D;
/**
* ビューインスタンスです。
*/
public var view:View;
/**
* カメラインスタンスです。
*/
public var camera:Camera3D;
/**
* カメラコントローラーです。
*/
public var cameraContoller:CameraController;
private var _viewWidth:int;
private var _viewHeight:int;
private var _scaleToStage:Boolean;
/**
* 新しい BasicTemplate インスタンスを作成します。
* @param viewWidth
* @param viewHeight
* @param scaleToStage
*/
public function BasicTemplate(viewWidth:int=640, viewHeight:int=480, scaleToStage:Boolean = true) {
_viewWidth = viewWidth;
_viewHeight = viewHeight;
_scaleToStage = scaleToStage;
// Creating scene
scene = new Scene3D();
scene.splitAnalysis = false; // not analysis for performance
scene.root = new Object3D();
// Adding camera
camera = new Camera3D();
camera.z = -1000;
scene.root.addChild(camera);
// camera contoller
cameraContoller = new CameraController(this);
cameraContoller.camera = camera;
// set view
view = new View();
view.camera = camera;
addChild(view);
// stage
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
/**
* 初期化されたときに実行されるイベントです。
* 初期化時に実行したい処理をオーバーライドして記述します。
*/
protected function atInit():void {}
/**
* 初期化されたときに実行されるイベントです。
* 初期化時に実行したい処理を記述します。
*/
private var _onInit:Function = function():void { };
public function get onInit():Function { return _onInit; }
public function set onInit(value:Function):void {
_onInit = value;
}
/**
* Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
* レンダリング前に実行したい処理をオーバーライドして記述します。
*/
protected function atPreRender():void {}
/**
* Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
* レンダリング前に実行したい処理を記述します。
*/
private var _onPreRender:Function = function():void{};
public function get onPreRender():Function { return _onPreRender; }
public function set onPreRender(value:Function):void {
_onPreRender = value;
}
/**
* Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
* レンダリング後に実行したい処理をオーバーライドして記述します。
*/
protected function atPostRender():void {
}
/**
* Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
* レンダリング後に実行したい処理を記述します。
*/
protected var _onPostRender:Function = function():void{};
public function get onPostRender():Function { return _onPostRender; }
public function set onPostRender(value:Function):void {
_onPostRender = value;
}
/**
* レンダリングを開始します。
*/
public function startRendering():void {
addEventListener(Event.ENTER_FRAME, onRenderTick);
}
/**
* レンダリングを停止します。
*/
public function stopRendering():void {
removeEventListener(Event.ENTER_FRAME, onRenderTick);
}
/**
* シングルレンダリング(レンダリングを一回だけ)を実行します。
*/
public function singleRender():void {
onRenderTick();
}
/**
* @private
*/
private function init(e:Event = null):void {
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.quality = StageQuality.HIGH;
// resize
stage.addEventListener(Event.RESIZE, onResize);
onResize(null);
// render
startRendering();
atInit();
_onInit();
}
/**
* @private
*/
private function onRenderTick(e:Event = null):void {
atPostRender();
_onPostRender();
scene.calculate();
atPreRender();
_onPreRender();
}
/**
* @private
*/
private function onResize(event:Event = null):void {
if (_scaleToStage) {
view.width = stage.stageWidth;
view.height = stage.stageHeight;
}else {
view.width = _viewWidth;
view.height = _viewHeight;
}
}
}