/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

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