Наложение текстуры на 3d модель во флеш 10.


Вообще не шарю в 3Д редакторах, но прочитав туториал, "Текстурирование с UNWRAP UVW" сделал текстуированный кубик.
текстуированный кубик в 2ds
На рисунке изображен мой непосильный труд в виде текстуированного кубика, нарисованного в программе 3ДМАХ.

Текстуру рисовал в Corel DRO, хотел в Фотошопе намалевать, но нервов нехватило.
изображение текстуры для кубика
вот такая текстурка, минуты 3-4 с Corel DRO версия 13.

Затем сделал кубический экспорт в as из 3dmax. Получил as класс и немного его переделал под свои нужды.
package 
{
//import away3d.core.mesh.*;

public class CubeObject
{
public var v3ds:Vector.<Number>;
public var uvs:Vector.<Number>;
public var facs:Vector.<int>;
public var facUvs:Vector.<int>;

private function v(x:Number,y:Number,z:Number):void
{
v3ds.push(x,y,z);
}

private function uv(u:Number,v:Number):void
{
uvs.push(u,v);
}
private function f(vn0:int, vn1:int, vn2:int, uvn0:int, uvn1:int, uvn2:int):void
{
	facs.push(vn0, vn1, vn2);
	facUvs.push(uvn0, uvn1, uvn2);
}

public function CubeObject()
{
v3ds = new Vector.<Number>()
uvs = new Vector.<Number>();
facs = new Vector.<int>();
facUvs = new Vector.<int>();
build();
}
private function build():void
{
v(-25.0,0.0,-25.0);
v(25.0,0.0,-25.0);
v(-25.0,0.0,25.0);
v(25.0,0.0,25.0);
v(-25.0,50.0,-25.0);
v(25.0,50.0,-25.0);
v(-25.0,50.0,25.0);
v(25.0,50.0,25.0);
uv(0.322791,0.0);
uv(0.0,0.0);
uv(0.322791,0.322791);
uv(0.0,0.322791);
uv(0.0,0.338605);
uv(0.322791,0.338605);
uv(0.0,0.661395);
uv(0.322791,0.661395);
uv(0.0,1.0);
uv(0.322791,1.0);
uv(0.0,0.677209);
uv(0.322791,0.677209);
uv(0.338605,0.677209);
uv(0.661395,0.677209);
uv(0.338605,1.0);
uv(0.661395,1.0);
uv(0.661395,0.0);
uv(0.338605,0.0);
uv(0.661395,0.322791);
uv(0.338605,0.322791);
uv(0.338605,0.338605);
uv(0.661395,0.338605);
uv(0.338605,0.661395);
uv(0.661395,0.661395);
f(0,2,3, 8,10,11);
f(3,1,0, 11,9,8);
f(4,5,7, 20,21,23);
f(7,6,4, 23,22,20);
f(0,1,5, 4,5,7);
f(5,4,0, 7,6,4);
f(1,3,7, 12,13,15);
f(7,5,1, 15,14,12);
f(3,2,6, 17,16,18);
f(6,7,3, 18,19,17);
f(2,0,4, 1,0,2);
f(4,6,2, 2,3,1);
}
}
}

Теперь собственно документ класс. Не я думаю, че делать-то ну там Papervision учить или away3d (стоящая фича). Потом хелп просматриваю, а там
public function drawTriangles(vertices:Vector.<Number>, indices:Vector.<int> = null, uvtData:Vector.<Number> = null, culling:String = "none"):void

Язык версии :  ActionScript 3.0 
Версии среды выполнения:  10, 1.5 



Визуализирует набор треугольников, чтобы придать растровому изображению трехмерный вид. Метод drawTriangles() накладывает текущую или растровую заливку на грани треугольника, используя набор координат (u,v). 

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

При использовании растровой заливки параметр uvtData улучшает наложение текстуры. 


