XCameraComponent.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. export default class XCameraComponent {
  2. constructor(e, t, r) {
  3. E(this, "maincameraRotLimitObserver", null);
  4. E(this, "mainCamera");
  5. E(this, "cgCamera");
  6. E(this, "saveCameraPose");
  7. E(this, "_cameraPose");
  8. E(this, "scene");
  9. E(this, "canvas");
  10. E(this, "yuvInfo");
  11. E(this, "forceKeepVertical", !1);
  12. E(this, "initCamera", e=>{
  13. const {maxZ: t=1e4, minZ: r=.1, angularSensibility: n=2e3} = e;
  14. this.mainCamera = new BABYLON.FreeCamera("camera_main",new BABYLON.Vector3(0,0,1),this.scene),
  15. this.mainCamera.mode = BABYLON.Camera.PERSPECTIVE_CAMERA,
  16. this.mainCamera.speed = .1,
  17. this.mainCamera.angularSensibility = n,
  18. this.mainCamera.setTarget(new BABYLON.Vector3(0,0,0)),
  19. this.mainCamera.minZ = r,
  20. this.mainCamera.fov = Math.PI * this.yuvInfo.fov / 180,
  21. this.mainCamera.maxZ = t,
  22. this.mainCamera.fovMode = BABYLON.Camera.FOVMODE_HORIZONTAL_FIXED,
  23. this.cgCamera = new BABYLON.FreeCamera("camera_temp",new BABYLON.Vector3(0,1e3,0),this.scene),
  24. this.cgCamera.mode = BABYLON.Camera.PERSPECTIVE_CAMERA,
  25. this.cgCamera.speed = .1,
  26. this.cgCamera.setTarget(new BABYLON.Vector3(0,1010,0)),
  27. this.cgCamera.maxZ = t,
  28. this.cgCamera.minZ = r,
  29. this.cgCamera.fovMode = BABYLON.Camera.FOVMODE_HORIZONTAL_FIXED,
  30. this.cameraFovChange(this.yuvInfo)
  31. }
  32. );
  33. E(this, "cameraFovChange", e=>{
  34. this.yuvInfo = e;
  35. const t = e.width
  36. , r = e.height
  37. , n = this.canvas.width
  38. , o = this.canvas.height
  39. , a = e.fov;
  40. if (this.forceKeepVertical == !0) {
  41. const s = t / (2 * Math.tan(Math.PI * a / 360))
  42. , l = 2 * Math.atan(r / (2 * s));
  43. this.mainCamera.fov = l,
  44. this.cgCamera.fov = l,
  45. this.mainCamera.fovMode = BABYLON.Camera.FOVMODE_VERTICAL_FIXED,
  46. this.cgCamera.fovMode = BABYLON.Camera.FOVMODE_VERTICAL_FIXED
  47. } else if (this.mainCamera.fovMode = BABYLON.Camera.FOVMODE_HORIZONTAL_FIXED,
  48. this.cgCamera.fovMode = BABYLON.Camera.FOVMODE_HORIZONTAL_FIXED,
  49. n / o < t / r && this.mainCamera.fov) {
  50. const s = o
  51. , l = n
  52. , u = s * t / r / (2 * Math.tan(a * Math.PI / 360))
  53. , c = 2 * Math.atan(l / (2 * u));
  54. this.mainCamera.fov = c,
  55. this.cgCamera.fov = c
  56. } else
  57. this.mainCamera.fov = Math.PI * a / 180,
  58. this.cgCamera.fov = Math.PI * a / 180
  59. }
  60. );
  61. E(this, "setCameraPose", e=>{
  62. var n;
  63. const t = ue4Position2Xverse(e.position);
  64. let r = null;
  65. e.rotation != null && (r = ue4Rotation2Xverse(e.rotation)),
  66. this._cameraPose = {
  67. position: t
  68. },
  69. r != null && (this._cameraPose.rotation = r),
  70. this.scene.activeCamera === this.mainCamera && !((n = this.mainCamera) != null && n.isDisposed()) && this._setCamPositionRotation(this.mainCamera, this._cameraPose)
  71. }
  72. );
  73. E(this, "_setCamPositionRotation", (e,t)=>{
  74. var r, n;
  75. t.position && (e.position = (r = t.position) == null ? void 0 : r.clone()),
  76. t.rotation && (e.rotation = (n = t.rotation) == null ? void 0 : n.clone())
  77. }
  78. );
  79. E(this, "switchCamera", e=>{
  80. var t;
  81. (t = this.scene.activeCamera) == null || t.detachControl(this.canvas),
  82. this.scene.activeCamera = e
  83. }
  84. );
  85. E(this, "reCalXYZRot", (e,t)=>(e = e % (2 * Math.PI),
  86. Math.abs(t - e) >= Math.PI && (e = e - 2 * Math.PI),
  87. e));
  88. E(this, "_moveCam", (e,t,r,n,o,a,s,l)=>{
  89. const u = (v,y,b)=>(v.x = this.reCalXYZRot(v.x, y.x),
  90. v.y = this.reCalXYZRot(v.y, y.y),
  91. v.z = this.reCalXYZRot(v.z, y.z),
  92. new BABYLON.Vector3((y.x - v.x) * b + v.x,(y.y - v.y) * b + v.y,(y.z - v.z) * b + v.z))
  93. , c = function(v, y, b) {
  94. return new BABYLON.Vector3((y.x - v.x) * b + v.x,(y.y - v.y) * b + v.y,(y.z - v.z) * b + v.z)
  95. }
  96. , h = new Animation("myAnimation1","position",s,Animation.ANIMATIONTYPE_VECTOR3,Animation.ANIMATIONLOOPMODE_CONSTANT);
  97. let f = []
  98. , d = t
  99. , _ = r;
  100. for (let v = 0; v < a; ++v)
  101. f.push({
  102. frame: v,
  103. value: c(d, _, v / a)
  104. });
  105. f.push({
  106. frame: f.length,
  107. value: c(d, _, 1)
  108. }),
  109. h.setKeys(f);
  110. const g = new Animation("myAnimation2","rotation",s,Animation.ANIMATIONTYPE_VECTOR3,Animation.ANIMATIONLOOPMODE_CONSTANT);
  111. f = [],
  112. d = n,
  113. _ = o;
  114. for (let v = 0; v < a; ++v)
  115. f.push({
  116. frame: v,
  117. value: u(d, _, v / a)
  118. });
  119. f.push({
  120. frame: f.length,
  121. value: u(d, _, 1)
  122. }),
  123. g.setKeys(f),
  124. e.animations.push(g),
  125. e.animations.push(h);
  126. const m = this.scene.beginAnimation(e, 0, a, !1);
  127. m.onAnimationEnd = ()=>{
  128. l(),
  129. m.stop(),
  130. m.animationStarted = !1
  131. }
  132. }
  133. );
  134. this.scene = t,
  135. this.canvas = e,
  136. this.yuvInfo = r.yuvInfo,
  137. r.forceKeepVertical != null && (this.forceKeepVertical = r.forceKeepVertical),
  138. this.initCamera(r.cameraParam)
  139. }
  140. get MainCamera() {
  141. return this.mainCamera
  142. }
  143. get CgCamera() {
  144. return this.cgCamera
  145. }
  146. getCameraHorizonFov() {
  147. return this.mainCamera.fovMode == BABYLON.Camera.FOVMODE_HORIZONTAL_FIXED ? this.mainCamera.fov : Math.PI * this.yuvInfo.fov / 180
  148. }
  149. changeMainCameraRotationDamping(e=2e3) {
  150. this.mainCamera.angularSensibility = e
  151. }
  152. removeMainCameraRotationLimit() {
  153. this.maincameraRotLimitObserver != null && this.mainCamera.onAfterCheckInputsObservable.remove(this.maincameraRotLimitObserver)
  154. }
  155. setMainCameraInfo(e) {
  156. const {maxZ: t=1e4, minZ: r=.1, angularSensibility: n=2e3} = e;
  157. this.mainCamera.maxZ = t,
  158. this.mainCamera.minZ = r,
  159. this.mainCamera.angularSensibility = n
  160. }
  161. getMainCameraInfo() {
  162. return {
  163. maxZ: this.mainCamera.maxZ,
  164. minZ: this.mainCamera.minZ,
  165. angularSensibility: this.mainCamera.angularSensibility
  166. }
  167. }
  168. _limitAngle(e, t) {
  169. return Math.abs(Math.abs(t[0] - t[1]) - 360) < 1e-6 || (e = (e % 360 + 360) % 360,
  170. t[0] = (t[0] % 360 + 360) % 360,
  171. t[1] = (t[1] % 360 + 360) % 360,
  172. t[0] > t[1] ? e > t[1] && e < t[0] && (Math.abs(e - t[0]) < Math.abs(e - t[1]) ? e = t[0] : e = t[1]) : e < t[0] ? e = t[0] : e > t[1] && (e = t[1])),
  173. e
  174. }
  175. setMainCameraRotationLimit(e, t) {
  176. this.maincameraRotLimitObserver != null && this.removeMainCameraRotationLimit();
  177. const r = this.mainCamera
  178. , {yaw: n, pitch: o, roll: a} = e
  179. , {yaw: s, pitch: l, roll: u} = t;
  180. if (s < 0 || l < 0 || u < 0)
  181. throw new Error("\u76F8\u673A\u65CB\u8F6C\u9650\u5236\u53EA\u80FD\u8BBE\u7F6E\u4E3A\u5927\u4E8E0");
  182. const c = [o - l, o + l]
  183. , h = [n - s, n + s]
  184. , f = [a - u, a + u];
  185. this.maincameraRotLimitObserver = r.onAfterCheckInputsObservable.add(()=>{
  186. let {pitch: d, yaw: _, roll: g} = xverseRotation2Ue4(r.rotation);
  187. d = this._limitAngle(d, c),
  188. _ = this._limitAngle(_, h),
  189. g = this._limitAngle(g, f),
  190. r.rotation = ue4Rotation2Xverse({
  191. pitch: d,
  192. yaw: _,
  193. roll: g
  194. })
  195. }
  196. )
  197. }
  198. setMainCameraRotationLimitByAnchor(e, t, r) {
  199. this.maincameraRotLimitObserver != null && this.removeMainCameraRotationLimit();
  200. const n = this.mainCamera
  201. , o = ue4Rotation2Xverse_mesh(t)
  202. , a = ue4Rotation2Xverse_mesh(r);
  203. a != null && o != null && e.mesh != null && (this.maincameraRotLimitObserver = n.onAfterCheckInputsObservable.add(()=>{
  204. const s = e.mesh.rotation;
  205. r.yaw > 0 && (n.rotation.y <= s.y - a.y + o.y ? n.rotation.y = s.y - a.y + o.y : n.rotation.y >= s.y + a.y + o.y && (n.rotation.y = s.y + a.y + o.y)),
  206. r.pitch > 0 && (n.rotation.x <= s.x - a.x + o.x ? n.rotation.x = s.x - a.x + o.x : n.rotation.x >= s.x + a.x + o.x && (n.rotation.x = s.x + a.x + o.x)),
  207. r.roll > 0 && (n.rotation.z <= s.z - a.z + o.z ? n.rotation.z = s.z - a.z + o.z : n.rotation.z >= s.z + a.z + o.z && (n.rotation.z = s.z + a.z + o.z))
  208. }
  209. ))
  210. }
  211. getCameraPose() {
  212. const e = xversePosition2Ue4({
  213. x: this.mainCamera.position.x,
  214. y: this.mainCamera.position.y,
  215. z: this.mainCamera.position.z
  216. })
  217. , t = xverseRotation2Ue4({
  218. x: this.mainCamera.rotation.x,
  219. y: this.mainCamera.rotation.y,
  220. z: this.mainCamera.rotation.z
  221. });
  222. return {
  223. position: e,
  224. rotation: t
  225. }
  226. }
  227. changeCameraFov(e, t) {
  228. this.mainCamera.fov = e,
  229. t != null && (this.mainCamera.fovMode = t == 0 ? BABYLON.Camera.FOVMODE_HORIZONTAL_FIXED : BABYLON.Camera.FOVMODE_VERTICAL_FIXED)
  230. }
  231. controlCameraRotation(e, t, r=.5, n=.5) {
  232. const o = {
  233. pitch: n * t * 180,
  234. yaw: r * e * 180,
  235. roll: 0
  236. };
  237. this.addRot(o)
  238. }
  239. addRot(e) {
  240. const t = this.mainCamera
  241. , r = ue4Rotation2Xverse_mesh(e);
  242. r != null && t.rotation.addInPlace(r)
  243. }
  244. getCameraFov() {
  245. return this.mainCamera.fov
  246. }
  247. allowMainCameraController() {
  248. this.mainCamera.attachControl(this.canvas, !0)
  249. }
  250. detachMainCameraController() {
  251. this.mainCamera.detachControl(this.canvas)
  252. }
  253. forceChangeSavedCameraPose(e) {
  254. this.saveCameraPose != null && (e.position != null && (this.saveCameraPose.position = ue4Position2Xverse(e.position)),
  255. e.rotation != null && (this.saveCameraPose.rotation = ue4Rotation2Xverse(e.rotation)))
  256. }
  257. changeToFirstPersonView(e) {
  258. this.saveCameraPose = {
  259. position: this.mainCamera.position.clone(),
  260. rotation: this.mainCamera.rotation.clone()
  261. },
  262. this.mainCamera.attachControl(this.canvas, !0),
  263. e.position != null && (this.mainCamera.position = ue4Position2Xverse(e.position)),
  264. e.rotation != null && (this.mainCamera.rotation = ue4Rotation2Xverse(e.rotation))
  265. }
  266. changeToThirdPersonView() {
  267. this.saveCameraPose != null && this.mainCamera != null && (this.mainCamera.position = this.saveCameraPose.position.clone(),
  268. this.mainCamera.rotation = this.saveCameraPose.rotation.clone(),
  269. this.mainCamera.detachControl(this.canvas))
  270. }
  271. switchToMainCamera() {
  272. this.switchCamera(this.mainCamera)
  273. }
  274. switchToCgCamera() {
  275. this.switchCamera(this.cgCamera)
  276. }
  277. moveMainCamera(e, t, r, n, o) {
  278. this._moveCam(this.mainCamera, this.mainCamera.position, e, this.mainCamera.rotation, t, r, n, o)
  279. }
  280. }