PageRenderTime 2496ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/sandy/as3/branches/3.0.2/src/sandy/core/data/Polygon.as

http://sandy.googlecode.com/
ActionScript | 713 lines | 387 code | 73 blank | 253 comment | 41 complexity | 293bf71ec57ddd52ebca126f40bc8468 MD5 | raw file
  1. /*
  2. # ***** BEGIN LICENSE BLOCK *****
  3. Copyright the original author Thomas PFEIFFER
  4. Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License");
  5. you may not use this file except in compliance with the License.
  6. You may obtain a copy of the License at
  7. http://www.mozilla.org/MPL/MPL-1.1.html
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. # ***** END LICENSE BLOCK *****
  14. */
  15. package sandy.core.data
  16. {
  17. import flash.display.Sprite;
  18. import flash.events.Event;
  19. import flash.events.KeyboardEvent;
  20. import flash.events.MouseEvent;
  21. import flash.geom.Matrix;
  22. import flash.geom.Point;
  23. import flash.geom.Rectangle;
  24. import flash.utils.Dictionary;
  25. import sandy.core.Scene3D;
  26. import sandy.core.interaction.VirtualMouse;
  27. import sandy.core.scenegraph.Geometry3D;
  28. import sandy.core.scenegraph.IDisplayable;
  29. import sandy.core.scenegraph.Shape3D;
  30. import sandy.events.BubbleEvent;
  31. import sandy.events.BubbleEventBroadcaster;
  32. import sandy.materials.Appearance;
  33. import sandy.math.IntersectionMath;
  34. import sandy.math.VectorMath;
  35. import sandy.view.Frustum;
  36. import sandy.events.Shape3DEvent;
  37. /**
  38. * Polygon's are the building blocks of visible 3D shapes.
  39. *
  40. * @author Thomas Pfeiffer - kiroukou
  41. * @author Mirek Mencel
  42. * @since 1.0
  43. * @version 3.0
  44. * @date 24.08.2007
  45. */
  46. public final class Polygon implements IDisplayable
  47. {
  48. // _______
  49. // STATICS_______________________________________________________
  50. private static var _ID_:uint = 0;
  51. /**
  52. * This property lists all the polygons.
  53. * This is an helping property since it allows to retrieve a polygon instance from its unique ID.
  54. * Polygon objects have an unique ID with myPolygon.id.
  55. * Using : Polygon.POLYGON_MAP[myPolygon.id] returns myPolygon (for sure this example has no interesst except showing the use of the property.
  56. */
  57. public static var POLYGON_MAP:Dictionary = new Dictionary(true);
  58. // ______
  59. // PUBLIC________________________________________________________
  60. /**
  61. * [READ-ONLY] property
  62. * Unique polygon ID Number.
  63. */
  64. public const id:uint = _ID_++;
  65. /**
  66. * [READ-ONLY] property.
  67. * Link to the Shape3D instance this polygon is related too.
  68. */
  69. public var shape:Shape3D;
  70. /**
  71. * [READ-ONLY] property.
  72. * Refers to the Scene3D the shape is linked to.
  73. */
  74. public var scene:Scene3D;
  75. /**
  76. * [READ-ONLY] property.
  77. * Specify if the polygon has been clipped
  78. */
  79. public var isClipped:Boolean = false;
  80. /**
  81. * [READ-ONLY] property.
  82. * Array of clipped vertices. Check isClipped property first to see if this array shall be containing the useful data or not.
  83. */
  84. public var cvertices:Array;
  85. /**
  86. * [READ-ONLY] property.
  87. * Array of original vertices.
  88. */
  89. public var vertices:Array;
  90. /**
  91. * [READ-ONLY] property.
  92. */
  93. public var vertexNormals:Array;
  94. /**
  95. * [READ-ONLY] property.
  96. */
  97. public var normal:Vertex;
  98. /**
  99. * [READ-ONLY] property.
  100. */
  101. public var aUVCoord:Array;
  102. /**
  103. * [READ-ONLY] property.
  104. */
  105. public var aEdges:Array;
  106. /**
  107. * [READ-ONLY] property.
  108. */
  109. public var caUVCoord:Array;
  110. /**
  111. * [READ-ONLY] property.
  112. * This property contains the texture bounds as a Rectangle.
  113. */
  114. public var uvBounds:Rectangle;
  115. /**
  116. * [READ-ONLY] property
  117. * Array of polygons that share an edge with the current polygon.
  118. */
  119. public var aNeighboors:Array = new Array();
  120. /**
  121. * Is this face visible?.
  122. * The method returns the visibility value pre computed after precompute method call. This getter shall be called afer the precompute call.
  123. * @return true if this face is visible, false otherwise.
  124. */
  125. public var visible:Boolean;
  126. public var minZ:Number;
  127. public var m_nDepth:Number;
  128. public var a:Vertex, b:Vertex, c:Vertex;
  129. /**
  130. * States if the appearance of the polygon has changed since the previous rendering.
  131. * Often used to update the scene material manager.
  132. * WARNING: Shall not be changed manually
  133. */
  134. public var hasAppearanceChanged:Boolean = false;
  135. /**
  136. * Creates a new polygon.
  137. *
  138. * @param p_oShape The shape this polygon belongs to
  139. * @param p_geometry The geometry this polygon is part of
  140. * @param p_aVertexID The vertexID array of this polygon
  141. * @param p_aUVCoordsID The UVCoordsID array of this polygon
  142. * @param p_nFaceNormalID The faceNormalID of this polygon
  143. * @param p_nEdgesID The edgesID of this polygon
  144. */
  145. public function Polygon( p_oOwner:Shape3D, p_geometry:Geometry3D, p_aVertexID:Array, p_aUVCoordsID:Array=null, p_nFaceNormalID:Number=0, p_nEdgesID:uint=0 )
  146. {
  147. shape = p_oOwner;
  148. m_oGeometry = p_geometry;
  149. // --
  150. __update( p_aVertexID, p_aUVCoordsID, p_nFaceNormalID, p_nEdgesID );
  151. m_oContainer = new Sprite();
  152. // --
  153. POLYGON_MAP[id] = this;
  154. }
  155. public function get depth():Number{ return m_nDepth; }
  156. public function set depth( p_nDepth:Number ):void{ m_nDepth = p_nDepth; }
  157. /**
  158. * The broadcaster property.
  159. *
  160. * <p>The broadcaster is the property used to send events to listeners.</p>
  161. */
  162. public function get broadcaster():BubbleEventBroadcaster
  163. {
  164. return m_oEB;
  165. }
  166. /**
  167. * Adds a listener for specifical event.
  168. *
  169. * @param p_sEvent Name of the Event.
  170. * @param oL Listener object.
  171. */
  172. public function addEventListener(p_sEvent:String, oL:*) : void
  173. {
  174. m_oEB.addEventListener.apply(m_oEB, arguments);
  175. }
  176. /**
  177. * Removes a listener for specifical event.
  178. *
  179. * @param p_sEvent Name of the Event.
  180. * @param oL Listener object.
  181. */
  182. public function removeEventListener(p_sEvent:String, oL:*) : void
  183. {
  184. m_oEB.removeEventListener(p_sEvent, oL);
  185. }
  186. /**
  187. * Pre-compute several properties of the polygon in the same time.
  188. * List of the computed properties :
  189. * <ul>
  190. * <li>minZ</li>
  191. * <li>visibility</li>
  192. * <li>depth</li>
  193. * </ul>
  194. */
  195. public function precompute():void
  196. {
  197. minZ = a.wz;
  198. if (b.wz < minZ) minZ = b.wz;
  199. // --
  200. if (c != null)
  201. {
  202. if (c.wz < minZ) minZ = c.wz;
  203. m_nDepth = 0.333*(a.wz+b.wz+c.wz);
  204. }
  205. else
  206. {
  207. m_nDepth = 0.5*(a.wz+b.wz);
  208. }
  209. }
  210. /**
  211. * Returns the real 3D position of the 2D screen position.
  212. * The 2D position is usually coming from :
  213. * <listing version="3.0">
  214. * var l_nClicX:Number = m_oScene.container.mouseX;
  215. * var l_nClicY:Number = m_oScene.container.mouseY;
  216. * </listing>
  217. *
  218. * @return the real 3D position which correspond to the intersection onto that polygone
  219. */
  220. public function get3DFrom2D( p_oScreenPoint:Point ):Vector
  221. {
  222. /// NEW CODE ADDED BY MAX with the help of makc ///
  223. var m1:Matrix= new Matrix(
  224. vertices[1].sx-vertices[0].sx,
  225. vertices[2].sx-vertices[0].sx,
  226. vertices[1].sy-vertices[0].sy,
  227. vertices[2].sy-vertices[0].sy,
  228. 0,
  229. 0);
  230. m1.invert();
  231. var capA:Number = m1.a *(p_oScreenPoint.x-vertices[0].sx) + m1.b * (p_oScreenPoint.y -vertices[0].sy);
  232. var capB:Number = m1.c *(p_oScreenPoint.x-vertices[0].sx) + m1.d * (p_oScreenPoint.y -vertices[0].sy);
  233. var l_oPoint:Vector = new Vector(
  234. vertices[0].x + capA*(vertices[1].x -vertices[0].x) + capB *(vertices[2].x - vertices[0].x),
  235. vertices[0].y + capA*(vertices[1].y -vertices[0].y) + capB *(vertices[2].y - vertices[0].y),
  236. vertices[0].z + capA*(vertices[1].z -vertices[0].z) + capB *(vertices[2].z - vertices[0].z)
  237. );
  238. // transform the vertex with the model Matrix
  239. this.shape.matrix.vectorMult( l_oPoint );
  240. return l_oPoint;
  241. }
  242. /**
  243. * Get the UVCoord under the 2D screen position after a mouse click or something
  244. * The 2D position is usually coming from :
  245. * <listing version="3.0">
  246. * var l_nClicX:Number = m_oScene.container.mouseX;
  247. * var l_nClicY:Number = m_oScene.container.mouseY;
  248. * </listing>
  249. *
  250. * @return the UVCoord under the 2D screen point
  251. */
  252. public function getUVFrom2D( p_oScreenPoint:Point ):UVCoord
  253. {
  254. var p0:Point = new Point(vertices[0].sx, vertices[0].sy);
  255. var p1:Point = new Point(vertices[1].sx, vertices[1].sy);
  256. var p2:Point = new Point(vertices[2].sx, vertices[2].sy);
  257. var u0:UVCoord = aUVCoord[0];
  258. var u1:UVCoord = aUVCoord[1];
  259. var u2:UVCoord = aUVCoord[2];
  260. var v01:Point = new Point(p1.x - p0.x, p1.y - p0.y );
  261. var vn01:Point = v01.clone();
  262. vn01.normalize(1);
  263. var v02:Point = new Point(p2.x - p0.x, p2.y - p0.y );
  264. var vn02:Point = v02.clone(); vn02.normalize(1);
  265. // sub that from click point
  266. var v4:Point = new Point( p_oScreenPoint.x - v01.x, p_oScreenPoint.y - v01.y );
  267. // we now have everything to find 1 intersection
  268. var l_oInter:Point = IntersectionMath.intersectionLine2D( p0, p2, p_oScreenPoint, v4 );
  269. // find vectors to intersection
  270. var vi02:Point = new Point( l_oInter.x - p0.x, l_oInter.y - p0.y );
  271. var vi01:Point = new Point( p_oScreenPoint.x - l_oInter.x , p_oScreenPoint.y - l_oInter.y );
  272. // interpolation coeffs
  273. var d1:Number = vi01.length / v01.length ;
  274. var d2:Number = vi02.length / v02.length;
  275. // -- on interpole linéairement pour trouver la position du point dans repere de la texture (normalisé)
  276. return new UVCoord( u0.u + d1*(u1.u - u0.u) + d2*(u2.u - u0.u),
  277. u0.v + d1*(u1.v - u0.v) + d2*(u2.v - u0.v));
  278. }
  279. /**
  280. * Returns an array containing the vertices, clipped by the camera frustum.
  281. *
  282. * @return The array of clipped vertices
  283. */
  284. public function clip( p_oFrustum:Frustum ):Array
  285. {
  286. isClipped = true;
  287. // For lines we only apply front plane clipping
  288. if( vertices.length < 3 )
  289. {
  290. clipFrontPlane( p_oFrustum );
  291. }
  292. else
  293. {
  294. cvertices = null;
  295. caUVCoord = null;
  296. // --
  297. cvertices = vertices.concat();
  298. caUVCoord = aUVCoord.concat();
  299. // --
  300. p_oFrustum.clipFrustum( cvertices, caUVCoord );
  301. }
  302. return cvertices;
  303. }
  304. /**
  305. * Perform a clipping against the near frustum plane.
  306. *
  307. * @return The array of clipped vertices
  308. */
  309. public function clipFrontPlane( p_oFrustum:Frustum ):Array
  310. {
  311. isClipped = true;
  312. cvertices = null;
  313. cvertices = vertices.concat();
  314. // If line
  315. if( vertices.length < 3 )
  316. {
  317. p_oFrustum.clipLineFrontPlane( cvertices );
  318. }
  319. else
  320. {
  321. caUVCoord = null;
  322. caUVCoord = aUVCoord.concat();
  323. p_oFrustum.clipFrontPlane( cvertices, caUVCoord );
  324. }
  325. return cvertices;
  326. }
  327. /**
  328. * Updates the vertices and normals for this polygon.
  329. *
  330. * <p>Calling this method make the polygon gets its vertice and normals by reference
  331. * instead of accessing them by their ID.<br/>
  332. * This method shall be called once the geometry created.</p>
  333. *
  334. * @param p_aVertexID The vertexID array of this polygon
  335. * @param p_aUVCoordsID The UVCoordsID array of this polygon
  336. * @param p_nFaceNormalID The faceNormalID of this polygon
  337. * @param p_nEdgesID The edgesID of this polygon
  338. */
  339. private function __update( p_aVertexID:Array, p_aUVCoordsID:Array, p_nFaceNormalID:uint, p_nEdgeListID:uint ):void
  340. {
  341. var i:int=0, l:int;
  342. // --
  343. vertexNormals = new Array();
  344. vertices = new Array();
  345. for each( var o:* in p_aVertexID )
  346. {
  347. vertices[i] = Vertex( m_oGeometry.aVertex[ p_aVertexID[i] ] );
  348. vertexNormals[i] = m_oGeometry.aVertexNormals[ p_aVertexID[i] ];
  349. i++;
  350. }
  351. // --
  352. a = vertices[0];
  353. b = vertices[1];
  354. c = vertices[2];
  355. // -- every polygon does not have some texture coordinates
  356. if( p_aUVCoordsID )
  357. {
  358. var l_nMinU:Number = Number.POSITIVE_INFINITY, l_nMinV:Number = Number.POSITIVE_INFINITY,
  359. l_nMaxU:Number = Number.NEGATIVE_INFINITY, l_nMaxV:Number = Number.NEGATIVE_INFINITY;
  360. // --
  361. aUVCoord = new Array();
  362. i = 0;
  363. for each( var p:* in p_aUVCoordsID )
  364. {
  365. var l_oUV:UVCoord = UVCoord( m_oGeometry.aUVCoords[ p_aUVCoordsID[i] ] );
  366. aUVCoord[i] = l_oUV;
  367. if( l_oUV.u < l_nMinU ) l_nMinU = l_oUV.u;
  368. else if( l_oUV.u > l_nMaxU ) l_nMaxU = l_oUV.u;
  369. // --
  370. if( l_oUV.v < l_nMinV ) l_nMinV = l_oUV.v;
  371. else if( l_oUV.v > l_nMaxV ) l_nMaxV = l_oUV.v;
  372. // --
  373. i++;
  374. }
  375. // --
  376. uvBounds = new Rectangle( l_nMinU, l_nMinV, l_nMaxU-l_nMinU, l_nMaxV-l_nMinV );
  377. }
  378. // --
  379. normal = Vertex( m_oGeometry.aFacesNormals[ p_nFaceNormalID ] );
  380. // If no normal has been given, we create it ourself.
  381. if( normal == null )
  382. {
  383. var l_oNormal:Vector = createNormal();
  384. var l_nID:Number = m_oGeometry.setFaceNormal( m_oGeometry.getNextFaceNormalID(), l_oNormal.x, l_oNormal.y, l_oNormal.z );
  385. normal = Vertex( m_oGeometry.aFacesNormals[ l_nID ] );
  386. }
  387. // --
  388. aEdges = new Array();
  389. for each( var l_nEdgeId:uint in m_oGeometry.aFaceEdges[p_nEdgeListID] )
  390. {
  391. var l_oEdge:Edge3D = m_oGeometry.aEdges[ l_nEdgeId ];
  392. l_oEdge.vertex1 = m_oGeometry.aVertex[ l_oEdge.vertexId1 ];
  393. l_oEdge.vertex2 = m_oGeometry.aVertex[ l_oEdge.vertexId2 ];
  394. aEdges.push( l_oEdge );
  395. }
  396. }
  397. /**
  398. * Clears the container of this polygon from graphics.
  399. */
  400. public function clear():void
  401. {
  402. m_oContainer.graphics.clear();
  403. }
  404. /**
  405. * Displays this polygon on its container if visible.
  406. *
  407. * @param p_oScene The current scene this polygon is rendered into
  408. * @param p_oContainer The container to draw on
  409. */
  410. public function display( p_oScene:Scene3D, p_oContainer:Sprite = null ):void
  411. {
  412. scene = p_oScene;
  413. // --
  414. const lCont:Sprite = (p_oContainer)?p_oContainer:m_oContainer;
  415. if( visible )
  416. {
  417. m_oAppearance.frontMaterial.renderPolygon( p_oScene, this, lCont );
  418. }
  419. else
  420. {
  421. m_oAppearance.backMaterial.renderPolygon( p_oScene, this, lCont );
  422. }
  423. }
  424. /**
  425. * The container for this polygon.
  426. */
  427. public function get container():Sprite
  428. {
  429. return m_oContainer;
  430. }
  431. /**
  432. * Returns a string representing of this polygon.
  433. *
  434. * @return The string representation.
  435. */
  436. public function toString():String
  437. {
  438. return "sandy.core.data.Polygon::id=" +id+ " [Points: " + vertices.length + "]";
  439. }
  440. /**
  441. * Enables or disables object events for this polygon.
  442. *
  443. * <p>If a value of true is passed, the object events onPress, onRollOver and onRollOut are enabled.<br />.
  444. * To use them, you have to add listeners for the events.</p>
  445. *
  446. * @param b Pass true to enable the events, false to disable.
  447. */
  448. public function set enableEvents( b:Boolean ):void
  449. {
  450. if( b && !mouseEvents )
  451. {
  452. container.addEventListener(MouseEvent.CLICK, _onInteraction);
  453. container.addEventListener(MouseEvent.MOUSE_UP, _onInteraction);
  454. container.addEventListener(MouseEvent.MOUSE_DOWN, _onInteraction);
  455. container.addEventListener(MouseEvent.ROLL_OVER, _onInteraction);
  456. container.addEventListener(MouseEvent.ROLL_OUT, _onInteraction);
  457. container.addEventListener(MouseEvent.DOUBLE_CLICK, _onInteraction);
  458. container.addEventListener(MouseEvent.MOUSE_MOVE, _onInteraction);
  459. container.addEventListener(MouseEvent.MOUSE_OVER, _onInteraction);
  460. container.addEventListener(MouseEvent.MOUSE_OUT, _onInteraction);
  461. container.addEventListener(MouseEvent.MOUSE_WHEEL, _onInteraction);
  462. }
  463. else if( !b && mouseEvents )
  464. {
  465. container.removeEventListener(MouseEvent.CLICK, _onInteraction);
  466. container.removeEventListener(MouseEvent.MOUSE_UP, _onInteraction);
  467. container.removeEventListener(MouseEvent.MOUSE_DOWN, _onInteraction);
  468. container.removeEventListener(MouseEvent.ROLL_OVER, _onInteraction);
  469. container.removeEventListener(MouseEvent.ROLL_OUT, _onInteraction);
  470. container.removeEventListener(MouseEvent.DOUBLE_CLICK, _onInteraction);
  471. container.removeEventListener(MouseEvent.MOUSE_MOVE, _onInteraction);
  472. container.removeEventListener(MouseEvent.MOUSE_OVER, _onInteraction);
  473. container.removeEventListener(MouseEvent.MOUSE_OUT, _onInteraction);
  474. container.removeEventListener(MouseEvent.MOUSE_WHEEL, _onInteraction);
  475. }
  476. mouseEvents = b;
  477. }
  478. public function get enableEvents():Boolean
  479. { return mouseEvents; }
  480. protected function _onInteraction( p_oEvt:Event ):void
  481. {
  482. var l_oClick:Point = new Point( m_oContainer.mouseX, m_oContainer.mouseY );
  483. var l_oUV:UVCoord = getUVFrom2D( l_oClick );
  484. var l_oPt3d:Vector = get3DFrom2D( l_oClick );
  485. m_oEB.broadcastEvent( new Shape3DEvent( p_oEvt.type, shape, this, l_oUV, l_oPt3d, p_oEvt ) );
  486. }
  487. protected function _startMouseInteraction( e : MouseEvent = null ) : void
  488. {
  489. container.addEventListener(MouseEvent.CLICK, _onTextureInteraction);
  490. container.addEventListener(MouseEvent.MOUSE_UP, _onTextureInteraction);
  491. container.addEventListener(MouseEvent.MOUSE_DOWN, _onTextureInteraction);
  492. container.addEventListener(MouseEvent.DOUBLE_CLICK, _onTextureInteraction);
  493. container.addEventListener(MouseEvent.MOUSE_MOVE, _onTextureInteraction);
  494. container.addEventListener(MouseEvent.MOUSE_OVER, _onTextureInteraction);
  495. container.addEventListener(MouseEvent.MOUSE_OUT, _onTextureInteraction);
  496. container.addEventListener(MouseEvent.MOUSE_WHEEL, _onTextureInteraction);
  497. container.addEventListener(KeyboardEvent.KEY_DOWN, _onTextureInteraction);
  498. container.addEventListener(KeyboardEvent.KEY_UP, _onTextureInteraction);
  499. m_oContainer.addEventListener( Event.ENTER_FRAME, _onTextureInteraction );
  500. }
  501. protected function _stopMouseInteraction( e : MouseEvent = null ) : void
  502. {
  503. container.removeEventListener(MouseEvent.CLICK, _onTextureInteraction);
  504. container.removeEventListener(MouseEvent.MOUSE_UP, _onTextureInteraction);
  505. container.removeEventListener(MouseEvent.MOUSE_DOWN, _onTextureInteraction);
  506. container.removeEventListener(MouseEvent.DOUBLE_CLICK, _onTextureInteraction);
  507. container.removeEventListener(MouseEvent.MOUSE_MOVE, _onTextureInteraction);
  508. container.removeEventListener(MouseEvent.MOUSE_OVER, _onTextureInteraction);
  509. container.removeEventListener(MouseEvent.MOUSE_OUT, _onTextureInteraction);
  510. container.removeEventListener(MouseEvent.MOUSE_WHEEL, _onTextureInteraction);
  511. m_oContainer.removeEventListener( Event.ENTER_FRAME, _onTextureInteraction );
  512. container.removeEventListener(KeyboardEvent.KEY_DOWN, _onTextureInteraction);
  513. container.removeEventListener(KeyboardEvent.KEY_UP, _onTextureInteraction);
  514. }
  515. public function set enableInteractivity( p_bState:Boolean ):void
  516. {
  517. if( p_bState != mouseInteractivity )
  518. {
  519. if( p_bState )
  520. {
  521. container.addEventListener( MouseEvent.ROLL_OVER, _startMouseInteraction, false );
  522. container.addEventListener( MouseEvent.ROLL_OUT, _stopMouseInteraction, false );
  523. }
  524. else
  525. {
  526. _stopMouseInteraction();
  527. }
  528. // --
  529. mouseInteractivity = p_bState;
  530. }
  531. }
  532. public function get enableInteractivity():Boolean
  533. { return mouseInteractivity; }
  534. protected function _onTextureInteraction( p_oEvt:Event = null ) : void
  535. {
  536. if ( p_oEvt == null || !(p_oEvt is MouseEvent) ) p_oEvt = new MouseEvent( MouseEvent.MOUSE_MOVE, true, false, 0, 0, null, false, false, false, false, 0);
  537. // get the position of the mouse on the poly
  538. var pt2D : Point = new Point( scene.container.mouseX, scene.container.mouseY );
  539. var uv : UVCoord = getUVFrom2D( pt2D );
  540. VirtualMouse.getInstance().interactWithTexture( this, uv, p_oEvt as MouseEvent );
  541. _onInteraction( p_oEvt );
  542. }
  543. /**
  544. * Calculates and returns the normal vector of the polygon.
  545. *
  546. * @return The normal vector
  547. */
  548. public function createNormal():Vector
  549. {
  550. if( vertices.length > 2 )
  551. {
  552. var v:Vector, w:Vector;
  553. var a:Vertex = vertices[0], b:Vertex = vertices[1], c:Vertex = vertices[2];
  554. v = new Vector( b.wx - a.wx, b.wy - a.wy, b.wz - a.wz );
  555. w = new Vector( b.wx - c.wx, b.wy - c.wy, b.wz - c.wz );
  556. // we compute de cross product
  557. var l_normal:Vector = VectorMath.cross( v, w );
  558. // we normalize the resulting vector
  559. VectorMath.normalize( l_normal ) ;
  560. // we return the resulting vertex
  561. return l_normal;
  562. }
  563. else
  564. {
  565. return new Vector();
  566. }
  567. }
  568. /**
  569. * The appearance of this polygon.
  570. */
  571. public function set appearance( p_oApp:Appearance ):void
  572. {
  573. if( scene )
  574. {
  575. if( scene.materialManager.isRegistered( m_oAppearance.frontMaterial ) )
  576. scene.materialManager.unregister( m_oAppearance.frontMaterial );
  577. if( scene.materialManager.isRegistered( m_oAppearance.backMaterial ) )
  578. scene.materialManager.unregister( m_oAppearance.backMaterial );
  579. }
  580. if( m_oAppearance )
  581. {
  582. p_oApp.frontMaterial.unlink( this );
  583. if( p_oApp.backMaterial != p_oApp.frontMaterial )
  584. p_oApp.backMaterial.unlink( this );
  585. }
  586. m_oAppearance = p_oApp;
  587. // --
  588. p_oApp.frontMaterial.init( this );
  589. if( p_oApp.backMaterial != p_oApp.frontMaterial )
  590. p_oApp.backMaterial.init( this );
  591. // --
  592. hasAppearanceChanged = true;
  593. }
  594. /**
  595. * @private
  596. */
  597. public function get appearance():Appearance
  598. {
  599. return m_oAppearance;
  600. }
  601. /**
  602. * Changes which side is the "normal" culling side.
  603. *
  604. * <p>The method also swaps the front and back skins.</p>
  605. */
  606. public function swapCulling():void
  607. {
  608. normal.negate();
  609. }
  610. /**
  611. * Destroys the sprite attache to this polygon.
  612. */
  613. public function destroy():void
  614. {
  615. clear();
  616. // --
  617. if( m_oContainer.parent ) m_oContainer.parent.removeChild( m_oContainer );
  618. if( m_oContainer ) m_oContainer = null;
  619. // --
  620. cvertices = null;
  621. vertices = null;
  622. m_oEB = null;
  623. // -- memory leak fix from nopmb on mediabox forums
  624. delete POLYGON_MAP[id];
  625. }
  626. // _______
  627. // PRIVATE_______________________________________________________
  628. /** Reference to its owner geometry */
  629. private var m_oGeometry:Geometry3D;
  630. private var m_oAppearance:Appearance;
  631. /** array of ID of uv coordinates in geometry object */
  632. private var m_aUVCoords:Array;
  633. protected var m_oContainer:Sprite;
  634. protected var m_oEB:BubbleEventBroadcaster = new BubbleEventBroadcaster();
  635. /** Boolean representing the state of the event activation */
  636. private var mouseEvents:Boolean = false;
  637. private var mouseInteractivity:Boolean = false;
  638. }
  639. }