package { import alternativ5.engine3d.controllers.*; import alternativ5.engine3d.core.*; import alternativ5.engine3d.display.*; import alternativ5.types.*; import alternativ5.utils.*; import flash.display.*; import flash.events.*; /** * Mapを使ったデモ * メッシュ情報には 地面と家の情報が1つずつしかありません * * Map : http://help.alternativaplatform.com/en/client/alternativa/types/Map.html * Set : http://help.alternativaplatform.com/en/client/alternativa/types/Set.html */ [SWF(backgroundColor="#000000", frameRate="120")] public class Main extends Sprite { private var scene:Scene3D; private var view:View; private var camera:Camera3D; private var cameraController:CameraController; public var textures:/*BitmapData*/Array; private var meshes:/*Mesh*/Array; private var map:Map; public function Main() { this.addEventListener(Event.ADDED, init); } public function init(e:Event):void { this.removeEventListener(Event.ADDED, init); stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; scene = new Scene3D(); scene.root = new Object3D(); camera = new Camera3D(); camera.x = camera.y = 1500; camera.z = 800; scene.root.addChild(camera); view = new View(); addChild(view); view.camera = camera; cameraController = new CameraController(stage); cameraController.camera = camera; cameraController.setDefaultBindings(); cameraController.lookAt(new Point3D); cameraController.checkCollisions = false; cameraController.speed = 500; cameraController.controlsEnabled = true; FPS.init(stage); stage.addEventListener(Event.RESIZE, onResize); stage.addEventListener(Event.ENTER_FRAME, onEnterFrame); onResize(null); //create create(); } /** * */ private function create():void { /** * メッシュ情報 */ var xml:XML = <meshes> <mesh name="Geo"> <surface materialType="FillMaterial" color="0x99ab4e" wirethickness="1" wirecolor="0x7b8d42"> <face><vertex x="0" y="0" z="0" /><vertex x="500" y="0" z="0" /><vertex x="500" y="500" z="0" /><vertex x="0" y="500" z="0" /></face> </surface> </mesh> <mesh name="House"> <surface materialType="FillMaterial" color="0xE0E0E0" wirethickness="1" wirecolor="0x7b8d42"> <face><vertex x="0" y="0" z="0" /><vertex x="100" y="0" z="0" /><vertex x="100" y="0" z="100" /><vertex x="0" y="0" z="100" /></face> <face><vertex x="100" y="0" z="0" /><vertex x="100" y="100" z="0" /><vertex x="100" y="100" z="100" /><vertex x="100" y="0" z="100" /></face> <face><vertex x="100" y="100" z="0" /><vertex x="0" y="100" z="0" /><vertex x="0" y="100" z="100" /><vertex x="100" y="100" z="100" /></face> <face><vertex x="0" y="100" z="0" /><vertex x="0" y="0" z="0" /><vertex x="0" y="0" z="100" /><vertex x="0" y="100" z="100" /></face> </surface> <surface materialType="FillMaterial" wirethickness="1" wirecolor="0x7b8d42"> <face><vertex x="-10" y="0" z="95" /><vertex x="50" y="0" z="130" /><vertex x="50" y="100" z="130" /><vertex x="-10" y="100" z="95" /></face> <face><vertex x="-10" y="100" z="95" /><vertex x="50" y="100" z="130" /><vertex x="50" y="0" z="130" /><vertex x="-10" y="0" z="95" /></face> <face><vertex x="110" y="0" z="95" /><vertex x="50" y="0" z="130" /><vertex x="50" y="100" z="130" /><vertex x="110" y="100" z="95" /></face> <face><vertex x="110" y="100" z="95" /><vertex x="50" y="100" z="130" /><vertex x="50" y="0" z="130" /><vertex x="110" y="0" z="95" /></face> </surface> </mesh> </meshes>; /** * マップ情報 */ var db:XML = <map> <set name="SetGeo"> <mesh name="Geo" z="0" x="-100" y="-100" scaleX="2" scaleY="2" /> </set> <set name="Town"> <mesh name="House" x="0" y="0"/> <mesh name="House" x="70" y="200" rotationZ="40"/> <mesh name="House" x="300" y="10" rotationZ="70"/> <mesh name="House" x="700" y="70" rotationZ="20"/> <mesh name="House" x="100" y="600" rotationZ="60"/> <mesh name="House" x="200" y="400" rotationZ="45"/> <mesh name="House" x="700" y="300" rotationZ="15"/> <mesh name="House" x="600" y="600" rotationZ="70"/> <mesh name="House" x="500" y="200" rotationZ="10"/> <mesh name="House" x="200" y="700" rotationZ="60"/> <mesh name="House" x="800" y="600" rotationZ="60"/> </set> </map>; // createMeshes meshes = EZCreateMesh.createMeshes(xml, textures); // createMap map = EZCreateMesh.createMap(db, meshes); // addSetObjects addSetObjects(map, "SetGeo"); addSetObjects(map, "Town"); } /** * * @param targetMap * @param targetSet */ private function addSetObjects(targetMap:Map, targetSet:String):void { addObjects(targetMap["map:::" + targetSet]); } /** * addObjects * @param objects */ private function addObjects(objects:Set):void { for (var o:* in objects) { scene.root.addChild(o); } } private function onResize(e:Event):void { view.width = stage.stageWidth; view.height = stage.stageHeight; } private function onEnterFrame(e:Event):void { cameraController.processInput(); scene.calculate(); } } } import alternativ5.engine3d.core.*; import alternativ5.engine3d.materials.*; import alternativ5.types.*; import alternativ5.utils.*; import flash.geom.*; import flash.display.*; import alternativ5.engine3d.core.*; import alternativ5.engine3d.materials.*; import alternativ5.types.*; import alternativ5.utils.*; import flash.geom.*; import flash.display.*; class EZCreateMesh { /** * static const */ public static const DEV:String = "DevMaterial"; public static const FILL:String = "FillMaterial"; public static const TEXTURE:String = "TextureMaterial"; public static const WIRE:String = "WireMaterial"; public static const MOVIECLIP:String = "MovieClipMaterial"; /** * 簡単に より早くメッシュを作成する為に * * Alternativa3Dを利用したマップ(Mesh)作成時に ASでは 頂点やフェイス、サーフェス全てに id(名前)をつける必要があり、これらの作業は非常に面倒です * XMLに情報を記述することによって 値 変更時にコンパイルが不要になり、誰でも簡単にマップ作成が可能です * * @author br */ /** * 渡されたXMLに記載されているMeshを全て作成し配列で返します * @param db */ public static function createMeshes(db:XML, textures:/*BitmapData*/Array = null):/*Mesh*/Array { var _meshes:/*Mesh*/Array = new Array(); for (var a:uint = 0; a < db.mesh.length(); a++) { _meshes[db.mesh[a].@name] = new Mesh(); var x:XMLList = db.mesh[a].surface.(@materialType == TEXTURE).@name; var arr/*Bitmap*/:Array = new Array(); for (var b:uint = 0; b < x.length(); b++) { arr[x[b]] = textures[x[b]] as BitmapData; } _meshes[db.mesh[a].@name] = createMesh(db.mesh[a], textures) as Mesh; } return _meshes; } /** * マップを作成 * @param map * @param mapName */ public static function createMap(db:XML, _meshes:/*Mesh*/Array):Map { var map:Map = new Map(); for (var a:uint = 0; a < db.set.length(); a++) { var _set:Set; var elements:Array = new Array(); for (var b:uint = 0; b < db.set[a].mesh.length(); b++) { var mesh:Mesh = meshPropertiesSetup( _meshes[db.set[a].mesh[b].@name].clone(), db.set[a].mesh[b] ); elements.push(mesh); } _set = Set.createFromArray(elements); map.add("map:::" + db.set[a].@name, _set); } return map; } /** * XMLを元にプロパティを変更したメッシュを返します * @param mesh メッシュ * @param properties プロパティが記載されたXML * @return mesh プロパティが変更されたメッシュを返します * @exampleText XMLの例を示します * <listing version="3.0"> * <mesh z="-100" scaleX="5" scaleY="5" /> * </listing> */ public static function meshPropertiesSetup(mesh:Mesh, properties:XML):Mesh { if(properties.hasOwnProperty("@x")) mesh.x = Number(properties.@x); if(properties.hasOwnProperty("@y")) mesh.y = Number(properties.@y); if(properties.hasOwnProperty("@z")) mesh.z = Number(properties.@z); if(properties.hasOwnProperty("@scaleX")) mesh.scaleX = Number(properties.@scaleX); if(properties.hasOwnProperty("@scaleY")) mesh.scaleY = Number(properties.@scaleY); if(properties.hasOwnProperty("@scaleZ")) mesh.scaleZ = Number(properties.@scaleZ); if(properties.hasOwnProperty("@rotationX")) mesh.rotationX = MathUtils.toRadian(Number(properties.@rotationX)); if(properties.hasOwnProperty("@rotationY")) mesh.rotationY = MathUtils.toRadian(Number(properties.@rotationY)); if(properties.hasOwnProperty("@rotationZ")) mesh.rotationZ = MathUtils.toRadian(Number(properties.@rotationZ)); return mesh; } /** * メッシュ作成 * @param xml メッシュの情報が記載されたXML * @return Mesh */ public static function createMesh(xml:XML, textures:/*BitmapData*/Array = null):Mesh { var _mesh:Mesh = new Mesh(); var surfaces:Array = new Array(); for (var a:uint = 0; a < xml.surface.length(); a++) { var surfaceName:String = String("s" + a); var faces:Array = new Array(); for (var b:uint = 0; b < xml.surface[a].face.length(); b++) { var faceName:String = String("f" + a + b); var vertices:Array = new Array(); for (var c:uint = 0; c < xml.surface[a].face[b].vertex.length(); c++) { var vertexName:String = String("v" + a + b + c); /** * createVertex */ _mesh.createVertex( xml.surface[a].face[b].vertex[c].@x, xml.surface[a].face[b].vertex[c].@y, xml.surface[a].face[b].vertex[c].@z, vertexName ); vertices.push(vertexName); } /** * createFace */ _mesh.createFace(vertices, faceName); /** * setUVsToFace */ if ("UVs" in xml.surface[a].face[b]) { _mesh.setUVsToFace( new Point( Number(xml.surface[a].face[b].UVs.aUV.@x), Number(xml.surface[a].face[b].UVs.aUV.@y) ), new Point( Number(xml.surface[a].face[b].UVs.bUV.@x), Number(xml.surface[a].face[b].UVs.bUV.@y) ), new Point( Number(xml.surface[a].face[b].UVs.cUV.@x), Number(xml.surface[a].face[b].UVs.cUV.@y) ), faceName ); } /** * push Faces */ faces.push(faceName); } /** * createSurface */ _mesh.createSurface(faces, surfaceName); surfaces.push(surfaceName); _mesh.setMaterialToSurface(createMaterial(xml.surface[a]), surfaceName); } return _mesh; /** * マテリアルを作成 * @param material マテリアル情報が記載されたXML * @return SurfaceMaterial * @exampleText XMLの例を示します * <listing version="3.0"> * <surface materialType="FillMaterial" color="0x99ab4e" wirethickness="1" wirecolor="0x7b8d42" /> * <surface materialType="TextureMaterial" repeat="true" smooth="true" src="image" precision="BEST" /> * </listing> */ function createMaterial(material:XML):SurfaceMaterial { switch (true) { /** * DEV */ case material.@materialType == DEV : return new DevMaterial( uint(material.@parametertype) ? material.@parametertype : 0, uint(material.@color) ? material.@color : 0xFFFFFF, Number(material.@maxparametervalue) ? material.@maxparametervalue : 20, Boolean(material.@shownormals) ? material.@shownormals : false, uint(material.@normalscolor) ? material.@normalscolor : 0x00FFFF, int(material.@minmobility) ? material.@minmobility : 0, int(material.@maxmobility) ? material.@maxmobility : 255, Number(material.@alpha) ? material.@alpha : 1, String(material.@blendmode) ? material.@blendmode : "normal", Number(material.@wirethickness) ? material.@wirethickness : -1, Number(material.@wirecolor) ? material.@wirecolor : 0 ); break; /** * FILL */ case material.@materialType == FILL : return new FillMaterial( uint(material.@color)? material.@color: 0xffffff * Math.random(), Number(material.@alpha)? material.@alpha : 1, String(material.@blendmode)? material.@blendmode : "normal", Number(material.@wirethickness)? material.@wirethickness : -1, Number(material.@wirecolor)? material.@wirecolor : 0 ); break; /** * TEXTURE */ case material.@materialType == TEXTURE : //Debug.bitmap(textures[material.@name]); return new TextureMaterial( new Texture(textures[material.@name]), uint(material.@alpha)? material.@alpha : 1, Boolean(material.@repeat == "true")? true : true, Boolean(material.@smooth == "true")? true : false, String(material.@blendmode.toString())? material.@blendmode : BlendMode.NORMAL, Number(material.@wirethickness)? material.@wirethickness : -1, uint(material.@wirecolor)? material.@wirecolor : 0, String(material.@precision.toString())? createTextureMaterialPrecision(material.@precision.toString()) : 10 ); break; /** * WIRE */ case material.@materialType == WIRE : return new WireMaterial( Number(material.@thickness) ? material.@thickness : 0, uint(material.@color) ? material.@color : 0xffffff * Math.random(), Number(material.@alpha) ? material.@alpha : 1, String(material.@blendmode) ? material.@blendmode : "normal" ); break; default : return null; break; } } /** * createTextureMaterialPrecision * @param precision * @return */ function createTextureMaterialPrecision(precision:String):Number { switch(true) { case precision == "BEST" : return TextureMaterialPrecision.BEST; break; case precision == "HIGH" : return TextureMaterialPrecision.HIGH; break; case precision == "LOW" : return TextureMaterialPrecision.LOW; break; case precision == "MEDIUM" : return TextureMaterialPrecision.MEDIUM; break; case precision == "NONE" : return TextureMaterialPrecision.NONE; break; case precision == "VERY_HIGH" : return TextureMaterialPrecision.VERY_HIGH; break; case precision == "VERY_LOW" : return TextureMaterialPrecision.VERY_LOW; break; default : return TextureMaterialPrecision.MEDIUM; } } } } createMeshes, Map - EZCreateMesh