Home > 梅原 > [PV3D]ColorAnaglyph

[PV3D]ColorAnaglyph

20090715
Category:梅原 /Tags:, ,

umhr_coloranaglyphアナグリフのカラー対応をしてみた。
理屈としては単純で、red一色のディスプレイオブジェクトと、green,blue二色のディスプレイオブジェクトを用意すればいい。

こんなかんじ

//赤用のディスプレイオブジェクト
redView.transform.colorTransform = new ColorTransform(1,0,0,1,0,0,0,0);
//青用のディスプレイオブジェクト
blueView.transform.colorTransform = new ColorTransform(0,1,1,1,0,0,0,0);
blueView.blendMode = "screen";

▼Wonderfl

▼参考
アナグリフの問題
http://www.geocities.jp/sasagelab/stereo36.html
製作(H1) anaglyph,画像色
http://www2.aimnet.ne.jp/nakahara/3dart/3seisak12.html

▼ActionScript AS3(FP9)

/**
*
* アナグリフのカラー対応をしてみた。
* 理屈としては単純で、red一色のディスプレイオブジェクトと、
* green,blue二色のディスプレイオブジェクトを用意すればいい。
*
* 赤用のディスプレイオブジェクト
* redView.transform.colorTransform = new ColorTransform(1,0,0,1,0,0,0,0);
* 青用のディスプレイオブジェクト
* blueView.transform.colorTransform = new ColorTransform(0,1,1,1,0,0,0,0);
* blueView.blendMode = "screen";
*
*
*
* 参考
* アナグリフの問題
* http://www.geocities.jp/sasagelab/stereo36.html
*
* 摩訶不思議な世界・3Dアート
* http://www2.aimnet.ne.jp/nakahara/3dart/3art.html
*
*
* forked from
* Papervision3Dで被写界深度
* 参照: http://clockmaker.jp/blog/2008/07/pv3d_gw_blur/
*/
package
{
    import flash.display.*;
    import flash.events.*;
    import flash.filters.*;
    import flash.geom.ColorTransform;
    import flash.display.BitmapData;

	[SWF(width = "465", height = "465", frameRate = "30", backgroundColor = "#000000")]
    public class Test2 extends Sprite
    {
		private var loadFiles_array:Array;
		private var MultiLoader:MultiLoaderClass = new MultiLoaderClass("http://mztm.heteml.jp/crossdomain.xml");
		private var data_xml:XML;
        /**
         * Constructor
         */
        public function Test2()
        {
			loadFiles_array = MultiLoader.setLoad(["http://mztm.heteml.jp/umhr/3d/arss/data.xml"], onXMLComp);
		}

		private function onXMLComp(e:*):void {
			var i:int;
			var jpg_array:Array = new Array();
			data_xml = XML(loadFiles_array[0].data);
			var _length:int = data_xml.items.item.length();
			for (i = 10; i < 30; i++) {
				if(data_xml.items.item[i].jpg != ""){
					var _array:Array = String(data_xml.items.item[i].jpg).split('/');
					var jpg_url:String = "http://mztm.heteml.jp/umhr/3d/arss/revolution/"+_array.pop();
					jpg_url = jpg_url.replace(/%/g,'');
					jpg_array.push(jpg_url);
				}
			}
			loadFiles_array = new Array();
			loadFiles_array = MultiLoader.setLoad(jpg_array, onComp);
		}

		private function onComp(e:* = null):void {
			var bitmap_array:Array = new Array();
			for (var i:int = 0; i < 20; i++) {
				bitmap_array[i] = new BitmapData(150, 150,false);
				bitmap_array[i].draw(loadFiles_array[i]);
			}
			var redView:View = new View(true,bitmap_array);
			redView.transform.colorTransform = new ColorTransform(1,0,0,1,0,0,0,0);
			addChild(redView);

			var blueView:View = new View(false,bitmap_array);
			blueView.transform.colorTransform = new ColorTransform(0,1,1,1,0,0,0,0);
			blueView.blendMode = "screen";
			addChild(blueView);

			addEventListener(Event.ENTER_FRAME, ENTER_FRAME);
			function ENTER_FRAME(event:Event = null):void {
				var mouseX:Number = Math.min(Math.max(stage.mouseX, 0), stage.stageWidth) - stage.stageWidth / 2;
				redView.loop(mouseX);
				blueView.loop(mouseX);
			}
		}

    }
}

