Camera.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. import CameraStates from "./enum/CameraStates.js"
  2. import Person from "./enum/Person.js"
  3. import EImageQuality from "./enum/EImageQuality.js"
  4. import Actions from "./enum/Actions.js"
  5. import Logger from "./Logger.js"
  6. const logger = new Logger('camera')
  7. export default class Camera extends EventEmitter {
  8. constructor(e) {
  9. super();
  10. this.initialFov = 0
  11. this._state = CameraStates.Normal
  12. this._person = Person.Third
  13. this._cameraFollowing = !0
  14. this._room = e
  15. }
  16. /*
  17. checkPointOnLeftOrRight(e){
  18. const t = ue4Position2Xverse(e);
  19. if (!t || this.checkPointInView(e))
  20. {
  21. return;
  22. }
  23. const activeCamera = this._room.scene.activeCamera;
  24. if (!activeCamera)
  25. {
  26. return;
  27. }
  28. const a = [activeCamera.target.x, activeCamera.target.y, activeCamera.target.z]
  29. , s = [activeCamera.position.x, activeCamera.position.y, activeCamera.position.z]
  30. , {x: l, y: u, z: c} = t
  31. , h = calNormVector(s, a)
  32. , f = calNormVector(s, [l, u, c]);
  33. return vectorCrossMulti(h, f) < 0 ? Direction.Right : Direction.Left
  34. }
  35. checkPointInView(e,t,r){
  36. const n = ue4Position2Xverse({
  37. x: e,
  38. y: t,
  39. z: r
  40. });
  41. if (!n)
  42. return !1;
  43. for (let o = 0; o < 6; o++)
  44. if (this._room.scene.frustumPlanes[o].dotCoordinate(n) < 0)
  45. return !1;
  46. return !0
  47. }
  48. get person() {
  49. return this._person
  50. }
  51. get state() {
  52. return this._state
  53. }
  54. get pose() {
  55. return this._room.currentClickingState.camera
  56. }
  57. set cameraFollowing(e) {
  58. logger.info("cameraFollowing setter", e),
  59. this.setCameraFollowing({
  60. isFollowHost: e
  61. })
  62. }
  63. get cameraFollowing() {
  64. return this._cameraFollowing
  65. }
  66. setCameraFollowing({isFollowHost: e}) {}
  67. */
  68. handleRenderInfo(e) {
  69. const {cameraStateType} = e.renderInfo;
  70. const sceneManager = this._room.sceneManager;
  71. if(cameraStateType !== this._state) {
  72. this._state = cameraStateType;
  73. logger.debug("camera._state changed to", CameraStates[cameraStateType]);
  74. if(cameraStateType === CameraStates.CGView) {
  75. sceneManager.cameraComponent.switchToCgCamera();
  76. sceneManager.staticmeshComponent.getCgMesh().show();
  77. } else {
  78. sceneManager.cameraComponent.switchToMainCamera();
  79. sceneManager.staticmeshComponent.getCgMesh().hide();
  80. }
  81. this.emit("stateChanged", { state: cameraStateType })
  82. }
  83. if(this._room.isHost) return;
  84. const {isFollowHost} = e.playerState;
  85. if(!!isFollowHost !== this._cameraFollowing) {
  86. this._cameraFollowing = !!isFollowHost;
  87. this.emit("cameraFollowingChanged", { cameraFollowing: !!isFollowHost })
  88. }
  89. }
  90. /*
  91. setCameraState({state: state}) {
  92. if (this._state === state) {
  93. logger.warn(`You are already in ${CameraStates[state]} camera state`);
  94. return
  95. }
  96. state === CameraStates.Normal || this._state === CameraStates.ItemView && logger.warn("CloseUp camera state can only be triggerd by room internally")
  97. }
  98. turnToFace({extra: e="", offset: t=0}) {
  99. const r = {
  100. action_type: Actions.TurnToFace,
  101. turn_to_face_action: {
  102. offset: t
  103. }
  104. };
  105. return this.emit("viewChanged", {
  106. extra: e
  107. }),
  108. this._room.actionsHandler.sendData({
  109. data: r
  110. })
  111. }
  112. isInDefaultView() {
  113. if (!this._room.isHost) {
  114. logger.warn("It is recommended to call the function on the host side");
  115. return
  116. }
  117. if (!this._room._currentClickingState)
  118. {
  119. logger.error("CurrentState should not be empty");
  120. return !1;
  121. }
  122. const {camera: camera, player: player} = this._room._currentClickingState;
  123. return Math.abs(player.angle.yaw - 180 - camera.angle.yaw) % 360 <= 4
  124. }
  125. async screenShot({name: name, autoSave: autoSave=!1}) {
  126. const engine = this._room.scene.getEngine()
  127. const activeCamera = this._room.scene.activeCamera;
  128. try {
  129. this._room.sceneManager.setImageQuality(EImageQuality.high);
  130. const promise = await CreateScreenshotAsync(engine, activeCamera, {
  131. precision: 1
  132. });
  133. this._room.sceneManager.setImageQuality(EImageQuality.low);
  134. autoSave === !0 && downloadFileByBase64(promise, name);
  135. return Promise.resolve(promise)
  136. } catch (error) {
  137. this._room.sceneManager.setImageQuality(EImageQuality.low)
  138. return Promise.reject(error)
  139. }
  140. }
  141. changeToFirstPerson(e, t, r) {
  142. const {camera: camera, player: player, attitude: attitude, areaName: areaName, pathName: pathName} = e;
  143. return this._room.actionsHandler.requestPanorama({
  144. camera: camera,
  145. player: player,
  146. attitude: attitude,
  147. areaName: areaName,
  148. pathName: pathName
  149. }, t, r).then(()=>{
  150. this._room.networkController.rtcp.workers.changePanoMode(!0);
  151. const {position: u, angle: c} = player || {};
  152. this._room.sceneManager.cameraComponent.changeToFirstPersonView({
  153. position: u,
  154. rotation: c
  155. })
  156. }
  157. )
  158. }
  159. setPerson(e, t={
  160. camera: this._room._currentClickingState.camera,
  161. player: this._room._currentClickingState.player
  162. }) {
  163. const startTime = Date.now();
  164. return this._setPerson(e, t).then(n=>(logger.infoAndReportMeasurement({
  165. tag: Person[e],
  166. startTime: startTime,
  167. metric: "setPerson"
  168. }),n)).catch(n=>(logger.infoAndReportMeasurement({
  169. tag: Person[e],
  170. startTime: startTime,
  171. metric: "setPerson",
  172. error: n
  173. }),
  174. Promise.reject(n)))
  175. }
  176. _setPerson(e, t={
  177. camera: this._room._currentClickingState.camera,
  178. player: this._room._currentClickingState.player
  179. }) {
  180. return e !== Person.First && e !== Person.Third ? Promise.reject("invalid person " + e) : !t.camera || !t.player ? Promise.reject(new ParamError("wrong camera or player")) : e === Person.First ? this._room.panorama.access({
  181. camera: t.camera,
  182. player: t.player,
  183. tag: "setPerson"
  184. }).then(()=>{
  185. var o, a;
  186. this._person = e,
  187. (o = this._room._userAvatar) == null || o.hide();
  188. const {position: r, angle: n} = ((a = this._room.currentClickingState) == null ? void 0 : a.camera) || {};
  189. !r || !n || this._room.sceneManager.cameraComponent.changeToFirstPersonView({
  190. position: r,
  191. rotation: n
  192. })
  193. }
  194. ) : this._room.panorama.exit({
  195. camera: t.camera,
  196. player: t.player
  197. }).then(()=>{
  198. var r, n;
  199. this._person = e,
  200. (r = this._room._userAvatar) != null && r.xAvatar && ((n = this._room._userAvatar) == null || n.xAvatar.show())
  201. }
  202. )
  203. }
  204. */
  205. setCameraPose(cameraPose) {
  206. this._room.sceneManager.cameraComponent.setCameraPose({
  207. position: cameraPose.position,
  208. rotation: cameraPose.angle
  209. })
  210. }
  211. // setMainCameraRotationLimit(e) {
  212. // const {limitAxis: t, limitRotation: r} = e;
  213. // this._room.sceneManager.cameraComponent.setMainCameraRotationLimit(t, r)
  214. // }
  215. }