In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

forked from: flash on 2010-1-10

元ネタ : 
Alternativa3D Tips 平面プリミティブの頂点にアクセスして、変形する2
http://wonderfl.net/code/c98f38e927e47ec3dc415e553c7c5c13197a35bf

Planeプリミティブを自作して頂点情報を操作しています
twoSided は false です
// forked from break's flash on 2010-1-10
package {
	import alternativ5.engine3d.controllers.*;
	import alternativ5.engine3d.core.*;
	import alternativ5.engine3d.display.*;
	import alternativ5.engine3d.events.MouseEvent3D;
	import alternativ5.types.*;
	import alternativ5.utils.*;

	import flash.display.*;
	import flash.events.*;
	
	/**
	 * 元ネタ : 
	 * Alternativa3D Tips 平面プリミティブの頂点にアクセスして、変形する2
	 * http://wonderfl.net/code/c98f38e927e47ec3dc415e553c7c5c13197a35bf
	 *  
	 * 
	 * Planeプリミティブを自作して頂点情報を操作しています
	 * twoSided は false です
	 */
	
	[SWF(backgroundColor="#000000", frameRate="60")]
	public class Main extends Sprite {
	    
		private var scene:Scene3D;
		private var view:View;
		private var camera:Camera3D;
		private var cameraController:CameraController;
		
		public var textures: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 = 600;
			camera.z = 700;
			scene.root.addChild(camera);
			
			view = new View();
			view.interactive = true;
			view.camera = camera;
			addChild(view);
			
			
			cameraController = new CameraController(stage);
			cameraController.camera = camera;
			cameraController.checkCollisions = false;
			cameraController.speed = 500;
			cameraController.controlsEnabled = true;
			cameraController.setDefaultBindings();
			cameraController.lookAt(new Point3D());
			
			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={EZCreateMesh.FILL} color="0xAAAAAA">
						<faces primitive={EZCreateMesh.PLANE} ox="0" oy="0" oz="0" w="1000" h="1000" ws="1" hs="36" twoSided="false" />;
					</surface>
				</mesh>
			</meshes>;
			
			// createMeshes
			meshes = EZCreateMesh.createMeshes(xml, textures, this);
			
			// addMehses
			addMehses(meshes);
			
		}
		
		/**
		 * addMeshes
		 * @param	meshes
		 */
		private function addMehses(meshes:Array):void {
			for (var o:* in meshes) {
				scene.root.addChild(meshes[o]);
			}
		}
		
		/**
		 * 
		 * @param	targetMap
		 * @param	targetSet
		 */
		private function addSetObjects(targetMap:Map, targetSet:String):void {
			addObjects(targetMap[EZCreateMesh.KEY_MAP + EZCreateMesh.ID_CONCAT + targetSet]);
		}
		
		/**
		 * addObjects
		 * @param	objects
		 */
		private function addObjects(objects:Set):void {
			for (var o:* in objects) {
				scene.root.addChild(o);
			}
		}
		
		/**
		 * onResize
		 * @param	e
		 */
		private function onResize(e:Event):void {
			view.width = stage.stageWidth;
			view.height = stage.stageHeight;
		}
		
		/**
		 * 
		 * @param	e
		 */
		private var angle:Number = 0;
		private function onEnterFrame(e:Event):void {
			cameraController.processInput();
			
			angle++;
			
			/**
			 * twoSidedをtrueにする場合は 
			 * i < 282
			 * var vy:Number = Math.sin(MathUtils.toRadian((i+8 + angle) * 4)) * 50;
			 * 
			 * と書き換えます
			 */
			for (var i:int = 0; i < 141; i++) {
				var vy:Number = Math.sin(MathUtils.toRadian((i+4 + angle) * 4)) * 50;
				var vz:Number = Math.sin(MathUtils.toRadian((i + angle) * 4)) * 50;
								
				var f:Number = Math.ceil(i / 4);
				
				meshes["Geo"].getVertexById("v:0" + f + 0).z = vz;
				meshes["Geo"].getVertexById("v:0" + f + 3).z = vz;
				meshes["Geo"].getVertexById("v:0" + f + 2).z = vy;
				meshes["Geo"].getVertexById("v:0" + f + 1).z = vy;
			}
			
			if (angle > 360) angle = 0;
			
			scene.calculate();
		}
	}
}


