Source: extern/scenes.js

  1. import register from "../util/register.js";
  2. import m_batch_fact from "../intern/batch.js";
  3. import m_cam_fact from "../intern/camera.js";
  4. import m_cont_fact from "../intern/container.js";
  5. import m_data_fact from "../intern/data.js";
  6. import m_graph_fact from "../intern/graph.js";
  7. import m_obj_fact from "../intern/objects.js";
  8. import m_obj_util_fact from "../intern/obj_util.js";
  9. import m_print_fact from "../intern/print.js";
  10. import m_phy_fact from "../intern/physics.js";
  11. import m_scenes_fact from "../intern/scenes.js";
  12. import m_subs_fact from "../intern/subscene.js";
  13. import * as m_util from "../intern/util.js";
  14. /**
  15. * Scene API.
  16. * Most of the routines presented here require an active scene to be set,
  17. * use get_active() set_active() to do that.
  18. * @module scenes
  19. * @local ColorCorrectionParams
  20. * @local SceneMetaTags
  21. * @local HMDParams
  22. * @local BloomParams
  23. * @local DOFParams
  24. * @local SSAOParams
  25. * @local SkyParams
  26. * @local WindParams
  27. */
  28. function Scenes(ns, exports) {
  29. var m_batch = m_batch_fact(ns);
  30. var m_cam = m_cam_fact(ns);
  31. var m_cont = m_cont_fact(ns);
  32. var m_data = m_data_fact(ns);
  33. var m_graph = m_graph_fact(ns);
  34. var m_obj = m_obj_fact(ns);
  35. var m_obj_util = m_obj_util_fact(ns);
  36. var m_print = m_print_fact(ns);
  37. var m_phy = m_phy_fact(ns);
  38. var m_scenes = m_scenes_fact(ns);
  39. var m_subs = m_subs_fact(ns);
  40. /**
  41. * Color correction params.
  42. * @typedef {Object} ColorCorrectionParams
  43. * @property {number} [brightness] Brightness
  44. * @property {number} [contrast] Contrast
  45. * @property {number} [exposure] Exposure
  46. * @property {number} [saturation] Saturation
  47. * @cc_externs brightness contrast exposure saturation
  48. */
  49. /**
  50. * Scene meta tags.
  51. * @typedef {Object} SceneMetaTags
  52. * @property {string} title The title meta tag.
  53. * @property {string} description The description meta tag.
  54. * @cc_externs title description
  55. */
  56. /**
  57. * Head-mounted display params.
  58. * @typedef {Object} HMDParams
  59. * @property {boolean} enable_hmd_stereo Enable hmd stereo
  60. * @property {Array} distortion_coefs Distortion coefficient list
  61. * @property {Array} chromatic_aberration_coefs Chromatic aberration coefficient list
  62. * @property {number} base_line_factor Tray to lens-center distance divided by screen height
  63. * @property {number} inter_lens_factor Inter-lens distance divided by screen width
  64. */
  65. /**
  66. * Bloom params.
  67. * @typedef {Object} BloomParams
  68. * @property {number} key Strength of bloom effect
  69. * @property {number} edge_lum Luminance threshold above which bloom is visible.
  70. * @property {number} blur The amount of blur applied to bloom effect.
  71. * @property {number} average_luminance The average luminance of the frame. Has influence only when
  72. * the adaptive bloom is disabled.
  73. * @cc_externs key edge_lum blur adaptive average_luminance
  74. */
  75. /**
  76. * Depth of Field parameters. Readonly properties like the "dof_bokeh" and the
  77. * "dof_object" can be only set beforehand in Blender.
  78. * @typedef {Object} DOFParams
  79. * @property {boolean} dof_on Use DOF.
  80. * @property {number} dof_distance The distance to the focal point. Readonly if
  81. * the "dof_object" property is set, which has a higher priority.
  82. * @property {number} dof_front_start The distance in front of the focal point
  83. * where the DOF effect starts. Disabled (has zero value and readonly status) if
  84. * the "dof_bokeh" property is False.
  85. * @property {number} dof_front_end The distance in front of the focal point
  86. * where the DOF effect reaches its maximum power.
  87. * @property {number} dof_rear_start The distance beyond the focal point where
  88. * the DOF effect starts. Disabled (has zero value and readonly status) if the
  89. * "dof_bokeh" property is False.
  90. * @property {number} dof_rear_end The distance beyond the focal point where
  91. * the DOF effect reaches its maximum power.
  92. * @property {number} dof_power The DOF intensity.
  93. * @property {boolean} dof_bokeh Use bokeh DOF (readonly).
  94. * @property {number} dof_bokeh_intensity The brightness of the bokeh DOF effect.
  95. * @property {Object3D} dof_object The object which center defines the focal
  96. * point. Controls the "dof_distance" property if set (readonly).
  97. * @cc_externs dof_on dof_distance dof_front_start dof_front_end dof_rear_start
  98. * @cc_externs dof_rear_end dof_power dof_bokeh dof_bokeh_intensity dof_object
  99. */
  100. /**
  101. * SSAO Parameters
  102. * @typedef {Object} SSAOParams
  103. * @property {number} [quality] The number of samples used for calculating SSAO.
  104. * Must be 8, 16, 24 or 32.
  105. * @property {number} [radius_increase] The spherical sampling radius multiply factor
  106. * when transferring from the internal sampling ring to the external one.
  107. * @property {boolean} [use_hemisphere] Use hemisphere to calculate SSAO.
  108. * @property {boolean} [use_blur_depth] Apply edge-preserving blur to SSAO.
  109. * @property {number} [blur_discard_value] Influence of depth difference between samples on blur weight.
  110. * @property {number} [influence] How much AO affects the final rendering.
  111. * @property {number} [dist_factor] How much AO decreases with distance.
  112. * @property {boolean} [ssao_white] Turn SSAO white, basically disabling it.
  113. * @property {boolean} [ssao_only] Only SSAO and not the regular render will be visible.
  114. * @cc_externs quality radius_increase use_hemisphere
  115. * @cc_externs use_blur_depth blur_discard_value
  116. * @cc_externs influence dist_factor ssao_white ssao_only
  117. */
  118. /**
  119. * Procedural Sky Parameters
  120. * @typedef {Object} SkyParams
  121. * @property {boolean} [procedural_skydome] Procedural sky is used (readonly).
  122. * @property {boolean} [use_as_environment_lighting] Procedural sky is used for
  123. * calculating environment lighting (readonly).
  124. * @property {number} [rayleigh_brightness] Brightness of Rayleigh scattering.
  125. * Available only if "procedural_skydome" is True.
  126. * @property {number} [mie_brightness] Brightness of Mie scattering. Available
  127. * only if "procedural_skydome" is True.
  128. * @property {number} [spot_brightness] Brightness of the sun spot. Available
  129. * only if "procedural_skydome" is True.
  130. * @property {number} [scatter_strength] The strength of the light scattering.
  131. * Available only if "procedural_skydome" is True.
  132. * @property {number} [rayleigh_strength] The strength of the Rayleigh
  133. * scattering. Available only if "procedural_skydome" is True.
  134. * @property {number} [mie_strength] The strength of the Mie scattering.
  135. * Available only if "procedural_skydome" is True.
  136. * @property {number} [rayleigh_collection_power] Rayleigh collection power.
  137. * Available only if "procedural_skydome" is True.
  138. * @property {number} [mie_collection_power] Mie collection power. Available
  139. * only if "procedural_skydome" is True.
  140. * @property {number} [mie_distribution] Mie distribution. Available only if
  141. * "procedural_skydome" is True.
  142. * @property {RGB} [color] The base color of the procedural sky. Available only
  143. * if "procedural_skydome" is True.
  144. * @cc_externs procedural_skydome use_as_environment_lighting
  145. * @cc_externs rayleigh_brightness mie_brightness spot_brightness
  146. * @cc_externs scatter_strength rayleigh_strength mie_strength
  147. * @cc_externs rayleigh_collection_power mie_collection_power
  148. * @cc_externs mie_distribution color
  149. */
  150. /**
  151. * Wind Parameters
  152. * @typedef {Object} WindParams
  153. * @property {number} [wind_dir] The direction of the wind.
  154. * @property {number} [wind_strength] The strength of the wind.
  155. * @cc_externs wind_dir wind_strength
  156. */
  157. /**
  158. * All possible data IDs.
  159. * @const module:scenes.DATA_ID_ALL
  160. */
  161. exports.DATA_ID_ALL = m_obj.DATA_ID_ALL;
  162. /**
  163. * Set the active scene
  164. * @method module:scenes.set_active
  165. * @param {string} scene_name Name of the scene
  166. * @example var m_scenes = require("scenes");
  167. *
  168. * m_scenes.set_active("Scene");
  169. */
  170. exports.set_active = function(scene_name) {
  171. // NOTE: keysearch is dangerous
  172. var scenes = m_scenes.get_all_scenes();
  173. m_scenes.set_active(m_util.keysearch("name", scene_name, scenes));
  174. }
  175. /**
  176. * Get the current active scene
  177. * @method module:scenes.get_active
  178. * @returns {string} Active scene name
  179. * @example var m_scenes = require("scenes");
  180. *
  181. * var current_scene = m_scenes.get_active();
  182. */
  183. exports.get_active = function() {
  184. if (!m_scenes.check_active())
  185. return "";
  186. else
  187. return m_scenes.get_active()["name"];
  188. }
  189. /**
  190. * Get all scene names.
  191. * @method module:scenes.get_scenes
  192. * @returns {string[]} Array of scene names.
  193. * @example var m_scenes = require("scenes");
  194. *
  195. * var scene_list = m_scenes.get_scenes();
  196. */
  197. exports.get_scenes = function() {
  198. var scenes = m_scenes.get_all_scenes();
  199. var scene_names = [];
  200. for (var i = 0; i < scenes.length; i++)
  201. scene_names.push(scenes[i]["name"]);
  202. return scene_names;
  203. }
  204. /**
  205. * Return the active camera object from the active scene.
  206. * @method module:scenes.get_active_camera
  207. * @returns {Object3D} Camera object.
  208. * @example var m_scenes = require("scenes");
  209. *
  210. * var camera = m_scenes.get_active_camera();
  211. */
  212. exports.get_active_camera = function() {
  213. if (!m_scenes.check_active()) {
  214. m_print.error("No active scene");
  215. return false;
  216. } else
  217. return m_scenes.get_camera(m_scenes.get_active());
  218. }
  219. /**
  220. * Get object by name.
  221. * @method module:scenes.get_object_by_name
  222. * @param {string} name Object name
  223. * @param {number} [data_id=0] ID of loaded data
  224. * @returns {Object3D} Object 3D
  225. * @example var m_scenes = require("scenes");
  226. *
  227. * var cube = m_scenes.get_object_by_name("Cube");
  228. */
  229. exports.get_object_by_name = function(name, data_id) {
  230. var obj = m_obj.get_object(m_obj.GET_OBJECT_BY_NAME, name, data_id | 0, true);
  231. if (obj)
  232. return obj;
  233. else
  234. m_print.error("get object " + name + ": not found");
  235. }
  236. /**
  237. * Get the duplicated object by empty name and dupli name.
  238. * @method module:scenes.get_object_by_dupli_name
  239. * @param {string} empty_name Name of the EMPTY object used to duplicate the object
  240. * @param {string} dupli_name Name of the duplicated object
  241. * @param {number} [data_id=0] ID of loaded data
  242. * @returns {Object3D} Object 3D
  243. */
  244. exports.get_object_by_dupli_name = function(empty_name, dupli_name,
  245. data_id) {
  246. var obj = m_obj.get_object(m_obj.GET_OBJECT_BY_DUPLI_NAME, empty_name,
  247. dupli_name, data_id | 0);
  248. if (obj)
  249. return obj;
  250. else
  251. m_print.error("get object " + dupli_name + ": not found");
  252. }
  253. /**
  254. * Get the duplicated object by empty name and dupli name list.
  255. * @method module:scenes.get_object_by_dupli_name_list
  256. * @param {string[]} name_list List of the EMPTY and DUPLI object names:
  257. * [empty_name,empty_name,...,dupli_name]. Can be retrieved with the get_object_name_hierarchy() method.
  258. * @param {number} [data_id=0] ID of loaded data.
  259. * @returns {Object3D} Object 3D.
  260. */
  261. exports.get_object_by_dupli_name_list = function(name_list, data_id) {
  262. var obj = m_obj.get_object(m_obj.GET_OBJECT_BY_DUPLI_NAME_LIST,
  263. name_list, data_id | 0);
  264. if (obj)
  265. return obj;
  266. else
  267. m_print.error("get object " + name_list + ": not found");
  268. }
  269. /**
  270. * Get world by name.
  271. * @method module:scenes.get_world_by_name
  272. * @param {string} name World name
  273. * @param {number} [data_id=0] ID of loaded data
  274. * @returns {Object3D} Object 3D
  275. * @example m_scenes = require("scenes");
  276. *
  277. * var world_obj = m_scenes.get_world_by_name("World");
  278. */
  279. exports.get_world_by_name = function(name, data_id) {
  280. var wrd = m_obj.get_world_by_name(name, data_id | 0);
  281. if (wrd)
  282. return wrd;
  283. else
  284. m_print.error("get object " + name + ": not found");
  285. }
  286. /**
  287. * Returns object data_id property.
  288. * @method module:scenes.get_object_data_id
  289. * @param {Object3D} obj Object 3D
  290. * @returns {number} data_id Data ID property
  291. * @example var m_scenes = require("scenes");
  292. *
  293. * var cube = m_scenes.get_object_by_name("Cube");
  294. *
  295. * var data_id = m_scenes.get_object_data_id(cube);
  296. */
  297. exports.get_object_data_id = function(obj) {
  298. return m_obj_util.get_object_data_id(obj);
  299. }
  300. /**
  301. * For given mouse coords, render the color scene and return an object.
  302. * @method module:scenes.pick_object
  303. * @param {number} x X Canvas coordinate.
  304. * @param {number} y Y Canvas coordinate.
  305. * @returns {Object3D?} The object under the given coordinates or null.
  306. * @example
  307. * var m_cont = require("container");
  308. * var m_scenes = require("scenes");
  309. *
  310. * var canvas_cont = m_cont.get_container();
  311. * canvas_cont.addEventListener("mousedown", down_cb);
  312. * var down_cb = function(event) {
  313. * var obj = m_scenes.pick_object(event.offsetX, event.offsetY);
  314. * }
  315. */
  316. exports.pick_object = function(x, y) {
  317. var main_scene = m_scenes.get_main();
  318. if (!main_scene) {
  319. m_print.error("No active scene");
  320. return null;
  321. }
  322. var subs_stereo = m_scenes.get_subs(main_scene, m_subs.STEREO);
  323. if (subs_stereo)
  324. if (subs_stereo.enable_hmd_stereo) {
  325. m_print.error_once("pick_object() is not available in the stereo rendering mode." +
  326. " Use scenes.pick_center instead.");
  327. return pick_center();
  328. }
  329. return m_obj.pick_object(x, y);
  330. }
  331. /**
  332. * Render the color scene and return an object in the viewport center.
  333. * @method module:scenes.pick_center
  334. * @returns {Object3D?} The object in the viewport center.
  335. */
  336. exports.pick_center = pick_center;
  337. function pick_center() {
  338. var canvas = m_cont.get_canvas();
  339. var h = canvas.clientHeight;
  340. var w = canvas.clientWidth;
  341. return m_obj.pick_object(w / 2, h / 2);
  342. }
  343. /**
  344. * Check if the outlining is enabled or not for the object.
  345. * @method module:scenes.outlining_is_enabled
  346. * @param {Object3D} obj Object 3D
  347. * @returns {boolean} Checking result.
  348. * @example var m_scenes = require("scenes");
  349. *
  350. * var cube = m_scenes.get_object_by_name("Cube");
  351. *
  352. * var outlining_is_enabled = m_scenes.outlining_is_enabled(cube);
  353. */
  354. exports.outlining_is_enabled = function(obj) {
  355. return obj && obj.render && obj.render.outlining;
  356. }
  357. /**
  358. * Set outline intensity for the object.
  359. * @method module:scenes.set_outline_intensity
  360. * @param {Object3D} obj Object 3D
  361. * @param {number} value Intensity value
  362. * @example var m_scenes = require("scenes");
  363. *
  364. * var cube = m_scenes.get_object_by_name("Cube");
  365. *
  366. * m_scenes.set_outline_intensity(cube, 0.4);
  367. */
  368. exports.set_outline_intensity = function(obj, value) {
  369. if (obj && obj.render && obj.render.outlining)
  370. m_obj.set_outline_intensity(obj, value);
  371. else
  372. m_print.error("set_outline_intensity(): wrong object");
  373. }
  374. /**
  375. * Get outline intensity for the object.
  376. * @method module:scenes.get_outline_intensity
  377. * @param {Object3D} obj Object 3D
  378. * @returns {number} Intensity value
  379. * @example var m_scenes = require("scenes");
  380. *
  381. * var cube = m_scenes.get_object_by_name("Cube");
  382. *
  383. * var outline_intensity = m_scenes.get_outline_intensity(cube);
  384. */
  385. exports.get_outline_intensity = function(obj) {
  386. if (obj && obj.render && obj.render.outlining)
  387. return obj.render.outline_intensity;
  388. else
  389. m_print.error("get_outline_intensity(): wrong object");
  390. return 0;
  391. }
  392. /**
  393. * Apply outlining animation to the object
  394. * @method module:scenes.apply_outline_anim
  395. * @param {Object3D} obj Object 3D
  396. * @param {number} tau Outlining duration
  397. * @param {number} T Period of outlining
  398. * @param {number} N Number of relapses (0 - infinity)
  399. * @example var m_scenes = require("scenes");
  400. *
  401. * var cube = m_scenes.get_object_by_name("Cube");
  402. *
  403. * m_scenes.apply_outline_anim(cube, 10, 5, 0);
  404. */
  405. exports.apply_outline_anim = function(obj, tau, T, N) {
  406. if (obj && obj.render && obj.render.outlining)
  407. m_obj.apply_outline_anim(obj, tau, T, N);
  408. else
  409. m_print.error("apply_outline_anim(): wrong object");
  410. }
  411. /**
  412. * Apply outlining animation to the object and use the object's default settings
  413. * @method module:scenes.apply_outline_anim_def
  414. * @param {Object3D} obj Object 3D
  415. * @example var m_scenes = require("scenes");
  416. *
  417. * var cube = m_scenes.get_object_by_name("Cube");
  418. *
  419. * m_scenes.apply_outline_anim_def(cube);
  420. */
  421. exports.apply_outline_anim_def = function(obj) {
  422. if (obj && obj.render && obj.render.outlining) {
  423. var oa_set = obj.render.outline_anim_settings_default;
  424. m_obj.apply_outline_anim(obj, oa_set.outline_duration,
  425. oa_set.outline_period, oa_set.outline_relapses);
  426. } else
  427. m_print.error("apply_outline_anim_def(): wrong object");
  428. }
  429. /**
  430. * Stop outlining animation for the object.
  431. * @method module:scenes.clear_outline_anim
  432. * @param {Object3D} obj Object 3D
  433. * @example var m_scenes = require("scenes");
  434. *
  435. * var cube = m_scenes.get_object_by_name("Cube");
  436. *
  437. * m_scenes.clear_outline_anim(cube);
  438. */
  439. exports.clear_outline_anim = function(obj) {
  440. if (obj && obj.render && obj.render.outlining)
  441. m_obj.clear_outline_anim(obj);
  442. else
  443. m_print.error("clear_outline_anim(): wrong object");
  444. }
  445. /**
  446. * Set the color of outline outline effect for active scene.
  447. * @method module:scenes.set_outline_color
  448. * @param {RGB} color RGB color vector
  449. * @example var m_scenes = require("scenes");
  450. *
  451. * m_scenes.set_outline_color([0.8, 0.2, 0.8]);
  452. */
  453. exports.set_outline_color = m_scenes.set_outline_color;
  454. /**
  455. * Get the color of outline outline effect for active scene.
  456. * @method module:scenes.get_outline_color
  457. * @param {?RGB} dest Destination RGB color vector
  458. * @returns {RGB} Destination RGB color vector
  459. * @example var m_scenes = require("scenes");
  460. *
  461. * var outline_color = new Float32Array(3);
  462. *
  463. * m_scenes.get_outline_color(outline_color);
  464. */
  465. exports.get_outline_color = function(dest) {
  466. var scene = m_scenes.get_active();
  467. var subs = m_scenes.get_subs(scene, m_subs.OUTLINE);
  468. if (subs) {
  469. dest = dest || new Float32Array(3);
  470. dest.set(subs.outline_color);
  471. return dest;
  472. }
  473. }
  474. /**
  475. * Set head-mounted display params.
  476. * @method module:scenes.set_hmd_params
  477. * @param {HMDParams} hmd_params Head-mounted display params.
  478. * @cc_externs enable_hmd_stereo distortion_coefs chromatic_aberration_coefs
  479. * @cc_externs base_line_factor inter_lens_factor
  480. */
  481. exports.set_hmd_params = function(hmd_params) {
  482. if (!m_scenes.check_active()) {
  483. m_print.error("No active scene");
  484. return;
  485. }
  486. if (!hmd_params)
  487. return;
  488. if (hmd_params.distortion_coefs && !(hmd_params.distortion_coefs instanceof Array))
  489. hmd_params.distortion_coefs = null;
  490. if (hmd_params.chromatic_aberration_coefs && !(hmd_params.chromatic_aberration_coefs instanceof Array))
  491. hmd_params.chromatic_aberration_coefs = null;
  492. if (typeof hmd_params.base_line_factor != "number")
  493. hmd_params.base_line_factor = null;
  494. if (typeof hmd_params.inter_lens_factor != "number")
  495. hmd_params.inter_lens_factor = null;
  496. if (typeof hmd_params.enable_hmd_stereo != "boolean")
  497. hmd_params.enable_hmd_stereo = null;
  498. m_scenes.set_hmd_params(hmd_params);
  499. }
  500. /**
  501. * Get shadow params.
  502. * @method module:scenes.get_shadow_params
  503. * @returns {ShadowParams} Shadow params
  504. * @cc_externs enable_csm csm_num csm_first_cascade_border first_cascade_blur_radius
  505. * @cc_externs csm_last_cascade_border last_cascade_blur_radius csm_resolution
  506. * @cc_externs self_shadow_normal_offset self_shadow_polygon_offset
  507. * @cc_externs pcf_blur_radius fade_last_cascade blend_between_cascades
  508. * @cc_externs csm_borders blur_radii
  509. * @example var m_scenes = require("scenes");
  510. *
  511. * var shadow_params = m_scenes.get_shadow_params();
  512. */
  513. exports.get_shadow_params = function() {
  514. if (!m_scenes.check_active()) {
  515. m_print.error("No active scene");
  516. return false;
  517. }
  518. var active_scene = m_scenes.get_active();
  519. var shadow_cast = m_scenes.get_subs(active_scene, m_subs.SHADOW_CAST);
  520. if (!shadow_cast)
  521. return null;
  522. var shs = active_scene._render.shadow_params;
  523. var subs_main = m_scenes.get_subs(active_scene, m_subs.MAIN_OPAQUE);
  524. var subs_shadow_receive = m_scenes.get_subs(active_scene, m_subs.SHADOW_RECEIVE);
  525. var shadow_params = {};
  526. shadow_params.csm_resolution = shs.csm_resolution;
  527. shadow_params.self_shadow_polygon_offset = shadow_cast.self_shadow_polygon_offset;
  528. if (subs_shadow_receive)
  529. shadow_params.self_shadow_normal_offset = subs_shadow_receive.self_shadow_normal_offset;
  530. shadow_params.enable_csm = shs.enable_csm;
  531. shadow_params.csm_num = shs.csm_num;
  532. shadow_params.csm_first_cascade_border = shs.csm_first_cascade_border;
  533. shadow_params.first_cascade_blur_radius = shs.first_cascade_blur_radius;
  534. shadow_params.csm_last_cascade_border = shs.csm_last_cascade_border;
  535. shadow_params.last_cascade_blur_radius = shs.last_cascade_blur_radius;
  536. shadow_params.fade_last_cascade = shs.fade_last_cascade;
  537. shadow_params.blend_between_cascades = shs.blend_between_cascades;
  538. if (shs.enable_csm) {
  539. shadow_params.csm_borders = m_scenes.get_csm_borders(active_scene,
  540. subs_main.camera);
  541. shadow_params.blur_radii = new Float32Array(shs.csm_num);
  542. shadow_params.blur_radii.set(subs_main.camera.pcf_blur_radii.subarray(0,
  543. shs.csm_num));
  544. } else {
  545. shadow_params.csm_borders = null;
  546. shadow_params.blur_radii = null;
  547. }
  548. return shadow_params;
  549. }
  550. /**
  551. * Set shadow params
  552. * @method module:scenes.set_shadow_params
  553. * @param {ShadowParams} shadow_params Shadow params
  554. * @example var m_scenes = require("scenes");
  555. *
  556. * m_scenes.set_shadow_params({ blend_between_cascades: true,
  557. * blur_radii: null,
  558. * csm_borders: null,
  559. * csm_first_cascade_border: 10,
  560. * csm_last_cascade_border: 100,
  561. * csm_num: 1,
  562. * csm_resolution: 2048,
  563. * enable_csm: true,
  564. * fade_last_cascade: true,
  565. * first_cascade_blur_radius: 3,
  566. * last_cascade_blur_radius: 1.5,
  567. * self_shadow_normal_offset: 0.01,
  568. * self_shadow_polygon_offset: 1 });
  569. */
  570. exports.set_shadow_params = function(shadow_params) {
  571. if (!m_scenes.check_active()) {
  572. m_print.error("No active scene");
  573. return;
  574. }
  575. var active_scene = m_scenes.get_active();
  576. if (typeof shadow_params.self_shadow_polygon_offset == "number")
  577. m_graph.traverse(active_scene._render.graph, function(node, attr) {
  578. if (attr.type == m_subs.SHADOW_CAST)
  579. attr.self_shadow_polygon_offset = shadow_params.self_shadow_polygon_offset;
  580. });
  581. var subs_shadow_receives = m_scenes.subs_array(active_scene, [m_subs.SHADOW_RECEIVE]);
  582. for (var i = 0; i < subs_shadow_receives.length; i++) {
  583. var subs_shadow_receive = subs_shadow_receives[i];
  584. if (typeof shadow_params.self_shadow_normal_offset == "number")
  585. subs_shadow_receive.self_shadow_normal_offset = shadow_params.self_shadow_normal_offset;
  586. if (typeof shadow_params.pcf_blur_radius == "number")
  587. subs_shadow_receive.pcf_blur_radius = shadow_params.pcf_blur_radius;
  588. }
  589. var subs_main_blends = m_scenes.subs_array(active_scene, [m_subs.MAIN_BLEND]);
  590. for (var i = 0; i < subs_main_blends.length; i++) {
  591. var subs_main_blend = subs_main_blends[i];
  592. if (typeof shadow_params.self_shadow_normal_offset == "number")
  593. subs_main_blend.self_shadow_normal_offset = shadow_params.self_shadow_normal_offset;
  594. if (typeof shadow_params.pcf_blur_radius == "number")
  595. subs_main_blend.pcf_blur_radius = shadow_params.pcf_blur_radius;
  596. subs_main_blend.need_perm_uniforms_update = true;
  597. }
  598. var shs = active_scene._render.shadow_params;
  599. if (typeof shadow_params.csm_first_cascade_border == "number")
  600. shs.csm_first_cascade_border = shadow_params.csm_first_cascade_border;
  601. if (typeof shadow_params.first_cascade_blur_radius == "number")
  602. shs.first_cascade_blur_radius = shadow_params.first_cascade_blur_radius;
  603. if (typeof shadow_params.csm_last_cascade_border == "number")
  604. shs.csm_last_cascade_border = shadow_params.csm_last_cascade_border;
  605. if (typeof shadow_params.last_cascade_blur_radius == "number")
  606. shs.last_cascade_blur_radius = shadow_params.last_cascade_blur_radius;
  607. // update directives; only depth subs supported
  608. if (subs_shadow_receive) {
  609. var draw_data = subs_shadow_receive.draw_data;
  610. for (var i = 0; i < draw_data.length; i++) {
  611. var bundles = draw_data[i].bundles;
  612. for (var j = 0; j < bundles.length; j++) {
  613. var bundle = bundles[j];
  614. if (!bundle.obj_render.shadow_receive)
  615. continue;
  616. var batch = bundle.batch;
  617. m_batch.assign_shadow_receive_dirs(batch, shs);
  618. m_batch.update_shader(batch);
  619. m_subs.append_draw_data(subs_shadow_receive, bundle)
  620. }
  621. }
  622. subs_shadow_receive.need_perm_uniforms_update = true;
  623. }
  624. var cam_scene_data = m_obj_util.get_scene_data(active_scene._camera, active_scene);
  625. var upd_cameras = cam_scene_data.cameras;
  626. for (var i = 0; i < upd_cameras.length; i++)
  627. m_cam.update_camera_shadows(upd_cameras[i], shs);
  628. m_scenes.schedule_shadow_update(active_scene);
  629. }
  630. /**
  631. * Get horizon and zenith colors of the environment.
  632. * @method module:scenes.get_environment_colors
  633. * @returns {Array} Environment colors
  634. * @example var m_scenes = require("scenes");
  635. *
  636. * var environment_colors = m_scenes.get_environment_colors();
  637. */
  638. exports.get_environment_colors = function() {
  639. if (!m_scenes.check_active()) {
  640. m_print.error("No active scene");
  641. return [];
  642. }
  643. var active_scene = m_scenes.get_active();
  644. return m_scenes.get_environment_colors(active_scene);
  645. }
  646. /**
  647. * Set horizon and/or zenith color(s) of the environment.
  648. * @method module:scenes.set_environment_colors
  649. * @param {number} [opt_environment_energy] Environment Energy
  650. * @param {RGB} [opt_horizon_color] Horizon color
  651. * @param {RGB} [opt_zenith_color] Zenith color
  652. * @example var m_rgb = require("rgb");
  653. * var m_scenes = require("scenes");
  654. *
  655. * var horizon_color = m_rgb.from_values(0.5, 0.1, 0.1);
  656. * var zenith_color = m_rgb.from_values(0.1, 0.1, 0.8);
  657. *
  658. * m_scenes.set_environment_colors(0.8, horizon_color, zenith_color);
  659. */
  660. exports.set_environment_colors = function(opt_environment_energy,
  661. opt_horizon_color, opt_zenith_color) {
  662. if (!m_scenes.check_active()) {
  663. m_print.error("No active scene");
  664. return;
  665. }
  666. var active_scene = m_scenes.get_active();
  667. var subs = m_scenes.get_subs(active_scene, m_subs.MAIN_OPAQUE);
  668. var energy = opt_environment_energy || opt_environment_energy == 0 ?
  669. parseFloat(opt_environment_energy):
  670. subs.environment_energy;
  671. var horizon_color = opt_horizon_color || opt_horizon_color == 0 ?
  672. opt_horizon_color:
  673. subs.horizon_color;
  674. var zenith_color = opt_zenith_color || opt_zenith_color == 0 ?
  675. opt_zenith_color:
  676. subs.zenith_color;
  677. m_scenes.set_environment_colors(active_scene, energy,
  678. horizon_color, zenith_color);
  679. }
  680. /**
  681. * Get fog color and density.
  682. * @method module:scenes.get_fog_color_density
  683. * @param {Vec4} dest Destination vector [C,C,C,D]
  684. * @returns {Vec4} Destination vector
  685. * @example var m_scenes = require("scenes");
  686. *
  687. * var fog_density = new Float32Array(4);
  688. * m_scenes.get_fog_color_density(fog_density);
  689. */
  690. exports.get_fog_color_density = function(dest) {
  691. if (!m_scenes.check_active()) {
  692. m_print.error("No active scene");
  693. return false;
  694. }
  695. var active_scene = m_scenes.get_active();
  696. return m_scenes.get_fog_color_density(active_scene, dest);
  697. }
  698. /**
  699. * Set fog color and density
  700. * @method module:scenes.set_fog_color_density
  701. * @param {Vec4} val Color-density vector [C,C,C,D]
  702. * @example var m_scenes = require("scenes");
  703. *
  704. * m_scenes.set_fog_color_density([0.5, 0.5, 0.7, 0.05]);
  705. */
  706. exports.set_fog_color_density = function(val) {
  707. if (!m_scenes.check_active()) {
  708. m_print.error("No active scene");
  709. return;
  710. }
  711. var active_scene = m_scenes.get_active();
  712. m_scenes.set_fog_color_density(active_scene, val);
  713. }
  714. /**
  715. * Get fog params
  716. * @method module:scenes.get_fog_params
  717. * @returns {FogParams} Fog params
  718. * @cc_externs fog_intensity fog_intensity fog intensity
  719. * @cc_externs fog_depth fog_depth fog_depth
  720. * @cc_externs fog_start fog_start fog start
  721. * @cc_externs fog_height fog_height fog height
  722. * @example var m_scenes = require("scenes");
  723. *
  724. * var fog_params = m_scenes.get_fog_params();
  725. */
  726. exports.get_fog_params = function() {
  727. if (!m_scenes.check_active()) {
  728. m_print.error("No active scene");
  729. return false;
  730. }
  731. var active_scene = m_scenes.get_active();
  732. var fog_params = {};
  733. fog_params.fog_intensity = m_scenes.get_fog_intensity(active_scene);
  734. fog_params.fog_depth = m_scenes.get_fog_depth(active_scene);
  735. fog_params.fog_start = m_scenes.get_fog_start(active_scene);
  736. fog_params.fog_height = m_scenes.get_fog_height(active_scene);
  737. return fog_params;
  738. }
  739. /**
  740. * Set fog params
  741. * @method module:scenes.set_fog_params
  742. * @param {FogParams} fog_params Fog params
  743. * @example var m_scenes = require("scenes");
  744. *
  745. * m_scenes.set_fog_params({ fog_intensity: 1,
  746. * fog_depth: 25,
  747. * fog_start: 5,
  748. * fog_height: 0 });
  749. */
  750. exports.set_fog_params = function(fog_params) {
  751. if (!m_scenes.check_active()) {
  752. m_print.error("No active scene");
  753. return;
  754. }
  755. var active_scene = m_scenes.get_active();
  756. if (typeof fog_params.fog_intensity == "number")
  757. m_scenes.set_fog_intensity(active_scene, fog_params.fog_intensity);
  758. if (typeof fog_params.fog_depth == "number")
  759. m_scenes.set_fog_depth(active_scene, fog_params.fog_depth);
  760. if (typeof fog_params.fog_start == "number")
  761. m_scenes.set_fog_start(active_scene, fog_params.fog_start);
  762. if (typeof fog_params.fog_height == "number")
  763. m_scenes.set_fog_height(active_scene, fog_params.fog_height);
  764. }
  765. /**
  766. * Get SSAO params
  767. * @method module:scenes.get_ssao_params
  768. * @returns {SSAOParams} SSAO params
  769. * @example var m_scenes = require("scenes");
  770. *
  771. * var ssao_params = m_scenes.get_ssao_params();
  772. */
  773. exports.get_ssao_params = function() {
  774. if (!m_scenes.check_active()) {
  775. m_print.error("No active scene");
  776. return false;
  777. }
  778. var active_scene = m_scenes.get_active();
  779. return m_scenes.get_ssao_params(active_scene);
  780. }
  781. /**
  782. * Set SSAO params
  783. * @method module:scenes.set_ssao_params
  784. * @param {SSAOParams} ssao_params SSAO params
  785. * @example var m_scenes = require("scenes");
  786. *
  787. * m_scenes.set_ssao_params({ quality: 16,
  788. * radius_increase: 3,
  789. * use_hemisphere: true,
  790. * use_blur_depth: false,
  791. * blur_discard_value: 1,
  792. * influence: 0.7,
  793. * dist_factor: 0,
  794. * ssao_white: false,
  795. * ssao_only: false });
  796. */
  797. exports.set_ssao_params = function(ssao_params) {
  798. if (!m_scenes.check_active()) {
  799. m_print.error("No active scene");
  800. return;
  801. }
  802. var scene = m_scenes.get_active();
  803. var subscenes = m_scenes.subs_array(scene, [m_subs.SSAO]);
  804. var subscenes_blur = m_scenes.subs_array(scene, [m_subs.SSAO_BLUR]);
  805. if (!subscenes.length) {
  806. m_print.error("SSAO is not enabled on the scene");
  807. return 0;
  808. }
  809. for (var i = 0; i < subscenes.length; i++)
  810. set_params_ssao_subs(subscenes[i], subscenes_blur[i], ssao_params);
  811. }
  812. function set_params_ssao_subs(subs, subs_blur, ssao_params) {
  813. var scene = m_scenes.get_active();
  814. var bundle = subs.draw_data[0].bundles[0];
  815. var batch = bundle.batch;
  816. var bundle_blur = subs_blur.draw_data[0].bundles[0];
  817. var batch_blur = bundle_blur.batch;
  818. if ("quality" in ssao_params) {
  819. var quality = ssao_params.quality
  820. if (quality === 8 || quality === 16 || quality === 24 || quality === 32) {
  821. subs.ssao_samples = quality;
  822. m_batch.set_batch_directive(batch, "SSAO_QUALITY", "SSAO_QUALITY_"
  823. + quality);
  824. m_batch.update_shader(batch);
  825. m_subs.append_draw_data(subs, bundle);
  826. } else
  827. m_print.error("set_ssao_params(): Wrong \"quality\" value.");
  828. }
  829. if ("use_hemisphere" in ssao_params) {
  830. subs.ssao_hemisphere = ssao_params.use_hemisphere;
  831. m_batch.set_batch_directive(batch, "SSAO_HEMISPHERE",
  832. ssao_params.use_hemisphere | 0);
  833. m_batch.update_shader(batch);
  834. m_subs.append_draw_data(subs, bundle);
  835. }
  836. if ("use_blur_depth" in ssao_params) {
  837. subs_blur.ssao_blur_depth = ssao_params.use_blur_depth;
  838. m_batch.set_batch_directive(batch_blur, "SSAO_BLUR_DEPTH",
  839. ssao_params.use_blur_depth | 0);
  840. m_batch.update_shader(batch_blur);
  841. m_subs.append_draw_data(subs_blur, bundle_blur);
  842. m_scenes.connect_render_targets_batch(scene._render.graph, subs_blur, batch_blur, false);
  843. }
  844. if ("ssao_white" in ssao_params) {
  845. subs.ssao_white = ssao_params.ssao_white;
  846. m_batch.set_batch_directive(batch, "SSAO_WHITE",
  847. ssao_params.ssao_white | 0);
  848. m_batch.update_shader(batch);
  849. m_subs.append_draw_data(subs, bundle);
  850. }
  851. if ("blur_discard_value" in ssao_params)
  852. subs_blur.ssao_blur_discard_value = ssao_params.blur_discard_value;
  853. if ("radius_increase" in ssao_params)
  854. subs.ssao_radius_increase = ssao_params.radius_increase;
  855. if ("influence" in ssao_params)
  856. subs.ssao_influence = ssao_params.influence;
  857. if ("dist_factor" in ssao_params)
  858. subs.ssao_dist_factor = ssao_params.dist_factor;
  859. if (typeof ssao_params.ssao_only == "boolean") {
  860. // FIX: in case of stereo mode there are 2 MAIN_OPAQUE
  861. var subs_main = m_scenes.get_subs(scene, m_subs.MAIN_OPAQUE);
  862. subs_main.ssao_only = ssao_params.ssao_only;
  863. var draw_data = subs_main.draw_data;
  864. var append_bundles = [];
  865. for (var i = 0; i < draw_data.length; i++) {
  866. var bundles = draw_data[i].bundles;
  867. for (var j = 0; j < bundles.length; j++) {
  868. var batch_main = bundles[j].batch;
  869. m_batch.set_batch_directive(batch_main, "SSAO_ONLY",
  870. ssao_params.ssao_only | 0);
  871. m_batch.update_shader(batch_main);
  872. append_bundles.push(bundles[j]);
  873. }
  874. }
  875. for (var i = 0; i < append_bundles.length; i++)
  876. m_subs.append_draw_data(subs_main, append_bundles[i]);
  877. }
  878. subs.need_perm_uniforms_update = true;
  879. subs_blur.need_perm_uniforms_update = true;
  880. }
  881. /**
  882. * Get color correction params
  883. * @method module:scenes.get_color_correction_params
  884. * @returns {ColorCorrectionParams} Color correction params
  885. * @example var m_scenes = require("scenes");
  886. *
  887. * var color_parameters = m_scenes.get_color_correction_params();
  888. */
  889. exports.get_color_correction_params = function() {
  890. if (!m_scenes.check_active()) {
  891. m_print.error("No active scene");
  892. return null;
  893. }
  894. var active_scene = m_scenes.get_active();
  895. var subs = m_scenes.get_subs(active_scene, m_subs.COMPOSITING);
  896. if (!subs)
  897. return null;
  898. var compos_params = {};
  899. compos_params.brightness = subs.brightness;
  900. compos_params.contrast = subs.contrast;
  901. compos_params.exposure = subs.exposure;
  902. compos_params.saturation = subs.saturation;
  903. return compos_params;
  904. }
  905. /**
  906. * Set color correction params.
  907. * @method module:scenes.set_color_correction_params
  908. * @param {ColorCorrectionParams} color_corr_params Color correction params.
  909. * @example var m_scenes = require("scenes");
  910. *
  911. * m_scenes.set_color_correction_params({ brightness: 0.2,
  912. * contrast: 0.4,
  913. * exposure: 0.9,
  914. * saturation: 0.5 });
  915. */
  916. exports.set_color_correction_params = function(color_corr_params) {
  917. if (!m_scenes.check_active()) {
  918. m_print.error("No active scene");
  919. return;
  920. }
  921. var active_scene = m_scenes.get_active();
  922. var subs = m_scenes.get_subs(active_scene, m_subs.COMPOSITING);
  923. if (!subs)
  924. return;
  925. if ("brightness" in color_corr_params)
  926. subs.brightness = color_corr_params.brightness;
  927. if ("contrast" in color_corr_params)
  928. subs.contrast = color_corr_params.contrast;
  929. if ("exposure" in color_corr_params)
  930. subs.exposure = color_corr_params.exposure;
  931. if ("saturation" in color_corr_params)
  932. subs.saturation = color_corr_params.saturation;
  933. subs.need_perm_uniforms_update = true;
  934. }
  935. /**
  936. * Get sky params
  937. * @method module:scenes.get_sky_params
  938. * @returns {SkyParams} Sky params
  939. * @example var m_scenes = require("scenes");
  940. *
  941. * var sky_params = m_scenes.get_sky_params();
  942. */
  943. exports.get_sky_params = function() {
  944. if (!m_scenes.check_active()) {
  945. m_print.error("No active scene");
  946. return false;
  947. }
  948. var active_scene = m_scenes.get_active();
  949. return m_scenes.get_sky_params(active_scene);
  950. }
  951. /**
  952. * Set sky params
  953. * @method module:scenes.set_sky_params
  954. * @param {SkyParams} sky_params Sky params
  955. * @example var m_scenes = require("scenes");
  956. *
  957. * m_scenes.set_sky_params({ rayleigh_brightness: 3.3,
  958. * mie_brightness: 0.1,
  959. * spot_brightness: 20,
  960. * scatter_strength: 0.2,
  961. * rayleigh_strength: 0.2,
  962. * mie_strength: 0.006,
  963. * rayleigh_collection_power: 0.35,
  964. * mie_collection_power: 0.5,
  965. * mie_distribution: 0.4,
  966. * color: [0.3, 0.9, 0.3] });
  967. */
  968. exports.set_sky_params = function(sky_params) {
  969. if (!m_scenes.check_active()) {
  970. m_print.error("No active scene");
  971. return;
  972. }
  973. var scene = m_scenes.get_active();
  974. var subs = m_scenes.get_subs(scene, m_subs.SKY);
  975. if (subs) {
  976. // procedural_skydome and use_as_environment_lighting are readonly
  977. if ("color" in sky_params)
  978. subs.sky_color.set(sky_params.color);
  979. if ("rayleigh_brightness" in sky_params)
  980. subs.rayleigh_brightness = sky_params.rayleigh_brightness;
  981. if ("mie_brightness" in sky_params)
  982. subs.mie_brightness = sky_params.mie_brightness;
  983. if ("spot_brightness" in sky_params)
  984. subs.spot_brightness = sky_params.spot_brightness;
  985. if ("scatter_strength" in sky_params)
  986. subs.scatter_strength = sky_params.scatter_strength;
  987. if ("rayleigh_strength" in sky_params)
  988. subs.rayleigh_strength = sky_params.rayleigh_strength;
  989. if ("mie_strength" in sky_params)
  990. subs.mie_strength = sky_params.mie_strength;
  991. if ("rayleigh_collection_power" in sky_params)
  992. subs.rayleigh_collection_power = sky_params.rayleigh_collection_power;
  993. if ("mie_collection_power" in sky_params)
  994. subs.mie_collection_power = sky_params.mie_collection_power;
  995. if ("mie_distribution" in sky_params)
  996. subs.mie_distribution = sky_params.mie_distribution;
  997. subs.need_perm_uniforms_update = true;
  998. subs.need_fog_update = true;
  999. m_scenes.update_sky(scene, subs);
  1000. }
  1001. }
  1002. /**
  1003. * Get depth-of-field (DOF) params.
  1004. * @method module:scenes.get_dof_params
  1005. * @returns {DOFParams} The object containing DOF parameters.
  1006. * @example var m_scenes = require("scenes");
  1007. *
  1008. * var dof_params = m_scenes.get_dof_params();
  1009. */
  1010. exports.get_dof_params = function() {
  1011. if (!m_scenes.check_active()) {
  1012. m_print.error("No active scene");
  1013. return false;
  1014. }
  1015. var active_scene = m_scenes.get_active();
  1016. var subs = m_scenes.get_subs(active_scene, m_subs.DOF);
  1017. if (subs)
  1018. return m_scenes.get_dof_params(active_scene);
  1019. else
  1020. return null;
  1021. }
  1022. /**
  1023. * Set depth-of-field (DOF) params
  1024. * @method module:scenes.set_dof_params
  1025. * @param {DOFParams} dof_params The object containing DOF parameters.
  1026. * @example
  1027. * var m_scenes = require("scenes");
  1028. *
  1029. * // adjusting the front/rear distances
  1030. * m_scenes.set_dof_params({ dof_front_start: 0,
  1031. * dof_front_end: 2,
  1032. * dof_rear_start: 0,
  1033. * dof_rear_end: 5 });
  1034. *
  1035. * // disabling the DOF effect
  1036. * m_scenes.set_dof_params({ dof_on: false });
  1037. */
  1038. exports.set_dof_params = function(dof_params) {
  1039. if (!m_scenes.check_active()) {
  1040. m_print.error("No active scene");
  1041. return;
  1042. }
  1043. var active_scene = m_scenes.get_active();
  1044. m_scenes.set_dof_params(active_scene, dof_params);
  1045. }
  1046. /**
  1047. * Get god rays parameters
  1048. * @method module:scenes.get_god_rays_params
  1049. * @returns {GodRaysParams} god rays parameters
  1050. * @example var m_scenes = require("scenes");
  1051. *
  1052. * var god_ray_params = m_scenes.get_god_rays_params();
  1053. */
  1054. exports.get_god_rays_params = function() {
  1055. if (!m_scenes.check_active()) {
  1056. m_print.error("No active scene");
  1057. return false;
  1058. }
  1059. var active_scene = m_scenes.get_active();
  1060. var subs = m_scenes.get_subs(active_scene, m_subs.GOD_RAYS);
  1061. if (subs)
  1062. return m_scenes.get_god_rays_params(active_scene);
  1063. else
  1064. return null;
  1065. }
  1066. /**
  1067. * Set god rays parameters
  1068. * @method module:scenes.set_god_rays_params
  1069. * @param {GodRaysParams} god_rays_params God rays parameters
  1070. * @cc_externs god_rays_max_ray_length god_rays_intensity god_rays_steps
  1071. * @example var m_scenes = require("scenes");
  1072. *
  1073. * m_scenes.set_god_rays_params({ god_rays_max_ray_length: 1,
  1074. * god_rays_intensity: 0.7,
  1075. * god_rays_steps: 10 });
  1076. */
  1077. exports.set_god_rays_params = function(god_rays_params) {
  1078. if (!m_scenes.check_active()) {
  1079. m_print.error("No active scene");
  1080. return;
  1081. }
  1082. var active_scene = m_scenes.get_active();
  1083. m_scenes.set_god_rays_params(active_scene, god_rays_params);
  1084. }
  1085. /**
  1086. * Get bloom parameters
  1087. * @method module:scenes.get_bloom_params
  1088. * @returns {BloomParams} bloom parameters
  1089. * @example var m_scenes = require("scenes");
  1090. *
  1091. * var bloom_parameters = m_scenes.get_bloom_params();
  1092. */
  1093. exports.get_bloom_params = function() {
  1094. if (!m_scenes.check_active()) {
  1095. m_print.error("No active scene");
  1096. return false;
  1097. }
  1098. var active_scene = m_scenes.get_active();
  1099. var subs = m_scenes.get_subs(active_scene, m_subs.BLOOM);
  1100. if (subs)
  1101. return m_scenes.get_bloom_params(active_scene);
  1102. else
  1103. return null;
  1104. }
  1105. /**
  1106. * Set bloom parameters
  1107. * @method module:scenes.set_bloom_params
  1108. * @param {BloomParams} bloom_params Bloom parameters
  1109. * @example var m_scenes = require("scenes");
  1110. *
  1111. * m_scenes.set_bloom_params({ key: 1, edge_lum: 0.5, blur: 4 });
  1112. */
  1113. exports.set_bloom_params = function(bloom_params) {
  1114. if (!m_scenes.check_active()) {
  1115. m_print.error("No active scene");
  1116. return;
  1117. }
  1118. var active_scene = m_scenes.get_active();
  1119. m_scenes.set_bloom_params(active_scene, bloom_params);
  1120. }
  1121. /**
  1122. * Get glow material parameters
  1123. * @method module:scenes.get_glow_material_params
  1124. * @returns {GlowMaterialParams} glow material parameters
  1125. * @example var m_scenes = require("scenes");
  1126. *
  1127. * var glow_params = m_scenes.get_glow_material_params();
  1128. */
  1129. exports.get_glow_material_params = function() {
  1130. if (!m_scenes.check_active()) {
  1131. m_print.error("No active scene");
  1132. return false;
  1133. }
  1134. var active_scene = m_scenes.get_active();
  1135. var subs = m_scenes.get_subs(active_scene, m_subs.GLOW_COMBINE);
  1136. if (subs)
  1137. return m_scenes.get_glow_material_params(active_scene);
  1138. else
  1139. return null;
  1140. }
  1141. /**
  1142. * Set glow material parameters
  1143. * @method module:scenes.set_glow_material_params
  1144. * @param {GlowMaterialParams} glow_material_params Glow material parameters
  1145. * @cc_externs small_glow_mask_coeff large_glow_mask_coeff small_glow_mask_width large_glow_mask_width
  1146. */
  1147. exports.set_glow_material_params = function(glow_material_params) {
  1148. if (!m_scenes.check_active()) {
  1149. m_print.error("No active scene");
  1150. return;
  1151. }
  1152. var active_scene = m_scenes.get_active();
  1153. m_scenes.set_glow_material_params(active_scene, glow_material_params);
  1154. }
  1155. /**
  1156. * Get wind parameters
  1157. * @method module:scenes.get_wind_params
  1158. * @returns {WindParams} Wind params
  1159. * @example var m_scenes = require("scenes");
  1160. *
  1161. * var wind_parameters = m_scenes.get_wind_params();
  1162. */
  1163. exports.get_wind_params = function() {
  1164. if (!m_scenes.check_active()) {
  1165. m_print.error("No active scene");
  1166. return false;
  1167. }
  1168. var active_scene = m_scenes.get_active();
  1169. return m_scenes.get_wind_params(active_scene);
  1170. }
  1171. /**
  1172. * Set wind parameters
  1173. * @method module:scenes.set_wind_params
  1174. * @param {WindParams} wind_params Wind parameters
  1175. * @example var m_scenes = require("scenes");
  1176. *
  1177. * m_scenes.set_wind_params({ wind_dir: 90,
  1178. * wind_strength: 3 });
  1179. */
  1180. exports.set_wind_params = function(wind_params) {
  1181. if (!m_scenes.check_active()) {
  1182. m_print.error("No active scene");
  1183. return;
  1184. }
  1185. var active_scene = m_scenes.get_active();
  1186. m_obj.set_wind_params(active_scene, wind_params);
  1187. }
  1188. /**
  1189. * Get water surface level.
  1190. * @method module:scenes.get_water_surface_level
  1191. * @param {number} pos_x World x position
  1192. * @param {number} pos_y World y position
  1193. * @returns {number} Surface level
  1194. * @example var m_scenes = require("scenes");
  1195. *
  1196. * var water_level = m_scenes.get_water_surface_level(10.3, 15.6);
  1197. */
  1198. exports.get_water_surface_level = function(pos_x, pos_y) {
  1199. if (!m_scenes.check_active()) {
  1200. m_print.error("No active scene");
  1201. return 0;
  1202. }
  1203. var active_scene = m_scenes.get_active();
  1204. if (!active_scene._render.water_params) {
  1205. m_print.error("No water parameters on the active scene");
  1206. return 0;
  1207. }
  1208. return m_scenes.get_water_surface_level(active_scene, pos_x, pos_y);
  1209. }
  1210. /**
  1211. * Set water params
  1212. * @method module:scenes.set_water_params
  1213. * @param {WaterParams} water_params Water parameters
  1214. * @cc_externs waves_height waves_length water_fog_density water_fog_color
  1215. * @cc_externs dst_noise_scale0 dst_noise_scale1 dst_noise_freq0 dst_noise_freq1
  1216. * @cc_externs dir_min_shore_fac dir_freq dir_noise_scale dir_noise_freq
  1217. * @cc_externs dir_min_noise_fac dst_min_fac waves_hor_fac water_dynamic
  1218. */
  1219. exports.set_water_params = function(water_params) {
  1220. if (!m_scenes.check_active()) {
  1221. m_print.error("No active scene");
  1222. return;
  1223. }
  1224. var active_scene = m_scenes.get_active();
  1225. m_scenes.set_water_params(active_scene, water_params);
  1226. }
  1227. /**
  1228. * Get water material parameters.
  1229. * @method module:scenes.get_water_mat_params
  1230. * @param {WaterParams} water_params Water parameters
  1231. */
  1232. exports.get_water_mat_params = function(water_params) {
  1233. if (!m_scenes.check_active()) {
  1234. m_print.error("No active scene");
  1235. return;
  1236. }
  1237. var active_scene = m_scenes.get_active();
  1238. m_scenes.get_water_mat_params(active_scene, water_params);
  1239. }
  1240. /**
  1241. * Update scene materials parameters.
  1242. * @method module:scenes.update_scene_materials_params
  1243. * @example var m_scenes = require("scenes");
  1244. *
  1245. * m_scenes.update_scene_materials_params();
  1246. */
  1247. exports.update_scene_materials_params = function() {
  1248. if (!m_scenes.check_active()) {
  1249. m_print.error("No active scene");
  1250. return;
  1251. }
  1252. var active_scene = m_scenes.get_active();
  1253. m_scenes.update_scene_permanent_uniforms(active_scene);
  1254. }
  1255. /**
  1256. * Hide object and his children if it's necessary.
  1257. * Supported only for dynamic meshes/empties and lamps.
  1258. * @method module:scenes.hide_object
  1259. * @param {Object3D} obj Object 3D
  1260. * @param {boolean} [ignore_children=false] Don't hide child objects.
  1261. * @example var m_scenes = require("scenes");
  1262. * var cube = m_scenes.get_object_by_name("Cube");
  1263. *
  1264. * m_scenes.hide_object(cube);
  1265. */
  1266. exports.hide_object = function(obj, ignore_children) {
  1267. ignore_children = ignore_children || false;
  1268. if (!is_hideable(obj))
  1269. m_print.error("show/hide is only supported for dynamic objects.");
  1270. else
  1271. if (ignore_children)
  1272. m_scenes.change_visibility(obj, true);
  1273. else
  1274. m_scenes.change_visibility_rec(obj, true);
  1275. }
  1276. /**
  1277. * Show object and his children if it's necessary.
  1278. * Supported only for dynamic meshes/empties and lamps.
  1279. * @method module:scenes.show_object
  1280. * @param {Object3D} obj Object 3D
  1281. * @param {boolean} [ignore_children=false] Don't show child objects.
  1282. * @example var m_scenes = require("scenes");
  1283. *
  1284. * var cube = m_scenes.get_object_by_name("Cube");
  1285. *
  1286. * m_scenes.show_object(cube);
  1287. */
  1288. exports.show_object = function(obj, ignore_children) {
  1289. ignore_children = ignore_children || false;
  1290. if (!is_hideable(obj))
  1291. m_print.error("show/hide is only supported for dynamic objects.");
  1292. else
  1293. if (ignore_children)
  1294. m_scenes.change_visibility(obj, false);
  1295. else
  1296. m_scenes.change_visibility_rec(obj, false);
  1297. }
  1298. /**
  1299. * Check if object is hidden.
  1300. * Supported only for dynamic meshes/empties and lamps.
  1301. * @method module:scenes.is_hidden
  1302. * @param {Object3D} obj Object 3D
  1303. * @returns {boolean} Check result
  1304. * @example var m_scenes = require("scenes");
  1305. *
  1306. * var cube = m_scenes.get_object_by_name("Cube");
  1307. *
  1308. * var object_is_hidden = m_scenes.is_hidden(cube);
  1309. */
  1310. exports.is_hidden = function(obj) {
  1311. if (is_hideable(obj)) {
  1312. return m_scenes.is_hidden(obj);
  1313. } else {
  1314. m_print.error("show/hide is only supported for dynamic meshes/empties and lamps");
  1315. return false;
  1316. }
  1317. }
  1318. function is_hideable(obj) {
  1319. return m_obj_util.is_dynamic_mesh(obj) || m_obj_util.is_empty(obj)
  1320. || m_obj_util.is_line(obj) || m_obj_util.is_lamp(obj)
  1321. }
  1322. /**
  1323. * Check if object is visible.
  1324. * @method module:scenes.is_visible
  1325. * @param {Object3D} obj Object 3D
  1326. * @returns {boolean} Check result
  1327. * @example var m_scenes = require("scenes");
  1328. *
  1329. * var cube = m_scenes.get_object_by_name("Cube");
  1330. *
  1331. * var object_is_visible = m_scenes.is_visible(cube);
  1332. */
  1333. exports.is_visible = function(obj) {
  1334. return obj.render.is_visible;
  1335. }
  1336. /**
  1337. * Check if object with given name is present on scene.
  1338. * @method module:scenes.check_object_by_name
  1339. * @param {string} name Object name
  1340. * @param {number} [data_id=0] ID of loaded data
  1341. * @returns {boolean} Check result
  1342. */
  1343. exports.check_object_by_name = function(name, data_id) {
  1344. var obj = m_obj.get_object(m_obj.GET_OBJECT_BY_NAME, name,
  1345. data_id | 0, true);
  1346. if (obj)
  1347. return true;
  1348. else
  1349. return false;
  1350. }
  1351. /**
  1352. * Check if duplicated object is present on scene by empty name and dupli name.
  1353. * @method module:scenes.check_object_by_dupli_name
  1354. * @param {string} empty_name Name of the EMPTY object used to duplicate the object
  1355. * @param {string} dupli_name Name of the duplicated object
  1356. * @param {number} [data_id=0] ID of loaded data
  1357. * @returns {boolean} Check result
  1358. */
  1359. exports.check_object_by_dupli_name = function(empty_name, dupli_name,
  1360. data_id) {
  1361. var obj = m_obj.get_object(m_obj.GET_OBJECT_BY_DUPLI_NAME, empty_name,
  1362. dupli_name, data_id | 0);
  1363. if (obj)
  1364. return true;
  1365. else
  1366. return false;
  1367. }
  1368. /**
  1369. * Check if duplicated object is present on scene by empty name and dupli name list.
  1370. * @method module:scenes.check_object_by_dupli_name_list
  1371. * @param {string[]} name_list List of the EMPTY and DUPLI object names: [empty_name,empty_name,...,dupli_name]
  1372. * @param {number} [data_id=0] ID of loaded data
  1373. * @returns {boolean} Check result
  1374. */
  1375. exports.check_object_by_dupli_name_list = function(name_list, data_id) {
  1376. var obj = m_obj.get_object(m_obj.GET_OBJECT_BY_DUPLI_NAME_LIST,
  1377. name_list, data_id | 0);
  1378. if (obj)
  1379. return true;
  1380. else
  1381. return false;
  1382. }
  1383. /**
  1384. * Get all objects from the active scene.
  1385. * @method module:scenes.get_all_objects
  1386. * @param {string} [type="ALL"] Object type.
  1387. * @param {number} [data_id=DATA_ID_ALL] Objects data id
  1388. * @returns {Object3D[]} Array with objects.
  1389. * @example var m_scenes = require("scenes");
  1390. *
  1391. * // get objects of all types
  1392. * var scene_object_list = m_scenes.get_all_objects();
  1393. *
  1394. * // get all MESH objects
  1395. * var scene_object_list = m_scenes.get_all_objects("MESH");
  1396. *
  1397. * // get all SPEAKER objects from the first dynamically loaded scene
  1398. * var scene_object_list = m_scenes.get_all_objects("SPEAKER", 1);
  1399. */
  1400. exports.get_all_objects = function(type, data_id) {
  1401. var scene = m_scenes.get_active();
  1402. if (!type)
  1403. type = "ALL";
  1404. if (!data_id && data_id !== 0)
  1405. data_id = m_obj.DATA_ID_ALL;
  1406. return m_obj.get_scene_objs_derived(scene, type, data_id);
  1407. }
  1408. /**
  1409. * Get the object's name.
  1410. * @method module:scenes.get_object_name
  1411. * @param {Object3D} obj Object 3D
  1412. * @returns {string} Object name
  1413. * @example var m_scenes = require("scenes");
  1414. *
  1415. * var cube = m_scenes.get_object_by_name("Cube");
  1416. *
  1417. * var object_name = m_scenes.get_object_name(cube);
  1418. */
  1419. exports.get_object_name = function(obj) {
  1420. if (!obj) {
  1421. m_print.error("Wrong object name");
  1422. return "";
  1423. }
  1424. return obj.origin_name;
  1425. }
  1426. /**
  1427. * Get the object names hierarchy (considering dupli group parenting).
  1428. * @method module:scenes.get_object_name_hierarchy
  1429. * @param {Object3D} obj Object 3D
  1430. * @returns {?Array} Object names hierarchy array (from the highest parent to the object itself).
  1431. * @example var m_scenes = require("scenes");
  1432. *
  1433. * var cube = m_scenes.get_object_by_name("Cube");
  1434. *
  1435. * var name_hierarchy = m_scenes.get_object_name_hierarchy(cube);
  1436. */
  1437. exports.get_object_name_hierarchy = function(obj) {
  1438. if (!obj) {
  1439. m_print.error("Wrong object name");
  1440. return null;
  1441. }
  1442. var names = [];
  1443. var curr_obj = obj;
  1444. while (curr_obj) {
  1445. names.push(curr_obj.origin_name);
  1446. curr_obj = m_obj_util.get_dg_parent(curr_obj);
  1447. }
  1448. return names.reverse();
  1449. }
  1450. /**
  1451. * Get the object's type.
  1452. * @method module:scenes.get_object_type
  1453. * @param {Object3D} obj Object 3D
  1454. * @returns {string} Object type
  1455. * @example var m_scenes = require("scenes");
  1456. *
  1457. * var cube = m_scenes.get_object_by_name("Cube");
  1458. *
  1459. * var object_type = m_scenes.get_object_type(cube);
  1460. */
  1461. exports.get_object_type = function(obj) {
  1462. if (!(obj && obj.type)) {
  1463. m_print.error("Wrong object");
  1464. return "UNDEFINED";
  1465. }
  1466. return obj.type;
  1467. }
  1468. /**
  1469. * Return the object's children.
  1470. * @method module:scenes.get_object_children
  1471. * @param {Object3D} obj Object 3D
  1472. * @returns {Object3D[]} Array of children objects.
  1473. * @example var m_scenes = require("scenes");
  1474. *
  1475. * var cube = m_scenes.get_object_by_name("Cube");
  1476. *
  1477. * var object_children = m_scenes.get_object_children(cube);
  1478. */
  1479. exports.get_object_children = function(obj) {
  1480. return obj.cons_descends.slice(0);
  1481. }
  1482. /**
  1483. * Find the first character on the active scene.
  1484. * @method module:scenes.get_first_character
  1485. * @returns {Object3D} Character object.
  1486. * @example var m_scenes = require("scenes");
  1487. *
  1488. * var character = m_scenes.get_first_character();
  1489. */
  1490. exports.get_first_character = function() {
  1491. return m_obj.get_first_character(m_scenes.get_active());
  1492. }
  1493. /**
  1494. * Return the distance to the shore line.
  1495. * @method module:scenes.get_shore_dist
  1496. * @param {Vec3} trans Current translation.
  1497. * @param {number} [v_dist_mult=1] Vertical distance multiplier.
  1498. * @returns {number} Distance.
  1499. */
  1500. exports.get_shore_dist = function(trans, v_dist_mult) {
  1501. if (!v_dist_mult && v_dist_mult !== 0)
  1502. v_dist_mult = 1;
  1503. if (!m_scenes.check_active()) {
  1504. m_print.error("No active scene");
  1505. return 0;
  1506. }
  1507. var active_scene = m_scenes.get_active();
  1508. return m_scenes.get_shore_dist(active_scene, trans, v_dist_mult);
  1509. }
  1510. /**
  1511. * Return the camera water depth or null if there is no water.
  1512. * @method module:scenes.get_cam_water_depth
  1513. * @returns {number} Depth
  1514. * @example var m_scenes = require("scenes");
  1515. *
  1516. * var water_depth = m_scenes.get_cam_water_depth();
  1517. */
  1518. exports.get_cam_water_depth = function() {
  1519. return m_scenes.get_cam_water_depth();
  1520. }
  1521. /**
  1522. * Return render type of mesh object or null.
  1523. * @method module:scenes.get_type_mesh_object
  1524. * @param {Object3D} obj Object 3D.
  1525. * @returns {string} Render type: "DYNAMIC" or "STATIC" or ""(for non meshes).
  1526. * @example var m_scenes = require("scenes");
  1527. *
  1528. * var cube = m_scenes.get_object_by_name("Cube");
  1529. * var type = m_scenes.get_type_mesh_object(cube);
  1530. */
  1531. exports.get_type_mesh_object = function(obj) {
  1532. if (m_obj_util.is_mesh(obj))
  1533. return obj.render.type;
  1534. return "";
  1535. }
  1536. /**
  1537. * Get the Blender-assigned meta tags from the active scene.
  1538. * @method module:scenes.get_meta_tags
  1539. * @returns {SceneMetaTags} Scene meta tags
  1540. * @example var m_scenes = require("scenes");
  1541. *
  1542. * var meta_tags = m_scenes.get_meta_tags();
  1543. */
  1544. exports.get_meta_tags = function() {
  1545. if (!m_scenes.check_active()) {
  1546. m_print.error("No active scene");
  1547. return false;
  1548. }
  1549. var active_scene = m_scenes.get_active();
  1550. return m_scenes.get_meta_tags(active_scene);
  1551. }
  1552. /**
  1553. * Get the Blender-assigned custom property from the active scene.
  1554. * @method module:scenes.get_custom_prop
  1555. * @returns {*} Scene custom property
  1556. */
  1557. exports.get_custom_prop = function() {
  1558. if (!m_scenes.check_active()) {
  1559. m_print.error("No active scene");
  1560. return false;
  1561. }
  1562. var active_scene = m_scenes.get_active();
  1563. return m_scenes.get_custom_prop(active_scene);
  1564. }
  1565. /**
  1566. * Append copied object to the scene.
  1567. * @method module:scenes.append_object
  1568. * @param {Object3D} obj Object 3D
  1569. * @param {string} [scene_name] Name of the scene
  1570. * @example var m_scs = require("scenes");
  1571. * var m_obj = require("objects");
  1572. *
  1573. * var src_obj = m_scs.get_object_by_name("Plane");
  1574. * var deep_copy = m_obj.copy(src_obj, "deep_copy", true);
  1575. *
  1576. * m_scs.append_object(deep_copy);
  1577. */
  1578. exports.append_object = function(obj, scene_name) {
  1579. if (scene_name) {
  1580. var scenes = m_scenes.get_all_scenes();
  1581. var scene = m_util.keysearch("name", scene_name, scenes);
  1582. } else
  1583. var scene = m_scenes.get_active();
  1584. m_scenes.append_object(scene, obj, true);
  1585. m_phy.append_object(obj, scene);
  1586. }
  1587. /**
  1588. * Remove dynamic object from all scenes.
  1589. * @method module:scenes.remove_object
  1590. * @param {Object3D} obj Object 3D
  1591. * @example var m_scenes = require("scenes");
  1592. *
  1593. * var cube = m_scenes.get_object_by_name("Cube");
  1594. * m_scenes.remove_object(cube);
  1595. */
  1596. exports.remove_object = function(obj) {
  1597. if (!m_obj_util.is_dynamic_mesh(obj) && !m_obj_util.is_empty(obj) &&
  1598. !m_obj_util.is_line(obj)) {
  1599. m_print.error("Can't remove object \"" + obj.name + "\". It must be " +
  1600. "dynamic and type of MESH or EMPTY.");
  1601. return;
  1602. }
  1603. // cleanup only vbo/ibo/vao buffers for deep copied objects
  1604. m_obj.obj_switch_cleanup_flags(obj, obj.render.is_copied_deep, false, false);
  1605. m_data.prepare_object_unloading(obj);
  1606. m_obj.obj_switch_cleanup_flags(obj, true, true, true);
  1607. m_obj.remove_object(obj);
  1608. }
  1609. /**
  1610. * Get timeline marker frame by name.
  1611. * @method module:scenes.marker_frame
  1612. * @param {string} name Timeline marker name
  1613. * @returns {number} Timeline marker frame
  1614. */
  1615. exports.marker_frame = function(name) {
  1616. var active_scene = m_scenes.get_active();
  1617. if (active_scene["timeline_markers"]
  1618. && name in active_scene["timeline_markers"])
  1619. return m_scenes.marker_frame(active_scene, name);
  1620. else {
  1621. m_print.error("\"" + name + "\" marker not found.");
  1622. return 0;
  1623. }
  1624. }
  1625. /**
  1626. * Get motion blur params.
  1627. * @method module:scenes.get_mb_params
  1628. * @returns {MotionBlurParams} Motion blur params
  1629. * @example var m_scenes = require("scenes");
  1630. *
  1631. * var motion_blur_params = m_scenes.get_mb_params();
  1632. */
  1633. exports.get_mb_params = function() {
  1634. var scene = m_scenes.get_active();
  1635. var mb_subs = m_scenes.get_subs(scene, m_subs.MOTION_BLUR);
  1636. if (mb_subs) {
  1637. var mb_params = {mb_factor : mb_subs.mb_factor,
  1638. mb_decay_threshold : mb_subs.mb_decay_threshold};
  1639. return mb_params;
  1640. } else
  1641. return null;
  1642. }
  1643. /**
  1644. * Set motion blur params.
  1645. * @method module:scenes.set_mb_params
  1646. * @param {MotionBlurParams} mb_params Motion blur params
  1647. * @cc_externs mb_factor mb_decay_threshold
  1648. * @example var m_scenes = require("scenes");
  1649. *
  1650. * m_scenes.set_mb_params({ mb_factor: 0.1,
  1651. * mb_decay_threshold: 0.01 });
  1652. */
  1653. exports.set_mb_params = function(mb_params) {
  1654. var scene = m_scenes.get_active();
  1655. var mb_subscenes = m_scenes.subs_array(scene, [m_subs.MOTION_BLUR]);
  1656. if (!mb_subscenes.length) {
  1657. m_print.error("The motion blur subscene doesn't exist.")
  1658. return;
  1659. }
  1660. for (var i = 0; i < mb_subscenes.length; i++) {
  1661. var mb_subs = mb_subscenes[i];
  1662. if (typeof mb_params.mb_decay_threshold == "number")
  1663. mb_subs.mb_decay_threshold = mb_params.mb_decay_threshold;
  1664. if (typeof mb_params.mb_factor == "number")
  1665. mb_subs.mb_factor = mb_params.mb_factor;
  1666. }
  1667. }
  1668. /**
  1669. * Check if objects can be selected.
  1670. * @method module:scenes.can_select_objects
  1671. * @returns {boolean} True if objects can be selected.
  1672. * @example var m_scenes = require("scenes");
  1673. *
  1674. * var objects_selectable = m_scenes.can_select_objects();
  1675. */
  1676. exports.can_select_objects = function() {
  1677. var scene = m_scenes.get_active();
  1678. return Boolean(m_scenes.get_subs(scene, m_subs.COLOR_PICKING));
  1679. }
  1680. }
  1681. var scenes_factory = register("scenes", Scenes);
  1682. export default scenes_factory;