XBillboard.js 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. import EMeshType from "./enum/EMeshType.js"
  2. import XBillboardManager from "./XBillboardManager.js"
  3. import Logger from "./Logger.js"
  4. const logger = new Logger('Billboard')
  5. export default class XBillboard {
  6. constructor(e, t=!1, r=!1) {
  7. E(this, "_mesh", null);
  8. E(this, "_texture", null);
  9. E(this, "_scalingFactor", 1);
  10. E(this, "offsets", null);
  11. E(this, "_pickable");
  12. E(this, "_background", null);
  13. E(this, "_billboardManager");
  14. E(this, "poolobj", null);
  15. E(this, "_usePool");
  16. E(this, "_initMeshScale", new BABYLON.Vector3(1,1,1));
  17. E(this, "_status", -1);
  18. E(this, "_stageChanged", !1);
  19. E(this, "DEFAULT_CONFIGS", {});
  20. this._billboardManager = e,
  21. this._pickable = t,
  22. this._usePool = r
  23. }
  24. set scalingFactor(e) {
  25. this._scalingFactor = e
  26. }
  27. set background(e) {
  28. this._background = e
  29. }
  30. get size() {
  31. return -1
  32. }
  33. setStatus(e) {
  34. e != this._status && (this._stageChanged = !0,
  35. this._status = e)
  36. }
  37. get status() {
  38. return this._status
  39. }
  40. get stageChanged() {
  41. return this._stageChanged
  42. }
  43. set stageChanged(e) {
  44. this._stageChanged = e
  45. }
  46. init(e="", t=.001, r=.001, n=!1) {
  47. const o = this._billboardManager.sceneManager.Scene;
  48. if (this._usePool) {
  49. const a = this._billboardManager.billboardPool.getFree(o, t, r, n);
  50. this._mesh = a.data,
  51. this._mesh.isPickable = this._pickable,
  52. this._mesh.xid = e,
  53. this._mesh.xtype = EMeshType.XBillboard,
  54. this._texture = this._mesh.material.diffuseTexture,
  55. this.poolobj = a
  56. } else
  57. this._mesh = this._billboardManager.createBillboardAsset(o, n);
  58. this._mesh.isPickable = this._pickable,
  59. this._initMeshScale.x = t * 1e3,
  60. this._initMeshScale.y = r * 1e3,
  61. this._mesh.xid = e,
  62. this._mesh.xtype = EMeshType.XBillboard,
  63. this._texture = this._mesh.material.diffuseTexture,
  64. this.setStatus(1),
  65. this._stageChanged = !0
  66. }
  67. dispose() {
  68. this._usePool ? this.poolobj && (this._billboardManager.billboardPool.release(this.poolobj),
  69. this._mesh = null,
  70. this._texture = null,
  71. this.poolobj = null) : this._mesh && (this._mesh.dispose(!0, !0),
  72. this._mesh = null,
  73. this._texture = null),
  74. this._background = null
  75. }
  76. getMesh() {
  77. return this._mesh
  78. }
  79. updateImage(e) {
  80. return new Promise(t=>{
  81. if (this._texture == null) {
  82. logger.error("[Engine]Billboard texture not found");
  83. return
  84. }
  85. const r = this._mesh
  86. , n = this._texture
  87. , o = this._scalingFactor
  88. , a = this._initMeshScale.x
  89. , s = this._initMeshScale.y
  90. , l = this._texture.getContext()
  91. , u = this._texture.getSize();
  92. l.clearRect(0, 0, u.width, u.height);
  93. const c = new Image;
  94. c.crossOrigin = "anonymous",
  95. c.src = e,
  96. c.onload = ()=>{
  97. const h = c.width * o
  98. , f = c.height * o;
  99. r.scaling.x = h * a,
  100. r.scaling.y = f * s,
  101. n.scaleTo(h, f),
  102. l.drawImage(c, 0, 0, h, f),
  103. n.hasAlpha = !0,
  104. n.update(),
  105. t()
  106. }
  107. }
  108. )
  109. }
  110. show() {
  111. this._mesh && (this._mesh.setEnabled(!0),
  112. this._mesh.isPickable = this._pickable)
  113. }
  114. hide() {
  115. this._mesh && (this._mesh.setEnabled(!1),
  116. this._mesh.isPickable = !1)
  117. }
  118. setId(e) {
  119. this._mesh && (this._mesh.xid = e)
  120. }
  121. setPosition(e) {
  122. if (e && this._mesh) {
  123. const t = ue4Position2Xverse(e);
  124. this._mesh.position = t
  125. }
  126. }
  127. updateText(e, t, r=!0, n=[], o=30, a="monospace", s="black", l="bold", u) {
  128. if (this._texture == null) {
  129. logger.error("[Engine]Billboard texture not found");
  130. return
  131. }
  132. const c = this._texture
  133. , h = this._mesh
  134. , f = this._scalingFactor
  135. , d = this._initMeshScale.x
  136. , _ = this._initMeshScale.y;
  137. if (e != "") {
  138. const g = this._texture.getContext()
  139. , m = this._texture.getSize();
  140. g.clearRect(0, 0, m.width, m.height);
  141. const v = new Image;
  142. if (r) {
  143. t != null ? t ? this._background = this._billboardManager.userBackGroundBlob : this._background = this._billboardManager.npcBackGroundBlob : this._background || (this._background = this._billboardManager.userBackGroundBlob);
  144. let y = e
  145. , b = u && u < n.length - 1 ? u : n.length - 1;
  146. if (this._background) {
  147. if (b > this._background.length) {
  148. for (let T = 0; T < b - this._background.length; T++)
  149. n.pop();
  150. b = n.length - 1,
  151. y = e.slice(0, n[b] - 1) + String.fromCharCode(8230)
  152. }
  153. v.crossOrigin = "anonymous",
  154. v.src = this._background[b - 1],
  155. v.onload = function() {
  156. const T = v.width * f
  157. , C = v.height * f;
  158. h.scaling.x = T * d,
  159. h.scaling.y = C * _,
  160. c.scaleTo(T, C),
  161. g.textAlign = "center",
  162. g.textBaseline = "middle",
  163. g.drawImage(v, 0, 0, T, C);
  164. for (let A = 0; A < b; A++)
  165. c.drawText(y.slice(n[0 + A], n[1 + A]), T / 2, C * (A + 1) / (b + 1) + (A - (b - 1) / 2) * f * 10, l + " " + o * f + "px " + a, s, "transparent", !0);
  166. c.hasAlpha = !0
  167. }
  168. }
  169. } else {
  170. const y = u && u < n.length - 1 ? u : n.length - 1
  171. , b = 480 * f
  172. , T = 60 * f * y;
  173. this._mesh.scaling = new BABYLON.Vector3(b * d,T * _,1),
  174. c.scaleTo(b, T);
  175. const C = c.getContext();
  176. C.textAlign = "center",
  177. C.textBaseline = "middle";
  178. for (let A = 0; A < y; A++)
  179. c.drawText(e.slice(n[0 + A], n[1 + A]), b / 2 + 2 * f, T * (A + 1) / (y + 1) + (A - (y - 1) / 2) * f * 10 + 2 * f, l + " " + o * f + "px " + a, "#333333", "transparent", !0),
  180. c.drawText(e.slice(n[0 + A], n[1 + A]), b / 2, T * (A + 1) / (y + 1) + (A - (y - 1) / 2) * f * 10, l + " " + o * f + "px " + a, s, "transparent", !0);
  181. c.hasAlpha = !0
  182. }
  183. } else
  184. this.clearText()
  185. }
  186. drawBillboard(e, t, r) {
  187. var m;
  188. const {imageList: n} = e
  189. , {texts: o, font: a="monospace", fontsize: s=40, fontcolor: l="#ffffff", fontstyle: u="", linesize: c=20, linelimit: h} = t
  190. , {position: f, offsets: d, scale: _, compensationZ: g=0} = r;
  191. if (this.scalingFactor = _ || 1,
  192. d && (this.offsets = {
  193. x: d.x * this._scalingFactor,
  194. y: d.y * this._scalingFactor,
  195. z: d.z * this._scalingFactor
  196. }),
  197. this.offsets || (this.offsets = {
  198. x: 0,
  199. y: 0,
  200. z: 0
  201. }),
  202. this.setPosition(f),
  203. n && !o)
  204. (m = this._billboardManager.sceneManager) == null || m.urlTransformer(n[0]).then(v=>{
  205. this.updateImage(v)
  206. }
  207. );
  208. else if (o && !n) {
  209. const [v,y] = getStringBoundaries(o, c, XBillboardManager.alphaWidthMap);
  210. this.offsets.z += this._scalingFactor * g * (y.length - 1),
  211. this.updateText(v, void 0, !1, y, s, a, l, u, h)
  212. } else if (o && n) {
  213. this.background = n;
  214. const [v,y] = getStringBoundaries(o, c, XBillboardManager.alphaWidthMap);
  215. this.offsets.z += this._scalingFactor * g * (y.length - 1),
  216. this.updateText(v, void 0, !0, y, s, a, l, u, h)
  217. }
  218. this.setStatus(1)
  219. }
  220. clearText() {
  221. if (this._texture != null) {
  222. const e = this._texture.getContext()
  223. , t = this._texture.getSize();
  224. e.clearRect(0, 0, t.width, t.height),
  225. this._texture.update()
  226. }
  227. }
  228. }