Параметры 

 vertices:Vector.<Number> — Вектор чисел, где каждая пара чисел рассматривается как точка в системе координат (пара координат x, y). Параметр vertices обязателен.  
  
 indices:Vector.<int> (default = null) — Вектор целых чисел или индексов, где каждые три индекса определяют треугольник. Если параметру indexes задано значение null, то треугольник определяют каждые три вершины (шесть пар х,у в векторе vertices). В противном случае каждый индекс относится к вершине, представленной парой чисел в векторе vertices. Например, indexes[1] определяет точку с координатами (vertices[2], vertices[3]). Параметр indexes является дополнительным, но индексы, как правило, сокращают объем отправляемых и вычисляемых данных.  
  
 uvtData:Vector.<Number> (default = null) — Вектор нормализованных координат, используемый для наложения текстуры. Каждая координата определяет точку на растровом изображении, используемом для заливки. Для каждой вершины должна быть указана одна координата UV или одна координата UVT. В координатах UV точка (0,0) — это верхняя левая точка, а точка (1,1) — нижняя правая точка растрового изображения.  

Мозг неадекватно среагировал (обычно не реагирует), а не те ли это UV, которые uv(0.661395,0.322791); Да вроде они, родные. Блин... Опять неправильно статейку, назвал, ну лан, пусть уж будет uw.html, интернет все стерпит.
package  
{
	import flash.display.*;
	import flash.events.*;
	import flash.geom.*;
	
	
	
	import lex.asComponent.LSlider;
	import lex.asComponent.style.LSliderStyle;
	import lex.LMath;
	
	/**
	 * ...
	 * @author Alex Lexcuk http://www.murmadillo.tut.su
	 */
	public class DocCube extends Sprite
	{
		[Embed(source = 'texture.jpg')]
		private var Pic:Class,
			baseBmd:BitmapData,
			baseBm:Bitmap;

		
		private var my3Obj:CubeObject = new CubeObject();


		private var slider:LSlider = new LSlider();
		private var cubeSh:Shape;
		private var world:Sprite;
		private var fcom:Vector.<int> = Vector.<int>([1,2,2,2]);
		private var fdat:Vector.<Number> = new Vector.<Number>();
		private var m3d:Matrix3D = new Matrix3D();
		private var dats:Vector.<Number> = new Vector.<Number> ();
		
		public function DocCube() 
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			
			addChild(cubeSh = new Shape());
			
			cubeSh.x = 400;
			cubeSh.y = 300;
			
			addChild(slider);
			slider.x = 100;
			slider.y = 100;
			slider.direction = LSliderStyle.DIRECTION_VERTICAL;
			slider.setSize(100, 10);
			slider.maximum = 180;
			slider.minimum = -180;
			slider.tickInterval = 30;
			//slider.liveDragging = true;
			
			slider.addEventListener(Event.CHANGE, announceChange);
			
			baseBmd = new Pic().bitmapData;
			baseBm = new Bitmap(baseBmd);
			//addChild(baseBm);
			drawCube();
		}


		private function drawCube():void {
			cubeSh.graphics.clear();
			var i:int;
			var j:int;
			var len:int = my3Obj.facs.length;
			var facs:Vector.<int> = my3Obj.facs;
			var x0:Number;
			var x:Number;
			var y0:Number;
			var y:Number;
			var w:Number;
			var focus:Number = 1000;
			var n:Vector3D;
			var poly:Vector.<Vector3D> = new Vector.<Vector3D>();
			var z:Number;
			var x1:Number;
			var x2:Number;
			var y1:Number;
			var y2:Number;
			var z0:Number, z1:Number, z2:Number;
			var c:int = 0;
			var uv:Vector.<Number> = new Vector.<Number>();
			var uvRes:Vector.<Number> = new Vector.<Number>();
			var verticesRes:Vector.<Number> = new Vector.<Number>();
			
			m3d.transformVectors(my3Obj.v3ds, dats);
			
			
			n = new Vector3D();
			
			w = 1 / ((focus + z) / focus);


			for (i = 0; i < len; i += 3) {
				j = 0;
				c = 0;
				//i =i;
				z = dats[facs[i] * 3 + 2 ];//z
				
				w = 1 / ((focus + z) / focus);
				
				
				x0 = fdat[j++] = dats[facs[i] * 3 ]*w;//x
				y0 = fdat[j++] = dats[facs[i] * 3 + 1 ]*w;//y
				z0 = dats[facs[i] * 3 + 2 ] * w;//z
				
				
				uv[c++]= my3Obj.uvs[my3Obj.facUvs[i] * 2 ] ;//x
				uv[c++] =( my3Obj.uvs[my3Obj.facUvs[i] * 2 +1] );//y
				
				
				z = dats[facs[i+1] * 3 +2];//z
				w = 1 / ((focus + z) / focus);
				
				x1 = fdat[j++] = dats[facs[i+1] * 3 ] * w;//x
				y1 = fdat[j++] = dats[facs[i+1] * 3 + 1 ] * w;//y
				z1 = dats[facs[i+1] * 3 + 2 ] * w;//z
				
				uv[c++] = (my3Obj.uvs[my3Obj.facUvs[i+1] * 2 ] );//x
				uv[c++] =( my3Obj.uvs[my3Obj.facUvs[i+1] * 2 +1] );//y
				
				
				z = dats[facs[i+2] * 3 + 2 ];//z
				w = 1 / ((focus + z) / focus);
				
				x2 = fdat[j++] = dats[facs[i+2] * 3 ] * w;//x
				y2 = fdat[j++] = dats[facs[i+2] * 3 + 1 ] * w;//y
				z2 =  dats[facs[i+2] * 3 + 2 ] * w;//z
				
				uv[c++] =( my3Obj.uvs[my3Obj.facUvs[i+2] * 2 ] );//x
				uv[c++] =( my3Obj.uvs[my3Obj.facUvs[i+2] * 2 +1] );//y
				
				
				
				poly[0] = new Vector3D( x0, y0, z0);
				poly[1] = new Vector3D( x1, y1, z1);
				poly[2] = new Vector3D( x2, y2, z2);
				
				
				
				LMath.calcNormal(poly[0], poly[1], poly[2], n);
				
				if (n.dotProduct(Vector3D.Z_AXIS)>0){//тут определяем видимость грани выпуклого многоугольника
				verticesRes.push(fdat[0], fdat[1], fdat[2], fdat[3], fdat[4], fdat[5]);
				uvRes.push(uv[0], uv[1], uv[2], uv[3], uv[4], uv[5]);
				
				//trace('рисую');
				}else ;//trace('не рисую');
				

			}
			cubeSh.graphics.beginBitmapFill(baseBmd);
			cubeSh.graphics.drawTriangles(verticesRes, null, uvRes);
		}


		private function announceChange(e:Event):void {
			m3d.identity();
			m3d.appendScale(3, 3, 3);
			m3d.appendRotation(30, Vector3D.Y_AXIS);
			m3d.appendRotation(e.target.value, Vector3D.X_AXIS);
			drawCube();
		}

	}

}





Потребуется функция LMath.calcNormal да вот она уже как-была в изображении октаэдр без текстуры
Тут я ничего не оптимизировал, хотя, конечно... идеи есть, зато быстро сделал. Ну идея номер 0, как повторение прочитанного из hepl системы: Параметр indexes является дополнительным, но индексы, как правило, сокращают объем отправляемых и вычисляемых данных.

Крутим слайдер

Наверно, кто-то захочет позырить на архив вывода текстуированной 3Д модельки во флеш
Интересно, а автомобильчик это выпуклый многогранник (тк. вывод таким образом предусматривает выпуклые многогранники) надо затестить

тачка вместо кубика
Нифига это не выпуклый многогранник, тк. есть косяки. И с текстурой проблема вышла, она какая-то отраженная и повернутая.
текстура для автомобиля

Все-таки, грани нужно сортировать... Кто не догадался, текстуру нарисовал сам в фотошопе.