Manipulasi Tekstur Collada (DAE)

Berikut ini demo manipulasi tekstur Collada (DAE) secara dinamis pada saat runtime.

Click to launch

Click to launch

DAE & texture files are courtesy of Away3D team.

package 
{
	import away3d.animators.SkinAnimation;
	import away3d.cameras.Camera3D;
	import away3d.containers.ObjectContainer3D;
	import away3d.containers.Scene3D;
	import away3d.containers.View3D;
	import away3d.core.base.Mesh;
	import away3d.core.base.Object3D;
	import away3d.core.math.Number3D;
	import away3d.core.utils.Cast;
	import away3d.loaders.Collada;
	import away3d.materials.BitmapMaterial;
	import away3d.materials.TransformBitmapMaterial;
	import away3d.primitives.Cube;
	import away3d.primitives.Plane;
	import br.com.stimuli.loading.BulkLoader;
	import br.com.stimuli.loading.BulkProgressEvent;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Matrix;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.utils.getTimer;
	
	public class Main extends Sprite{
		
		public var daeFile:String = "mario_testrun.dae";
		public var daeTexture:String = "assets/mario_tex.jpg";
		public var floorTexture:String = "assets/floor.jpg";
		
		public var cam:Camera3D;
		public var scene:Scene3D;
		public var view:View3D;
		public var collada:Collada;
		public var model:ObjectContainer3D;
		public var skinAnim:SkinAnimation;
		public var mesh:Mesh;
		
		public var floor:Plane;
		
		//material variables
		public var colladaMaterial:BitmapMaterial;
		public var floorMaterial:TransformBitmapMaterial;
		
		//drawing pane
		public var materialSprite:Sprite;
		
		public var ldr:BulkLoader;
		
		public var loadStatus:TextField;
		
		public function Main() {
			
			loadStatus = new TextField();
			loadStatus.textColor = 0xFFFFFF;
			loadStatus.autoSize = TextFieldAutoSize.RIGHT;
			addChild(loadStatus);
			
			if (stage) loadAssets();
			else addEventListener(Event.ADDED_TO_STAGE, loadAssets);
		}
		
//----------------------------------------------------------- LOAD STUFF	

		private function loadAssets(e:Event = null):void {
			
			removeEventListener(Event.ADDED_TO_STAGE, loadAssets);
			
			ldr = new BulkLoader('assets');
			
			ldr.logLevel = BulkLoader.LOG_INFO;
			
			ldr.add(daeTexture, { id:"texture", type:BulkLoader.TYPE_IMAGE } );
			ldr.add(floorTexture, { id:"floor", type:BulkLoader.TYPE_IMAGE } );
			ldr.add(daeFile, { id:"dae", type:BulkLoader.TYPE_XML } );
			
			ldr.addEventListener(BulkProgressEvent.PROGRESS, handleBulkLoaderEvents);
			ldr.addEventListener(BulkProgressEvent.COMPLETE, handleBulkLoaderEvents);
			
			ldr.start(1);
		}
		
		private function handleBulkLoaderEvents(e:BulkProgressEvent):void {
			if (e.type == BulkProgressEvent.PROGRESS) {
				
				loadStatus.text = "loading ..." + (BulkLoader.truncateNumber(e.percentLoaded,2) * 100) +"%";
				
				return;
			}
			if (e.type == BulkProgressEvent.COMPLETE) {
				
				loadStatus.x = 200;
				loadStatus.text = "<<< draw lines with your mouse here";
				
				initEngine();
				
				initFloor(ldr.getBitmap("floor"));
				
				initObjects(ldr.getXML("dae"), ldr.getBitmap("texture"));
				
			}
			
			
		}
		
//----------------------------------------------------------- INIT

		private function initEngine():void {
			
			scene = new Scene3D();
			
			cam = new Camera3D();
			cam.lookAt(new Number3D(0, 0, 0));
			cam.moveUp(100);
			cam.moveBackward(400);
			
			view = new View3D();
			view.x = stage.stageWidth / 2;
			view.y = stage.stageHeight / 2;
			view.camera = cam;
			view.scene = scene;
			view.mouseZeroMove = true;
			addChild(view);
			
		}
		
		private function initFloor(material:Bitmap):void {
			
			floorMaterial = new TransformBitmapMaterial(material.bitmapData);
			floorMaterial.repeat = true;
			
			floor = new Plane();
			floor.width = 400;
			floor.height = 400;
			floor.material = floorMaterial;
			
			scene.addChild(floor);
		}
		
		private function initObjects(dae:XML,material:Bitmap):void {
			
			colladaMaterial = new BitmapMaterial(material.bitmapData);
			
			collada = new Collada();
			collada.scaling = 10;
			
			/**
			 * [1] If you do this, you can't assign a new material later on. Dunno why. 
			 * 
			 *   collada.material = colladaMaterial;
			 * 
			 * Do [2] instead.
			 */
			
			model = collada.parse(dae) as ObjectContainer3D;
			
			//[2] 
			Mesh(model.getChildByName('polySurface1')).material = colladaMaterial;
			
			scene.addChild(model);
			
			skinAnim = model.animationLibrary.getAnimation("default").animation as SkinAnimation;
			
			addEventListener(Event.ENTER_FRAME, render);
			
			initDrawingPane(material);
		}
		
//----------------------------------------------------------- DRAWING PANE		
		
		private function initDrawingPane(material:Bitmap):void {
			
			materialSprite = new Sprite();
			materialSprite.addChild(new Bitmap(material.bitmapData));
			materialSprite.scaleX = materialSprite.scaleY = .2;
			addChild(materialSprite);
			
			var drawingLayer:Sprite = new Sprite();
			drawingLayer.name = "drawingLayer";
			materialSprite.addChild(drawingLayer);
			
			materialSprite.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
		}
		
		
		private function onMouseDown(e:MouseEvent):void {
			
			var drawingLayer:Sprite = materialSprite.getChildByName('drawingLayer') as Sprite;
			drawingLayer.graphics.lineStyle(1, 0xFFFFFF);
			drawingLayer.graphics.moveTo(e.localX, e.localY);
			materialSprite.addEventListener(MouseEvent.MOUSE_MOVE, drawLine);
			stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
		}
		
		private function drawLine(e:MouseEvent):void {
			var drawingLayer:Sprite = materialSprite.getChildByName('drawingLayer') as Sprite;
			drawingLayer.graphics.lineTo(e.localX, e.localY);
		}
		
		private function onMouseUp(e:MouseEvent):void {
			if (materialSprite.hasEventListener(MouseEvent.MOUSE_MOVE)){
				materialSprite.removeEventListener(MouseEvent.MOUSE_MOVE, drawLine);
				
				var bd:BitmapData = new BitmapData(materialSprite.width, materialSprite.height);
				var mat:Matrix = new Matrix(materialSprite.scaleX, 0, 0, materialSprite.scaleY);
				bd.draw(materialSprite,mat);
				
				//This won't work if you assign the material to the collada instance like [1]
				Mesh(model.getChildByName('polySurface1')).material = new BitmapMaterial(bd);
				
			}
		}
		

		
//----------------------------------------------------------- RENDER

		private function render(e:Event):void {
			model.rotationY += 10;
			//update the collada animation
			skinAnim.update(getTimer() * 2 / 1000);
			view.render();
		}
	}
}
Download source : → dae-mat.rar

