PageRenderTime 65ms CodeModel.GetById 20ms app.highlight 25ms RepoModel.GetById 15ms app.codeStats 0ms

/src/away3d/core/base/data/Face.as

http://github.com/away3d/away3d-core-fp11
ActionScript | 484 lines | 260 code | 52 blank | 172 comment | 9 complexity | 7be1c3272f036a53c4048f82bbaeea70 MD5 | raw file
  1package away3d.core.base.data
  2{
  3	import flash.geom.Point;
  4	import flash.geom.Vector3D;
  5	
  6	/**
  7	 * Face value object.
  8	 */
  9	public class Face
 10	{
 11		private static var _calcPoint:Point;
 12		
 13		private var _vertices:Vector.<Number>;
 14		private var _uvs:Vector.<Number>;
 15		private var _faceIndex:uint;
 16		private var _v0Index:uint;
 17		private var _v1Index:uint;
 18		private var _v2Index:uint;
 19		private var _uv0Index:uint;
 20		private var _uv1Index:uint;
 21		private var _uv2Index:uint;
 22		
 23		/**
 24		 * Creates a new <code>Face</code> value object.
 25		 *
 26		 * @param    vertices        [optional] 9 entries long Vector.&lt;Number&gt; representing the x, y and z of v0, v1, and v2 of a face
 27		 * @param    uvs            [optional] 6 entries long Vector.&lt;Number&gt; representing the u and v of uv0, uv1, and uv2 of a face
 28		 */
 29		function Face(vertices:Vector.<Number> = null, uvs:Vector.<Number> = null)
 30		{
 31			_vertices = vertices || Vector.<Number>([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]);
 32			_uvs = uvs || Vector.<Number>([0.0, 0.0, 0.0, 0.0, 0.0, 0.0]);
 33		}
 34		
 35		//uvs
 36		/**
 37		 * To set uv values for either uv0, uv1 or uv2.
 38		 * @param    index        The id of the uv (0, 1 or 2)
 39		 * @param    u            The horizontal coordinate of the texture value.
 40		 * @param    v            The vertical coordinate of the texture value.
 41		 */
 42		public function setUVat(index:uint, u:Number, v:Number):void
 43		{
 44			var ind:uint = (index*2);
 45			_uvs[ind] = u;
 46			_uvs[ind + 1] = v;
 47		}
 48		
 49		/**
 50		 * To store a temp index of a face during a loop
 51		 * @param    ind        The index
 52		 */
 53		public function set faceIndex(ind:uint):void
 54		{
 55			_faceIndex = ind;
 56		}
 57		
 58		/**
 59		 * @return            Returns the tmp index set for this Face object
 60		 */
 61		public function get faceIndex():uint
 62		{
 63			return _faceIndex;
 64		}
 65		
 66		//uv0
 67		/**
 68		 * the index set for uv0 in this Face value object
 69		 * @param    ind        The index
 70		 */
 71		public function set uv0Index(ind:uint):void
 72		{
 73			_uv0Index = ind;
 74		}
 75		
 76		/**
 77		 * @return return the index set for uv0 in this Face value object
 78		 */
 79		public function get uv0Index():uint
 80		{
 81			return _uv0Index;
 82		}
 83		
 84		/**
 85		 * uv0 u and v values
 86		 * @param    u        The u value
 87		 * @param    v        The v value
 88		 */
 89		public function setUv0Value(u:Number, v:Number):void
 90		{
 91			_uvs[0] = u;
 92			_uvs[1] = v;
 93		}
 94		
 95		/**
 96		 * @return return the u value of the uv0 of this Face value object
 97		 */
 98		public function get uv0u():Number
 99		{
100			return _uvs[0];
101		}
102		
103		/**
104		 * @return return the v value of the uv0 of this Face value object
105		 */
106		public function get uv0v():Number
107		{
108			return _uvs[1];
109		}
110		
111		//uv1
112		/**
113		 * the index set for uv1 in this Face value object
114		 * @param    ind        The index
115		 */
116		public function set uv1Index(ind:uint):void
117		{
118			_uv1Index = ind;
119		}
120		
121		/**
122		 * @return Returns the index set for uv1 in this Face value object
123		 */
124		public function get uv1Index():uint
125		{
126			return _uv1Index;
127		}
128		
129		/**
130		 * uv1 u and v values
131		 * @param    u        The u value
132		 * @param    v        The v value
133		 */
134		public function setUv1Value(u:Number, v:Number):void
135		{
136			_uvs[2] = u;
137			_uvs[3] = v;
138		}
139		
140		/**
141		 * @return Returns the u value of the uv1 of this Face value object
142		 */
143		public function get uv1u():Number
144		{
145			return _uvs[2];
146		}
147		
148		/**
149		 * @return Returns the v value of the uv1 of this Face value object
150		 */
151		public function get uv1v():Number
152		{
153			return _uvs[3];
154		}
155		
156		//uv2
157		/**
158		 * the index set for uv2 in this Face value object
159		 * @param    ind        The index
160		 */
161		public function set uv2Index(ind:uint):void
162		{
163			_uv2Index = ind;
164		}
165		
166		/**
167		 * @return return the index set for uv2 in this Face value object
168		 */
169		public function get uv2Index():uint
170		{
171			return _uv2Index;
172		}
173		
174		/**
175		 * uv2 u and v values
176		 * @param    u        The u value
177		 * @param    v        The v value
178		 */
179		public function setUv2Value(u:Number, v:Number):void
180		{
181			_uvs[4] = u;
182			_uvs[5] = v;
183		}
184		
185		/**
186		 * @return return the u value of the uv2 of this Face value object
187		 */
188		public function get uv2u():Number
189		{
190			return _uvs[4];
191		}
192		
193		/**
194		 * @return return the v value of the uv2 of this Face value object
195		 */
196		public function get uv2v():Number
197		{
198			return _uvs[5];
199		}
200		
201		//vertices
202		/**
203		 * To set uv values for either v0, v1 or v2.
204		 * @param    index        The id of the uv (0, 1 or 2)
205		 * @param    x            The x value of the vertex.
206		 * @param    y            The y value of the vertex.
207		 * @param    z            The z value of the vertex.
208		 */
209		public function setVertexAt(index:uint, x:Number, y:Number, z:Number):void
210		{
211			var ind:uint = (index*3);
212			_vertices[ind] = x;
213			_vertices[ind + 1] = y;
214			_vertices[ind + 2] = z;
215		}
216		
217		//v0
218		/**
219		 * set the index value for v0
220		 * @param    ind            The index value to store
221		 */
222		public function set v0Index(ind:uint):void
223		{
224			_v0Index = ind;
225		}
226		
227		/**
228		 * @return Returns the index value of the v0 stored in the Face value object
229		 */
230		public function get v0Index():uint
231		{
232			return _v0Index;
233		}
234		
235		/**
236		 * @return Returns a Vector.<Number> representing the v0 stored in the Face value object
237		 */
238		public function get v0():Vector.<Number>
239		{
240			return Vector.<Number>([_vertices[0], _vertices[1], _vertices[2]]);
241		}
242		
243		/**
244		 * @return Returns the x value of the v0 stored in the Face value object
245		 */
246		public function get v0x():Number
247		{
248			return _vertices[0];
249		}
250		
251		/**
252		 * @return Returns the y value of the v0 stored in the Face value object
253		 */
254		public function get v0y():Number
255		{
256			return _vertices[1];
257		}
258		
259		/**
260		 * @return Returns the z value of the v0 stored in the Face value object
261		 */
262		public function get v0z():Number
263		{
264			return _vertices[2];
265		}
266		
267		//v1
268		/**
269		 * set the index value for v1
270		 * @param    ind            The index value to store
271		 */
272		public function set v1Index(ind:uint):void
273		{
274			_v1Index = ind;
275		}
276		
277		/**
278		 * @return Returns the index value of the v1 stored in the Face value object
279		 */
280		public function get v1Index():uint
281		{
282			return _v1Index;
283		}
284		
285		/**
286		 * @return Returns a Vector.<Number> representing the v1 stored in the Face value object
287		 */
288		public function get v1():Vector.<Number>
289		{
290			return Vector.<Number>([_vertices[3], _vertices[4], _vertices[5]]);
291		}
292		
293		/**
294		 * @return Returns the x value of the v1 stored in the Face value object
295		 */
296		public function get v1x():Number
297		{
298			return _vertices[3];
299		}
300		
301		/**
302		 * @return Returns the y value of the v1 stored in the Face value object
303		 */
304		public function get v1y():Number
305		{
306			return _vertices[4];
307		}
308		
309		/**
310		 * @return Returns the z value of the v1 stored in the Face value object
311		 */
312		public function get v1z():Number
313		{
314			return _vertices[5];
315		}
316		
317		//v2
318		/**
319		 * set the index value for v2
320		 * @param    ind            The index value to store
321		 */
322		public function set v2Index(ind:uint):void
323		{
324			_v2Index = ind;
325		}
326		
327		/**
328		 * @return return the index value of the v2 stored in the Face value object
329		 */
330		public function get v2Index():uint
331		{
332			return _v2Index;
333		}
334		
335		/**
336		 * @return Returns a Vector.<Number> representing the v2 stored in the Face value object
337		 */
338		public function get v2():Vector.<Number>
339		{
340			return Vector.<Number>([_vertices[6], _vertices[7], _vertices[8]]);
341		}
342		
343		/**
344		 * @return Returns the x value of the v2 stored in the Face value object
345		 */
346		public function get v2x():Number
347		{
348			return _vertices[6];
349		}
350		
351		/**
352		 * @return Returns the y value of the v2 stored in the Face value object
353		 */
354		public function get v2y():Number
355		{
356			return _vertices[7];
357		}
358		
359		/**
360		 * @return Returns the z value of the v2 stored in the Face value object
361		 */
362		public function get v2z():Number
363		{
364			return _vertices[8];
365		}
366		
367		/**
368		 * returns a new Face value Object
369		 */
370		public function clone():Face
371		{
372			var nVertices:Vector.<Number> = Vector.<Number>([    _vertices[0], _vertices[1], _vertices[2],
373				_vertices[3], _vertices[4], _vertices[5],
374				_vertices[6], _vertices[7], _vertices[8]]);
375			
376			var nUvs:Vector.<Number> = Vector.<Number>([_uvs[0], _uvs[1],
377				_uvs[2], _uvs[3],
378				_uvs[4], _uvs[5]]);
379			
380			return new Face(nVertices, nUvs);
381		}
382		
383		/**
384		 * Returns the first two barycentric coordinates for a point on (or outside) the triangle. The third coordinate is 1 - x - y
385		 * @param point The point for which to calculate the new target
386		 * @param target An optional Point object to store the calculation in order to prevent creation of a new object
387		 */
388		public function getBarycentricCoords(point:Vector3D, target:Point = null):Point
389		{
390			var v0x:Number = _vertices[0];
391			var v0y:Number = _vertices[1];
392			var v0z:Number = _vertices[2];
393			var dx0:Number = point.x - v0x;
394			var dy0:Number = point.y - v0y;
395			var dz0:Number = point.z - v0z;
396			var dx1:Number = _vertices[3] - v0x;
397			var dy1:Number = _vertices[4] - v0y;
398			var dz1:Number = _vertices[5] - v0z;
399			var dx2:Number = _vertices[6] - v0x;
400			var dy2:Number = _vertices[7] - v0y;
401			var dz2:Number = _vertices[8] - v0z;
402			
403			var dot01:Number = dx1*dx0 + dy1*dy0 + dz1*dz0;
404			var dot02:Number = dx2*dx0 + dy2*dy0 + dz2*dz0;
405			var dot11:Number = dx1*dx1 + dy1*dy1 + dz1*dz1;
406			var dot22:Number = dx2*dx2 + dy2*dy2 + dz2*dz2;
407			var dot12:Number = dx2*dx1 + dy2*dy1 + dz2*dz1;
408			
409			var invDenom:Number = 1/(dot22*dot11 - dot12*dot12);
410			target ||= new Point();
411			target.x = (dot22*dot01 - dot12*dot02)*invDenom;
412			target.y = (dot11*dot02 - dot12*dot01)*invDenom;
413			return target;
414		}
415		
416		/**
417		 * Tests whether a given point is inside the triangle
418		 * @param point The point to test against
419		 * @param maxDistanceToPlane The minimum distance to the plane for the point to be considered on the triangle. This is usually used to allow for rounding error, but can also be used to perform a volumetric test.
420		 */
421		public function containsPoint(point:Vector3D, maxDistanceToPlane:Number = .007):Boolean
422		{
423			if (!planeContains(point, maxDistanceToPlane))
424				return false;
425			
426			getBarycentricCoords(point, _calcPoint ||= new Point());
427			var s:Number = _calcPoint.x;
428			var t:Number = _calcPoint.y;
429			return s >= 0.0 && t >= 0.0 && (s + t) <= 1.0;
430		}
431		
432		private function planeContains(point:Vector3D, epsilon:Number = .007):Boolean
433		{
434			var v0x:Number = _vertices[0];
435			var v0y:Number = _vertices[1];
436			var v0z:Number = _vertices[2];
437			var d1x:Number = _vertices[3] - v0x;
438			var d1y:Number = _vertices[4] - v0y;
439			var d1z:Number = _vertices[5] - v0z;
440			var d2x:Number = _vertices[6] - v0x;
441			var d2y:Number = _vertices[7] - v0y;
442			var d2z:Number = _vertices[8] - v0z;
443			var a:Number = d1y*d2z - d1z*d2y;
444			var b:Number = d1z*d2x - d1x*d2z;
445			var c:Number = d1x*d2y - d1y*d2x;
446			var len:Number = 1/Math.sqrt(a*a + b*b + c*c);
447			a *= len;
448			b *= len;
449			c *= len;
450			var dist:Number = a*(point.x - v0x) + b*(point.y - v0y) + c*(point.z - v0z);
451			trace(dist);
452			return dist > -epsilon && dist < epsilon;
453		}
454		
455		/**
456		 * Returns the target coordinates for a point on a triangle
457		 * @param v0 The triangle's first vertex
458		 * @param v1 The triangle's second vertex
459		 * @param v2 The triangle's third vertex
460		 * @param uv0 The UV coord associated with the triangle's first vertex
461		 * @param uv1 The UV coord associated with the triangle's second vertex
462		 * @param uv2 The UV coord associated with the triangle's third vertex
463		 * @param point The point for which to calculate the new target
464		 * @param target An optional UV object to store the calculation in order to prevent creation of a new object
465		 */
466		public function getUVAtPoint(point:Vector3D, target:UV = null):UV
467		{
468			getBarycentricCoords(point, _calcPoint ||= new Point());
469			
470			var s:Number = _calcPoint.x;
471			var t:Number = _calcPoint.y;
472			
473			if (s >= 0.0 && t >= 0.0 && (s + t) <= 1.0) {
474				var u0:Number = _uvs[0];
475				var v0:Number = _uvs[1];
476				target ||= new UV();
477				target.u = u0 + t*(_uvs[4] - u0) + s*(_uvs[2] - u0);
478				target.v = v0 + t*(_uvs[5] - v0) + s*(_uvs[3] - v0);
479				return target;
480			} else
481				return null;
482		}
483	}
484}