Рабочий процесс, изготовление модельки дома на флеше для игры.

Вы наблюдаете процесс создания домика для игры. Для этого пришлось сделать небольшой редактор. На фотке видно снимок экрана рабочего процесса. Тут имеется готовый набор элементов домика, соединяя, которые можно получить модель в законченном виде. Выкладывать сам редактор пока рановато, да и смысла нет никакого, ведь 3Д Макс превосходит его как по функциональности, так и удобству пользования. А, для меня, мой редактор самый практичный и удобный, т.к. сохраняется модель, так как надо мне (минимум полигонов), а это могут быть и треугольники, и четырехгранники и др. разнообразные фигуры.
рисование домика самодельным редактором
Проект демки состоит из четырех классов документ класс
package
{
	import flash.display.*;
	import flash.geom.*;
	import flash.events.*;
	
	import lex.*;
	/**
	 * ...
	 * @author http://www.murmadillo.tut.su/
	 */
	public class Doc extends MovieClip
	{
		private var lex3D:Lex3D = new Lex3D;
		private var xml:XML, myData:MyData, pointObj:Object, facesObject:Object,
		facObj:Object, sh:Shape, projectVec:Vector.<Vector3D>, testSp:Sprite,
		fArr:Array = [], realVec:Vector.<Vector3D> = new Vector.<Vector3D>(),
		cardCount:int,focus:int = 1000, rotWheel:int;
		public function Doc() 
		{
			var i:int, j:int, vec:Vector3D, coor:Vector.<Number>, com:Vector.<int>;
			var xmlList:XMLList, zArr:Array = [], m3D:Matrix3D = new Matrix3D;
			var colorObj:Object = new Object, fData:FacData,  fac:Shape, color:uint;
			addChild(testSp = new Sprite);
			testSp.x = 20;
			myData = new MyData();
			xml = myData.xml;
			pointObj = new Object;
			facesObject = new Object;
			projectVec = new Vector.<Vector3D>();
			x = y = 250;
			y = 350;
			xmlList = xml.color;
			for (i = 0; i < xmlList.length(); i++) colorObj[xmlList[i].id] = xmlList[i].color;
			xmlList = xml.p;
			//trace(xml);
			m3D.appendRotation(-80, new Vector3D(0, 1, 0));
			m3D.appendRotation(15, new Vector3D(1, 0, 0));
			for (i = 0; i < xmlList.length(); i++) {
				pointObj[xmlList[i].id] = new Vector3D(Number(xmlList[i].x) , Number(xmlList[i].y), Number(xmlList[i].z));
				vec = new Vector3D(Number(xmlList[i].x) , Number(xmlList[i].y), Number(xmlList[i].z));
				realVec[i] = vec.clone();
				vec =  m3D.transformVector(vec);
				vec.w = (focus + vec.z) / focus;
				vec.project();
				projectVec[int(xmlList[i].id)] = vec;
			}
			xmlList = xml.fac;
			for (i = 0; i < xmlList.length(); i++) {
				facesObject[xmlList[i].id] = facObj = new Object;
				facObj.id = xmlList[i].id;
				facObj.com = String(xmlList[i].com).split(',');
				facObj.coor = String(xmlList[i].coor).split(',');
				//facObj.mid = String(xmlList[i].mid).split(',');
				facObj.color = color =uint(colorObj[xmlList[i].color]);
				
				coor = new Vector.<Number>();
				com = new Vector.<int>();
				for (j = 0; j < facObj.com.length; j++) com.push(facObj.com[j]);
				for (j = 0; j < facObj.coor.length; j++) {
					vec = projectVec[facObj.coor[j]];
					coor.push(vec.x, vec.y);
				}
				facObj.z = 0;
				
				fArr.push(fData = new FacData(facObj.coor, facObj.com, facObj.mid, color));
				
				fData.calcZ(projectVec);
			}
			fArr.sortOn("z", Array.NUMERIC | Array.DESCENDING);
			for (i = 0; i < fArr.length; i++) {
				testSp.addChild(sh = new Shape);
			}
			
		addEventListener(Event.ENTER_FRAME, enterFrameHandler);
		
		}

		private function enterFrameHandler(evt:Event):void {
			var i:int, m3D:Matrix3D = new Matrix3D, sh:Shape;
			//m3D.appendRotation(rotWheel += 10, new Vector3D(0, 0, 1));
			m3D.appendRotation(cardCount++, new Vector3D(0, 1, 0));
			testSp.z = 0;
			var len:int = realVec.length;
			for (i = 0; i < len; i++) {
				projectVec[i] =  m3D.transformVector(realVec[i]);
				projectVec[i].w = (focus + projectVec[i].z) / focus;
				projectVec[i].project();
			}
			len = fArr.length;
			for (i = 0; i < len; i++) fArr[i].calcZ(projectVec);
			fArr.sortOn("z", Array.NUMERIC | Array.DESCENDING);
			for (i = 0; i < len; i++) {
				sh = testSp.getChildAt(i) as Shape;
				sh.graphics.clear();
				fArr[i].draw(sh.graphics, projectVec, lex3D);
			}
			

		}
	}
	
}