import flash.display.*;
import flash.events.*;
import flash.filters.*;

import org.papervision3d.view.*;
import org.papervision3d.materials.*;
import org.papervision3d.objects.*;
import org.papervision3d.objects.primitives.*
import org.papervision3d.core.effects.BitmapColorEffect;

class View extends BasicView
{
	// const vars
	static private const OBJ_LENGTH   :int = 12;
	static private const CIRCLE_RANGE :int = 400;

	// 3d vars
	private var list :Array = []
	private var wrap :D isplayObject3D;
	/**
	 * Constructor
	 */
	public function View(isRed:Boolean,bitmap_array:Array)
	{
		//camera
		if(isRed){
			camera.x = 30;
			camera.rotationY = -1;
		}else{
			camera.x = -30;
			camera.rotationY = 1;
		}
		camera.y = 10;
		camera.z = 800;

		// wrap
		wrap = new DisplayObject3D();
		wrap.localRotationX = -15;
		scene.addChild(wrap);

		for (var i:int = 0; i < OBJ_LENGTH; i++)
		{
			var rot:Number = 360 * i / OBJ_LENGTH ;
			var m:BitmapMaterial = new BitmapMaterial(bitmap_array[i]);
			m.doubleSided = true;

			var o:Plane = new Plane(m, 150, 150);
			o.x = CIRCLE_RANGE * Math.sin(rot * Math.PI / 180);
			o.y = 0;
			o.z = CIRCLE_RANGE * Math.cos(rot * Math.PI / 180);
			o.rotationY = rot+180;
			o.useOwnContainer = true; //ココ重要

			var bce:BitmapColorEffect = new BitmapColorEffect(0);

			// 配列に追加 & wrapの子供にする
			list.push(wrap.addChild(o));
		}

		startRendering();
	}

	public function loop(num:Number):void
	{
		wrap.yaw(num/300);
		// 被写界深度
		for (var i:int = 0; i < list.length; i++)
		{
			var o:DisplayObject3D = list[i] as DisplayObject3D;
			var blur:Number = Math.ceil((CIRCLE_RANGE - o.sceneZ) / 50);
			o.filters = [new BlurFilter(blur, blur, 2)];
		}
	}
}

class MultiLoaderClass extends Sprite{
	import flash.system.Security;
	import flash.net.URLRequest;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.display.Loader;
	//import flash.display.LoaderInfo;

	private var onComplete:Function = function(arg:Array=null):void{};
	//private var onOpen:Function = function():void{};
	private var loadNum:int;
	private var loadCompNum:int;
	private var error_array:Array = new Array();
	private var URLs_array:Array = new Array();
	public var _uniqueParam:String = "";

	public function set uniqueParam(uStr:String):void {
		if (uStr) {
			if (uStr.substr(0,2) == "?=") {
				_uniqueParam = uStr;
			}else {
				_uniqueParam = "?=" + uStr;
			}
		}else {
			_uniqueParam = "";
		}
	}
	public function get uniqueParam():String {
		return _uniqueParam;
	}

	public function MultiLoaderClass(_str:String = null,uStr:String = null){
		if(_str){
			Security.loadPolicyFile(_str);
		}
		uniqueParam = uStr;
	}

