XBreathPointManager.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. import XStaticMesh from "./XStaticMesh.js"
  2. import EMeshType from "./enum/EMeshType.js"
  3. import BreathPoint from "./BreathPoint.js"
  4. import Logger from "./Logger.js"
  5. import util from "./util.js"
  6. const logger = new Logger('XBreathPointManager')
  7. const scaleFromUE4toXverse = 100
  8. export default class XBreathPointManager {
  9. constructor(e) {
  10. E(this, "_scene");
  11. E(this, "materialMap", new Map);
  12. E(this, "breathPoints", new Map);
  13. E(this, "_sceneManager");
  14. E(this, "_allIds", new Set);
  15. E(this, "_loopBPKeys", []);
  16. E(this, "addBreathPoint", async e=>{
  17. const t = [{
  18. //url: "https://metaverse.oss-cn-beijing.aliyuncs.com/images/texture.png"
  19. url: "https://static.xverse.cn/qqktv/texture.png"
  20. }];
  21. if (t.length <= 0) {
  22. logger.warn("[Engine] BreathPoint get texture list error: textureList.length <= 0"),
  23. new XBreathPointError("[Engine] BreathPoint get texture list error!");
  24. return
  25. }
  26. const r = t[0]
  27. , {id: n, spriteSheet: o=r.url, spriteWidthNumber: a=20, spriteHeightNumber: s=1, position: l, rotation: u={
  28. pitch: -90,
  29. yaw: 270,
  30. roll: 0
  31. }, size: c=.6, width: h=-1, height: f=-1, fps: d=30, billboardMode: _=!1, forceLeaveGround: g=!1, type: m="default", lifeTime: v=-1, backfaceculling: y=!0, maxVisibleRegion: b=-1, skinInfo: T="default"} = e;
  32. if (this.breathPoints.get(n)) {
  33. logger.warn("[Engine] Cannot add breathPoint with an existing id: [" + n + "]"),
  34. new XBreathPointError("[Engine] Cannot add breathPoint with an existing id: [" + n + "]");
  35. return
  36. }
  37. if (g) {
  38. const I = this.castRay(new BABYLON.Vector3(l.x,l.y,l.z)) * scaleFromUE4toXverse;
  39. I != 0 ? l.z = l.z - I + 1 : l.z = l.z + 1
  40. }
  41. let C;
  42. if (this.materialMap.get(m)) {
  43. const I = this.materialMap.get(m);
  44. I.count = I.count + 1,
  45. C = I.mat
  46. } else {
  47. const I = new BABYLON.Texture(o,this._scene,!0,!0,BABYLON.Texture.BILINEAR_SAMPLINGMODE,null,()=>{
  48. logger.error("[Engine] Breathpoint create texture error."),
  49. new XBreathPointError("[Engine] Breathpoint create texture error.")
  50. }
  51. ,null,!0);
  52. I.name = "TexBreathPoint_" + n,
  53. C = new BABYLON.StandardMaterial(`MaterialBreathPoint_${n}`,this._scene),
  54. C.alpha = 1,
  55. C.emissiveTexture = I,
  56. C.backFaceCulling = y,
  57. C.diffuseTexture = I,
  58. C.diffuseTexture.hasAlpha = !0,
  59. C.useAlphaFromDiffuseTexture = !0,
  60. this.materialMap.set(m, {
  61. mat: C,
  62. count: 1,
  63. lastRenderTime: Date.now(),
  64. fps: d,
  65. spriteWidthNumber: a,
  66. spriteHeightNumber: s,
  67. spriteSheet: o,
  68. texture: I
  69. })
  70. }
  71. const A = new Array(6);
  72. for (let I = 0; I < 6; I++)
  73. A[I] = new BABYLON.Vector4(0,0,0,0);
  74. A[0] = new BABYLON.Vector4(0,0,1 / a,1 / s),
  75. A[1] = new BABYLON.Vector4(0,0,1 / a,1 / s);
  76. let S = {};
  77. h > 0 && f > 0 ? S = {
  78. width: h,
  79. height: f,
  80. depth: .01,
  81. faceUV: A
  82. } : S = {
  83. size: c,
  84. depth: .01,
  85. faceUV: A
  86. };
  87. const P = BABYLON.MeshBuilder.CreateBox(n, S, this._scene);
  88. P.material = C;
  89. const R = new XStaticMesh({
  90. id: n,
  91. mesh: P,
  92. xtype: EMeshType.XBreathPoint,
  93. skinInfo: T
  94. });
  95. let M = u;
  96. _ && (P.billboardMode = BABYLON.Mesh.BILLBOARDMODE_ALL,
  97. R.allowMove(),
  98. M = {
  99. pitch: 0,
  100. yaw: 270,
  101. roll: 0
  102. });
  103. const x = new BreathPoint({
  104. type: m,
  105. mesh: R,
  106. id: n,
  107. position: l,
  108. rotation: M,
  109. mat: C,
  110. maxVisibleRegion: b,
  111. scene: this._scene,
  112. skinInfo: T
  113. });
  114. this.breathPoints.set(n, x),
  115. this._allIds.add(n),
  116. v > 0 && setTimeout(()=>{
  117. this.clearBreathPoints(n)
  118. }
  119. , v * 1e3)
  120. }
  121. );
  122. E(this, "reg_breathpoint_update", ()=>{
  123. const e = new Date().getTime();
  124. if (this.materialMap != null)
  125. for (const [t,r] of this.materialMap)
  126. e - r.lastRenderTime > 1e3 / r.fps && (r.lastRenderTime = e,
  127. Math.abs(r.mat.diffuseTexture.uOffset - (1 - 1 / r.spriteWidthNumber)) < 1e-6 ? (r.mat.diffuseTexture.uOffset = 0,
  128. Math.abs(r.mat.diffuseTexture.vOffset - (1 - 1 / r.spriteHeightNumber)) < 1e-6 ? r.mat.diffuseTexture.vOffset = 0 : r.mat.diffuseTexture.vOffset += 1 / r.spriteHeightNumber) : r.mat.diffuseTexture.uOffset += 1 / r.spriteWidthNumber)
  129. }
  130. );
  131. E(this, "reg_breathpoint_autovisible", ()=>{
  132. if (this._scene.getFrameId() % 2 == 0)
  133. if (this._loopBPKeys.length == 0)
  134. this._loopBPKeys = Array.from(this._allIds);
  135. else {
  136. const e = this._getMainPlayerPosition();
  137. for (let t = 0; t < 5 && this._loopBPKeys.length > 0; ++t) {
  138. const r = this._loopBPKeys.pop();
  139. if (r != null) {
  140. const n = this.getBreathPoint(r);
  141. if (n != null && n.maxvisibleregion >= 0 && n.mesh.visibility == 1) {
  142. const o = n.mesh.position;
  143. calcDistance3DVector(e, o) >= n.maxvisibleregion ? n == null || n.removeFromScene() : n == null || n.addToScene()
  144. }
  145. }
  146. }
  147. }
  148. }
  149. );
  150. this._sceneManager = e,
  151. this._scene = e.Scene,
  152. this._scene.registerBeforeRender(this.reg_breathpoint_update),
  153. this._scene.registerBeforeRender(this.reg_breathpoint_autovisible)
  154. }
  155. setAllBreathPointVisibility(e) {
  156. for (const [t,r] of this.breathPoints.entries())
  157. r.toggleVisibility(e)
  158. }
  159. toggleBPVisibilityBySkinInfo(e, t) {
  160. for (const [r,n] of this.breathPoints.entries())
  161. n.skinInfo == e && n.toggleVisibility(t)
  162. }
  163. toggleBPVisibilityById(e, t) {
  164. const r = this.getBreathPoint(e);
  165. r != null && r.toggleVisibility(t)
  166. }
  167. getBreathPointBySkinInfo(e) {
  168. const t = [];
  169. for (const [r,n] of this.breathPoints.entries())
  170. n.skinInfo == e && t.push(n);
  171. return t
  172. }
  173. getAllBreathPoint() {
  174. return this.breathPoints
  175. }
  176. getBreathPoint(e) {
  177. return this.breathPoints.get(e)
  178. }
  179. delete(e) {
  180. const t = this.breathPoints.get(e);
  181. if (t != null) {
  182. t.dispose(),
  183. this._allIds.delete(e);
  184. const r = this.materialMap.get(t._type);
  185. r != null && (r.count = r.count - 1,
  186. r.count <= 0 && (r.count = 0,
  187. r.texture.dispose(),
  188. r.mat.dispose(!0, !0),
  189. this.materialMap.delete(t._type))),
  190. this.breathPoints.delete(e)
  191. }
  192. }
  193. castRay(e) {
  194. var s;
  195. e = util.ue4Position2Xverse({
  196. x: e.x,
  197. y: e.y,
  198. z: e.z
  199. });
  200. const t = new BABYLON.Vector3(0,-1,0)
  201. , r = new BABYLON.Ray(e,t,length)
  202. , n = []
  203. , o = (s = this._sceneManager) == null ? void 0 : s.getGround({
  204. x: e.x,
  205. y: e.y,
  206. z: e.z
  207. });
  208. let a = r.intersectsMeshes(o);
  209. if (a.length > 0) {
  210. const l = a[0];
  211. if (l && l.pickedMesh) {
  212. const u = l.distance;
  213. t.y = 1;
  214. const c = r.intersectsMeshes(n);
  215. let h = 1e8;
  216. if (c.length > 0) {
  217. const f = c[0];
  218. return f && f.pickedMesh && (h = -f.distance),
  219. h == 1e8 ? u : Math.abs(h) < Math.abs(u) ? h : u
  220. }
  221. }
  222. } else if (t.y = 1,
  223. a = r.intersectsMeshes(n),
  224. a.length > 0) {
  225. const l = a[0];
  226. if (l && l.pickedMesh)
  227. return l.distance
  228. }
  229. return 0
  230. }
  231. changePickable(e) {
  232. for (const [t,r] of this.breathPoints.entries())
  233. r.changePickable(e)
  234. }
  235. clearBreathPoints(e) {
  236. logger.info(`[Engine] clearBreathPoints: ${e}`);
  237. for (const [t,r] of this.breathPoints.entries())
  238. (r._type == e || r._id == e) && this.delete(r._id)
  239. }
  240. clearBreathPointsBySkinInfo(e) {
  241. logger.info(`[Engine] clearBreathPointsBySkinInfo: ${e}`);
  242. for (const [t,r] of this.breathPoints.entries())
  243. r.skinInfo == e && this.delete(r._id)
  244. }
  245. clearAllBreathPoints() {
  246. logger.info("[Engine] ClearAllBreathPoints");
  247. for (const [e,t] of this.breathPoints.entries())
  248. this.delete(t._id)
  249. }
  250. _getMainPlayerPosition() {
  251. var r;
  252. const e = this._sceneManager.cameraComponent.MainCamera.position
  253. , t = this._sceneManager.avatarComponent.getMainAvatar();
  254. if (t != null && t != null) {
  255. const n = (r = t == null ? void 0 : t.rootNode) == null ? void 0 : r.position;
  256. if (n != null)
  257. return n
  258. }
  259. return e
  260. }
  261. changeBreathPointPose(e, t, r) {
  262. const n = new BABYLON.Vector3(e.position.x,e.position.y,e.position.z);
  263. if (this.breathPoints.get(r) != null) {
  264. logger.info(`[Engine] changeBreathPointPose, id:${r}`);
  265. const o = this.breathPoints.get(r)
  266. , a = o.mesh.position;
  267. let s = a.subtract(n);
  268. s = BABYLON.Vector3.Normalize(s);
  269. const l = BABYLON.Vector3.Distance(a, n)
  270. , u = new Ray(n,s,l)
  271. , c = this._scene.multiPickWithRay(u);
  272. if (c) {
  273. for (let h = 0; h < c.length; h++)
  274. if (c[h].pickedMesh != null && t.mesh.name.indexOf(c[h].pickedMesh.name) >= 0) {
  275. const f = c[h].pickedPoint;
  276. o.mesh.position = n.add(f.subtract(n).scale(.99)),
  277. this.breathPoints.set(r, o)
  278. }
  279. }
  280. } else
  281. logger.warn(`[Engine] changeBreathPointPose, id:${r} is not existing!`)
  282. }
  283. }