PageRenderTime 739ms CodeModel.GetById 192ms app.highlight 415ms RepoModel.GetById 118ms app.codeStats 0ms

/src/away3d/extrusions/PathExtrude.as

http://github.com/away3d/away3d-core-fp11
ActionScript | 1313 lines | 978 code | 229 blank | 106 comment | 256 complexity | 87f41ec93c880755d1bf25ef196615a4 MD5 | raw file
   1package away3d.extrusions
   2{
   3	import away3d.bounds.BoundingVolumeBase;
   4	import away3d.core.base.Geometry;
   5	import away3d.core.base.SubGeometry;
   6	import away3d.core.base.SubMesh;
   7	import away3d.core.base.data.UV;
   8	import away3d.core.base.data.Vertex;
   9	import away3d.core.math.Vector3DUtils;
  10	import away3d.entities.Mesh;
  11	import away3d.materials.MaterialBase;
  12	import away3d.paths.IPath;
  13	import away3d.paths.IPathSegment;
  14	import away3d.tools.helpers.MeshHelper;
  15	
  16	import flash.geom.Matrix3D;
  17	import flash.geom.Vector3D;
  18	
  19	[Deprecated]
  20	public class PathExtrude extends Mesh
  21	{
  22		private var _varr:Vector.<Vertex>;
  23		private var _doubles:Vector.<Vertex> = new Vector.<Vertex>();
  24		private var _upAxis:Vector3D = new Vector3D(0, 1, 0);
  25		private var _trans:Matrix3D = new Matrix3D();
  26		
  27		private const LIMIT:uint = 196605;
  28		private const MAXRAD:Number = 1.2;
  29		private var _path:IPath;
  30		private var _profile:Vector.<Vector3D>;
  31		private var _centerMesh:Boolean;
  32		private var _scales:Vector.<Vector3D>;
  33		private var _rotations:Vector.<Vector3D>;
  34		private var _materials:Vector.<MaterialBase>;
  35		private var _activeMaterial:MaterialBase;
  36		private var _subdivision:uint;
  37		private var _coverAll:Boolean;
  38		private var _coverSegment:Boolean;
  39		private var _flip:Boolean;
  40		private var _mapFit:Boolean;
  41		private var _closePath:Boolean;
  42		private var _alignToPath:Boolean;
  43		private var _smoothScale:Boolean;
  44		private var _smoothSurface:Boolean;
  45		private var _isClosedProfile:Boolean;
  46		private var _maxIndProfile:uint;
  47		private var _matIndex:uint = 0;
  48		private var _segv:Number;
  49		private var _geomDirty:Boolean = true;
  50		private var _subGeometry:SubGeometry;
  51		private var _MaterialsSubGeometries:Vector.<SubGeometryList> = new Vector.<SubGeometryList>();
  52		private var _uva:UV;
  53		private var _uvb:UV;
  54		private var _uvc:UV;
  55		private var _uvd:UV;
  56		private var _uvs:Vector.<Number>;
  57		private var _vertices:Vector.<Number>;
  58		private var _indices:Vector.<uint>;
  59		private var _normals:Vector.<Number>;
  60		private var _normalTmp:Vector3D;
  61		private var _normal0:Vector3D;
  62		private var _normal1:Vector3D;
  63		private var _normal2:Vector3D;
  64		private var _keepExtremes:Boolean;
  65		private var _distribute:Boolean;
  66		private var _distributeU:Boolean;
  67		private var _distributedU:Vector.<Number>;
  68		private var _startPoints:Vector.<Vector3D>;
  69		private var _endPoints:Vector.<Vector3D>;
  70		
  71		/**
  72		 * Creates a new <code>PathExtrude</code>
  73		 *
  74		 * @param    material                [optional]     MaterialBase. The PathExtrude (Mesh) material. Optional in constructor, material must be set before PathExtrude object is rendered. Required for the class to work.
  75		 * @param    path                    [optional]     Path. Defines the <code>Path</code> object representing path to extrude along. Required for the class to work.
  76		 * @param    profile                [optional]     Vector.&lt;Vector3D&gt;. Defines an Vector.&lt;Vector3D&gt; of Vector3D objects representing the profile information to be projected along the Path object. Required for the class to work.
  77		 * @param    subdivision            [optional]    uint. Howmany steps between each PathSegment. If the path holds curves, the higher this value, the higher the curve fidelity. Default and minimum is 2;
  78		 * @param    coverall                [optional]     Boolean. Defines the uv mapping, when true a unique material is stretched along the entire path/shape. Default is true.
  79		 * @param    coverSegment    [optional]     Boolean. Defines the uv mapping, when true and coverall is false a unique material is stretched along one PathSegment. Default is false.
  80		 * @param    alignToPath        [optional]    Boolean. If the profile must follow the path or keep its original orientation.
  81		 * @param    centerMesh        [optional]     Boolean. If the geometry needs to be recentered in its own object space. If the position after generation is set to 0,0,0, the object would be centered in worldspace. Default is false.
  82		 * @param    mapFit                [optional]    Boolean. The UV mapping is percentually spreaded over the width of the path, making texture looking nicer and edits for applications such as a race track, road, more easy. Affects the uv's u values and set distributeU to false. Default is false.
  83		 * @param    flip                    [optional]    Boolean. If the faces must be reversed depending on Vector3D's orientation. Default is false.
  84		 * @param    closePath            [optional]    Boolean. If the last PathSegment entered must be welded back to first one. Executed in a straight manner, its recommanded to pass the first entry to the Path again, as last entry if curves are involved.
  85		 * @param    materials            [optional]    Vector.&lt;MaterialBase&gt;. An optional Vector.&lt;MaterialBase&gt; of different materials that can be alternated along the path if coverAll is false.
  86		 * @param    scales                [optional]    An optional Vector.&lt;Vector3D&gt; of <code>Vector3D</code> objects that defines a series of scales to be set on each PathSegment.
  87		 * @param    smoothScale        [optional]    Boolean. Defines if the scale must be interpolated between values or keep their full aspect on each PathSegment.
  88		 * @param    rotations            [optional]    An optional Vector.&lt;Vector3D&gt; of <code>Vector3D</code> objects that defines a series of rotations to be set on each PathSegment.
  89		 * @param    smoothSurface    [optional]    An optional Boolean. Defines if the surface of the mesh must be smoothed or not. Default is true.
  90		 * @param    distribute            [optional]    Boolean. If the mesh subdivision is evenly spreaded over the entire mesh. Depending on path definition, segments are possibly not having the same amount of subdivision.
  91		 * @param    distributeU            [optional]    Boolean. If the mesh uv' u value is procentually spreaded over the entire mesh surface. Prevents the source map to be stretched. Default is true.
  92		 * @param    keepExtremes        [optional]    Boolean. If the the first and last profile coordinates must be kept accessible, in order to feed classes such as DelaunayMesh. Default is false;
  93		 */
  94		function PathExtrude(material:MaterialBase = null, path:IPath = null, profile:Vector.<Vector3D> = null, subdivision:uint = 2, coverAll:Boolean = true, coverSegment:Boolean = false, alignToPath:Boolean = true, centerMesh:Boolean = false, mapFit:Boolean = false, flip:Boolean = false, closePath:Boolean = false, materials:Vector.<MaterialBase> = null, scales:Vector.<Vector3D> = null, smoothScale:Boolean = true, rotations:Vector.<Vector3D> = null, smoothSurface:Boolean = true, distribute:Boolean = false, distributeU:Boolean = true, keepExtremes:Boolean = false)
  95		{
  96			distribute = distribute;
  97			
  98			var geom:Geometry = new Geometry();
  99			_subGeometry = new SubGeometry();
 100			super(geom, material);
 101			
 102			_activeMaterial = this.material;
 103			_path = path;
 104			this.profile = profile;
 105			this.subdivision = subdivision;
 106			_coverSegment = coverSegment;
 107			_coverAll = (_coverSegment)? false : coverAll;
 108			_alignToPath = alignToPath;
 109			_centerMesh = centerMesh;
 110			_mapFit = mapFit;
 111			_flip = flip;
 112			_closePath = closePath;
 113			_materials = (materials)? materials : new Vector.<MaterialBase>();
 114			_scales = scales;
 115			_smoothScale = smoothScale;
 116			_rotations = rotations;
 117			_smoothSurface = smoothSurface;
 118			_distributeU = distributeU;
 119			_keepExtremes = keepExtremes;
 120		}
 121		
 122		public function get upAxis():Vector3D
 123		{
 124			return _upAxis;
 125		}
 126		
 127		public function set upAxis(value:Vector3D):void
 128		{
 129			_upAxis = value;
 130		}
 131		
 132		/**
 133		 * @inheritDoc
 134		 */
 135		override public function get bounds():BoundingVolumeBase
 136		{
 137			if (_geomDirty)
 138				buildExtrude();
 139			
 140			return super.bounds;
 141		}
 142		
 143		/**
 144		 * @inheritDoc
 145		 */
 146		override public function get geometry():Geometry
 147		{
 148			if (_geomDirty)
 149				buildExtrude();
 150			
 151			return super.geometry;
 152		}
 153		
 154		/**
 155		 * @inheritDoc
 156		 */
 157		override public function get subMeshes():Vector.<SubMesh>
 158		{
 159			if (_geomDirty)
 160				buildExtrude();
 161			
 162			return super.subMeshes;
 163		}
 164		
 165		/**
 166		 * Defines whether the mesh is recentered of not after generation
 167		 */
 168		public function get centerMesh():Boolean
 169		{
 170			return _centerMesh;
 171		}
 172		
 173		public function set centerMesh(val:Boolean):void
 174		{
 175			if (_centerMesh == val)
 176				return;
 177			
 178			_centerMesh = val;
 179			
 180			if (_centerMesh && this.geometry.subGeometries.length > 0)
 181				MeshHelper.recenter(this);
 182			else
 183				invalidateGeometry();
 184		}
 185		
 186		/**
 187		 * Defines the uv's u values are spreaded procentually over the entire surface to prevent the maps to be stretched.
 188		 */
 189		public function get distributeU():Boolean
 190		{
 191			return _distributeU;
 192		}
 193		
 194		public function set distributeU(val:Boolean):void
 195		{
 196			if (_distributeU == val)
 197				return;
 198			
 199			_distributeU = val;
 200			
 201			if (val && _mapFit)
 202				_mapFit = false;
 203			if (!val && _distributedU)
 204				_distributedU = null;
 205			
 206			invalidateGeometry();
 207		}
 208		
 209		/**
 210		 * Invalidates the geometry, causing it to be rebuillded when requested.
 211		 */
 212		private function invalidateGeometry():void
 213		{
 214			_geomDirty = true;
 215			invalidateBounds();
 216		}
 217		
 218		/**
 219		 * Defines the <code>Path</code> object representing path to extrude along. Required.
 220		 */
 221		public function get path():IPath
 222		{
 223			return _path;
 224		}
 225		
 226		public function set path(val:IPath):void
 227		{
 228			_path = val;
 229			_geomDirty = true;
 230		}
 231		
 232		/**
 233		 * Defines a Vector.&lt;Vector3D&gt; of Vector3D objects representing the profile information to be projected along the Path object. Required.
 234		 */
 235		public function get profile():Vector.<Vector3D>
 236		{
 237			return _profile;
 238		}
 239		
 240		public function set profile(val:Vector.<Vector3D>):void
 241		{
 242			_profile = val;
 243			
 244			if (_profile != null)
 245				_isClosedProfile = (_profile[0].x == _profile[_profile.length - 1].x && _profile[0].y == _profile[_profile.length - 1].y && _profile[0].z == _profile[_profile.length - 1].z);
 246			
 247			_geomDirty = true;
 248		}
 249		
 250		/**
 251		 * An optional Vector.&lt;Vector3D&gt; of <code>Vector3D</code> objects that defines a series of scales to be set on each PathSegment.
 252		 */
 253		public function get scales():Vector.<Vector3D>
 254		{
 255			return _scales;
 256		}
 257		
 258		public function set scales(val:Vector.<Vector3D>):void
 259		{
 260			_scales = val;
 261			_geomDirty = true;
 262		}
 263		
 264		/**
 265		 * An optional Vector.&lt;Vector3D&gt; of <code>Vector3D</code> objects that defines a series of rotations to be set on each PathSegment.
 266		 */
 267		public function get rotations():Vector.<Vector3D>
 268		{
 269			return _rotations;
 270		}
 271		
 272		public function set rotations(val:Vector.<Vector3D>):void
 273		{
 274			_rotations = val;
 275			_geomDirty = true;
 276		}
 277		
 278		/**
 279		 * An optional Vector.&lt;MaterialBase&gt;. It defines a series of materials to be set on each PathSegment if coverAll is set to false.
 280		 */
 281		public function get materials():Vector.<MaterialBase>
 282		{
 283			return _materials;
 284		}
 285		
 286		public function set materials(val:Vector.<MaterialBase>):void
 287		{
 288			if (val == null)
 289				return;
 290			_materials = val;
 291			_geomDirty = true;
 292		}
 293		
 294		/**
 295		 * Defines the subdivisions created in the mesh for each PathSegment. Defaults to 2, minimum 2.
 296		 */
 297		public function get subdivision():int
 298		{
 299			return _subdivision;
 300		}
 301		
 302		public function set subdivision(val:int):void
 303		{
 304			val = (val < 2)? 2 : val;
 305			
 306			if (_subdivision == val)
 307				return;
 308			
 309			_subdivision = val;
 310			_geomDirty = true;
 311		}
 312		
 313		/**
 314		 * Defines if the texture(s) should be stretched to cover the entire mesh or per step between segments. Defaults to true.
 315		 */
 316		public function get coverAll():Boolean
 317		{
 318			return _coverAll;
 319		}
 320		
 321		public function set coverAll(val:Boolean):void
 322		{
 323			if (_coverAll == val)
 324				return;
 325			
 326			_coverAll = val;
 327			_geomDirty = true;
 328		}
 329		
 330		/**
 331		 * Defines if the mesh subdivision is spread evenly over the entire geometry. Possibly resulting in uneven subdivision per segments.
 332		 * Uv mapping is less distorted on complex shapes once applied. Depending on Path length, extra construct time might be significant.
 333		 * Defaults to false.
 334		 */
 335		public function get distribute():Boolean
 336		{
 337			return _distribute;
 338		}
 339		
 340		public function set distribute(val:Boolean):void
 341		{
 342			if (_distribute == val)
 343				return;
 344			
 345			_distribute = val;
 346			_geomDirty = true;
 347		}
 348		
 349		/**
 350		 * Defines if the surface of the mesh must be smoothed or not.
 351		 */
 352		public function get smoothSurface():Boolean
 353		{
 354			return _smoothSurface;
 355		}
 356		
 357		public function set smoothSurface(val:Boolean):void
 358		{
 359			if (_smoothSurface == val)
 360				return;
 361			
 362			_smoothSurface = val;
 363			_geomDirty = true;
 364		}
 365		
 366		/**
 367		 * Defines if the texture(s) should applied per segment. Default false.
 368		 */
 369		public function set coverSegment(b:Boolean):void
 370		{
 371			_coverSegment = b;
 372		}
 373		
 374		public function get coverSegment():Boolean
 375		{
 376			return _coverSegment;
 377		}
 378		
 379		/**
 380		 * Defines if the texture(s) should be projected on the geometry evenly spreaded over the source bitmapdata or using distance/percent. Default is false.
 381		 * The mapping considers first and last profile points are the most distant from each other. Most left and most right on the map.
 382		 * Note that it is NOT suitable for most cases. It is helpfull for roads definition, usually seen from above with simple profile. It prevents then distorts and eases map designs.
 383		 */
 384		public function get mapFit():Boolean
 385		{
 386			return _mapFit;
 387		}
 388		
 389		public function set mapFit(val:Boolean):void
 390		{
 391			if (_mapFit == val)
 392				return;
 393			
 394			if (val && _distributeU)
 395				_distributeU = false;
 396			
 397			_mapFit = val;
 398			_geomDirty = true;
 399		}
 400		
 401		/**
 402		 * Defines if the generated faces should be inversed. Default false.
 403		 */
 404		public function get flip():Boolean
 405		{
 406			return _flip;
 407		}
 408		
 409		public function set flip(val:Boolean):void
 410		{
 411			if (_flip == val)
 412				return;
 413			
 414			_flip = val;
 415			_geomDirty = true;
 416		}
 417		
 418		/**
 419		 * Defines if the last PathSegment should join the first one and close the loop. Defaults to false.
 420		 */
 421		public function get closePath():Boolean
 422		{
 423			return _closePath;
 424		}
 425		
 426		public function set closePath(val:Boolean):void
 427		{
 428			if (_closePath == val)
 429				return;
 430			
 431			_closePath = val;
 432			_geomDirty = true;
 433		}
 434		
 435		/**
 436		 * Defines if the array of profile points should be orientated on path or not. Default true. Note that Path object's worldaxis property might need to be changed. default = 0,1,0.
 437		 *
 438		 * @see #profile
 439		 */
 440		public function get aligntoPath():Boolean
 441		{
 442			return _alignToPath;
 443		}
 444		
 445		public function set alignToPath(val:Boolean):void
 446		{
 447			if (_alignToPath == val)
 448				return;
 449			
 450			_alignToPath = val;
 451			_geomDirty = true;
 452		}
 453		
 454		/**
 455		 * Defines if a scaling of a PathSegment defined from the scales array of <code>Vector3D</code> objects should affect the whole PathSegment evenly or be smoothly interpolated from previous PathSegment scale. Defaults to true.
 456		 */
 457		public function get smoothScale():Boolean
 458		{
 459			return _smoothScale;
 460		}
 461		
 462		public function set smoothScale(val:Boolean):void
 463		{
 464			if (_smoothScale == val)
 465				return;
 466			
 467			_smoothScale = val;
 468			_geomDirty = true;
 469		}
 470		
 471		/**
 472		 * Defines if the first and last transformed vector3d's of the profile are kept.
 473		 * For instance to be able to pass these coordinates to DelaunayMesh class, to close the extrude, if it was a tube.
 474		 * @see getStartProfile
 475		 * @see getEndProfile
 476		 */
 477		public function get keepExtremes():Boolean
 478		{
 479			return _keepExtremes;
 480		}
 481		
 482		public function set keepExtremes(b:Boolean):void
 483		{
 484			_keepExtremes = b;
 485		}
 486		
 487		/**
 488		 * returns a vector of vector3d's representing the transformed profile coordinates at the start of the extrude shape
 489		 * null if "keepExtremes" is false or if the extrusion has not been builded yet.
 490		 */
 491		public function get startProfile():Vector.<Vector3D>
 492		{
 493			if (!_path || !_startPoints)
 494				return null;
 495			
 496			return _startPoints;
 497		}
 498		
 499		/**
 500		 * returns a vector of vector3d's representing the transformed profile coordinates at the end of the extrude shape
 501		 * null if "keepExtremes" is false or if the extrusion has not been builded yet.
 502		 */
 503		public function get endProfile():Vector.<Vector3D>
 504		{
 505			if (!_path || !_endPoints)
 506				return null;
 507			
 508			return _endPoints;
 509		}
 510		
 511		private function orientateAt(target:Vector3D, position:Vector3D):void
 512		{
 513			var xAxis:Vector3D;
 514			var yAxis:Vector3D;
 515			var zAxis:Vector3D = target.subtract(position);
 516			
 517			zAxis.normalize();
 518			
 519			if (zAxis.length > 0.1) {
 520				xAxis = _upAxis.crossProduct(zAxis);
 521				xAxis.normalize();
 522				
 523				yAxis = xAxis.crossProduct(zAxis);
 524				yAxis.normalize();
 525				
 526				var rawData:Vector.<Number> = _trans.rawData;
 527				
 528				rawData[0] = xAxis.x;
 529				rawData[1] = xAxis.y;
 530				rawData[2] = xAxis.z;
 531				
 532				rawData[4] = -yAxis.x;
 533				rawData[5] = -yAxis.y;
 534				rawData[6] = -yAxis.z;
 535				
 536				rawData[8] = zAxis.x;
 537				rawData[9] = zAxis.y;
 538				rawData[10] = zAxis.z;
 539				
 540				_trans.rawData = rawData;
 541			}
 542		}
 543		
 544		private function generate(points:Vector.<Vector.<Vector3D>>, offsetV:int = 0, closedata:Boolean = false):void
 545		{
 546			var uvlength:int = (points.length - 1) + offsetV;
 547			var offset:uint;
 548			
 549			for (var i:uint = 0; i < points.length - 1; ++i) {
 550				_varr = new Vector.<Vertex>();
 551				offset = (closedata)? i + uvlength : i;
 552				
 553				extrudePoints(points[i], points[i + 1], (1/uvlength)*offset, uvlength, offset/(_subdivision - 1));
 554				
 555				if (i == 0 && _isClosedProfile)
 556					_doubles = _varr.concat();
 557			}
 558			_varr = _doubles = null;
 559		}
 560		
 561		private function extrudePoints(points1:Vector.<Vector3D>, points2:Vector.<Vector3D>, vscale:Number, indexv:int, indexp:Number):void
 562		{
 563			var i:int;
 564			var j:int;
 565			
 566			var stepx:Number;
 567			var stepy:Number;
 568			var stepz:Number;
 569			
 570			var va:Vertex;
 571			var vb:Vertex;
 572			var vc:Vertex;
 573			var vd:Vertex;
 574			
 575			var u1:Number;
 576			var u2:Number;
 577			var index:uint = 0;
 578			
 579			var v1:Number = 0;
 580			var v2:Number = 0;
 581			
 582			var countloop:int = points1.length;
 583			
 584			var mat:MaterialBase;
 585			
 586			if (_mapFit) {
 587				var dist:Number = 0;
 588				var tdist:Number;
 589				var bleft:Vector3D;
 590				for (i = 0; i < countloop; ++i) {
 591					for (j = 0; j < countloop; ++j) {
 592						if (i != j) {
 593							tdist = Vector3D.distance(points1[i], points1[j]);
 594							if (tdist > dist) {
 595								dist = tdist;
 596								bleft = points1[i];
 597							}
 598						}
 599					}
 600				}
 601				
 602			} else {
 603				var bu:Number = 0;
 604				var bincu:Number = 1/(countloop - 1);
 605			}
 606			
 607			function getDouble(x:Number, y:Number, z:Number):Vertex
 608			{
 609				for (var i:int = 0; i < _doubles.length; ++i) {
 610					if (_doubles[i].x == x && _doubles[i].y == y && _doubles[i].z == z) {
 611						return _doubles[i];
 612					}
 613				}
 614				return new Vertex(x, y, z);
 615			}
 616			
 617			for (i = 0; i < countloop; ++i) {
 618				stepx = points2[i].x - points1[i].x;
 619				stepy = points2[i].y - points1[i].y;
 620				stepz = points2[i].z - points1[i].z;
 621				
 622				for (j = 0; j < 2; ++j) {
 623					if (_isClosedProfile && _doubles.length > 0)
 624						_varr.push(getDouble(points1[i].x + (stepx*j), points1[i].y + (stepy*j), points1[i].z + (stepz*j)));
 625					else
 626						_varr.push(new Vertex(points1[i].x + (stepx*j), points1[i].y + (stepy*j), points1[i].z + (stepz*j)));
 627				}
 628			}
 629			
 630			var floored:uint = _coverSegment? indexp : 0;
 631			
 632			if (_materials && _materials.length > 0) {
 633				
 634				if (_coverSegment && indexp - floored == 0)
 635					_matIndex = (_matIndex + 1 > _materials.length - 1)? 0 : _matIndex + 1;
 636				else if (!coverAll && !_coverSegment)
 637					_matIndex = (_matIndex + 1 > _materials.length - 1)? 0 : _matIndex + 1;
 638			}
 639			
 640			mat = ( _coverAll || !_materials || _materials.length == 0)? this.material : _materials[_matIndex];
 641			
 642			var covSub:Boolean = _coverAll && _subdivision > 1;
 643			var cosegSub:Boolean = _coverSegment && _subdivision > 1;
 644			
 645			for (i = 0; i < countloop - 1; ++i) {
 646				
 647				if (_distributeU) {
 648					u1 = _distributedU[i];
 649					u2 = _distributedU[i + 1];
 650					
 651				} else if (_mapFit) {
 652					u1 = 1 - Vector3D.distance(points1[i], bleft)/dist;
 653					u2 = 1 - Vector3D.distance(points1[i + 1], bleft)/dist;
 654					
 655				} else {
 656					u1 = 1 - bu;
 657					bu += bincu;
 658					u2 = 1 - bu;
 659				}
 660				
 661				v1 = (covSub)? vscale : ( (cosegSub)? indexp - floored : 0 );
 662				v2 = (covSub)? vscale + (1/indexv) : ( (cosegSub)? v1 + _segv : 1 );
 663				
 664				_uva.u = u1;
 665				_uva.v = v1;
 666				_uvb.u = u1;
 667				_uvb.v = v2;
 668				_uvc.u = u2;
 669				_uvc.v = v2;
 670				_uvd.u = u2;
 671				_uvd.v = v1;
 672				
 673				va = _varr[index];
 674				vb = _varr[index + 1];
 675				vc = _varr[index + 3];
 676				vd = _varr[index + 2];
 677				
 678				if (_flip) {
 679					addFace(vb, va, vc, _uvb, _uva, _uvc, mat);
 680					addFace(vc, va, vd, _uvc, _uva, _uvd, mat);
 681					
 682				} else {
 683					addFace(va, vb, vc, _uva, _uvb, _uvc, mat);
 684					addFace(va, vc, vd, _uva, _uvc, _uvd, mat);
 685				}
 686				
 687				if (_mapFit)
 688					u1 = u2;
 689				
 690				index += 2;
 691			}
 692		}
 693		
 694		private function initHolders():void
 695		{
 696			if (!_uva) {
 697				_uva = new UV(0, 0);
 698				_uvb = new UV(0, 0);
 699				_uvc = new UV(0, 0);
 700				_uvd = new UV(0, 0);
 701				_normal0 = new Vector3D(0.0, 0.0, 0.0);
 702				_normal1 = new Vector3D(0.0, 0.0, 0.0);
 703				_normal2 = new Vector3D(0.0, 0.0, 0.0);
 704				_normalTmp = new Vector3D(0.0, 0.0, 0.0);
 705			}
 706			
 707			if (_materials && _materials.length > 0) {
 708				var sglist:SubGeometryList = new SubGeometryList();
 709				_MaterialsSubGeometries.push(sglist);
 710				sglist.subGeometry = new SubGeometry();
 711				_subGeometry = sglist.subGeometry;
 712				
 713				sglist.uvs = _uvs = new Vector.<Number>();
 714				sglist.vertices = _vertices = new Vector.<Number>();
 715				if (_smoothSurface)
 716					sglist.normals = _normals = new Vector.<Number>();
 717				sglist.indices = _indices = new Vector.<uint>();
 718				sglist.material = this.material;
 719				if (sglist.material.name == null)
 720					sglist.material.name = "baseMaterial";
 721				
 722				_matIndex = _materials.length;
 723				
 724			} else {
 725				_uvs = new Vector.<Number>();
 726				_vertices = new Vector.<Number>();
 727				_indices = new Vector.<uint>();
 728				if (_smoothSurface)
 729					_normals = new Vector.<Number>();
 730				else
 731					_subGeometry.autoDeriveVertexNormals = true;
 732				_subGeometry.autoDeriveVertexTangents = true;
 733			}
 734		}
 735		
 736		private function getSubGeometryListFromMaterial(mat:MaterialBase):SubGeometryList
 737		{
 738			var sglist:SubGeometryList;
 739			
 740			for (var i:uint = 0; i < _MaterialsSubGeometries.length; ++i) {
 741				if (_MaterialsSubGeometries[i].material == mat) {
 742					sglist = _MaterialsSubGeometries[i];
 743					break;
 744				}
 745			}
 746			
 747			if (!sglist) {
 748				sglist = new SubGeometryList();
 749				_MaterialsSubGeometries.push(sglist);
 750				sglist.subGeometry = new SubGeometry();
 751				sglist.uvs = new Vector.<Number>();
 752				sglist.vertices = new Vector.<Number>();
 753				sglist.indices = new Vector.<uint>();
 754				sglist.material = mat;
 755				if (_smoothSurface)
 756					sglist.normals = new Vector.<Number>();
 757			}
 758			
 759			return sglist;
 760		}
 761		
 762		private function calcNormal(v0:Vertex, v1:Vertex, v2:Vertex):void
 763		{
 764			var dx1:Number = v2.x - v0.x;
 765			var dy1:Number = v2.y - v0.y;
 766			var dz1:Number = v2.z - v0.z;
 767			var dx2:Number = v1.x - v0.x;
 768			var dy2:Number = v1.y - v0.y;
 769			var dz2:Number = v1.z - v0.z;
 770			
 771			var cx:Number = dz1*dy2 - dy1*dz2;
 772			var cy:Number = dx1*dz2 - dz1*dx2;
 773			var cz:Number = dy1*dx2 - dx1*dy2;
 774			var d:Number = 1/Math.sqrt(cx*cx + cy*cy + cz*cz);
 775			
 776			_normal0.x = _normal1.x = _normal2.x = cx*d;
 777			_normal0.y = _normal1.y = _normal2.y = cy*d;
 778			_normal0.z = _normal1.z = _normal2.z = cz*d;
 779		}
 780		
 781		private function addFace(v0:Vertex, v1:Vertex, v2:Vertex, uv0:UV, uv1:UV, uv2:UV, mat:MaterialBase):void
 782		{
 783			var subGeom:SubGeometry;
 784			var uvs:Vector.<Number>;
 785			var vertices:Vector.<Number>;
 786			var normals:Vector.<Number>;
 787			var indices:Vector.<uint>;
 788			var sglist:SubGeometryList;
 789			var startMat:Boolean;
 790			
 791			if (_activeMaterial != mat && _materials && _materials.length > 0) {
 792				_activeMaterial = mat;
 793				sglist = getSubGeometryListFromMaterial(mat);
 794				_subGeometry = subGeom = sglist.subGeometry;
 795				_uvs = uvs = sglist.uvs;
 796				_vertices = vertices = sglist.vertices;
 797				_indices = indices = sglist.indices;
 798				_normals = normals = sglist.normals;
 799				startMat = true;
 800				
 801			} else {
 802				subGeom = _subGeometry;
 803				uvs = _uvs;
 804				vertices = _vertices;
 805				indices = _indices;
 806				normals = _normals;
 807			}
 808			
 809			if (vertices.length + 9 > LIMIT) {
 810				subGeom.updateVertexData(vertices);
 811				subGeom.updateIndexData(indices);
 812				subGeom.updateUVData(uvs);
 813				if (_smoothSurface)
 814					subGeom.updateVertexNormalData(normals);
 815				
 816				this.geometry.addSubGeometry(subGeom);
 817				this.subMeshes[this.subMeshes.length - 1].material = mat;
 818				
 819				subGeom = new SubGeometry();
 820				subGeom.autoDeriveVertexTangents = true;
 821				if (!_smoothSurface)
 822					subGeom.autoDeriveVertexNormals = true;
 823				
 824				if (_MaterialsSubGeometries && _MaterialsSubGeometries.length > 1) {
 825					
 826					sglist = getSubGeometryListFromMaterial(mat);
 827					sglist.subGeometry = _subGeometry = subGeom;
 828					sglist.uvs = _uvs = uvs = new Vector.<Number>();
 829					sglist.vertices = _vertices = vertices = new Vector.<Number>();
 830					sglist.indices = _indices = indices = new Vector.<uint>();
 831					if (_smoothSurface)
 832						sglist.normals = _normals = normals = new Vector.<Number>();
 833					
 834				} else {
 835					
 836					_subGeometry = subGeom;
 837					uvs = _uvs = new Vector.<Number>();
 838					vertices = _vertices = new Vector.<Number>();
 839					indices = _indices = new Vector.<uint>();
 840					normals = _normals = new Vector.<Number>();
 841				}
 842			}
 843			
 844			var bv0:Boolean;
 845			var bv1:Boolean;
 846			var bv2:Boolean;
 847			
 848			var ind0:uint;
 849			var ind1:uint;
 850			var ind2:uint;
 851			
 852			if (_smoothSurface && !startMat) {
 853				var uvind:uint;
 854				var uvindV:uint;
 855				var vind:uint;
 856				var vindy:uint;
 857				var vindz:uint;
 858				var ind:uint;
 859				var indlength:uint = indices.length;
 860				calcNormal(v0, v1, v2);
 861				var ab:Number;
 862				
 863				if (indlength > 0) {
 864					var back:Number = indlength - _maxIndProfile;
 865					var limitBack:uint = (back < 0)? 0 : back;
 866					
 867					for (var i:uint = indlength - 1; i > limitBack; --i) {
 868						ind = indices[i];
 869						vind = ind*3;
 870						vindy = vind + 1;
 871						vindz = vind + 2;
 872						uvind = ind*2;
 873						uvindV = uvind + 1;
 874						
 875						if (bv0 && bv1 && bv2)
 876							break;
 877						
 878						if (!bv0 && vertices[vind] == v0.x && vertices[vindy] == v0.y && vertices[vindz] == v0.z) {
 879							
 880							_normalTmp.x = normals[vind];
 881							_normalTmp.y = normals[vindy];
 882							_normalTmp.z = normals[vindz];
 883							ab = Vector3D.angleBetween(_normalTmp, _normal0);
 884							
 885							if (ab < MAXRAD) {
 886								_normal0.x = (_normalTmp.x + _normal0.x)*.5;
 887								_normal0.y = (_normalTmp.y + _normal0.y)*.5;
 888								_normal0.z = (_normalTmp.z + _normal0.z)*.5;
 889								
 890								if (_coverAll || uvs[uvind] == uv0.u && uvs[uvindV] == uv0.v) {
 891									bv0 = true;
 892									ind0 = ind;
 893									continue;
 894								}
 895							}
 896						}
 897						
 898						if (!bv1 && vertices[vind] == v1.x && vertices[vindy] == v1.y && vertices[vindz] == v1.z) {
 899							
 900							_normalTmp.x = normals[vind];
 901							_normalTmp.y = normals[vindy];
 902							_normalTmp.z = normals[vindz];
 903							ab = Vector3D.angleBetween(_normalTmp, _normal1);
 904							
 905							if (ab < MAXRAD) {
 906								_normal1.x = (_normalTmp.x + _normal1.x)*.5;
 907								_normal1.y = (_normalTmp.y + _normal1.y)*.5;
 908								_normal1.z = (_normalTmp.z + _normal1.z)*.5;
 909								
 910								if (_coverAll || uvs[uvind] == uv1.u && uvs[uvindV] == uv1.v) {
 911									bv1 = true;
 912									ind1 = ind;
 913									continue;
 914								}
 915							}
 916						}
 917						
 918						if (!bv2 && vertices[vind] == v2.x && vertices[vindy] == v2.y && vertices[vindz] == v2.z) {
 919							
 920							_normalTmp.x = normals[vind];
 921							_normalTmp.y = normals[vindy];
 922							_normalTmp.z = normals[vindz];
 923							ab = Vector3D.angleBetween(_normalTmp, _normal2);
 924							
 925							if (ab < MAXRAD) {
 926								_normal2.x = (_normalTmp.x + _normal2.x)*.5;
 927								_normal2.y = (_normalTmp.y + _normal2.y)*.5;
 928								_normal2.z = (_normalTmp.z + _normal2.z)*.5;
 929								
 930								if (_coverAll || uvs[uvind] == uv2.u && uvs[uvindV] == uv2.v) {
 931									bv2 = true;
 932									ind2 = ind;
 933									continue;
 934								}
 935							}
 936							
 937						}
 938					}
 939				}
 940			}
 941			
 942			if (!bv0) {
 943				ind0 = vertices.length/3;
 944				vertices.push(v0.x, v0.y, v0.z);
 945				uvs.push(uv0.u, uv0.v);
 946				if (_smoothSurface)
 947					normals.push(_normal0.x, _normal0.y, _normal0.z);
 948			}
 949			
 950			if (!bv1) {
 951				ind1 = vertices.length/3;
 952				vertices.push(v1.x, v1.y, v1.z);
 953				uvs.push(uv1.u, uv1.v);
 954				if (_smoothSurface)
 955					normals.push(_normal1.x, _normal1.y, _normal1.z);
 956			}
 957			
 958			if (!bv2) {
 959				ind2 = vertices.length/3;
 960				vertices.push(v2.x, v2.y, v2.z);
 961				uvs.push(uv2.u, uv2.v);
 962				if (_smoothSurface)
 963					normals.push(_normal2.x, _normal2.y, _normal2.z);
 964			}
 965			
 966			indices.push(ind0, ind1, ind2);
 967		}
 968		
 969		private function distributeVectors():Vector.<Vector.<Vector3D>>
 970		{
 971			var segs:Vector.<Vector.<Vector3D>> = _path.getPointsOnCurvePerSegment(_subdivision);
 972			var nSegs:Vector.<Vector.<Vector3D>> = new Vector.<Vector.<Vector3D>>();
 973			
 974			var seg:Vector.<Vector3D>;
 975			var j:uint;
 976			var estLength:Number = 0;
 977			var vCount:uint;
 978			
 979			var v:Vector3D;
 980			var tmpV:Vector3D = new Vector3D();
 981			var prevV:Vector3D;
 982			
 983			for (var i:uint = 0; i < segs.length; ++i) {
 984				seg = segs[i];
 985				for (j = 0; j < _subdivision; ++j) {
 986					if (prevV)
 987						estLength += Vector3D.distance(prevV, seg[j]);
 988					prevV = seg[j];
 989					vCount++;
 990				}
 991			}
 992			var step:Number = estLength/vCount;
 993			var tPrecision:Number = 0.001;
 994			var t:Number = 0;
 995			var ps:IPathSegment;
 996			
 997			var tmpVDist:Number = 0;
 998			var diff:Number = 0;
 999			var ignore:Boolean;
1000			
1001			for (i = 0; i < segs.length; ++i) {
1002				ps = _path.getSegmentAt(i);
1003				ignore = false;
1004				t = diff;
1005				seg = new Vector.<Vector3D>();
1006				
1007				while (t < 1) {
1008					
1009					if (segs.length == 0) {
1010						v = segs[i][0];
1011						seg.push(v);
1012						prevV = v;
1013						continue;
1014					}
1015					
1016					tmpVDist = 0;
1017					while (tmpVDist < step) {
1018						t += tPrecision;
1019						if (t > 1 && i < segs.length - 1) {
1020							ignore = true;
1021							break;
1022						} else {
1023							tmpV = ps.getPointOnSegment(t, tmpV);
1024							tmpVDist = Vector3D.distance(prevV, tmpV);
1025						}
1026					}
1027					
1028					diff = 1 - t;
1029					if (!ignore) {
1030						v = new Vector3D(tmpV.x, tmpV.y, tmpV.z);
1031						prevV = v;
1032						seg.push(v);
1033					}
1034				}
1035				
1036				nSegs.push(seg);
1037			}
1038			
1039			segs = null;
1040			
1041			return nSegs;
1042		}
1043		
1044		private function generateUlist():void
1045		{
1046			_distributedU = Vector.<Number>([0]);
1047			var tdist:Number = 0;
1048			var dist:Number = 0;
1049			var tmpDists:Vector.<Number> = new Vector.<Number>();
1050			for (var i:uint = 0; i < _profile.length - 1; ++i) {
1051				tmpDists[i] = Vector3D.distance(_profile[i], _profile[i + 1]);
1052				tdist += tmpDists[i];
1053			}
1054			for (i = 1; i < _profile.length; ++i) {
1055				_distributedU[i] = (tmpDists[i - 1] + dist)/tdist;
1056				dist += tmpDists[i - 1];
1057			}
1058			
1059			tmpDists = null;
1060		}
1061		
1062		private function buildExtrude():void
1063		{
1064			if (_path == null || _path.numSegments == 0 || _profile == null || _profile.length < 2)
1065				throw new Error("PathExtrude error: invalid Path or profile with unsufficient data");
1066			
1067			_geomDirty = false;
1068			initHolders();
1069			
1070			_maxIndProfile = _profile.length*9;
1071			
1072			var vSegPts:Vector.<Vector.<Vector3D>>;
1073			
1074			if (_distribute)
1075				vSegPts = distributeVectors();
1076			else
1077				vSegPts = _path.getPointsOnCurvePerSegment(_subdivision);
1078			
1079			if (_distributeU)
1080				generateUlist();
1081			
1082			var vPtsList:Vector.<Vector3D> = new Vector.<Vector3D>();
1083			var vSegResults:Vector.<Vector.<Vector3D>> = new Vector.<Vector.<Vector3D>>();
1084			var atmp:Vector.<Vector3D>;
1085			var tmppt:Vector3D = new Vector3D(0, 0, 0);
1086			
1087			var i:uint;
1088			var j:uint;
1089			var k:uint;
1090			
1091			var nextpt:Vector3D;
1092			if (_coverSegment)
1093				_segv = 1/(_subdivision - 1);
1094			
1095			var lastP:Vector.<Vector3D>
1096			if (_closePath)
1097				lastP = new Vector.<Vector3D>();
1098			
1099			var rescale:Boolean = (_scales != null);
1100			var lastscale:Vector3D;
1101			if (rescale)
1102				lastscale = (_scales[0] == null)? new Vector3D(1, 1, 1) : _scales[0];
1103			
1104			var rotate:Boolean = (_rotations != null);
1105			
1106			if (rotate && _rotations.length > 0) {
1107				var lastrotate:Vector3D = _rotations[0];
1108				var nextrotate:Vector3D;
1109				var rotation:Vector.<Vector3D> = new Vector.<Vector3D>();
1110				var tweenrot:Vector3D;
1111			}
1112			
1113			if (_smoothScale && rescale) {
1114				var nextscale:Vector3D = new Vector3D(1, 1, 1);
1115				var vScales:Vector.<Vector3D> = Vector.<Vector3D>([lastscale]);
1116				if (_scales.length != _path.numSegments + 2) {
1117					var lastScl:Vector3D = _scales[_scales.length - 1];
1118					while (_scales.length != _path.numSegments + 2)
1119						_scales.push(lastScl);
1120				}
1121			}
1122			
1123			var tmploop:uint = _profile.length;
1124			for (i = 0; i < vSegPts.length; ++i) {
1125				if (rotate) {
1126					lastrotate = (_rotations[i] == null)? lastrotate : _rotations[i];
1127					nextrotate = (_rotations[i + 1] == null)? lastrotate : _rotations[i + 1];
1128					rotation = Vector.<Vector3D>([lastrotate]);
1129					rotation = rotation.concat(Vector3DUtils.subdivide(lastrotate, nextrotate, _subdivision));
1130				}
1131				
1132				if (rescale)
1133					lastscale = (!_scales[i])? lastscale : _scales[i];
1134				
1135				if (_smoothScale && rescale) {
1136					nextscale = (!_scales[i + 1])? (!_scales[i])? lastscale : _scales[i] : _scales[i + 1];
1137					vScales = vScales.concat(Vector3DUtils.subdivide(lastscale, nextscale, _subdivision));
1138				}
1139				
1140				for (j = 0; j < vSegPts[i].length; ++j) {
1141					
1142					atmp = new Vector.<Vector3D>();
1143					atmp = atmp.concat(_profile);
1144					vPtsList = new Vector.<Vector3D>();
1145					
1146					if (rotate)
1147						tweenrot = rotation[j];
1148					
1149					if (_alignToPath) {
1150						_trans = new Matrix3D();
1151						if (i == vSegPts.length - 1 && j == vSegPts[i].length - 1) {
1152							
1153							if (_closePath) {
1154								nextpt = vSegPts[0][0];
1155								orientateAt(nextpt, vSegPts[i][j]);
1156							} else {
1157								nextpt = vSegPts[i][j - 1];
1158								orientateAt(vSegPts[i][j], nextpt);
1159							}
1160							
1161						} else {
1162							nextpt = (j < vSegPts[i].length - 1)? vSegPts[i][j + 1] : vSegPts[i + 1][0];
1163							orientateAt(nextpt, vSegPts[i][j]);
1164						}
1165					}
1166					
1167					for (k = 0; k < tmploop; ++k) {
1168						
1169						if (rescale && !_smoothScale) {
1170							atmp[k].x *= lastscale.x;
1171							atmp[k].y *= lastscale.y;
1172							atmp[k].z *= lastscale.z;
1173						}
1174						
1175						if (_alignToPath) {
1176							tmppt = new Vector3D();
1177							
1178							tmppt.x = atmp[k].x*_trans.rawData[0] + atmp[k].y*_trans.rawData[4] + atmp[k].z*_trans.rawData[8] + _trans.rawData[12];
1179							tmppt.y = atmp[k].x*_trans.rawData[1] + atmp[k].y*_trans.rawData[5] + atmp[k].z*_trans.rawData[9] + _trans.rawData[13];
1180							tmppt.z = atmp[k].x*_trans.rawData[2] + atmp[k].y*_trans.rawData[6] + atmp[k].z*_trans.rawData[10] + _trans.rawData[14];
1181							
1182							if (rotate)
1183								tmppt = Vector3DUtils.rotatePoint(tmppt, tweenrot);
1184							
1185							tmppt.x += vSegPts[i][j].x;
1186							tmppt.y += vSegPts[i][j].y;
1187							tmppt.z += vSegPts[i][j].z;
1188							
1189						} else
1190							tmppt = new Vector3D(atmp[k].x + vSegPts[i][j].x, atmp[k].y + vSegPts[i][j].y, atmp[k].z + vSegPts[i][j].z);
1191						
1192						vPtsList.push(tmppt);
1193					}
1194					
1195					if (_closePath && i == vSegPts.length - 1 && j == vSegPts[i].length - 1)
1196						break;
1197					
1198					if (_closePath)
1199						lastP = vPtsList;
1200					
1201					vSegResults.push(vPtsList);
1202					
1203				}
1204			}
1205			
1206			if (rescale && _smoothScale) {
1207				for (i = 0; i < vScales.length; ++i) {
1208					for (j = 0; j < vSegResults[i].length; ++j) {
1209						vSegResults[i][j].x *= vScales[i].x;
1210						vSegResults[i][j].y *= vScales[i].y;
1211						vSegResults[i][j].z *= vScales[i].z;
1212					}
1213				}
1214				vScales = null;
1215			}
1216			
1217			if (rotate)
1218				rotation = null;
1219			
1220			if (_closePath) {
1221				var stepx:Number;
1222				var stepy:Number;
1223				var stepz:Number;
1224				var c:Vector.<Vector3D>;
1225				var c2:Vector.<Vector.<Vector3D>> = new Vector.<Vector.<Vector3D>>();
1226				
1227				for (i = 1; i < _subdivision + 1; ++i) {
1228					c = new Vector.<Vector3D>();
1229					for (j = 0; j < lastP.length; ++j) {
1230						stepx = (vSegResults[0][j].x - lastP[j].x)/_subdivision;
1231						stepy = (vSegResults[0][j].y - lastP[j].y)/_subdivision;
1232						stepz = (vSegResults[0][j].z - lastP[j].z)/_subdivision;
1233						c.push(new Vector3D(lastP[j].x + (stepx*i), lastP[j].y + (stepy*i), lastP[j].z + (stepz*i)));
1234					}
1235					c2.push(c);
1236				}
1237				
1238				c2[0] = lastP;
1239				generate(c2, (_coverAll)? vSegResults.length : 0, _coverAll);
1240				c = null;
1241				c2 = null;
1242			}
1243			
1244			if (_keepExtremes) {
1245				_startPoints = new Vector.<Vector3D>();
1246				_endPoints = new Vector.<Vector3D>();
1247				var offsetEnd:uint = vSegResults.length - 1;
1248				
1249				for (i = 0; i < tmploop; ++i) {
1250					_startPoints[i] = vSegResults[0][i];
1251					_endPoints[i] = vSegResults[offsetEnd][i];
1252				}
1253				
1254			} else if (_startPoints) {
1255				
1256				for (i = 0; i < tmploop; ++i)
1257					_startPoints[i] = _endPoints[i] = null;
1258				_startPoints = _endPoints = null;
1259			}
1260			
1261			generate(vSegResults, (_closePath && _coverAll)? 1 : 0, (_closePath && !_coverAll));
1262			
1263			vSegPts = null;
1264			_varr = null;
1265			
1266			if (_MaterialsSubGeometries && _MaterialsSubGeometries.length > 0) {
1267				var sglist:SubGeometryList;
1268				var sg:SubGeometry;
1269				for (i = 0; i < _MaterialsSubGeometries.length; ++i) {
1270					sglist = _MaterialsSubGeometries[i];
1271					sg = sglist.subGeometry;
1272					if (sg && sglist.vertices.length > 0) {
1273						this.geometry.addSubGeometry(sg);
1274						this.subMeshes[this.subMeshes.length - 1].material = sglist.material;
1275						sg.updateVertexData(sglist.vertices);
1276						sg.updateIndexData(sglist.indices);
1277						sg.updateUVData(sglist.uvs);
1278						
1279						if (_smoothSurface)
1280							sg.updateVertexNormalData(sglist.normals);
1281					}
1282				}
1283				
1284			} else {
1285				
1286				_subGeometry.updateVertexData(_vertices);
1287				_subGeometry.updateIndexData(_indices);
1288				_subGeometry.updateUVData(_uvs);
1289				
1290				if (_smoothSurface)
1291					_subGeometry.updateVertexNormalData(_normals);
1292				
1293				this.geometry.addSubGeometry(_subGeometry);
1294			}
1295			
1296			if (_centerMesh)
1297				MeshHelper.recenter(this);
1298		}
1299	}
1300}
1301
1302import away3d.core.base.SubGeometry;
1303import away3d.materials.MaterialBase;
1304
1305class SubGeometryList
1306{
1307	public var uvs:Vector.<Number>;
1308	public var vertices:Vector.<Number>;
1309	public var normals:Vector.<Number>;
1310	public var indices:Vector.<uint>;
1311	public var subGeometry:SubGeometry;
1312	public var material:MaterialBase;
1313}