package { import flash.accessibility.Accessibility; /* Alternativa3D & box2D = simple kaleidoscope 愚直な万華鏡 別にAlternativa3Dじゃなくてもいいんだけど、複数のcameraとViewをテストしたかっただけ @narutohyper */ 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 alternativ5.types.Point3D; import alternativ5.utils.* import flash.display.Shape; import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageQuality; import flash.display.StageScaleMode; import flash.events.Event; import flash.filters.BitmapFilter; import flash.filters.BitmapFilterQuality; import flash.filters.BlurFilter; import Box2D.Dynamics.b2Body; import flash.display.Sprite; import flash.events.Event; import flash.geom.Point; import flash.geom.Matrix; [SWF(width = 465, height = 465, frameRate = 30, backgroundColor=0)] public class SimpleDemo extends Sprite { private var view2d:b2View; private var kaleidoscope:Sprite; private var msk:Shape; public function SimpleDemo():void { FPS.init(stage); // テンプレートを作成します // Creating scene stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; stage.quality = StageQuality.HIGH; var scene:Scene3D = new Scene3D(); scene.splitAnalysis = false; // not analysis for performance scene.root = new Object3D(); kaleidoscope=new Sprite(); kaleidoscope.x=465/2 kaleidoscope.y=465/2 addChild(kaleidoscope) msk=new Shape(); msk.graphics.beginFill(0x000000) msk.graphics.drawCircle(x, y, 600/2); msk.x=465/2 msk.y=465/2 addChild(msk) kaleidoscope.mask=msk var mirrorArray:Array=[]; var tempY:Array=[2.5,3, 1.5,1, 0.5,0, 1.5,2, 3.5,3]; var mtr:Matrix=new Matrix() var radius:Number=100/Math.sin(60 * Math.PI / 180) for (var i:uint=0;i<34;i++) { mirrorArray.push(new mirrorView(scene)); kaleidoscope.addChild(mirrorArray[i]) mtr.createBox( (i%7%2)?1:-1, (Math.floor(i/7)%2)?-1:1, (i%7*60-180) * Math.PI / 180, i%7*100-300, ((i>13)?-1:1)*radius*tempY[(i%7%2)+Math.floor(i/7)*2] ) mirrorArray[i].transform.matrix=mtr; } view2d = new b2View(scene.root) for (var n:uint=0;n<20;n++) { view2d.CreateBeads((Math.random()*60+240) / b2View.SCALE, (Math.random()*60+240) / b2View.SCALE); } stage.addEventListener(Event.RESIZE, onResize); addEventListener(Event.ENTER_FRAME, onRendering); var pitch:Number=0.5 function onRendering(e:Event):void { kaleidoscope.rotation+=pitch for (var i:uint=0;i<mirrorArray.length;i++) { mirrorArray[i].onRendering(pitch); } view2d.onRendering(pitch) scene.calculate(); } } private function onResize(event:Event = null):void { kaleidoscope.x=stage.stageWidth/2; kaleidoscope.y=stage.stageHeight/2; msk.x=stage.stageWidth/2; msk.y=stage.stageHeight/2; } } } //cloneView //真上からcameraで取った物をlocalなViewに表示。View自体は、DisplayObjectなので、加工が可能 //Matrixで変換して、並べる import alternativ5.engine3d.controllers.CameraController; import alternativ5.engine3d.core.Camera3D; import alternativ5.engine3d.core.Scene3D; import alternativ5.engine3d.display.View; import alternativ5.types.Point3D; import flash.display.Sprite; import flash.display.GradientType; import flash.display.Shape; import flash.geom.Matrix; import frocessing.color.ColorHSV; class mirrorView extends Sprite{ private var camera:Camera3D private var back:Shape private var hs:ColorHSV private var he:ColorHSV private var counter:Number=0 public function mirrorView(scene:Scene3D) { //メインcameraをViewを作成 camera = new Camera3D(); camera.z = -650; scene.root.addChild(camera); camera.rotationZ=1*Math.PI/180 // set view var view:View = new View(); view.width=465 view.height=465 view.camera = camera; var sp:Sprite=new Sprite() sp.rotation=30 hs=new ColorHSV(); he=new ColorHSV(); hs.h=0 hs.s=0.05 he.h=0 he.s=0.3 he.v=0.7 back=new Shape() drawBack(0) sp.addChild(back); sp.addChild(view); view.x=-465/2 view.y=-465/2 this.addChild(sp); } public function onRendering(no:Number=1):void { counter+=0.5 drawBack(counter) camera.rotationZ+=no*Math.PI/180 } private function drawBack(no:Number):void { hs.h=no he.h=no back.graphics.clear(); var colors:Array=new Array(hs.value32,he.value32) var alphas:Array=new Array(1,1) var ratios:Array=new Array(0,255) var matrix:Matrix=new Matrix() matrix.createGradientBox(200,200,Math.PI/2,-100,-100) back.graphics.beginGradientFill(GradientType.RADIAL ,colors, alphas, ratios, matrix) var radius:Number=100/Math.sin(60 * Math.PI / 180) var star_commands:Vector.<int> = new Vector.<int>(4, true); star_commands[0] = 1; star_commands[1] = 2; star_commands[2] = 2; star_commands[3] = 2; var star_coord:Vector.<Number> = new Vector.<Number>(8, true); star_coord[0]=Math.sin((120*0-30)*Math.PI/180)*radius star_coord[1]=Math.cos((120*0-30)*Math.PI/180)*radius star_coord[2]=Math.sin((120*1-30)*Math.PI/180)*radius star_coord[3]=Math.cos((120*1-30)*Math.PI/180)*radius star_coord[4]=Math.sin((120*2-30)*Math.PI/180)*radius star_coord[5]=Math.cos((120*2-30)*Math.PI/180)*radius star_coord[6]=Math.sin((120*0-30)*Math.PI/180)*radius star_coord[7]=Math.cos((120*0-30)*Math.PI/180)*radius back.graphics.lineStyle(2,0x333333) back.graphics.drawPath(star_commands, star_coord); } } import alternativ5.engine3d.primitives.Cone; import alternativ5.engine3d.materials.FillMaterial; import alternativ5.utils.MeshUtils import alternativ5.engine3d.core.Object3D; import Box2D.Collision.b2AABB; import Box2D.Collision.Shapes.b2CircleDef; import Box2D.Dynamics.b2Body; import Box2D.Dynamics.b2BodyDef; import Box2D.Dynamics.b2World; import Box2D.Common.Math.b2Vec2; import Box2D.Collision.Shapes.b2PolygonDef; import flash.display.Sprite; import flash.display.BlendMode; import flash.events.Event; import flash.geom.Point; internal class b2View extends Sprite { public static var SCALE:int = 100; private var _world:b2World; private var _gravity:b2Vec2; private var _doSleep:Boolean; private var _worldAABB:b2AABB; private var _body:b2BodyDef; private var _bodyPolygon:b2Body; private var _altView:Object3D private var donut:b2Body public function b2View(altView:Object3D) { _altView=altView; // world; _worldAABB = new b2AABB(); _worldAABB.lowerBound.Set( -500.0, -500.0); _worldAABB.upperBound.Set( 500.0, 500.0); _gravity = new b2Vec2(0.0, 6.5); _doSleep = true; _world = new b2World(_worldAABB, _gravity, _doSleep); _body = new b2BodyDef(); _body.position.Set(0,0); _bodyPolygon = _world.CreateBody(_body); donut=CreateRegularPolygon(3,200 / SCALE, 50 / SCALE,new Point(240 / SCALE, 240/ SCALE)); } public function onRendering(no:Number=1):void { _world.Step(1 / 60, 10); // Sprite の場所を更新する for (var b:b2Body = _world.GetBodyList(); b; b = b.GetNext()) { var sprite:Object3D = b.GetUserData() as Object3D; if (sprite){ sprite.x = b.GetWorldCenter().x * SCALE-465/2; sprite.y = b.GetWorldCenter().y * SCALE-465/2; sprite.rotationZ = b.GetAngle(); } } donut.SetXForm(donut.GetPosition(), donut.GetAngle() + no*Math.PI/180); } public function CreateRegularPolygon( num:int, radiusIn:Number, radiusWidth:Number,center:Point) : b2Body { var b2body:b2Body = _world.CreateBody(_body); var divisionAngle:Number = 360 / num; for ( var a:int = 0; a < num; a ++ ) { var angle:Number = divisionAngle * a * Math.PI / 180 ; var radiusOut:Number = radiusIn + radiusWidth; var cos:Number = Math.cos(angle); var sin:Number = Math.sin(angle); var rI:Point = new Point(cos * radiusIn, sin * radiusIn); var rO:Point = new Point(cos * radiusOut, sin * radiusOut); var angleN:Number = divisionAngle * (a+1) * Math.PI / 180 ; var cosN:Number = Math.cos(angleN); var sinN:Number = Math.sin(angleN); var rIN:Point = new Point(cosN * radiusIn, sinN * radiusIn); var rON:Point = new Point(cosN * radiusOut, sinN * radiusOut); var poly:b2PolygonDef = new b2PolygonDef(); poly.vertexCount = 4; poly.vertices[0].Set(rI.x, rI.y); poly.vertices[1].Set(rO.x, rO.y); poly.vertices[2].Set(rON.x, rON.y); poly.vertices[3].Set(rIN.x, rIN.y ); poly.density = 0; poly.restitution = 0; poly.friction = 0; b2body.CreateShape(poly); } b2body.SetXForm(new b2Vec2(center.x, center.y),0) return b2body; } //----------------------------------------------------------- //ビーズを作成する //----------------------------------------------------------- public function CreateBeads( x:Number, y:Number):void { var b2body:b2Body = _world.CreateBody(_body); var radius:Number=(Math.random() * 5 + 20) var beads:* var r:uint=15 * (Math.random()*0.7) var g:uint=15 * (Math.random()*0.7) var b:uint=15 * (Math.random()*0.7) var color:uint=(r<<20|r<<16|g<<12|g<<8|b<<4|b) var material:FillMaterial=new FillMaterial(color,1,BlendMode.OVERLAY); var beads3d:Cone; switch (Math.round(Math.random()*2)) { case 0: //四角の作成 beads= new b2PolygonDef(); beads.SetAsBox(radius / SCALE, radius / SCALE); beads3d=new Cone(10,radius*Math.sqrt(2),radius*Math.sqrt(2),1,4,true); beads3d.rotationZ=-45*Math.PI/180 break; case 1: //三角の作成 beads= new b2PolygonDef(); beads.SetAsBox(radius / SCALE, radius / SCALE); var vertexCount:Number=3; beads.vertexCount = vertexCount; // 底辺の半分の長さと高さを設定 var h:Number=Math.tan(60 * Math.PI / 180) * radius; // 角の数を設定して頂点の位置を設定する beads.vertices[0].Set(-1 * radius / SCALE, -1 * h / 2 / SCALE); beads.vertices[1].Set(radius / SCALE, -1 * h / 2 / SCALE); beads.vertices[2].Set(0, h / 2 / SCALE); beads3d=new Cone(10,radius,radius,1,3,true); beads3d.rotationZ=-30*Math.PI/180 break; default: //丸の作成 beads = new b2CircleDef(); beads.radius = radius / SCALE; beads3d=new Cone(10,radius,radius,1,8,true); break; } beads3d.removeSurface('side') beads3d.removeSurface('bottom') MeshUtils.removeSingularFaces(beads3d); MeshUtils.removeIsolatedVertices(beads3d); beads3d.cloneMaterialToAllSurfaces(material); beads.density = 10; beads.restitution = 0.5; beads.friction = 0.3; b2body.CreateShape(beads); b2body.SetXForm(new b2Vec2(x ,y), 0); b2body.SetMassFromShapes(); b2body.m_userData = new Object3D(); b2body.GetUserData().x = b2body.GetWorldCenter().x; b2body.GetUserData().y = b2body.GetWorldCenter().y; b2body.GetUserData().addChild( beads3d); _altView.addChild(b2body.GetUserData()); } } Alternativa3D and box2D = simple kaleidoscope