/**
 * EZCreateMesh
 * 
 * 簡単に より早くメッシュを作成する為に
 * 
 * Alternativa3Dを利用したマップ(Mesh)作成時に ASでは 頂点やフェイス、
 * サーフェス全てに id(名前)をつける必要があり、これらの作業は非常に面倒です
 * 
 * XMLに情報を記述することによって 
 * 値 変更時にコンパイルが不要になり、誰でも簡単にマップ作成が可能です
 * 
 * @author br
 */
import alternativ5.engine3d.core.*;
import alternativ5.engine3d.materials.*;
import alternativ5.types.*;
import alternativ5.utils.*;
import org.libspark.betweenas3.BetweenAS3;
import org.libspark.betweenas3.tweens.ITween;

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.*;

import alternativ5.engine3d.events.*;

class EZCreateMesh {
	
	/**
	 * static const
	 */
	
	// MATERIAL
	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";
	
	
	// SPEITE 3D
	public static const SPRITE_TEXTURE:String = "SpriteTextureMaterial";
	public static const SPRITE:String = "SpriteMaterial";
	
	public static const ID_CONCAT:String = ":";
	public static const ID_SURFACE:String = "s";
	public static const ID_FACE:String = "f";
	public static const ID_VERTEX:String = "v";
	
	public static const KEY_MAP:String = "m";
	
