PageRenderTime 4259ms CodeModel.GetById 43ms RepoModel.GetById 7ms app.codeStats 0ms

/sandy/haxe/tags/3.0.2/src/sandy/core/data/Polygon.hx

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