babylon.scene.js 121 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617
  1. var __extends = (this && this.__extends) || function (d, b) {
  2. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  3. function __() { this.constructor = d; }
  4. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  5. };
  6. var BABYLON;
  7. (function (BABYLON) {
  8. var PointerEventTypes = (function () {
  9. function PointerEventTypes() {
  10. }
  11. Object.defineProperty(PointerEventTypes, "POINTERDOWN", {
  12. get: function () {
  13. return PointerEventTypes._POINTERDOWN;
  14. },
  15. enumerable: true,
  16. configurable: true
  17. });
  18. Object.defineProperty(PointerEventTypes, "POINTERUP", {
  19. get: function () {
  20. return PointerEventTypes._POINTERUP;
  21. },
  22. enumerable: true,
  23. configurable: true
  24. });
  25. Object.defineProperty(PointerEventTypes, "POINTERMOVE", {
  26. get: function () {
  27. return PointerEventTypes._POINTERMOVE;
  28. },
  29. enumerable: true,
  30. configurable: true
  31. });
  32. Object.defineProperty(PointerEventTypes, "POINTERWHEEL", {
  33. get: function () {
  34. return PointerEventTypes._POINTERWHEEL;
  35. },
  36. enumerable: true,
  37. configurable: true
  38. });
  39. Object.defineProperty(PointerEventTypes, "POINTERPICK", {
  40. get: function () {
  41. return PointerEventTypes._POINTERPICK;
  42. },
  43. enumerable: true,
  44. configurable: true
  45. });
  46. PointerEventTypes._POINTERDOWN = 0x01;
  47. PointerEventTypes._POINTERUP = 0x02;
  48. PointerEventTypes._POINTERMOVE = 0x04;
  49. PointerEventTypes._POINTERWHEEL = 0x08;
  50. PointerEventTypes._POINTERPICK = 0x10;
  51. return PointerEventTypes;
  52. }());
  53. BABYLON.PointerEventTypes = PointerEventTypes;
  54. var PointerInfoBase = (function () {
  55. function PointerInfoBase(type, event) {
  56. this.type = type;
  57. this.event = event;
  58. }
  59. return PointerInfoBase;
  60. }());
  61. BABYLON.PointerInfoBase = PointerInfoBase;
  62. /**
  63. * This class is used to store pointer related info for the onPrePointerObservable event.
  64. * Set the skipOnPointerObservable property to true if you want the engine to stop any process after this event is triggered, even not calling onPointerObservable
  65. */
  66. var PointerInfoPre = (function (_super) {
  67. __extends(PointerInfoPre, _super);
  68. function PointerInfoPre(type, event, localX, localY) {
  69. _super.call(this, type, event);
  70. this.skipOnPointerObservable = false;
  71. this.localPosition = new BABYLON.Vector2(localX, localY);
  72. }
  73. return PointerInfoPre;
  74. }(PointerInfoBase));
  75. BABYLON.PointerInfoPre = PointerInfoPre;
  76. /**
  77. * This type contains all the data related to a pointer event in Babylon.js.
  78. * The event member is an instance of PointerEvent for all types except PointerWheel and is of type MouseWheelEvent when type equals PointerWheel. The different event types can be found in the PointerEventTypes class.
  79. */
  80. var PointerInfo = (function (_super) {
  81. __extends(PointerInfo, _super);
  82. function PointerInfo(type, event, pickInfo) {
  83. _super.call(this, type, event);
  84. this.pickInfo = pickInfo;
  85. }
  86. return PointerInfo;
  87. }(PointerInfoBase));
  88. BABYLON.PointerInfo = PointerInfo;
  89. /**
  90. * This class is used by the onRenderingGroupObservable
  91. */
  92. var RenderingGroupInfo = (function () {
  93. function RenderingGroupInfo() {
  94. }
  95. /**
  96. * Stage corresponding to the very first hook in the renderingGroup phase: before the render buffer may be cleared
  97. * This stage will be fired no matter what
  98. */
  99. RenderingGroupInfo.STAGE_PRECLEAR = 1;
  100. /**
  101. * Called before opaque object are rendered.
  102. * This stage will be fired only if there's 3D Opaque content to render
  103. */
  104. RenderingGroupInfo.STAGE_PREOPAQUE = 2;
  105. /**
  106. * Called after the opaque objects are rendered and before the transparent ones
  107. * This stage will be fired only if there's 3D transparent content to render
  108. */
  109. RenderingGroupInfo.STAGE_PRETRANSPARENT = 3;
  110. /**
  111. * Called after the transparent object are rendered, last hook of the renderingGroup phase
  112. * This stage will be fired no matter what
  113. */
  114. RenderingGroupInfo.STAGE_POSTTRANSPARENT = 4;
  115. return RenderingGroupInfo;
  116. }());
  117. BABYLON.RenderingGroupInfo = RenderingGroupInfo;
  118. /**
  119. * Represents a scene to be rendered by the engine.
  120. * @see http://doc.babylonjs.com/page.php?p=21911
  121. */
  122. var Scene = (function () {
  123. /**
  124. * @constructor
  125. * @param {BABYLON.Engine} engine - the engine to be used to render this scene.
  126. */
  127. function Scene(engine) {
  128. // Members
  129. this.autoClear = true;
  130. this.clearColor = new BABYLON.Color3(0.2, 0.2, 0.3);
  131. this.ambientColor = new BABYLON.Color3(0, 0, 0);
  132. this.forceWireframe = false;
  133. this.forcePointsCloud = false;
  134. this.forceShowBoundingBoxes = false;
  135. this.animationsEnabled = true;
  136. this.constantlyUpdateMeshUnderPointer = false;
  137. this.useRightHandedSystem = false;
  138. this.hoverCursor = "pointer";
  139. // Events
  140. /**
  141. * An event triggered when the scene is disposed.
  142. * @type {BABYLON.Observable}
  143. */
  144. this.onDisposeObservable = new BABYLON.Observable();
  145. /**
  146. * An event triggered before rendering the scene
  147. * @type {BABYLON.Observable}
  148. */
  149. this.onBeforeRenderObservable = new BABYLON.Observable();
  150. /**
  151. * An event triggered after rendering the scene
  152. * @type {BABYLON.Observable}
  153. */
  154. this.onAfterRenderObservable = new BABYLON.Observable();
  155. /**
  156. * An event triggered when the scene is ready
  157. * @type {BABYLON.Observable}
  158. */
  159. this.onReadyObservable = new BABYLON.Observable();
  160. /**
  161. * An event triggered before rendering a camera
  162. * @type {BABYLON.Observable}
  163. */
  164. this.onBeforeCameraRenderObservable = new BABYLON.Observable();
  165. /**
  166. * An event triggered after rendering a camera
  167. * @type {BABYLON.Observable}
  168. */
  169. this.onAfterCameraRenderObservable = new BABYLON.Observable();
  170. /**
  171. * An event triggered when a camera is created
  172. * @type {BABYLON.Observable}
  173. */
  174. this.onNewCameraAddedObservable = new BABYLON.Observable();
  175. /**
  176. * An event triggered when a camera is removed
  177. * @type {BABYLON.Observable}
  178. */
  179. this.onCameraRemovedObservable = new BABYLON.Observable();
  180. /**
  181. * An event triggered when a light is created
  182. * @type {BABYLON.Observable}
  183. */
  184. this.onNewLightAddedObservable = new BABYLON.Observable();
  185. /**
  186. * An event triggered when a light is removed
  187. * @type {BABYLON.Observable}
  188. */
  189. this.onLightRemovedObservable = new BABYLON.Observable();
  190. /**
  191. * An event triggered when a geometry is created
  192. * @type {BABYLON.Observable}
  193. */
  194. this.onNewGeometryAddedObservable = new BABYLON.Observable();
  195. /**
  196. * An event triggered when a geometry is removed
  197. * @type {BABYLON.Observable}
  198. */
  199. this.onGeometryRemovedObservable = new BABYLON.Observable();
  200. /**
  201. * An event triggered when a mesh is created
  202. * @type {BABYLON.Observable}
  203. */
  204. this.onNewMeshAddedObservable = new BABYLON.Observable();
  205. /**
  206. * An event triggered when a mesh is removed
  207. * @type {BABYLON.Observable}
  208. */
  209. this.onMeshRemovedObservable = new BABYLON.Observable();
  210. /**
  211. * This Observable will be triggered for each stage of each renderingGroup of each rendered camera.
  212. * The RenderinGroupInfo class contains all the information about the context in which the observable is called
  213. * If you wish to register an Observer only for a given set of renderingGroup, use the mask with a combination of the renderingGroup index elevated to the power of two (1 for renderingGroup 0, 2 for renderingrOup1, 4 for 2 and 8 for 3)
  214. */
  215. this.onRenderingGroupObservable = new BABYLON.Observable();
  216. // Animations
  217. this.animations = [];
  218. /**
  219. * This observable event is triggered when any mouse event registered during Scene.attach() is called BEFORE the 3D engine to process anything (mesh/sprite picking for instance).
  220. * You have the possibility to skip the 3D Engine process and the call to onPointerObservable by setting PointerInfoBase.skipOnPointerObservable to true
  221. */
  222. this.onPrePointerObservable = new BABYLON.Observable();
  223. /**
  224. * Observable event triggered each time an input event is received from the rendering canvas
  225. */
  226. this.onPointerObservable = new BABYLON.Observable();
  227. this.cameraToUseForPointers = null; // Define this parameter if you are using multiple cameras and you want to specify which one should be used for pointer position
  228. this._startingPointerPosition = new BABYLON.Vector2(0, 0);
  229. this._startingPointerTime = 0;
  230. // Fog
  231. /**
  232. * is fog enabled on this scene.
  233. * @type {boolean}
  234. */
  235. this.fogEnabled = true;
  236. this.fogMode = Scene.FOGMODE_NONE;
  237. this.fogColor = new BABYLON.Color3(0.2, 0.2, 0.3);
  238. this.fogDensity = 0.1;
  239. this.fogStart = 0;
  240. this.fogEnd = 1000.0;
  241. // Lights
  242. /**
  243. * is shadow enabled on this scene.
  244. * @type {boolean}
  245. */
  246. this.shadowsEnabled = true;
  247. /**
  248. * is light enabled on this scene.
  249. * @type {boolean}
  250. */
  251. this.lightsEnabled = true;
  252. /**
  253. * All of the lights added to this scene.
  254. * @see BABYLON.Light
  255. * @type {BABYLON.Light[]}
  256. */
  257. this.lights = new Array();
  258. // Cameras
  259. /**
  260. * All of the cameras added to this scene.
  261. * @see BABYLON.Camera
  262. * @type {BABYLON.Camera[]}
  263. */
  264. this.cameras = new Array();
  265. this.activeCameras = new Array();
  266. // Meshes
  267. /**
  268. * All of the (abstract) meshes added to this scene.
  269. * @see BABYLON.AbstractMesh
  270. * @type {BABYLON.AbstractMesh[]}
  271. */
  272. this.meshes = new Array();
  273. // Geometries
  274. this._geometries = new Array();
  275. this.materials = new Array();
  276. this.multiMaterials = new Array();
  277. // Textures
  278. this.texturesEnabled = true;
  279. this.textures = new Array();
  280. // Particles
  281. this.particlesEnabled = true;
  282. this.particleSystems = new Array();
  283. // Sprites
  284. this.spritesEnabled = true;
  285. this.spriteManagers = new Array();
  286. // Layers
  287. this.layers = new Array();
  288. this.highlightLayers = new Array();
  289. // Skeletons
  290. this.skeletonsEnabled = true;
  291. this.skeletons = new Array();
  292. // Lens flares
  293. this.lensFlaresEnabled = true;
  294. this.lensFlareSystems = new Array();
  295. // Collisions
  296. this.collisionsEnabled = true;
  297. this.gravity = new BABYLON.Vector3(0, -9.807, 0);
  298. // Postprocesses
  299. this.postProcessesEnabled = true;
  300. // Customs render targets
  301. this.renderTargetsEnabled = true;
  302. this.dumpNextRenderTargets = false;
  303. this.customRenderTargets = new Array();
  304. // Imported meshes
  305. this.importedMeshesFiles = new Array();
  306. // Probes
  307. this.probesEnabled = true;
  308. this.reflectionProbes = new Array();
  309. this._actionManagers = new Array();
  310. this._meshesForIntersections = new BABYLON.SmartArray(256);
  311. // Procedural textures
  312. this.proceduralTexturesEnabled = true;
  313. this._proceduralTextures = new Array();
  314. this.soundTracks = new Array();
  315. this._audioEnabled = true;
  316. this._headphone = false;
  317. // Performance counters
  318. this._totalMeshesCounter = new BABYLON.PerfCounter();
  319. this._totalLightsCounter = new BABYLON.PerfCounter();
  320. this._totalMaterialsCounter = new BABYLON.PerfCounter();
  321. this._totalTexturesCounter = new BABYLON.PerfCounter();
  322. this._totalVertices = new BABYLON.PerfCounter();
  323. this._activeIndices = new BABYLON.PerfCounter();
  324. this._activeParticles = new BABYLON.PerfCounter();
  325. this._lastFrameDuration = new BABYLON.PerfCounter();
  326. this._evaluateActiveMeshesDuration = new BABYLON.PerfCounter();
  327. this._renderTargetsDuration = new BABYLON.PerfCounter();
  328. this._particlesDuration = new BABYLON.PerfCounter();
  329. this._renderDuration = new BABYLON.PerfCounter();
  330. this._spritesDuration = new BABYLON.PerfCounter();
  331. this._activeBones = new BABYLON.PerfCounter();
  332. this._renderId = 0;
  333. this._executeWhenReadyTimeoutId = -1;
  334. this._intermediateRendering = false;
  335. this._toBeDisposed = new BABYLON.SmartArray(256);
  336. this._pendingData = []; //ANY
  337. this._activeMeshes = new BABYLON.SmartArray(256);
  338. this._processedMaterials = new BABYLON.SmartArray(256);
  339. this._renderTargets = new BABYLON.SmartArray(256);
  340. this._activeParticleSystems = new BABYLON.SmartArray(256);
  341. this._activeSkeletons = new BABYLON.SmartArray(32);
  342. this._softwareSkinnedMeshes = new BABYLON.SmartArray(32);
  343. this._activeAnimatables = new Array();
  344. this._transformMatrix = BABYLON.Matrix.Zero();
  345. this._edgesRenderers = new BABYLON.SmartArray(16);
  346. this._uniqueIdCounter = 0;
  347. this._engine = engine;
  348. engine.scenes.push(this);
  349. this._externalData = new BABYLON.StringDictionary();
  350. this._uid = null;
  351. this._renderingManager = new BABYLON.RenderingManager(this);
  352. this.postProcessManager = new BABYLON.PostProcessManager(this);
  353. this.postProcessRenderPipelineManager = new BABYLON.PostProcessRenderPipelineManager();
  354. this._boundingBoxRenderer = new BABYLON.BoundingBoxRenderer(this);
  355. if (BABYLON.OutlineRenderer) {
  356. this._outlineRenderer = new BABYLON.OutlineRenderer(this);
  357. }
  358. this.attachControl();
  359. if (BABYLON.SoundTrack) {
  360. this.mainSoundTrack = new BABYLON.SoundTrack(this, { mainTrack: true });
  361. }
  362. //simplification queue
  363. if (BABYLON.SimplificationQueue) {
  364. this.simplificationQueue = new BABYLON.SimplificationQueue();
  365. }
  366. //collision coordinator initialization. For now legacy per default.
  367. this.workerCollisions = false; //(!!Worker && (!!BABYLON.CollisionWorker || BABYLON.WorkerIncluded));
  368. }
  369. Object.defineProperty(Scene, "FOGMODE_NONE", {
  370. get: function () {
  371. return Scene._FOGMODE_NONE;
  372. },
  373. enumerable: true,
  374. configurable: true
  375. });
  376. Object.defineProperty(Scene, "FOGMODE_EXP", {
  377. get: function () {
  378. return Scene._FOGMODE_EXP;
  379. },
  380. enumerable: true,
  381. configurable: true
  382. });
  383. Object.defineProperty(Scene, "FOGMODE_EXP2", {
  384. get: function () {
  385. return Scene._FOGMODE_EXP2;
  386. },
  387. enumerable: true,
  388. configurable: true
  389. });
  390. Object.defineProperty(Scene, "FOGMODE_LINEAR", {
  391. get: function () {
  392. return Scene._FOGMODE_LINEAR;
  393. },
  394. enumerable: true,
  395. configurable: true
  396. });
  397. Object.defineProperty(Scene.prototype, "onDispose", {
  398. set: function (callback) {
  399. if (this._onDisposeObserver) {
  400. this.onDisposeObservable.remove(this._onDisposeObserver);
  401. }
  402. this._onDisposeObserver = this.onDisposeObservable.add(callback);
  403. },
  404. enumerable: true,
  405. configurable: true
  406. });
  407. Object.defineProperty(Scene.prototype, "beforeRender", {
  408. set: function (callback) {
  409. if (this._onBeforeRenderObserver) {
  410. this.onBeforeRenderObservable.remove(this._onBeforeRenderObserver);
  411. }
  412. this._onBeforeRenderObserver = this.onBeforeRenderObservable.add(callback);
  413. },
  414. enumerable: true,
  415. configurable: true
  416. });
  417. Object.defineProperty(Scene.prototype, "afterRender", {
  418. set: function (callback) {
  419. if (this._onAfterRenderObserver) {
  420. this.onAfterRenderObservable.remove(this._onAfterRenderObserver);
  421. }
  422. this._onAfterRenderObserver = this.onAfterRenderObservable.add(callback);
  423. },
  424. enumerable: true,
  425. configurable: true
  426. });
  427. Object.defineProperty(Scene.prototype, "beforeCameraRender", {
  428. set: function (callback) {
  429. if (this._onBeforeCameraRenderObserver) {
  430. this.onBeforeCameraRenderObservable.remove(this._onBeforeCameraRenderObserver);
  431. }
  432. this._onBeforeCameraRenderObserver = this.onBeforeCameraRenderObservable.add(callback);
  433. },
  434. enumerable: true,
  435. configurable: true
  436. });
  437. Object.defineProperty(Scene.prototype, "afterCameraRender", {
  438. set: function (callback) {
  439. if (this._onAfterCameraRenderObserver) {
  440. this.onAfterCameraRenderObservable.remove(this._onAfterCameraRenderObserver);
  441. }
  442. this._onAfterCameraRenderObserver = this.onAfterCameraRenderObservable.add(callback);
  443. },
  444. enumerable: true,
  445. configurable: true
  446. });
  447. Object.defineProperty(Scene.prototype, "unTranslatedPointer", {
  448. get: function () {
  449. return new BABYLON.Vector2(this._unTranslatedPointerX, this._unTranslatedPointerY);
  450. },
  451. enumerable: true,
  452. configurable: true
  453. });
  454. Object.defineProperty(Scene.prototype, "defaultMaterial", {
  455. get: function () {
  456. if (!this._defaultMaterial) {
  457. this._defaultMaterial = new BABYLON.StandardMaterial("default material", this);
  458. }
  459. return this._defaultMaterial;
  460. },
  461. enumerable: true,
  462. configurable: true
  463. });
  464. Object.defineProperty(Scene.prototype, "debugLayer", {
  465. // Properties
  466. get: function () {
  467. if (!this._debugLayer) {
  468. this._debugLayer = new BABYLON.DebugLayer(this);
  469. }
  470. return this._debugLayer;
  471. },
  472. enumerable: true,
  473. configurable: true
  474. });
  475. Object.defineProperty(Scene.prototype, "workerCollisions", {
  476. get: function () {
  477. return this._workerCollisions;
  478. },
  479. set: function (enabled) {
  480. enabled = (enabled && !!Worker);
  481. this._workerCollisions = enabled;
  482. if (this.collisionCoordinator) {
  483. this.collisionCoordinator.destroy();
  484. }
  485. this.collisionCoordinator = enabled ? new BABYLON.CollisionCoordinatorWorker() : new BABYLON.CollisionCoordinatorLegacy();
  486. this.collisionCoordinator.init(this);
  487. },
  488. enumerable: true,
  489. configurable: true
  490. });
  491. Object.defineProperty(Scene.prototype, "SelectionOctree", {
  492. get: function () {
  493. return this._selectionOctree;
  494. },
  495. enumerable: true,
  496. configurable: true
  497. });
  498. Object.defineProperty(Scene.prototype, "meshUnderPointer", {
  499. /**
  500. * The mesh that is currently under the pointer.
  501. * @return {BABYLON.AbstractMesh} mesh under the pointer/mouse cursor or null if none.
  502. */
  503. get: function () {
  504. return this._pointerOverMesh;
  505. },
  506. enumerable: true,
  507. configurable: true
  508. });
  509. Object.defineProperty(Scene.prototype, "pointerX", {
  510. /**
  511. * Current on-screen X position of the pointer
  512. * @return {number} X position of the pointer
  513. */
  514. get: function () {
  515. return this._pointerX;
  516. },
  517. enumerable: true,
  518. configurable: true
  519. });
  520. Object.defineProperty(Scene.prototype, "pointerY", {
  521. /**
  522. * Current on-screen Y position of the pointer
  523. * @return {number} Y position of the pointer
  524. */
  525. get: function () {
  526. return this._pointerY;
  527. },
  528. enumerable: true,
  529. configurable: true
  530. });
  531. Scene.prototype.getCachedMaterial = function () {
  532. return this._cachedMaterial;
  533. };
  534. Scene.prototype.getBoundingBoxRenderer = function () {
  535. return this._boundingBoxRenderer;
  536. };
  537. Scene.prototype.getOutlineRenderer = function () {
  538. return this._outlineRenderer;
  539. };
  540. Scene.prototype.getEngine = function () {
  541. return this._engine;
  542. };
  543. Scene.prototype.getTotalVertices = function () {
  544. return this._totalVertices.current;
  545. };
  546. Object.defineProperty(Scene.prototype, "totalVerticesPerfCounter", {
  547. get: function () {
  548. return this._totalVertices;
  549. },
  550. enumerable: true,
  551. configurable: true
  552. });
  553. Scene.prototype.getActiveIndices = function () {
  554. return this._activeIndices.current;
  555. };
  556. Object.defineProperty(Scene.prototype, "totalActiveIndicesPerfCounter", {
  557. get: function () {
  558. return this._activeIndices;
  559. },
  560. enumerable: true,
  561. configurable: true
  562. });
  563. Scene.prototype.getActiveParticles = function () {
  564. return this._activeParticles.current;
  565. };
  566. Object.defineProperty(Scene.prototype, "activeParticlesPerfCounter", {
  567. get: function () {
  568. return this._activeParticles;
  569. },
  570. enumerable: true,
  571. configurable: true
  572. });
  573. Scene.prototype.getActiveBones = function () {
  574. return this._activeBones.current;
  575. };
  576. Object.defineProperty(Scene.prototype, "activeBonesPerfCounter", {
  577. get: function () {
  578. return this._activeBones;
  579. },
  580. enumerable: true,
  581. configurable: true
  582. });
  583. // Stats
  584. Scene.prototype.getLastFrameDuration = function () {
  585. return this._lastFrameDuration.current;
  586. };
  587. Object.defineProperty(Scene.prototype, "lastFramePerfCounter", {
  588. get: function () {
  589. return this._lastFrameDuration;
  590. },
  591. enumerable: true,
  592. configurable: true
  593. });
  594. Scene.prototype.getEvaluateActiveMeshesDuration = function () {
  595. return this._evaluateActiveMeshesDuration.current;
  596. };
  597. Object.defineProperty(Scene.prototype, "evaluateActiveMeshesDurationPerfCounter", {
  598. get: function () {
  599. return this._evaluateActiveMeshesDuration;
  600. },
  601. enumerable: true,
  602. configurable: true
  603. });
  604. Scene.prototype.getActiveMeshes = function () {
  605. return this._activeMeshes;
  606. };
  607. Scene.prototype.getRenderTargetsDuration = function () {
  608. return this._renderTargetsDuration.current;
  609. };
  610. Scene.prototype.getRenderDuration = function () {
  611. return this._renderDuration.current;
  612. };
  613. Object.defineProperty(Scene.prototype, "renderDurationPerfCounter", {
  614. get: function () {
  615. return this._renderDuration;
  616. },
  617. enumerable: true,
  618. configurable: true
  619. });
  620. Scene.prototype.getParticlesDuration = function () {
  621. return this._particlesDuration.current;
  622. };
  623. Object.defineProperty(Scene.prototype, "particlesDurationPerfCounter", {
  624. get: function () {
  625. return this._particlesDuration;
  626. },
  627. enumerable: true,
  628. configurable: true
  629. });
  630. Scene.prototype.getSpritesDuration = function () {
  631. return this._spritesDuration.current;
  632. };
  633. Object.defineProperty(Scene.prototype, "spriteDuractionPerfCounter", {
  634. get: function () {
  635. return this._spritesDuration;
  636. },
  637. enumerable: true,
  638. configurable: true
  639. });
  640. Scene.prototype.getAnimationRatio = function () {
  641. return this._animationRatio;
  642. };
  643. Scene.prototype.getRenderId = function () {
  644. return this._renderId;
  645. };
  646. Scene.prototype.incrementRenderId = function () {
  647. this._renderId++;
  648. };
  649. Scene.prototype._updatePointerPosition = function (evt) {
  650. var canvasRect = this._engine.getRenderingCanvasClientRect();
  651. this._pointerX = evt.clientX - canvasRect.left;
  652. this._pointerY = evt.clientY - canvasRect.top;
  653. this._unTranslatedPointerX = this._pointerX;
  654. this._unTranslatedPointerY = this._pointerY;
  655. if (this.cameraToUseForPointers) {
  656. this._pointerX = this._pointerX - this.cameraToUseForPointers.viewport.x * this._engine.getRenderWidth();
  657. this._pointerY = this._pointerY - this.cameraToUseForPointers.viewport.y * this._engine.getRenderHeight();
  658. }
  659. };
  660. // Pointers handling
  661. /**
  662. * Attach events to the canvas (To handle actionManagers triggers and raise onPointerMove, onPointerDown and onPointerUp
  663. * @param attachUp defines if you want to attach events to pointerup
  664. * @param attachDown defines if you want to attach events to pointerdown
  665. * @param attachMove defines if you want to attach events to pointermove
  666. */
  667. Scene.prototype.attachControl = function (attachUp, attachDown, attachMove) {
  668. var _this = this;
  669. if (attachUp === void 0) { attachUp = true; }
  670. if (attachDown === void 0) { attachDown = true; }
  671. if (attachMove === void 0) { attachMove = true; }
  672. var spritePredicate = function (sprite) {
  673. return sprite.isPickable && sprite.actionManager && sprite.actionManager.hasPointerTriggers;
  674. };
  675. this._onPointerMove = function (evt) {
  676. _this._updatePointerPosition(evt);
  677. // PreObservable support
  678. if (_this.onPrePointerObservable.hasObservers()) {
  679. var type = evt.type === "mousewheel" || evt.type === "DOMMouseScroll" ? PointerEventTypes.POINTERWHEEL : PointerEventTypes.POINTERMOVE;
  680. var pi = new PointerInfoPre(type, evt, _this._unTranslatedPointerX, _this._unTranslatedPointerY);
  681. _this.onPrePointerObservable.notifyObservers(pi, type);
  682. if (pi.skipOnPointerObservable) {
  683. return;
  684. }
  685. }
  686. if (!_this.cameraToUseForPointers && !_this.activeCamera) {
  687. return;
  688. }
  689. var canvas = _this._engine.getRenderingCanvas();
  690. if (!_this.pointerMovePredicate) {
  691. _this.pointerMovePredicate = function (mesh) { return mesh.isPickable && mesh.isVisible && mesh.isReady() && (_this.constantlyUpdateMeshUnderPointer || mesh.actionManager !== null && mesh.actionManager !== undefined); };
  692. }
  693. // Meshes
  694. var pickResult = _this.pick(_this._unTranslatedPointerX, _this._unTranslatedPointerY, _this.pointerMovePredicate, false, _this.cameraToUseForPointers);
  695. if (pickResult.hit && pickResult.pickedMesh) {
  696. _this.setPointerOverSprite(null);
  697. _this.setPointerOverMesh(pickResult.pickedMesh);
  698. if (_this._pointerOverMesh.actionManager && _this._pointerOverMesh.actionManager.hasPointerTriggers) {
  699. canvas.style.cursor = _this.hoverCursor;
  700. }
  701. else {
  702. canvas.style.cursor = "";
  703. }
  704. }
  705. else {
  706. _this.setPointerOverMesh(null);
  707. // Sprites
  708. pickResult = _this.pickSprite(_this._unTranslatedPointerX, _this._unTranslatedPointerY, spritePredicate, false, _this.cameraToUseForPointers);
  709. if (pickResult.hit && pickResult.pickedSprite) {
  710. canvas.style.cursor = _this.hoverCursor;
  711. _this.setPointerOverSprite(pickResult.pickedSprite);
  712. }
  713. else {
  714. _this.setPointerOverSprite(null);
  715. // Restore pointer
  716. canvas.style.cursor = "";
  717. }
  718. }
  719. if (_this.onPointerMove) {
  720. _this.onPointerMove(evt, pickResult);
  721. }
  722. if (_this.onPointerObservable.hasObservers()) {
  723. var type = evt.type === "mousewheel" || evt.type === "DOMMouseScroll" ? PointerEventTypes.POINTERWHEEL : PointerEventTypes.POINTERMOVE;
  724. var pi = new PointerInfo(type, evt, pickResult);
  725. _this.onPointerObservable.notifyObservers(pi, type);
  726. }
  727. };
  728. this._onPointerDown = function (evt) {
  729. _this._updatePointerPosition(evt);
  730. // PreObservable support
  731. if (_this.onPrePointerObservable.hasObservers()) {
  732. var type = PointerEventTypes.POINTERDOWN;
  733. var pi = new PointerInfoPre(type, evt, _this._unTranslatedPointerX, _this._unTranslatedPointerY);
  734. _this.onPrePointerObservable.notifyObservers(pi, type);
  735. if (pi.skipOnPointerObservable) {
  736. return;
  737. }
  738. }
  739. if (!_this.cameraToUseForPointers && !_this.activeCamera) {
  740. return;
  741. }
  742. _this._startingPointerPosition.x = _this._pointerX;
  743. _this._startingPointerPosition.y = _this._pointerY;
  744. _this._startingPointerTime = new Date().getTime();
  745. if (!_this.pointerDownPredicate) {
  746. _this.pointerDownPredicate = function (mesh) {
  747. return mesh.isPickable && mesh.isVisible && mesh.isReady() && (!mesh.actionManager || mesh.actionManager.hasPointerTriggers);
  748. };
  749. }
  750. // Meshes
  751. _this._pickedDownMesh = null;
  752. var pickResult = _this.pick(_this._unTranslatedPointerX, _this._unTranslatedPointerY, _this.pointerDownPredicate, false, _this.cameraToUseForPointers);
  753. if (pickResult.hit && pickResult.pickedMesh) {
  754. if (pickResult.pickedMesh.actionManager) {
  755. _this._pickedDownMesh = pickResult.pickedMesh;
  756. if (pickResult.pickedMesh.actionManager.hasPickTriggers) {
  757. switch (evt.button) {
  758. case 0:
  759. pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnLeftPickTrigger, BABYLON.ActionEvent.CreateNew(pickResult.pickedMesh, evt));
  760. break;
  761. case 1:
  762. pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnCenterPickTrigger, BABYLON.ActionEvent.CreateNew(pickResult.pickedMesh, evt));
  763. break;
  764. case 2:
  765. pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnRightPickTrigger, BABYLON.ActionEvent.CreateNew(pickResult.pickedMesh, evt));
  766. break;
  767. }
  768. pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnPickDownTrigger, BABYLON.ActionEvent.CreateNew(pickResult.pickedMesh, evt));
  769. }
  770. if (pickResult.pickedMesh.actionManager.hasSpecificTrigger(BABYLON.ActionManager.OnLongPressTrigger)) {
  771. var that = _this;
  772. window.setTimeout(function () {
  773. var pickResult = that.pick(that._unTranslatedPointerX, that._unTranslatedPointerY, function (mesh) { return mesh.isPickable && mesh.isVisible && mesh.isReady() && mesh.actionManager && mesh.actionManager.hasSpecificTrigger(BABYLON.ActionManager.OnLongPressTrigger); }, false, that.cameraToUseForPointers);
  774. if (pickResult.hit && pickResult.pickedMesh) {
  775. if (pickResult.pickedMesh.actionManager) {
  776. if (that._startingPointerTime !== 0 && ((new Date().getTime() - that._startingPointerTime) > BABYLON.ActionManager.LongPressDelay) && (Math.abs(that._startingPointerPosition.x - that._pointerX) < BABYLON.ActionManager.DragMovementThreshold && Math.abs(that._startingPointerPosition.y - that._pointerY) < BABYLON.ActionManager.DragMovementThreshold)) {
  777. that._startingPointerTime = 0;
  778. pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnLongPressTrigger, BABYLON.ActionEvent.CreateNew(pickResult.pickedMesh, evt));
  779. }
  780. }
  781. }
  782. }, BABYLON.ActionManager.LongPressDelay);
  783. }
  784. }
  785. }
  786. if (_this.onPointerDown) {
  787. _this.onPointerDown(evt, pickResult);
  788. }
  789. if (_this.onPointerObservable.hasObservers()) {
  790. var type = PointerEventTypes.POINTERDOWN;
  791. var pi = new PointerInfo(type, evt, pickResult);
  792. _this.onPointerObservable.notifyObservers(pi, type);
  793. }
  794. // Sprites
  795. _this._pickedDownSprite = null;
  796. if (_this.spriteManagers.length > 0) {
  797. pickResult = _this.pickSprite(_this._unTranslatedPointerX, _this._unTranslatedPointerY, spritePredicate, false, _this.cameraToUseForPointers);
  798. if (pickResult.hit && pickResult.pickedSprite) {
  799. if (pickResult.pickedSprite.actionManager) {
  800. _this._pickedDownSprite = pickResult.pickedSprite;
  801. switch (evt.button) {
  802. case 0:
  803. pickResult.pickedSprite.actionManager.processTrigger(BABYLON.ActionManager.OnLeftPickTrigger, BABYLON.ActionEvent.CreateNewFromSprite(pickResult.pickedSprite, _this, evt));
  804. break;
  805. case 1:
  806. pickResult.pickedSprite.actionManager.processTrigger(BABYLON.ActionManager.OnCenterPickTrigger, BABYLON.ActionEvent.CreateNewFromSprite(pickResult.pickedSprite, _this, evt));
  807. break;
  808. case 2:
  809. pickResult.pickedSprite.actionManager.processTrigger(BABYLON.ActionManager.OnRightPickTrigger, BABYLON.ActionEvent.CreateNewFromSprite(pickResult.pickedSprite, _this, evt));
  810. break;
  811. }
  812. pickResult.pickedSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickDownTrigger, BABYLON.ActionEvent.CreateNewFromSprite(pickResult.pickedSprite, _this, evt));
  813. }
  814. }
  815. }
  816. };
  817. this._onPointerUp = function (evt) {
  818. _this._updatePointerPosition(evt);
  819. // PreObservable support
  820. if (_this.onPrePointerObservable.hasObservers()) {
  821. var type = PointerEventTypes.POINTERUP;
  822. var pi = new PointerInfoPre(type, evt, _this._unTranslatedPointerX, _this._unTranslatedPointerY);
  823. _this.onPrePointerObservable.notifyObservers(pi, type);
  824. if (pi.skipOnPointerObservable) {
  825. return;
  826. }
  827. }
  828. if (!_this.cameraToUseForPointers && !_this.activeCamera) {
  829. return;
  830. }
  831. if (!_this.pointerUpPredicate) {
  832. _this.pointerUpPredicate = function (mesh) {
  833. return mesh.isPickable && mesh.isVisible && mesh.isReady() && (!mesh.actionManager || (mesh.actionManager.hasPickTriggers || mesh.actionManager.hasSpecificTrigger(BABYLON.ActionManager.OnLongPressTrigger)));
  834. };
  835. }
  836. // Meshes
  837. var pickResult = _this.pick(_this._unTranslatedPointerX, _this._unTranslatedPointerY, _this.pointerUpPredicate, false, _this.cameraToUseForPointers);
  838. if (pickResult.hit && pickResult.pickedMesh) {
  839. if (_this._pickedDownMesh != null && pickResult.pickedMesh == _this._pickedDownMesh) {
  840. if (_this.onPointerPick) {
  841. _this.onPointerPick(evt, pickResult);
  842. }
  843. if (_this.onPointerObservable.hasObservers()) {
  844. var type = PointerEventTypes.POINTERPICK;
  845. var pi = new PointerInfo(type, evt, pickResult);
  846. _this.onPointerObservable.notifyObservers(pi, type);
  847. }
  848. }
  849. if (pickResult.pickedMesh.actionManager) {
  850. pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnPickUpTrigger, BABYLON.ActionEvent.CreateNew(pickResult.pickedMesh, evt));
  851. if (Math.abs(_this._startingPointerPosition.x - _this._pointerX) < BABYLON.ActionManager.DragMovementThreshold && Math.abs(_this._startingPointerPosition.y - _this._pointerY) < BABYLON.ActionManager.DragMovementThreshold) {
  852. pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnPickTrigger, BABYLON.ActionEvent.CreateNew(pickResult.pickedMesh, evt));
  853. }
  854. }
  855. }
  856. if (_this._pickedDownMesh && _this._pickedDownMesh !== pickResult.pickedMesh) {
  857. _this._pickedDownMesh.actionManager.processTrigger(BABYLON.ActionManager.OnPickOutTrigger, BABYLON.ActionEvent.CreateNew(_this._pickedDownMesh, evt));
  858. }
  859. if (_this.onPointerUp) {
  860. _this.onPointerUp(evt, pickResult);
  861. }
  862. if (_this.onPointerObservable.hasObservers()) {
  863. var type = PointerEventTypes.POINTERUP;
  864. var pi = new PointerInfo(type, evt, pickResult);
  865. _this.onPointerObservable.notifyObservers(pi, type);
  866. }
  867. _this._startingPointerTime = 0;
  868. // Sprites
  869. if (_this.spriteManagers.length > 0) {
  870. pickResult = _this.pickSprite(_this._unTranslatedPointerX, _this._unTranslatedPointerY, spritePredicate, false, _this.cameraToUseForPointers);
  871. if (pickResult.hit && pickResult.pickedSprite) {
  872. if (pickResult.pickedSprite.actionManager) {
  873. pickResult.pickedSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickUpTrigger, BABYLON.ActionEvent.CreateNewFromSprite(pickResult.pickedSprite, _this, evt));
  874. if (Math.abs(_this._startingPointerPosition.x - _this._pointerX) < BABYLON.ActionManager.DragMovementThreshold && Math.abs(_this._startingPointerPosition.y - _this._pointerY) < BABYLON.ActionManager.DragMovementThreshold) {
  875. pickResult.pickedSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickTrigger, BABYLON.ActionEvent.CreateNewFromSprite(pickResult.pickedSprite, _this, evt));
  876. }
  877. }
  878. }
  879. if (_this._pickedDownSprite && _this._pickedDownSprite !== pickResult.pickedSprite) {
  880. _this._pickedDownSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickOutTrigger, BABYLON.ActionEvent.CreateNewFromSprite(_this._pickedDownSprite, _this, evt));
  881. }
  882. }
  883. };
  884. this._onKeyDown = function (evt) {
  885. if (_this.actionManager) {
  886. _this.actionManager.processTrigger(BABYLON.ActionManager.OnKeyDownTrigger, BABYLON.ActionEvent.CreateNewFromScene(_this, evt));
  887. }
  888. };
  889. this._onKeyUp = function (evt) {
  890. if (_this.actionManager) {
  891. _this.actionManager.processTrigger(BABYLON.ActionManager.OnKeyUpTrigger, BABYLON.ActionEvent.CreateNewFromScene(_this, evt));
  892. }
  893. };
  894. var eventPrefix = BABYLON.Tools.GetPointerPrefix();
  895. var canvas = this._engine.getRenderingCanvas();
  896. if (attachMove) {
  897. canvas.addEventListener(eventPrefix + "move", this._onPointerMove, false);
  898. // Wheel
  899. canvas.addEventListener('mousewheel', this._onPointerMove, false);
  900. canvas.addEventListener('DOMMouseScroll', this._onPointerMove, false);
  901. }
  902. if (attachDown) {
  903. canvas.addEventListener(eventPrefix + "down", this._onPointerDown, false);
  904. }
  905. if (attachUp) {
  906. canvas.addEventListener(eventPrefix + "up", this._onPointerUp, false);
  907. }
  908. canvas.tabIndex = 1;
  909. canvas.addEventListener("keydown", this._onKeyDown, false);
  910. canvas.addEventListener("keyup", this._onKeyUp, false);
  911. };
  912. Scene.prototype.detachControl = function () {
  913. var eventPrefix = BABYLON.Tools.GetPointerPrefix();
  914. var canvas = this._engine.getRenderingCanvas();
  915. canvas.removeEventListener(eventPrefix + "move", this._onPointerMove);
  916. canvas.removeEventListener(eventPrefix + "down", this._onPointerDown);
  917. canvas.removeEventListener(eventPrefix + "up", this._onPointerUp);
  918. // Wheel
  919. canvas.removeEventListener('mousewheel', this._onPointerMove);
  920. canvas.removeEventListener('DOMMouseScroll', this._onPointerMove);
  921. canvas.removeEventListener("keydown", this._onKeyDown);
  922. canvas.removeEventListener("keyup", this._onKeyUp);
  923. };
  924. // Ready
  925. Scene.prototype.isReady = function () {
  926. if (this._pendingData.length > 0) {
  927. return false;
  928. }
  929. var index;
  930. for (index = 0; index < this._geometries.length; index++) {
  931. var geometry = this._geometries[index];
  932. if (geometry.delayLoadState === BABYLON.Engine.DELAYLOADSTATE_LOADING) {
  933. return false;
  934. }
  935. }
  936. for (index = 0; index < this.meshes.length; index++) {
  937. var mesh = this.meshes[index];
  938. if (!mesh.isReady()) {
  939. return false;
  940. }
  941. var mat = mesh.material;
  942. if (mat) {
  943. if (!mat.isReady(mesh)) {
  944. return false;
  945. }
  946. }
  947. }
  948. return true;
  949. };
  950. Scene.prototype.resetCachedMaterial = function () {
  951. this._cachedMaterial = null;
  952. };
  953. Scene.prototype.registerBeforeRender = function (func) {
  954. this.onBeforeRenderObservable.add(func);
  955. };
  956. Scene.prototype.unregisterBeforeRender = function (func) {
  957. this.onBeforeRenderObservable.removeCallback(func);
  958. };
  959. Scene.prototype.registerAfterRender = function (func) {
  960. this.onAfterRenderObservable.add(func);
  961. };
  962. Scene.prototype.unregisterAfterRender = function (func) {
  963. this.onAfterRenderObservable.removeCallback(func);
  964. };
  965. Scene.prototype._addPendingData = function (data) {
  966. this._pendingData.push(data);
  967. };
  968. Scene.prototype._removePendingData = function (data) {
  969. var index = this._pendingData.indexOf(data);
  970. if (index !== -1) {
  971. this._pendingData.splice(index, 1);
  972. }
  973. };
  974. Scene.prototype.getWaitingItemsCount = function () {
  975. return this._pendingData.length;
  976. };
  977. /**
  978. * Registers a function to be executed when the scene is ready.
  979. * @param {Function} func - the function to be executed.
  980. */
  981. Scene.prototype.executeWhenReady = function (func) {
  982. var _this = this;
  983. this.onReadyObservable.add(func);
  984. if (this._executeWhenReadyTimeoutId !== -1) {
  985. return;
  986. }
  987. this._executeWhenReadyTimeoutId = setTimeout(function () {
  988. _this._checkIsReady();
  989. }, 150);
  990. };
  991. Scene.prototype._checkIsReady = function () {
  992. var _this = this;
  993. if (this.isReady()) {
  994. this.onReadyObservable.notifyObservers(this);
  995. this.onReadyObservable.clear();
  996. this._executeWhenReadyTimeoutId = -1;
  997. return;
  998. }
  999. this._executeWhenReadyTimeoutId = setTimeout(function () {
  1000. _this._checkIsReady();
  1001. }, 150);
  1002. };
  1003. // Animations
  1004. /**
  1005. * Will start the animation sequence of a given target
  1006. * @param target - the target
  1007. * @param {number} from - from which frame should animation start
  1008. * @param {number} to - till which frame should animation run.
  1009. * @param {boolean} [loop] - should the animation loop
  1010. * @param {number} [speedRatio] - the speed in which to run the animation
  1011. * @param {Function} [onAnimationEnd] function to be executed when the animation ended.
  1012. * @param {BABYLON.Animatable} [animatable] an animatable object. If not provided a new one will be created from the given params.
  1013. * @return {BABYLON.Animatable} the animatable object created for this animation
  1014. * @see BABYLON.Animatable
  1015. * @see http://doc.babylonjs.com/page.php?p=22081
  1016. */
  1017. Scene.prototype.beginAnimation = function (target, from, to, loop, speedRatio, onAnimationEnd, animatable) {
  1018. if (speedRatio === void 0) { speedRatio = 1.0; }
  1019. this.stopAnimation(target);
  1020. if (!animatable) {
  1021. animatable = new BABYLON.Animatable(this, target, from, to, loop, speedRatio, onAnimationEnd);
  1022. }
  1023. // Local animations
  1024. if (target.animations) {
  1025. animatable.appendAnimations(target, target.animations);
  1026. }
  1027. // Children animations
  1028. if (target.getAnimatables) {
  1029. var animatables = target.getAnimatables();
  1030. for (var index = 0; index < animatables.length; index++) {
  1031. this.beginAnimation(animatables[index], from, to, loop, speedRatio, onAnimationEnd, animatable);
  1032. }
  1033. }
  1034. animatable.reset();
  1035. return animatable;
  1036. };
  1037. Scene.prototype.beginDirectAnimation = function (target, animations, from, to, loop, speedRatio, onAnimationEnd) {
  1038. if (speedRatio === undefined) {
  1039. speedRatio = 1.0;
  1040. }
  1041. var animatable = new BABYLON.Animatable(this, target, from, to, loop, speedRatio, onAnimationEnd, animations);
  1042. return animatable;
  1043. };
  1044. Scene.prototype.getAnimatableByTarget = function (target) {
  1045. for (var index = 0; index < this._activeAnimatables.length; index++) {
  1046. if (this._activeAnimatables[index].target === target) {
  1047. return this._activeAnimatables[index];
  1048. }
  1049. }
  1050. return null;
  1051. };
  1052. Object.defineProperty(Scene.prototype, "Animatables", {
  1053. get: function () {
  1054. return this._activeAnimatables;
  1055. },
  1056. enumerable: true,
  1057. configurable: true
  1058. });
  1059. /**
  1060. * Will stop the animation of the given target
  1061. * @param target - the target
  1062. * @param animationName - the name of the animation to stop (all animations will be stopped is empty)
  1063. * @see beginAnimation
  1064. */
  1065. Scene.prototype.stopAnimation = function (target, animationName) {
  1066. var animatable = this.getAnimatableByTarget(target);
  1067. if (animatable) {
  1068. animatable.stop(animationName);
  1069. }
  1070. };
  1071. Scene.prototype._animate = function () {
  1072. if (!this.animationsEnabled || this._activeAnimatables.length === 0) {
  1073. return;
  1074. }
  1075. if (!this._animationStartDate) {
  1076. if (this._pendingData.length > 0) {
  1077. return;
  1078. }
  1079. this._animationStartDate = BABYLON.Tools.Now;
  1080. }
  1081. // Getting time
  1082. var now = BABYLON.Tools.Now;
  1083. var delay = now - this._animationStartDate;
  1084. for (var index = 0; index < this._activeAnimatables.length; index++) {
  1085. this._activeAnimatables[index]._animate(delay);
  1086. }
  1087. };
  1088. // Matrix
  1089. Scene.prototype.getViewMatrix = function () {
  1090. return this._viewMatrix;
  1091. };
  1092. Scene.prototype.getProjectionMatrix = function () {
  1093. return this._projectionMatrix;
  1094. };
  1095. Scene.prototype.getTransformMatrix = function () {
  1096. return this._transformMatrix;
  1097. };
  1098. Scene.prototype.setTransformMatrix = function (view, projection) {
  1099. this._viewMatrix = view;
  1100. this._projectionMatrix = projection;
  1101. this._viewMatrix.multiplyToRef(this._projectionMatrix, this._transformMatrix);
  1102. // Update frustum
  1103. if (!this._frustumPlanes) {
  1104. this._frustumPlanes = BABYLON.Frustum.GetPlanes(this._transformMatrix);
  1105. }
  1106. else {
  1107. BABYLON.Frustum.GetPlanesToRef(this._transformMatrix, this._frustumPlanes);
  1108. }
  1109. };
  1110. // Methods
  1111. Scene.prototype.addMesh = function (newMesh) {
  1112. newMesh.uniqueId = this._uniqueIdCounter++;
  1113. var position = this.meshes.push(newMesh);
  1114. //notify the collision coordinator
  1115. this.collisionCoordinator.onMeshAdded(newMesh);
  1116. this.onNewMeshAddedObservable.notifyObservers(newMesh);
  1117. };
  1118. Scene.prototype.removeMesh = function (toRemove) {
  1119. var index = this.meshes.indexOf(toRemove);
  1120. if (index !== -1) {
  1121. // Remove from the scene if mesh found
  1122. this.meshes.splice(index, 1);
  1123. }
  1124. //notify the collision coordinator
  1125. this.collisionCoordinator.onMeshRemoved(toRemove);
  1126. this.onMeshRemovedObservable.notifyObservers(toRemove);
  1127. return index;
  1128. };
  1129. Scene.prototype.removeSkeleton = function (toRemove) {
  1130. var index = this.skeletons.indexOf(toRemove);
  1131. if (index !== -1) {
  1132. // Remove from the scene if mesh found
  1133. this.skeletons.splice(index, 1);
  1134. }
  1135. return index;
  1136. };
  1137. Scene.prototype.removeLight = function (toRemove) {
  1138. var index = this.lights.indexOf(toRemove);
  1139. if (index !== -1) {
  1140. // Remove from the scene if mesh found
  1141. this.lights.splice(index, 1);
  1142. }
  1143. this.onLightRemovedObservable.notifyObservers(toRemove);
  1144. return index;
  1145. };
  1146. Scene.prototype.removeCamera = function (toRemove) {
  1147. var index = this.cameras.indexOf(toRemove);
  1148. if (index !== -1) {
  1149. // Remove from the scene if mesh found
  1150. this.cameras.splice(index, 1);
  1151. }
  1152. // Remove from activeCameras
  1153. var index2 = this.activeCameras.indexOf(toRemove);
  1154. if (index2 !== -1) {
  1155. // Remove from the scene if mesh found
  1156. this.activeCameras.splice(index2, 1);
  1157. }
  1158. // Reset the activeCamera
  1159. if (this.activeCamera === toRemove) {
  1160. if (this.cameras.length > 0) {
  1161. this.activeCamera = this.cameras[0];
  1162. }
  1163. else {
  1164. this.activeCamera = null;
  1165. }
  1166. }
  1167. this.onCameraRemovedObservable.notifyObservers(toRemove);
  1168. return index;
  1169. };
  1170. Scene.prototype.addLight = function (newLight) {
  1171. newLight.uniqueId = this._uniqueIdCounter++;
  1172. var position = this.lights.push(newLight);
  1173. this.onNewLightAddedObservable.notifyObservers(newLight);
  1174. };
  1175. Scene.prototype.addCamera = function (newCamera) {
  1176. newCamera.uniqueId = this._uniqueIdCounter++;
  1177. var position = this.cameras.push(newCamera);
  1178. this.onNewCameraAddedObservable.notifyObservers(newCamera);
  1179. };
  1180. /**
  1181. * Switch active camera
  1182. * @param {Camera} newCamera - new active camera
  1183. * @param {boolean} attachControl - call attachControl for the new active camera (default: true)
  1184. */
  1185. Scene.prototype.switchActiveCamera = function (newCamera, attachControl) {
  1186. if (attachControl === void 0) { attachControl = true; }
  1187. var canvas = this._engine.getRenderingCanvas();
  1188. this.activeCamera.detachControl(canvas);
  1189. this.activeCamera = newCamera;
  1190. if (attachControl) {
  1191. newCamera.attachControl(canvas);
  1192. }
  1193. };
  1194. /**
  1195. * sets the active camera of the scene using its ID
  1196. * @param {string} id - the camera's ID
  1197. * @return {BABYLON.Camera|null} the new active camera or null if none found.
  1198. * @see activeCamera
  1199. */
  1200. Scene.prototype.setActiveCameraByID = function (id) {
  1201. var camera = this.getCameraByID(id);
  1202. if (camera) {
  1203. this.activeCamera = camera;
  1204. return camera;
  1205. }
  1206. return null;
  1207. };
  1208. /**
  1209. * sets the active camera of the scene using its name
  1210. * @param {string} name - the camera's name
  1211. * @return {BABYLON.Camera|null} the new active camera or null if none found.
  1212. * @see activeCamera
  1213. */
  1214. Scene.prototype.setActiveCameraByName = function (name) {
  1215. var camera = this.getCameraByName(name);
  1216. if (camera) {
  1217. this.activeCamera = camera;
  1218. return camera;
  1219. }
  1220. return null;
  1221. };
  1222. /**
  1223. * get a material using its id
  1224. * @param {string} the material's ID
  1225. * @return {BABYLON.Material|null} the material or null if none found.
  1226. */
  1227. Scene.prototype.getMaterialByID = function (id) {
  1228. for (var index = 0; index < this.materials.length; index++) {
  1229. if (this.materials[index].id === id) {
  1230. return this.materials[index];
  1231. }
  1232. }
  1233. return null;
  1234. };
  1235. /**
  1236. * get a material using its name
  1237. * @param {string} the material's name
  1238. * @return {BABYLON.Material|null} the material or null if none found.
  1239. */
  1240. Scene.prototype.getMaterialByName = function (name) {
  1241. for (var index = 0; index < this.materials.length; index++) {
  1242. if (this.materials[index].name === name) {
  1243. return this.materials[index];
  1244. }
  1245. }
  1246. return null;
  1247. };
  1248. Scene.prototype.getLensFlareSystemByName = function (name) {
  1249. for (var index = 0; index < this.lensFlareSystems.length; index++) {
  1250. if (this.lensFlareSystems[index].name === name) {
  1251. return this.lensFlareSystems[index];
  1252. }
  1253. }
  1254. return null;
  1255. };
  1256. Scene.prototype.getLensFlareSystemByID = function (id) {
  1257. for (var index = 0; index < this.lensFlareSystems.length; index++) {
  1258. if (this.lensFlareSystems[index].id === id) {
  1259. return this.lensFlareSystems[index];
  1260. }
  1261. }
  1262. return null;
  1263. };
  1264. Scene.prototype.getCameraByID = function (id) {
  1265. for (var index = 0; index < this.cameras.length; index++) {
  1266. if (this.cameras[index].id === id) {
  1267. return this.cameras[index];
  1268. }
  1269. }
  1270. return null;
  1271. };
  1272. Scene.prototype.getCameraByUniqueID = function (uniqueId) {
  1273. for (var index = 0; index < this.cameras.length; index++) {
  1274. if (this.cameras[index].uniqueId === uniqueId) {
  1275. return this.cameras[index];
  1276. }
  1277. }
  1278. return null;
  1279. };
  1280. /**
  1281. * get a camera using its name
  1282. * @param {string} the camera's name
  1283. * @return {BABYLON.Camera|null} the camera or null if none found.
  1284. */
  1285. Scene.prototype.getCameraByName = function (name) {
  1286. for (var index = 0; index < this.cameras.length; index++) {
  1287. if (this.cameras[index].name === name) {
  1288. return this.cameras[index];
  1289. }
  1290. }
  1291. return null;
  1292. };
  1293. /**
  1294. * get a bone using its id
  1295. * @param {string} the bone's id
  1296. * @return {BABYLON.Bone|null} the bone or null if not found
  1297. */
  1298. Scene.prototype.getBoneByID = function (id) {
  1299. for (var skeletonIndex = 0; skeletonIndex < this.skeletons.length; skeletonIndex++) {
  1300. var skeleton = this.skeletons[skeletonIndex];
  1301. for (var boneIndex = 0; boneIndex < skeleton.bones.length; boneIndex++) {
  1302. if (skeleton.bones[boneIndex].id === id) {
  1303. return skeleton.bones[boneIndex];
  1304. }
  1305. }
  1306. }
  1307. return null;
  1308. };
  1309. /**
  1310. * get a bone using its id
  1311. * @param {string} the bone's name
  1312. * @return {BABYLON.Bone|null} the bone or null if not found
  1313. */
  1314. Scene.prototype.getBoneByName = function (name) {
  1315. for (var skeletonIndex = 0; skeletonIndex < this.skeletons.length; skeletonIndex++) {
  1316. var skeleton = this.skeletons[skeletonIndex];
  1317. for (var boneIndex = 0; boneIndex < skeleton.bones.length; boneIndex++) {
  1318. if (skeleton.bones[boneIndex].name === name) {
  1319. return skeleton.bones[boneIndex];
  1320. }
  1321. }
  1322. }
  1323. return null;
  1324. };
  1325. /**
  1326. * get a light node using its name
  1327. * @param {string} the light's name
  1328. * @return {BABYLON.Light|null} the light or null if none found.
  1329. */
  1330. Scene.prototype.getLightByName = function (name) {
  1331. for (var index = 0; index < this.lights.length; index++) {
  1332. if (this.lights[index].name === name) {
  1333. return this.lights[index];
  1334. }
  1335. }
  1336. return null;
  1337. };
  1338. /**
  1339. * get a light node using its ID
  1340. * @param {string} the light's id
  1341. * @return {BABYLON.Light|null} the light or null if none found.
  1342. */
  1343. Scene.prototype.getLightByID = function (id) {
  1344. for (var index = 0; index < this.lights.length; index++) {
  1345. if (this.lights[index].id === id) {
  1346. return this.lights[index];
  1347. }
  1348. }
  1349. return null;
  1350. };
  1351. /**
  1352. * get a light node using its scene-generated unique ID
  1353. * @param {number} the light's unique id
  1354. * @return {BABYLON.Light|null} the light or null if none found.
  1355. */
  1356. Scene.prototype.getLightByUniqueID = function (uniqueId) {
  1357. for (var index = 0; index < this.lights.length; index++) {
  1358. if (this.lights[index].uniqueId === uniqueId) {
  1359. return this.lights[index];
  1360. }
  1361. }
  1362. return null;
  1363. };
  1364. /**
  1365. * get a particle system by id
  1366. * @param id {number} the particle system id
  1367. * @return {BABYLON.ParticleSystem|null} the corresponding system or null if none found.
  1368. */
  1369. Scene.prototype.getParticleSystemByID = function (id) {
  1370. for (var index = 0; index < this.particleSystems.length; index++) {
  1371. if (this.particleSystems[index].id === id) {
  1372. return this.particleSystems[index];
  1373. }
  1374. }
  1375. return null;
  1376. };
  1377. /**
  1378. * get a geometry using its ID
  1379. * @param {string} the geometry's id
  1380. * @return {BABYLON.Geometry|null} the geometry or null if none found.
  1381. */
  1382. Scene.prototype.getGeometryByID = function (id) {
  1383. for (var index = 0; index < this._geometries.length; index++) {
  1384. if (this._geometries[index].id === id) {
  1385. return this._geometries[index];
  1386. }
  1387. }
  1388. return null;
  1389. };
  1390. /**
  1391. * add a new geometry to this scene.
  1392. * @param {BABYLON.Geometry} geometry - the geometry to be added to the scene.
  1393. * @param {boolean} [force] - force addition, even if a geometry with this ID already exists
  1394. * @return {boolean} was the geometry added or not
  1395. */
  1396. Scene.prototype.pushGeometry = function (geometry, force) {
  1397. if (!force && this.getGeometryByID(geometry.id)) {
  1398. return false;
  1399. }
  1400. this._geometries.push(geometry);
  1401. //notify the collision coordinator
  1402. this.collisionCoordinator.onGeometryAdded(geometry);
  1403. this.onNewGeometryAddedObservable.notifyObservers(geometry);
  1404. return true;
  1405. };
  1406. /**
  1407. * Removes an existing geometry
  1408. * @param {BABYLON.Geometry} geometry - the geometry to be removed from the scene.
  1409. * @return {boolean} was the geometry removed or not
  1410. */
  1411. Scene.prototype.removeGeometry = function (geometry) {
  1412. var index = this._geometries.indexOf(geometry);
  1413. if (index > -1) {
  1414. this._geometries.splice(index, 1);
  1415. //notify the collision coordinator
  1416. this.collisionCoordinator.onGeometryDeleted(geometry);
  1417. this.onGeometryRemovedObservable.notifyObservers(geometry);
  1418. return true;
  1419. }
  1420. return false;
  1421. };
  1422. Scene.prototype.getGeometries = function () {
  1423. return this._geometries;
  1424. };
  1425. /**
  1426. * Get the first added mesh found of a given ID
  1427. * @param {string} id - the id to search for
  1428. * @return {BABYLON.AbstractMesh|null} the mesh found or null if not found at all.
  1429. */
  1430. Scene.prototype.getMeshByID = function (id) {
  1431. for (var index = 0; index < this.meshes.length; index++) {
  1432. if (this.meshes[index].id === id) {
  1433. return this.meshes[index];
  1434. }
  1435. }
  1436. return null;
  1437. };
  1438. Scene.prototype.getMeshesByID = function (id) {
  1439. return this.meshes.filter(function (m) {
  1440. return m.id === id;
  1441. });
  1442. };
  1443. /**
  1444. * Get a mesh with its auto-generated unique id
  1445. * @param {number} uniqueId - the unique id to search for
  1446. * @return {BABYLON.AbstractMesh|null} the mesh found or null if not found at all.
  1447. */
  1448. Scene.prototype.getMeshByUniqueID = function (uniqueId) {
  1449. for (var index = 0; index < this.meshes.length; index++) {
  1450. if (this.meshes[index].uniqueId === uniqueId) {
  1451. return this.meshes[index];
  1452. }
  1453. }
  1454. return null;
  1455. };
  1456. /**
  1457. * Get a the last added mesh found of a given ID
  1458. * @param {string} id - the id to search for
  1459. * @return {BABYLON.AbstractMesh|null} the mesh found or null if not found at all.
  1460. */
  1461. Scene.prototype.getLastMeshByID = function (id) {
  1462. for (var index = this.meshes.length - 1; index >= 0; index--) {
  1463. if (this.meshes[index].id === id) {
  1464. return this.meshes[index];
  1465. }
  1466. }
  1467. return null;
  1468. };
  1469. /**
  1470. * Get a the last added node (Mesh, Camera, Light) found of a given ID
  1471. * @param {string} id - the id to search for
  1472. * @return {BABYLON.Node|null} the node found or null if not found at all.
  1473. */
  1474. Scene.prototype.getLastEntryByID = function (id) {
  1475. var index;
  1476. for (index = this.meshes.length - 1; index >= 0; index--) {
  1477. if (this.meshes[index].id === id) {
  1478. return this.meshes[index];
  1479. }
  1480. }
  1481. for (index = this.cameras.length - 1; index >= 0; index--) {
  1482. if (this.cameras[index].id === id) {
  1483. return this.cameras[index];
  1484. }
  1485. }
  1486. for (index = this.lights.length - 1; index >= 0; index--) {
  1487. if (this.lights[index].id === id) {
  1488. return this.lights[index];
  1489. }
  1490. }
  1491. return null;
  1492. };
  1493. Scene.prototype.getNodeByID = function (id) {
  1494. var mesh = this.getMeshByID(id);
  1495. if (mesh) {
  1496. return mesh;
  1497. }
  1498. var light = this.getLightByID(id);
  1499. if (light) {
  1500. return light;
  1501. }
  1502. var camera = this.getCameraByID(id);
  1503. if (camera) {
  1504. return camera;
  1505. }
  1506. var bone = this.getBoneByID(id);
  1507. return bone;
  1508. };
  1509. Scene.prototype.getNodeByName = function (name) {
  1510. var mesh = this.getMeshByName(name);
  1511. if (mesh) {
  1512. return mesh;
  1513. }
  1514. var light = this.getLightByName(name);
  1515. if (light) {
  1516. return light;
  1517. }
  1518. var camera = this.getCameraByName(name);
  1519. if (camera) {
  1520. return camera;
  1521. }
  1522. var bone = this.getBoneByName(name);
  1523. return bone;
  1524. };
  1525. Scene.prototype.getMeshByName = function (name) {
  1526. for (var index = 0; index < this.meshes.length; index++) {
  1527. if (this.meshes[index].name === name) {
  1528. return this.meshes[index];
  1529. }
  1530. }
  1531. return null;
  1532. };
  1533. Scene.prototype.getSoundByName = function (name) {
  1534. var index;
  1535. if (BABYLON.AudioEngine) {
  1536. for (index = 0; index < this.mainSoundTrack.soundCollection.length; index++) {
  1537. if (this.mainSoundTrack.soundCollection[index].name === name) {
  1538. return this.mainSoundTrack.soundCollection[index];
  1539. }
  1540. }
  1541. for (var sdIndex = 0; sdIndex < this.soundTracks.length; sdIndex++) {
  1542. for (index = 0; index < this.soundTracks[sdIndex].soundCollection.length; index++) {
  1543. if (this.soundTracks[sdIndex].soundCollection[index].name === name) {
  1544. return this.soundTracks[sdIndex].soundCollection[index];
  1545. }
  1546. }
  1547. }
  1548. }
  1549. return null;
  1550. };
  1551. Scene.prototype.getLastSkeletonByID = function (id) {
  1552. for (var index = this.skeletons.length - 1; index >= 0; index--) {
  1553. if (this.skeletons[index].id === id) {
  1554. return this.skeletons[index];
  1555. }
  1556. }
  1557. return null;
  1558. };
  1559. Scene.prototype.getSkeletonById = function (id) {
  1560. for (var index = 0; index < this.skeletons.length; index++) {
  1561. if (this.skeletons[index].id === id) {
  1562. return this.skeletons[index];
  1563. }
  1564. }
  1565. return null;
  1566. };
  1567. Scene.prototype.getSkeletonByName = function (name) {
  1568. for (var index = 0; index < this.skeletons.length; index++) {
  1569. if (this.skeletons[index].name === name) {
  1570. return this.skeletons[index];
  1571. }
  1572. }
  1573. return null;
  1574. };
  1575. Scene.prototype.isActiveMesh = function (mesh) {
  1576. return (this._activeMeshes.indexOf(mesh) !== -1);
  1577. };
  1578. Object.defineProperty(Scene.prototype, "uid", {
  1579. /**
  1580. * Return a unique id as a string which can serve as an identifier for the scene
  1581. */
  1582. get: function () {
  1583. if (!this._uid) {
  1584. this._uid = BABYLON.Tools.RandomId();
  1585. }
  1586. return this._uid;
  1587. },
  1588. enumerable: true,
  1589. configurable: true
  1590. });
  1591. /**
  1592. * Add an externaly attached data from its key.
  1593. * This method call will fail and return false, if such key already exists.
  1594. * If you don't care and just want to get the data no matter what, use the more convenient getOrAddExternalDataWithFactory() method.
  1595. * @param key the unique key that identifies the data
  1596. * @param data the data object to associate to the key for this Engine instance
  1597. * @return true if no such key were already present and the data was added successfully, false otherwise
  1598. */
  1599. Scene.prototype.addExternalData = function (key, data) {
  1600. return this._externalData.add(key, data);
  1601. };
  1602. /**
  1603. * Get an externaly attached data from its key
  1604. * @param key the unique key that identifies the data
  1605. * @return the associated data, if present (can be null), or undefined if not present
  1606. */
  1607. Scene.prototype.getExternalData = function (key) {
  1608. return this._externalData.get(key);
  1609. };
  1610. /**
  1611. * Get an externaly attached data from its key, create it using a factory if it's not already present
  1612. * @param key the unique key that identifies the data
  1613. * @param factory the factory that will be called to create the instance if and only if it doesn't exists
  1614. * @return the associated data, can be null if the factory returned null.
  1615. */
  1616. Scene.prototype.getOrAddExternalDataWithFactory = function (key, factory) {
  1617. return this._externalData.getOrAddWithFactory(key, factory);
  1618. };
  1619. /**
  1620. * Remove an externaly attached data from the Engine instance
  1621. * @param key the unique key that identifies the data
  1622. * @return true if the data was successfully removed, false if it doesn't exist
  1623. */
  1624. Scene.prototype.removeExternalData = function (key) {
  1625. return this._externalData.remove(key);
  1626. };
  1627. Scene.prototype._evaluateSubMesh = function (subMesh, mesh) {
  1628. if (mesh.alwaysSelectAsActiveMesh || mesh.subMeshes.length === 1 || subMesh.isInFrustum(this._frustumPlanes)) {
  1629. var material = subMesh.getMaterial();
  1630. if (mesh.showSubMeshesBoundingBox) {
  1631. this._boundingBoxRenderer.renderList.push(subMesh.getBoundingInfo().boundingBox);
  1632. }
  1633. if (material) {
  1634. // Render targets
  1635. if (material.getRenderTargetTextures) {
  1636. if (this._processedMaterials.indexOf(material) === -1) {
  1637. this._processedMaterials.push(material);
  1638. this._renderTargets.concatWithNoDuplicate(material.getRenderTargetTextures());
  1639. }
  1640. }
  1641. // Dispatch
  1642. this._activeIndices.addCount(subMesh.indexCount, false);
  1643. this._renderingManager.dispatch(subMesh);
  1644. }
  1645. }
  1646. };
  1647. Scene.prototype._isInIntermediateRendering = function () {
  1648. return this._intermediateRendering;
  1649. };
  1650. Scene.prototype._evaluateActiveMeshes = function () {
  1651. this.activeCamera._activeMeshes.reset();
  1652. this._activeMeshes.reset();
  1653. this._renderingManager.reset();
  1654. this._processedMaterials.reset();
  1655. this._activeParticleSystems.reset();
  1656. this._activeSkeletons.reset();
  1657. this._softwareSkinnedMeshes.reset();
  1658. this._boundingBoxRenderer.reset();
  1659. this._edgesRenderers.reset();
  1660. // Meshes
  1661. var meshes;
  1662. var len;
  1663. if (this._selectionOctree) {
  1664. var selection = this._selectionOctree.select(this._frustumPlanes);
  1665. meshes = selection.data;
  1666. len = selection.length;
  1667. }
  1668. else {
  1669. len = this.meshes.length;
  1670. meshes = this.meshes;
  1671. }
  1672. for (var meshIndex = 0; meshIndex < len; meshIndex++) {
  1673. var mesh = meshes[meshIndex];
  1674. if (mesh.isBlocked) {
  1675. continue;
  1676. }
  1677. this._totalVertices.addCount(mesh.getTotalVertices(), false);
  1678. if (!mesh.isReady() || !mesh.isEnabled()) {
  1679. continue;
  1680. }
  1681. mesh.computeWorldMatrix();
  1682. // Intersections
  1683. if (mesh.actionManager && mesh.actionManager.hasSpecificTriggers([BABYLON.ActionManager.OnIntersectionEnterTrigger, BABYLON.ActionManager.OnIntersectionExitTrigger])) {
  1684. this._meshesForIntersections.pushNoDuplicate(mesh);
  1685. }
  1686. // Switch to current LOD
  1687. var meshLOD = mesh.getLOD(this.activeCamera);
  1688. if (!meshLOD) {
  1689. continue;
  1690. }
  1691. mesh._preActivate();
  1692. if (mesh.alwaysSelectAsActiveMesh || mesh.isVisible && mesh.visibility > 0 && ((mesh.layerMask & this.activeCamera.layerMask) !== 0) && mesh.isInFrustum(this._frustumPlanes)) {
  1693. this._activeMeshes.push(mesh);
  1694. this.activeCamera._activeMeshes.push(mesh);
  1695. mesh._activate(this._renderId);
  1696. this._activeMesh(mesh, meshLOD);
  1697. }
  1698. }
  1699. // Particle systems
  1700. this._particlesDuration.beginMonitoring();
  1701. var beforeParticlesDate = BABYLON.Tools.Now;
  1702. if (this.particlesEnabled) {
  1703. BABYLON.Tools.StartPerformanceCounter("Particles", this.particleSystems.length > 0);
  1704. for (var particleIndex = 0; particleIndex < this.particleSystems.length; particleIndex++) {
  1705. var particleSystem = this.particleSystems[particleIndex];
  1706. if (!particleSystem.isStarted()) {
  1707. continue;
  1708. }
  1709. if (!particleSystem.emitter.position || (particleSystem.emitter && particleSystem.emitter.isEnabled())) {
  1710. this._activeParticleSystems.push(particleSystem);
  1711. particleSystem.animate();
  1712. }
  1713. }
  1714. BABYLON.Tools.EndPerformanceCounter("Particles", this.particleSystems.length > 0);
  1715. }
  1716. this._particlesDuration.endMonitoring(false);
  1717. };
  1718. Scene.prototype._activeMesh = function (sourceMesh, mesh) {
  1719. if (mesh.skeleton && this.skeletonsEnabled) {
  1720. if (this._activeSkeletons.pushNoDuplicate(mesh.skeleton)) {
  1721. mesh.skeleton.prepare();
  1722. }
  1723. if (!mesh.computeBonesUsingShaders) {
  1724. this._softwareSkinnedMeshes.pushNoDuplicate(mesh);
  1725. }
  1726. }
  1727. if (sourceMesh.showBoundingBox || this.forceShowBoundingBoxes) {
  1728. this._boundingBoxRenderer.renderList.push(sourceMesh.getBoundingInfo().boundingBox);
  1729. }
  1730. if (sourceMesh._edgesRenderer) {
  1731. this._edgesRenderers.push(sourceMesh._edgesRenderer);
  1732. }
  1733. if (mesh && mesh.subMeshes) {
  1734. // Submeshes Octrees
  1735. var len;
  1736. var subMeshes;
  1737. if (mesh._submeshesOctree && mesh.useOctreeForRenderingSelection) {
  1738. var intersections = mesh._submeshesOctree.select(this._frustumPlanes);
  1739. len = intersections.length;
  1740. subMeshes = intersections.data;
  1741. }
  1742. else {
  1743. subMeshes = mesh.subMeshes;
  1744. len = subMeshes.length;
  1745. }
  1746. for (var subIndex = 0; subIndex < len; subIndex++) {
  1747. var subMesh = subMeshes[subIndex];
  1748. this._evaluateSubMesh(subMesh, mesh);
  1749. }
  1750. }
  1751. };
  1752. Scene.prototype.updateTransformMatrix = function (force) {
  1753. this.setTransformMatrix(this.activeCamera.getViewMatrix(), this.activeCamera.getProjectionMatrix(force));
  1754. };
  1755. Scene.prototype._renderForCamera = function (camera) {
  1756. var engine = this._engine;
  1757. var startTime = BABYLON.Tools.Now;
  1758. this.activeCamera = camera;
  1759. if (!this.activeCamera)
  1760. throw new Error("Active camera not set");
  1761. BABYLON.Tools.StartPerformanceCounter("Rendering camera " + this.activeCamera.name);
  1762. // Viewport
  1763. engine.setViewport(this.activeCamera.viewport);
  1764. // Camera
  1765. this.resetCachedMaterial();
  1766. this._renderId++;
  1767. this.updateTransformMatrix();
  1768. this.onBeforeCameraRenderObservable.notifyObservers(this.activeCamera);
  1769. // Meshes
  1770. this._evaluateActiveMeshesDuration.beginMonitoring();
  1771. BABYLON.Tools.StartPerformanceCounter("Active meshes evaluation");
  1772. this._evaluateActiveMeshes();
  1773. this._evaluateActiveMeshesDuration.endMonitoring(false);
  1774. BABYLON.Tools.EndPerformanceCounter("Active meshes evaluation");
  1775. // Software skinning
  1776. for (var softwareSkinnedMeshIndex = 0; softwareSkinnedMeshIndex < this._softwareSkinnedMeshes.length; softwareSkinnedMeshIndex++) {
  1777. var mesh = this._softwareSkinnedMeshes.data[softwareSkinnedMeshIndex];
  1778. mesh.applySkeleton(mesh.skeleton);
  1779. }
  1780. // Render targets
  1781. this._renderTargetsDuration.beginMonitoring();
  1782. var beforeRenderTargetDate = BABYLON.Tools.Now;
  1783. if (this.renderTargetsEnabled && this._renderTargets.length > 0) {
  1784. this._intermediateRendering = true;
  1785. BABYLON.Tools.StartPerformanceCounter("Render targets", this._renderTargets.length > 0);
  1786. for (var renderIndex = 0; renderIndex < this._renderTargets.length; renderIndex++) {
  1787. var renderTarget = this._renderTargets.data[renderIndex];
  1788. if (renderTarget._shouldRender()) {
  1789. this._renderId++;
  1790. var hasSpecialRenderTargetCamera = renderTarget.activeCamera && renderTarget.activeCamera !== this.activeCamera;
  1791. renderTarget.render(hasSpecialRenderTargetCamera, this.dumpNextRenderTargets);
  1792. }
  1793. }
  1794. BABYLON.Tools.EndPerformanceCounter("Render targets", this._renderTargets.length > 0);
  1795. this._intermediateRendering = false;
  1796. this._renderId++;
  1797. engine.restoreDefaultFramebuffer(); // Restore back buffer
  1798. }
  1799. this._renderTargetsDuration.endMonitoring(false);
  1800. // Prepare Frame
  1801. this.postProcessManager._prepareFrame();
  1802. this._renderDuration.beginMonitoring();
  1803. // Backgrounds
  1804. var layerIndex;
  1805. var layer;
  1806. if (this.layers.length) {
  1807. engine.setDepthBuffer(false);
  1808. for (layerIndex = 0; layerIndex < this.layers.length; layerIndex++) {
  1809. layer = this.layers[layerIndex];
  1810. if (layer.isBackground) {
  1811. layer.render();
  1812. }
  1813. }
  1814. engine.setDepthBuffer(true);
  1815. }
  1816. // Render
  1817. BABYLON.Tools.StartPerformanceCounter("Main render");
  1818. // Activate HighlightLayer stencil
  1819. var stencilState = this._engine.getStencilBuffer();
  1820. var renderhighlights = false;
  1821. if (this.highlightLayers && this.highlightLayers.length > 0) {
  1822. for (var i = 0; i < this.highlightLayers.length; i++) {
  1823. var highlightLayer = this.highlightLayers[i];
  1824. if ((!highlightLayer.camera || camera == highlightLayer.camera) && highlightLayer.shouldRender()) {
  1825. renderhighlights = true;
  1826. this._engine.setStencilBuffer(true);
  1827. break;
  1828. }
  1829. }
  1830. }
  1831. this._renderingManager.render(null, null, true, true);
  1832. // Restore HighlightLayer stencil
  1833. if (renderhighlights) {
  1834. this._engine.setStencilBuffer(stencilState);
  1835. }
  1836. BABYLON.Tools.EndPerformanceCounter("Main render");
  1837. // Bounding boxes
  1838. this._boundingBoxRenderer.render();
  1839. // Edges
  1840. for (var edgesRendererIndex = 0; edgesRendererIndex < this._edgesRenderers.length; edgesRendererIndex++) {
  1841. this._edgesRenderers.data[edgesRendererIndex].render();
  1842. }
  1843. // Lens flares
  1844. if (this.lensFlaresEnabled) {
  1845. BABYLON.Tools.StartPerformanceCounter("Lens flares", this.lensFlareSystems.length > 0);
  1846. for (var lensFlareSystemIndex = 0; lensFlareSystemIndex < this.lensFlareSystems.length; lensFlareSystemIndex++) {
  1847. var lensFlareSystem = this.lensFlareSystems[lensFlareSystemIndex];
  1848. if ((camera.layerMask & lensFlareSystem.layerMask) !== 0) {
  1849. lensFlareSystem.render();
  1850. }
  1851. }
  1852. BABYLON.Tools.EndPerformanceCounter("Lens flares", this.lensFlareSystems.length > 0);
  1853. }
  1854. // Foregrounds
  1855. if (this.layers.length) {
  1856. engine.setDepthBuffer(false);
  1857. for (layerIndex = 0; layerIndex < this.layers.length; layerIndex++) {
  1858. layer = this.layers[layerIndex];
  1859. if (!layer.isBackground) {
  1860. layer.render();
  1861. }
  1862. }
  1863. engine.setDepthBuffer(true);
  1864. }
  1865. // Highlight Layer
  1866. if (renderhighlights) {
  1867. engine.setDepthBuffer(false);
  1868. for (var i = 0; i < this.highlightLayers.length; i++) {
  1869. if (this.highlightLayers[i].shouldRender()) {
  1870. this.highlightLayers[i].render();
  1871. }
  1872. }
  1873. engine.setDepthBuffer(true);
  1874. }
  1875. this._renderDuration.endMonitoring(false);
  1876. // Finalize frame
  1877. this.postProcessManager._finalizeFrame(camera.isIntermediate);
  1878. // Update camera
  1879. this.activeCamera._updateFromScene();
  1880. // Reset some special arrays
  1881. this._renderTargets.reset();
  1882. this.onAfterCameraRenderObservable.notifyObservers(this.activeCamera);
  1883. BABYLON.Tools.EndPerformanceCounter("Rendering camera " + this.activeCamera.name);
  1884. };
  1885. Scene.prototype._processSubCameras = function (camera) {
  1886. if (camera.cameraRigMode === BABYLON.Camera.RIG_MODE_NONE) {
  1887. this._renderForCamera(camera);
  1888. return;
  1889. }
  1890. // rig cameras
  1891. for (var index = 0; index < camera._rigCameras.length; index++) {
  1892. this._renderForCamera(camera._rigCameras[index]);
  1893. }
  1894. this.activeCamera = camera;
  1895. this.setTransformMatrix(this.activeCamera.getViewMatrix(), this.activeCamera.getProjectionMatrix());
  1896. // Update camera
  1897. this.activeCamera._updateFromScene();
  1898. };
  1899. Scene.prototype._checkIntersections = function () {
  1900. for (var index = 0; index < this._meshesForIntersections.length; index++) {
  1901. var sourceMesh = this._meshesForIntersections.data[index];
  1902. for (var actionIndex = 0; actionIndex < sourceMesh.actionManager.actions.length; actionIndex++) {
  1903. var action = sourceMesh.actionManager.actions[actionIndex];
  1904. if (action.trigger === BABYLON.ActionManager.OnIntersectionEnterTrigger || action.trigger === BABYLON.ActionManager.OnIntersectionExitTrigger) {
  1905. var parameters = action.getTriggerParameter();
  1906. var otherMesh = parameters instanceof BABYLON.AbstractMesh ? parameters : parameters.mesh;
  1907. var areIntersecting = otherMesh.intersectsMesh(sourceMesh, parameters.usePreciseIntersection);
  1908. var currentIntersectionInProgress = sourceMesh._intersectionsInProgress.indexOf(otherMesh);
  1909. if (areIntersecting && currentIntersectionInProgress === -1) {
  1910. if (action.trigger === BABYLON.ActionManager.OnIntersectionEnterTrigger) {
  1911. action._executeCurrent(BABYLON.ActionEvent.CreateNew(sourceMesh, null, otherMesh));
  1912. sourceMesh._intersectionsInProgress.push(otherMesh);
  1913. }
  1914. else if (action.trigger === BABYLON.ActionManager.OnIntersectionExitTrigger) {
  1915. sourceMesh._intersectionsInProgress.push(otherMesh);
  1916. }
  1917. }
  1918. else if (!areIntersecting && currentIntersectionInProgress > -1) {
  1919. //They intersected, and now they don't.
  1920. //is this trigger an exit trigger? execute an event.
  1921. if (action.trigger === BABYLON.ActionManager.OnIntersectionExitTrigger) {
  1922. action._executeCurrent(BABYLON.ActionEvent.CreateNew(sourceMesh, null, otherMesh));
  1923. }
  1924. //if this is an exit trigger, or no exit trigger exists, remove the id from the intersection in progress array.
  1925. if (!sourceMesh.actionManager.hasSpecificTrigger(BABYLON.ActionManager.OnIntersectionExitTrigger) || action.trigger === BABYLON.ActionManager.OnIntersectionExitTrigger) {
  1926. sourceMesh._intersectionsInProgress.splice(currentIntersectionInProgress, 1);
  1927. }
  1928. }
  1929. }
  1930. }
  1931. }
  1932. };
  1933. Scene.prototype.render = function () {
  1934. this._lastFrameDuration.beginMonitoring();
  1935. this._particlesDuration.fetchNewFrame();
  1936. this._spritesDuration.fetchNewFrame();
  1937. this._activeParticles.fetchNewFrame();
  1938. this._renderDuration.fetchNewFrame();
  1939. this._renderTargetsDuration.fetchNewFrame();
  1940. this._evaluateActiveMeshesDuration.fetchNewFrame();
  1941. this._totalVertices.fetchNewFrame();
  1942. this._activeIndices.fetchNewFrame();
  1943. this._activeBones.fetchNewFrame();
  1944. this.getEngine().drawCallsPerfCounter.fetchNewFrame();
  1945. this._meshesForIntersections.reset();
  1946. this.resetCachedMaterial();
  1947. BABYLON.Tools.StartPerformanceCounter("Scene rendering");
  1948. // Actions
  1949. if (this.actionManager) {
  1950. this.actionManager.processTrigger(BABYLON.ActionManager.OnEveryFrameTrigger, null);
  1951. }
  1952. //Simplification Queue
  1953. if (this.simplificationQueue && !this.simplificationQueue.running) {
  1954. this.simplificationQueue.executeNext();
  1955. }
  1956. // Animations
  1957. var deltaTime = Math.max(Scene.MinDeltaTime, Math.min(this._engine.getDeltaTime(), Scene.MaxDeltaTime));
  1958. this._animationRatio = deltaTime * (60.0 / 1000.0);
  1959. this._animate();
  1960. // Physics
  1961. if (this._physicsEngine) {
  1962. BABYLON.Tools.StartPerformanceCounter("Physics");
  1963. this._physicsEngine._step(deltaTime / 1000.0);
  1964. BABYLON.Tools.EndPerformanceCounter("Physics");
  1965. }
  1966. // Before render
  1967. this.onBeforeRenderObservable.notifyObservers(this);
  1968. // Customs render targets
  1969. this._renderTargetsDuration.beginMonitoring();
  1970. var beforeRenderTargetDate = BABYLON.Tools.Now;
  1971. var engine = this.getEngine();
  1972. var currentActiveCamera = this.activeCamera;
  1973. if (this.renderTargetsEnabled) {
  1974. BABYLON.Tools.StartPerformanceCounter("Custom render targets", this.customRenderTargets.length > 0);
  1975. for (var customIndex = 0; customIndex < this.customRenderTargets.length; customIndex++) {
  1976. var renderTarget = this.customRenderTargets[customIndex];
  1977. if (renderTarget._shouldRender()) {
  1978. this._renderId++;
  1979. this.activeCamera = renderTarget.activeCamera || this.activeCamera;
  1980. if (!this.activeCamera)
  1981. throw new Error("Active camera not set");
  1982. // Viewport
  1983. engine.setViewport(this.activeCamera.viewport);
  1984. // Camera
  1985. this.updateTransformMatrix();
  1986. renderTarget.render(currentActiveCamera !== this.activeCamera, this.dumpNextRenderTargets);
  1987. }
  1988. }
  1989. BABYLON.Tools.EndPerformanceCounter("Custom render targets", this.customRenderTargets.length > 0);
  1990. this._renderId++;
  1991. }
  1992. if (this.customRenderTargets.length > 0) {
  1993. engine.restoreDefaultFramebuffer();
  1994. }
  1995. this._renderTargetsDuration.endMonitoring();
  1996. this.activeCamera = currentActiveCamera;
  1997. // Procedural textures
  1998. if (this.proceduralTexturesEnabled) {
  1999. BABYLON.Tools.StartPerformanceCounter("Procedural textures", this._proceduralTextures.length > 0);
  2000. for (var proceduralIndex = 0; proceduralIndex < this._proceduralTextures.length; proceduralIndex++) {
  2001. var proceduralTexture = this._proceduralTextures[proceduralIndex];
  2002. if (proceduralTexture._shouldRender()) {
  2003. proceduralTexture.render();
  2004. }
  2005. }
  2006. BABYLON.Tools.EndPerformanceCounter("Procedural textures", this._proceduralTextures.length > 0);
  2007. }
  2008. // Clear
  2009. this._engine.clear(this.clearColor, this.autoClear || this.forceWireframe || this.forcePointsCloud, true, true);
  2010. // Shadows
  2011. if (this.shadowsEnabled) {
  2012. for (var lightIndex = 0; lightIndex < this.lights.length; lightIndex++) {
  2013. var light = this.lights[lightIndex];
  2014. var shadowGenerator = light.getShadowGenerator();
  2015. if (light.isEnabled() && shadowGenerator && shadowGenerator.getShadowMap().getScene().textures.indexOf(shadowGenerator.getShadowMap()) !== -1) {
  2016. this._renderTargets.push(shadowGenerator.getShadowMap());
  2017. }
  2018. }
  2019. }
  2020. // Depth renderer
  2021. if (this._depthRenderer) {
  2022. this._renderTargets.push(this._depthRenderer.getDepthMap());
  2023. }
  2024. // HighlightLayer
  2025. if (this.highlightLayers && this.highlightLayers.length > 0) {
  2026. for (var i = 0; i < this.highlightLayers.length; i++) {
  2027. if (this.highlightLayers[i].shouldRender()) {
  2028. this._renderTargets.push(this.highlightLayers[i]._mainTexture);
  2029. }
  2030. }
  2031. }
  2032. // RenderPipeline
  2033. this.postProcessRenderPipelineManager.update();
  2034. // Multi-cameras?
  2035. if (this.activeCameras.length > 0) {
  2036. var currentRenderId = this._renderId;
  2037. for (var cameraIndex = 0; cameraIndex < this.activeCameras.length; cameraIndex++) {
  2038. this._renderId = currentRenderId;
  2039. if (cameraIndex > 0) {
  2040. this._engine.clear(0, false, true, true);
  2041. }
  2042. this._processSubCameras(this.activeCameras[cameraIndex]);
  2043. }
  2044. }
  2045. else {
  2046. if (!this.activeCamera) {
  2047. throw new Error("No camera defined");
  2048. }
  2049. this._processSubCameras(this.activeCamera);
  2050. }
  2051. // Intersection checks
  2052. this._checkIntersections();
  2053. // Update the audio listener attached to the camera
  2054. if (BABYLON.AudioEngine) {
  2055. this._updateAudioParameters();
  2056. }
  2057. // After render
  2058. if (this.afterRender) {
  2059. this.afterRender();
  2060. }
  2061. this.onAfterRenderObservable.notifyObservers(this);
  2062. // Cleaning
  2063. for (var index = 0; index < this._toBeDisposed.length; index++) {
  2064. this._toBeDisposed.data[index].dispose();
  2065. this._toBeDisposed[index] = null;
  2066. }
  2067. this._toBeDisposed.reset();
  2068. if (this.dumpNextRenderTargets) {
  2069. this.dumpNextRenderTargets = false;
  2070. }
  2071. BABYLON.Tools.EndPerformanceCounter("Scene rendering");
  2072. this._lastFrameDuration.endMonitoring();
  2073. this._totalMeshesCounter.addCount(this.meshes.length, true);
  2074. this._totalLightsCounter.addCount(this.lights.length, true);
  2075. this._totalMaterialsCounter.addCount(this.materials.length, true);
  2076. this._totalTexturesCounter.addCount(this.textures.length, true);
  2077. this._activeBones.addCount(0, true);
  2078. this._activeIndices.addCount(0, true);
  2079. this._activeParticles.addCount(0, true);
  2080. };
  2081. Scene.prototype._updateAudioParameters = function () {
  2082. if (!this.audioEnabled || (this.mainSoundTrack.soundCollection.length === 0 && this.soundTracks.length === 1)) {
  2083. return;
  2084. }
  2085. var listeningCamera;
  2086. var audioEngine = BABYLON.Engine.audioEngine;
  2087. if (this.activeCameras.length > 0) {
  2088. listeningCamera = this.activeCameras[0];
  2089. }
  2090. else {
  2091. listeningCamera = this.activeCamera;
  2092. }
  2093. if (listeningCamera && audioEngine.canUseWebAudio) {
  2094. audioEngine.audioContext.listener.setPosition(listeningCamera.position.x, listeningCamera.position.y, listeningCamera.position.z);
  2095. var mat = BABYLON.Matrix.Invert(listeningCamera.getViewMatrix());
  2096. var cameraDirection = BABYLON.Vector3.TransformNormal(new BABYLON.Vector3(0, 0, -1), mat);
  2097. cameraDirection.normalize();
  2098. audioEngine.audioContext.listener.setOrientation(cameraDirection.x, cameraDirection.y, cameraDirection.z, 0, 1, 0);
  2099. var i;
  2100. for (i = 0; i < this.mainSoundTrack.soundCollection.length; i++) {
  2101. var sound = this.mainSoundTrack.soundCollection[i];
  2102. if (sound.useCustomAttenuation) {
  2103. sound.updateDistanceFromListener();
  2104. }
  2105. }
  2106. for (i = 0; i < this.soundTracks.length; i++) {
  2107. for (var j = 0; j < this.soundTracks[i].soundCollection.length; j++) {
  2108. sound = this.soundTracks[i].soundCollection[j];
  2109. if (sound.useCustomAttenuation) {
  2110. sound.updateDistanceFromListener();
  2111. }
  2112. }
  2113. }
  2114. }
  2115. };
  2116. Object.defineProperty(Scene.prototype, "audioEnabled", {
  2117. // Audio
  2118. get: function () {
  2119. return this._audioEnabled;
  2120. },
  2121. set: function (value) {
  2122. this._audioEnabled = value;
  2123. if (BABYLON.AudioEngine) {
  2124. if (this._audioEnabled) {
  2125. this._enableAudio();
  2126. }
  2127. else {
  2128. this._disableAudio();
  2129. }
  2130. }
  2131. },
  2132. enumerable: true,
  2133. configurable: true
  2134. });
  2135. Scene.prototype._disableAudio = function () {
  2136. var i;
  2137. for (i = 0; i < this.mainSoundTrack.soundCollection.length; i++) {
  2138. this.mainSoundTrack.soundCollection[i].pause();
  2139. }
  2140. for (i = 0; i < this.soundTracks.length; i++) {
  2141. for (var j = 0; j < this.soundTracks[i].soundCollection.length; j++) {
  2142. this.soundTracks[i].soundCollection[j].pause();
  2143. }
  2144. }
  2145. };
  2146. Scene.prototype._enableAudio = function () {
  2147. var i;
  2148. for (i = 0; i < this.mainSoundTrack.soundCollection.length; i++) {
  2149. if (this.mainSoundTrack.soundCollection[i].isPaused) {
  2150. this.mainSoundTrack.soundCollection[i].play();
  2151. }
  2152. }
  2153. for (i = 0; i < this.soundTracks.length; i++) {
  2154. for (var j = 0; j < this.soundTracks[i].soundCollection.length; j++) {
  2155. if (this.soundTracks[i].soundCollection[j].isPaused) {
  2156. this.soundTracks[i].soundCollection[j].play();
  2157. }
  2158. }
  2159. }
  2160. };
  2161. Object.defineProperty(Scene.prototype, "headphone", {
  2162. get: function () {
  2163. return this._headphone;
  2164. },
  2165. set: function (value) {
  2166. this._headphone = value;
  2167. if (BABYLON.AudioEngine) {
  2168. if (this._headphone) {
  2169. this._switchAudioModeForHeadphones();
  2170. }
  2171. else {
  2172. this._switchAudioModeForNormalSpeakers();
  2173. }
  2174. }
  2175. },
  2176. enumerable: true,
  2177. configurable: true
  2178. });
  2179. Scene.prototype._switchAudioModeForHeadphones = function () {
  2180. this.mainSoundTrack.switchPanningModelToHRTF();
  2181. for (var i = 0; i < this.soundTracks.length; i++) {
  2182. this.soundTracks[i].switchPanningModelToHRTF();
  2183. }
  2184. };
  2185. Scene.prototype._switchAudioModeForNormalSpeakers = function () {
  2186. this.mainSoundTrack.switchPanningModelToEqualPower();
  2187. for (var i = 0; i < this.soundTracks.length; i++) {
  2188. this.soundTracks[i].switchPanningModelToEqualPower();
  2189. }
  2190. };
  2191. Scene.prototype.enableDepthRenderer = function () {
  2192. if (this._depthRenderer) {
  2193. return this._depthRenderer;
  2194. }
  2195. this._depthRenderer = new BABYLON.DepthRenderer(this);
  2196. return this._depthRenderer;
  2197. };
  2198. Scene.prototype.disableDepthRenderer = function () {
  2199. if (!this._depthRenderer) {
  2200. return;
  2201. }
  2202. this._depthRenderer.dispose();
  2203. this._depthRenderer = null;
  2204. };
  2205. Scene.prototype.freezeMaterials = function () {
  2206. for (var i = 0; i < this.materials.length; i++) {
  2207. this.materials[i].freeze();
  2208. }
  2209. };
  2210. Scene.prototype.unfreezeMaterials = function () {
  2211. for (var i = 0; i < this.materials.length; i++) {
  2212. this.materials[i].unfreeze();
  2213. }
  2214. };
  2215. Scene.prototype.dispose = function () {
  2216. this.beforeRender = null;
  2217. this.afterRender = null;
  2218. this.skeletons = [];
  2219. this._boundingBoxRenderer.dispose();
  2220. if (this._depthRenderer) {
  2221. this._depthRenderer.dispose();
  2222. }
  2223. // Debug layer
  2224. if (this._debugLayer) {
  2225. this._debugLayer.hide();
  2226. }
  2227. // Events
  2228. this.onDisposeObservable.notifyObservers(this);
  2229. this.onDisposeObservable.clear();
  2230. this.onBeforeRenderObservable.clear();
  2231. this.onAfterRenderObservable.clear();
  2232. this.detachControl();
  2233. // Release sounds & sounds tracks
  2234. if (BABYLON.AudioEngine) {
  2235. this.disposeSounds();
  2236. }
  2237. // Detach cameras
  2238. var canvas = this._engine.getRenderingCanvas();
  2239. var index;
  2240. for (index = 0; index < this.cameras.length; index++) {
  2241. this.cameras[index].detachControl(canvas);
  2242. }
  2243. // Release lights
  2244. while (this.lights.length) {
  2245. this.lights[0].dispose();
  2246. }
  2247. // Release meshes
  2248. while (this.meshes.length) {
  2249. this.meshes[0].dispose(true);
  2250. }
  2251. // Release cameras
  2252. while (this.cameras.length) {
  2253. this.cameras[0].dispose();
  2254. }
  2255. // Release materials
  2256. while (this.materials.length) {
  2257. this.materials[0].dispose();
  2258. }
  2259. // Release particles
  2260. while (this.particleSystems.length) {
  2261. this.particleSystems[0].dispose();
  2262. }
  2263. // Release sprites
  2264. while (this.spriteManagers.length) {
  2265. this.spriteManagers[0].dispose();
  2266. }
  2267. // Release layers
  2268. while (this.layers.length) {
  2269. this.layers[0].dispose();
  2270. }
  2271. while (this.highlightLayers.length) {
  2272. this.highlightLayers[0].dispose();
  2273. }
  2274. // Release textures
  2275. while (this.textures.length) {
  2276. this.textures[0].dispose();
  2277. }
  2278. // Post-processes
  2279. this.postProcessManager.dispose();
  2280. // Physics
  2281. if (this._physicsEngine) {
  2282. this.disablePhysicsEngine();
  2283. }
  2284. // Remove from engine
  2285. index = this._engine.scenes.indexOf(this);
  2286. if (index > -1) {
  2287. this._engine.scenes.splice(index, 1);
  2288. }
  2289. this._engine.wipeCaches();
  2290. };
  2291. // Release sounds & sounds tracks
  2292. Scene.prototype.disposeSounds = function () {
  2293. this.mainSoundTrack.dispose();
  2294. for (var scIndex = 0; scIndex < this.soundTracks.length; scIndex++) {
  2295. this.soundTracks[scIndex].dispose();
  2296. }
  2297. };
  2298. // Octrees
  2299. Scene.prototype.getWorldExtends = function () {
  2300. var min = new BABYLON.Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
  2301. var max = new BABYLON.Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
  2302. for (var index = 0; index < this.meshes.length; index++) {
  2303. var mesh = this.meshes[index];
  2304. mesh.computeWorldMatrix(true);
  2305. var minBox = mesh.getBoundingInfo().boundingBox.minimumWorld;
  2306. var maxBox = mesh.getBoundingInfo().boundingBox.maximumWorld;
  2307. BABYLON.Tools.CheckExtends(minBox, min, max);
  2308. BABYLON.Tools.CheckExtends(maxBox, min, max);
  2309. }
  2310. return {
  2311. min: min,
  2312. max: max
  2313. };
  2314. };
  2315. Scene.prototype.createOrUpdateSelectionOctree = function (maxCapacity, maxDepth) {
  2316. if (maxCapacity === void 0) { maxCapacity = 64; }
  2317. if (maxDepth === void 0) { maxDepth = 2; }
  2318. if (!this._selectionOctree) {
  2319. this._selectionOctree = new BABYLON.Octree(BABYLON.Octree.CreationFuncForMeshes, maxCapacity, maxDepth);
  2320. }
  2321. var worldExtends = this.getWorldExtends();
  2322. // Update octree
  2323. this._selectionOctree.update(worldExtends.min, worldExtends.max, this.meshes);
  2324. return this._selectionOctree;
  2325. };
  2326. // Picking
  2327. Scene.prototype.createPickingRay = function (x, y, world, camera, cameraViewSpace) {
  2328. if (cameraViewSpace === void 0) { cameraViewSpace = false; }
  2329. var engine = this._engine;
  2330. if (!camera) {
  2331. if (!this.activeCamera)
  2332. throw new Error("Active camera not set");
  2333. camera = this.activeCamera;
  2334. }
  2335. var cameraViewport = camera.viewport;
  2336. var viewport = cameraViewport.toGlobal(engine.getRenderWidth(), engine.getRenderHeight());
  2337. // Moving coordinates to local viewport world
  2338. x = x / this._engine.getHardwareScalingLevel() - viewport.x;
  2339. y = y / this._engine.getHardwareScalingLevel() - (this._engine.getRenderHeight() - viewport.y - viewport.height);
  2340. return BABYLON.Ray.CreateNew(x, y, viewport.width, viewport.height, world ? world : BABYLON.Matrix.Identity(), cameraViewSpace ? BABYLON.Matrix.Identity() : camera.getViewMatrix(), camera.getProjectionMatrix());
  2341. // return BABYLON.Ray.CreateNew(x / window.devicePixelRatio, y / window.devicePixelRatio, viewport.width, viewport.height, world ? world : BABYLON.Matrix.Identity(), camera.getViewMatrix(), camera.getProjectionMatrix());
  2342. };
  2343. Scene.prototype.createPickingRayInCameraSpace = function (x, y, camera) {
  2344. var engine = this._engine;
  2345. if (!camera) {
  2346. if (!this.activeCamera)
  2347. throw new Error("Active camera not set");
  2348. camera = this.activeCamera;
  2349. }
  2350. var cameraViewport = camera.viewport;
  2351. var viewport = cameraViewport.toGlobal(engine.getRenderWidth(), engine.getRenderHeight());
  2352. var identity = BABYLON.Matrix.Identity();
  2353. // Moving coordinates to local viewport world
  2354. x = x / this._engine.getHardwareScalingLevel() - viewport.x;
  2355. y = y / this._engine.getHardwareScalingLevel() - (this._engine.getRenderHeight() - viewport.y - viewport.height);
  2356. return BABYLON.Ray.CreateNew(x, y, viewport.width, viewport.height, identity, identity, camera.getProjectionMatrix());
  2357. };
  2358. Scene.prototype._internalPick = function (rayFunction, predicate, fastCheck) {
  2359. var pickingInfo = null;
  2360. for (var meshIndex = 0; meshIndex < this.meshes.length; meshIndex++) {
  2361. var mesh = this.meshes[meshIndex];
  2362. if (predicate) {
  2363. if (!predicate(mesh)) {
  2364. continue;
  2365. }
  2366. }
  2367. else if (!mesh.isEnabled() || !mesh.isVisible || !mesh.isPickable) {
  2368. continue;
  2369. }
  2370. var world = mesh.getWorldMatrix();
  2371. var ray = rayFunction(world);
  2372. var result = mesh.intersects(ray, fastCheck);
  2373. if (!result || !result.hit)
  2374. continue;
  2375. if (!fastCheck && pickingInfo != null && result.distance >= pickingInfo.distance)
  2376. continue;
  2377. pickingInfo = result;
  2378. if (fastCheck) {
  2379. break;
  2380. }
  2381. }
  2382. return pickingInfo || new BABYLON.PickingInfo();
  2383. };
  2384. Scene.prototype._internalPickSprites = function (ray, predicate, fastCheck, camera) {
  2385. var pickingInfo = null;
  2386. camera = camera || this.activeCamera;
  2387. if (this.spriteManagers.length > 0) {
  2388. for (var spriteIndex = 0; spriteIndex < this.spriteManagers.length; spriteIndex++) {
  2389. var spriteManager = this.spriteManagers[spriteIndex];
  2390. if (!spriteManager.isPickable) {
  2391. continue;
  2392. }
  2393. var result = spriteManager.intersects(ray, camera, predicate, fastCheck);
  2394. if (!result || !result.hit)
  2395. continue;
  2396. if (!fastCheck && pickingInfo != null && result.distance >= pickingInfo.distance)
  2397. continue;
  2398. pickingInfo = result;
  2399. if (fastCheck) {
  2400. break;
  2401. }
  2402. }
  2403. }
  2404. return pickingInfo || new BABYLON.PickingInfo();
  2405. };
  2406. Scene.prototype.pick = function (x, y, predicate, fastCheck, camera) {
  2407. var _this = this;
  2408. /// <summary>Launch a ray to try to pick a mesh in the scene</summary>
  2409. /// <param name="x">X position on screen</param>
  2410. /// <param name="y">Y position on screen</param>
  2411. /// <param name="predicate">Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true</param>
  2412. /// <param name="fastCheck">Launch a fast check only using the bounding boxes. Can be set to null.</param>
  2413. /// <param name="camera">camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used</param>
  2414. return this._internalPick(function (world) { return _this.createPickingRay(x, y, world, camera); }, predicate, fastCheck);
  2415. };
  2416. Scene.prototype.pickSprite = function (x, y, predicate, fastCheck, camera) {
  2417. /// <summary>Launch a ray to try to pick a mesh in the scene</summary>
  2418. /// <param name="x">X position on screen</param>
  2419. /// <param name="y">Y position on screen</param>
  2420. /// <param name="predicate">Predicate function used to determine eligible sprites. Can be set to null. In this case, a sprite must have isPickable set to true</param>
  2421. /// <param name="fastCheck">Launch a fast check only using the bounding boxes. Can be set to null.</param>
  2422. /// <param name="camera">camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used</param>
  2423. return this._internalPickSprites(this.createPickingRayInCameraSpace(x, y, camera), predicate, fastCheck, camera);
  2424. };
  2425. Scene.prototype.pickWithRay = function (ray, predicate, fastCheck) {
  2426. var _this = this;
  2427. return this._internalPick(function (world) {
  2428. if (!_this._pickWithRayInverseMatrix) {
  2429. _this._pickWithRayInverseMatrix = BABYLON.Matrix.Identity();
  2430. }
  2431. world.invertToRef(_this._pickWithRayInverseMatrix);
  2432. return BABYLON.Ray.Transform(ray, _this._pickWithRayInverseMatrix);
  2433. }, predicate, fastCheck);
  2434. };
  2435. Scene.prototype.setPointerOverMesh = function (mesh) {
  2436. if (this._pointerOverMesh === mesh) {
  2437. return;
  2438. }
  2439. if (this._pointerOverMesh && this._pointerOverMesh.actionManager) {
  2440. this._pointerOverMesh.actionManager.processTrigger(BABYLON.ActionManager.OnPointerOutTrigger, BABYLON.ActionEvent.CreateNew(this._pointerOverMesh));
  2441. }
  2442. this._pointerOverMesh = mesh;
  2443. if (this._pointerOverMesh && this._pointerOverMesh.actionManager) {
  2444. this._pointerOverMesh.actionManager.processTrigger(BABYLON.ActionManager.OnPointerOverTrigger, BABYLON.ActionEvent.CreateNew(this._pointerOverMesh));
  2445. }
  2446. };
  2447. Scene.prototype.getPointerOverMesh = function () {
  2448. return this._pointerOverMesh;
  2449. };
  2450. Scene.prototype.setPointerOverSprite = function (sprite) {
  2451. if (this._pointerOverSprite === sprite) {
  2452. return;
  2453. }
  2454. if (this._pointerOverSprite && this._pointerOverSprite.actionManager) {
  2455. this._pointerOverSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPointerOutTrigger, BABYLON.ActionEvent.CreateNewFromSprite(this._pointerOverSprite, this));
  2456. }
  2457. this._pointerOverSprite = sprite;
  2458. if (this._pointerOverSprite && this._pointerOverSprite.actionManager) {
  2459. this._pointerOverSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPointerOverTrigger, BABYLON.ActionEvent.CreateNewFromSprite(this._pointerOverSprite, this));
  2460. }
  2461. };
  2462. Scene.prototype.getPointerOverSprite = function () {
  2463. return this._pointerOverSprite;
  2464. };
  2465. // Physics
  2466. Scene.prototype.getPhysicsEngine = function () {
  2467. return this._physicsEngine;
  2468. };
  2469. /**
  2470. * Enables physics to the current scene
  2471. * @param {BABYLON.Vector3} [gravity] - the scene's gravity for the physics engine
  2472. * @param {BABYLON.IPhysicsEnginePlugin} [plugin] - The physics engine to be used. defaults to OimoJS.
  2473. * @return {boolean} was the physics engine initialized
  2474. */
  2475. Scene.prototype.enablePhysics = function (gravity, plugin) {
  2476. if (this._physicsEngine) {
  2477. return true;
  2478. }
  2479. try {
  2480. this._physicsEngine = new BABYLON.PhysicsEngine(gravity, plugin);
  2481. return true;
  2482. }
  2483. catch (e) {
  2484. BABYLON.Tools.Error(e.message);
  2485. return false;
  2486. }
  2487. };
  2488. Scene.prototype.disablePhysicsEngine = function () {
  2489. if (!this._physicsEngine) {
  2490. return;
  2491. }
  2492. this._physicsEngine.dispose();
  2493. this._physicsEngine = undefined;
  2494. };
  2495. Scene.prototype.isPhysicsEnabled = function () {
  2496. return this._physicsEngine !== undefined;
  2497. };
  2498. /**
  2499. *
  2500. * Sets the gravity of the physics engine (and NOT of the scene)
  2501. * @param {BABYLON.Vector3} [gravity] - the new gravity to be used
  2502. */
  2503. Scene.prototype.setGravity = function (gravity) {
  2504. BABYLON.Tools.Warn("Deprecated, please use 'scene.getPhysicsEngine().setGravity()'");
  2505. if (!this._physicsEngine) {
  2506. return;
  2507. }
  2508. this._physicsEngine.setGravity(gravity);
  2509. };
  2510. /**
  2511. * Legacy support, using the new API
  2512. * @Deprecated
  2513. */
  2514. Scene.prototype.createCompoundImpostor = function (parts, options) {
  2515. BABYLON.Tools.Warn("Scene.createCompoundImpostor is deprecated. Please use PhysicsImpostor parent/child");
  2516. if (parts.parts) {
  2517. options = parts;
  2518. parts = parts.parts;
  2519. }
  2520. var mainMesh = parts[0].mesh;
  2521. mainMesh.physicsImpostor = new BABYLON.PhysicsImpostor(mainMesh, parts[0].impostor, options, this);
  2522. for (var index = 1; index < parts.length; index++) {
  2523. var mesh = parts[index].mesh;
  2524. if (mesh.parent !== mainMesh) {
  2525. mesh.position = mesh.position.subtract(mainMesh.position);
  2526. mesh.parent = mainMesh;
  2527. }
  2528. mesh.physicsImpostor = new BABYLON.PhysicsImpostor(mesh, parts[index].impostor, options, this);
  2529. }
  2530. mainMesh.physicsImpostor.forceUpdate();
  2531. };
  2532. Scene.prototype.deleteCompoundImpostor = function (compound) {
  2533. var mesh = compound.parts[0].mesh;
  2534. mesh.physicsImpostor.dispose();
  2535. mesh.physicsImpostor = null;
  2536. };
  2537. // Misc.
  2538. Scene.prototype.createDefaultCameraOrLight = function () {
  2539. // Light
  2540. if (this.lights.length === 0) {
  2541. new BABYLON.HemisphericLight("default light", BABYLON.Vector3.Up(), this);
  2542. }
  2543. // Camera
  2544. if (!this.activeCamera) {
  2545. var camera = new BABYLON.FreeCamera("default camera", BABYLON.Vector3.Zero(), this);
  2546. // Compute position
  2547. var worldExtends = this.getWorldExtends();
  2548. var worldCenter = worldExtends.min.add(worldExtends.max.subtract(worldExtends.min).scale(0.5));
  2549. camera.position = new BABYLON.Vector3(worldCenter.x, worldCenter.y, worldExtends.min.z - (worldExtends.max.z - worldExtends.min.z));
  2550. camera.setTarget(worldCenter);
  2551. this.activeCamera = camera;
  2552. }
  2553. };
  2554. // Tags
  2555. Scene.prototype._getByTags = function (list, tagsQuery, forEach) {
  2556. if (tagsQuery === undefined) {
  2557. // returns the complete list (could be done with BABYLON.Tags.MatchesQuery but no need to have a for-loop here)
  2558. return list;
  2559. }
  2560. var listByTags = [];
  2561. forEach = forEach || (function (item) { return; });
  2562. for (var i in list) {
  2563. var item = list[i];
  2564. if (BABYLON.Tags.MatchesQuery(item, tagsQuery)) {
  2565. listByTags.push(item);
  2566. forEach(item);
  2567. }
  2568. }
  2569. return listByTags;
  2570. };
  2571. Scene.prototype.getMeshesByTags = function (tagsQuery, forEach) {
  2572. return this._getByTags(this.meshes, tagsQuery, forEach);
  2573. };
  2574. Scene.prototype.getCamerasByTags = function (tagsQuery, forEach) {
  2575. return this._getByTags(this.cameras, tagsQuery, forEach);
  2576. };
  2577. Scene.prototype.getLightsByTags = function (tagsQuery, forEach) {
  2578. return this._getByTags(this.lights, tagsQuery, forEach);
  2579. };
  2580. Scene.prototype.getMaterialByTags = function (tagsQuery, forEach) {
  2581. return this._getByTags(this.materials, tagsQuery, forEach).concat(this._getByTags(this.multiMaterials, tagsQuery, forEach));
  2582. };
  2583. /**
  2584. * Overrides the default sort function applied in the renderging group to prepare the meshes.
  2585. * This allowed control for front to back rendering or reversly depending of the special needs.
  2586. *
  2587. * @param renderingGroupId The rendering group id corresponding to its index
  2588. * @param opaqueSortCompareFn The opaque queue comparison function use to sort.
  2589. * @param alphaTestSortCompareFn The alpha test queue comparison function use to sort.
  2590. * @param transparentSortCompareFn The transparent queue comparison function use to sort.
  2591. */
  2592. Scene.prototype.setRenderingOrder = function (renderingGroupId, opaqueSortCompareFn, alphaTestSortCompareFn, transparentSortCompareFn) {
  2593. if (opaqueSortCompareFn === void 0) { opaqueSortCompareFn = null; }
  2594. if (alphaTestSortCompareFn === void 0) { alphaTestSortCompareFn = null; }
  2595. if (transparentSortCompareFn === void 0) { transparentSortCompareFn = null; }
  2596. this._renderingManager.setRenderingOrder(renderingGroupId, opaqueSortCompareFn, alphaTestSortCompareFn, transparentSortCompareFn);
  2597. };
  2598. /**
  2599. * Specifies whether or not the stencil and depth buffer are cleared between two rendering groups.
  2600. *
  2601. * @param renderingGroupId The rendering group id corresponding to its index
  2602. * @param autoClearDepthStencil Automatically clears depth and stencil between groups if true.
  2603. */
  2604. Scene.prototype.setRenderingAutoClearDepthStencil = function (renderingGroupId, autoClearDepthStencil) {
  2605. this._renderingManager.setRenderingAutoClearDepthStencil(renderingGroupId, autoClearDepthStencil);
  2606. };
  2607. // Statics
  2608. Scene._FOGMODE_NONE = 0;
  2609. Scene._FOGMODE_EXP = 1;
  2610. Scene._FOGMODE_EXP2 = 2;
  2611. Scene._FOGMODE_LINEAR = 3;
  2612. Scene.MinDeltaTime = 1.0;
  2613. Scene.MaxDeltaTime = 1000.0;
  2614. return Scene;
  2615. }());
  2616. BABYLON.Scene = Scene;
  2617. })(BABYLON || (BABYLON = {}));