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: Alternativa3D discipline

@OKASUKE
*2010/02/26
* Alternativa3D discipline(Alternativa3Dの鍛錬)
* たまに小Boxがくっつきます。。。そのうち分裂・・・
* 小Box数を多くするとPlaneにちかちか線がはしる。。。なして?
*
* ↑説明すると長くなるので、詳しくは割愛しますが、
* alternativa3DのWireMaterialはBSPツリーの階層に基ずくポリゴン分割の視覚化を目的とした
* デバッグの為の機能と位置づけられています。なので、ちかちか走るのは「仕様」だそうです。
* とりあえずObject3Dのmobility(BSPの階層Lv)を指定する事で、分割線を(ある程度)制御できます。
*
* boxがくっつくのは、Object3D同士が2度続けて当たらないようにする事で、ある程度は解消できます。
*
* @narutohyper
/**
 * Copyright narutohyper ( http://wonderfl.net/user/narutohyper )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/96de
 */

// forked from OKASUKE's Alternativa3D discipline
/*@OKASUKE
*2010/02/26
* Alternativa3D discipline(Alternativa3Dの鍛錬)
* たまに小Boxがくっつきます。。。そのうち分裂・・・
* 小Box数を多くするとPlaneにちかちか線がはしる。。。なして?
*
* ↑説明すると長くなるので、詳しくは割愛しますが、
* alternativa3DのWireMaterialはBSPツリーの階層に基ずくポリゴン分割の視覚化を目的とした
* デバッグの為の機能と位置づけられています。なので、ちかちか走るのは「仕様」だそうです。
* とりあえずObject3Dのmobility(BSPの階層Lv)を指定する事で、分割線を(ある程度)制御できます。
*
* boxがくっつくのは、Object3D同士が2度続けて当たらないようにする事で、ある程度は解消できます。
*
* @narutohyper
*/

package {
	import alternativ5.engine3d.materials.FillMaterial;
	import alternativ5.engine3d.primitives.Box;
	import alternativ5.engine3d.events.MouseEvent3D
	import alternativ5.types.Point3D;
	import alternativ5.engine3d.primitives.Plane;
	import alternativ5.engine3d.materials.WireMaterial;
	import alternativ5.engine3d.core.Object3D;
	import alternativ5.utils.FPS	
	
	import flash.display.Sprite;
	import flash.display.BlendMode;	
	import flash.display.DisplayObject;
	
	[SWF(width = 465, height = 465, frameRate = 30, backgroundColor=0x00000000)]	
	public class Main extends Sprite {

			public static const COUNTBOX:Number = 60; //小Box数
		private var _materialList:Vector.<FillMaterial> = new Vector.<FillMaterial>;
		private var _boxList:Vector.<Ball> = new Vector.<Ball>;
	
		public function Main():void {

			FPS.init(stage); 
			var template:BasicTemplate = new BasicTemplate();
			addChild(template);				
			var box:Box = new Box(500,500,500,10,10,10,true)
			box.mobility=0;
			box.name="outerWall";
			box.cloneMaterialToAllSurfaces(new WireMaterial(1, 0xFF00FFFF));
			template.scene.root.addChild(box);
						
			for (var i:uint = 0; i < COUNTBOX; i++) {
				_materialList[i] = new FillMaterial(Math.random() * 0xFFFFFF, 1,BlendMode.NORMAL,-1,0x000000);
				_boxList[i] = new Ball(template.scene, 30, 30, 30, _materialList[i]); 
				//_boxList[i].cloneMaterialToAllSurfaces(_materialList[i]);
				template.scene.root.addChild(_boxList[i]);		
			}
			
			
			template.onPreRender = function():void {			
				var rateZ:Number;
				var rateX:Number;
						
				rateZ = (mouseY - stage.stageHeight/2)/2;
				rateX = (mouseX - stage.stageWidth/ 2)/ 2;					
									
				for (var i:int = 0; i <= _boxList.length - 1; i++) {
			
					_boxList[i].doAction();
					
				}			
					
				//trace(template.camera.y)

				if (template.camera.y  >= 640) {					
						template.camera.z  += ( rateZ - template.camera.z) * 0.02;
						template.camera.y  += ( rateX - template.camera.x) * 0.02;							
				} else {
					if (template.camera.y <= -640 ) {
						template.camera.z  += ( rateZ - template.camera.z) * 0.01;
						template.camera.y  += ( rateX - template.camera.x) * 0.01;
					} else {
						template.camera.z  += ( rateZ - template.camera.z) * 0.1;
						template.camera.y  += ( rateX - template.camera.x) * 0.1;
					}
					
				}
	
				template.cameraContoller.lookAt(new Point3D());
			}		
		}
	}
}


