XCameraComponent.js 12 KB

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