XMaterialComponent.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. import XVideoRawYUV from "./XVideoRawYUV"
  2. import Logger from "./Logger.js"
  3. const logger = new Logger('XMaterial')
  4. export default class XMaterialComponent {
  5. constructor(e, t) {
  6. E(this, "scene");
  7. E(this, "engine");
  8. E(this, "yuvInfo");
  9. E(this, "shaderMode");
  10. E(this, "_panoInfo");
  11. E(this, "_dynamic_size");
  12. E(this, "_dynamic_babylonpose");
  13. E(this, "_dynamic_textures");
  14. E(this, "_dynamic_shaders");
  15. E(this, "_scenemanager");
  16. E(this, "_videoTexture");
  17. E(this, "_videoElement");
  18. E(this, "_lowModelShader");
  19. E(this, "_defaultShader");
  20. E(this, "_inputYUV420", !0);
  21. E(this, "_inputPanoYUV420", !0);
  22. E(this, "_videoRawYUVTexArray");
  23. E(this, "_isUpdateYUV", !0);
  24. E(this, "initMaterial", async()=>new Promise((e,t)=>{
  25. this._initDefaultShader(),
  26. this.shaderMode == 2 ? this.initDynamicData(this._panoInfo.dynamicRange, this._panoInfo.width, this._panoInfo.height).then(()=>{
  27. this._initPureVideoShader(),
  28. this._prepareRender(this.yuvInfo)
  29. }
  30. ) : this.shaderMode == 1 ? (this._initPureVideoShader(),
  31. this._prepareRender(this.yuvInfo)) : this.shaderMode == 0,
  32. e(!0)
  33. }
  34. ));
  35. E(this, "_initPureVideoContent", e=>{
  36. this._inputYUV420 ? this._videoRawYUVTexArray.getVideoYUVTex(0) != null && (this._lowModelShader.setTexture("texture_video", this._videoRawYUVTexArray.getVideoYUVTex(0)),
  37. this._lowModelShader.setFloat("isYUV", 1),
  38. BABYLON.Texture.WhenAllReady([this._videoRawYUVTexArray.getVideoYUVTex(0)], ()=>{
  39. this._changePureVideoLowModelShaderCanvasSize(e)
  40. }
  41. )) : (this._videoElement = e.videoElement,
  42. this._videoTexture || (this._videoTexture = new VideoTexture("InterVideoTexture",this._videoElement,this.scene,!0,!1)),
  43. BABYLON.Texture.WhenAllReady([this._videoTexture], ()=>{
  44. this._changePureVideoLowModelShaderCanvasSize({
  45. width: this._videoElement.height,
  46. height: this._videoElement.width,
  47. fov: e.fov
  48. })
  49. }
  50. ),
  51. this._lowModelShader.setTexture("texture_video", this._videoTexture),
  52. this._lowModelShader.setFloat("isYUV", 0))
  53. }
  54. );
  55. E(this, "_changePureVideoLowModelShaderCanvasSize", e=>{
  56. var a;
  57. const t = e.fov || 50
  58. , r = e.width || 720
  59. , n = e.height || 1280
  60. , o = r / (2 * Math.tan(Math.PI * t / 360));
  61. (a = this._lowModelShader) == null || a.setVector3("focal_width_height", new BABYLON.Vector3(o,r,n))
  62. }
  63. );
  64. E(this, "updateRawYUVData", (e,t,r,n=-1)=>{
  65. var o, a;
  66. if (n == -1 && (n = this.yuvInfo.fov),
  67. this._isUpdateYUV == !0) {
  68. const s = {
  69. width: t,
  70. height: r,
  71. fov: n
  72. }
  73. , l = this._videoRawYUVTexArray.findId(t, r)
  74. , u = this._videoRawYUVTexArray.getCurrentVideoTexId();
  75. (u < 0 || l != u || n != this.yuvInfo.fov) && (this.yuvInfo.width = t,
  76. this.yuvInfo.height = r,
  77. this.yuvInfo.fov = n,
  78. this._videoRawYUVTexArray.setCurrentVideoTexId(l),
  79. this._changeVideoRes(l),
  80. this._changePureVideoLowModelShaderCanvasSize(s),
  81. this._scenemanager.cameraComponent.cameraFovChange(s),
  82. this._scenemanager.yuvInfo = s),
  83. (o = this._videoRawYUVTexArray.getVideoYUVTex(l)) == null || o.update(e),
  84. (a = this._videoRawYUVTexArray.getVideoYUVTex(l)) == null || a.updateSamplingMode(BABYLON.Texture.BILINEAR_SAMPLINGMODE)
  85. }
  86. }
  87. );
  88. E(this, "_changeVideoRes", e=>{
  89. this._lowModelShader.setTexture("texture_video", this._videoRawYUVTexArray.getVideoYUVTex(e))
  90. }
  91. );
  92. E(this, "initDynamicData", (e,t,r)=>new Promise((n,o)=>{
  93. this.setDynamicSize(e).then(a=>{
  94. if (a) {
  95. for (let s = 0; s < e; ++s)
  96. (l=>{
  97. this.initDynamicTexture(l, t, r),
  98. this.initDynamicShaders(l).then(()=>{
  99. this._updatePanoShaderInput(l)
  100. }
  101. )
  102. }
  103. )(s);
  104. n(!0)
  105. } else
  106. o(new XMaterialError(`[Engine] DynamicRoomSize (${e}) is too small`))
  107. }
  108. )
  109. }
  110. ).catch(n=>logger.error(`[Engine] ${n}`)));
  111. E(this, "_initDefaultShader", ()=>{
  112. this._defaultShader == null && (this._defaultShader = new BABYLON.GridMaterial("GridShader",this.scene),
  113. this._defaultShader.gridRatio = 50,
  114. this._defaultShader.lineColor = new BABYLON.Color3(0,0,.5),
  115. this._defaultShader.majorUnitFrequency = 1,
  116. this._defaultShader.mainColor = new BABYLON.Color3(.6,.6,.6),
  117. this._defaultShader.backFaceCulling = !1)
  118. }
  119. );
  120. E(this, "_initPureVideoShader", ()=>{
  121. if (this._lowModelShader == null) {
  122. const e = new BABYLON.ShaderMaterial("PureVideoShader",this.scene,{
  123. vertexSource: pureVideoVertex,
  124. fragmentSource: pureVideoFragment
  125. },{
  126. attributes: ["uv", "position", "world0", "world1", "world2", "world3"],
  127. uniforms: ["view", "projection", "worldViewProjection", "world"],
  128. defines: ["#define SHADOWFULLFLOAT"]
  129. });
  130. e.setTexture("shadowSampler", null),
  131. e.setMatrix("lightSpaceMatrix", null),
  132. e.setFloat("haveShadowLight", 0),
  133. e.setTexture("texture_video", null),
  134. e.setFloat("isYUV", this._inputYUV420 ? 1 : 0),
  135. e.setFloat("fireworkLight", 0),
  136. e.setVector3("fireworkLightPosition", new BABYLON.Vector3(0,0,0)),
  137. e.setVector3("focal_width_height", new BABYLON.Vector3(772.022491,720,1280)),
  138. e.backFaceCulling = !1,
  139. this._lowModelShader = e
  140. }
  141. }
  142. );
  143. E(this, "setDynamicSize", e=>new Promise((t,r)=>{
  144. e >= 1 && e <= 100 ? (this._dynamic_size = e,
  145. t(!0)) : (this._dynamic_size = 1,
  146. t(!1))
  147. }
  148. ));
  149. E(this, "_isInDynamicRange", e=>e < this._dynamic_size && e >= 0);
  150. E(this, "initDynamicTexture", (e,t,r)=>{
  151. this._isInDynamicRange(e) && (this._dynamic_textures[e] != null && (this._dynamic_textures[e].dispose(),
  152. this._dynamic_textures[e] = null),
  153. this._dynamic_textures[e] = new BABYLON.RawTexture(null,t,r * 1.5,BABYLON.Engine.TEXTUREFORMAT_LUMINANCE,this.scene,!1,!0,BABYLON.Texture.NEAREST_SAMPLINGMODE,BABYLON.Engine.TEXTURETYPE_UNSIGNED_BYTE),
  154. this._dynamic_textures[e].name = "Pano_Dynamic_" + e + "_" + Date.now())
  155. }
  156. );
  157. E(this, "initDynamicShaders", e=>(logger.info("[Engine] Material init dynamic shader."),
  158. new Promise((t,r)=>{
  159. this._dynamic_shaders[e] != null && this._dynamic_shaders[e].dispose();
  160. const n = new BABYLON.ShaderMaterial("Pano_Shader_" + e,this.scene,{
  161. vertexSource: panoVertex,
  162. fragmentSource: panoFragment
  163. },{
  164. attributes: ["uv", "position", "world0", "world1", "world2", "world3"],
  165. uniforms: ["view", "projection", "worldViewProjection", "world"],
  166. defines: ["#define SHADOWFULLFLOAT"]
  167. });
  168. n.setTexture("texture_pano", null),
  169. n.setVector3("centre_pose", new BABYLON.Vector3(0,0,0)),
  170. n.setFloat("isYUV", this._inputPanoYUV420 ? 1 : 0),
  171. n.setTexture("shadowSampler", null),
  172. n.setMatrix("lightSpaceMatrix", null),
  173. n.setFloat("haveShadowLight", 0),
  174. n.setFloat("fireworkLight", 0),
  175. n.setVector3("fireworkLightPosition", new BABYLON.Vector3(0,0,0)),
  176. n.backFaceCulling = !1,
  177. this._dynamic_shaders[e] = n,
  178. t(!0)
  179. }
  180. )));
  181. this._scenemanager = e,
  182. this.scene = e.Scene,
  183. this.engine = this.scene.getEngine(),
  184. this.shaderMode = 1,
  185. this._dynamic_textures = [],
  186. this._dynamic_shaders = [],
  187. this._dynamic_babylonpose = [],
  188. this._videoRawYUVTexArray = new XVideoRawYUV(this.scene,t.videoResOriArray),
  189. this.shaderMode = t.shaderMode,
  190. t.yuvInfo != null && (this.yuvInfo = t.yuvInfo),
  191. t.panoInfo != null && this.setPanoInfo(t.panoInfo)
  192. }
  193. stopYUVUpdate() {
  194. this._isUpdateYUV = !1
  195. }
  196. allowYUVUpdate() {
  197. this._isUpdateYUV = !0
  198. }
  199. setPanoInfo(e) {
  200. this._panoInfo = e
  201. }
  202. _prepareRender(e) {
  203. e && (this._initPureVideoContent(e),
  204. this._updatePureVideoShaderInput())
  205. }
  206. getPureVideoShader() {
  207. return this._lowModelShader
  208. }
  209. getDefaultShader() {
  210. return this._defaultShader
  211. }
  212. updatePanoPartYUV(e, t, r) {
  213. const n = t.subarray(0, r.width * r.height)
  214. , o = t.subarray(r.width * r.height, r.width * r.height * 1.25)
  215. , a = t.subarray(r.width * r.height * 1.25)
  216. , s = this._panoInfo.width
  217. , l = this._panoInfo.height;
  218. if (this._dynamic_textures[e] != null) {
  219. const u = this._dynamic_textures[e].getInternalTexture();
  220. if (u != null && u != null) {
  221. const c = this.engine._getTextureTarget(u);
  222. this.engine._bindTextureDirectly(c, u, !0),
  223. this.engine.updateTextureData(u, n, r.startX, l * 1.5 - r.startY - r.height, r.width, r.height),
  224. this.engine.updateTextureData(u, o, r.startX * .5, (l - r.startY - r.height) * .5, r.width * .5 - 1, r.height * .5 - 1),
  225. this.engine.updateTextureData(u, a, r.startX * .5 + s * .5, (l - r.startY - r.height) * .5, r.width * .5, r.height * .5),
  226. this.engine._bindTextureDirectly(c, null)
  227. }
  228. }
  229. }
  230. changePanoImg(e, t) {
  231. if (logger.info(`[Engine] changePanoImg, id=${e}, pose=${t.pose.position.x},${t.pose.position.y},${t.pose.position.z}`),
  232. !this._isInDynamicRange(e))
  233. return logger.error(`[Engine] ${e} is bigger than dynamic size set in PanoInfo`),
  234. Promise.reject(new XMaterialError(`[Engine] ${e} is bigger than dynamic size set in PanoInfo`));
  235. const r = ue4Position2Xverse(t.pose.position);
  236. return r && (this._dynamic_babylonpose[e] = {
  237. position: r
  238. }),
  239. new Promise((n,o)=>{
  240. try {
  241. typeof t.data == "string" ? (this.setPanoYUV420(!1),
  242. this._dynamic_textures[e].updateURL(t.data, null, ()=>{
  243. this._dynamic_textures[e].updateSamplingMode(BABYLON.Texture.NEAREST_SAMPLINGMODE)
  244. }
  245. )) : (this.isPanoYUV420() == !1 && this.initDynamicTexture(e, this._panoInfo.width, this._panoInfo.height),
  246. this.setPanoYUV420(!0),
  247. this._dynamic_textures[e].update(t.data),
  248. this._dynamic_textures[e].updateSamplingMode(BABYLON.Texture.NEAREST_SAMPLINGMODE)),
  249. n(this)
  250. } catch (a) {
  251. o(new XMaterialError(`[Engine] ChangePanoImg Error! ${a}`))
  252. }
  253. }
  254. ).then(n=>(t.fov != null && this._scenemanager.cameraComponent.changeCameraFov(t.fov * Math.PI / 180),
  255. this._dynamic_shaders[e].setFloat("isYUV", this._inputPanoYUV420 ? 1 : 0),
  256. this._dynamic_shaders[e].setTexture("texture_pano", this._dynamic_textures[e]),
  257. this._dynamic_shaders[e].setVector3("centre_pose", this._dynamic_babylonpose[e].position),
  258. !0))
  259. }
  260. setYUV420(e) {
  261. this._inputYUV420 = e
  262. }
  263. isYUV420() {
  264. return this._inputYUV420
  265. }
  266. setPanoYUV420(e) {
  267. this._inputPanoYUV420 = e
  268. }
  269. isPanoYUV420() {
  270. return this._inputPanoYUV420
  271. }
  272. getDynamicShader(e) {
  273. return this._dynamic_shaders[e]
  274. }
  275. _updatePureVideoShaderInput() {
  276. var e, t, r, n, o, a, s, l, u, c;
  277. if (this.scene.getLightByName("AvatarLight") ? ((e = this._lowModelShader) == null || e.setFloat("haveShadowLight", 1),
  278. (n = this._lowModelShader) == null || n.setTexture("shadowSampler", (r = (t = this.scene.getLightByName("AvatarLight")) == null ? void 0 : t.getShadowGenerator()) == null ? void 0 : r.getShadowMapForRendering()),
  279. (s = this._lowModelShader) == null || s.setMatrix("lightSpaceMatrix", (a = (o = this.scene.getLightByName("AvatarLight")) == null ? void 0 : o.getShadowGenerator()) == null ? void 0 : a.getTransformMatrix())) : ((l = this._lowModelShader) == null || l.setTexture("shadowSampler", this._videoTexture),
  280. (u = this._lowModelShader) == null || u.setMatrix("lightSpaceMatrix", new Matrix),
  281. (c = this._lowModelShader) == null || c.setFloat("haveShadowLight", 0)),
  282. this.scene.getLightByName("fireworkLight"))
  283. this.scene.registerBeforeRender(()=>{
  284. var h;
  285. this._lowModelShader.setFloat("fireworkLight", this.scene.getLightByName("fireworkLight").getScaledIntensity()),
  286. this._lowModelShader.setVector3("fireworkLightPosition", (h = this.scene.getLightByName("fireworkLight")) == null ? void 0 : h.position)
  287. }
  288. );
  289. else {
  290. const h = new BABYLON.PointLight("fireworkLight",new BABYLON.Vector3(0,0,0),this.scene);
  291. h.intensity = 0
  292. }
  293. }
  294. _updatePanoShaderInput(e) {
  295. var t, r, n, o, a, s, l, u, c, h;
  296. if (this._isInDynamicRange(e))
  297. if (this.scene.getLightByName("AvatarLight") ? ((t = this._dynamic_shaders[e]) == null || t.setFloat("haveShadowLight", 1),
  298. (o = this._dynamic_shaders[e]) == null || o.setTexture("shadowSampler", (n = (r = this.scene.getLightByName("AvatarLight")) == null ? void 0 : r.getShadowGenerator()) == null ? void 0 : n.getShadowMapForRendering()),
  299. (l = this._dynamic_shaders[e]) == null || l.setMatrix("lightSpaceMatrix", (s = (a = this.scene.getLightByName("AvatarLight")) == null ? void 0 : a.getShadowGenerator()) == null ? void 0 : s.getTransformMatrix())) : ((u = this._dynamic_shaders[e]) == null || u.setTexture("shadowSampler", null),
  300. (c = this._dynamic_shaders[e]) == null || c.setMatrix("lightSpaceMatrix", new Matrix),
  301. (h = this._dynamic_shaders[e]) == null || h.setFloat("haveShadowLight", 0)),
  302. this.scene.getLightByName("fireworkLight"))
  303. this.scene.registerBeforeRender(()=>{
  304. var f;
  305. this._dynamic_shaders[e].setFloat("fireworkLight", this.scene.getLightByName("fireworkLight").getScaledIntensity()),
  306. this._dynamic_shaders[e].setVector3("fireworkLightPosition", (f = this.scene.getLightByName("fireworkLight")) == null ? void 0 : f.position)
  307. }
  308. );
  309. else {
  310. const f = new BABYLON.PointLight("fireworkLight",new BABYLON.Vector3(0,0,0),this.scene);
  311. f.intensity = 0
  312. }
  313. }
  314. }