/src/away3d/extrusions/DelaunayMesh.as

http://github.com/away3d/away3d-core-fp11 · ActionScript · 818 lines · 619 code · 159 blank · 40 comment · 135 complexity · 01cb6322e399ea8cd2b2a4ee6ca451fc MD5 · raw file

  1. // The Delaunay triangulation code used in this class is adapted for Away from the work done by:
  2. // Paul Bourke's, triangulate.c (http://local.wasp.uwa.edu.au/~pbourke/papers/triangulate/triangulate.c)
  3. // Zachary Forest Johnson
  4. package away3d.extrusions
  5. {
  6. import away3d.bounds.BoundingVolumeBase;
  7. import away3d.core.base.Geometry;
  8. import away3d.core.base.SubGeometry;
  9. import away3d.core.base.SubMesh;
  10. import away3d.core.base.data.UV;
  11. import away3d.entities.Mesh;
  12. import away3d.materials.MaterialBase;
  13. import away3d.tools.helpers.MeshHelper;
  14. import flash.geom.Vector3D;
  15. public class DelaunayMesh extends Mesh
  16. {
  17. public static const PLANE_XZ:String = "xz";
  18. public static const PLANE_XY:String = "xy";
  19. public static const PLANE_ZY:String = "zy";
  20. private const LIMIT:uint = 196605;
  21. private const EPS:Number = .0001;
  22. private const MAXRAD:Number = 1.2;
  23. private var _circle:Vector3D;
  24. private var _vectors:Vector.<Vector3D>;
  25. private var _subGeometry:SubGeometry;
  26. private var _sortProp:String;
  27. private var _loopProp:String;
  28. private var _uvs:Vector.<Number>;
  29. private var _vertices:Vector.<Number>;
  30. private var _indices:Vector.<uint>;
  31. private var _normals:Vector.<Number>;
  32. private var _geomDirty:Boolean = true;
  33. private var _centerMesh:Boolean;
  34. private var _plane:String;
  35. private var _flip:Boolean;
  36. private var _smoothSurface:Boolean;
  37. private var _axis0Min:Number;
  38. private var _axis0Max:Number;
  39. private var _axis1Min:Number;
  40. private var _axis1Max:Number;
  41. private var _tmpNormal:Vector3D;
  42. private var _normal0:Vector3D;
  43. private var _normal1:Vector3D;
  44. private var _normal2:Vector3D;
  45. /*
  46. * Class DelaunayMesh generates (and becomes) a mesh from a vector of vector3D's . <code>DelaunayMesh</code>
  47. *@param material MaterialBase. The material for the resulting mesh.
  48. *@param vectors Vector.<Vector3D> A series of vector3d's defining the surface of the shape.
  49. *@param plane [optional] String. The destination plane: can be DelaunayMesh.PLANE_XY, DelaunayMesh.PLANE_XZ or DelaunayMesh.PLANE_ZY. Default is xz plane.
  50. *@param centerMesh [optional] Boolean. If the final mesh must be centered. Default is false.
  51. *@param flip [optional] Boolean. If the faces need to be inverted. Default is false.
  52. *@param smoothSurface [optional] Boolean. If the surface finished needs to smooth or flat. Default is true, a smooth finish.
  53. */
  54. public function DelaunayMesh(material:MaterialBase, vectors:Vector.<Vector3D>, plane:String = PLANE_XZ, centerMesh:Boolean = false, flip:Boolean = false, smoothSurface:Boolean = true)
  55. {
  56. var geom:Geometry = new Geometry();
  57. _subGeometry = new SubGeometry();
  58. geom.addSubGeometry(_subGeometry);
  59. super(geom, material);
  60. _vectors = vectors;
  61. _centerMesh = centerMesh;
  62. _plane = plane;
  63. _flip = flip;
  64. _smoothSurface = smoothSurface;
  65. }
  66. /**
  67. * The "cloud" of vector3d's to compose the mesh
  68. */
  69. public function get vectors():Vector.<Vector3D>
  70. {
  71. return _vectors;
  72. }
  73. public function set vectors(val:Vector.<Vector3D>):void
  74. {
  75. if (_vectors.length < 3)
  76. return;
  77. _vectors = val;
  78. invalidateGeometry();
  79. }
  80. /**
  81. * Defines if the surface of the mesh must be smoothed or not. Default value is true.
  82. */
  83. public function get smoothSurface():Boolean
  84. {
  85. return _smoothSurface;
  86. }
  87. public function set smoothSurface(val:Boolean):void
  88. {
  89. if (_smoothSurface == val)
  90. return;
  91. _smoothSurface = val;
  92. invalidateGeometry();
  93. }
  94. /**
  95. * Defines the projection plane for the class. Default is xz.
  96. */
  97. public function get plane():String
  98. {
  99. return _plane;
  100. }
  101. public function set plane(val:String):void
  102. {
  103. if (_plane == val)
  104. return;
  105. if (val != PLANE_XZ && val != PLANE_XY && val != PLANE_ZY)
  106. return;
  107. _plane = val;
  108. invalidateGeometry();
  109. }
  110. /**
  111. * Defines if the face orientation needs to be inverted
  112. */
  113. public function get flip():Boolean
  114. {
  115. return _flip;
  116. }
  117. public function set flip(val:Boolean):void
  118. {
  119. if (_flip == val)
  120. return;
  121. _flip = val;
  122. invalidateGeometry();
  123. }
  124. /**
  125. * Defines whether the mesh is recentered of not after generation
  126. */
  127. public function get centerMesh():Boolean
  128. {
  129. return _centerMesh;
  130. }
  131. public function set centerMesh(val:Boolean):void
  132. {
  133. if (_centerMesh == val)
  134. return;
  135. _centerMesh = val;
  136. if (_centerMesh && _subGeometry.vertexData.length > 0)
  137. MeshHelper.applyPosition(this, (this.minX + this.maxX)*.5, (this.minY + this.maxY)*.5, (this.minZ + this.maxZ)*.5);
  138. else
  139. invalidateGeometry();
  140. }
  141. private function buildExtrude():void
  142. {
  143. _geomDirty = false;
  144. if (_vectors && _vectors.length > 2) {
  145. initHolders();
  146. generate();
  147. } else
  148. throw new Error("DelaunayMesh: minimum 3 Vector3D are required to generate a surface");
  149. if (_centerMesh)
  150. MeshHelper.recenter(this);
  151. }
  152. private function initHolders():void
  153. {
  154. _axis0Min = Infinity;
  155. _axis0Max = -Infinity;
  156. _axis1Min = Infinity;
  157. _axis1Max = -Infinity;
  158. _uvs = new Vector.<Number>();
  159. _vertices = new Vector.<Number>();
  160. _indices = new Vector.<uint>();
  161. _circle = new Vector3D();
  162. if (_smoothSurface) {
  163. _normals = new Vector.<Number>();
  164. _normal0 = new Vector3D(0.0, 0.0, 0.0);
  165. _normal1 = new Vector3D(0.0, 0.0, 0.0);
  166. _normal2 = new Vector3D(0.0, 0.0, 0.0);
  167. _tmpNormal = new Vector3D(0.0, 0.0, 0.0);
  168. _subGeometry.autoDeriveVertexNormals = false;
  169. } else
  170. _subGeometry.autoDeriveVertexNormals = true;
  171. _subGeometry.autoDeriveVertexTangents = true;
  172. }
  173. private function addFace(v0:Vector3D, v1:Vector3D, v2:Vector3D, uv0:UV, uv1:UV, uv2:UV):void
  174. {
  175. var subGeom:SubGeometry = _subGeometry;
  176. var uvs:Vector.<Number> = _uvs;
  177. var vertices:Vector.<Number> = _vertices;
  178. var indices:Vector.<uint> = _indices;
  179. if (_smoothSurface)
  180. var normals:Vector.<Number> = _normals;
  181. if (vertices.length + 9 > LIMIT) {
  182. subGeom.updateVertexData(vertices);
  183. subGeom.updateIndexData(indices);
  184. subGeom.updateUVData(uvs);
  185. if (_smoothSurface)
  186. subGeom.updateVertexNormalData(normals);
  187. this.geometry.addSubGeometry(subGeom);
  188. subGeom = _subGeometry = new SubGeometry();
  189. subGeom.autoDeriveVertexTangents = true;
  190. uvs = _uvs = new Vector.<Number>();
  191. vertices = _vertices = new Vector.<Number>();
  192. indices = _indices = new Vector.<uint>();
  193. if (!_smoothSurface)
  194. subGeom.autoDeriveVertexNormals = true;
  195. else {
  196. subGeom.autoDeriveVertexNormals = false;
  197. normals = _normals = new Vector.<Number>();
  198. }
  199. subGeom.autoDeriveVertexTangents = true;
  200. }
  201. var bv0:Boolean;
  202. var bv1:Boolean;
  203. var bv2:Boolean;
  204. var ind0:uint;
  205. var ind1:uint;
  206. var ind2:uint;
  207. if (_smoothSurface) {
  208. var uvind:uint;
  209. var uvindV:uint;
  210. var vind:uint;
  211. var vindb:uint;
  212. var vindz:uint;
  213. var ind:uint;
  214. var indlength:uint = indices.length;
  215. calcNormal(v0, v1, v2);
  216. var ab:Number;
  217. if (indlength > 0) {
  218. for (var i:uint = indlength - 1; i > 0; --i) {
  219. ind = indices[i];
  220. vind = ind*3;
  221. vindb = vind + 1;
  222. vindz = vind + 2;
  223. uvind = ind*2;
  224. uvindV = uvind + 1;
  225. if (bv0 && bv1 && bv2)
  226. break;
  227. if (!bv0 && vertices[vind] == v0.x && vertices[vindb] == v0.y && vertices[vindz] == v0.z) {
  228. _tmpNormal.x = normals[vind];
  229. _tmpNormal.y = normals[vindb];
  230. _tmpNormal.z = normals[vindz];
  231. ab = Vector3D.angleBetween(_tmpNormal, _normal0);
  232. if (ab < MAXRAD) {
  233. _normal0.x = (_tmpNormal.x + _normal0.x)*.5;
  234. _normal0.y = (_tmpNormal.y + _normal0.y)*.5;
  235. _normal0.z = (_tmpNormal.z + _normal0.z)*.5;
  236. bv0 = true;
  237. ind0 = ind;
  238. continue;
  239. }
  240. }
  241. if (!bv1 && vertices[vind] == v1.x && vertices[vindb] == v1.y && vertices[vindz] == v1.z) {
  242. _tmpNormal.x = normals[vind];
  243. _tmpNormal.y = normals[vindb];
  244. _tmpNormal.z = normals[vindz];
  245. ab = Vector3D.angleBetween(_tmpNormal, _normal1);
  246. if (ab < MAXRAD) {
  247. _normal1.x = (_tmpNormal.x + _normal1.x)*.5;
  248. _normal1.y = (_tmpNormal.y + _normal1.y)*.5;
  249. _normal1.z = (_tmpNormal.z + _normal1.z)*.5;
  250. bv1 = true;
  251. ind1 = ind;
  252. continue;
  253. }
  254. }
  255. if (!bv2 && vertices[vind] == v2.x && vertices[vindb] == v2.y && vertices[vindz] == v2.z) {
  256. _tmpNormal.x = normals[vind];
  257. _tmpNormal.y = normals[vindb];
  258. _tmpNormal.z = normals[vindz];
  259. ab = Vector3D.angleBetween(_tmpNormal, _normal2);
  260. if (ab < MAXRAD) {
  261. _normal2.x = (_tmpNormal.x + _normal2.x)*.5;
  262. _normal2.y = (_tmpNormal.y + _normal2.y)*.5;
  263. _normal2.z = (_tmpNormal.z + _normal2.z)*.5;
  264. bv2 = true;
  265. ind2 = ind;
  266. continue;
  267. }
  268. }
  269. }
  270. }
  271. }
  272. if (!bv0) {
  273. ind0 = vertices.length/3;
  274. vertices.push(v0.x, v0.y, v0.z);
  275. uvs.push(uv0.u, uv0.v);
  276. if (_smoothSurface)
  277. normals.push(_normal0.x, _normal0.y, _normal0.z);
  278. }
  279. if (!bv1) {
  280. ind1 = vertices.length/3;
  281. vertices.push(v1.x, v1.y, v1.z);
  282. uvs.push(uv1.u, uv1.v);
  283. if (_smoothSurface)
  284. normals.push(_normal1.x, _normal1.y, _normal1.z);
  285. }
  286. if (!bv2) {
  287. ind2 = vertices.length/3;
  288. vertices.push(v2.x, v2.y, v2.z);
  289. uvs.push(uv2.u, uv2.v);
  290. if (_smoothSurface)
  291. normals.push(_normal2.x, _normal2.y, _normal2.z);
  292. }
  293. indices.push(ind0, ind1, ind2);
  294. }
  295. private function generate():void
  296. {
  297. getVectorsBounds();
  298. var w:Number = _axis0Max - _axis0Min;
  299. var h:Number = _axis1Max - _axis1Min;
  300. var offW:Number = (_axis0Min > 0)? -_axis0Min : Math.abs(_axis0Min);
  301. var offH:Number = (_axis1Min > 0)? -_axis1Min : Math.abs(_axis1Min);
  302. var uv0:UV = new UV();
  303. var uv1:UV = new UV();
  304. var uv2:UV = new UV();
  305. var v0:Vector3D;
  306. var v1:Vector3D;
  307. var v2:Vector3D;
  308. var limit:uint = _vectors.length;
  309. if (limit > 3) {
  310. var nVectors:Vector.<Vector3D> = new Vector.<Vector3D>();
  311. nVectors = _vectors.sort(sortFunction);
  312. var i:uint;
  313. var j:uint;
  314. var k:uint;
  315. var v:Vector.<Tri> = new Vector.<Tri>();
  316. var nv:uint = nVectors.length;
  317. for (i = 0; i < (nv*3); ++i)
  318. v[i] = new Tri();
  319. var bList:Vector.<Boolean> = new Vector.<Boolean>();
  320. var edges:Array = [];
  321. var nEdge:uint = 0;
  322. var maxTris:uint = 4*nv;
  323. var maxEdges:uint = nv*2;
  324. for (i = 0; i < maxTris; ++i)
  325. bList[i] = false;
  326. var inside:Boolean;
  327. var valA:Number;
  328. var valB:Number;
  329. var x1:Number;
  330. var y1:Number;
  331. var x2:Number;
  332. var y2:Number;
  333. var x3:Number;
  334. var y3:Number;
  335. // TODO: not used
  336. // var xc:Number;
  337. // TODO: not used
  338. // var yc:Number;
  339. var sortMin:Number;
  340. var sortMax:Number;
  341. var loopMin:Number;
  342. var loopMax:Number;
  343. var sortMid:Number;
  344. var loopMid:Number;
  345. var ntri:uint = 1;
  346. for (i = 0; i < maxEdges; ++i)
  347. edges[i] = new Edge();
  348. sortMin = nVectors[0][_sortProp];
  349. loopMin = nVectors[0][_loopProp];
  350. sortMax = sortMin;
  351. loopMax = loopMin;
  352. for (i = 1; i < nv; ++i) {
  353. if (nVectors[i][_sortProp] < sortMin)
  354. sortMin = nVectors[i][_sortProp];
  355. if (nVectors[i][_sortProp] > sortMax)
  356. sortMax = nVectors[i][_sortProp];
  357. if (nVectors[i][_loopProp] < loopMin)
  358. loopMin = nVectors[i][_loopProp];
  359. if (nVectors[i][_loopProp] > loopMax)
  360. loopMax = nVectors[i][_loopProp];
  361. }
  362. var da:Number = sortMax - sortMin;
  363. var db:Number = loopMax - loopMin;
  364. var dmax:Number = (da > db)? da : db;
  365. sortMid = (sortMax + sortMin)*.5;
  366. loopMid = (loopMax + loopMin)*.5;
  367. nVectors[nv] = new Vector3D(0.0, 0.0, 0.0);
  368. nVectors[nv + 1] = new Vector3D(0.0, 0.0, 0.0);
  369. nVectors[nv + 2] = new Vector3D(0.0, 0.0, 0.0);
  370. var offset:Number = 2.0;
  371. nVectors[nv + 0][_sortProp] = sortMid - offset*dmax;
  372. nVectors[nv + 0][_loopProp] = loopMid - dmax;
  373. nVectors[nv + 1][_sortProp] = sortMid;
  374. nVectors[nv + 1][_loopProp] = loopMid + offset*dmax;
  375. nVectors[nv + 2][_sortProp] = sortMid + offset*dmax;
  376. nVectors[nv + 2][_loopProp] = loopMid - dmax;
  377. v[0].v0 = nv;
  378. v[0].v1 = nv + 1;
  379. v[0].v2 = nv + 2;
  380. bList[0] = false;
  381. for (i = 0; i < nv; ++i) {
  382. valA = vectors[i][_sortProp];
  383. valB = vectors[i][_loopProp];
  384. nEdge = 0;
  385. for (j = 0; j < ntri; ++j) {
  386. if (bList[j])
  387. continue;
  388. x1 = nVectors[v[j].v0][_sortProp];
  389. y1 = nVectors[v[j].v0][_loopProp];
  390. x2 = nVectors[v[j].v1][_sortProp];
  391. y2 = nVectors[v[j].v1][_loopProp];
  392. x3 = nVectors[v[j].v2][_sortProp];
  393. y3 = nVectors[v[j].v2][_loopProp];
  394. inside = circumCircle(valA, valB, x1, y1, x2, y2, x3, y3);
  395. if (_circle.x + _circle.z < valA)
  396. bList[j] = true;
  397. if (inside) {
  398. if (nEdge + 3 >= maxEdges) {
  399. maxEdges += 3;
  400. edges.push(new Edge(), new Edge(), new Edge());
  401. }
  402. edges[nEdge].v0 = v[j].v0;
  403. edges[nEdge].v1 = v[j].v1;
  404. edges[nEdge + 1].v0 = v[j].v1;
  405. edges[nEdge + 1].v1 = v[j].v2;
  406. edges[nEdge + 2].v0 = v[j].v2;
  407. edges[nEdge + 2].v1 = v[j].v0;
  408. nEdge += 3;
  409. ntri--;
  410. v[j].v0 = v[ntri].v0;
  411. v[j].v1 = v[ntri].v1;
  412. v[j].v2 = v[ntri].v2;
  413. bList[j] = bList[ntri];
  414. j--;
  415. }
  416. }
  417. for (j = 0; j < nEdge - 1; ++j) {
  418. for (k = j + 1; k < nEdge; ++k) {
  419. if ((edges[j].v0 == edges[k].v1) && (edges[j].v1 == edges[k].v0))
  420. edges[j].v0 = edges[j].v1 = edges[k].v0 = edges[k].v1 = -1;
  421. if ((edges[j].v0 == edges[k].v0) && (edges[j].v1 == edges[k].v1))
  422. edges[j].v0 = edges[j].v1 = edges[k].v0 = edges[k].v1 = -1;
  423. }
  424. }
  425. for (j = 0; j < nEdge; ++j) {
  426. if (edges[j].v0 == -1 || edges[j].v1 == -1)
  427. continue;
  428. if (ntri >= maxTris)
  429. continue;
  430. v[ntri].v0 = edges[j].v0;
  431. v[ntri].v1 = edges[j].v1;
  432. v[ntri].v2 = i;
  433. bList[ntri] = false;
  434. ntri++;
  435. }
  436. }
  437. for (i = 0; i < ntri; ++i) {
  438. if (v[i].v0 == v[i].v1 && v[i].v1 == v[i].v2)
  439. continue;
  440. if ((v[i].v0 >= limit || v[i].v1 >= limit || v[i].v2 >= limit)) {
  441. v[i] = v[ntri - 1];
  442. ntri--;
  443. i--;
  444. continue;
  445. }
  446. v0 = nVectors[v[i].v0];
  447. v1 = nVectors[v[i].v1];
  448. v2 = nVectors[v[i].v2];
  449. uv0.u = (v0[_loopProp] + offW)/w;
  450. uv0.v = 1 - (v0[_sortProp] + offH)/h;
  451. uv1.u = (v1[_loopProp] + offW)/w;
  452. uv1.v = 1 - (v1[_sortProp] + offH)/h;
  453. uv2.u = (v2[_loopProp] + offW)/w;
  454. uv2.v = 1 - (v2[_sortProp] + offH)/h;
  455. if (_flip)
  456. addFace(v0, v1, v2, uv0, uv1, uv2);
  457. else
  458. addFace(v1, v0, v2, uv1, uv0, uv2);
  459. }
  460. if (_smoothSurface)
  461. _subGeometry.updateVertexNormalData(_normals);
  462. for (i = 0; i < v.length; ++i)
  463. v[i] = null;
  464. v = null;
  465. nVectors = null;
  466. } else {
  467. v0 = _vectors[0];
  468. v1 = _vectors[1];
  469. v2 = _vectors[2];
  470. _vertices.push(v0.x, v0.y, v0.z, v1.x, v1.y, v1.z, v2.x, v2.y, v2.z);
  471. uv0.u = (v0[_loopProp] + offW)/w;
  472. uv0.v = 1 - (v0[_sortProp] + offH)/h;
  473. uv1.u = (v1[_loopProp] + offW)/w;
  474. uv1.v = 1 - (v1[_sortProp] + offH)/h;
  475. uv2.u = (v2[_loopProp] + offW)/w;
  476. uv2.v = 1 - (v2[_sortProp] + offH)/h;
  477. _uvs.push(uv0.u, uv0.v, uv1.u, uv1.v, uv2.u, uv2.v);
  478. if (_flip)
  479. _indices.push(1, 0, 2);
  480. else
  481. _indices.push(0, 1, 2);
  482. _subGeometry.autoDeriveVertexNormals = true;
  483. }
  484. _subGeometry.updateVertexData(_vertices);
  485. _subGeometry.updateIndexData(_indices);
  486. _subGeometry.updateUVData(_uvs);
  487. }
  488. private function sortFunction(v0:Vector3D, v1:Vector3D):int
  489. {
  490. var a:Number = v0[_sortProp];
  491. var b:Number = v1[_sortProp];
  492. if (a == b)
  493. return 0;
  494. else if (a < b)
  495. return 1;
  496. else
  497. return -1;
  498. }
  499. private function calcNormal(v0:Vector3D, v1:Vector3D, v2:Vector3D):void
  500. {
  501. var da1:Number = v2.x - v0.x;
  502. var db1:Number = v2.y - v0.y;
  503. var dz1:Number = v2.z - v0.z;
  504. var da2:Number = v1.x - v0.x;
  505. var db2:Number = v1.y - v0.y;
  506. var dz2:Number = v1.z - v0.z;
  507. var cx:Number = dz1*db2 - db1*dz2;
  508. var cy:Number = da1*dz2 - dz1*da2;
  509. var cz:Number = db1*da2 - da1*db2;
  510. var d:Number = 1/Math.sqrt(cx*cx + cy*cy + cz*cz);
  511. _normal0.x = _normal1.x = _normal2.x = cx*d;
  512. _normal0.y = _normal1.y = _normal2.y = cy*d;
  513. _normal0.z = _normal1.z = _normal2.z = cz*d;
  514. }
  515. private function getVectorsBounds():void
  516. {
  517. var i:uint;
  518. var v:Vector3D;
  519. switch (_plane) {
  520. case PLANE_XZ:
  521. _sortProp = "z";
  522. _loopProp = "x";
  523. for (i = 0; i < _vectors.length; ++i) {
  524. v = _vectors[i];
  525. if (v.x < _axis0Min)
  526. _axis0Min = v.x;
  527. if (v.x > _axis0Max)
  528. _axis0Max = v.x;
  529. if (v.z < _axis1Min)
  530. _axis1Min = v.z;
  531. if (v.z > _axis1Max)
  532. _axis1Max = v.z;
  533. }
  534. break;
  535. case PLANE_XY:
  536. _sortProp = "y";
  537. _loopProp = "x";
  538. for (i = 0; i < _vectors.length; ++i) {
  539. v = _vectors[i];
  540. if (v.x < _axis0Min)
  541. _axis0Min = v.x;
  542. if (v.x > _axis0Max)
  543. _axis0Max = v.x;
  544. if (v.y < _axis1Min)
  545. _axis1Min = v.y;
  546. if (v.y > _axis1Max)
  547. _axis1Max = v.y;
  548. }
  549. break;
  550. case PLANE_ZY:
  551. _sortProp = "y";
  552. _loopProp = "z";
  553. for (i = 0; i < _vectors.length; ++i) {
  554. v = _vectors[i];
  555. if (v.z < _axis0Min)
  556. _axis0Min = v.z;
  557. if (v.z > _axis0Max)
  558. _axis0Max = v.z;
  559. if (v.y < _axis1Min)
  560. _axis1Min = v.y;
  561. if (v.y > _axis1Max)
  562. _axis1Max = v.y;
  563. }
  564. }
  565. }
  566. /**
  567. * @inheritDoc
  568. */
  569. override public function get bounds():BoundingVolumeBase
  570. {
  571. if (_geomDirty)
  572. buildExtrude();
  573. return super.bounds;
  574. }
  575. /**
  576. * @inheritDoc
  577. */
  578. override public function get geometry():Geometry
  579. {
  580. if (_geomDirty)
  581. buildExtrude();
  582. return super.geometry;
  583. }
  584. /**
  585. * @inheritDoc
  586. */
  587. override public function get subMeshes():Vector.<SubMesh>
  588. {
  589. if (_geomDirty)
  590. buildExtrude();
  591. return super.subMeshes;
  592. }
  593. private function invalidateGeometry():void
  594. {
  595. _geomDirty = true;
  596. invalidateBounds();
  597. }
  598. private function circumCircle(xp:Number, yp:Number, x1:Number, y1:Number, x2:Number, y2:Number, x3:Number, y3:Number):Boolean
  599. {
  600. var m1:Number;
  601. var m2:Number;
  602. var mx1:Number;
  603. var mx2:Number;
  604. var my1:Number;
  605. var my2:Number;
  606. var da:Number;
  607. var db:Number;
  608. var rsqr:Number;
  609. var drsqr:Number;
  610. var xc:Number;
  611. var yc:Number;
  612. if (Math.abs(y1 - y2) < EPS && Math.abs(y2 - y3) < EPS)
  613. return false;
  614. if (Math.abs(y2 - y1) < EPS) {
  615. m2 = -(x3 - x2)/(y3 - y2);
  616. mx2 = (x2 + x3)*.5;
  617. my2 = (y2 + y3)*.5;
  618. xc = (x2 + x1)*.5;
  619. yc = m2*(xc - mx2) + my2;
  620. } else if (Math.abs(y3 - y2) < EPS) {
  621. m1 = -(x2 - x1)/(y2 - y1);
  622. mx1 = (x1 + x2)*.5;
  623. my1 = (y1 + y2)*.5;
  624. xc = (x3 + x2)*.5;
  625. yc = m1*(xc - mx1) + my1;
  626. } else {
  627. m1 = -(x2 - x1)/(y2 - y1);
  628. m2 = -(x3 - x2)/(y3 - y2);
  629. mx1 = (x1 + x2)*.5;
  630. mx2 = (x2 + x3)*.5;
  631. my1 = (y1 + y2)*.5;
  632. my2 = (y2 + y3)*.5;
  633. xc = (m1*mx1 - m2*mx2 + my2 - my1)/(m1 - m2);
  634. yc = m1*(xc - mx1) + my1;
  635. }
  636. da = x2 - xc;
  637. db = y2 - yc;
  638. rsqr = da*da + db*db;
  639. da = xp - xc;
  640. db = yp - yc;
  641. drsqr = da*da + db*db;
  642. _circle.x = xc;
  643. _circle.y = yc;
  644. _circle.z = Math.sqrt(rsqr);
  645. return Boolean(drsqr <= rsqr);
  646. }
  647. }
  648. }
  649. class Tri
  650. {
  651. public var v0:int;
  652. public var v1:int;
  653. public var v2:int;
  654. }
  655. class Edge
  656. {
  657. public var v0:int;
  658. public var v1:int;
  659. }