diff --git a/public/images/fire.png b/public/images/fire.png new file mode 100644 index 000000000..c826c442a Binary files /dev/null and b/public/images/fire.png differ diff --git a/public/models/导弹整体.glb b/public/models/导弹整体.glb new file mode 100644 index 000000000..3ebecbca7 Binary files /dev/null and b/public/models/导弹整体.glb differ diff --git a/public/models/第一级.glb b/public/models/第一级.glb new file mode 100644 index 000000000..789b1258e Binary files /dev/null and b/public/models/第一级.glb differ diff --git a/public/models/第三级.glb b/public/models/第三级.glb new file mode 100644 index 000000000..8361cabcf Binary files /dev/null and b/public/models/第三级.glb differ diff --git a/public/models/第二级.glb b/public/models/第二级.glb new file mode 100644 index 000000000..72eed3a09 Binary files /dev/null and b/public/models/第二级.glb differ diff --git a/public/models/美三叉戟2动画.glb b/public/models/美三叉戟2动画.glb new file mode 100644 index 000000000..9c302db23 Binary files /dev/null and b/public/models/美三叉戟2动画.glb differ diff --git a/public/models/美三叉戟2整体.glb b/public/models/美三叉戟2整体.glb new file mode 100644 index 000000000..bb3e291f4 Binary files /dev/null and b/public/models/美三叉戟2整体.glb differ diff --git a/public/models/美三叉戟2第一级.glb b/public/models/美三叉戟2第一级.glb new file mode 100644 index 000000000..7600b82fc Binary files /dev/null and b/public/models/美三叉戟2第一级.glb differ diff --git a/public/models/美三叉戟2第三级.glb b/public/models/美三叉戟2第三级.glb new file mode 100644 index 000000000..c6f6b06f8 Binary files /dev/null and b/public/models/美三叉戟2第三级.glb differ diff --git a/public/models/美三叉戟2第二级.glb b/public/models/美三叉戟2第二级.glb new file mode 100644 index 000000000..405549f3a Binary files /dev/null and b/public/models/美三叉戟2第二级.glb differ diff --git a/src/js/Explosion.js b/src/js/Explosion.js index b66ac6027..b15b554bc 100644 --- a/src/js/Explosion.js +++ b/src/js/Explosion.js @@ -2,6 +2,15 @@ export default class ExplosionEffect { constructor(viewer, obj) { this.viewer = viewer this.viewModel = { + // emissionRate: 5, + // gravity: 0.0, //设置重力参数 + // minimumParticleLife: 1, + // maximumParticleLife: 6, + // minimumSpeed: 1.0, //粒子发射的最小速度 + // maximumSpeed: 4.0, //粒子发射的最大速度 + // startScale: 0.0, + // endScale: 8.0, + // particleSize: 25.0, emissionRate: 5, gravity: 0.0, //设置重力参数 minimumParticleLife: 1, @@ -10,7 +19,7 @@ export default class ExplosionEffect { maximumSpeed: 4.0, //粒子发射的最大速度 startScale: 0.0, endScale: 8.0, - particleSize: 25.0, + particleSize: 10.0, } this.emitterModelMatrix = new Cesium.Matrix4() this.translation = new Cesium.Cartesian3() @@ -33,7 +42,8 @@ export default class ExplosionEffect { // this.viewer.trackedEntity = this.entity; let particleSystem = this.scene.primitives.add( new Cesium.ParticleSystem({ - image: './images/explosion.png', //生成所需粒子的图片路径 + // image: './images/explosion.png', //生成所需粒子的图片路径 + image: './images/fire.png', //生成所需粒子的图片路径 //粒子在生命周期开始时的颜色 startColor: Cesium.Color.RED.withAlpha(0.7), //粒子在生命周期结束时的颜色 @@ -61,14 +71,33 @@ export default class ExplosionEffect { lifetime: 16.0, //设置粒子的大小是否以米或像素为单位 sizeInMeters: false, + // sizeInMeters: true, //系统的粒子发射器 - emitter: new Cesium.CircleEmitter(5.0), //BoxEmitter 盒形发射器,ConeEmitter 锥形发射器,SphereEmitter 球形发射器,CircleEmitter圆形发射器 + // emitter: new Cesium.CircleEmitter(5.0), //BoxEmitter 盒形发射器,ConeEmitter 锥形发射器,SphereEmitter 球形发射器,CircleEmitter圆形发射器 + emitter: new Cesium.CircleEmitter(2.0), //BoxEmitter 盒形发射器,ConeEmitter 锥形发射器,SphereEmitter 球形发射器,CircleEmitter圆形发射器 + //回调函数,实现各种喷泉、烟雾效果 + updateCallback: (p, dt) => { + return this.applyGravity(p, dt) + }, }) ) this.particleSystem = particleSystem this.preUpdateEvent() } + applyGravity(p, dt) { + let gravityScratch = new Cesium.Cartesian3() + let position = p.position + Cesium.Cartesian3.normalize(position, gravityScratch) + Cesium.Cartesian3.fromElements( + 20 * dt, + 30 * dt, + gravityScratch.y * dt, + gravityScratch + ) + p.velocity = Cesium.Cartesian3.add(p.velocity, gravityScratch, p.velocity) + } + //场景渲染事件 preUpdateEvent() { let _this = this diff --git a/src/utils/pos.js b/src/utils/pos.js index 72bb41bf3..3e8142a6c 100644 --- a/src/utils/pos.js +++ b/src/utils/pos.js @@ -32,6 +32,107 @@ export function getPositionFromTime( return points } +export function getOnePositionFromTime(startTime, i, pos) { + const time = Cesium.JulianDate.addSeconds( + startTime, + i, + new Cesium.JulianDate() + ) + const point = pos.getValue(time) + return point +} + export function getBezierSpline(points) { return bezierSpline(lineString(points)) } + +export async function test() { + const points = createTrajectory( + [137, 25, 0, 1183135285000], + [140, 27, 100000, 1183135295000] + ).map(point => { + // const point = getTrajectoryPoint(i) + console.log(point) + // console.log( + // `t=${point.time}s, lon=${point.longitude.toFixed( + // 3 + // )}, lat=${point.latitude.toFixed(3)}, alt=${point.altitude.toFixed(2)}m` + // ) + return [point.lon, point.lat, point.alt] + }) + // const points = a.map(item => { + // return [item.lon, item.lat, item.alt] + // }) + viewer.entities.add({ + name: 'line', + polyline: { + positions: Cesium.Cartesian3.fromDegreesArrayHeights( + points.flat(Infinity) + ), + width: 10, + material: new Cesium.PolylineGlowMaterialProperty({ + glowPower: 0.1, + color: Cesium.Color.RED, + }), + }, + }) +} + +export function createTrajectory(p1, p2, options = {}) { + const { + steps = 20, + useStartAsPeak = false, + useEndAsPeak = false, + peakBias = 0.3, // 控制曲率偏向:0.5 表示中点;靠近 0 表示更靠近起点 + midOffset = 1000, + } = options + + const [lon1, lat1, alt1, t1] = p1 + const [lon2, lat2, alt2, t2] = p2 + + const dt = (t2 - t1) / 1000 // 秒 + const tPeak = + dt * (useEndAsPeak ? 1 - peakBias : useStartAsPeak ? peakBias : 0.5) + + // 设置高度 + let h0 = alt1 + let h2 = alt2 + let h1 + + if (useStartAsPeak) { + h1 = (alt1 + alt2) / 2 - midOffset + } else if (useEndAsPeak) { + h1 = (alt1 + alt2) / 2 - midOffset + } else { + h1 = Math.max(alt1, alt2) + midOffset + } + + // 三点拟合抛物线 + const c = h0 + const A = [ + [tPeak ** 2, tPeak], + [dt ** 2, dt], + ] + const B = [h1 - c, h2 - c] + + const denom = A[0][0] * A[1][1] - A[0][1] * A[1][0] + const a = (B[0] * A[1][1] - B[1] * A[0][1]) / denom + const b = (A[0][0] * B[1] - A[1][0] * B[0]) / denom + + const result = [] + + for (let i = 0; i <= steps; i++) { + const t = (dt * i) / steps + const fraction = t / dt + + const lon = lon1 + (lon2 - lon1) * fraction + const lat = lat1 + (lat2 - lat1) * fraction + const alt = a * t * t + b * t + c + + result.push({ t: t1 + t * 1000, lon, lat, alt }) + } + + return result +} + +// 示例:每秒插值 diff --git a/src/views/Daodan/components/TestConfig.jsx b/src/views/Daodan/components/TestConfig.jsx index 416734a20..affb3bbc2 100644 --- a/src/views/Daodan/components/TestConfig.jsx +++ b/src/views/Daodan/components/TestConfig.jsx @@ -9,8 +9,14 @@ const panels = ['手动配置', 'STK轨迹文件配置'] export default defineComponent({ setup() { const { daodanData, showOrHideDdConfig } = useDaodan() - const { trajData, interceptData, loadStoreData, addIntercept, initDaodan } = - useTestConfig() + const { + trajData, + boosterList, + interceptData, + loadStoreData, + addIntercept, + initDaodan, + } = useTestConfig() watch(daodanData, newval => { loadStoreData() @@ -54,8 +60,19 @@ export default defineComponent({
{panel === '手动配置' ? ( <> -
- +
+ + {boosterList.value.map((booster, index) => ( + + ))}
{interceptData.value.map(data => ( @@ -63,6 +80,7 @@ export default defineComponent({ title="拦截" data={data} onRemoveIntercept={removeIntercept} + showPosIcon={false} /> ))}
@@ -75,6 +93,9 @@ export default defineComponent({ ) : ( <> + + + )} diff --git a/src/views/Daodan/components/TrajTable.jsx b/src/views/Daodan/components/TrajTable.jsx index 21b293b3e..d1c68a85f 100644 --- a/src/views/Daodan/components/TrajTable.jsx +++ b/src/views/Daodan/components/TrajTable.jsx @@ -38,7 +38,7 @@ export default defineComponent({ render(row) { return (
-
{row.name}
+
{row.name}
{props.showPosIcon && ( - ) : ( - '-' - ) - }, - }, - { - title: '操作', - render(row, rowIndex) { - return rowIndex !== 0 && rowIndex < trajData.value.length - 1 ? ( - ( - - - - ), - }} - onClick={() => { - trajData.value.splice(rowIndex, 1) - }} - > - ) : ( - '-' - ) - }, - }, ] - const addFeaturePoint = () => { - trajData.value.splice(trajData.value.length - 1, 0, { - name: '中间特征点', - lon: 0, - lat: 0, - alt: 0, - time: Date.now(), - detached: false, - }) + function getTitle(key) { + const isIntercept = props.title.indexOf('拦截') > -1 + const isBooster = props.title.indexOf('助推器') > -1 + + const dict = { + time: isIntercept ? '命中时间' : isBooster ? '脱离时间' : '时间', + lat: isIntercept ? '发射纬度' : isBooster ? '落点纬度' : '纬度', + lon: isIntercept ? '发射经度' : isBooster ? '落点经度' : '经度', + alt: '高度', + } + return dict[key] || key } + + if (props.title.indexOf('助推器') > -1) { + columns.splice(3, 1) + } else if (props.title.indexOf('拦截') > -1) { + columns.splice(3, 1) + } + const dialog = useDialog() const remove = () => { dialog.warning({ @@ -180,9 +155,6 @@ export default defineComponent({
{props.title}
- - 添加特征点 - {props.title.indexOf('拦截') > -1 && ( 删除拦截 diff --git a/src/views/Daodan/components/hooks/testHooks.jsx b/src/views/Daodan/components/hooks/testHooks.jsx index c8fe6edbd..53c1a0847 100644 --- a/src/views/Daodan/components/hooks/testHooks.jsx +++ b/src/views/Daodan/components/hooks/testHooks.jsx @@ -1,12 +1,20 @@ import { ref, toRaw } from 'vue' import { useDaodan } from '../../ddHooks' -import { cartesian32LonLat, getPositionFromTime } from '@/utils/pos' +import { + cartesian32LonLat, + getPositionFromTime, + getOnePositionFromTime, + test, + createTrajectory, +} from '@/utils/pos' import ExplosionEffect from '@/js/Explosion' import { generateId } from '@/utils/id' import store from 'store2' -// import { getPositionFromTime } from '@/utils/pos' +import { lineString, bezierSpline } from '@turf/turf' // import { useDaodan } from '../../ddHooks' +const ddScale = 30 + const trajData = ref({ id: 'dd', data: [ @@ -18,63 +26,69 @@ const trajData = ref({ time: 1183135260000, }, { - name: '中间特征点', - lon: 122, - lat: 21, - alt: 1000000, - time: 1183135265000, - detached: true, - }, - { - name: '中间特征点', - lon: 124, - lat: 21, - alt: 1500000, - time: 1183135270000, - detached: true, - }, - { - name: '中间特征点', - lon: 128, - lat: 21, + name: '最高点', + lon: 125, + lat: 25, alt: 2000000, time: 1183135280000, - detached: true, }, { name: '落点', - lon: 135, - lat: 21, - alt: 1500000, - time: 1183135290000, + lon: 160, + lat: 40, + alt: 0, + time: 1183135300000, }, ], }) -const interceptData = ref([ +const boosterList = ref([ { - id: 'dd1', + id: 'booster-1', data: [ { - name: '起始点', - lon: 137, - lat: 25, + // name: '落点', + lon: 130, + lat: 23, + alt: 0, + time: 1183135265000, + }, + ], + }, + { + id: 'booster-2', + data: [ + { + // name: '落点', + lon: 135, + lat: 28, alt: 0, time: 1183135270000, }, + ], + }, + { + id: 'booster-3', + data: [ { - name: '中间特征点', - lon: 138, - lat: 24, - alt: 1000000, - time: 1183135280000, - detached: true, + // name: '落点', + lon: 140, + lat: 35, + alt: 0, + time: 1183135275000, }, + ], + }, +]) +const interceptData = ref([ + { + id: 'intercept-1', + data: [ { - name: '落点', - lon: 135, - lat: 21, - alt: 1500000, - time: 1183135290000, + // name: '起始点', + lon: 137, + lat: 25, + alt: 0, + time: 1183135285000, }, ], }, @@ -85,6 +99,7 @@ const { daodanData, showDdConfigCom } = useDaodan() export function useTestConfig() { return { trajData, + boosterList, interceptData, loadStoreData, addIntercept, @@ -94,13 +109,16 @@ export function useTestConfig() { } function saveDataToStore() { + // test() const daodanDataRaw = toRaw(daodanData.value) const storeData = store.get('daodanData') + store.set('daodanData', { ...storeData, [daodanDataRaw.id]: { ...daodanDataRaw, trajData: trajData.value, + boosterList: boosterList.value, interceptData: interceptData.value, }, }) @@ -174,20 +192,23 @@ function addDaodan(trajData, type = 0) { ddTrajData[0].alt ) const hpRoll = new Cesium.HeadingPitchRoll() + // const fixedFrameTransform = Cesium.Transforms.eastNorthUpToFixedFrame const fixedFrameTransform = Cesium.Transforms.localFrameToFixedFrameGenerator( 'north', 'west' ) - hpRoll.pitch = (90 * Math.PI) / 180 + // hpRoll.pitch = (90 * Math.PI) / 180 const modelObj = Cesium.Model.fromGltf({ - url: './models/launchvehicle.glb', + // url: './models/launchvehicle.glb', + url: './models/美三叉戟2动画.glb', modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame( position, hpRoll, Cesium.Ellipsoid.WGS84, fixedFrameTransform ), - minimumPixelSize: 70, + scale: ddScale, + minimumPixelSize: ddScale, }) const ddPrimitive = viewer.scene.primitives.add(modelObj) @@ -210,17 +231,16 @@ function addDaodan(trajData, type = 0) { // }) ddPrimitive.readyPromise.then(model => { + console.log('model', model) nodes = model.pickIds.map(item => item.object.detail.node) - nodes.forEach(i => { - // console.log(i._name, model.getNode(i._name)) - if (new RegExp(/SRB\d/).test(i._name)) { - model.getNode(i._name).show = false - } - }) + console.log('nodes', nodes) + // nodes.forEach(i => { + // // console.log(i._name, model.getNode(i._name)) + // if (new RegExp(/SRB\d/).test(i._name)) { + // model.getNode(i._name).show = false + // } + // }) computePath(ddPrimitive, trajData, type) - // setTimeout(() => { - // playDaodan(ddPrimitive, nodes) - // }, 3000) }) } @@ -229,16 +249,16 @@ function initDaodan() { saveDataToStore() minTime = getMinTime([ ...toRaw(trajData.value.data), - ...toRaw(interceptData.value.map(item => toRaw(item.data))).flat(Infinity), + // ...toRaw(interceptData.value.map(item => toRaw(item.data))).flat(Infinity), ]) // console.log(minTime) addDaodan(trajData.value) aniIndexMap.set(trajData.value.id, 0) - interceptData.value.forEach(item => { - const { id, data } = item - addDaodan(item, 1) - aniIndexMap.set(id, 0) - }) + // interceptData.value.forEach(item => { + // const { id, data } = item + // addDaodan(item, 1) + // aniIndexMap.set(id, 0) + // }) } function getMinTime(data) { @@ -249,14 +269,16 @@ function getMinTime(data) { return minTime } +const pathLine = new Map() + function computePath(daodan, trajData, type) { - const { data: ddTrajData } = trajData + const { id, data: ddTrajData } = trajData const points = ddTrajData.map(item => { - const { time, lon, lat, alt, detached } = item + const { time, lon, lat, alt } = item + return { position: Cesium.Cartesian3.fromDegrees(lon, lat, alt), time: time - minTime, - detached, } }) const totalAnimationTime = points.at(-1).time @@ -270,13 +292,13 @@ function computePath(daodan, trajData, type) { point.time / 1000, new Cesium.JulianDate() ) - viewer.entities.add({ - position: point.position, - point: { - color: Cesium.Color.WHITE, - pixelSize: 5, - }, - }) + // const point = viewer.entities.add({ + // position: point.position, + // point: { + // color: Cesium.Color.WHITE, + // pixelSize: 5, + // }, + // }) positionProperty.addSample(time, point.position) }) positionProperty.setInterpolationOptions({ @@ -285,7 +307,28 @@ function computePath(daodan, trajData, type) { // interpolationDegree: 5, // interpolationAlgorithm: Cesium.LagrangePolynomialApproximation, }) - createLine({ totalAnimationTime, startTime, positionProperty, type }) + const line = createLine({ + totalAnimationTime, + startTime, + positionProperty, + type, + }) + + pathLine.set(id, line) + if (type === 0) { + computeBoosterOrInterceptPath({ + dataList: boosterList.value, + startTime, + positionProperty, + type: 'booster', + }) + computeBoosterOrInterceptPath({ + dataList: interceptData.value, + startTime, + positionProperty, + type: 'intercept', + }) + } daodanAnimation({ totalAnimationTime, startTime, @@ -295,11 +338,140 @@ function computePath(daodan, trajData, type) { }) } +const boosterMap = new Map() +const interceptMap = new Map() +const interceptTime = ref() +function computeBoosterOrInterceptPath({ + dataList, + startTime, + positionProperty, + type, +}) { + dataList.forEach((dataItem, index) => { + const { id, data } = dataItem + let points = [] + data.forEach(item => { + const { time, lon, lat, alt } = item + + const position = getOnePositionFromTime( + startTime, + (time - minTime) / 1000, + positionProperty + ) + + // points.push({ + // position, + // time: time - minTime, + // }) + + const lonlat = cartesian32LonLat(position) + + const pointTime = time - minTime + + const aniPointTime = pointTime + (type === 'booster' ? 10000 : -10000) + type === 'intercept' && (interceptTime.value = pointTime / 1000) + const pointInline = { + position: Cesium.Cartesian3.fromDegrees(lon, lat, alt), + time: aniPointTime, + } + // points.push(pointInline) + + points = createTrajectory( + [lon, lat, alt, aniPointTime], + [...lonlat, time - minTime], + { + useEndAsPeak: true, + peakBias: 0.65, + midOffset: 1000, + } + ).map(item => { + return { + position: Cesium.Cartesian3.fromDegrees(item.lon, item.lat, item.alt), + time: item.t, + } + }) + }) + + const dataPositionProperty = new Cesium.SampledPositionProperty() + points.forEach(point => { + const time = Cesium.JulianDate.addSeconds( + startTime, + point.time / 1000, + new Cesium.JulianDate() + ) + + // viewer.entities.add({ + // position: point.position, + // point: { + // color: Cesium.Color.ORANGE, + // pixelSize: 5, + // }, + // }) + dataPositionProperty.addSample(time, point.position) + }) + dataPositionProperty.setInterpolationOptions({ + interpolationDegree: 2, + interpolationAlgorithm: Cesium.HermitePolynomialApproximation, + }) + + const dataLine = createLine({ + totalAnimationTime: points.at(-1).time, + startTime, + positionProperty: dataPositionProperty, + type: 2, + color: type === 'booster' ? 'ORANGE' : 'RED', + }) + + const modelUrl = + type === 'booster' + ? `./models/美三叉戟2第${['一', '二', '三'][index]}级.glb` + : './models/美三叉戟2动画.glb' + + dataLine.model = { + show: true, + uri: modelUrl, + runAnimations: false, + // uri: `./models/第${['一', '二', '三'][index]}级.glb`, + scale: type === 'booster' ? ddScale / 4 : ddScale, + minimumPixelSize: type === 'booster' ? ddScale / 4 : ddScale, + } + dataLine.orientation = new Cesium.VelocityOrientationProperty( + dataPositionProperty + ) + + type === 'booster' + ? boosterMap.set(id, dataLine) + : interceptMap.set(id, dataLine) + }) +} + function daodanAnimation(params) { const { totalAnimationTime, startTime, positionProperty, daodan, trajData } = params // const { data: ddTrajData } = trajData - dianhuo(daodan) + // dianhuo(daodan) + + // setTimeout(() => { + // modelAnimationController({ + // primitive: daodan, + // type: '第一级发动机 MoveZ', + // initVal: 0, + // minVal: -450, + // step: -3, + // fn: () => { + // console.log( + // `一级脱离`, + // 'color: red;font-size: 20px;border: 1px solid red' + // ) + // nodes.forEach(i => { + // const nodeName = i._name + // if (new RegExp(/第一级发动机/).test(nodeName)) { + // daodan.getNode(nodeName).show = false + // } + // }) + // }, + // }) + // }, 3000) let lastFrameTime = performance.now() let customElapsedTime = 0 @@ -317,12 +489,17 @@ function daodanAnimation(params) { if (customElapsedTime >= totalAnimationTime) { customElapsedTime = totalAnimationTime // 限制时间为总时长 isAnimationRunning = false // 停止动画 + + setTimeout(() => { + removeAllEntity() + }, 6000) } - ddNodesAnimationController({ - ddPrimitive: daodan, - curTime: minTime + customElapsedTime * 1000, - trajData, - }) + + // ddNodesAnimationController({ + // ddPrimitive: daodan, + // curTime: minTime + customElapsedTime * 1000, + // trajData, + // }) // 计算自定义时间下的位置 const customTime = Cesium.JulianDate.addSeconds( @@ -340,17 +517,28 @@ function daodanAnimation(params) { new Cesium.JulianDate() ) ) - if (position && !nextPosition && !explosion) { - const [lon, lat, height] = cartesian32LonLat(position) - explosion = new ExplosionEffect(viewer, { - lng: lon, - lat: lat, - height, - }) + + if (interceptTime.value && customElapsedTime >= interceptTime.value) { + customElapsedTime = totalAnimationTime + isAnimationRunning = false + explosion = explosionEffect(position) + setTimeout(() => { - explosion && explosion.remove() + removeAllEntity() }, 6000) } + if (position && !nextPosition && !explosion) { + // const [lon, lat, height] = cartesian32LonLat(position) + // explosion = new ExplosionEffect(viewer, { + // lng: lon, + // lat: lat, + // height, + // }) + // setTimeout(() => { + // explosion && explosion.remove() + // }, 6000) + explosion = explosionEffect(position) + } if (position && nextPosition) { const fixedFrameTransform = Cesium.Transforms.localFrameToFixedFrameGenerator('north', 'west') @@ -363,16 +551,22 @@ function daodanAnimation(params) { fixedFrameTransform, daodan.modelMatrix ) - - // Cesium.Matrix4.fromTranslationQuaternionRotationScale( - // position, - // orientation, - // new Cesium.Cartesian3(1.0, 1.0, 1.0), // 缩放比例, - // daodan.modelMatrix - // ) } }) } + +function explosionEffect(position) { + const [lon, lat, height] = cartesian32LonLat(position) + const explosion = new ExplosionEffect(viewer, { + lng: lon, + lat: lat, + height, + }) + setTimeout(() => { + explosion && explosion.remove() + }, 6000) + return explosion +} function dianhuo(ddPrimitive) { modelAnimationController({ primitive: ddPrimitive, @@ -392,14 +586,6 @@ function ddNodesAnimationController(params) { const { id: ddId, data: ddTrajData } = trajData const nodeAniList = ddTrajData.filter(item => item.detached) - // console.log( - // curTime, - // aniIndex, - // nodeAniList[aniIndex].time, - // curTime >= nodeAniList[aniIndex].time, - // 'curTime' - // ) - if (!ddPrimitive || !aniIndexMap.has(ddId)) return const aniIndex = aniIndexMap.get(ddId) @@ -595,38 +781,36 @@ function getHeadingPitchRoll(curPos, nextPos) { return hpr } -function createLine({ totalAnimationTime, startTime, positionProperty, type }) { +function createLine({ + totalAnimationTime, + startTime, + positionProperty, + type, + color, +}) { const positionList = getPositionFromTime( startTime, positionProperty, totalAnimationTime ) - viewer.entities.add({ + // if (type === 2) { + // console.log('positionList', positionList) + // } + + return viewer.entities.add({ position: positionProperty, polyline: { positions: positionList, - width: 2, - material: type - ? Cesium.Color.RED.withAlpha(0.5) - : Cesium.Color.BLUE.withAlpha(0.5), + width: 8, + material: new Cesium.PolylineGlowMaterialProperty({ + glowPower: 0.1, + color: type + ? type === 2 && Cesium.Color[color].withAlpha(0.5) + : Cesium.Color.BLUE.withAlpha(0.5), + }), }, }) } -// function getPositionFromTime(startTime, pos, totalAnimationTime) { -// const points = [] - -// for (let i = 0; i <= totalAnimationTime / 100; i++) { -// const time = Cesium.JulianDate.addSeconds( -// startTime, -// i, -// new Cesium.JulianDate() -// ) -// const point = pos.getValue(time) -// point && points.push(point) -// } - -// return points -// } function modelAnimationController(controller) { const { type, initVal, maxVal, fn, step, minVal, primitive } = controller @@ -648,3 +832,25 @@ function modelAnimationController(controller) { } render() } + +function removeAllEntity() { + boosterMap.values().forEach(i => { + viewer.entities.remove(i) + }) + boosterMap.clear() + + interceptMap.values().forEach(i => { + viewer.entities.remove(i) + }) + interceptMap.clear() + + pathLine.values().forEach(i => { + viewer.entities.remove(i) + }) + pathLine.clear() + + ddMap.values().forEach(i => { + viewer.scene.primitives.remove(i.primitive) + }) + ddMap.clear() +}