import alternativ5.engine3d.core.Mesh;
import alternativ5.engine3d.core.Surface;
import alternativ5.engine3d.primitives.Box;
import alternativ5.types.Set;
import alternativ5.engine3d.physics.Collision;
import alternativ5.engine3d.physics.EllipsoidCollider;
import alternativ5.types.Point3D;
import alternativ5.engine3d.materials.TextureMaterial;
import alternativ5.engine3d.materials.SurfaceMaterial;
import alternativ5.engine3d.materials.FillMaterial;
import alternativ5.types.Texture;

import flash.display.Sprite;
import flash.filters.BlurFilter;
import flash.display.GradientType;
import flash.geom.Matrix;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
//Ballクラスはnarutohyperさんのを参考
//ここらへんかな、
//http://marubayashi.net/tips/alternativa3d/step2/a2-3/index.html
class Ball extends Box {

	private var collider:EllipsoidCollider;

	private var collision:Collision;

	private var nowPoint:Point3D;			//現在の位置
	private var newPoint:Point3D;			//移動位置
	private var speed:Point3D;				//スピード
	private var deceleration:Number;		//跳ね
	private var acceleration:Point3D;		//加速

	private var tempPoint:Point3D;
	private var _firstmaterial:FillMaterial;
	
	private var tempBall:Mesh
	
	public function Ball(scene:Scene3D,w:Number,h:Number,l:Number,mate:FillMaterial) {
		super(w,h,l);
		mobility=1;
		tempPoint= new Point3D();
		nowPoint = new Point3D();
		newPoint = new Point3D();
		//等速運動なので、speedの値が固定
		speed=new Point3D(Math.random()*10-5,Math.random()*10+0.5,Math.random()*10+0.5);				//スピード
		//加速・減速は重力計算で使用するので使わない
		//deceleration=0.6;					//減速
		//acceleration=new Point3D(Math.random()-0.5,Math.random()+0.5,Math.random()+0.5);	//加速
		
		collider = new EllipsoidCollider (scene,w,h,l);
		collision = new Collision();
		collider.collisionSet = new Set()
		
		collider.collisionSet.add(this);
		nowPoint = new Point3D (Math.random() * 460 - 230,Math.random() * 460 - 230,Math.random() * 460 - 230);
		this.coords = nowPoint;	
		_firstmaterial = mate;
		changeMaterial();
	}
		
	public function doAction():void {
		//speed.add(acceleration);		//加速減速は、重力関係ないので必要なし
		
		if (collider.getCollision (nowPoint, speed, collision)) {
			//壁で方向転換、同じ球には続けて当たらないように処理
			if (tempBall!=collision.face.mesh || collision.face.mesh.name=="outerWall") {
				tempBall=collision.face.mesh

				//speed.multiply(deceleration);		//加速減速は、重力関係ないので必要なし

				//当たった面の法線を使い、内積で方向を反転させる
				tempPoint=collision.normal
				tempPoint.multiply(2 * Point3D.dot(tempPoint, speed));
				speed.subtract(tempPoint);

				this.cloneMaterialToAllSurfaces(_textureMaterialArray[0]);
			} else {
				collider.calculateDestination(nowPoint, speed , newPoint);
				this.cloneMaterialToAllSurfaces(_firstmaterial);
			}
		}else {
			collider.calculateDestination(nowPoint, speed , newPoint);
			this.cloneMaterialToAllSurfaces(_firstmaterial);
		}		
		nowPoint.copy(newPoint);
		this.coords = nowPoint;
		this.rotationX += 1;
		this.rotationY += 1;
		this.rotationZ += 1;
	}
	
	private var _textureMaterialArray:Array = [];	
	private function changeMaterial():void {
		_textureMaterialArray.push(new FillMaterial(0xFFFFFF));
	}	
}


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.y = -500;
		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;
		}
	}
}