index.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. import CharactorManager from "./CharactorManager.js";
  2. import common from "./utils/common.js";
  3. import houseShader from "./shaders/houseShader.js";
  4. import settings from "./utils/settings.js";
  5. import CameraController from "./CameraController.js";
  6. export default class App {
  7. constructor(engine) {
  8. var scene = new BABYLON.Scene(engine);
  9. this.scene = scene
  10. scene.collisionsEnabled = true;
  11. // Lights
  12. var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, -1, 0), scene);
  13. light.intensity = 1.0;
  14. light.specular = BABYLON.Color3.Black();
  15. var light2 = new BABYLON.HemisphericLight("dir01", new BABYLON.Vector3(0, 1, 0), scene);
  16. light2.intensity = 0.1;
  17. light2.position = new BABYLON.Vector3(0, 5, 5);
  18. // Skybox
  19. var skybox = BABYLON.MeshBuilder.CreateBox("skyBox", { size: 1000.0 }, scene);
  20. var skyboxMaterial = new BABYLON.StandardMaterial("skyBox", scene);
  21. skyboxMaterial.backFaceCulling = false;
  22. skyboxMaterial.reflectionTexture = new BABYLON.CubeTexture("textures/environment.env", scene);
  23. skyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;
  24. skyboxMaterial.diffuseColor = new BABYLON.Color3(0, 0, 0);
  25. skyboxMaterial.specularColor = new BABYLON.Color3(0, 0, 0);
  26. skybox.material = skyboxMaterial;
  27. this.hasVideoTexture = false
  28. this.hasVideoTexture = true
  29. this.init()
  30. this.bindEvents()
  31. setTimeout(() => this.bindSocketEvents(), 1000)
  32. }
  33. init() {
  34. this.initVideo = true
  35. this.isReverse = false
  36. let self = this
  37. BABYLON.SceneLoader.ImportMesh("", "../scenes/house/", "close_to_bottom_L.glb", this.scene, async function (newMeshes, particleSystems, skeletons, animationGroups) {
  38. self.house = newMeshes
  39. // self.house[0].position = new BABYLON.Vector3(0, 0, -0.5)
  40. // self.house[0].position = new BABYLON.Vector3(-22, 0, 12)
  41. let houseVideo = document.getElementById("houseTexture")
  42. setTimeout(() => {
  43. window.connection.socket.emit("getRotateVideoUrl", {
  44. videoPath: "0/0",
  45. sangle: 0,
  46. eangle: 360,
  47. reverses: false,
  48. sceneCode: settings.sceneCode,
  49. roomId: settings.roomId,
  50. userId: settings.userId,
  51. });
  52. window.connection.socket.emit("getRotateVideoUrl", {
  53. videoPath: "0/0" ,
  54. sangle: 0,
  55. eangle: 360,
  56. reverses: true,
  57. sceneCode: settings.sceneCode,
  58. roomId: settings.roomId,
  59. userId: settings.userId,
  60. });
  61. }, 1500)
  62. newMeshes.forEach(m => {
  63. // m.scaling.scaleInPlace(100);
  64. m._geometry && (m.checkCollisions = true)
  65. if(m.material)
  66. {
  67. BABYLON.Effect.ShadersStore['aFragmentShader'] = houseShader.fragment;
  68. BABYLON.Effect.ShadersStore['aVertexShader'] = houseShader.vertex;
  69. let shaderMaterial = new BABYLON.ShaderMaterial("shader", self.scene, { vertex: "a", fragment: "a", }, {
  70. attributes: houseShader.attributes,
  71. uniforms: houseShader.uniforms,
  72. defines: houseShader.defines
  73. });
  74. let videoTexture = new BABYLON.VideoTexture("", houseVideo, self.scene)
  75. // document.getElementById("houseTexture0").play()
  76. // document.getElementById("houseTexture0").loop = "loop"
  77. shaderMaterial.setTexture("texture_video", videoTexture)
  78. shaderMaterial.setVector3("focal_width_height", new BABYLON.Vector3(
  79. 864 * window.innerWidth / settings.video.width, // 1500
  80. settings.video.width * window.innerHeight / settings.video.height,
  81. window.innerHeight
  82. // 864 * window.innerHeight / settings.video.width, // 1500
  83. // settings.video.width * window.innerWidth / settings.video.height,
  84. // window.innerWidth
  85. ))
  86. shaderMaterial.setFloat("isYUV", 0)
  87. if(self.hasVideoTexture) m.material = shaderMaterial
  88. }
  89. });
  90. self.charactorManager = new CharactorManager(self)
  91. await self.charactorManager.readPointData()
  92. self.charactorManager.importCharactorModel("../scenes/charactors/", "man_YXL.glb")
  93. });
  94. this.cameraController = new CameraController(self)
  95. }
  96. bindEvents() {
  97. this.scene.onPointerObservable.add((pointerInfo) => {
  98. switch (pointerInfo.type) {
  99. case BABYLON.PointerEventTypes.POINTERDOWN:
  100. this.cameraController.startMouseRotate(pointerInfo)
  101. break;
  102. case BABYLON.PointerEventTypes.POINTERUP:
  103. this.cameraController.endMouseRotate()
  104. break;
  105. case BABYLON.PointerEventTypes.POINTERMOVE:
  106. if(this.cameraController.lastFramePoint)
  107. this.cameraController.mouseRotating(pointerInfo)
  108. break;
  109. case BABYLON.PointerEventTypes.POINTERWHEEL:
  110. break;
  111. case BABYLON.PointerEventTypes.POINTERPICK:
  112. break;
  113. case BABYLON.PointerEventTypes.POINTERTAP:
  114. if(pointerInfo.pickInfo.hit && this.house.indexOf(pointerInfo.pickInfo.pickedMesh)) {
  115. this.charactorManager.clickHouse()
  116. }
  117. break;
  118. case BABYLON.PointerEventTypes.POINTERDOUBLETAP:
  119. break;
  120. }
  121. });
  122. this.scene.onBeforeAnimationsObservable.add(() => {
  123. if(this.charactorManager && this.charactorManager.charactor)
  124. this.charactorManager.onBeforeAnimation()
  125. })
  126. this.scene.onBeforeRenderObservable.add(() => {
  127. this.cameraController.updateCameraPos()
  128. })
  129. }
  130. bindSocketEvents() {
  131. let walkPointsTemp = []
  132. window.connection.socket.on('getRotateVideoUrl', async(data) => {
  133. console.log("[3D] getSocketVideo: ", data)
  134. const url = data
  135. // 获得旋转视频
  136. let video = this.isReverse ? document.getElementById("houseTextureReverse")
  137. : document.getElementById("houseTexture")
  138. video.src = url
  139. this.isReverse = !this.isReverse
  140. // 页面刷新后初次加载视频
  141. if(this.initVideo) {
  142. this.updateHouseVideo(video, true)
  143. this.initVideo = false
  144. this.cameraController.camera.minZ = 0.001
  145. }
  146. })
  147. window.connection.socket.on('getVideoUrl', async(data) => {
  148. console.log("[3D] getSocketVideo: ", data)
  149. const url = data
  150. if(this.getSocketVideoType == "walkPath") {
  151. let dir = this.charactorManager.getVideoDirecNum()
  152. // 获得行走视频
  153. let path = walkPointsTemp.map( (point, i) => {
  154. return {
  155. id: point.id,
  156. point: new BABYLON.Vector3(-point.location.x, 0, point.location.z),
  157. video: i == 0 ? common.createVideoElement0(url) : null,
  158. videoName: i != walkPointsTemp.length - 1 ? (point.id + "/" + point.id + "_" + walkPointsTemp[i+1].id + "_" + dir) : null
  159. }
  160. })
  161. this.getSocketVideoType = "nextWalk"
  162. // 行走时锁定camera
  163. this.cameraController.lockCamera(true)
  164. this.charactorManager.charactor.startWalk(path, this.charactorManager)
  165. }
  166. else if(this.getSocketVideoType == "nextWalk") {
  167. let charactor = this.charactorManager.charactor
  168. let video = common.createVideoElement0(url) //await common.createVideoElement(url)
  169. console.error(charactor.walkData.currentPoint+1)
  170. charactor.walkData.pathArr[charactor.walkData.currentPoint+1].video = video
  171. }
  172. })
  173. window.connection.socket.on('getSocketVideo', async(data) => {
  174. console.log("[3D] getSocketVideo: ", data)
  175. const blob = new Blob( [data], { type: 'application/video' })
  176. const url = URL.createObjectURL(blob)
  177. setTimeout(function () {
  178. URL.revokeObjectURL(url)
  179. }, 3000)
  180. if(this.getSocketVideoType == "walkPath") {
  181. let dir = this.charactorManager.getVideoDirecNum()
  182. // 获得行走视频
  183. let path = walkPointsTemp.map( (point, i) => {
  184. return {
  185. id: point.id,
  186. point: new BABYLON.Vector3(-point.location.x, 0, point.location.z),
  187. video: i == 0 ? common.createVideoElement0(url) : null,
  188. videoName: i != walkPointsTemp.length - 1 ? (point.id + "/" + point.id + "_" + walkPointsTemp[i+1].id + "_" + dir) : null
  189. }
  190. })
  191. this.getSocketVideoType = "nextWalk"
  192. // 行走时锁定camera
  193. this.cameraController.lockCamera(true)
  194. this.charactorManager.charactor.startWalk(path, this.charactorManager)
  195. }
  196. else if(this.getSocketVideoType == "nextWalk") {
  197. let charactor = this.charactorManager.charactor
  198. let video = common.createVideoElement0(url) //await common.createVideoElement(url)
  199. charactor.walkData.pathArr[charactor.walkData.currentPoint+1].video = video
  200. }
  201. else {
  202. // 获得旋转视频
  203. let video = this.isReverse ? document.getElementById("houseTextureReverse")
  204. : document.getElementById("houseTexture")
  205. video.src = url
  206. this.isReverse = !this.isReverse
  207. // 页面刷新后初次加载视频
  208. if(this.initVideo) {
  209. // this.updateHouseVideo(video, true)
  210. this.initVideo = false
  211. this.cameraController.camera.minZ = 0.001
  212. }
  213. }
  214. })
  215. window.connection.socket.on('getVideoUrl', async (data) => {
  216. console.log("[3D] getVideoUrl: ", data)
  217. // const blob = new Blob([data], { type: 'application/video' })
  218. // const url = URL.createObjectURL(blob)
  219. // setTimeout(function () {
  220. // URL.revokeObjectURL(url)
  221. // }, 3000)
  222. // let path = this.currentPoints.map( (point, index) => {
  223. // return {
  224. // point: new BABYLON.Vector3(point.location.x, 0, point.location.z),
  225. // video: url // await common.createVideoElement0(url)
  226. // }
  227. // })
  228. // // 行走时锁定camera
  229. // this.cameraController.lockCamera(true)
  230. // this.charactorManager.charactor.startWalk(path, this.charactorManager)
  231. })
  232. // 获得行走路径
  233. window.connection.socket.on("getRoute", (data) => {
  234. console.log("[3D] getRoute", data);
  235. if(!data || data.length < 2) return
  236. walkPointsTemp = data
  237. let dir = this.charactorManager.getVideoDirecNum()
  238. let firstVideoName = data[0].id + "/" + data[0].id + "_" + data[1].id + "_" + dir
  239. this.getSocketVideoType = "walkPath"
  240. let sendData = {
  241. videoList: [firstVideoName],
  242. sceneCode: settings.sceneCode,
  243. roomId: settings.roomId,
  244. userId: settings.userId,
  245. }
  246. console.log("[3D] send(getVideoUrl): ", sendData);
  247. connection.socket.emit("getVideoUrl", sendData);
  248. });
  249. }
  250. updateHouseVideo(video, notPlay) {
  251. let videoTexture = new BABYLON.VideoTexture("", video, this.scene)
  252. this.house.forEach(mesh => {
  253. // mesh.material && mesh.material.setTexture("texture_video", videoTexture)
  254. })
  255. !notPlay && video.play()
  256. }
  257. async updateHouseVideoBlob(blobUrl, notPlay) {
  258. let video = await common.createVideoElement(blobUrl)
  259. // video.loop = "loop"
  260. let videoTexture = new BABYLON.VideoTexture("", video, this.scene)
  261. this.hasVideoTexture && this.house.forEach(mesh => {
  262. mesh.material && mesh.material.setTexture("texture_video", videoTexture)
  263. })
  264. !notPlay && video.play()
  265. }
  266. }