Source: mesh/Rope.js

mesh/Rope.js

  1. import Mesh from './Mesh';
  2. /**
  3. * The rope allows you to draw a texture across several points and them manipulate these points
  4. *
  5. *```js
  6. * for (let i = 0; i < 20; i++) {
  7. * points.push(new PIXI.Point(i * 50, 0));
  8. * };
  9. * let rope = new PIXI.Rope(PIXI.Texture.fromImage("snake.png"), points);
  10. * ```
  11. *
  12. * @class
  13. * @extends PIXI.mesh.Mesh
  14. * @memberof PIXI.mesh
  15. *
  16. */
  17. export default class Rope extends Mesh
  18. {
  19. /**
  20. * @param {PIXI.Texture} texture - The texture to use on the rope.
  21. * @param {PIXI.Point[]} points - An array of {@link PIXI.Point} objects to construct this rope.
  22. */
  23. constructor(texture, points)
  24. {
  25. super(texture);
  26. /**
  27. * An array of points that determine the rope
  28. *
  29. * @member {PIXI.Point[]}
  30. */
  31. this.points = points;
  32. /**
  33. * An array of vertices used to construct this rope.
  34. *
  35. * @member {Float32Array}
  36. */
  37. this.vertices = new Float32Array(points.length * 4);
  38. /**
  39. * The WebGL Uvs of the rope.
  40. *
  41. * @member {Float32Array}
  42. */
  43. this.uvs = new Float32Array(points.length * 4);
  44. /**
  45. * An array containing the color components
  46. *
  47. * @member {Float32Array}
  48. */
  49. this.colors = new Float32Array(points.length * 2);
  50. /**
  51. * An array containing the indices of the vertices
  52. *
  53. * @member {Uint16Array}
  54. */
  55. this.indices = new Uint16Array(points.length * 2);
  56. /**
  57. * refreshes vertices on every updateTransform
  58. * @member {boolean}
  59. * @default true
  60. */
  61. this.autoUpdate = true;
  62. this.refresh();
  63. }
  64. /**
  65. * Refreshes
  66. *
  67. */
  68. _refresh()
  69. {
  70. const points = this.points;
  71. // if too little points, or texture hasn't got UVs set yet just move on.
  72. if (points.length < 1 || !this._texture._uvs)
  73. {
  74. return;
  75. }
  76. // if the number of points has changed we will need to recreate the arraybuffers
  77. if (this.vertices.length / 4 !== points.length)
  78. {
  79. this.vertices = new Float32Array(points.length * 4);
  80. this.uvs = new Float32Array(points.length * 4);
  81. this.colors = new Float32Array(points.length * 2);
  82. this.indices = new Uint16Array(points.length * 2);
  83. }
  84. const uvs = this.uvs;
  85. const indices = this.indices;
  86. const colors = this.colors;
  87. uvs[0] = 0;
  88. uvs[1] = 0;
  89. uvs[2] = 0;
  90. uvs[3] = 1;
  91. colors[0] = 1;
  92. colors[1] = 1;
  93. indices[0] = 0;
  94. indices[1] = 1;
  95. const total = points.length;
  96. for (let i = 1; i < total; i++)
  97. {
  98. // time to do some smart drawing!
  99. let index = i * 4;
  100. const amount = i / (total - 1);
  101. uvs[index] = amount;
  102. uvs[index + 1] = 0;
  103. uvs[index + 2] = amount;
  104. uvs[index + 3] = 1;
  105. index = i * 2;
  106. colors[index] = 1;
  107. colors[index + 1] = 1;
  108. index = i * 2;
  109. indices[index] = index;
  110. indices[index + 1] = index + 1;
  111. }
  112. // ensure that the changes are uploaded
  113. this.dirty++;
  114. this.indexDirty++;
  115. this.multiplyUvs();
  116. this.refreshVertices();
  117. }
  118. /**
  119. * refreshes vertices of Rope mesh
  120. */
  121. refreshVertices()
  122. {
  123. const points = this.points;
  124. if (points.length < 1)
  125. {
  126. return;
  127. }
  128. let lastPoint = points[0];
  129. let nextPoint;
  130. let perpX = 0;
  131. let perpY = 0;
  132. // this.count -= 0.2;
  133. const vertices = this.vertices;
  134. const total = points.length;
  135. for (let i = 0; i < total; i++)
  136. {
  137. const point = points[i];
  138. const index = i * 4;
  139. if (i < points.length - 1)
  140. {
  141. nextPoint = points[i + 1];
  142. }
  143. else
  144. {
  145. nextPoint = point;
  146. }
  147. perpY = -(nextPoint.x - lastPoint.x);
  148. perpX = nextPoint.y - lastPoint.y;
  149. let ratio = (1 - (i / (total - 1))) * 10;
  150. if (ratio > 1)
  151. {
  152. ratio = 1;
  153. }
  154. const perpLength = Math.sqrt((perpX * perpX) + (perpY * perpY));
  155. const num = this._texture.height / 2; // (20 + Math.abs(Math.sin((i + this.count) * 0.3) * 50) )* ratio;
  156. perpX /= perpLength;
  157. perpY /= perpLength;
  158. perpX *= num;
  159. perpY *= num;
  160. vertices[index] = point.x + perpX;
  161. vertices[index + 1] = point.y + perpY;
  162. vertices[index + 2] = point.x - perpX;
  163. vertices[index + 3] = point.y - perpY;
  164. lastPoint = point;
  165. }
  166. }
  167. /**
  168. * Updates the object transform for rendering
  169. *
  170. * @private
  171. */
  172. updateTransform()
  173. {
  174. if (this.autoUpdate)
  175. {
  176. this.refreshVertices();
  177. }
  178. this.containerUpdateTransform();
  179. }
  180. }