PageRenderTime 220ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/resources/Papervision3D_2.0.883/org/papervision3d/view/Viewport3D.as

https://github.com/nunomorgadinho/Calamity
ActionScript | 562 lines | 349 code | 61 blank | 152 comment | 37 complexity | f5880673c8f1dc3cfbbde96ddab42622 MD5 | raw file
  1. package org.papervision3d.view
  2. {
  3. import flash.display.Sprite;
  4. import flash.display.StageAlign;
  5. import flash.display.StageScaleMode;
  6. import flash.events.Event;
  7. import flash.geom.Point;
  8. import flash.geom.Rectangle;
  9. import flash.utils.Dictionary;
  10. import org.papervision3d.core.culling.DefaultLineCuller;
  11. import org.papervision3d.core.culling.DefaultParticleCuller;
  12. import org.papervision3d.core.culling.DefaultTriangleCuller;
  13. import org.papervision3d.core.culling.ILineCuller;
  14. import org.papervision3d.core.culling.IParticleCuller;
  15. import org.papervision3d.core.culling.ITriangleCuller;
  16. import org.papervision3d.core.culling.RectangleLineCuller;
  17. import org.papervision3d.core.culling.RectangleParticleCuller;
  18. import org.papervision3d.core.culling.RectangleTriangleCuller;
  19. import org.papervision3d.core.culling.ViewportObjectFilter;
  20. import org.papervision3d.core.geom.renderables.Triangle3D;
  21. import org.papervision3d.core.log.PaperLogger;
  22. import org.papervision3d.core.render.IRenderEngine;
  23. import org.papervision3d.core.render.command.IRenderListItem;
  24. import org.papervision3d.core.render.command.RenderableListItem;
  25. import org.papervision3d.core.render.data.RenderHitData;
  26. import org.papervision3d.core.render.data.RenderSessionData;
  27. import org.papervision3d.core.utils.InteractiveSceneManager;
  28. import org.papervision3d.core.view.IViewport3D;
  29. import org.papervision3d.objects.DisplayObject3D;
  30. import org.papervision3d.view.layer.ViewportBaseLayer;
  31. import org.papervision3d.view.layer.ViewportLayer;
  32. /**
  33. * @Author Ralph Hauwert
  34. */
  35. /* Changed to protected methods on 11/27/2007 by John */
  36. /* Added LineCulling on 22 May 08 by Seb Lee-Delisle */
  37. public class Viewport3D extends Sprite implements IViewport3D
  38. {
  39. //use namespace org.papervision3d.core.ns.pv3dview;
  40. /** @private */
  41. protected var _width:Number;
  42. /** @private */
  43. protected var _hWidth:Number;
  44. /** @private */
  45. protected var _height:Number;
  46. /** @private */
  47. protected var _hHeight:Number;
  48. /** @private */
  49. protected var _autoClipping:Boolean;
  50. /** @private */
  51. protected var _autoCulling:Boolean;
  52. /** @private */
  53. protected var _autoScaleToStage:Boolean;
  54. /** @private */
  55. protected var _interactive:Boolean;
  56. /** @private */
  57. protected var _lastRenderer:IRenderEngine;
  58. /** @private */
  59. protected var _viewportObjectFilter:ViewportObjectFilter;
  60. /** @private */
  61. protected var _containerSprite:ViewportBaseLayer;
  62. /** @private */
  63. protected var _layerInstances:Dictionary;
  64. /**
  65. * sizeRectangle stores the width and the height of the Viewport3D sprite
  66. * @see #viewportWidth
  67. * @see #viewportHeight
  68. */
  69. public var sizeRectangle:Rectangle;
  70. /**
  71. * cullingRectangle stores the width, height, x, y of the culling rectangle. It's used to determine the bounds in which the triangles are drawn.
  72. * @see #autoCulling
  73. */
  74. public var cullingRectangle:Rectangle;
  75. /**
  76. * triangleCuller uses the cullingRectangle to determine which triangles will not be rendered in BasicRenderEngine
  77. * @see #autoCulling
  78. */
  79. public var triangleCuller:ITriangleCuller;
  80. /**
  81. * particleCuller uses the cullingRectangle to determine which particles will not be rendered in BasicRenderEngine
  82. * @see #autoCulling
  83. */
  84. public var particleCuller:IParticleCuller;
  85. /**
  86. * lineCuller uses the culling Rectangle to determine which particles will not be rendered in BasicRenderEngine
  87. * @see #autoCulling
  88. */
  89. public var lineCuller:ILineCuller;
  90. /**
  91. * lastRenderList stores RenderableListItems (Triangles, Lines, Pixels, Particles, Fog) of everything that was rendered in the last pass. This list is used to determine hitTests in hitTestPoint2D.
  92. * @see #hitTestPoint2D()
  93. */
  94. public var lastRenderList:Array;
  95. /**
  96. * interactiveSceneManager manages the interaction between the user's mouse and the Papervision3D scene. This is done by checking the mouse against renderHitData. renderHitData is generated from hitTestPoint2D and passed into the interactiveSceneManager to check agains the various mouse actions.
  97. * @see #hitTestPoint2D()
  98. * @see org.papervision3d.core.utils.InteractiveSceneManager#renderHitData
  99. */
  100. public var interactiveSceneManager:InteractiveSceneManager;
  101. /** @private */
  102. protected var renderHitData:RenderHitData;
  103. private var stageScaleModeSet :Boolean = false;
  104. /**
  105. * @param viewportWidth Width of the viewport
  106. * @param viewportHeight Height of the viewport
  107. * @param autoScaleToStage Determines whether the viewport should resize when the stage resizes
  108. * @param interactive Determines whether the viewport should listen for Mouse events by creating an <code>InteractiveSceneManager</code>
  109. * @param autoClipping Determines whether DisplayObject3Ds outside the rectangle of the viewport should be rendered
  110. * @param autoCulling Detemines whether only the objects in front of the camera should be rendered. In other words, if a triangle is hidden by another triangle from the camera, it will not be rendered.
  111. */
  112. public function Viewport3D(viewportWidth:Number = 640, viewportHeight:Number = 480, autoScaleToStage:Boolean = false, interactive:Boolean = false, autoClipping:Boolean = true, autoCulling:Boolean = true)
  113. {
  114. super();
  115. init();
  116. this.interactive = interactive;
  117. this.viewportWidth = viewportWidth;
  118. this.viewportHeight = viewportHeight;
  119. this.autoClipping = autoClipping;
  120. this.autoCulling = autoCulling;
  121. this.autoScaleToStage = autoScaleToStage;
  122. this._layerInstances = new Dictionary(true);
  123. }
  124. /**
  125. * Removes all references and sets the viewport's
  126. * InteractiveSceneManager to null for a future
  127. * garbage collection sweep
  128. */
  129. public function destroy():void
  130. {
  131. if(interactiveSceneManager)
  132. {
  133. interactiveSceneManager.destroy();
  134. interactiveSceneManager = null;
  135. }
  136. lastRenderList = null;
  137. }
  138. /**
  139. * @private
  140. */
  141. protected function init():void
  142. {
  143. this.renderHitData = new RenderHitData();
  144. lastRenderList = new Array();
  145. sizeRectangle = new Rectangle();
  146. cullingRectangle = new Rectangle();
  147. _containerSprite = new ViewportBaseLayer(this);
  148. _containerSprite.doubleClickEnabled = true;
  149. addChild(_containerSprite);
  150. addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
  151. addEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage);
  152. }
  153. /**
  154. * Checks the Mouse x and y against the <code>RenderHitData</code>
  155. * @return RenderHitData of the current mouse location
  156. */
  157. public function hitTestMouse():RenderHitData
  158. {
  159. var p:Point = new Point(containerSprite.mouseX, containerSprite.mouseY);
  160. return hitTestPoint2D(p);
  161. }
  162. /**
  163. * Checks a <code>Point</code> against the <code>RenderHitData</code>
  164. * of the viewport
  165. * @param point a 2d <code>Point</code> you want to analyze into 3d space
  166. * @return <code>RenderHitData</code> of the given <code>Point</code>
  167. */
  168. public function hitTestPoint2D(point:Point):RenderHitData
  169. {
  170. renderHitData.clear();
  171. if(interactive)
  172. {
  173. var rli:RenderableListItem;
  174. var rhd:RenderHitData = renderHitData;
  175. var rc:IRenderListItem;
  176. for(var i:uint = lastRenderList.length;rc = lastRenderList[--i]; )
  177. {
  178. if(rc is RenderableListItem)
  179. {
  180. rli = rc as RenderableListItem;
  181. rhd = rli.hitTestPoint2D(point, rhd);
  182. if(rhd.hasHit)
  183. {
  184. return rhd;
  185. }
  186. }
  187. }
  188. }
  189. return renderHitData;
  190. }
  191. public function hitTestPointObject(point:Point, object:DisplayObject3D):RenderHitData
  192. {
  193. if(interactive){
  194. var rli:RenderableListItem;
  195. var rhd:RenderHitData = new RenderHitData();
  196. var rc:IRenderListItem;
  197. for(var i:uint = lastRenderList.length; rc = lastRenderList[--i]; )
  198. {
  199. if(rc is RenderableListItem)
  200. {
  201. rli = rc as RenderableListItem;
  202. if(rli.renderableInstance is Triangle3D){
  203. if(Triangle3D(rli.renderableInstance).instance != object)
  204. continue;
  205. }else{
  206. continue;
  207. }
  208. rhd = rli.hitTestPoint2D(point, rhd);
  209. if(rhd.hasHit)
  210. {
  211. return rhd;
  212. }
  213. }
  214. }
  215. }
  216. return new RenderHitData();
  217. }
  218. /**
  219. * Creates or receives a <code>ViewportLayer</code> of the given <code>DisplayObject3D</code>
  220. * @param do3d A <code>DisplayObject3D</code> used to either find the layer or create a new one
  221. * @param createNew Forces the creation of a new layer
  222. * @param recurse Adds the <code>DisplayObject3D</code> as well as all of its children to a new layer
  223. * @return <code>ViewportLayer</code> of the given <code>DisplayObject3D</code>
  224. */
  225. public function getChildLayer(do3d:DisplayObject3D, createNew:Boolean = true, recurse:Boolean = true):ViewportLayer
  226. {
  227. return containerSprite.getChildLayer(do3d, createNew, recurse);
  228. }
  229. /**
  230. * Gets the layer of the RenderListItem. Most-likely internal use.
  231. * @param rc A RenderableListItem to look for
  232. * @param setInstance sets the container to the layer
  233. * @return The found <code>ViewportLayer</code>
  234. */
  235. public function accessLayerFor(rc:RenderableListItem, setInstance:Boolean = false):ViewportLayer
  236. {
  237. var do3d:DisplayObject3D;
  238. if(rc.renderableInstance)
  239. {
  240. do3d = rc.renderableInstance.instance;
  241. do3d = do3d.parentContainer ? do3d.parentContainer : do3d;
  242. if(containerSprite.layers[do3d])
  243. {
  244. if(setInstance)
  245. {
  246. do3d.container = containerSprite.layers[do3d];
  247. }
  248. return containerSprite.layers[do3d];
  249. }else if(do3d.useOwnContainer)
  250. {
  251. return containerSprite.getChildLayer(do3d, true, true);
  252. }
  253. }
  254. return containerSprite;
  255. }
  256. /**
  257. * Triggered when added to the stage to start listening to stage resizing
  258. */
  259. protected function onAddedToStage(event:Event):void
  260. {
  261. if(_autoScaleToStage)
  262. {
  263. setStageScaleMode();
  264. }
  265. stage.addEventListener(Event.RESIZE, onStageResize);
  266. onStageResize();
  267. }
  268. /**
  269. * Triggered when removed from the stage to remove the stage resizing listener
  270. */
  271. protected function onRemovedFromStage(event:Event):void
  272. {
  273. stage.removeEventListener(Event.RESIZE, onStageResize);
  274. }
  275. /**
  276. * Resizes the viewport when the stage is resized (if autoScaleToStage == true)
  277. */
  278. protected function onStageResize(event:Event = null):void
  279. {
  280. if(_autoScaleToStage)
  281. {
  282. viewportWidth = stage.stageWidth;
  283. viewportHeight = stage.stageHeight;
  284. }
  285. }
  286. protected function setStageScaleMode() : void
  287. {
  288. if(!stageScaleModeSet)
  289. {
  290. PaperLogger.info("Viewport autoScaleToStage : Papervision has changed the Stage scale mode.");
  291. stage.align = StageAlign.TOP_LEFT;
  292. stage.scaleMode = StageScaleMode.NO_SCALE;
  293. stageScaleModeSet = true;
  294. }
  295. }
  296. /**
  297. * Sets the viewport width
  298. * @param width A number designating the width of the viewport
  299. */
  300. public function set viewportWidth(width:Number):void
  301. {
  302. _width = width;
  303. _hWidth = width / 2;
  304. containerSprite.x = _hWidth;
  305. cullingRectangle.x = -_hWidth;
  306. cullingRectangle.width = width;
  307. sizeRectangle.width = width;
  308. if(_autoClipping)
  309. {
  310. scrollRect = sizeRectangle;
  311. }
  312. }
  313. /**
  314. * Width of the <code>Viewport3D</code>
  315. */
  316. public function get viewportWidth():Number
  317. {
  318. return _width;
  319. }
  320. /**
  321. * Sets the the height of the <code>Viewport3D</code>
  322. * @param height A number designating the height of the <code>Viewport3D</code>
  323. */
  324. public function set viewportHeight(height:Number):void
  325. {
  326. _height = height;
  327. _hHeight = height / 2;
  328. containerSprite.y = _hHeight;
  329. cullingRectangle.y = -_hHeight;
  330. cullingRectangle.height = height;
  331. sizeRectangle.height = height;
  332. if(_autoClipping)
  333. {
  334. scrollRect = sizeRectangle;
  335. }
  336. }
  337. /**
  338. * Height of the Viewport
  339. */
  340. public function get viewportHeight():Number
  341. {
  342. return _height;
  343. }
  344. /**
  345. * The <code>Sprite</code> holding the <code>Viewport3D</code>
  346. */
  347. public function get containerSprite():ViewportLayer
  348. {
  349. return _containerSprite;
  350. }
  351. /**
  352. * Whether clipping is enabled (not rendering bitmap data outside the rectangle of the viewport by making use of the <code>Sprite.scrollRect</code>)
  353. * @see flash.display.Sprite#scrollRect
  354. * @see http://www.gskinner.com/blog/archives/2006/11/understanding_d.html
  355. */
  356. public function get autoClipping():Boolean
  357. {
  358. return _autoClipping;
  359. }
  360. public function set autoClipping(clip:Boolean):void
  361. {
  362. if(clip)
  363. {
  364. scrollRect = sizeRectangle;
  365. }else
  366. {
  367. scrollRect = null;
  368. }
  369. _autoClipping = clip;
  370. }
  371. /**
  372. * Whether culling is enabled (not rendering triangles hidden behind other triangles)
  373. * @see #lineCuller
  374. * @see #particleCuller
  375. * @see #triangleCuller
  376. */
  377. public function get autoCulling():Boolean
  378. {
  379. return _autoCulling;
  380. }
  381. public function set autoCulling(culling:Boolean):void
  382. {
  383. if(culling)
  384. {
  385. triangleCuller = new RectangleTriangleCuller(cullingRectangle);
  386. particleCuller = new RectangleParticleCuller(cullingRectangle);
  387. lineCuller = new RectangleLineCuller(cullingRectangle);
  388. }else if(!culling)
  389. {
  390. triangleCuller = new DefaultTriangleCuller();
  391. particleCuller = new DefaultParticleCuller();
  392. lineCuller = new DefaultLineCuller();
  393. }
  394. _autoCulling = culling;
  395. }
  396. /**
  397. * Whether the <code>Viewport3D</code> should scale with the <code>Stage</code>
  398. */
  399. public function set autoScaleToStage(scale:Boolean):void
  400. {
  401. _autoScaleToStage = scale;
  402. if(scale && stage != null)
  403. {
  404. setStageScaleMode();
  405. onStageResize();
  406. }
  407. }
  408. /**
  409. * The auto scale to stage boolean flag
  410. */
  411. public function get autoScaleToStage():Boolean
  412. {
  413. return _autoScaleToStage;
  414. }
  415. /**
  416. * Whether the <code>Viewport3D</code> should listen for <code>Mouse</code> events and create an <code>InteractiveSceneManager</code>
  417. */
  418. public function set interactive(b:Boolean):void
  419. {
  420. if(b != _interactive)
  421. {
  422. if(_interactive && interactiveSceneManager)
  423. {
  424. interactiveSceneManager.destroy();
  425. interactiveSceneManager = null;
  426. }
  427. _interactive = b;
  428. if(b)
  429. {
  430. interactiveSceneManager = new InteractiveSceneManager(this);
  431. }
  432. }
  433. }
  434. /**
  435. * The interactive boolean flag
  436. */
  437. public function get interactive():Boolean
  438. {
  439. return _interactive;
  440. }
  441. /**
  442. * Updates a <code>ViewportLayer</code> prior to the 3d data being rendered into the 2d scene
  443. * @param renderSessionData All the information regarding the current renderSession packed into one class
  444. */
  445. public function updateBeforeRender(renderSessionData:RenderSessionData):void
  446. {
  447. lastRenderList.length = 0;
  448. if(renderSessionData.renderLayers)
  449. {
  450. for each(var vpl:ViewportLayer in renderSessionData.renderLayers)
  451. {
  452. vpl.updateBeforeRender();
  453. }
  454. }else
  455. {
  456. _containerSprite.updateBeforeRender();
  457. }
  458. _layerInstances = new Dictionary(true);
  459. }
  460. /**
  461. * Updates a <code>ViewportLayer</code> after the 3d data is rendered into the 2d scene
  462. * @param renderSessionData All the information regarding the current renderSession packed into one class
  463. */
  464. public function updateAfterRender(renderSessionData:RenderSessionData):void
  465. {
  466. if(interactive)
  467. {
  468. interactiveSceneManager.updateAfterRender();
  469. }
  470. if(renderSessionData.renderLayers)
  471. {
  472. for each(var vpl:ViewportLayer in renderSessionData.renderLayers)
  473. {
  474. vpl.updateInfo();
  475. vpl.sortChildLayers();
  476. vpl.updateAfterRender();
  477. }
  478. }else
  479. {
  480. containerSprite.updateInfo();
  481. containerSprite.updateAfterRender();
  482. }
  483. containerSprite.sortChildLayers();
  484. }
  485. /**
  486. * Sets the <code>ViewportObjectFilter</code> of the <code>Viewport3D</code>
  487. * @param vof The <code>ViewportObjectFilter</code> you want applied
  488. */
  489. public function set viewportObjectFilter(vof:ViewportObjectFilter):void
  490. {
  491. _viewportObjectFilter = vof;
  492. }
  493. /**
  494. * The <code>ViewportObjectFilter</code>
  495. */
  496. public function get viewportObjectFilter():ViewportObjectFilter
  497. {
  498. return _viewportObjectFilter;
  499. }
  500. }
  501. }