/src/away3d/extrusions/LatheExtrude.as

http://github.com/away3d/away3d-core-fp11 · ActionScript · 1550 lines · 1179 code · 281 blank · 90 comment · 262 complexity · 2a0d8865febf486421fce403e35cc27e MD5 · raw file

  1. package 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.entities.Mesh;
  9. import away3d.materials.MaterialBase;
  10. import away3d.materials.utils.MultipleMaterials;
  11. import away3d.tools.helpers.MeshHelper;
  12. import flash.geom.Point;
  13. import flash.geom.Vector3D;
  14. /**
  15. * Class for generating meshes with axial symmetry such as donuts, pipes, vases etc.
  16. */
  17. public class LatheExtrude extends Mesh
  18. {
  19. private const EPS:Number = .0001;
  20. private const LIMIT:uint = 196605;
  21. private const MAXRAD:Number = 1.2;
  22. private var _profile:Vector.<Vector3D>;
  23. private var _lastProfile:Vector.<Vector3D>;
  24. private var _keepLastProfile:Boolean;
  25. private var _axis:String;
  26. private var _revolutions:Number;
  27. private var _subdivision:uint;
  28. private var _offsetRadius:Number;
  29. private var _prevOffsetRadius:Number = 0;
  30. private var _materials:MultipleMaterials;
  31. private var _coverAll:Boolean;
  32. private var _flip:Boolean;
  33. private var _centerMesh:Boolean;
  34. private var _thickness:Number;
  35. private var _preciseThickness:Boolean;
  36. private var _ignoreSides:String;
  37. private var _smoothSurface:Boolean;
  38. private var _tweek:Object;
  39. private var _varr:Vector.<Vector3D>;
  40. private var _varr2:Vector.<Vector3D>;
  41. private var _uvarr:Vector.<UV>;
  42. private var _startRotationOffset:Number = 0;
  43. private var _geomDirty:Boolean = true;
  44. private var _subGeometry:SubGeometry;
  45. private var _MaterialsSubGeometries:Vector.<SubGeometryList> = new Vector.<SubGeometryList>();
  46. private var _maxIndProfile:uint;
  47. private var _uva:UV;
  48. private var _uvb:UV;
  49. private var _uvc:UV;
  50. private var _uvd:UV;
  51. private var _va:Vector3D;
  52. private var _vb:Vector3D;
  53. private var _vc:Vector3D;
  54. private var _vd:Vector3D;
  55. private var _uvs:Vector.<Number>;
  56. private var _vertices:Vector.<Number>;
  57. private var _indices:Vector.<uint>;
  58. private var _normals:Vector.<Number>;
  59. private var _normalTmp:Vector3D;
  60. private var _normal0:Vector3D;
  61. private var _normal1:Vector3D;
  62. private var _normal2:Vector3D;
  63. public static const X_AXIS:String = "x";
  64. public static const Y_AXIS:String = "y";
  65. public static const Z_AXIS:String = "z";
  66. /**
  67. * Class LatheExtrude generates circular meshes such as donuts, pipes, pyramids etc.. from a series of Vector3D's
  68. *
  69. *@param material [optional] MaterialBase. The LatheExtrude (Mesh) material. Optional in constructor, material must be set before LatheExtrude object is render.
  70. * @param profile [optional] Vector.&lt;Vector3D&gt;. A series of Vector3D's representing the profile information to be repeated/rotated around a given axis.
  71. * @param axis [optional] String. The axis to rotate around: X_AXIS, Y_AXIS or Z_AXIS. Default is LatheExtrude.Y_AXIS.
  72. * @param revolutions [optional] Number. The LatheExtrude object can have less than one revolution, like 0.6 for a piechart or greater than 1 if a tweek object is passed. Minimum is 0.01. Default is 1.
  73. * @param subdivision [optional] uint. Howmany segments will compose the mesh in its rotational construction. Minimum is 3. Default is 10.
  74. * @param coverall [optional] Boolean. The way the uv mapping is spreaded across the shape. True covers an entire side of the geometry while false covers per segments. Default is true.
  75. * @param flip [optional] Boolean. If the faces must be reversed depending on Vector3D's orientation. Default is false.
  76. * @param thickness [optional] Number. If the shape must simulate a thickness. Default is 0.
  77. * @param preciseThickness [optional] Boolean. If the thickness must be repected along the entire volume profile. Default is true.
  78. * @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.
  79. * @param offsetRadius [optional] Number. An offset radius if the profile data is not to be updated but the radius expected to be different. Default is 0.
  80. * @param materials [optional] MultipleMaterials. Allows multiple material support when thickness is set higher to 1. Default is null.
  81. * properties as MaterialBase are: bottom, top, left, right, front and back.
  82. * @param ignoreSides [optional] String. To prevent the generation of sides if thickness is set higher than 0. To avoid the bottom ignoreSides = "bottom", avoiding both top and bottom: ignoreSides = "bottom, top". Strings options: bottom, top, left, right, front and back. Default is "".
  83. * @param tweek [optional] Object. To build springs like shapes, rotation must be higher than 1. Properties of the tweek object are x,y,z, radius and rotation. Default is null.
  84. * @param smoothSurface [optional] An optional Boolean. Defines if the surface of the mesh must be smoothed or not.
  85. */
  86. public function LatheExtrude(material:MaterialBase = null, profile:Vector.<Vector3D> = null, axis:String = LatheExtrude.Y_AXIS, revolutions:Number = 1, subdivision:uint = 10, coverall:Boolean = true, centerMesh:Boolean = false, flip:Boolean = false, thickness:Number = 0, preciseThickness:Boolean = true, offsetRadius:Number = 0, materials:MultipleMaterials = null, ignoreSides:String = "", tweek:Object = null, smoothSurface:Boolean = true)
  87. {
  88. var geom:Geometry = new Geometry();
  89. _subGeometry = new SubGeometry();
  90. if (!material && materials && materials.front)
  91. material = materials.front;
  92. super(geom, material);
  93. _profile = profile;
  94. _axis = axis;
  95. _revolutions = revolutions;
  96. _subdivision = (subdivision < 3)? 3 : subdivision;
  97. _offsetRadius = offsetRadius;
  98. _materials = materials;
  99. _coverAll = coverall;
  100. _flip = flip;
  101. _centerMesh = centerMesh;
  102. _thickness = Math.abs(thickness);
  103. _preciseThickness = preciseThickness;
  104. _ignoreSides = ignoreSides;
  105. _tweek = tweek;
  106. _smoothSurface = smoothSurface;
  107. }
  108. /*
  109. * A Vector.<Vector3D> representing the profile information to be repeated/rotated around a given axis.
  110. */
  111. public function get profile():Vector.<Vector3D>
  112. {
  113. return _profile;
  114. }
  115. public function set profile(val:Vector.<Vector3D>):void
  116. {
  117. if (val.length > 1) {
  118. _profile = val;
  119. invalidateGeometry();
  120. } else
  121. throw new Error("LatheExtrude error: the profile Vector.<Vector3D> must hold a mimimun of 2 vector3D's");
  122. }
  123. /*
  124. * A Number, to offset the original start angle of the rotation. Default is 0;
  125. */
  126. public function get startRotationOffset():Number
  127. {
  128. return _startRotationOffset;
  129. }
  130. public function set startRotationOffset(val:Number):void
  131. {
  132. _startRotationOffset = val;
  133. }
  134. /**
  135. * Defines the axis used for the lathe rotation. Defaults to "y".
  136. */
  137. public function get axis():String
  138. {
  139. return _axis;
  140. }
  141. public function set axis(val:String):void
  142. {
  143. if (_axis == val)
  144. return;
  145. _axis = val;
  146. invalidateGeometry();
  147. }
  148. /**
  149. * Defines the number of revolutions performed by the lathe extrusion. Defaults to 1.
  150. */
  151. public function get revolutions():Number
  152. {
  153. return _revolutions;
  154. }
  155. public function set revolutions(val:Number):void
  156. {
  157. if (_revolutions == val)
  158. return;
  159. _revolutions = (_revolutions > .001)? _revolutions : .001;
  160. _revolutions = val;
  161. invalidateGeometry();
  162. }
  163. /**
  164. * Defines the subdivisions created in the mesh for the total number of revolutions. Defaults to 2, minimum 2.
  165. *
  166. * @see #revolutions
  167. */
  168. public function get subdivision():uint
  169. {
  170. return _subdivision;
  171. }
  172. public function set subdivision(val:uint):void
  173. {
  174. val = (val < 3)? 3 : val;
  175. if (_subdivision == val)
  176. return;
  177. _subdivision = val;
  178. invalidateGeometry();
  179. }
  180. /**
  181. * Defines an offset radius applied to the profile. Defaults to 0.
  182. */
  183. public function get offsetRadius():Number
  184. {
  185. return _offsetRadius;
  186. }
  187. public function set offsetRadius(val:Number):void
  188. {
  189. if (_offsetRadius == val)
  190. return;
  191. _offsetRadius = val;
  192. invalidateGeometry();
  193. }
  194. /**
  195. * An optional object that defines left, right, front, back, top and bottom materials to be set on the resulting lathe extrusion.
  196. */
  197. public function get materials():MultipleMaterials
  198. {
  199. return _materials;
  200. }
  201. public function set materials(val:MultipleMaterials):void
  202. {
  203. _materials = val;
  204. if (_materials.front && this.material != _materials.front)
  205. this.material = _materials.front;
  206. invalidateGeometry();
  207. }
  208. /**
  209. * Defines if the texture(s) should be stretched to cover the entire mesh or per step between segments. Defaults to true.
  210. */
  211. public function get coverAll():Boolean
  212. {
  213. return _coverAll;
  214. }
  215. public function set coverAll(val:Boolean):void
  216. {
  217. if (_coverAll == val)
  218. return;
  219. _coverAll = val;
  220. invalidateGeometry();
  221. }
  222. /**
  223. * Defines if the generated faces should be inversed. Default false.
  224. */
  225. public function get flip():Boolean
  226. {
  227. return _flip;
  228. }
  229. public function set flip(val:Boolean):void
  230. {
  231. if (_flip == val)
  232. return;
  233. _flip = val;
  234. invalidateGeometry();
  235. }
  236. /**
  237. * Defines if the surface of the mesh must be smoothed or not.
  238. */
  239. public function get smoothSurface():Boolean
  240. {
  241. return _smoothSurface;
  242. }
  243. public function set smoothSurface(val:Boolean):void
  244. {
  245. if (_smoothSurface == val)
  246. return;
  247. _smoothSurface = val;
  248. _geomDirty = true;
  249. }
  250. /**
  251. * Defines if the last transformed profile values are saved or not. Useful in combo with rotations less than 1, to ease combinations with other extrusions classes such as SkinExtrude.
  252. */
  253. public function get keepLastProfile():Boolean
  254. {
  255. return _keepLastProfile;
  256. }
  257. public function set keepLastProfile(val:Boolean):void
  258. {
  259. if (_keepLastProfile == val)
  260. return;
  261. _keepLastProfile = val;
  262. }
  263. /**
  264. * returns the last rotated profile values, if keepLastProfile was true
  265. */
  266. public function get lastProfile():Vector.<Vector3D>
  267. {
  268. if (keepLastProfile && !_lastProfile)
  269. buildExtrude();
  270. return _lastProfile;
  271. }
  272. /**
  273. * Defines if thickness is greater than 0 if the thickness is equally distributed along the volume. Default is false.
  274. */
  275. public function get preciseThickness():Boolean
  276. {
  277. return _preciseThickness;
  278. }
  279. public function set preciseThickness(val:Boolean):void
  280. {
  281. if (_preciseThickness == val)
  282. return;
  283. _preciseThickness = val;
  284. invalidateGeometry();
  285. }
  286. /**
  287. * Defines whether the mesh is recentered of not after generation
  288. */
  289. public function get centerMesh():Boolean
  290. {
  291. return _centerMesh;
  292. }
  293. public function set centerMesh(val:Boolean):void
  294. {
  295. if (_centerMesh == val)
  296. return;
  297. _centerMesh = val;
  298. if (_centerMesh && _subGeometry.vertexData.length > 0)
  299. MeshHelper.recenter(this);
  300. else
  301. invalidateGeometry();
  302. }
  303. /**
  304. * Defines the thickness of the resulting lathed geometry. Defaults to 0 (single face).
  305. */
  306. public function get thickness():Number
  307. {
  308. return _thickness;
  309. }
  310. public function set thickness(val:Number):void
  311. {
  312. if (_thickness == val)
  313. return;
  314. _thickness = (val > 0)? val : _thickness;
  315. invalidateGeometry();
  316. }
  317. /**
  318. * Defines if the top, bottom, left, right, front or back of the the extrusion is left open.
  319. */
  320. public function get ignoreSides():String
  321. {
  322. return _ignoreSides;
  323. }
  324. public function set ignoreSides(val:String):void
  325. {
  326. _ignoreSides = val;
  327. invalidateGeometry();
  328. }
  329. /**
  330. * Allows the building of shapes such as springs. Rotation must be higher than 1 to have significant effect. Properties of the objects are x,y,z,radius and rotation
  331. */
  332. public function get tweek():Object
  333. {
  334. return _tweek;
  335. }
  336. public function set tweek(val:Object):void
  337. {
  338. _tweek = val;
  339. invalidateGeometry();
  340. }
  341. /**
  342. * @inheritDoc
  343. */
  344. override public function get bounds():BoundingVolumeBase
  345. {
  346. if (_geomDirty)
  347. buildExtrude();
  348. return super.bounds;
  349. }
  350. /**
  351. * @inheritDoc
  352. */
  353. override public function get geometry():Geometry
  354. {
  355. if (_geomDirty)
  356. buildExtrude();
  357. return super.geometry;
  358. }
  359. /**
  360. * @inheritDoc
  361. */
  362. override public function get subMeshes():Vector.<SubMesh>
  363. {
  364. if (_geomDirty)
  365. buildExtrude();
  366. return super.subMeshes;
  367. }
  368. private function closeTopBottom(ptLength:int, renderSide:RenderSide):void
  369. {
  370. var va:Vector3D;
  371. var vb:Vector3D;
  372. var vc:Vector3D;
  373. var vd:Vector3D;
  374. var i:uint;
  375. var j:uint;
  376. var a:Number;
  377. var b:Number;
  378. var total:uint = _varr.length - ptLength;
  379. _uva.u = _uvb.u = 0;
  380. _uvc.u = _uvd.u = 1;
  381. for (i = 0; i < total; i += ptLength) {
  382. if (i != 0) {
  383. if (_coverAll) {
  384. a = i/total;
  385. b = (i + ptLength)/total;
  386. _uva.v = a;
  387. _uvb.v = b;
  388. _uvc.v = b;
  389. _uvd.v = a;
  390. } else {
  391. _uva.v = 0;
  392. _uvb.v = 1;
  393. _uvc.v = 1;
  394. _uvd.v = 0;
  395. }
  396. if (renderSide.top) {
  397. va = _varr[i];
  398. vb = _varr[i + ptLength];
  399. vc = _varr2[i + ptLength];
  400. vd = _varr2[i];
  401. if (_flip) {
  402. addFace(vb, va, vc, _uvb, _uva, _uvc, 4);
  403. addFace(vc, va, vd, _uvc, _uva, _uvd, 4);
  404. } else {
  405. addFace(va, vb, vc, _uva, _uvb, _uvc, 4);
  406. addFace(va, vc, vd, _uva, _uvc, _uvd, 4);
  407. }
  408. }
  409. if (renderSide.bottom) {
  410. j = i + ptLength - 1;
  411. va = _varr[j];
  412. vb = _varr[j + ptLength];
  413. vc = _varr2[j + ptLength];
  414. vd = _varr2[j];
  415. if (_flip) {
  416. addFace(va, vb, vc, _uva, _uvb, _uvc, 5);
  417. addFace(va, vc, vd, _uva, _uvc, _uvd, 5);
  418. } else {
  419. addFace(vb, va, vc, _uvb, _uva, _uvc, 5);
  420. addFace(vc, va, vd, _uvc, _uva, _uvd, 5);
  421. }
  422. }
  423. }
  424. }
  425. }
  426. private function closeSides(ptLength:uint, renderSide:RenderSide):void
  427. {
  428. var va:Vector3D;
  429. var vb:Vector3D;
  430. var vc:Vector3D;
  431. var vd:Vector3D;
  432. var total:uint = _varr.length - ptLength;
  433. var i:uint;
  434. var j:uint;
  435. var a:Number;
  436. var b:Number;
  437. var iter:int = ptLength - 1;
  438. var step:Number = (_preciseThickness && ptLength%2 == 0)? 1/iter : 1/ptLength;
  439. for (i = 0; i < iter; ++i) {
  440. if (_coverAll) {
  441. a = i*step;
  442. b = a + step;
  443. _uva.v = 1 - a;
  444. _uvb.v = 1 - b;
  445. _uvc.v = 1 - b;
  446. _uvd.v = 1 - a;
  447. } else {
  448. _uva.v = 0;
  449. _uvb.v = 1;
  450. _uvc.v = 1;
  451. _uvd.v = 0;
  452. }
  453. if (renderSide.left) {
  454. va = _varr[i + 1];
  455. vb = _varr[i];
  456. vc = _varr2[i];
  457. vd = _varr2[i + 1];
  458. _uva.u = _uvb.u = 0;
  459. _uvc.u = _uvd.u = 1;
  460. if (_flip) {
  461. addFace(vb, va, vc, _uvb, _uva, _uvc, 2);
  462. addFace(vc, va, vd, _uvc, _uva, _uvd, 2);
  463. } else {
  464. addFace(va, vb, vc, _uva, _uvb, _uvc, 2);
  465. addFace(va, vc, vd, _uva, _uvc, _uvd, 2);
  466. }
  467. }
  468. if (renderSide.right) {
  469. j = total + i;
  470. va = _varr[j + 1];
  471. vb = _varr[j ];
  472. vc = _varr2[j];
  473. vd = _varr2[j + 1];
  474. _uva.u = _uvb.u = 1;
  475. _uvc.u = _uvd.u = 0;
  476. if (_flip) {
  477. addFace(va, vb, vc, _uva, _uvb, _uvc, 3);
  478. addFace(va, vc, vd, _uva, _uvc, _uvd, 3);
  479. } else {
  480. addFace(vb, va, vc, _uvb, _uva, _uvc, 3);
  481. addFace(vc, va, vd, _uvc, _uva, _uvd, 3);
  482. }
  483. }
  484. }
  485. }
  486. private function generate(vectors:Vector.<Vector3D>, axis:String, tweek:Object, render:Boolean = true, id:uint = 0):void
  487. {
  488. // TODO: not used
  489. axis = axis;
  490. if (!tweek)
  491. tweek = {};
  492. if (isNaN(tweek[X_AXIS]) || !tweek[X_AXIS])
  493. tweek[X_AXIS] = 0;
  494. if (isNaN(tweek[Y_AXIS]) || !tweek[Y_AXIS])
  495. tweek[Y_AXIS] = 0;
  496. if (isNaN(tweek[Z_AXIS]) || !tweek[Z_AXIS])
  497. tweek[Z_AXIS] = 0;
  498. if (isNaN(tweek["radius"]) || !tweek["radius"])
  499. tweek["radius"] = 0;
  500. var angle:Number = _startRotationOffset;
  501. var step:Number = 360/_subdivision;
  502. var j:uint;
  503. var tweekX:Number = 0;
  504. var tweekY:Number = 0;
  505. var tweekZ:Number = 0;
  506. var tweekradius:Number = 0;
  507. var tweekrotation:Number = 0;
  508. var tmpVecs:Vector.<Vector3D>;
  509. var aRads:Array = [];
  510. var uvu:Number;
  511. var uvv:Number;
  512. var i:uint;
  513. if (!_varr)
  514. _varr = new Vector.<Vector3D>();
  515. for (i = 0; i < vectors.length; ++i) {
  516. _varr.push(new Vector3D(vectors[i].x, vectors[i].y, vectors[i].z));
  517. _uvarr.push(new UV(0, 1%i));
  518. }
  519. var offsetradius:Number = -_offsetRadius;
  520. offsetradius += _prevOffsetRadius;
  521. var factor:Number = 0;
  522. var stepm:Number = 360*_revolutions;
  523. var lsub:Number = (_revolutions < 1)? _subdivision : _subdivision*_revolutions;
  524. if (_revolutions < 1)
  525. step *= _revolutions;
  526. for (i = 0; i <= lsub; ++i) {
  527. tmpVecs = new Vector.<Vector3D>();
  528. tmpVecs = vectors.concat();
  529. for (j = 0; j < tmpVecs.length; ++j) {
  530. factor = ((_revolutions - 1)/(_varr.length + 1));
  531. if (tweek[X_AXIS] != 0)
  532. tweekX += (tweek[X_AXIS]*factor)/_revolutions;
  533. if (tweek[Y_AXIS] != 0)
  534. tweekY += (tweek[Y_AXIS]*factor)/_revolutions;
  535. if (tweek[Z_AXIS] != 0)
  536. tweekZ += (tweek[Z_AXIS]*factor)/_revolutions;
  537. if (tweek.radius != 0)
  538. tweekradius += (tweek.radius/(_varr.length + 1));
  539. if (tweek.rotation != 0)
  540. tweekrotation += 360/(tweek.rotation*_subdivision);
  541. if (_axis == X_AXIS) {
  542. if (i == 0)
  543. aRads[j] = offsetradius - Math.abs(tmpVecs[j].z);
  544. tmpVecs[j].z = Math.cos(-angle/180*Math.PI)*(aRads[j] + tweekradius );
  545. tmpVecs[j].y = Math.sin(angle/180*Math.PI)*(aRads[j] + tweekradius );
  546. if (i == 0) {
  547. _varr[j].z += tmpVecs[j].z;
  548. _varr[j].y += tmpVecs[j].y;
  549. }
  550. } else if (_axis == Y_AXIS) {
  551. if (i == 0)
  552. aRads[j] = offsetradius - Math.abs(tmpVecs[j].x);
  553. tmpVecs[j].x = Math.cos(-angle/180*Math.PI)*(aRads[j] + tweekradius );
  554. tmpVecs[j].z = Math.sin(angle/180*Math.PI)*(aRads[j] + tweekradius );
  555. if (i == 0) {
  556. _varr[j].x = tmpVecs[j].x;
  557. _varr[j].z = tmpVecs[j].z;
  558. }
  559. } else {
  560. if (i == 0)
  561. aRads[j] = offsetradius - Math.abs(tmpVecs[j].y);
  562. tmpVecs[j].x = Math.cos(-angle/180*Math.PI)*(aRads[j] + tweekradius );
  563. tmpVecs[j].y = Math.sin(angle/180*Math.PI)*(aRads[j] + tweekradius );
  564. if (i == 0) {
  565. _varr[j].x = tmpVecs[j].x;
  566. _varr[j].y = tmpVecs[j].y;
  567. }
  568. }
  569. tmpVecs[j].x += tweekX;
  570. tmpVecs[j].y += tweekY;
  571. tmpVecs[j].z += tweekZ;
  572. _varr.push(new Vector3D(tmpVecs[j].x, tmpVecs[j].y, tmpVecs[j].z));
  573. if (_coverAll)
  574. uvu = angle/stepm;
  575. else
  576. uvu = (i%2 == 0)? 0 : 1;
  577. uvv = j/(_profile.length - 1);
  578. _uvarr.push(new UV(uvu, uvv));
  579. }
  580. angle += step;
  581. }
  582. _prevOffsetRadius = _offsetRadius;
  583. if (render) {
  584. var index:int;
  585. var inc:int = vectors.length;
  586. var loop:int = _varr.length - inc;
  587. var va:Vector3D;
  588. var vb:Vector3D;
  589. var vc:Vector3D;
  590. var vd:Vector3D;
  591. var uva:UV;
  592. var uvb:UV;
  593. var uvc:UV;
  594. var uvd:UV;
  595. var uvind:uint;
  596. var vind:uint;
  597. var iter:int = inc - 1;
  598. for (i = 0; i < loop; i += inc) {
  599. index = 0;
  600. for (j = 0; j < iter; ++j) {
  601. if (i > 0) {
  602. uvind = i + index;
  603. vind = uvind;
  604. uva = _uvarr[uvind + 1];
  605. uvb = _uvarr[uvind];
  606. uvc = _uvarr[uvind + inc];
  607. uvd = _uvarr[uvind + inc + 1];
  608. if (_revolutions == 1 && i + inc == loop && _tweek == null) {
  609. va = _varr[vind + 1];
  610. vb = _varr[vind];
  611. vc = _varr[vind + inc];
  612. vd = _varr[vind + inc + 1];
  613. } else {
  614. va = _varr[vind + 1];
  615. vb = _varr[vind];
  616. vc = _varr[vind + inc];
  617. vd = _varr[vind + inc + 1];
  618. }
  619. if (_flip) {
  620. if (id == 1) {
  621. _uva.u = 1 - uva.u;
  622. _uva.v = uva.v;
  623. _uvb.u = 1 - uvb.u;
  624. _uvb.v = uvb.v;
  625. _uvc.u = 1 - uvc.u;
  626. _uvc.v = uvc.v;
  627. _uvd.u = 1 - uvd.u;
  628. _uvd.v = uvd.v;
  629. addFace(va, vb, vc, _uva, _uvb, _uvc, id);
  630. addFace(va, vc, vd, _uva, _uvc, _uvd, id);
  631. } else {
  632. addFace(vb, va, vc, uvb, uva, uvc, id);
  633. addFace(vc, va, vd, uvc, uva, uvd, id);
  634. }
  635. } else {
  636. if (id == 1) {
  637. _uva.u = uva.u;
  638. _uva.v = 1 - uva.v;
  639. _uvb.u = uvb.u;
  640. _uvb.v = 1 - uvb.v;
  641. _uvc.u = uvc.u;
  642. _uvc.v = 1 - uvc.v;
  643. _uvd.u = uvd.u;
  644. _uvd.v = 1 - uvd.v;
  645. addFace(vb, va, vc, _uvb, _uva, _uvc, id);
  646. addFace(vc, va, vd, _uvc, _uva, _uvd, id);
  647. } else {
  648. addFace(va, vb, vc, uva, uvb, uvc, id);
  649. addFace(va, vc, vd, uva, uvc, uvd, id);
  650. }
  651. }
  652. }
  653. index++;
  654. }
  655. }
  656. }
  657. }
  658. private function buildExtrude():void
  659. {
  660. if (!_profile)
  661. throw new Error("LatheExtrude error: No profile Vector.<Vector3D> set");
  662. _MaterialsSubGeometries = null;
  663. _geomDirty = false;
  664. initHolders();
  665. _maxIndProfile = _profile.length*9;
  666. if (_profile.length > 1) {
  667. if (_thickness != 0) {
  668. var i:uint;
  669. var aListsides:Array = ["top", "bottom", "right", "left", "front", "back"];
  670. var renderSide:RenderSide = new RenderSide();
  671. for (i = 0; i < aListsides.length; ++i)
  672. renderSide[aListsides[i]] = (_ignoreSides.indexOf(aListsides[i]) == -1);
  673. _varr = new Vector.<Vector3D>();
  674. _varr2 = new Vector.<Vector3D>();
  675. if (_preciseThickness) {
  676. var prop1:String;
  677. var prop2:String;
  678. var prop3:String;
  679. switch (_axis) {
  680. case X_AXIS:
  681. prop1 = X_AXIS;
  682. prop2 = Z_AXIS;
  683. prop3 = Y_AXIS;
  684. break;
  685. case Y_AXIS:
  686. prop1 = Y_AXIS;
  687. prop2 = X_AXIS;
  688. prop3 = Z_AXIS;
  689. break;
  690. case Z_AXIS:
  691. prop1 = Z_AXIS;
  692. prop2 = Y_AXIS;
  693. prop3 = X_AXIS;
  694. }
  695. var lines:Array = buildThicknessPoints(_profile, thickness, prop1, prop2);
  696. var points:FourPoints;
  697. var vector:Vector3D;
  698. var vector2:Vector3D;
  699. var vector3:Vector3D;
  700. var vector4:Vector3D;
  701. var profileFront:Vector.<Vector3D> = new Vector.<Vector3D>();
  702. var profileBack:Vector.<Vector3D> = new Vector.<Vector3D>();
  703. for (i = 0; i < lines.length; ++i) {
  704. points = lines[i];
  705. vector = new Vector3D();
  706. vector2 = new Vector3D();
  707. if (i == 0) {
  708. vector[prop1] = points.pt2.x;
  709. vector[prop2] = points.pt2.y;
  710. vector[prop3] = _profile[0][prop3];
  711. profileFront.push(vector);
  712. vector2[prop1] = points.pt1.x;
  713. vector2[prop2] = points.pt1.y;
  714. vector2[prop3] = _profile[0][prop3];
  715. profileBack.push(vector2);
  716. if (lines.length == 1) {
  717. vector3 = new Vector3D();
  718. vector4 = new Vector3D();
  719. vector3[prop1] = points.pt4.x;
  720. vector3[prop2] = points.pt4.y;
  721. vector3[prop3] = _profile[0][prop3];
  722. profileFront.push(vector3);
  723. vector4[prop1] = points.pt3.x;
  724. vector4[prop2] = points.pt3.y;
  725. vector4[prop3] = _profile[0][prop3];
  726. profileBack.push(vector4);
  727. }
  728. } else if (i == lines.length - 1) {
  729. vector[prop1] = points.pt2.x;
  730. vector[prop2] = points.pt2.y;
  731. vector[prop3] = _profile[i][prop3];
  732. profileFront.push(vector);
  733. vector2[prop1] = points.pt1.x;
  734. vector2[prop2] = points.pt1.y;
  735. vector2[prop3] = _profile[i][prop3];
  736. profileBack.push(vector2);
  737. vector3 = new Vector3D();
  738. vector4 = new Vector3D();
  739. vector3[prop1] = points.pt4.x;
  740. vector3[prop2] = points.pt4.y;
  741. vector3[prop3] = _profile[i][prop3];
  742. profileFront.push(vector3);
  743. vector4[prop1] = points.pt3.x;
  744. vector4[prop2] = points.pt3.y;
  745. vector4[prop3] = _profile[i][prop3];
  746. profileBack.push(vector4);
  747. } else {
  748. vector[prop1] = points.pt2.x;
  749. vector[prop2] = points.pt2.y;
  750. vector[prop3] = _profile[i][prop3];
  751. profileFront.push(vector);
  752. vector2[prop1] = points.pt1.x;
  753. vector2[prop2] = points.pt1.y;
  754. vector2[prop3] = _profile[i][prop3];
  755. profileBack.push(vector2);
  756. }
  757. }
  758. generate(profileFront, _axis, _tweek, renderSide.front, 0);
  759. _varr2 = _varr2.concat(_varr);
  760. _varr = new Vector.<Vector3D>();
  761. generate(profileBack, _axis, _tweek, renderSide.back, 1);
  762. } else {
  763. // non distributed thickness
  764. var tmprofile1:Vector.<Vector3D> = new Vector.<Vector3D>();
  765. var tmprofile2:Vector.<Vector3D> = new Vector.<Vector3D>();
  766. var halft:Number = _thickness*.5;
  767. var val:Number;
  768. for (i = 0; i < _profile.length; ++i) {
  769. switch (_axis) {
  770. case X_AXIS:
  771. val = (_profile[i].z < 0)? halft : -halft;
  772. tmprofile1.push(new Vector3D(_profile[i].x, _profile[i].y, _profile[i].z - val));
  773. tmprofile2.push(new Vector3D(_profile[i].x, _profile[i].y, _profile[i].z + val));
  774. break;
  775. case Y_AXIS:
  776. val = (_profile[i].x < 0)? halft : -halft;
  777. tmprofile1.push(new Vector3D(_profile[i].x - val, _profile[i].y, _profile[i].z));
  778. tmprofile2.push(new Vector3D(_profile[i].x + val, _profile[i].y, _profile[i].z));
  779. break;
  780. case Z_AXIS:
  781. val = (_profile[i].y < 0)? halft : -halft;
  782. tmprofile1.push(new Vector3D(_profile[i].x, _profile[i].y - val, _profile[i].z));
  783. tmprofile2.push(new Vector3D(_profile[i].x, _profile[i].y + val, _profile[i].z));
  784. }
  785. }
  786. generate(tmprofile1, _axis, _tweek, renderSide.front, 0);
  787. _varr2 = _varr2.concat(_varr);
  788. _varr = new Vector.<Vector3D>();
  789. generate(tmprofile2, _axis, _tweek, renderSide.back, 1);
  790. }
  791. closeTopBottom(_profile.length, renderSide);
  792. if (_revolutions != 1)
  793. closeSides(_profile.length, renderSide);
  794. } else
  795. generate(_profile, _axis, _tweek);
  796. } else
  797. throw new Error("LatheExtrude error: the profile Vector.<Vector3D> must hold a mimimun of 2 vector3D's");
  798. if (_vertices.length > 0) {
  799. _subGeometry.updateVertexData(_vertices);
  800. _subGeometry.updateIndexData(_indices);
  801. _subGeometry.updateUVData(_uvs);
  802. if (_smoothSurface)
  803. _subGeometry.updateVertexNormalData(_normals);
  804. this.geometry.addSubGeometry(_subGeometry);
  805. }
  806. if (_MaterialsSubGeometries && _MaterialsSubGeometries.length > 0) {
  807. var sglist:SubGeometryList;
  808. var sg:SubGeometry;
  809. for (i = 1; i < 6; ++i) {
  810. sglist = _MaterialsSubGeometries[i];
  811. sg = sglist.subGeometry;
  812. if (sg && sglist.vertices.length > 0) {
  813. this.geometry.addSubGeometry(sg);
  814. this.subMeshes[this.subMeshes.length - 1].material = sglist.material;
  815. sg.updateVertexData(sglist.vertices);
  816. sg.updateIndexData(sglist.indices);
  817. sg.updateUVData(sglist.uvs);
  818. if (_smoothSurface)
  819. sg.updateVertexNormalData(sglist.normals);
  820. }
  821. }
  822. }
  823. if (_keepLastProfile)
  824. _lastProfile = _varr.splice(_varr.length - _profile.length, _profile.length);
  825. else
  826. _lastProfile = null;
  827. _varr = _varr2 = null;
  828. _uvarr = null;
  829. if (_centerMesh)
  830. MeshHelper.recenter(this);
  831. }
  832. private function calcNormal(v0:Vector3D, v1:Vector3D, v2:Vector3D):void
  833. {
  834. var dx1:Number = v2.x - v0.x;
  835. var dy1:Number = v2.y - v0.y;
  836. var dz1:Number = v2.z - v0.z;
  837. var dx2:Number = v1.x - v0.x;
  838. var dy2:Number = v1.y - v0.y;
  839. var dz2:Number = v1.z - v0.z;
  840. var cx:Number = dz1*dy2 - dy1*dz2;
  841. var cy:Number = dx1*dz2 - dz1*dx2;
  842. var cz:Number = dy1*dx2 - dx1*dy2;
  843. var d:Number = 1/Math.sqrt(cx*cx + cy*cy + cz*cz);
  844. _normal0.x = _normal1.x = _normal2.x = cx*d;
  845. _normal0.y = _normal1.y = _normal2.y = cy*d;
  846. _normal0.z = _normal1.z = _normal2.z = cz*d;
  847. }
  848. private function addFace(v0:Vector3D, v1:Vector3D, v2:Vector3D, uv0:UV, uv1:UV, uv2:UV, subGeomInd:uint):void
  849. {
  850. var subGeom:SubGeometry;
  851. var uvs:Vector.<Number>;
  852. var normals:Vector.<Number>;
  853. var vertices:Vector.<Number>;
  854. var indices:Vector.<uint>;
  855. if (subGeomInd > 0 && _MaterialsSubGeometries && _MaterialsSubGeometries.length > 0) {
  856. subGeom = _MaterialsSubGeometries[subGeomInd].subGeometry;
  857. uvs = _MaterialsSubGeometries[subGeomInd].uvs;
  858. vertices = _MaterialsSubGeometries[subGeomInd].vertices;
  859. indices = _MaterialsSubGeometries[subGeomInd].indices;
  860. normals = _MaterialsSubGeometries[subGeomInd].normals;
  861. } else {
  862. subGeom = _subGeometry;
  863. uvs = _uvs;
  864. vertices = _vertices;
  865. indices = _indices;
  866. normals = _normals;
  867. }
  868. if (vertices.length + 9 > LIMIT) {
  869. subGeom.updateVertexData(vertices);
  870. subGeom.updateIndexData(indices);
  871. subGeom.updateUVData(uvs);
  872. if (_smoothSurface)
  873. subGeom.updateVertexNormalData(normals);
  874. this.geometry.addSubGeometry(subGeom);
  875. if (subGeomInd > 0 && _MaterialsSubGeometries && _MaterialsSubGeometries[subGeomInd].subGeometry)
  876. this.subMeshes[this.subMeshes.length - 1].material = _MaterialsSubGeometries[subGeomInd].material;
  877. subGeom = new SubGeometry();
  878. subGeom.autoDeriveVertexTangents = true;
  879. if (_MaterialsSubGeometries && _MaterialsSubGeometries.length > 0) {
  880. _MaterialsSubGeometries[subGeomInd].subGeometry = subGeom;
  881. uvs = new Vector.<Number>();
  882. vertices = new Vector.<Number>();
  883. indices = new Vector.<uint>();
  884. normals = new Vector.<Number>();
  885. _MaterialsSubGeometries[subGeomInd].uvs = uvs;
  886. _MaterialsSubGeometries[subGeomInd].indices = indices;
  887. if (_smoothSurface)
  888. _MaterialsSubGeometries[subGeomInd].normals = normals;
  889. else
  890. subGeom.autoDeriveVertexNormals = true;
  891. if (subGeomInd == 0) {
  892. _subGeometry = subGeom;
  893. _uvs = uvs;
  894. _vertices = vertices;
  895. _indices = indices;
  896. _normals = normals;
  897. }
  898. } else {
  899. _subGeometry = subGeom;
  900. _uvs = new Vector.<Number>();
  901. _vertices = new Vector.<Number>();
  902. _indices = new Vector.<uint>();
  903. _normals = new Vector.<Number>();
  904. uvs = _uvs;
  905. vertices = _vertices;
  906. indices = _indices;
  907. normals = _normals;
  908. }
  909. }
  910. var bv0:Boolean;
  911. var bv1:Boolean;
  912. var bv2:Boolean;
  913. var ind0:uint;
  914. var ind1:uint;
  915. var ind2:uint;
  916. if (_smoothSurface) {
  917. var uvind:uint;
  918. var uvindV:uint;
  919. var vind:uint;
  920. var vindy:uint;
  921. var vindz:uint;
  922. var ind:uint;
  923. var indlength:uint = indices.length;
  924. calcNormal(v0, v1, v2);
  925. var ab:Number;
  926. if (indlength > 0) {
  927. var back:Number = indlength - _maxIndProfile;
  928. var limitBack:uint = (back < 0)? 0 : back;
  929. for (var i:uint = indlength - 1; i > limitBack; --i) {
  930. ind = indices[i];
  931. vind = ind*3;
  932. vindy = vind + 1;
  933. vindz = vind + 2;
  934. uvind = ind*2;
  935. uvindV = uvind + 1;
  936. if (bv0 && bv1 && bv2)
  937. break;
  938. if (!bv0 && vertices[vind] == v0.x && vertices[vindy] == v0.y && vertices[vindz] == v0.z) {
  939. _normalTmp.x = normals[vind];
  940. _normalTmp.y = normals[vindy];
  941. _normalTmp.z = normals[vindz];
  942. ab = Vector3D.angleBetween(_normalTmp, _normal0);
  943. if (ab < MAXRAD) {
  944. _normal0.x = (_normalTmp.x + _normal0.x)*.5;
  945. _normal0.y = (_normalTmp.y + _normal0.y)*.5;
  946. _normal0.z = (_normalTmp.z + _normal0.z)*.5;
  947. if (uvs[uvind] == uv0.u && uvs[uvindV] == uv0.v) {
  948. bv0 = true;
  949. ind0 = ind;
  950. continue;
  951. }
  952. }
  953. }
  954. if (!bv1 && vertices[vind] == v1.x && vertices[vindy] == v1.y && vertices[vindz] == v1.z) {
  955. _normalTmp.x = normals[vind];
  956. _normalTmp.y = normals[vindy];
  957. _normalTmp.z = normals[vindz];
  958. ab = Vector3D.angleBetween(_normalTmp, _normal1);
  959. if (ab < MAXRAD) {
  960. _normal1.x = (_normalTmp.x + _normal1.x)*.5;
  961. _normal1.y = (_normalTmp.y + _normal1.y)*.5;
  962. _normal1.z = (_normalTmp.z + _normal1.z)*.5;
  963. if (uvs[uvind] == uv1.u && uvs[uvindV] == uv1.v) {
  964. bv1 = true;
  965. ind1 = ind;
  966. continue;
  967. }
  968. }
  969. }
  970. if (!bv2 && vertices[vind] == v2.x && vertices[vindy] == v2.y && vertices[vindz] == v2.z) {
  971. _normalTmp.x = normals[vind];
  972. _normalTmp.y = normals[vindy];
  973. _normalTmp.z = normals[vindz];
  974. ab = Vector3D.angleBetween(_normalTmp, _normal2);
  975. if (ab < MAXRAD) {
  976. _normal2.x = (_normalTmp.x + _normal2.x)*.5;
  977. _normal2.y = (_normalTmp.y + _normal2.y)*.5;
  978. _normal2.z = (_normalTmp.z + _normal2.z)*.5;
  979. if (uvs[uvind] == uv2.u && uvs[uvindV] == uv2.v) {
  980. bv2 = true;
  981. ind2 = ind;
  982. continue;
  983. }
  984. }
  985. }
  986. }
  987. }
  988. }
  989. if (!bv0) {
  990. ind0 = vertices.length/3;
  991. vertices.push(v0.x, v0.y, v0.z);
  992. uvs.push(uv0.u, uv0.v);
  993. if (_smoothSurface)
  994. normals.push(_normal0.x, _normal0.y, _normal0.z);
  995. }
  996. if (!bv1) {
  997. ind1 = vertices.length/3;
  998. vertices.push(v1.x, v1.y, v1.z);
  999. uvs.push(uv1.u, uv1.v);
  1000. if (_smoothSurface)
  1001. normals.push(_normal1.x, _normal1.y, _normal1.z);
  1002. }
  1003. if (!bv2) {
  1004. ind2 = vertices.length/3;
  1005. vertices.push(v2.x, v2.y, v2.z);
  1006. uvs.push(uv2.u, uv2.v);
  1007. if (_smoothSurface)
  1008. normals.push(_normal2.x, _normal2.y, _normal2.z);
  1009. }
  1010. indices.push(ind0, ind1, ind2);
  1011. }
  1012. private function initHolders():void
  1013. {
  1014. _uvarr = new Vector.<UV>();
  1015. _uva = new UV(0, 0);
  1016. _uvb = new UV(0, 0);
  1017. _uvc = new UV(0, 0);
  1018. _uvd = new UV(0, 0);
  1019. _va = new Vector3D(0, 0, 0);
  1020. _vb = new Vector3D(0, 0, 0);
  1021. _vc = new Vector3D(0, 0, 0);
  1022. _vd = new Vector3D(0, 0, 0);
  1023. _uvs = new Vector.<Number>();
  1024. _vertices = new Vector.<Number>();
  1025. _indices = new Vector.<uint>();
  1026. _normals = new Vector.<Number>();
  1027. if (_smoothSurface) {
  1028. _normal0 = new Vector3D(0.0, 0.0, 0.0);
  1029. _normal1 = new Vector3D(0.0, 0.0, 0.0);
  1030. _normal2 = new Vector3D(0.0, 0.0, 0.0);
  1031. _normalTmp = new Vector3D(0.0, 0.0, 0.0);
  1032. } else
  1033. _subGeometry.autoDeriveVertexNormals = true;
  1034. _subGeometry.autoDeriveVertexTangents = true;
  1035. if (_materials && _thickness > 0)
  1036. initSubGeometryList();
  1037. }
  1038. private function buildThicknessPoints(aPoints:Vector.<Vector3D>, thickness:Number, prop1:String, prop2:String):Array
  1039. {
  1040. var anchors:Array = [];
  1041. var lines:Array = [];
  1042. var i:int;
  1043. for (i = 0; i < aPoints.length - 1; ++i) {
  1044. if (aPoints[i][prop1] == 0 && aPoints[i][prop2] == 0)
  1045. aPoints[i][prop1] = EPS;
  1046. if (aPoints[i + 1][prop2] != null && aPoints[i][prop2] == aPoints[i + 1][prop2])
  1047. aPoints[i + 1][prop2] += EPS;
  1048. if (aPoints[i][prop1] != null && aPoints[i][prop1] == aPoints[i + 1][prop1])
  1049. aPoints[i + 1][prop1] += EPS;
  1050. anchors.push(defineAnchors(aPoints[i], aPoints[i + 1], thickness, prop1, prop2));
  1051. }
  1052. var totallength:int = anchors.length;
  1053. var pointResult:FourPoints;
  1054. if (totallength > 1) {
  1055. for (i = 0; i < totallength; ++i) {
  1056. if (i < totallength)
  1057. pointResult = defineLines(i, anchors[i], anchors[i + 1], lines);
  1058. else
  1059. pointResult = defineLines(i, anchors[i], anchors[i - 1], lines);
  1060. if (pointResult != null)
  1061. lines.push(pointResult);
  1062. }
  1063. } else {
  1064. var fourPoints:FourPoints = new FourPoints();
  1065. var anchorFP:FourPoints = anchors[0];
  1066. fourPoints.pt1 = anchorFP.pt1;
  1067. fourPoints.pt2 = anchorFP.pt2;
  1068. fourPoints.pt3 = anchorFP.pt3;
  1069. fourPoints.pt4 = anchorFP.pt4;
  1070. lines = [fourPoints];
  1071. }
  1072. return lines;
  1073. }
  1074. private function defineLines(index:int, point1:FourPoints, point2:FourPoints = null, lines:Array = null):FourPoints
  1075. {
  1076. var tmppt:FourPoints;
  1077. var fourPoints:FourPoints = new FourPoints();
  1078. if (point2 == null) {
  1079. tmppt = lines[index - 1];
  1080. fourPoints.pt1 = tmppt.pt3;
  1081. fourPoints.pt2 = tmppt.pt4;
  1082. fourPoints.pt3 = point1.pt3;
  1083. fourPoints.pt4 = point1.pt4;
  1084. return fourPoints;
  1085. }
  1086. var line1:Line = buildObjectLine(point1.pt1.x, point1.pt1.y, point1.pt3.x, point1.pt3.y);
  1087. var line2:Line = buildObjectLine(point1.pt2.x, point1.pt2.y, point1.pt4.x, point1.pt4.y);
  1088. var line3:Line = buildObjectLine(point2.pt1.x, point2.pt1.y, point2.pt3.x, point2.pt3.y);
  1089. var line4:Line = buildObjectLine(point2.pt2.x, point2.pt2.y, point2.pt4.x, point2.pt4.y);
  1090. var cross1:Point = lineIntersect(line3, line1);
  1091. var cross2:Point = lineIntersect(line2, line4);
  1092. if (cross1 != null && cross2 != null) {
  1093. if (index == 0) {
  1094. fourPoints.pt1 = point1.pt1;
  1095. fourPoints.pt2 = point1.pt2;
  1096. fourPoints.pt3 = cross1;
  1097. fourPoints.pt4 = cross2;
  1098. return fourPoints;
  1099. }
  1100. tmppt = lines[index - 1];
  1101. fourPoints.pt1 = tmppt.pt3;
  1102. fourPoints.pt2 = tmppt.pt4;
  1103. fourPoints.pt3 = cross1;
  1104. fourPoints.pt4 = cross2;
  1105. return fourPoints;
  1106. } else
  1107. return null;
  1108. }
  1109. private function defineAnchors(base:Vector3D, baseEnd:Vector3D, thickness:Number, prop1:String, prop2:String):FourPoints
  1110. {
  1111. var angle:Number = (Math.atan2(base[prop2] - baseEnd[prop2], base[prop1] - baseEnd[prop1])*180)/Math.PI;
  1112. angle -= 270;
  1113. var angle2:Number = angle + 180;
  1114. var fourPoints:FourPoints = new FourPoints();
  1115. fourPoints.pt1 = new Point(base[prop1], base[prop2]);
  1116. fourPoints.pt2 = new Point(base[prop1], base[prop2]);
  1117. fourPoints.pt3 = new Point(baseEnd[prop1], baseEnd[prop2]);
  1118. fourPoints.pt4 = new Point(baseEnd[prop1], baseEnd[prop2]);
  1119. var radius:Number = thickness*.5;
  1120. fourPoints.pt1.x = fourPoints.pt1.x + Math.cos(-angle/180*Math.PI)*radius;
  1121. fourPoints.pt1.y = fourPoints.pt1.y + Math.sin(angle/180*Math.PI)*radius;
  1122. fourPoints.pt2.x = fourPoints.pt2.x + Math.cos(-angle2/180*Math.PI)*radius;
  1123. fourPoints.pt2.y = fourPoints.pt2.y + Math.sin(angle2/180*Math.PI)*radius;
  1124. fourPoints.pt3.x = fourPoints.pt3.x + Math.cos(-angle/180*Math.PI)*radius;
  1125. fourPoints.pt3.y = fourPoints.pt3.y + Math.sin(angle/180*Math.PI)*radius;
  1126. fourPoints.pt4.x = fourPoints.pt4.x + Math.cos(-angle2/180*Math.PI)*radius;
  1127. fourPoints.pt4.y = fourPoints.pt4.y + Math.sin(angle2/180*Math.PI)*radius;
  1128. return fourPoints;
  1129. }
  1130. private function buildObjectLine(origX:Number, origY:Number, endX:Number, endY:Number):Line
  1131. {
  1132. var line:Line = new Line();
  1133. line.ax = origX;
  1134. line.ay = origY;
  1135. line.bx = endX - origX;
  1136. line.by = endY - origY;
  1137. return line;
  1138. }
  1139. private function lineIntersect(Line1:Line, Line2:Line):Point
  1140. {
  1141. Line1.bx = (Line1.bx == 0)? EPS : Line1.bx;
  1142. Line2.bx = (Line2.bx == 0)? EPS : Line2.bx;
  1143. var a1:Number = Line1.by/Line1.bx;
  1144. var b1:Number = Line1.ay - a1*Line1.ax;
  1145. var a2:Number = Line2.by/Line2.bx;
  1146. var b2:Number = Line2.ay - a2*Line2.ax;
  1147. var nzero:Number = ((a1 - a2) == 0)? EPS : a1 - a2;
  1148. var ptx:Number = ( b2 - b1 )/(nzero);
  1149. var pty:Number = a1*ptx + b1;
  1150. if (isFinite(ptx) && isFinite(pty))
  1151. return new Point(ptx, pty);
  1152. else {
  1153. trace("infinity");
  1154. return null;
  1155. }
  1156. }
  1157. /**
  1158. * Invalidates the geometry, causing it to be rebuilded when requested.
  1159. */
  1160. private function invalidateGeometry():void
  1161. {
  1162. _geomDirty = true;
  1163. invalidateBounds();
  1164. }
  1165. private function initSubGeometryList():void
  1166. {
  1167. var i:uint;
  1168. var sglist:SubGeometryList;
  1169. if (!_MaterialsSubGeometries)
  1170. _MaterialsSubGeometries = new Vector.<SubGeometryList>();
  1171. for (i = 0; i < 6; ++i) {
  1172. sglist = new SubGeometryList();
  1173. _MaterialsSubGeometries.push(sglist);
  1174. sglist.id = i;
  1175. if (i == 0) {
  1176. sglist.subGeometry = _subGeometry;
  1177. sglist.uvs = _uvs;
  1178. sglist.vertices = _vertices;
  1179. sglist.indices = _indices;
  1180. sglist.normals = _normals;
  1181. } else {
  1182. sglist.uvs = new Vector.<Number>();
  1183. sglist.vertices = new Vector.<Number>();
  1184. sglist.indices = new Vector.<uint>();
  1185. sglist.normals = new Vector.<Number>();
  1186. }
  1187. }
  1188. var sg:SubGeometry;
  1189. var prop:String;
  1190. for (i = 1; i < 6; ++i) {
  1191. switch (i) {
  1192. case 1:
  1193. prop = "back";
  1194. break;
  1195. case 2:
  1196. prop = "left";
  1197. break;
  1198. case 3:
  1199. prop = "right";
  1200. break;
  1201. case 4:
  1202. prop = "top";
  1203. break;
  1204. case 5:
  1205. prop = "bottom";
  1206. break;
  1207. default:
  1208. prop = "front";
  1209. }
  1210. if (_materials[prop] && _MaterialsSubGeometries[i].subGeometry == null) {
  1211. sglist = _MaterialsSubGeometries[i];
  1212. sg = new SubGeometry();
  1213. sglist.material = _materials[prop];
  1214. sglist.subGeometry = sg;
  1215. sg.autoDeriveVertexNormals = true;
  1216. sg.autoDeriveVertexTangents = true;
  1217. }
  1218. }
  1219. }
  1220. }
  1221. }
  1222. import away3d.core.base.SubGeometry;
  1223. import away3d.materials.MaterialBase;
  1224. import flash.geom.Point;
  1225. class SubGeometryList
  1226. {
  1227. public var id:uint;
  1228. public var uvs:Vector.<Number>;
  1229. public var vertices:Vector.<Number>;
  1230. public var normals:Vector.<Number>;
  1231. public var indices:Vector.<uint>;
  1232. public var subGeometry:SubGeometry;
  1233. public var material:MaterialBase;
  1234. public function SubGeometryList()
  1235. {
  1236. }
  1237. }
  1238. class RenderSide
  1239. {
  1240. public var top:Boolean;
  1241. public var bottom:Boolean;
  1242. public var right:Boolean;
  1243. public var left:Boolean;
  1244. public var front:Boolean;
  1245. public var back:Boolean;
  1246. public function RenderSide()
  1247. {
  1248. }
  1249. }
  1250. class Line
  1251. {
  1252. public var ax:Number;
  1253. public var ay:Number;
  1254. public var bx:Number;
  1255. public var by:Number;
  1256. public function Line()
  1257. {
  1258. }
  1259. }
  1260. class FourPoints
  1261. {
  1262. public var pt1:Point;
  1263. public var pt2:Point;
  1264. public var pt3:Point;
  1265. public var pt4:Point;
  1266. public function FourPoints()
  1267. {
  1268. }
  1269. }