PageRenderTime 53ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/src/away3d/containers/View3D.as

https://github.com/M4TH76/away3d-core-fp11
ActionScript | 609 lines | 428 code | 113 blank | 68 comment | 67 complexity | f8b0671d7f59abaae9b7bd8d9a2cc4ce MD5 | raw file
  1. package away3d.containers
  2. {
  3. import away3d.arcane;
  4. import away3d.cameras.Camera3D;
  5. import away3d.core.managers.Mouse3DManager;
  6. import away3d.core.managers.Stage3DManager;
  7. import away3d.core.managers.Stage3DProxy;
  8. import away3d.core.render.DefaultRenderer;
  9. import away3d.core.render.DepthRenderer;
  10. import away3d.core.render.Filter3DRenderer;
  11. import away3d.core.render.RendererBase;
  12. import away3d.core.traverse.EntityCollector;
  13. import away3d.lights.LightBase;
  14. import flash.display.BitmapData;
  15. import flash.display.Sprite;
  16. import flash.display3D.Context3D;
  17. import flash.display3D.Context3DTextureFormat;
  18. import flash.display3D.textures.Texture;
  19. import flash.events.Event;
  20. import flash.geom.Matrix3D;
  21. import flash.geom.Point;
  22. import flash.geom.Transform;
  23. import flash.geom.Vector3D;
  24. import flash.utils.getTimer;
  25. use namespace arcane;
  26. public class View3D extends Sprite
  27. {
  28. private var _width : Number = 0;
  29. private var _height : Number = 0;
  30. private var _localPos : Point = new Point();
  31. private var _globalPos : Point = new Point();
  32. private var _scene : Scene3D;
  33. private var _camera : Camera3D;
  34. private var _entityCollector : EntityCollector;
  35. private var _aspectRatio : Number;
  36. private var _time : Number = 0;
  37. private var _deltaTime : uint;
  38. private var _backgroundColor : uint = 0x000000;
  39. private var _backgroundAlpha : Number = 1;
  40. private var _mouse3DManager : Mouse3DManager;
  41. private var _stage3DManager : Stage3DManager;
  42. private var _renderer : RendererBase;
  43. private var _depthRenderer : DepthRenderer;
  44. private var _addedToStage:Boolean;
  45. private var _filter3DRenderer : Filter3DRenderer;
  46. private var _requireDepthRender : Boolean;
  47. private var _depthRender : Texture;
  48. private var _depthTextureWidth : int = -1;
  49. private var _depthTextureHeight : int = -1;
  50. private var _depthTextureInvalid : Boolean = true;
  51. private var _hitField : Sprite;
  52. private var _parentIsStage : Boolean;
  53. private var _backgroundImage : BitmapData;
  54. private var _bgImageFitToViewPort:Boolean = true;
  55. private var _stage3DProxy : Stage3DProxy;
  56. private var _backBufferInvalid : Boolean = true;
  57. private var _antiAlias : uint;
  58. public function View3D(scene : Scene3D = null, camera : Camera3D = null, renderer : DefaultRenderer = null)
  59. {
  60. super();
  61. _scene = scene || new Scene3D();
  62. _camera = camera || new Camera3D();
  63. _renderer = renderer || new DefaultRenderer();
  64. _mouse3DManager = new Mouse3DManager(this);
  65. _depthRenderer = new DepthRenderer();
  66. _entityCollector = new EntityCollector();
  67. initHitField();
  68. addEventListener(Event.ADDED_TO_STAGE, onAddedToStage, false, 0, true);
  69. addEventListener(Event.ADDED, onAdded, false, 0, true);
  70. _camera.partition = _scene.partition;
  71. }
  72. public function get stage3DProxy() : Stage3DProxy
  73. {
  74. return _stage3DProxy;
  75. }
  76. /**
  77. * Forces mouse-move related events even when the mouse hasn't moved. This allows mouseOver and mouseOut events
  78. * etc to be triggered due to changes in the scene graph.
  79. */
  80. public function get forceMouseMove() : Boolean
  81. {
  82. return _mouse3DManager.forceMouseMove;
  83. }
  84. public function set forceMouseMove(value : Boolean) : void
  85. {
  86. _mouse3DManager.forceMouseMove = value;
  87. }
  88. public function get backgroundImage() : BitmapData
  89. {
  90. return _backgroundImage;
  91. }
  92. public function set backgroundImageFitToViewPort(value:Boolean):void
  93. {
  94. _bgImageFitToViewPort = value;
  95. if(_renderer.backgroundImageRenderer == null)
  96. return;
  97. _renderer.backgroundImageRenderer.fitToViewPort = value;
  98. }
  99. public function set backgroundImage(value : BitmapData) : void
  100. {
  101. _backgroundImage = value;
  102. _renderer.backgroundImage = _backgroundImage;
  103. _renderer.backgroundImageRenderer.viewWidth = _width;
  104. _renderer.backgroundImageRenderer.viewHeight = _height;
  105. _renderer.backgroundImageRenderer.fitToViewPort = _bgImageFitToViewPort;
  106. }
  107. private function initHitField() : void
  108. {
  109. _hitField = new Sprite();
  110. _hitField.alpha = 0;
  111. _hitField.doubleClickEnabled = true;
  112. _hitField.graphics.beginFill(0x000000);
  113. _hitField.graphics.drawRect(0, 0, 100, 100);
  114. addChild(_hitField);
  115. }
  116. /**
  117. * Not supported. Use filters3d instead.
  118. */
  119. override public function get filters() : Array
  120. {
  121. throw new Error("filters is not supported in View3D. Use filters3d instead.");
  122. return super.filters;
  123. }
  124. /**
  125. * Not supported. Use filters3d instead.
  126. */
  127. override public function set filters(value : Array) : void
  128. {
  129. throw new Error("filters is not supported in View3D. Use filters3d instead.");
  130. }
  131. public function get filters3d() : Array
  132. {
  133. return _filter3DRenderer? _filter3DRenderer.filters : null;
  134. }
  135. public function set filters3d(value : Array) : void
  136. {
  137. if (value && value.length == 0)
  138. value = null;
  139. if (_filter3DRenderer && !value) {
  140. _filter3DRenderer.dispose();
  141. _filter3DRenderer = null;
  142. } else if (!_filter3DRenderer && value) {
  143. _filter3DRenderer = new Filter3DRenderer(_width, _height);
  144. _filter3DRenderer.filters = value;
  145. }
  146. if (_filter3DRenderer) {
  147. _filter3DRenderer.filters = value;
  148. _requireDepthRender = _filter3DRenderer.requireDepthRender;
  149. } else {
  150. _requireDepthRender = false;
  151. if (_depthRender) {
  152. _depthRender.dispose();
  153. _depthRender = null;
  154. }
  155. }
  156. }
  157. /**
  158. * The renderer used to draw the scene.
  159. */
  160. public function get renderer() : RendererBase
  161. {
  162. return _renderer;
  163. }
  164. public function set renderer(value : RendererBase) : void
  165. {
  166. _renderer.dispose();
  167. _renderer = value;
  168. _renderer.stage3DProxy = _stage3DProxy;
  169. _renderer.backgroundR = ((_backgroundColor >> 16) & 0xff) / 0xff;
  170. _renderer.backgroundG = ((_backgroundColor >> 8) & 0xff) / 0xff;
  171. _renderer.backgroundB = (_backgroundColor & 0xff) / 0xff;
  172. _renderer.backgroundAlpha = _backgroundAlpha;
  173. _renderer.backgroundImage = _backgroundImage;
  174. invalidateBackBuffer();
  175. }
  176. private function invalidateBackBuffer() : void
  177. {
  178. _backBufferInvalid = true;
  179. }
  180. /**
  181. * The background color of the screen. This value is only used when clearAll is set to true.
  182. */
  183. public function get backgroundColor() : uint
  184. {
  185. return _backgroundColor;
  186. }
  187. public function set backgroundColor(value : uint) : void
  188. {
  189. _backgroundColor = value;
  190. _renderer.backgroundR = ((value >> 16) & 0xff) / 0xff;
  191. _renderer.backgroundG = ((value >> 8) & 0xff) / 0xff;
  192. _renderer.backgroundB = (value & 0xff) / 0xff;
  193. }
  194. public function get backgroundAlpha() : Number
  195. {
  196. return _backgroundAlpha;
  197. }
  198. public function set backgroundAlpha(value : Number) : void
  199. {
  200. if (value > 1)
  201. value = 1;
  202. else if (value < 0)
  203. value = 0;
  204. _renderer.backgroundAlpha = value;
  205. _backgroundAlpha = value;
  206. }
  207. /**
  208. * The camera that's used to render the scene for this viewport
  209. */
  210. public function get camera() : Camera3D
  211. {
  212. return _camera;
  213. }
  214. /**
  215. * Set camera that's used to render the scene for this viewport
  216. */
  217. public function set camera(camera:Camera3D) : void
  218. {
  219. _camera = camera;
  220. if (_scene)
  221. _camera.partition = _scene.partition;
  222. }
  223. /**
  224. * The scene that's used to render for this viewport
  225. */
  226. public function get scene() : Scene3D
  227. {
  228. return _scene;
  229. }
  230. /**
  231. * Set the scene that's used to render for this viewport
  232. */
  233. public function set scene(scene:Scene3D) : void
  234. {
  235. _scene = scene;
  236. if (_camera)
  237. _camera.partition = _scene.partition;
  238. }
  239. // todo: probably temporary:
  240. /**
  241. * The amount of milliseconds the last render call took
  242. */
  243. public function get deltaTime() : uint
  244. {
  245. return _deltaTime;
  246. }
  247. /**
  248. * The width of the viewport
  249. */
  250. override public function get width() : Number
  251. {
  252. return _width;
  253. }
  254. override public function set width(value : Number) : void
  255. {
  256. if (_width == value)
  257. return;
  258. _hitField.width = value;
  259. _width = value;
  260. _aspectRatio = _width/_height;
  261. _depthTextureInvalid = true;
  262. if (_filter3DRenderer)
  263. _filter3DRenderer.viewWidth = value;
  264. if (_renderer.backgroundImageRenderer != null) {
  265. _renderer.backgroundImageRenderer.viewWidth = _width;
  266. _renderer.backgroundImageRenderer.viewHeight = _height;
  267. }
  268. invalidateBackBuffer();
  269. }
  270. /**
  271. * The height of the viewport
  272. */
  273. override public function get height() : Number
  274. {
  275. return _height;
  276. }
  277. override public function set height(value : Number) : void
  278. {
  279. if (_height == value)
  280. return;
  281. _hitField.height = value;
  282. _height = value;
  283. _aspectRatio = _width/_height;
  284. _depthTextureInvalid = true;
  285. if (_filter3DRenderer)
  286. _filter3DRenderer.viewHeight = value;
  287. invalidateBackBuffer();
  288. }
  289. override public function set x(value : Number) : void
  290. {
  291. super.x = value;
  292. _localPos.x = value;
  293. _globalPos.x = parent? parent.localToGlobal(_localPos).x : value;
  294. if (_stage3DProxy)
  295. _stage3DProxy.x = _globalPos.x;
  296. }
  297. override public function set y(value : Number) : void
  298. {
  299. super.y = value;
  300. _localPos.y = value;
  301. _globalPos.y = parent? parent.localToGlobal(_localPos).y : value;
  302. if (_stage3DProxy)
  303. _stage3DProxy.y = _globalPos.y;
  304. }
  305. /**
  306. * The amount of anti-aliasing to be used.
  307. */
  308. public function get antiAlias() : uint
  309. {
  310. return _antiAlias;
  311. }
  312. public function set antiAlias(value : uint) : void
  313. {
  314. _antiAlias = value;
  315. invalidateBackBuffer();
  316. }
  317. /**
  318. * The amount of faces that were pushed through the render pipeline on the last frame render.
  319. */
  320. public function get renderedFacesCount() : uint
  321. {
  322. return _entityCollector.numTriangles;
  323. }
  324. /**
  325. * Updates the backbuffer dimensions.
  326. */
  327. private function updateBackBuffer() : void
  328. {
  329. _stage3DProxy.configureBackBuffer(_width, _height, _antiAlias, true);
  330. _backBufferInvalid = false;
  331. }
  332. /**
  333. * Renders the view.
  334. */
  335. public function render() : void
  336. {
  337. // reset or update render settings
  338. if (_backBufferInvalid)
  339. updateBackBuffer();
  340. if (!_parentIsStage)
  341. updateGlobalPos();
  342. updateTime();
  343. _entityCollector.clear();
  344. updateCamera();
  345. // collect stuff to render
  346. _scene.traversePartitions(_entityCollector);
  347. // render things
  348. if (_entityCollector.numMouseEnableds > 0)
  349. _mouse3DManager.updateHitData();
  350. updateLights(_entityCollector);
  351. if (_requireDepthRender)
  352. renderSceneDepth(_entityCollector);
  353. if (_filter3DRenderer && _stage3DProxy._context3D) {
  354. _renderer.render(_entityCollector, _filter3DRenderer.getMainInputTexture(_stage3DProxy), _filter3DRenderer.renderRect);
  355. _filter3DRenderer.render(_stage3DProxy, camera, _depthRender);
  356. _stage3DProxy._context3D.present();
  357. } else {
  358. _renderer.render(_entityCollector);
  359. }
  360. // clean up data for this render
  361. _entityCollector.cleanUp();
  362. // fire collected mouse events
  363. _mouse3DManager.fireMouseEvents();
  364. }
  365. private function updateGlobalPos() : void
  366. {
  367. var globalPos : Point = parent.localToGlobal(_localPos);
  368. if (_globalPos.x != globalPos.x) _stage3DProxy.x = globalPos.x;
  369. if (_globalPos.y != globalPos.y) _stage3DProxy.y = globalPos.y;
  370. _globalPos = globalPos;
  371. }
  372. private function updateTime() : void
  373. {
  374. var time : Number = getTimer();
  375. if (_time == 0) _time = time;
  376. _deltaTime = time - _time;
  377. _time = time;
  378. }
  379. private function updateCamera() : void
  380. {
  381. _camera.lens.aspectRatio = _aspectRatio;
  382. _entityCollector.camera = _camera;
  383. if (_filter3DRenderer) {
  384. _camera.textureRatioX = _width/_filter3DRenderer.textureWidth;
  385. _camera.textureRatioY = _height/_filter3DRenderer.textureHeight;
  386. }
  387. else {
  388. _camera.textureRatioX = 1;
  389. _camera.textureRatioY = 1;
  390. }
  391. }
  392. private function renderSceneDepth(entityCollector : EntityCollector) : void
  393. {
  394. if (_depthTextureInvalid || !_depthRender) initDepthTexture(_stage3DProxy._context3D);
  395. _depthRenderer.render(entityCollector, _depthRender);
  396. }
  397. private function initDepthTexture(context : Context3D) : void
  398. {
  399. var w : int = getPowerOf2Exceeding(_width);
  400. var h : int = getPowerOf2Exceeding(_height);
  401. _depthTextureInvalid = false;
  402. if (w == _depthTextureWidth && h == _depthTextureHeight) return;
  403. _depthTextureWidth = w;
  404. _depthTextureHeight = h;
  405. if (_depthRender) _depthRender.dispose();
  406. _depthRender = context.createTexture(w, h, Context3DTextureFormat.BGRA, true);
  407. }
  408. private function getPowerOf2Exceeding(value : int) : Number
  409. {
  410. var p : int = 1;
  411. while (p < value && p < 2048)
  412. p <<= 1;
  413. if (p > 2048) p = 2048;
  414. return p;
  415. }
  416. private function updateLights(entityCollector : EntityCollector) : void
  417. {
  418. var lights : Vector.<LightBase> = entityCollector.lights;
  419. var len : uint = lights.length;
  420. var light : LightBase;
  421. for (var i : int = 0; i < len; ++i) {
  422. light = lights[i];
  423. if (light.castsShadows)
  424. light.shadowMapper.renderDepthMap(_renderer.stage3DProxy, entityCollector, _depthRenderer);
  425. }
  426. }
  427. /**
  428. * Disposes all memory occupied by the view. This will also dispose the renderer.
  429. */
  430. public function dispose() : void
  431. {
  432. _stage3DProxy.dispose();
  433. _renderer.dispose();
  434. _mouse3DManager.dispose();
  435. if (_depthRenderer) _depthRenderer.dispose();
  436. _mouse3DManager.dispose();
  437. if (_depthRender) _depthRender.dispose();
  438. }
  439. public function project(point3d : Vector3D) : Point
  440. {
  441. var p : Point = _camera.project(point3d);
  442. p.x = (p.x + 1.0)*_width/2.0;
  443. p.y = (p.y + 1.0)*_height/2.0;
  444. return p;
  445. }
  446. public function unproject(mX : Number, mY : Number) : Vector3D
  447. {
  448. return _camera.unproject((mX * 2 - _width)/_width, (mY * 2 - _height)/_height );
  449. }
  450. /**
  451. * The EntityCollector object that will collect all potentially visible entities in the partition tree.
  452. *
  453. * @see away3d.core.traverse.EntityCollector
  454. * @private
  455. */
  456. arcane function get entityCollector() : EntityCollector
  457. {
  458. return _entityCollector;
  459. }
  460. /**
  461. * When added to the stage, retrieve a Stage3D instance
  462. */
  463. private function onAddedToStage(event : Event) : void
  464. {
  465. if (_addedToStage)
  466. return;
  467. _addedToStage = true;
  468. _stage3DManager = Stage3DManager.getInstance(stage);
  469. if (_width == 0) width = stage.stageWidth;
  470. if (_height == 0) height = stage.stageHeight;
  471. _stage3DProxy = _stage3DManager.getFreeStage3DProxy();
  472. _stage3DProxy.x = _globalPos.x;
  473. _stage3DProxy.y = _globalPos.y;
  474. _renderer.stage3DProxy = _depthRenderer.stage3DProxy = _mouse3DManager.stage3DProxy = _stage3DProxy;
  475. }
  476. private function onAdded(event : Event) : void
  477. {
  478. _parentIsStage = (parent == stage);
  479. _globalPos = parent.localToGlobal(new Point(x, y));
  480. if (_stage3DProxy) {
  481. _stage3DProxy.x = _globalPos.x;
  482. _stage3DProxy.y = _globalPos.y;
  483. }
  484. }
  485. // dead ends:
  486. override public function set z(value : Number) : void {}
  487. override public function set scaleZ(value : Number) : void {}
  488. override public function set rotation(value : Number) : void {}
  489. override public function set rotationX(value : Number) : void {}
  490. override public function set rotationY(value : Number) : void {}
  491. override public function set rotationZ(value : Number) : void {}
  492. override public function set transform(value : Transform) : void {}
  493. override public function set scaleX(value : Number) : void {}
  494. override public function set scaleY(value : Number) : void {}
  495. }
  496. }