Skip to content

Commit e00dd76

Browse files
Enhance model placement and center of mass display
Updated version number and added functionality to toggle the display of the center of mass marker for placed models. Improved aircraft model handling and ensured previous models are removed when placing new ones.
1 parent 642a9f5 commit e00dd76

1 file changed

Lines changed: 145 additions & 40 deletions

File tree

user.js

Lines changed: 145 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// @description:zh-CN GeoFS 的 GLTF 模型导入工具
77
// @description:zh-TW GeoFS 的 GLTF 模型匯入工具
88
// @namespace https://github.com/GeofsExplorer/GeoFS-Model-Importer
9-
// @version 1.0.1
9+
// @version 1.0.4
1010
// @author GeofsExplorer and 31124呀
1111
// @match https://www.geo-fs.com/geofs.php?v=3.9
1212
// @match https://geo-fs.com/geofs.php*
@@ -26,6 +26,9 @@
2626
this.placedModels = [];
2727
this.isDraggingUI = false;
2828
this.dragOffset = { x: 0, y: 0 };
29+
this.currentAircraftModel = null;
30+
this.showCenterOfMass = true;
31+
this.aircraftModelUpdateHandler = null;
2932
this.init();
3033
}
3134

@@ -98,6 +101,13 @@
98101
style="width: 100%; min-width: 100%; max-width: 100%; padding: 8px; height: 32px; border: 1px solid #555; border-radius: 4px; background: #222; color: white; font-size: 12px; box-sizing: border-box; overflow: hidden;">
99102
</div>
100103
104+
<div style="margin-bottom: 15px;">
105+
<label style="display: flex; align-items: center; gap: 8px; font-size: 12px; cursor: pointer;">
106+
<input type="checkbox" id="show-center-of-mass" checked>
107+
Show Center of Mass Marker
108+
</label>
109+
</div>
110+
101111
<div style="display: flex; gap: 8px;">
102112
<button id="place-model-btn" style="flex: 1; padding: 8px; border: none; border-radius: 3px; background: #2d5aa0; color: white; font-size: 11px; cursor: pointer;">
103113
Place Here
@@ -106,6 +116,12 @@
106116
Use as Aircraft
107117
</button>
108118
</div>
119+
120+
<div style="margin-top: 15px; padding: 10px; background: rgba(255,255,255,0.05); border-radius: 3px;">
121+
<div style="font-size: 11px; color: #aaa;">
122+
<strong>Note:</strong> Placing a new model or using as aircraft will remove previous ones.
123+
</div>
124+
</div>
109125
</div>
110126
`;
111127
document.body.appendChild(controlPanel);
@@ -136,6 +152,12 @@
136152
this.updateScaleValue(value);
137153
});
138154

155+
const centerOfMassCheckbox = document.getElementById("show-center-of-mass");
156+
centerOfMassCheckbox.addEventListener('change', (e) => {
157+
this.showCenterOfMass = e.target.checked;
158+
this.updateAllCenterOfMassMarkers();
159+
});
160+
139161
document.getElementById("place-model-btn").onclick = () => this.place3DModel();
140162
document.getElementById("use-as-aircraft-btn").onclick = () => this.replaceAircraftModel();
141163

@@ -160,6 +182,10 @@
160182
this.placedModels.forEach(model => {
161183
this.adjustModelScale(model.entity, this.scaleValue);
162184
});
185+
186+
if (this.currentAircraftModel) {
187+
this.updateAircraftModelScale();
188+
}
163189
}
164190

165191
adjustModelScale(modelEntity, scale) {
@@ -171,6 +197,93 @@
171197
}
172198
}
173199

200+
createCenterOfMassMarker(position) {
201+
if (!this.showCenterOfMass) return null;
202+
203+
try {
204+
return window.geofs.api.viewer.entities.add({
205+
position: position,
206+
point: {
207+
pixelSize: 8,
208+
color: window.Cesium.Color.RED,
209+
outlineColor: window.Cesium.Color.WHITE,
210+
outlineWidth: 2,
211+
heightReference: window.Cesium.HeightReference.NONE,
212+
disableDepthTestDistance: Number.POSITIVE_INFINITY
213+
},
214+
label: {
215+
text: "Center of Mass",
216+
font: "12pt Arial",
217+
pixelOffset: new window.Cesium.Cartesian2(0, -20),
218+
fillColor: window.Cesium.Color.WHITE,
219+
outlineColor: window.Cesium.Color.BLACK,
220+
outlineWidth: 2,
221+
showBackground: true,
222+
backgroundColor: new window.Cesium.Color(0.1, 0.1, 0.1, 0.7),
223+
verticalOrigin: window.Cesium.VerticalOrigin.BOTTOM,
224+
heightReference: window.Cesium.HeightReference.NONE
225+
}
226+
});
227+
} catch(error) {
228+
console.warn('Failed to create center of mass marker:', error);
229+
return null;
230+
}
231+
}
232+
233+
updateAllCenterOfMassMarkers() {
234+
this.placedModels.forEach(model => {
235+
if (model.centerOfMassMarker) {
236+
model.centerOfMassMarker.show = this.showCenterOfMass;
237+
}
238+
});
239+
}
240+
241+
removeAllPlacedModels() {
242+
this.placedModels.forEach(model => {
243+
try {
244+
window.geofs.api.viewer.entities.remove(model.entity);
245+
if (model.centerOfMassMarker) {
246+
window.geofs.api.viewer.entities.remove(model.centerOfMassMarker);
247+
}
248+
} catch(error) {
249+
console.warn('Failed to remove model:', error);
250+
}
251+
});
252+
this.placedModels = [];
253+
}
254+
255+
removeAircraftModel() {
256+
if (this.currentAircraftModel) {
257+
try {
258+
if (this.aircraftModelUpdateHandler) {
259+
window.geofs.api.viewer.scene.preRender.removeEventListener(this.aircraftModelUpdateHandler);
260+
this.aircraftModelUpdateHandler = null;
261+
}
262+
263+
if (window.geofs && window.geofs.aircraft && window.geofs.aircraft.instance) {
264+
window.geofs.aircraft.instance.setVisibility(1);
265+
}
266+
267+
try {
268+
if (typeof this.currentAircraftModel.destroy === 'function') {
269+
this.currentAircraftModel.destroy();
270+
}
271+
} catch(e) {
272+
console.warn('Cannot destroy aircraft model, but it will be replaced:', e);
273+
}
274+
275+
this.currentAircraftModel = null;
276+
} catch(error) {
277+
console.warn('Failed to remove aircraft model:', error);
278+
}
279+
}
280+
}
281+
282+
removeAllModels() {
283+
this.removeAllPlacedModels();
284+
this.removeAircraftModel();
285+
}
286+
174287
startDragging(event) {
175288
this.isDraggingUI = true;
176289
this.dragOffset.initialX = event.clientX - this.dragOffset.x;
@@ -248,6 +361,8 @@
248361
}
249362

250363
try {
364+
this.removeAllModels();
365+
251366
const modelDataURL = await this.convertFileToDataURL(selectedFile);
252367
const aircraft = window.geofs.aircraft.instance;
253368
const groundPosition = window.geofs.getGroundAltitude(aircraft.llaLocation).location;
@@ -270,14 +385,16 @@
270385
}
271386
});
272387

388+
const centerOfMassMarker = this.createCenterOfMassMarker(worldPosition);
389+
273390
const modelData = {
274391
entity: modelEntity,
392+
centerOfMassMarker: centerOfMassMarker,
275393
scale: this.scaleValue
276394
};
277395
this.placedModels.push(modelData);
278396

279-
this.setupModelTracking(modelData);
280-
this.showMessage("Model placed successfully! Congratulations!");
397+
this.showMessage("Model placed successfully! Previous models have been removed.");
281398
this.controlPanel.style.display = 'none';
282399
} catch (error) {
283400
this.showMessage("Error placing model: " + error.message);
@@ -299,62 +416,50 @@
299416
}
300417

301418
try {
419+
this.removeAllModels();
420+
302421
const modelDataURL = await this.convertFileToDataURL(selectedFile);
303422
const aircraft = window.geofs.aircraft.instance;
304423

305-
const customModel = new window.geofs.api.Model(null, {
424+
this.currentAircraftModel = new window.geofs.api.Model(null, {
306425
url: modelDataURL,
307426
location: aircraft.llaLocation,
308427
rotation: aircraft.htr
309428
});
310429

311-
const updateHandler = () => {
312-
try {
313-
const currentAircraft = window.geofs.aircraft.instance;
314-
customModel.setPositionOrientationAndScale(
315-
currentAircraft.llaLocation,
316-
currentAircraft.htr,
317-
this.scaleValue
318-
);
319-
currentAircraft.setVisibility(0);
320-
} catch(error) {
321-
console.warn('Aircraft model update failed:', error);
322-
}
323-
};
324-
325-
window.geofs.api.viewer.scene.preRender.addEventListener(updateHandler);
326-
this.showMessage("Aircraft model replaced!");
430+
this.setupAircraftModelTracking();
431+
this.showMessage("Aircraft model replaced! Previous models have been removed.");
327432
this.controlPanel.style.display = 'none';
328433
} catch (error) {
329434
this.showMessage("Error replacing aircraft: " + error.message);
330435
}
331436
}
332437

333-
setupModelTracking(modelData) {
334-
const updateProcedure = () => {
438+
setupAircraftModelTracking() {
439+
if (this.aircraftModelUpdateHandler) {
440+
window.geofs.api.viewer.scene.preRender.removeEventListener(this.aircraftModelUpdateHandler);
441+
}
442+
443+
this.aircraftModelUpdateHandler = () => {
335444
try {
336-
const aircraft = window.geofs.aircraft.instance;
337-
const position = aircraft.llaLocation;
338-
const rotation = aircraft.htr || aircraft.hpr || [0, 0, 0];
339-
340-
const worldPos = window.Cesium.Cartesian3.fromDegrees(
341-
position[1],
342-
position[0],
343-
position[2]
344-
);
345-
346-
modelData.entity.position = worldPos;
347-
modelData.entity.orientation = window.Cesium.Transforms.headingPitchRollQuaternion(
348-
worldPos,
349-
new window.Cesium.HeadingPitchRoll(rotation[0], rotation[1], rotation[2])
350-
);
351-
this.adjustModelScale(modelData.entity, modelData.scale);
445+
const currentAircraft = window.geofs.aircraft.instance;
446+
if (this.currentAircraftModel) {
447+
this.currentAircraftModel.setPositionOrientationAndScale(
448+
currentAircraft.llaLocation,
449+
currentAircraft.htr,
450+
this.scaleValue
451+
);
452+
currentAircraft.setVisibility(0);
453+
}
352454
} catch(error) {
353-
console.warn('Model tracking update failed:', error);
455+
console.warn('Aircraft model update failed:', error);
354456
}
355457
};
356458

357-
window.geofs.api.viewer.scene.preRender.addEventListener(updateProcedure);
459+
window.geofs.api.viewer.scene.preRender.addEventListener(this.aircraftModelUpdateHandler);
460+
}
461+
462+
updateAircraftModelScale() {
358463
}
359464

360465
checkGeoFSReady() {

0 commit comments

Comments
 (0)