	public function setLoad(__item_array:Array = null, _onComp:Function = null):Array {
		//trace(__item_array)
		loadCompNum = loadNum = 0;
		if(_onComp != null){
			onComplete = _onComp;
		}
		if (__item_array.length == 0) {
			loadNum ++;
			onComplete();
		}

		URLs_array = __item_array.concat();
		error_array = new Array();
		//trace(__item_array.length)
		//onOpen = _onOpen;
		var _array:Array = new Array();
		var _length:int = __item_array.length;
		for (var i:int = 0; i < _length; i++) {
			error_array[i] = false;
			if (__item_array[i] == null) { continue };
			var _extension:String = __item_array[i].substr(-4,4).toLowerCase();//拡張子を取り出す。
			if (_extension == ".xml" || _extension == "html") {
			//trace("**",__item_array[i]);
				loadNum ++;
				_array[i] = fnURLLoader(__item_array[i] + uniqueParam);
			}else if(_extension == ".jpg" || _extension == ".gif" || _extension == ".png" || _extension == ".swf"){
				loadNum ++;
				_array[i] = img(__item_array[i] + uniqueParam);
			}else if(_extension == ".bin"){
				loadNum ++;
				__item_array[i] = __item_array[i].substr(0, __item_array[i].length - 4);
				_array[i] = binaryFromURL(__item_array[i] + uniqueParam);
			}else{
				//_array[i] = null;
			}
		}

		return _array;
	}
	private function binaryFromURL(__url:String):URLLoader{
		var _loader:URLLoader = new URLLoader();
		_loader.dataFormat = URLLoaderDataFormat.BINARY;
		_loader.addEventListener(Event.COMPLETE,completeHandler);
		_loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
		_loader.load(new URLRequest(__url));
		return _loader;
	}

	private function fnURLLoader(__url:String):URLLoader{
		var _loader:URLLoader = new URLLoader();
		_loader.addEventListener(Event.COMPLETE,completeHandler);
		_loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
		//_loader.addEventListener(Event.OPEN,openHandler);
		_loader.load(new URLRequest(__url));
		//trace(_loader.loaderInfo);//.loaderURL
		return _loader;
	}

	private function img(__url:String):Loader{
		var _loader:Loader = new Loader();
		_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
		_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
		//_loader.contentLoaderInfo.addEventListener(Event.OPEN,openHandler);
		_loader.load(new URLRequest(__url));
		//_loader.name = __url;

		return _loader;
	}

	private function completeHandler(event:Event = null):void {
		loadCompNum ++;
		if(loadCompNum == loadNum){
			onComplete(error_array);
		}
		//var loaderInfo:LoaderInfo=event.currentTarget as LoaderInfo;
		//var loader:Loader=loaderInfo.loader;
		//addChild(loader);
	}
	private function openHandler (event:Event):void {
		if(Math.random()>0.95){
			trace ("読み込みを開始した");
			//event.currentTarget.contentLoaderInfo.close();
			var str:String = event.currentTarget.toString().substr(8);
			if(str == "LoaderInfo]"){
				//event.currentTarget.contentLoaderInfo.close();
				//event.target.contentLoaderInfo.close();
				//event.currentTarget.close();
				//event.target.close();
			}else if(str == "URLLoader]"){
				event.currentTarget.close();
				completeHandler();
			}

			//completeHandler();
			//onOpen();
		}
	}

	private function ioErrorHandler(event:IOErrorEvent):void {
		//event.text = "Error #2035: URL が見つかりません。 URL: file:///~~~~~";
		//event.text = "Error #2036: 読み込みが未完了です。 URL: http://~~~~~";
		//から、URLのみを取り出す。
		//trace(String(event.text).substr(String(event.text).indexOf(" URL: ")+6),"*****");
		for (var i:int = 0; i < URLs_array.length; i++) {
			var _str:String = String(event.text).substr(String(event.text).indexOf(" URL: ")+6).substr(-URLs_array[i].length);
			if(URLs_array[i] == _str){
				error_array[i] = true;
				//trace("これだ",i,_str)
			}
		}

		//URLs_array
		completeHandler();
	}
}

関連記事:

Comments are closed.