Класс для трехмерных расчетов Lex3D
package  lex
{
	import flash.geom.*;
	import __AS3__.vec.*;
	
	import flash.display.*;
	import flash.events.*;
	import flash.text.*;
	
	/**
	 * ...
	 * @author http://www.murmadillo.tut.su/
	 */
	public class Lex3D 
	{
		private var matrix:Matrix, bd:BitmapData,rect:Rectangle;
		public function Lex3D() 
		{
			bd = new BitmapData(1, 1, true, 0x00000000);
			matrix = new Matrix;
			rect = new Rectangle(0, 0, 1, 1);
		}




		public function calcNormal(_v1:Vector3D, _v2:Vector3D, _v3:Vector3D):Vector3D {
			var v:Vector3D = new Vector3D(
			(_v2.y - _v1.y) * (_v3.z - _v1.z) - (_v3.y - _v1.y) * (_v2.z - _v1.z),
			(_v2.x - _v1.x) * (_v3.z - _v1.z) - (_v3.x - _v1.x) * (_v2.z - _v1.z),
			(_v2.x - _v1.x) * (_v3.y - _v1.y) - (_v3.x - _v1.x) * (_v2.y - _v1.y));
			return v;
		}

		public function calcZ(myNum:Vector.<uint> , vec3D:Vector.<Vector3D> ):Number {
			var i:int, len:int, z:Number = 0;
			len = myNum.length;
			for (i = 0; i < len; i++) {
				z += vec3D[myNum[i]].z;
				//trace(vec3D[myNum[i]].z);
			}
			z = z / len;
			return z;
		}

		public function calcLigth(_k:Number, maxColor:uint=0xffffff):uint {
			var rMax:uint = maxColor >> 16 & 0xFF;
			var gMax:uint = maxColor >> 8 & 0xFF;
			var bMax:uint = maxColor & 0xFF;
			
			var r:uint;
			var g:uint;
			var b:uint;
			r = max0xff(rMax * _k);
			b = max0xff(bMax * _k);
			g = max0xff(gMax * _k);
			
			var color:uint = ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF);
			return color;
		}

		private function max0xff(_c:uint):uint {
			if (_c > 0xff) _c = 0xff;
			return uint(_c);
		}

	}
	
}

Класс для работы с данными грани FacData.
package  
{
	import flash.display.Graphics;
	import flash.geom.*;
	
	import lex.*;
	/**
	 * ...
	 * @author http://www.murmadillo.tut.su/
	 */
	public class FacData 
	{
		private var coor:Vector.<Number>, com:Vector.<int>, mid:Vector.<int>,
		coorAdress:Vector.<uint>, j:int, adresslen:int, c:int, color:uint, norm:Vector3D,
		ang:Number, baseColor:uint;
		public var z:Number;
		
		public function FacData(_coor:Array,_com:Array,_mid:Array,_color:uint) 
		{
			coor = new Vector.<Number>();
			com = new Vector.<int>();
			mid = new Vector.<int>();
			baseColor = _color;
			coorAdress = new Vector.<uint>();
			norm = new Vector3D;
			for (j = 0; j < _com.length; j++) com.push(_com[j]);
			//for (j = 0; j < 4; j++) mid.push(_mid[j]);
			for (j = 0; j < _coor.length; j++) {
				coorAdress.push(_coor[j]);
			}
			adresslen = coorAdress.length;
		}

		public function calcZ( _vecs:Vector.<Vector3D>):void {
			//var cam:Vector3D = new Vector3D(0, 0, -2000);
			z = 0;
			for (j = 0; j < coorAdress.length; j++) {
				z += _vecs[coorAdress[j]].z;
			}
			z = z / coorAdress.length;
		}

		public function draw(graphics:Graphics, _vecs:Vector.<Vector3D>, lex3D:Lex3D ):void {
			c = 0;
			for (j = 0; j < adresslen; j++) {
				coor[c] = _vecs[coorAdress[j]].x;
				c++;
				coor[c] = _vecs[coorAdress[j]].y;
				c++;
			}
			
			norm = lex3D.calcNormal(_vecs[coorAdress[0]], _vecs[coorAdress[1]], _vecs[coorAdress[2]]);
			norm.normalize();
			ang = Math.abs(norm.dotProduct(new Vector3D(0, 0, -1)));
			
			color = lex3D.calcLigth(ang +0.8, baseColor);
			
			graphics.beginFill(color, 1);
			
			graphics.drawPath(com, coor);
			graphics.endFill();
		}

	}
	
}

И класс собственно который содержит xml с объектом. Троеточия похожие повторы. MyData
package  
{
	
	/**
	 * ...
	 * @author http://www.murmadillo.tut.su/
	 */
	public class MyData 
	{
		public var xml:XML;
		public function MyData() 
		{
			xml = <doc>
  <color>
    <id>0</id>
    <color>6710886</color>
  </color>
  <color>
    <id>1</id>
    <color>39168</color>
  </color>
  <color>
    <id>2</id>
    <color>0x008080</color>
  </color>
  <color>
    <id>3</id>
    <color>10040115</color>
  </color>
  <color>
    <id>4</id>
    <color>3355545</color>
  </color>
  <p>
    <id>0</id>
    <x>-139.99998474121094</x>
    <y>0</y>
    <z>-120.00001525878906</z>
  </p>
  <p>
    <id>1</id>
    <x>140</x>
    <y>0</y>
    <z>-120.00001525878906</z>
  </p>
  <p>
    <id>2</id>
    <x>-139.99998474121094</x>
    <y>-150</y>
    <z>-120.00001525878906</z>
  </p>
...
...
...
  <fac>
    <id>0</id>
    <color>0</color>
    <com>1,2,2,2,1,2,2,2</com>
    <coor>14,2,0,12,26,27,25,24</coor>
    <mid>,,,</mid>
  </fac>
  <fac>
    <id>1</id>
    <color>0</color>
    <com>1,2,2,2,1,2,2,2</com>
    <coor>2,3,1,0,5,6,8,7</coor>
    <mid>,,,</mid>
  </fac>
...
...
...
</doc>
		}
		
	}
	
}


Можно таким же способом нарисовать и автомобильчик, и не смотрите, что у него стекла красного цвета, просто владелец программер кодил в неположенное для работы время и у него теперь красные зенки.


Архив демки с крутящимся домиком.