webgl/pointUtil.js

  1. var pointFeature = require('../pointFeature');
  2. /**
  3. * Extend a point-like feature with additional functions.
  4. *
  5. * @param {this} m_this The point-like feature.
  6. * @param {object} [arg] Feature definition object that might specify the
  7. * primitive shape.
  8. * @memberof geo.webgl
  9. */
  10. function pointUtil(m_this, arg) {
  11. arg = arg || {};
  12. m_this._primitiveShapeAuto = true;
  13. m_this._primitiveShape = pointFeature.primitiveShapes.auto;
  14. if (pointFeature.primitiveShapes[arg.primitiveShape] !== undefined) {
  15. m_this._primitiveShape = arg.primitiveShape;
  16. }
  17. m_this._primitiveShapeAuto = m_this._primitiveShape === pointFeature.primitiveShapes.auto;
  18. if (m_this._primitiveShapeAuto) {
  19. m_this._primitiveShape = pointFeature.primitiveShapes.sprite;
  20. m_this._primitiveShapeAuto = true;
  21. }
  22. /**
  23. * Given the current primitive shape and a basic size, return a set of
  24. * vertices that can be used for a generic point.
  25. *
  26. * @param {number} x The base x coordinate. Usually 0.
  27. * @param {number} y The base y coordinate. Usually 0.
  28. * @param {number} w The base width. Usually 1.
  29. * @param {number} h The base height. Usually 1.
  30. * @returns {number[]} A flat array of vertices in the form of
  31. * `[x0, y0, x1, y1, ...]`.
  32. */
  33. m_this._pointPolygon = function (x, y, w, h) {
  34. var verts;
  35. switch (m_this._primitiveShape) {
  36. case pointFeature.primitiveShapes.triangle:
  37. /* Use an equilateral triangle. While this has 30% more area than a
  38. * square, the reduction in vertices should help more than the
  39. * processing the additional fragments. */
  40. verts = [
  41. x, y - h * 2,
  42. x - w * Math.sqrt(3.0), y + h,
  43. x + w * Math.sqrt(3.0), y + h
  44. ];
  45. break;
  46. case pointFeature.primitiveShapes.square:
  47. /* Use a surrounding square split diagonally into two triangles. */
  48. verts = [
  49. x - w, y + h,
  50. x - w, y - h,
  51. x + w, y + h,
  52. x - w, y - h,
  53. x + w, y - h,
  54. x + w, y + h
  55. ];
  56. break;
  57. default: // sprite
  58. /* Point sprite uses only one vertex per point. */
  59. verts = [x, y];
  60. break;
  61. }
  62. return verts;
  63. };
  64. /**
  65. * Return the number of vertices used for each point.
  66. *
  67. * @returns {number}
  68. */
  69. m_this.verticesPerFeature = function () {
  70. var unit = m_this._pointPolygon(0, 0, 1, 1);
  71. return unit.length / 2;
  72. };
  73. /**
  74. * Get or set the primitiveShape.
  75. *
  76. * @param {geo.pointFeature.primitiveShapes} [primitiveShape] If specified,
  77. * the new primitive shape.
  78. * @param {boolean} [currentShape] If truthy and getting the shape, return
  79. * the shape currently in use if the shape is set to `auto`. If falsy,
  80. * return the specific primitiveShape, which may be `auto`.
  81. * @returns {geo.pointFeature.primitiveShapes|this} The primitiveShape or
  82. * this instance of the feature.
  83. */
  84. m_this.primitiveShape = function (primitiveShape, currentShape) {
  85. if (primitiveShape === undefined) {
  86. return currentShape || !m_this._primitiveShapeAuto ? m_this._primitiveShape : pointFeature.primitiveShapes.auto;
  87. }
  88. if (pointFeature.primitiveShapes[primitiveShape] !== undefined) {
  89. var update = false;
  90. if (primitiveShape === pointFeature.primitiveShapes.auto) {
  91. update = !m_this._primitiveShapeAuto;
  92. m_this._primitiveShapeAuto = true;
  93. } else {
  94. update = m_this._primitiveShapeAuto || m_this._primitiveShape !== primitiveShape;
  95. m_this._primitiveShapeAuto = false;
  96. m_this._primitiveShape = primitiveShape;
  97. }
  98. if (update) {
  99. m_this.renderer().contextRenderer().removeActor(m_this.actors()[0]);
  100. m_this._init(true);
  101. m_this.dataTime().modified();
  102. }
  103. }
  104. return m_this;
  105. };
  106. }
  107. module.exports = pointUtil;