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

3D VOCALOID RUNS!

ミクさん、リンちゃん、レンきゅんが走ります。3人のうち誰になるかはランダムで決まります。

[↑]: 前進
[←][→]: 旋回
[A][D]: カメラ回転
[W][S]: カメラ高さ調節

3d model: mqdlさん ( http://mqdl.jpn.org/ )

※もし動かない場合は一度flashエリア内をクリックしてみてください
/**
 * Copyright daniwell ( http://wonderfl.net/user/daniwell )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/tkxl
 */

package  
{
	import alternativa.engine3d.core.Camera3D;
	import alternativa.engine3d.core.Object3D;
	import alternativa.engine3d.core.Resource;
	import alternativa.engine3d.core.View;
	import alternativa.engine3d.lights.AmbientLight;
	import alternativa.engine3d.lights.DirectionalLight;
	import alternativa.engine3d.lights.OmniLight;
	import alternativa.engine3d.materials.TextureMaterial;
	import alternativa.engine3d.primitives.Plane;
	import alternativa.engine3d.resources.BitmapTextureResource;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.Stage3D;
	import flash.display3D.Context3DRenderMode;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.geom.Point;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.system.LoaderContext;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.ui.Keyboard;
	
	public class ModelRun extends Sprite 
	{
		// MMD でモーション付けて、Blender のプラグインで読み込んで COLLADA 書き出しするだけ
		// 但しモーションに IK は使えない
		private const PATH_DAEIDLE :Array = ["http://aidn.jp/_wonderfl/vr/miku_idle.dae",    "http://aidn.jp/_wonderfl/vr/rin_idle.dae",    "http://aidn.jp/_wonderfl/vr/len_idle.dae"];
		private const PATH_DAERUN  :Array = ["http://aidn.jp/_wonderfl/vr/miku_run.dae",     "http://aidn.jp/_wonderfl/vr/rin_run.dae",     "http://aidn.jp/_wonderfl/vr/len_run.dae"];
		private const PATH_TEXTURE :Array = ["http://aidn.jp/_wonderfl/vr/miku_texture.png", "http://aidn.jp/_wonderfl/vr/rin_texture.png", "http://aidn.jp/_wonderfl/vr/len_texture.png"];
		
		private const CAMERA_DISTANCE :Number = 600;
		private const BOX_NUMS        :int    = 30;
		
		private var _texture :BitmapData;
		private var _daeIdle :XML;
		private var _daeRun  :XML;
		
		private var _n :int = int(Math.random() * 3);
		
		private var _stage3D :Stage3D;
		private var _camera  :Camera3D;
		private var _scene   :Object3D;
		
		private var _model    :ColladaModel;
		private var _shadow   :Plane;
		private var _boxes    :/*CustomBox*/Array = [];
		private var _keyFlags :/*Boolean*/Array = [];
		
		private var _t      :Number = 0;
		private var _rot    :Number = 0;
		private var _rotTmp :Number = -90;
		
		private var _cameraZ :Number = 50;
		
		private var _tfLoading :TextField;
		
		public function ModelRun () {
			
			stage.scaleMode = "noScale";
			stage.align     = "TL";

			// Now Loading
			_tfLoading = addChild(new TextField()) as TextField;
			_tfLoading.defaultTextFormat = new TextFormat("_sans", 42, 0x999999, true);
			_tfLoading.autoSize = "left"; _tfLoading.text = "NOW LOADING...";
			stage.addEventListener(Event.ENTER_FRAME, _enterFrame);

			// Stage3D
			_stage3D = stage.stage3Ds[0];
			_stage3D.addEventListener(Event.CONTEXT3D_CREATE, _contextCreate);
			_stage3D.requestContext3D(Context3DRenderMode.AUTO);
        }
		
		private function _contextCreate ( evt :Event ) :void {
			
			_stage3D.removeEventListener(Event.CONTEXT3D_CREATE, _contextCreate);
			
			// IDLE 時データ読み込み
			var ul :URLLoader = new URLLoader(); ul.addEventListener(Event.COMPLETE, _loadCompleteIdle); ul.load(new URLRequest(PATH_DAEIDLE[_n]));
		}
		private function _loadCompleteIdle ( evt :Event ) :void  {
			
			_daeIdle = XML(URLLoader(evt.target).data);
			
			// RUN 時データ読み込み
			var ul :URLLoader = new URLLoader(); ul.addEventListener(Event.COMPLETE, _loadCompleteRun); ul.load(new URLRequest(PATH_DAERUN[_n]));
		}
		private function _loadCompleteRun ( evt :Event ) :void {
			
			_daeRun = XML(URLLoader(evt.target).data);
			
			var l :Loader = new Loader();
			l.contentLoaderInfo.addEventListener(Event.COMPLETE, _loadCompleteTexture);
			l.load(new URLRequest(PATH_TEXTURE[_n]), new LoaderContext(true));
		}
		private function _loadCompleteTexture ( evt :Event ) :void {
			
			_tfLoading.visible = false;
			_texture = Bitmap(evt.target.content).bitmapData;
			
			_scene  = new Object3D();
			_camera = new Camera3D(1, 10000);
			
			_camera.view = new View(stage.stageWidth, stage.stageHeight);
			_camera.view.hideLogo();
			addChild(_camera.view);
			//// addChild(_camera.diagram);
			
			_camera.rotationX = MathUtil.toRad(-90);
			_camera.x = 0; _camera.y = 0; _camera.z = 250;
			_camera.fov = 1.8;
			
			_scene.addChild(_camera);
			
			
			// Box
			for (var i :int = 0; i < BOX_NUMS; i ++) _boxes.push(new CustomBox(_scene));
			
			
			// Model
			_model = new ColladaModel(_stage3D, _scene);
			_model.init(_daeIdle, _texture, 0, 0, -300, 100);
			_model.addAnimation(_daeIdle, 0);
			_model.addAnimation(_daeRun,  1);
			
			
			// Shadow
			var bmd :BitmapData = new BitmapData(128, 128, false, 0x0);
			var sp :Shape = new Shape(); sp.graphics.beginFill(0xffffff); sp.graphics.drawCircle(64, 64, 64); sp.graphics.endFill();
			bmd.draw(sp);
			
			var material :TextureMaterial = new TextureMaterial(new BitmapTextureResource(new BitmapData(128, 128, false, 0x333333)), new BitmapTextureResource(bmd));
			material.alphaThreshold = 1;
			
			_shadow = new Plane(100, 100);
			_shadow.setMaterialToAllSurfaces(material);
			_shadow.z = _model.z;
			_shadow.y = _model.y;
			_scene.addChild(_shadow);
			
			
			// Light
			var aLight :AmbientLight = new AmbientLight(0xffffff);
			aLight.intensity = 0.5;
			_scene.addChild(aLight);
			
			var oLight :OmniLight = new OmniLight(0xffffff, 1000, 10000);
			oLight.x = 100; oLight.y = 200; oLight.z = 200;
			_scene.addChild(oLight);
			
			var dLight :DirectionalLight = new DirectionalLight(0xffffff);
			dLight.x = 0; dLight.y = - 100; dLight.z = 100; dLight.intensity = 0.5; 
			_scene.addChild(dLight);
			
			
			// Resource
			for each (var resource :Resource in _scene.getResources(true)) resource.upload(_stage3D.context3D);
			
			
			// Event
			stage.addEventListener(KeyboardEvent.KEY_DOWN, _keyDown);
			stage.addEventListener(KeyboardEvent.KEY_UP,   _keyUp);
			
			stage.addEventListener(Event.RESIZE, _resize);
			_resize();
		}
		/* RESIZE */
		private function _resize ( evt :Event = null ) :void {
			_camera.view.width  = stage.stageWidth;
			_camera.view.height = stage.stageHeight;
		}
		/* KEY DOWN & KEY UP */
		private function _keyDown ( evt :KeyboardEvent ) :void { _keyFlags[evt.keyCode] =  true; if (evt.keyCode == Keyboard.UP) _model.changeAnimation(1, 1.8); }
		private function _keyUp   ( evt :KeyboardEvent ) :void { _keyFlags[evt.keyCode] = false; if (evt.keyCode == Keyboard.UP) _model.changeAnimation(0, 1.4); }
		
		/* ENTER FRAME */
		private function _enterFrame ( evt :Event ) :void {
			// loading
			if (! _scene) {
				_tfLoading.visible = ! _tfLoading.visible;
				return;
			}
			
			if (_keyFlags[Keyboard.LEFT])  _model.rotationZ += MathUtil.toRad(5);
			if (_keyFlags[Keyboard.RIGHT]) _model.rotationZ -= MathUtil.toRad(5);
			
			if (_keyFlags[Keyboard.UP]) {
				
				_model.moveFront(16);
				
				var p :Point, n :int = 0;
				var l :int = _boxes.length;
				
				for (var i :int = 0; i < l; i ++) {
					
					p = _boxes[i].hitTest(_model.x, _model.y, _model.prePosition.x, _model.prePosition.y);
					if (p) {
						_model.x = p.x;
						_model.y = p.y;
						i = -1; n ++; if (10 < n) break;
					}
				}
				_shadow.x = _model.x;
				_shadow.y = _model.y;
			}
			
			_model.updataAnimation();
			
			// カメラの回転
			     if (_keyFlags[Keyboard.A]) _rotTmp  += 8;
			else if (_keyFlags[Keyboard.D]) _rotTmp  -= 8;
			else if (_keyFlags[Keyboard.W]) _cameraZ += 20;
			else if (_keyFlags[Keyboard.S]) _cameraZ -= 20;
			
			_updateCameraPosition();
			_camera.render(_stage3D);
		}
		
		private function _updateCameraPosition ( ) :void {
			
			_rot += (_rotTmp - _rot) / 6;
			
			var px :Number = _model.x + CAMERA_DISTANCE * Math.cos(MathUtil.toRad(_rot));
			var py :Number = _model.y + CAMERA_DISTANCE * Math.sin(MathUtil.toRad(_rot));
			
			_camera.x += (px - _camera.x) / 6;
			_camera.y += (py - _camera.y) / 6;
			_camera.z += (_cameraZ - _camera.z) / 6;
			
			_camera.x += Math.sin(_t / 210) * 11;
			_camera.y += Math.sin(_t / 300) * 9;
			_t += 11;
			
			_camera.lookAt(_model.x, _model.y, _model.z);
		}
		
	}
}
import alternativa.engine3d.animation.AnimationClip;
import alternativa.engine3d.animation.AnimationController;
import alternativa.engine3d.core.Object3D;
import alternativa.engine3d.loaders.ParserCollada;
import alternativa.engine3d.materials.TextureMaterial;
import alternativa.engine3d.materials.VertexLightTextureMaterial;
import alternativa.engine3d.objects.Mesh;
import alternativa.engine3d.primitives.Box;
import alternativa.engine3d.resources.BitmapTextureResource;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Stage3D;
import flash.geom.Point;
import mx.core.BitmapAsset;


/* -----------------------------------------------------------------
 * ColladaModel
 */
class ColladaModel extends Object3D
{
	private var _stage3D  :Stage3D;
	private var _material :TextureMaterial;
	
	private var _animationController :AnimationController;
	private var _animationClips      :/*AnimationClip*/Array = [];
	
	private var _textureResources :/*BitmapTextureResource*/Array = [];
	
	private var _pre :Point;
	
	public function ColladaModel ( stage3D :Stage3D, parent :Object3D = null )  {
		_stage3D = stage3D;
		if (parent) parent.addChild(this);
	}
	
	public function init ( dae :*, texture :*, x :Number = 0, y :Number = 0, z :Number = 0, scale :Number = 1 ) :void {
		
		if (! (dae is XML)) dae = new XML(dae);
		if (texture is Bitmap || texture is BitmapAsset) texture = texture.bitmapData;
		
		this.x = x; this.y = y; this.z = z;
		scaleX = scaleY = scaleZ = scale;
		_pre = new Point(x, y);
		
		// Parser
		var parser :ParserCollada = new ParserCollada();
		parser.parse(dae);
		
		// Texture
		var texResource :BitmapTextureResource = new BitmapTextureResource(texture);
		texResource.upload(_stage3D.context3D);
		var txtRes :BitmapTextureResource = texResource;
		_material = new TextureMaterial(txtRes);
		
		// Mesh
		for each (var obj :Object3D in parser.objects) {
			var mesh :Mesh = obj as Mesh;
			if (mesh) { mesh.setMaterialToAllSurfaces(_material); addChild(obj); }
		}
	}
	
	/* 前進 */
	public function moveFront ( d :Number ) :void {
		_pre.x = this.x;
		_pre.y = this.y;
		
		var radZ :Number = this.rotationZ;
		this.x += d * Math.sin(radZ);
		this.y -= d * Math.cos(radZ);
	}
	
	/* アニメーションのアップデート */
	public function updataAnimation ( ) :void { _animationController.update(); }
	
	/* アニメーションを追加 */
	public function addAnimation ( dae :*, id :int ) :void {
		if (! (dae is XML)) dae = new XML(dae);
		
		// Animation Clip
		var animationClip :AnimationClip = ParserCollada.parseAnimation(dae);
		animationClip.attach(this, true);
		
		_animationClips[id] = animationClip;
		
		// Animation Controller
		if (! _animationController) {
			_animationController      =  new AnimationController();
			_animationController.root = animationClip;
		}
	}
	/* アニメーションの切り替え */
	public function changeAnimation ( id :int, speed :Number = 1.0, loop :Boolean = true ) :void {
		_animationClips[id].speed = speed;
		_animationClips[id].loop  = loop;
		_animationController.root = _animationClips[id];
	}
	
	public function get prePosition ( ) :Point { return _pre; }
}

/* -----------------------------------------------------------------
 * Box
 */
class CustomBox extends Box
{
	private var _p :/*Point*/Array = [];
	
	public function CustomBox ( parent :Object3D = null ) {
		
		var w :int = MathUtil.rand(100, 500);
		var l :int = MathUtil.rand(100, 500);
		var h :int = MathUtil.rand(100, 500);
		
		super(w, l, h);
		
		const RANGE :int = 3000;
		if (Math.random() < 0.5) {
			x = MathUtil.rand(-RANGE, RANGE);
			y = (Math.random() < 0.5) ? MathUtil.rand(-RANGE, -l/2) : MathUtil.rand(l/2, RANGE);
		} else {
			x = (Math.random() < 0.5) ? MathUtil.rand(-RANGE, -w/2) : MathUtil.rand(w/2, RANGE);
			y = MathUtil.rand(-RANGE, RANGE);
		}
		
		
		z = - 300 + h /2;
		setMaterialToAllSurfaces(new VertexLightTextureMaterial(new BitmapTextureResource(new BitmapData(8, 8, false, 0xffffff))));
		if (parent) parent.addChild(this);
		
		var rad :Number = rotationZ = MathUtil.toRad(MathUtil.rand(0, 45));
		var cw :Number = (w + 90) / 2;
		var cl :Number = (l + 90) / 2;
		_p[0] = new Point(x + (-cw * Math.cos(rad) + cl * Math.sin(rad)), y + (-cw * Math.sin(rad) - cl * Math.cos(rad)));
		_p[1] = new Point(x + (-cw * Math.cos(rad) - cl * Math.sin(rad)), y + (-cw * Math.sin(rad) + cl * Math.cos(rad)));
		_p[2] = new Point(x + ( cw * Math.cos(rad) - cl * Math.sin(rad)), y + ( cw * Math.sin(rad) + cl * Math.cos(rad)));
		_p[3] = new Point(x + ( cw * Math.cos(rad) + cl * Math.sin(rad)), y + ( cw * Math.sin(rad) - cl * Math.cos(rad)));
		
		/*
		// Show HitArea
		var zz :Number = z - h / 2;
		var vec :Vector.<Vector3D> = new <Vector3D>[
			new Vector3D(_p[0].x, _p[0].y, zz),
			new Vector3D(_p[1].x, _p[1].y, zz),
			new Vector3D(_p[2].x, _p[2].y, zz),
			new Vector3D(_p[3].x, _p[3].y, zz),
			new Vector3D(_p[0].x, _p[0].y, zz)
		];
		var wire :WireFrame = WireFrame.createLineStrip(vec, 0x999999, 1, 2);
		parent.addChild(wire);
		//*/
	}
	
	public function hitTest (nx :Number, ny :Number, px :Number, py :Number) :Point {
		
		var f :Boolean = MathUtil.boxContainsPos(_p[0].x, _p[0].y, _p[1].x, _p[1].y, _p[2].x, _p[2].y, _p[3].x, _p[3].y, nx, ny);
		if (! f) return null;
		
		for (var i :int = 0; i < 4; i ++) {
			
			var p1x :Number = _p[i].x;
			var p1y :Number = _p[i].y;
			var p2x :Number = _p[(i+1)%4].x;
			var p2y :Number = _p[(i+1)%4].y;
			
			f = MathUtil.intersectLineSegment(px, py, nx, ny, p1x, p1y, p2x, p2y);
			if (f) {
				var pt :Point = MathUtil.getCrossPoint(p1x, p1y, p2x, p2y, nx, ny);
				return new Point(pt.x + (pt.x - nx) * 0.2, pt.y + (pt.y - ny) * 0.2);
			}
		}
		return null;
	}
	
}

/* -----------------------------------------------------------------
 * MathUtil
 */
class MathUtil
{
	/* min ~ max の範囲で乱数生成 */
	public static function rand ( min :Number, max :Number ) :Number { return Math.random() * ( max - min ) + min; }
	/* 角度からラジアンに変換 */
	public static function toRad ( deg :Number ) :Number { return deg * Math.PI / 180; }
	
	/* 外積 */
	public static function intersect ( p1x :Number, p1y :Number, p2x :Number, p2y :Number, p3x :Number, p3y :Number, p4x :Number, p4y :Number ) :Number {
		
		var n :Number = ((p1x - p2x) * (p3y - p1y) + (p1y - p2y) * (p1x - p3x)) * ((p1x - p2x) * (p4y - p1y) + (p1y - p2y) * (p1x - p4x));
		return n;
	}
	/* 任意の三角形の中に任意の点が内包されているかどうか */
	public static function triContainsPos ( p1x :Number, p1y :Number, p2x :Number, p2y :Number, p3x :Number, p3y :Number, psx :Number, psy :Number ) :Boolean {
		
		if ((p1x - p3x) * (p1y - p2y) == (p1x - p2x) * (p1y - p3y)) return false;
		
		if (intersect(p1x, p1y, p2x, p2y, psx, psy, p3x, p3y) < 0) return false;
		if (intersect(p1x, p1y, p3x, p3y, psx, psy, p2x, p2y) < 0) return false;
		if (intersect(p2x, p2y, p3x, p3y, psx, psy, p1x, p1y) < 0) return false;
		
		return true;
	}
	/* 任意の四角形の中に任意の点が内包されているかどうか(凸のみ) */
	public static function boxContainsPos ( p1x :Number, p1y :Number, p2x :Number, p2y :Number, p3x :Number, p3y :Number, p4x :Number, p4y :Number, psx :Number, psy :Number ) :Boolean {
		
		if (triContainsPos(p1x, p1y, p2x, p2y, p3x, p3y, psx, psy)) return true;
		if (triContainsPos(p1x, p1y, p3x, p3y, p4x, p4y, psx, psy)) return true;
		
		return false;
	}
	/* 線分の交差判定 */
	public static function intersectLineSegment ( p1x :Number, p1y :Number, p2x :Number, p2y :Number, p3x :Number, p3y :Number, p4x :Number, p4y :Number) :Boolean {
		
		if (intersect(p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y) < 0)
			if (intersect(p3x, p3y, p4x, p4y, p1x, p1y, p2x, p2y) < 0) return true;
		return false;
	}
	/* 点から直線におろした垂線の交点の座標 */
	public static function getCrossPoint ( p1x :Number, p1y :Number, p2x :Number, p2y :Number, psx :Number, psy :Number ) :Point {
		
		var a :Number = p2y - p1y;
		var b :Number = p1x - p2x;
		var c :Number = (p1y - p2y) * p1x + (p2x - p1x) * p1y;
		
		var d :Number = (a * psx + b * psy + c) / (a * a + b * b);
		
		var x :Number = psx - d * a;
		var y :Number = psy - d * b;
		
		return new Point(x, y);
	}
}