// 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=25 backBt.addChild(backArrow) backArrow.x=25 backArrow.y=25 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; } } } forked from: Alternativa3D next one