Away3D 4.0 Beta でプリミティブの頂点を取得して線を引く


Away3D 4.0 Beta でプリミティブの球体の頂点(vertexData)を取得して、その頂点に向けてランダムな位置からラインを引いてみたらこんな感じになりました。

120608_away3d_line

Away3D 4.0 Beta でプリミティブの頂点を利用した LineDrawing

画像クリックでデモ画面が開きます。
※ FlashPlayer 11 および GPU レンダリングが出来る PC が必要です(たぶん)

コードはこんな感じ。

package
{
	import away3d.cameras.Camera3D;
	import away3d.containers.Scene3D;
	import away3d.containers.View3D;
	import away3d.core.base.SubGeometry;
	import away3d.debug.AwayStats;
	import away3d.entities.Mesh;
	import away3d.entities.SegmentSet;
	import away3d.filters.BloomFilter3D;
	import away3d.filters.MotionBlurFilter3D;
	import away3d.materials.ColorMaterial;
	import away3d.primitives.LineSegment;
	import away3d.primitives.PlaneGeometry;
	import away3d.primitives.SphereGeometry;
	import away3d.primitives.WireframeGrid;
	import away3d.primitives.WireframeSphere;
	
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Vector3D;
	import flash.utils.getTimer;
	
	import frocessing.color.ColorHSV;
	
	[SWF(backgroundColor="0xC0C0C0", frameRate="60", width="800", height="600")]
	
	public class DrawLine2 extends Sprite
	{
		
		private var _view : View3D;
		private var _scene : Scene3D;
		private var _camera : Camera3D;
		
		private var _mesh:Mesh;
		
		private var _lines:SegmentSet;
		
		private var _hsv:ColorHSV;
		
		public function DrawLine2()
		{
			setup();
			lineDraw();
			addEventListener(Event.ENTER_FRAME, update);
		}
		
		private function setup():void
		{
			_view = addChild(new View3D()) as View3D;
			_view.antiAlias = 3;
			_view.backgroundColor = 0;
			
			_scene = _view.scene;
			_camera = _view.camera;
			_camera.x = 100;
			_camera.y = 500;
			_camera.z = -2000;
			
			_lines = new SegmentSet();
			_scene.addChild( _lines );
			
			var plane:WireframeGrid = new WireframeGrid(6, 3000 , 1, 0x696969);
			_scene.addChild(plane);
						
			var wsphere:WireframeSphere = new WireframeSphere( 600, 32, 24, 0xCCFFFF, .1 );
			_scene.addChild(wsphere);
			
			var sphere:SphereGeometry = new SphereGeometry(600, 32, 24);
			var mat:ColorMaterial = new ColorMaterial(0x00FF99);
			_mesh = new Mesh(sphere, mat);
			//_scene.addChild(_mesh);
			
			var motionBlur:MotionBlurFilter3D = new MotionBlurFilter3D(.9);
			var bloom:BloomFilter3D = new BloomFilter3D( 16, 16, .75, 4, 3);
			_view.filters3d = [motionBlur, bloom];
			
			_hsv = new ColorHSV(0, .9, .98);
			
			var awayStats:AwayStats = new AwayStats(_view);
			addChild(awayStats);
		}
		
		private function lineDraw():void
		{	
			var geo:SubGeometry = _mesh.geometry.subGeometries[0] as SubGeometry;
			var vlen : int = geo.vertexData.length / 3;
			for (var i : int = 0; i < vlen; i++ )
			{
				var v1:int = i * 3;
				var v2:int = v1 + 1;
				var v3:int = v1 + 2;
				
				var v3d:Vector3D = new Vector3D();
				v3d.x = geo.vertexData[v1];
				v3d.y = geo.vertexData[v2];
				v3d.z = geo.vertexData[v3];
				
				++_hsv.h;
				var col:int = uint(_hsv.toRGB());
				
				_lines.addSegment(
					new LineSegment(
						new Vector3D( Math.random() * 800 - 400, Math.random() * 800 - 400, Math.random() * 800 - 400 ),
						v3d,
						col,
						0,
						Math.random() * 1
					)
				)
				
			}
		}
		
		
		private function update(e:Event) : void
		{
			_lines.removeAllSegments();
			lineDraw();
			
			_camera.x = 2000 * Math.sin(getTimer() / 1000);
			_camera.z = 2000 * Math.cos(getTimer() / 5000);
			_camera.y = 1000 * Math.sin(getTimer() / 2000) + 500;
			_camera.lookAt(new Vector3D());
			_view.render();
		}
	}
}

これも100行ちょっとでできました。
でも、さすがにこれはちょっと重いなぁ…