Reference Source

src/viewer/scene/materials/PointsMaterial.js

  1. import {Material} from './Material.js';
  2. import {RenderState} from '../webgl/RenderState.js';
  3.  
  4. const PRESETS = {
  5. "default": {
  6. pointSize: 4,
  7. roundPoints: true,
  8. perspectivePoints: true
  9. },
  10. "square": {
  11. pointSize: 4,
  12. roundPoints: false,
  13. perspectivePoints: true
  14. },
  15. "round": {
  16. pointSize: 4,
  17. roundPoints: true,
  18. perspectivePoints: true
  19. }
  20. };
  21.  
  22. /**
  23. * @desc Configures the size and shape of "points" geometry primitives.
  24. *
  25. * * Located at {@link Scene#pointsMaterial}.
  26. * * Supports round and square points.
  27. * * Optional perspective point scaling.
  28. * * Globally configures "points" primitives for all {@link VBOSceneModel}s.
  29. *
  30. * ## Usage
  31. *
  32. * In the example below, we'll customize the {@link Scene}'s global ````PointsMaterial````, then use
  33. * an {@link XKTLoaderPlugin} to load a model containing a point cloud.
  34. *
  35. * [[Run this example](/examples/index.html#materials_PointsMaterial)]
  36. *
  37. * ````javascript
  38. * import {Viewer, XKTLoaderPlugin} from "xeokit-sdk.es.js";
  39. *
  40. * const viewer = new Viewer({
  41. * canvasId: "myCanvas",
  42. * transparent: true
  43. * });
  44. *
  45. * viewer.scene.camera.eye = [0, 0, 5];
  46. * viewer.scene.camera.look = [0, 0, 0];
  47. * viewer.scene.camera.up = [0, 1, 0];
  48. *
  49. * viewer.scene.pointsMaterial.pointSize = 2;
  50. * viewer.scene.pointsMaterial.roundPoints = true;
  51. * viewer.scene.pointsMaterial.perspectivePoints = true;
  52. * viewer.scene.pointsMaterial.minPerspectivePointSize = 1;
  53. * viewer.scene.pointsMaterial.maxPerspectivePointSize = 6;
  54. * viewer.scene.pointsMaterial.filterIntensity = true;
  55. * viewer.scene.pointsMaterial.minIntensity = 0.0;
  56. * viewer.scene.pointsMaterial.maxIntensity = 1.0;
  57. *
  58. * const xktLoader = new XKTLoaderPlugin(viewer);
  59. *
  60. * const model = xktLoader.load({
  61. * id: "myModel",
  62. * src: "../assets/models/xkt/MAP-PointCloud.xkt"
  63. * });
  64. * ````
  65. */
  66. class PointsMaterial extends Material {
  67.  
  68. /**
  69. @private
  70. */
  71. get type() {
  72. return "PointsMaterial";
  73. }
  74.  
  75. /**
  76. * Gets available PointsMaterial presets.
  77. *
  78. * @type {Object}
  79. */
  80. get presets() {
  81. return PRESETS;
  82. };
  83.  
  84. /**
  85. * @constructor
  86. * @param {Component} owner Owner component. When destroyed, the owner will destroy this component as well.
  87. * @param {*} [cfg] The PointsMaterial configuration
  88. * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.
  89. * @param {Number} [cfg.pointSize=2] Point size in pixels.
  90. * @param {Boolean} [cfg.roundPoints=true] Whether points are round (````true````) or square (````false````).
  91. * @param {Boolean} [cfg.perspectivePoints=true] Whether apparent point size reduces with distance when {@link Camera#projection} is set to "perspective".
  92. * @param {Number} [cfg.minPerspectivePointSize=1] When ````perspectivePoints```` is ````true````, this is the minimum rendered size of each point in pixels.
  93. * @param {Number} [cfg.maxPerspectivePointSize=6] When ````perspectivePoints```` is ````true````, this is the maximum rendered size of each point in pixels.
  94. * @param {Boolean} [cfg.filterIntensity=false] When this is true, points are only rendered when their intensity value falls within the range given in {@link }
  95. * @param {Number} [cfg.minIntensity=0] When ````filterIntensity```` is ````true````, points with intensity below this value will not be rendered.
  96. * @param {Number} [cfg.maxIntensity=1] When ````filterIntensity```` is ````true````, points with intensity above this value will not be rendered.
  97. * @param {String} [cfg.preset] Selects a preset PointsMaterial configuration - see {@link PointsMaterial#presets}.
  98. */
  99. constructor(owner, cfg = {}) {
  100.  
  101. super(owner, cfg);
  102.  
  103. this._state = new RenderState({
  104. type: "PointsMaterial",
  105. pointSize: null,
  106. roundPoints: null,
  107. perspectivePoints: null,
  108. minPerspectivePointSize: null,
  109. maxPerspectivePointSize: null,
  110. filterIntensity: null,
  111. minIntensity: null,
  112. maxIntensity: null
  113. });
  114.  
  115. if (cfg.preset) { // Apply preset then override with configs where provided
  116. this.preset = cfg.preset;
  117. if (cfg.pointSize !== undefined) {
  118. this.pointSize = cfg.pointSize;
  119. }
  120. if (cfg.roundPoints !== undefined) {
  121. this.roundPoints = cfg.roundPoints;
  122. }
  123. if (cfg.perspectivePoints !== undefined) {
  124. this.perspectivePoints = cfg.perspectivePoints;
  125. }
  126. if (cfg.minPerspectivePointSize !== undefined) {
  127. this.minPerspectivePointSize = cfg.minPerspectivePointSize;
  128. }
  129. if (cfg.maxPerspectivePointSize !== undefined) {
  130. this.maxPerspectivePointSize = cfg.minPerspectivePointSize;
  131. }
  132. } else {
  133. this._preset = "default";
  134. this.pointSize = cfg.pointSize;
  135. this.roundPoints = cfg.roundPoints;
  136.  
  137. this.perspectivePoints = cfg.perspectivePoints;
  138. this.minPerspectivePointSize = cfg.minPerspectivePointSize;
  139. this.maxPerspectivePointSize = cfg.maxPerspectivePointSize;
  140. }
  141.  
  142. this.filterIntensity = cfg.filterIntensity;
  143. this.minIntensity = cfg.minIntensity;
  144. this.maxIntensity = cfg.maxIntensity;
  145. }
  146.  
  147. /**
  148. * Sets point size.
  149. *
  150. * Default value is ````2.0```` pixels.
  151. *
  152. * @type {Number}
  153. */
  154. set pointSize(value) {
  155. this._state.pointSize = value || 2.0;
  156. this.glRedraw();
  157. }
  158.  
  159. /**
  160. * Gets point size.
  161. *
  162. * Default value is ````2.0```` pixels.
  163. *
  164. * @type {Number}
  165. */
  166. get pointSize() {
  167. return this._state.pointSize;
  168. }
  169.  
  170.  
  171. /**
  172. * Sets if points are round or square.
  173. *
  174. * Default is ````true```` to set points round.
  175. *
  176. * @type {Boolean}
  177. */
  178. set roundPoints(value) {
  179. value = (value !== false);
  180. if (this._state.roundPoints === value) {
  181. return;
  182. }
  183. this._state.roundPoints = value;
  184. this.scene._needRecompile = true;
  185. this.glRedraw();
  186. }
  187.  
  188. /**
  189. * Gets if points are round or square.
  190. *
  191. * Default is ````true```` to set points round.
  192. *
  193. * @type {Boolean}
  194. */
  195. get roundPoints() {
  196. return this._state.roundPoints;
  197. }
  198.  
  199. /**
  200. * Sets if rendered point size reduces with distance when {@link Camera#projection} is set to ````"perspective"````.
  201. *
  202. * Default is ````true````.
  203. *
  204. * @type {Boolean}
  205. */
  206. set perspectivePoints(value) {
  207. value = (value !== false);
  208. if (this._state.perspectivePoints === value) {
  209. return;
  210. }
  211. this._state.perspectivePoints = value;
  212. this.scene._needRecompile = true;
  213. this.glRedraw();
  214. }
  215.  
  216. /**
  217. * Gets if rendered point size reduces with distance when {@link Camera#projection} is set to "perspective".
  218. *
  219. * Default is ````false````.
  220. *
  221. * @type {Boolean}
  222. */
  223. get perspectivePoints() {
  224. return this._state.perspectivePoints;
  225. }
  226.  
  227. /**
  228. * Sets the minimum rendered size of points when {@link PointsMaterial#perspectivePoints} is ````true````.
  229. *
  230. * Default value is ````1.0```` pixels.
  231. *
  232. * @type {Number}
  233. */
  234. set minPerspectivePointSize(value) {
  235. this._state.minPerspectivePointSize = value || 1.0;
  236. this.scene._needRecompile = true;
  237. this.glRedraw();
  238. }
  239.  
  240. /**
  241. * Gets the minimum rendered size of points when {@link PointsMaterial#perspectivePoints} is ````true````.
  242. *
  243. * Default value is ````1.0```` pixels.
  244. *
  245. * @type {Number}
  246. */
  247. get minPerspectivePointSize() {
  248. return this._state.minPerspectivePointSize;
  249. }
  250.  
  251. /**
  252. * Sets the maximum rendered size of points when {@link PointsMaterial#perspectivePoints} is ````true````.
  253. *
  254. * Default value is ````6```` pixels.
  255. *
  256. * @type {Number}
  257. */
  258. set maxPerspectivePointSize(value) {
  259. this._state.maxPerspectivePointSize = value || 6;
  260. this.scene._needRecompile = true;
  261. this.glRedraw();
  262. }
  263.  
  264. /**
  265. * Gets the maximum rendered size of points when {@link PointsMaterial#perspectivePoints} is ````true````.
  266. *
  267. * Default value is ````6```` pixels.
  268. *
  269. * @type {Number}
  270. */
  271. get maxPerspectivePointSize() {
  272. return this._state.maxPerspectivePointSize;
  273. }
  274.  
  275. /**
  276. * Sets if rendered point size reduces with distance when {@link Camera#projection} is set to ````"perspective"````.
  277. *
  278. * Default is ````false````.
  279. *
  280. * @type {Boolean}
  281. */
  282. set filterIntensity(value) {
  283. value = (value !== false);
  284. if (this._state.filterIntensity === value) {
  285. return;
  286. }
  287. this._state.filterIntensity = value;
  288. this.scene._needRecompile = true;
  289. this.glRedraw();
  290. }
  291.  
  292. /**
  293. * Gets if rendered point size reduces with distance when {@link Camera#projection} is set to "perspective".
  294. *
  295. * Default is ````false````.
  296. *
  297. * @type {Boolean}
  298. */
  299. get filterIntensity() {
  300. return this._state.filterIntensity;
  301. }
  302.  
  303. /**
  304. * Sets the minimum rendered size of points when {@link PointsMaterial#perspectivePoints} is ````true````.
  305. *
  306. * Default value is ````0````.
  307. *
  308. * @type {Number}
  309. */
  310. set minIntensity(value) {
  311. this._state.minIntensity = (value !== undefined && value !== null) ? value: 0.0;
  312. this.glRedraw();
  313. }
  314.  
  315. /**
  316. * Gets the minimum rendered size of points when {@link PointsMaterial#filterIntensity} is ````true````.
  317. *
  318. * Default value is ````0````.
  319. *
  320. * @type {Number}
  321. */
  322. get minIntensity() {
  323. return this._state.minIntensity;
  324. }
  325.  
  326. /**
  327. * Sets the maximum rendered size of points when {@link PointsMaterial#filterIntensity} is ````true````.
  328. *
  329. * Default value is ````1````.
  330. *
  331. * @type {Number}
  332. */
  333. set maxIntensity(value) {
  334. this._state.maxIntensity = (value !== undefined && value !== null) ? value: 1.0;
  335. this.glRedraw();
  336. }
  337.  
  338. /**
  339. * Gets the maximum rendered size of points when {@link PointsMaterial#filterIntensity} is ````true````.
  340. *
  341. * Default value is ````1````.
  342. *
  343. * @type {Number}
  344. */
  345. get maxIntensity() {
  346. return this._state.maxIntensity;
  347. }
  348.  
  349. /**
  350. * Selects a preset ````PointsMaterial```` configuration.
  351. *
  352. * Default value is ````"default"````.
  353. *
  354. * @type {String}
  355. */
  356. set preset(value) {
  357. value = value || "default";
  358. if (this._preset === value) {
  359. return;
  360. }
  361. const preset = PRESETS[value];
  362. if (!preset) {
  363. this.error("unsupported preset: '" + value + "' - supported values are " + Object.keys(PRESETS).join(", "));
  364. return;
  365. }
  366. this.pointSize = preset.pointSize;
  367. this.roundPoints = preset.roundPoints;
  368. this.perspectivePoints = preset.perspectivePoints;
  369. this.minPerspectivePointSize = preset.minPerspectivePointSize;
  370. this.maxPerspectivePointSize = preset.maxPerspectivePointSize;
  371. this._preset = value;
  372. }
  373.  
  374. /**
  375. * The current preset ````PointsMaterial```` configuration.
  376. *
  377. * Default value is ````"default"````.
  378. *
  379. * @type {String}
  380. */
  381. get preset() {
  382. return this._preset;
  383. }
  384.  
  385. /**
  386. * @private
  387. * @return {string}
  388. */
  389. get hash() {
  390. return [
  391. this.pointSize,
  392. this.roundPoints,
  393. this.perspectivePoints,
  394. this.minPerspectivePointSize,
  395. this.maxPerspectivePointSize,
  396. this.filterIntensity
  397. ].join((";"));
  398. }
  399.  
  400. /**
  401. * Destroys this ````PointsMaterial````.
  402. */
  403. destroy() {
  404. super.destroy();
  405. this._state.destroy();
  406. }
  407. }
  408.  
  409. export {PointsMaterial};