index.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  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.init()
  28. this.bindEvents()
  29. setTimeout(() => this.bindSocketEvents(), 1000)
  30. }
  31. init() {
  32. this.initVideo = true
  33. this.isReverse = false
  34. let self = this
  35. BABYLON.SceneLoader.ImportMesh("", "../scenes/house/", "close_to_bottom_L.glb", this.scene, async function (newMeshes, particleSystems, skeletons, animationGroups) {
  36. self.house = newMeshes
  37. // self.house[0].position = new BABYLON.Vector3(0.6, 2.1, 1.5)
  38. // self.house[0].position = new BABYLON.Vector3(-22, 0, 12)
  39. let houseVideo = document.getElementById("houseTexture0")
  40. setTimeout(() => {
  41. window.connection.socket.emit("getRotateVideo", {
  42. videoPath: "0/0",
  43. sangle: 0,
  44. eangle: 360,
  45. reverses: false,
  46. sceneCode: settings.sceneCode,
  47. roomId: settings.roomId,
  48. userId: settings.userId,
  49. });
  50. window.connection.socket.emit("getRotateVideo", {
  51. videoPath: "0/0" ,
  52. sangle: 0,
  53. eangle: 360,
  54. reverses: true,
  55. sceneCode: settings.sceneCode,
  56. roomId: settings.roomId,
  57. userId: settings.userId,
  58. });
  59. }, 1500)
  60. newMeshes.forEach(m => {
  61. // m.scaling.scaleInPlace(100);
  62. m._geometry && (m.checkCollisions = true)
  63. if(m.material)
  64. {
  65. BABYLON.Effect.ShadersStore['aFragmentShader'] = houseShader.fragment;
  66. BABYLON.Effect.ShadersStore['aVertexShader'] = houseShader.vertex;
  67. let shaderMaterial = new BABYLON.ShaderMaterial("shader", self.scene, { vertex: "a", fragment: "a", }, {
  68. attributes: houseShader.attributes,
  69. uniforms: houseShader.uniforms,
  70. defines: houseShader.defines
  71. });
  72. let videoTexture = new BABYLON.VideoTexture("", houseVideo, self.scene)
  73. // document.getElementById("houseTexture0").play()
  74. // document.getElementById("houseTexture0").loop = "loop"
  75. shaderMaterial.setTexture("texture_video", videoTexture)
  76. shaderMaterial.setVector3("focal_width_height", new BABYLON.Vector3(
  77. 864 * window.innerWidth / settings.video.width, // 1500
  78. settings.video.width * window.innerHeight / settings.video.height,
  79. window.innerHeight
  80. // 864 * window.innerHeight / settings.video.width, // 1500
  81. // settings.video.width * window.innerWidth / settings.video.height,
  82. // window.innerWidth
  83. ))
  84. shaderMaterial.setFloat("isYUV", 0)
  85. m.material = shaderMaterial
  86. }
  87. });
  88. self.charactorManager = new CharactorManager(self)
  89. await self.charactorManager.readPointData()
  90. self.charactorManager.importCharactorModel("../scenes/charactors/", "man_YXL.glb")
  91. });
  92. this.cameraController = new CameraController(self)
  93. }
  94. bindEvents() {
  95. this.scene.onPointerObservable.add((pointerInfo) => {
  96. switch (pointerInfo.type) {
  97. case BABYLON.PointerEventTypes.POINTERDOWN:
  98. this.cameraController.startMouseRotate(pointerInfo)
  99. break;
  100. case BABYLON.PointerEventTypes.POINTERUP:
  101. this.cameraController.endMouseRotate()
  102. break;
  103. case BABYLON.PointerEventTypes.POINTERMOVE:
  104. if(this.cameraController.lastFramePoint)
  105. this.cameraController.mouseRotating(pointerInfo)
  106. break;
  107. case BABYLON.PointerEventTypes.POINTERWHEEL:
  108. break;
  109. case BABYLON.PointerEventTypes.POINTERPICK:
  110. break;
  111. case BABYLON.PointerEventTypes.POINTERTAP:
  112. if(pointerInfo.pickInfo.hit && this.house.indexOf(pointerInfo.pickInfo.pickedMesh)) {
  113. this.charactorManager.clickHouse()
  114. }
  115. break;
  116. case BABYLON.PointerEventTypes.POINTERDOUBLETAP:
  117. break;
  118. }
  119. });
  120. this.scene.onBeforeAnimationsObservable.add(() => {
  121. if(this.charactorManager && this.charactorManager.charactor)
  122. this.charactorManager.onBeforeAnimation()
  123. })
  124. this.scene.onBeforeRenderObservable.add(() => {
  125. this.cameraController.updateCameraPos()
  126. })
  127. }
  128. bindSocketEvents() {
  129. // 获得旋转视频
  130. window.connection.socket.on('getSocketVideo', async(data) => {
  131. console.log("[3D] getSocketVideo: ", data)
  132. const blob = new Blob([data], { type: 'application/video' })
  133. const url = URL.createObjectURL(blob)
  134. // this.updateHouseVideoBlob(url, true)
  135. // let video = common.createVideoElement0(url)
  136. // video.loop = "loop"
  137. setTimeout(function () {
  138. return URL.revokeObjectURL(url)
  139. }, 3000)
  140. if(this.getWalkVideo) {
  141. let path = this.currentPoints.map( (point, index) => {
  142. return {
  143. point: new BABYLON.Vector3(point.location.x, 0, point.location.z),
  144. video: common.createVideoElement0(url)
  145. }
  146. })
  147. // 行走时锁定camera
  148. this.cameraController.lockCamera(true)
  149. this.charactorManager.charactor.startWalk(path, this.charactorManager)
  150. this.getWalkVideo = false
  151. } else {
  152. // this.cameraController.rotateCamera(this.cameraController.alphaOffset)
  153. if(this.isReverse) {
  154. document.getElementById("houseTextureReverse").src = url
  155. } else {
  156. document.getElementById("houseTexture").src = url
  157. }
  158. this.isReverse = !this.isReverse
  159. if(this.initVideo) {
  160. this.updateHouseVideoBlob(url, true)
  161. this.initVideo = false
  162. }
  163. }
  164. })
  165. // 获得行走视频
  166. window.connection.socket.on('getVideo', async (data) => {
  167. console.log("[3D] getVideo: ", data)
  168. const blob = new Blob([data], { type: 'application/video' })
  169. const url = URL.createObjectURL(blob)
  170. setTimeout(function () {
  171. URL.revokeObjectURL(url)
  172. }, 3000)
  173. // let path = this.currentPoints.map( (point, index) => {
  174. // return {
  175. // point: new BABYLON.Vector3(point.location.x, 0, point.location.z),
  176. // video: url // await common.createVideoElement0(url)
  177. // }
  178. // })
  179. // // 行走时锁定camera
  180. // this.cameraController.lockCamera(true)
  181. // this.charactorManager.charactor.startWalk(path, this.charactorManager)
  182. })
  183. // 获得行走路径
  184. window.connection.socket.on("getRoute", (data) => {
  185. console.log("[3D] getRoute", data);
  186. if(data.length < 2) return
  187. data = data.reverse()
  188. this.currentPoints = data
  189. let dir = this.charactorManager.getVideoDirecNum()
  190. let videos = []
  191. for(let i = 0; i < data.length - 1; i++) {
  192. videos.push(data[i].id + "/" + data[i].id + "_" + data[i+1].id + "_" + dir)
  193. }
  194. this.getWalkVideo = true
  195. connection.socket.emit("getVideo", {
  196. videoList: videos,
  197. sceneCode: settings.sceneCode,
  198. roomId: settings.roomId,
  199. userId: settings.userId,
  200. });
  201. });
  202. }
  203. updateHouseVideo(video, notPlay) {
  204. let videoTexture = new BABYLON.VideoTexture("", video, this.scene)
  205. this.house.forEach(mesh => {
  206. mesh.material && mesh.material.setTexture("texture_video", videoTexture)
  207. })
  208. !notPlay && video.play()
  209. }
  210. async updateHouseVideoBlob(blobUrl, notPlay) {
  211. let video = await common.createVideoElement(blobUrl)
  212. // video.loop = "loop"
  213. let videoTexture = new BABYLON.VideoTexture("", video, this.scene)
  214. this.house.forEach(mesh => {
  215. mesh.material && mesh.material.setTexture("texture_video", videoTexture)
  216. })
  217. !notPlay && video.play()
  218. return video
  219. }
  220. }