华农3D项目
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

713 lines
22 KiB

2 months ago
  1. // 从这里开始
  2. var h1 = null
  3. var h2 = null
  4. var h3 = null
  5. var oldtransformNodex = null
  6. // var oldtransformNodeOther = null
  7. // var oldMesh = null
  8. var oldMeshOther = null
  9. var drag = null
  10. // var notmoveGroup = null
  11. // var movedGroup = null
  12. // var movesingle = false
  13. // var dynamicTexture = null
  14. // var dynamicTexture2 = null
  15. // var show = 50
  16. // var showdd = 50
  17. var isRotating = true
  18. var clickParentRotate = false
  19. var targetAngles = {
  20. default: { // 初始视角
  21. alpha: 0,
  22. beta: 0,
  23. radius: 120
  24. },
  25. alarm: { // 报警视角(示例)
  26. alpha: 1.5683, // -π(180度)
  27. beta: 0.0100, // π/4(45度)
  28. radius: 134 // 更近的距离
  29. }
  30. }
  31. var camera
  32. BABYLON.DefaultLoadingScreen.prototype.displayLoadingUI = function() {
  33. if (document.getElementById('customLoadingScreenDiv')) {
  34. document.getElementById('customLoadingScreenDiv').style.display = 'initial'
  35. return
  36. }
  37. this._loadingDiv = document.createElement('div')
  38. // this._loadingDiv.style.height = '1750px';
  39. this._loadingDiv.id = 'customLoadingScreenDiv'
  40. thecss = 'lohingifpc'
  41. thecss2 = 'zcpc'
  42. this._loadingDiv.innerHTML = "<div class='oka'><div class='" + thecss + "'><image src='./logok.gif' class='jiazaiimg'/></div></div>"
  43. this._resizeLoadingUI()
  44. window.addEventListener('resize', this._resizeLoadingUI)
  45. document.body.appendChild(this._loadingDiv)
  46. }
  47. // var movebyName = function(nodeName) {
  48. // var x = scene.getTransformNodeByName(nodeName)
  49. // moveTrans(x)
  50. // }
  51. function prepareGroupButton2(transformNodex, color, qu) {
  52. var mesheses = null
  53. // if (transformNodex.getClassName() === 'TransformNode') {
  54. // mesheses = transformNodex.getChildMeshes(false)
  55. // } else {
  56. // mesheses = []
  57. // mesheses.push(transformNodex)
  58. // }
  59. if (transformNodex.getClassName() === 'Mesh') {
  60. mesheses = []
  61. mesheses.push(transformNodex)
  62. }
  63. for (var i = 0; i < mesheses.length; i++) {
  64. mesheses[i].actionManager = new BABYLON.ActionManager(scene)
  65. // var theScaling = mesheses[i].scaling
  66. /* if (true) {
  67. try {
  68. mesheses[i].actionManager.registerAction(new BABYLON.InterpolateValueAction(BABYLON.ActionManager.OnPointerOutTrigger, mesheses[i], "scaling", new BABYLON.Vector3(theScaling.x, theScaling.y, theScaling.z), 100));
  69. mesheses[i].actionManager.registerAction(new BABYLON.InterpolateValueAction(BABYLON.ActionManager.OnPointerOverTrigger, mesheses[i], "scaling", new BABYLON.Vector3(theScaling.x * 1.01, theScaling.y * 1.01, theScaling.z * 1.01), 100));
  70. } catch (error) {
  71. //alert(error)
  72. }
  73. }*/
  74. // var clickbegin = false
  75. mesheses[i].actionManager.registerAction(
  76. new BABYLON.ExecuteCodeAction({
  77. trigger: BABYLON.ActionManager.OnPointerOverTrigger,
  78. parameter: ''
  79. },
  80. function() {
  81. // clickbegin = true
  82. // if (true) {
  83. // if (oldtransformNodeOther != null) {
  84. // oldtransformNodeOther.removeBehavior(drag)
  85. // var mesheses2 = null
  86. // if (oldtransformNodeOther.getClassName() === 'TransformNode') {
  87. // mesheses2 = oldtransformNodeOther.getChildMeshes(false)
  88. // } else {
  89. // mesheses2 = []
  90. // mesheses2.push(oldtransformNodeOther)
  91. // }
  92. // for (var i = 0; i < mesheses2.length; i++) {
  93. // try {
  94. // h2.removeMesh(mesheses2[i])
  95. // } catch (error) {
  96. // // alert(error)
  97. // }
  98. // }
  99. // }
  100. // oldtransformNodeOther = transformNodex
  101. // // transformNodex.addBehavior(drag);
  102. // var mesheses3 = null
  103. // if (transformNodex.getClassName() === 'TransformNode') {
  104. // mesheses3 = transformNodex.getChildMeshes(false)
  105. // } else {
  106. // mesheses3 = []
  107. // mesheses3.push(transformNodex)
  108. // }
  109. // for (var i = 0; i < mesheses3.length; i++) {
  110. // try {
  111. // h2.addMesh(mesheses3[i], color)
  112. // } catch (error) {
  113. // // alert(error)
  114. // }
  115. // }
  116. isRotating = false
  117. camera.useAutoRotationBehavior = isRotating
  118. // }
  119. }
  120. )
  121. )
  122. // 移出事件
  123. mesheses[i].actionManager.registerAction(
  124. new BABYLON.ExecuteCodeAction({
  125. trigger: BABYLON.ActionManager.OnPointerOutTrigger,
  126. parameter: ''
  127. },
  128. function() {
  129. // clickbegin = true
  130. // if (true) {
  131. // var mesheses4 = null
  132. // if (transformNodex.getClassName() === 'Mesh') {
  133. // mesheses4 = []
  134. // mesheses4.push(transformNodex)
  135. // }
  136. // for (var i = 0; i < mesheses4.length; i++) {
  137. // try {
  138. // h2.removeMesh(mesheses4[i])
  139. // } catch (error) {
  140. // // alert(error)
  141. // }
  142. // }
  143. // clickbegin = false
  144. if (clickParentRotate) {
  145. isRotating = true
  146. camera.useAutoRotationBehavior = isRotating
  147. }
  148. // }
  149. }
  150. )
  151. )
  152. mesheses[i].actionManager.registerAction(
  153. new BABYLON.ExecuteCodeAction({
  154. trigger: BABYLON.ActionManager.OnPickTrigger,
  155. parameter: ''
  156. },
  157. function() {
  158. clickbegin = true
  159. // if (true) {
  160. try {
  161. cameraClick(transformNodex)
  162. } catch (error) {
  163. // alert(error)
  164. }
  165. // clickbegin = false
  166. // }
  167. })
  168. )
  169. }
  170. }
  171. BABYLON.DefaultLoadingScreen.prototype.hideLoadingUI = function() {
  172. show = 50
  173. document.getElementById('customLoadingScreenDiv').style.display = 'none'
  174. document.getElementById('customLoadingScreenDiv_first').style.display = 'none'
  175. document.title = '水泵房'
  176. var prepareGroupButton2ByMesh = function(transformNodex, color, qu) {
  177. var mesheses = null
  178. if (transformNodex.getClassName() === 'Mesh') {
  179. mesheses = []
  180. mesheses.push(transformNodex)
  181. }
  182. for (var i = 0; i < mesheses.length; i++) {
  183. mesheses[i].actionManager = new BABYLON.ActionManager(scene)
  184. // var theScaling = mesheses[i].scaling
  185. /* if (true) {
  186. try {
  187. mesheses[i].actionManager.registerAction(new BABYLON.InterpolateValueAction(BABYLON.ActionManager.OnPointerOutTrigger, mesheses[i], "scaling", new BABYLON.Vector3(theScaling.x, theScaling.y, theScaling.z), 100));
  188. mesheses[i].actionManager.registerAction(new BABYLON.InterpolateValueAction(BABYLON.ActionManager.OnPointerOverTrigger, mesheses[i], "scaling", new BABYLON.Vector3(theScaling.x * 1.01, theScaling.y * 1.01, theScaling.z * 1.01), 100));
  189. } catch (error) {
  190. //alert(error)
  191. }
  192. }*/
  193. // let clickbegin = false
  194. mesheses[i].actionManager.registerAction(
  195. new BABYLON.ExecuteCodeAction({
  196. trigger: BABYLON.ActionManager.OnPointerOverTrigger,
  197. parameter: ''
  198. },
  199. function() {
  200. // clickbegin = true
  201. // if (true) {
  202. if (oldMeshOther != null) {
  203. oldMeshOther.removeBehavior(drag)
  204. var mesheses2 = null
  205. if (oldMeshOther.getClassName() === 'Mesh') {
  206. mesheses2 = []
  207. mesheses2.push(oldMeshOther)
  208. }
  209. for (var i = 0; i < mesheses2.length; i++) {
  210. try {
  211. h2.removeMesh(mesheses2[i])
  212. } catch (error) {
  213. // alert(error)
  214. }
  215. }
  216. }
  217. oldMeshOther = transformNodex
  218. // transformNodex.addBehavior(drag);
  219. var mesheses3 = null
  220. if (transformNodex.getClassName() === 'Mesh') {
  221. mesheses3 = []
  222. mesheses3.push(transformNodex)
  223. }
  224. for (let i = 0; i < mesheses3.length; i++) {
  225. try {
  226. h2.addMesh(mesheses3[i], color)
  227. } catch (error) {
  228. // alert(error)
  229. }
  230. }
  231. // clickbegin = false
  232. isRotating = false
  233. camera.useAutoRotationBehavior = isRotating
  234. // }
  235. }
  236. )
  237. )
  238. // 移出事件
  239. mesheses[i].actionManager.registerAction(
  240. new BABYLON.ExecuteCodeAction({
  241. trigger: BABYLON.ActionManager.OnPointerOutTrigger,
  242. parameter: ''
  243. },
  244. function() {
  245. // clickbegin = true
  246. // if (true) {
  247. var mesheses4 = null
  248. if (transformNodex.getClassName() === 'Mesh') {
  249. mesheses4 = []
  250. mesheses4.push(transformNodex)
  251. }
  252. for (var i = 0; i < mesheses4.length; i++) {
  253. try {
  254. h2.removeMesh(mesheses4[i])
  255. } catch (error) {
  256. // alert(error)
  257. }
  258. }
  259. // clickbegin = false
  260. if (clickParentRotate) {
  261. isRotating = true
  262. camera.useAutoRotationBehavior = isRotating
  263. }
  264. // }
  265. }
  266. )
  267. )
  268. mesheses[i].actionManager.registerAction(
  269. new BABYLON.ExecuteCodeAction({
  270. trigger: BABYLON.ActionManager.OnPickTrigger,
  271. parameter: ''
  272. },
  273. function() {
  274. // clickbegin = true
  275. // if (true) {
  276. try {
  277. // quClick(transformNodex.name)
  278. cameraClick(transformNodex)
  279. } catch (error) {
  280. // alert(error)
  281. }
  282. // clickbegin = false
  283. // }
  284. }
  285. )
  286. )
  287. }
  288. }
  289. // 绑功能点
  290. // var cl = new BABYLON.Color3(0, 0, 1)
  291. // var c2 = new BABYLON.Color3(1, 0, 0)
  292. var smokeAlarms = []
  293. scene.meshes.forEach(function(node) {
  294. if (node.name.startsWith('smokealarm')) {
  295. smokeAlarms.push(node)
  296. }
  297. })
  298. // 对 smokeAlarms 数组按照 name 进行排序
  299. smokeAlarms.sort(function(a, b) {
  300. var numA = parseInt(a.name.split('smokealarm.')[1])
  301. var numB = parseInt(b.name.split('smokealarm.')[1])
  302. return numA - numB
  303. })
  304. var length = smokeAlarms.length
  305. console.log('以 smokealarm 开头的对象数量:', length)
  306. smokeAlarms.forEach(function(jk01, index) {
  307. // console.log('smokeAlarms', jk01)
  308. var parts = jk01.name.split('smokealarm')
  309. if (parts.length > 1) {
  310. const paddedIndex = String(index + 1).padStart(3, '0')
  311. jk01.nameID = `S${paddedIndex}`
  312. } else {
  313. jk01.nameID = 'S000'
  314. }
  315. jk01.baojing = false
  316. prepareGroupButton2(jk01)
  317. })
  318. // 存储所有 camera 相关的 Mesh
  319. const cameraMeshes = []
  320. scene.meshes.forEach(mesh => {
  321. if (mesh.name.startsWith('camera')) {
  322. cameraMeshes.push(mesh)
  323. }
  324. })
  325. const cameraCount = cameraMeshes.length
  326. console.log('以 camera 开头的 Mesh 数量:', cameraCount)
  327. // 定义颜色
  328. // const colorRed = new BABYLON.Color3(1, 0, 0) // 红
  329. const colorBlue = new BABYLON.Color3(0, 0, 1)
  330. cameraMeshes.forEach((cam, index) => {
  331. const paddedIndex = String(index + 1).padStart(3, '0')
  332. cam.nameID = `C${paddedIndex}`
  333. prepareGroupButton2ByMesh(cam, colorBlue, '摄像头1')
  334. })
  335. // var light = new BABYLON.HemisphericLight('HemiLight', new BABYLON.Vector3(0, 1, 0), scene)
  336. // light.intensity = 2 //光的强度设置为 2,强度值越高,光照就越强
  337. // light.diffuse = new BABYLON.Color3(0.92, 0.92, 0.92) // 光的漫反射颜色设置为接近白色的颜色
  338. // 给vue页面传值,加载完成之后
  339. parent.getIframeLoading('false')
  340. }
  341. BABYLON.DracoCompression.Configuration.decoder.wasmUrl = './js/draco_wasm_wrapper_gltf.js'
  342. BABYLON.DracoCompression.Configuration.decoder.wasmBinaryUrl = './js/draco_decoder_gltf.wasm'
  343. BABYLON.DracoCompression.Configuration.decoder.fallbackUrl = './js/draco_decoder_gltf.js'
  344. // createScene function that creates and return the scene
  345. var createScene = function() {
  346. engine.displayLoadingUI()
  347. // var scene = new BABYLON.Scene(engine)
  348. // camera = new BABYLON.ArcRotateCamera('Camera', 0, 0, 5, new BABYLON.Vector3(0, -1, 0), scene)
  349. // camera.setTarget(new BABYLON.Vector3(0, 0, 0))
  350. // camera.attachControl(canvas, true)
  351. var scene = new BABYLON.Scene(engine)
  352. camera = new BABYLON.ArcRotateCamera(
  353. 'Camera', 0, 0, 134, // alpha=0(水平角度),beta=90°(垂直俯视),radius=200(距离)
  354. new BABYLON.Vector3(0, 0, 0), // 相机位置会根据 alpha/beta/radius 自动计算,无需手动设置
  355. scene
  356. )
  357. camera.setTarget(new BABYLON.Vector3(0, 0, 0)) // 瞄准原点
  358. camera.attachControl(canvas, true)
  359. camera.lowerRadiusLimit = 5.0 // 这里是最大的位置,值越大,物体越小
  360. camera.upperRadiusLimit = 200
  361. camera.inertia = 0.1 // 缩放的快慢
  362. camera.useAutoRotationBehavior = isRotating // 自动旋转
  363. // 改变场景背景颜色 - 背景颜色opacity值设为0,达到透明背景的效果
  364. scene.clearColor = new BABYLON.Color4(0, 0, 0, 0)
  365. scene.activeCamera = camera
  366. scene.activeCamera.useInputToRestoreState = true
  367. // var camera1_status = scene.activeCamera.storeState()
  368. var assetsManager = new BABYLON.AssetsManager(scene)
  369. // var meshTask = assetsManager.addMeshTask('skull task', '', 'asset/', 'F5.glb')
  370. // meshTask.onSuccess = function(task) {
  371. // task.loadedMeshes[0].scaling = new BABYLON.Vector3(0.4, 0.4, 0.4)
  372. // task.loadedMeshes[0].position = new BABYLON.Vector3(0, 0.35, 0)
  373. // }
  374. // meshTask.onError = function(task, message, exception) {
  375. // console.log(message, exception)
  376. // }
  377. // 加载GLB模型并处理材质
  378. BABYLON.SceneLoader.LoadAssetContainerAsync('asset/', 'F5.glb', scene).then((container) => {
  379. // 遍历所有材质
  380. container.materials.forEach(material => {
  381. // 处理标准材质
  382. if (material instanceof BABYLON.StandardMaterial) {
  383. material.backFaceCulling = true // 启用背面剔除
  384. }
  385. // 处理PBR材质
  386. // if (material instanceof BABYLON.PBRMaterial) {
  387. // material.backFaceCulling = true // 启用背面剔除
  388. // }
  389. })
  390. // 将加载的资产添加到场景中
  391. container.addAllToScene()
  392. setTimeout(() => {
  393. moveCameraTo('alarm')
  394. }, 3000)
  395. }).catch((error) => {
  396. console.error('加载模型时出错:', error)
  397. })
  398. var hdrTexture = new BABYLON.CubeTexture.CreateFromPrefilteredData('textures/environmentSpecular.env', scene)
  399. scene.environmentTexture = hdrTexture
  400. var spriteManagerPlayer = new BABYLON.SpriteManager('playerManager', './img/bl9.png', 10, {
  401. width: 100,
  402. height: 100
  403. }, scene)
  404. // spriteManagerPlayer.renderingGroupId = 2;
  405. spriteManagerPlayer.isPickable = true
  406. scene.onPointerDown = function(evt) {
  407. var pickResult = scene.pickSprite(this.pointerX, this.pointerY)
  408. var pick = scene.pick(scene.pointerX, scene.pointerY)
  409. console.log('pick', pick.pickedPoint)
  410. if (pickResult.pickedSprite != null) {
  411. if (pickResult.hit) {
  412. alert(pickResult.pickedSprite.name)
  413. }
  414. }
  415. }
  416. // renderCanvas.style.backgroundImage = 'url("./textures/' + '4' + '.jpg")'
  417. assetsManager.load()
  418. drag = new BABYLON.PointerDragBehavior({
  419. dragPlaneNormal: new BABYLON.Vector3(0, 0, 1)
  420. })
  421. // drag.useObjectOrienationForDragging = false;
  422. drag.validateDrag = (targetPosition) => {
  423. if (targetPosition.x > 10.5 || targetPosition.x < -10.5) {
  424. return false
  425. }
  426. if (targetPosition.z > 10.5 || targetPosition.z < -10.5) {
  427. return false
  428. }
  429. if (oldtransformNodex != null) {
  430. return true
  431. }
  432. }
  433. drag.onDragEndObservable.add((event) => {
  434. // console.log("dragEnd");
  435. // console.log(event);
  436. // console.log(line03_position)
  437. })
  438. // GUI
  439. h1 = new BABYLON.HighlightLayer('hl1', scene)
  440. h2 = new BABYLON.HighlightLayer('hl2', scene)
  441. h3 = new BABYLON.HighlightLayer('hl2', scene)
  442. var step = 0.1
  443. var currentx = 1
  444. // var step2 = 0.1
  445. // var currentx2 = 0.1
  446. h1.blurHorizontalSize = 0.1
  447. // var showx = 0
  448. // var showx2 = 2
  449. // console.log("x4");
  450. scene.registerAfterRender(() => {
  451. h1.blurHorizontalSize = h1.blurVerticalSize + currentx
  452. var nodealert = scene.getTransformNodeByName('yan')
  453. if (nodealert != null) {
  454. var mesheses3 = null
  455. if (nodealert.getClassName() === 'TransformNode') {
  456. mesheses3 = nodealert.getChildMeshes(false)
  457. } else {
  458. mesheses3 = []
  459. mesheses3.push(nodealert)
  460. }
  461. for (var i = 0; i < mesheses3.length; i++) {
  462. try {
  463. if (nodealert.baojing === true) {
  464. h3.addMesh(mesheses3[i], new BABYLON.Color3(1, 0, 0))
  465. } else {
  466. h3.removeMesh(mesheses3[i])
  467. }
  468. } catch (error) {
  469. // alert(error)
  470. }
  471. }
  472. }
  473. })
  474. if (currentx > 0.5) {
  475. step *= -1
  476. }
  477. if (currentx < 0) {
  478. step *= -1
  479. }
  480. currentx += step
  481. return scene
  482. }
  483. var canvas = document.getElementById('renderCanvas')
  484. // load the 3D engine
  485. var engine = new BABYLON.Engine(canvas, true, {
  486. stencil: true
  487. })
  488. // call the createScene function
  489. var scene = createScene()
  490. scene.autoClear = true
  491. scene.imageProcessingConfiguration.exposure = 1
  492. scene.imageProcessingConfiguration.contrast = 1
  493. scene.environmentIntensity = 0.4
  494. engine.runRenderLoop(function() {
  495. scene.render()
  496. })
  497. window.addEventListener('resize', function() {
  498. engine.resize()
  499. })
  500. // 功能转入报警
  501. // function Myalert(MathineID, baojingx) {
  502. // var theName = yangans.get(MathineID)
  503. // if (theName === 'yan') {
  504. // // console.log(scene);
  505. // xx = scene.getTransformNodeByName('yan').baojing = baojingx
  506. // }
  507. // }
  508. // scene.debugLayer.show();
  509. // 报警 true:表示报警, false :表示不报警
  510. function cameraClick(TheCamera) {
  511. window.parent.postMessage(
  512. {
  513. type: 'cameraClick',
  514. data: TheCamera.nameID
  515. },
  516. '*'
  517. )
  518. }
  519. function handleAlarm(deviceId, isAlarm) {
  520. var cl = new BABYLON.Color3(0, 0, 1)
  521. var c2 = new BABYLON.Color3(1, 0, 0)
  522. console.log('scene', scene)
  523. const targetDevice = scene.meshes.find(node => node.nameID === deviceId)
  524. console.log('targetDevice', targetDevice)
  525. if (targetDevice) {
  526. targetDevice.baojing = isAlarm
  527. let mesheses
  528. if (targetDevice.getClassName() === 'TransformNode') {
  529. mesheses = targetDevice.getChildMeshes(false)
  530. } else {
  531. mesheses = [targetDevice]
  532. }
  533. console.log('targetDevice.getClassName()', targetDevice.getClassName())
  534. if (isAlarm) {
  535. console.log('111')
  536. for (var i = 0; i < mesheses.length; i++) {
  537. h2.addMesh(mesheses[i], c2)
  538. }
  539. } else {
  540. console.log('222')
  541. for (var j = 0; j < mesheses.length; j++) {
  542. h2.removeMesh(mesheses[j])
  543. h2.addMesh(mesheses[j], cl)
  544. }
  545. }
  546. } else {
  547. console.log(`未找到设备 ID 为 ${deviceId} 的设备`)
  548. }
  549. }
  550. window.addEventListener(
  551. 'message',
  552. function(e) {
  553. if (e.data.type === 'deviceState') {
  554. console.log('ddd', e.data.data)
  555. const deviceData = e.data.data
  556. if (Array.isArray(deviceData)) {
  557. deviceData.forEach((device) => {
  558. handleAlarm(device.deviceId, device.isAlarm)
  559. })
  560. } else {
  561. handleAlarm(deviceData.deviceId, deviceData.isAlarm)
  562. }
  563. } else if (e.data.type === 'isGetRotate') {
  564. const isGetRotate = e.data.value
  565. console.log('isGetRotate:', isGetRotate)
  566. // 这里可以添加处理 isGetRotate 的逻辑
  567. toggleAutoRotation(isGetRotate)
  568. }
  569. },
  570. false
  571. )
  572. function toggleAutoRotation(isAutoRotating) {
  573. var camera = scene.activeCamera
  574. clickParentRotate = !isAutoRotating
  575. if (!isAutoRotating) {
  576. // 启用自动旋转
  577. camera.useAutoRotationBehavior = true
  578. } else {
  579. // 禁用自动旋转
  580. camera.useAutoRotationBehavior = false
  581. camera.angularSpeed = 0 // 停止旋转
  582. }
  583. }
  584. // 相机运动到指定视角(带动画)
  585. function moveCameraTo(targetPreset) {
  586. // 获取目标参数
  587. var target = targetAngles[targetPreset]
  588. if (!target) return console.error('无效的视角预设')
  589. var camera = scene.activeCamera
  590. // 禁用用户交互(可选)
  591. camera.panningInertia = 0 // 禁止平移
  592. // 创建并设置动画
  593. var animationAlpha = new BABYLON.Animation(
  594. 'cameraAlphaAnimation',
  595. 'alpha',
  596. 60, // 帧率
  597. BABYLON.Animation.ANIMATIONTYPE_FLOAT,
  598. BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT
  599. )
  600. var animationBeta = new BABYLON.Animation(
  601. 'cameraBetaAnimation',
  602. 'beta',
  603. 60, // 帧率
  604. BABYLON.Animation.ANIMATIONTYPE_FLOAT,
  605. BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT
  606. )
  607. var animationRadius = new BABYLON.Animation(
  608. 'cameraRadiusAnimation',
  609. 'radius',
  610. 60, // 帧率
  611. BABYLON.Animation.ANIMATIONTYPE_FLOAT,
  612. BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT
  613. )
  614. // 定义关键帧
  615. var keysAlpha = [
  616. { frame: 0, value: camera.alpha },
  617. { frame: 120, value: target.alpha }
  618. ]
  619. var keysBeta = [
  620. { frame: 0, value: camera.beta },
  621. { frame: 120, value: target.beta }
  622. ]
  623. var keysRadius = [
  624. { frame: 0, value: camera.radius },
  625. { frame: 120, value: target.radius }
  626. ]
  627. animationAlpha.setKeys(keysAlpha)
  628. animationBeta.setKeys(keysBeta)
  629. animationRadius.setKeys(keysRadius)
  630. // 设置缓动函数
  631. var easingFunction = new BABYLON.CubicEase()
  632. easingFunction.setEasingMode(BABYLON.EasingFunction.EASINGMODE_EASEINOUT)
  633. animationAlpha.setEasingFunction(easingFunction)
  634. animationBeta.setEasingFunction(easingFunction)
  635. animationRadius.setEasingFunction(easingFunction)
  636. // 开始动画
  637. scene.beginDirectAnimation(camera, [animationAlpha, animationBeta, animationRadius], 0, 120, false, 1, function() {
  638. // 动画完成后恢复用户交互
  639. camera.panningInertia = 0.1
  640. toggleAutoRotation(true)
  641. window.parent.postMessage({ type: 'autoRotationStatus', value: true }, '*')
  642. })
  643. }