	private static const _PI:Number = Math.PI;
	
	
	/**
	 * 渡されたXMLに記載されているMeshを全て作成し配列で返します
	 * @param	db
	 */
	public static function createMeshes(db:XML, textures:Array = null, main:Main = null):/*Mesh*/Array {
		
		
		var _meshes:/*Mesh*/Array = [];
		
		for (var a:int = 0; a < db.mesh.length(); a++) {
			_meshes[db.mesh[a].@name] = new Mesh();
			
			var textureLists:XMLList = db.mesh[a].surface.(@materialType == TEXTURE).@name;
			
			_meshes[db.mesh[a].@name] = createMesh(db.mesh[a], textures, main) 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:int = 0; a < db.set.length(); a++) {
			
			var _set:Set;
			var elements:Array = [];
			
			for (var b:int = 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(KEY_MAP + ID_CONCAT + 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, main:Main = null):Mesh {
		
		import flash.utils.getTimer;
		var now:Number = getTimer();
		
		var _mesh:Mesh = new Mesh();
		var surfaces:Array = [];
		
		for (var a:int = 0; a < xml.surface.length(); a++)
		{
			
			if ("faces" in xml.surface[a]) {
				for ( var f:int = 0; f < xml.surface[a].faces.length(); f++) {
					xml.surface[a].faces.prependChild(createFacesPrimitive(xml.surface[a].faces[f]));
				}
			}
			
			// eg - s:s (s:0)
			var surfaceName:String = xml.surface[a].hasOwnProperty("@id") ? xml.surface[a].@id : String(ID_SURFACE + ID_CONCAT + a);
			var materialType:String = xml.surface[a].@materialType;
			
			var faces:Array = [];
			
			for (var b:int = 0; b < xml.surface[a]..face.length(); b++)
			{
				
				if ("vertices" in xml.surface[a]..face[b]) {
					for (var v:int = 0; v < xml.surface[a]..face[b].vertices.length(); v++) {
						xml.surface[a]..face[b].vertices[v].prependChild(createVerticesPrimitive(xml.surface[a]..face[b].vertices[v]));
					}
				}
				
				// eg - f:sf (f:00)
				var faceName:String = xml.surface[a]..face[b].hasOwnProperty("@id") ? xml.surface[a]..face[b].@id : String(ID_FACE + ID_CONCAT + a + b);
				var vertices:Array = [];
				
				for (var c:int = 0; c < xml.surface[a]..face[b]..vertex.length(); c++)
				{
					
					// eg - v:sfv (v:000)
					var vertexName:String = xml.surface[a]..face[b]..vertex[c].hasOwnProperty("@id") ? xml.surface[a]..face[b]..vertex[c].@id : String(ID_VERTEX + ID_CONCAT + 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);
				
				with ( _mesh.getFaceById( faceName ) ) {
					if ( xml.surface[a]..face[b].hasOwnProperty("@click") ) 
						addEventListener(MouseEvent3D.CLICK , main[xml.surface[a]..face[b].@click]);
					
					if ( xml.surface[a]..face[b].hasOwnProperty("@mouseDown") )
						addEventListener(MouseEvent3D.MOUSE_DOWN, main[xml.surface[a]..face[b].@mouseDown]);
					
					if ( xml.surface[a]..face[b].hasOwnProperty("@mouseMove") )
						addEventListener(MouseEvent3D.MOUSE_MOVE , main[xml.surface[a]..face[b].@mouseMove]);
					
					if ( xml.surface[a]..face[b].hasOwnProperty("@mouseOut") )
						addEventListener(MouseEvent3D.MOUSE_OUT, main[xml.surface[a]..face[b].@mouseOut]);
					
					if ( xml.surface[a]..face[b].hasOwnProperty("@mouseOver") )
						addEventListener(MouseEvent3D.MOUSE_OVER, main[xml.surface[a]..face[b].@mouseOver]);
					
					if ( xml.surface[a]..face[b].hasOwnProperty("@mouseUp") )
						addEventListener(MouseEvent3D.MOUSE_UP , main[xml.surface[a]..face[b].@mouseUp]);
					
					if ( xml.surface[a]..face[b].hasOwnProperty("@mouseWheel") )
						addEventListener(MouseEvent3D.MOUSE_WHEEL, main[xml.surface[a]..face[b].@mouseWheel]);
				}
				
				
				/**
				 * setUVsToFace
				 */
				if ("UVs" in xml.surface[a]..face[b]) {
					with ( xml.surface[a]..face[b].UVs ) {
						_mesh.setUVsToFace(
							new Point(aUV.@x, aUV.@y),
							new Point(bUV.@x, bUV.@y),
							new Point(cUV.@x, cUV.@y),
							faceName
						);
					}
				}
				
				/**
				 * push Faces
				 */
				faces.push(faceName);
			}
			
			/**
			 * createSurface
			 */
			_mesh.createSurface(faces, surfaceName);
			
			with ( _mesh.getSurfaceById(surfaceName) ) {
				if ( xml.surface[a].hasOwnProperty("@click") )
					addEventListener(MouseEvent3D.CLICK , main[xml.surface[a].@click]);
				
				if ( xml.surface[a].hasOwnProperty("@mouseDown") )
					addEventListener(MouseEvent3D.MOUSE_DOWN, main[xml.surface[a].@mouseDown]);
				
				if ( xml.surface[a].hasOwnProperty("@mouseMove") )
					addEventListener(MouseEvent3D.MOUSE_MOVE , main[xml.surface[a].@mouseMove]);
				
				if ( xml.surface[a].hasOwnProperty("@mouseOut") )
					addEventListener(MouseEvent3D.MOUSE_OUT, main[xml.surface[a].@mouseOut]);
				
				if ( xml.surface[a].hasOwnProperty("@mouseOver") )
					addEventListener(MouseEvent3D.MOUSE_OVER, main[xml.surface[a].@mouseOver]);
				
				if ( xml.surface[a].hasOwnProperty("@mouseUp") )
					addEventListener(MouseEvent3D.MOUSE_UP , main[xml.surface[a].@mouseUp]);
				
				if ( xml.surface[a].hasOwnProperty("@mouseWheel") )
					addEventListener(MouseEvent3D.MOUSE_WHEEL, main[xml.surface[a].@mouseWheel]);
			}
			
			
			/**
			 * push
			 */
			surfaces.push(surfaceName);
			
			/**
			 * setMaterialToSurface
			 */
			_mesh.setMaterialToSurface(
				createMaterial(
					xml.surface[a],
					( materialType == TEXTURE || materialType == MOVIECLIP ) ? textures[xml.surface[a].@name] : null),
				surfaceName
			);
		}
		
		return _mesh;
	}
	
	/**
	 * マテリアルを作成
	 * @param	material マテリアル情報が記載されたXML
	 * @return SurfaceMaterial
	 * @exampleText XMLの例を示します
	 * <listing version="3.0">
	 * <surface materialType={EZCreateMesh.FILL} color="0x99ab4e" wirethickness="1" wirecolor="0x7b8d42" />
	 * <surface materialType="TextureMaterial" repeat="true" smooth="true" src="image" precision="BEST" />
	 * </listing>
	 */
	public static function createMaterial(material:XML, texture:* = null):SurfaceMaterial {
		with ( material ) {
			switch ( @materialType.toString() ) {
				
				case DEV : 
					return new DevMaterial(
						hasOwnProperty("@parametertype") ? @parametertype : 0,
						hasOwnProperty("@color") ? @color: 0xffffff * Math.random(),
						hasOwnProperty("@maxparametervalue") ? @maxparametervalue : 20,
						hasOwnProperty("@shownormals") ? @shownormals : false,
						hasOwnProperty("@normalscolor") ? @normalscolor : 0x00FFFF,
						hasOwnProperty("@minmobility") ? @minmobility : 0,
						hasOwnProperty("@maxmobility") ? @maxmobility : 255,
						hasOwnProperty("@alpha") ? @alpha : 1,
						hasOwnProperty("@blendmode") ? @blendmode : BlendMode.NORMAL,
						hasOwnProperty("@wirethickness") ? @wirethickness : -1,
						hasOwnProperty("@wirecolor") ? @wirecolor : 0
					);
				break;
				
				case FILL : 
					return new FillMaterial(
						hasOwnProperty("@color") ? @color: 0xffffff * Math.random(),
						hasOwnProperty("@alpha") ? @alpha : 1,
						hasOwnProperty("@blendmode") ? @blendmode : BlendMode.NORMAL,
						hasOwnProperty("@wirethickness") ? @wirethickness : -1,
						hasOwnProperty("@wirecolor") ? @wirecolor : 0
					);
				break;
				
				case TEXTURE : 
					return new TextureMaterial(
					new Texture(texture),
					hasOwnProperty("@alpha") ? @alpha : 1,
					hasOwnProperty("@repeat") ? (@repeat == "true" ? true : false) : true,
					hasOwnProperty("@smooth") ? (@smooth == "true" ? true : false) : false,
					hasOwnProperty("@blendmode") ? @blendmode : BlendMode.NORMAL,
					hasOwnProperty("@wirethickness") ? @wirethickness : -1,
					hasOwnProperty("@wirecolor") ? @wirecolor : 0,
					hasOwnProperty("@precision") ? @precision : 10
					);
				break;
				
				case WIRE : 
					return new WireMaterial(
						hasOwnProperty("@thickness") ? @thickness : 0,
						hasOwnProperty("@color") ? @color : 0xffffff * Math.random(),
						hasOwnProperty("@alpha") ? @alpha : 1,
						hasOwnProperty("@blendmode") ? @blendmode : BlendMode.NORMAL
					);
				break;
				
				case MOVIECLIP : 
					return new MovieClipMaterial(
						MovieClip( texture ),
						@textureWidth,
						@textureHeight,
						new Rectangle(
							hasOwnProperty("@clipX") ? @clipX : 0,
							hasOwnProperty("@clipY") ? @clipY : 0,
							hasOwnProperty("@clipWidth") ? @clipWidth : 0,
							hasOwnProperty("@clipHeight") ? @clipHeight : 0
						),
						new Matrix(
							hasOwnProperty("@a") ? @a : 1,
							hasOwnProperty("@b") ? @b : 0,
							hasOwnProperty("@c") ? @c : 0,
							hasOwnProperty("@d") ? @d : 1,
							hasOwnProperty("@tx") ? @tx : 0,
							hasOwnProperty("@ty") ? @ty : 0
						),
						hasOwnProperty("@smooth") ? (@smooth == "true" ? true : false) : false,
						hasOwnProperty("@precision") ? @precision : 10,
						hasOwnProperty("@fillColor") ? @fillColor : 0xffffff * Math.random(),
						hasOwnProperty("@refreshRate") ? @refreshRate : 1
					);
				break;
				
				default : 
					return null;
				break;
			}
		}
	}
	
	
	/**
	 * PRIMITIVE
	 */
	
	
	/**
	 * 
	 * @param	primitive
	 * @return
	 */
	public static function createFacesPrimitive(primitive:XML):XMLList {
		
		var _faces:XML = <faces></faces>;
		
		with (primitive) {
			switch ( @primitive.toString() ) {
				case PLANE : return buildPlaneFaces(@ox, @oy, @oz, @w, @h, @ws, @hs, @twoSided);
				default : return new XMLList();
			}
		}
		
		function buildPlaneFaces(ox:Number, oy:Number, oz:Number, w:Number, h:Number, ws:Number, hs:Number, twoSided:String ="false"):XMLList {
			
			var gridWidth:Number = w / ws;
			var gridHeight:Number = h / hs;
			
			
			import flash.utils.getTimer;
			var now:Number = getTimer();
			
			
			var aw:Number = ox - w / 2;
			var ah:Number = oy - h / 2;
			
			for ( var a:int = 0; a < ws; a++) {
				
				for (var b:int = 0; b < hs; b++) {
					
					var x1:Number = aw + gridWidth * a;
					var x2:Number =  aw + gridWidth * (a + 1);
					
					var y1:Number = ah + gridHeight * b;
					var y2:Number = ah + gridHeight * (b + 1);
					
					_faces.appendChild( <face>
						<vertex x={ x2 } y={ y1 } z="0" />
						<vertex x={ x2 } y={ y2 } z="0" />
						<vertex x={ x1 } y={ y2 } z="0" />
						<vertex x={ x1 } y={ y1 } z="0" />
					</face>);
					
					if ( twoSided == "true" ) {
						_faces.appendChild( <face>
						<vertex x={ x1 } y={ y1 } z="0" />
						<vertex x={ x1 } y={ y2 } z="0" />
						<vertex x={ x2 } y={ y2 } z="0" />
						<vertex x={ x2 } y={ y1 } z="0" />
					</face>);
					}
					
				}
			}
			
			
			return _faces.face;
		}
		
		return new XMLList();
	}
	
	public static const PLANE:String = "Plane";
	
	/**
	 * 頂点の情報を返します UV情報は含まれません。
	 * @param	primitive
	 * @return
	 */
	public static function createVerticesPrimitive(primitive:XML):XMLList {
		
		var _vertices:XML = <vertices></vertices>;
		
		with (primitive) {
			switch ( @primitive.toString() ) {
				case PLANE : return buildPlaneVertices(@ax, @ay, @az, @bx, @by, @bz, @cx, @cy, @cz, @dx, @dy, @dz, @rv);
				default : return new XMLList();
			}
		}
		
		function buildPlaneVertices(ax:Number, ay:Number, az:Number, bx:Number, by:Number, bz:Number, cx:Number, cy:Number, cz:Number, dx:Number, dy:Number, dz:Number, rv:String = "false"):XMLList {
			
			if ( rv == "true" ) {
				v(ax, ay, az);
				v(bx, by, bz);
				v(cx, cy, cz);
				v(dx, dy, dz);
			}
			else {
				v(dx, dy, dz);
				v(cx, cy, cz);
				v(bx, by, bz);
				v(ax, ay, az);
			}
			
			return _vertices.vertex;
		}
		
		/**
		 * create v
		 * @param	_x
		 * @param	_y
		 * @param	_z
		 */
		function v(_x:Number, _y:Number, _z:Number):void {
			_vertices.appendChild(<vertex x={_x} y={_y} z={_z} />);
		}
	}
}