package { /** * 3DText.in APIのデモアプリ * 立体メガネ(赤緑)を装着するのだぁ~ */ import flash.events.Event; import flash.events.MouseEvent; import flash.geom.*; import flash.text.*; import flash.utils.*; import flash.display.*; import flash.geom.ColorTransform; import org.papervision3d.cameras.*; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.render.BasicRenderEngine; import org.papervision3d.scenes.Scene3D; import org.papervision3d.view.*; import org.papervision3d.materials.*; import org.papervision3d.events.FileLoadEvent; import org.papervision3d.core.proto.MaterialObject3D import org.papervision3d.objects.special.ParticleField; import org.papervision3d.materials.special.ParticleMaterial; [SWF( width = "465", height = "465", frameRate = "60" , backgroundColor = "0xFFFFFF")] public class Main extends Sprite { public var scene : Scene3D; public var renderer : BasicRenderEngine; private var text:_3DText; private var mat:MaterialObject3D; private var rootNode : DisplayObject3D; private var Eye_d : Number=40; private var letters:Array=new Array(); private var viewports:Array = new Array(); private var cameras:Array = new Array(); private var ptc_obj:Array; private var in_arr:Array=new Array(); private var val:Number = -10; private var mflag:Boolean=false; public function Main() { scene = new Scene3D(); renderer = new BasicRenderEngine(); for (var i:int = 0; i < 2; i++ ) { var v:Viewport3D = new AnaghlyphViewport3D(0xffffff, 465, 465, false, false); v.cacheAsBitmap = true; v.transform.colorTransform = (i == 0)?new ColorTransform(0 , 1 , 1 , 1):new ColorTransform(1 , 0 , 0 , 1); if (i == 1) v.blendMode = BlendMode.SCREEN; v.mouseEnabled = false; v.mouseChildren = false; var c:Camera3D = new Camera3D(60); c.target = DisplayObject3D.ZERO; addChild(v); viewports.push(v);cameras.push(c); v.containerSprite.cacheAsBitmap = false; } cameras[0].moveLeft(Eye_d / 2); cameras[1].moveRight(Eye_d / 2); create_ctrl(); addEventListener(Event.ENTER_FRAME, onEnterFrame); } private function create_ctrl() : void { var carr:Array = [ { text:"Text", val:"立体", width:70,max:5,rest:null }, { text:"Depth", val:2, width:30,max:3,rest:"0-9." }]; var barr:Array = [ { text:"Generate", val:Btn_Press, width:80 }, { text:"Material_Change", val:chg_Press, width:100 } ]; rootNode = scene.addChild( new DisplayObject3D( "rootNode" ) ); scene.addChild(rootNode); mat = new WireframeMaterial(0x666666); text = new _3DText(mat, carr[0].val,2, 0, "ipagp"); rootNode.addChild(text); ptc_obj = [new ParticleField(new ParticleMaterial(0x666666, 1), 100,100, 3500, 3500, 40000),new ParticleField(new ParticleMaterial(0x666666, 1),100,100, 3500, 3500, 40000)]; scene.addChild(ptc_obj[0]);scene.addChild(ptc_obj[1]);ptc_obj[0].z=20000+500;ptc_obj[1].z=20000+500+40000; var left:int = 5; for (var k:int = 0; k < carr.length; k++ ) { var label:TextField = new TextField(); label.y = 5; label.x = left + 5; label.selectable = false; label.autoSize = TextFieldAutoSize.LEFT; label.htmlText = "<b>"+carr[k].text+"</b>"; addChild(label); var inp:TextField= new TextField(); inp.y = 5; inp.x = label.textWidth+label.x+8; inp.width =carr[k].width; inp.text = carr[k].val; inp.border = true; inp.height = 20; left = inp.x + carr[k].width; inp.type = TextFieldType.INPUT; inp.selectable = true; inp.maxChars = carr[k].max; inp.restrict = carr[k].rest; addChild(inp); in_arr.push(inp); } left += 15; for (var l:int = 0; l < barr.length; l++ ) { var btn:Sprite = new Sprite(); btn.buttonMode = true; btn.y = 5;btn.x = left; btn.graphics.beginFill(0xcccccc); btn.graphics.lineStyle(1, 0x888888); btn.graphics.drawRect(0,0,barr[l].width,20); btn.graphics.endFill(); btn.mouseChildren = false; var label2:TextField = new TextField(); label2.width = barr[l].width; label2.htmlText = "<p align='center'>"+barr[l].text+"</p>"; btn.addChild(label2); left = btn.x + barr[l].width+7;left+=(l==0)?10:0 addChild(btn); btn.addEventListener(MouseEvent.CLICK,barr[l].val); } } private function onEnterFrame(event:Event):void { rootNode.rotationX += 4; rootNode.rotationY += 2; rootNode.rotationZ += 1; for(var j:int=0;j<ptc_obj.length;j++){ ptc_obj[j].z-=200;if(ptc_obj[j].z<-25000)ptc_obj[j].z+=80000; } if (rootNode.z > 1200) { val = -val }; if (rootNode.z < -500) { val = -val }; rootNode.z += val; if(mflag)scrollBitmap(mat.bitmap, -1, -1); renderer.renderScene(scene, cameras[0], viewports[1]); renderer.renderScene(scene, cameras[1], viewports[0]); } private function Btn_Press(e:MouseEvent):void { var d:Number = Number(in_arr[1].text); if (d > 5) { d = 5; in_arr[1].text = d; } text.removeLetters(); text = new _3DText(mat,in_arr[0].text,d,0, "ipagp"); rootNode.addChild(text); } private function chg_Press(e:MouseEvent):void { mat= mflag?new WireframeMaterial(0x666666):new BitmapFileMaterial("http://www.3dtext.in/image/" + (18 * Math.random() | 0) + ".jpg"); text.set_letters_material(mat); mflag = !mflag; } private function scrollBitmap(bm:BitmapData,sx:int,sy:int):void{ var divx:int = Math.abs(sx), divy:int = Math.abs(sy); var rect:Array = [new Rectangle(bm.width - divx, 0, divx, bm.height), new Rectangle(0, 0, divx, bm.height), new Rectangle(0,0,bm.width,divy),new Rectangle(0,bm.height-divy,bm.width,divy)]; var p:Array=[new Point(0,0),new Point(bm.width-divx,0),new Point(0,0),new Point(0,bm.height-divy)]; var tmp:BitmapData = new BitmapData(bm.width,bm.height,bm.transparent,0x000000); (sx>0)?tmp.copyPixels(bm,rect[0],p[0]) : tmp.copyPixels(bm,rect[1], p[1]); bm.scroll(sx,0); (sx>0)?bm.copyPixels(tmp,rect[1],p[0]) : bm.copyPixels(tmp,rect[0], p[1]); (sy>0)?tmp.copyPixels(bm,rect[3],p[2]) : tmp.copyPixels(bm,rect[2], p[3]); bm.scroll(0,sy); (sy>0)?bm.copyPixels(tmp,rect[2],p[2]) : bm.copyPixels(tmp,rect[3], p[3]); tmp.dispose(); } } } import org.papervision3d.view.Viewport3D; class AnaghlyphViewport3D extends Viewport3D { private var _bgColor : uint; public function AnaghlyphViewport3D(bgColor:uint = 0xFFFFFF, viewportWidth:Number = 640, viewportHeight:Number = 480, autoScaleToStage:Boolean = false, interactive:Boolean = false, autoClipping:Boolean = true, autoCulling:Boolean = true) { _bgColor = bgColor; super(viewportWidth, viewportHeight, autoScaleToStage, interactive, autoClipping, autoCulling); } override public function set viewportWidth(width:Number) : void { super.viewportWidth = width; if(!isNaN(viewportHeight)) { graphics.clear(); graphics.beginFill(_bgColor, 1); graphics.drawRect(0, 0, viewportWidth, viewportHeight); } } override public function set viewportHeight(height:Number):void { super.viewportHeight = height; if(!isNaN(viewportWidth)) { graphics.clear(); graphics.beginFill(_bgColor, 1); graphics.drawRect(0, 0, viewportWidth, viewportHeight); } } } import org.papervision3d.core.geom.* import org.papervision3d.core.geom.renderables.*; import org.papervision3d.core.math.*; import org.papervision3d.core.proto.MaterialObject3D import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.materials.*; import org.papervision3d.events.FileLoadEvent; import flash.events.*; import flash.net.*; import flash.utils.*; class _3DText extends TriangleMesh3D { public var loaded :Boolean; public var letters:Array; private var spacer:int = 30; private var _Mesh:DisplayObject3D; private var mat:MaterialObject3D; private var _filename:String; public function _3DText(material:MaterialObject3D,word:String,depth:Number,bevel:Number,font:String=null) { super( material, new Array(), new Array(), null ); _Mesh = this; mat = material; letters = new Array(); var val:URLVariables = new URLVariables(); val.text=word; //作成する立体文字 val.depth=depth; //文字の厚さ val.bevel=bevel; //文字べベル val.font = font; //フォント名 var req:URLRequest = new URLRequest("http://www.3dtext.in/api/for_wonderfl_demo_key"); req.method = URLRequestMethod.POST;req.data=val; var loader:URLLoader = new URLLoader(); loader.dataFormat = URLLoaderDataFormat.BINARY; loader.addEventListener(Event.COMPLETE, completeHandler); loader.load(req); } public function set_letters_material(m:MaterialObject3D):void { for(var j:int=0;j<letters.length;j++)letters[j].material=m; } public function removeLetters():void { for each( var l:DisplayObject3D in letters){ removeChild(l); } letters.length = 0; parent.removeChild( this ); } private function completeHandler(event:Event):void { var data:ByteArray = event.target.data; data.endian = Endian.LITTLE_ENDIAN var q:int;var sum:int=0 try { while (q = data.readUnsignedShort()) { var t:TriangleMesh3D = new TriangleMesh3D(mat, new Array(), new Array()); var arr: Array = new Array(); if(q>1)for (var a:int = 0; a < q; a++) { var v1:Vertex3D = new Vertex3D(data.readFloat(), data.readFloat(),data.readFloat()) var v2:Vertex3D = new Vertex3D(data.readFloat(), data.readFloat(),data.readFloat()) var v3:Vertex3D = new Vertex3D(data.readFloat(), data.readFloat(),data.readFloat()) t.geometry.vertices.push(v1);t.geometry.vertices.push(v2);t.geometry.vertices.push(v3); t.geometry.faces.push(new Triangle3D(t, [v1,v2,v3],mat, [new NumberUV(data.readFloat(),data.readFloat()),new NumberUV(data.readFloat(),data.readFloat()),new NumberUV(data.readFloat(),data.readFloat())])); } for (var i:int = 0; i < 9; i++) {arr.push(data.readFloat());} t.extra = { stat:arr }; sum += arr[0]; letters.push(t); } } catch (err:Error) { }finally { if (letters.length > 1) { sum +=(letters.length - 1)* spacer; } letters[0].x = -sum / 2+letters[0].extra.stat[0]/2; for (var i:int = 0; i < letters.length; i++ ) { _Mesh.addChild(letters[i]); if (i > 0) { letters[i].x=letters[i-1].x+spacer+(letters[i-1].extra.stat[0]/2)+(letters[i].extra.stat[0]/2); } } this.geometry.ready = true; var fileEvent:FileLoadEvent = new FileLoadEvent( FileLoadEvent.LOAD_COMPLETE, _filename ); this.dispatchEvent( fileEvent ); this.loaded = true; } } } 3Dメガネを使った立体視 3dtext.in API