ConvertViews.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. import math from './math.js'
  2. export default class ConvertViews {
  3. constructor() {
  4. this.sourceApp = null
  5. this.targetApp = null
  6. this.player1 = null
  7. this.player2 = null
  8. this.KanKan = null
  9. }
  10. /* bind(options = { sourceApp: null, targetApp: null }) {
  11. if (options.sourceApp) {
  12. this.sourceApp = options.sourceApp
  13. this.player1 = this.sourceApp.core.get('Player')
  14. //this.player1.model.addEventListener('gotPanos', this.init.bind(this))
  15. } else if (options.targetApp) {
  16. this.targetApp = options.targetApp
  17. this.player2 = this.targetApp.core.get('Player')
  18. //this.player2.model.addEventListener('gotPanos', this.init.bind(this))
  19. }
  20. if (this.sourceApp && this.targetApp) {
  21. // 两个实例都加载完了,可以进行特性处理
  22. this.init()
  23. this.applyDiff(options.sourceApp || options.targetApp)
  24. }
  25. } */
  26. init(viewer, dom2, sceneType, data) {
  27. //if (!this.player1.model.panos.list.length || !this.player2.model.panos.list.length) return
  28. this.needConvertAxis = sceneType == '4dkk'
  29. this.lastCamStatus = viewer.getCameraStatus()
  30. viewer.setNavigationMode(Glodon.Bimface.Viewer.NavigationMode3D.Walk)
  31. viewer.setFlySpeedRate(5)
  32. viewer.getViewer().setTransitionAnimationState(false) //setCameraStatus瞬间变化相机
  33. viewer.addEventListener('Rendered', (e)=>{
  34. let info = viewer.getCameraStatus()
  35. let poseChanged = !math.closeTo(this.lastCamStatus.position, info.position)
  36. || !math.closeTo(this.lastCamStatus.target, info.target)
  37. || !math.closeTo(this.lastCamStatus.fov, info.fov)
  38. if(poseChanged){
  39. this.send(info)
  40. }
  41. this.lastCamStatus = info
  42. /* aspect: 0.7879440258342304
  43. coordinateSystem: "world"
  44. far: 11485.989363357028
  45. fov: 45
  46. name: "persp"
  47. near: 1.1852000000072447
  48. position: {x: -1130.0432094639486, y: -6058.569138159733, z: 2265.9284566100446}
  49. target: {x: 310.3968263091223, y: -66.0595010237127, z: 1477.7045866099475}
  50. up: {x: 0, y: 1.534753124827774e-13, z: 1}
  51. version: 1
  52. zoom: 0 */
  53. })
  54. viewer.addEventListener( Glodon.Bimface.Viewer.Viewer3DEvent.ViewAdded,
  55. ()=>{
  56. this.loaded = true
  57. if(this.firstData){
  58. this.receive(this.firstData)
  59. }
  60. }
  61. )
  62. this.receive(data)
  63. {
  64. this.lockCamera(true)
  65. let dom1 = viewer.getDomElement()
  66. dom1.addEventListener('mousedown',(e)=>{//传递到另一边的dom
  67. dom2.dispatchEvent(e) //试试
  68. })
  69. dom1.addEventListener('mousemove',(e)=>{//传递到另一边的dom
  70. dom2.dispatchEvent(e) //试试
  71. })
  72. dom1.addEventListener('mouseup',(e)=>{//传递到另一边的dom
  73. dom2.dispatchEvent(e) //试试
  74. })
  75. dom1.addEventListener('mousewheel',(e)=>{//传递到另一边的dom
  76. dom2.dispatchEvent(e) //试试
  77. })
  78. let stop = (e)=>{
  79. var event = document.createEvent('MouseEvents');
  80. event.initMouseEvent('mouseup', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
  81. dom2.dispatchEvent(event)
  82. }
  83. dom1.addEventListener('mouseout',stop)
  84. dom1.addEventListener('mouseover',stop)
  85. }
  86. this.computeAveDiffLon()
  87. }
  88. receive(data){
  89. if(!this.loaded){
  90. return this.firstData = data
  91. }
  92. /* if(this.isMaster){
  93. return //正在操作当前,不接收
  94. } */
  95. let position, target
  96. let currStatus = viewer.getCameraStatus()
  97. if(data.position){
  98. position = new THREE.Vector3().copy(data.position)
  99. }else{
  100. position.copy(currStatus.position)
  101. }
  102. if(this.needConvertAxis){
  103. position = math.convertVector.YupToZup(position)
  104. }
  105. if(!data.target){
  106. if(data.quaternion){
  107. if(this.needConvertAxis){
  108. data.quaternion = math.convertQuaternion.YupToZup(data.quaternion)
  109. }
  110. let dir = new THREE.Vector3(0, 0, -1).applyQuaternion(data.quaternion)
  111. dir.applyQuaternion(this.diffQuaternion)/////!
  112. target.copy(position).add(dir)
  113. }
  114. }else{
  115. if(this.needConvertAxis){
  116. target = math.convertVector.YupToZup(target)
  117. }else{
  118. target.copy(data.target)
  119. }
  120. }
  121. let msg = {
  122. position,
  123. target,
  124. up: new THREE.Vector3(0,0,1)
  125. }//前三个缺一不可
  126. viewer.setCameraStatus(msg)
  127. //fov, near, far
  128. }
  129. send(info){
  130. let camera = viewer.getViewer().camera
  131. let data = {
  132. position : info.position,
  133. quaternion : camera.quaternion,
  134. target : info.target,
  135. }
  136. }
  137. lockCamera(locked){
  138. this.locked = locked
  139. this.updateCtrlEnable()
  140. }
  141. setPanoMode(state){
  142. this.isPanoMode = state
  143. this.updateCtrlEnable()
  144. }
  145. updateCtrlEnable(){
  146. viewer.camera3D.enableRotate(this.locked ? false : true)
  147. viewer.enableShortcutKey((this.locked || this.isPanoMode) ? false : true) //键盘移动
  148. }
  149. computeAveDiffLon() {
  150. //获取两个场景的lon偏差值
  151. //需要点的个数>1, 且两个场景点一一对应,位置接近且顺序一致
  152. //pick两个点来计算
  153. let diffLonAve = 0,
  154. diffLons = []
  155. let panoPos1 = [//4dkk
  156. ]
  157. let panoPos2 = [{
  158. x: -0.8948667986001945,
  159. y: -0.7200655233964686,
  160. z: 1.742798893355817
  161. },{
  162. x: -0.8675960783595227,
  163. y: 2.3758592370806317,
  164. z: 1.7428102653224462
  165. }]
  166. let length = panoPos1.length
  167. if(this.needConvertAxis){
  168. panoPos1 = panoPos1.map(e=>math.convertVector.YupToZup(e))
  169. }
  170. //挑选连续的两个点为向量来计算,如有123个漫游点,则选取12 23 31作为向量
  171. let index = 0
  172. while (index < length) {
  173. let pos11 = new THREE.Vector3().copy(panoPos1[index])
  174. let pos12 = new THREE.Vector3().copy(panoPos1[(index + 1) % length])
  175. let pos21 = new THREE.Vector3().copy(panoPos2[index])
  176. let pos22 = new THREE.Vector3().copy(panoPos2[(index + 1) % length])
  177. let vec1 = new THREE.Vector3().subVectors(pos11, pos12).setY(0)
  178. let vec2 = new THREE.Vector3().subVectors(pos21, pos22).setY(0)
  179. let diffLon = this.KanKan.Utils.math.getAngle(vec1, vec2, 'z')
  180. diffLons.push(diffLon)
  181. diffLonAve += diffLon
  182. index++
  183. }
  184. console.log('diffLons', diffLons)
  185. diffLonAve /= length
  186. console.log('diffLonAve', diffLonAve)
  187. this.diffQuaternion = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), diffLonAve)
  188. this.diffQuaternionInvert = this.diffQuaternion.clone().invert()
  189. }
  190. /* applyDiff(app) {
  191. //sourcePlayer -> targetPlayer
  192. if (!this.player1 || !this.player2 || this.targetApp.config.num == this.sourceApp.config.num) return //场景码相同的话返回
  193. if (this.player1.mode != this.player2.mode) return
  194. let player1, player2, quaternion //player1为要改变的, player2是参照
  195. if (app == this.sourceApp) {
  196. player1 = this.player1
  197. player2 = this.player2
  198. quaternion = this.diffQuaternion
  199. } else {
  200. player1 = this.player2
  201. player2 = this.player1
  202. quaternion = this.diffQuaternionInvert
  203. }
  204. let control1 = player1.cameraControls.activeControl
  205. let control2 = player2.cameraControls.activeControl
  206. //if(!control1 || !control2)return
  207. player1.quaternion.copy(player2.quaternion).premultiply(quaternion)
  208. if (player1.mode == 'panorama') {
  209. //平移
  210. let dir = new this.KanKan.THREE.Vector3().subVectors(control2.target, player2.position)
  211. dir.applyQuaternion(quaternion)
  212. let target1 = new this.KanKan.THREE.Vector3().addVectors(player1.position, dir)
  213. control1.lookAt(target1)
  214. control1.target.copy(target1)
  215. } else if (control2) {
  216. //修改target,保证target在panos之间的相对位置一样
  217. //console.log('target', control2.target.clone())
  218. //console.log('position', control2.target.clone())
  219. let vec = new this.KanKan.THREE.Vector3().subVectors(control2.target, player2.model.panos.list[0].position)
  220. vec.applyQuaternion(quaternion)
  221. control1.target.addVectors(player1.model.panos.list[0].position, vec)
  222. player1.target.copy(control1.target)
  223. //修改position,保证方向一样
  224. let dir = new this.KanKan.THREE.Vector3().subVectors(control2.camera.position , control2.target)
  225. dir.applyQuaternion(quaternion)
  226. player1.position = new this.KanKan.THREE.Vector3().addVectors(control1.target, dir)
  227. control1.camera.position.copy(player1.position)
  228. }
  229. control1.camera.quaternion.copy(player1.quaternion)
  230. } */
  231. /* applyDiff(app, data) {
  232. //sourcePlayer -> targetPlayer
  233. let quaternion
  234. if (data.quaternion) {
  235. quaternion = new this.KanKan.THREE.Quaternion().copy(data.quaternion)
  236. data.quaternion = quaternion
  237. } else if (data.info && data.info.quaternion) {
  238. //飞出
  239. quaternion = new this.KanKan.THREE.Quaternion(data.info.quaternion._x, data.info.quaternion._y, data.info.quaternion._z, data.info.quaternion._w)
  240. data.info.quaternion = quaternion
  241. //let radius = data.info.position.distanceTo(data.info.target)
  242. }
  243. if (!quaternion) return
  244. if (app == this.sourceApp) {
  245. quaternion.premultiply(this.diffQuaternionInvert)
  246. } else {
  247. quaternion.premultiply(this.diffQuaternion)
  248. }
  249. if (data.info && data.info.quaternion) {
  250. //飞出
  251. let dir = new this.KanKan.THREE.Vector3().subVectors(data.info.position, data.info.target)
  252. dir.applyQuaternion(app == this.sourceApp ? this.diffQuaternionInvert : this.diffQuaternion)
  253. data.info.position = new this.KanKan.THREE.Vector3().addVectors(data.info.target, dir)
  254. }
  255. //先不管飞出后的位置平移
  256. //位置参照第一个漫游点。保持相机相对第一个漫游点的位移和
  257. } */
  258. }