Also in this category ...


4 Comments

  1. Thanx for the example..

    eh btw, kalo boleh tanya, saya skrg lg suka pake engine away3d di FlashPlayer 10, tp koq itu ngelag banget (diitung2 ga bisa lebih dr 2000 poly).. kalo pake Flex itu bisa lebih kenceng ngga ya?
    Thanks again.. keep on posting 🙂

  2. Pake Flex atau Flash nggak ada pengaruhnya sama performance. Krn keterbatasan flashplayer, model yg dipake harus low-poly. 2000 poly kayanya emang terlalu berat. Idealnya dibawah 1000 biar bisa jalan lancar di semua kompie termasuk yg low-spec.

  3. ooOw.. iya sih 1000-an poly polygonnya tabrak2an aja udah turun fpsnya, kekekeke.

    Tapi ngeliat example2 di away3d (salah satunya http://www.bandit3.com/, cocacola2 dsb) dimana jumlah polygonnya terlihat banyak dan jenis clipping, render, n material precision dsbnya kayaknya dipake mentok2nya away3d tp bisa ngga sebegitu ngelag..

  4. bandit3 poly-nya ga banyak. teksturnya aja yg bagus. Tembok gedung2 nya kalo diliat dari deket semua rata ga ada reliefnya. Kalo pengen bikin model yang low-poly tapi keliatan punya detil tinggi coba pake bump-map.

Comments are closed.