diff --git a/dist/main/solvers/trajectory.js b/dist/main/solvers/trajectory.js index 799ce34..211b86d 100644 --- a/dist/main/solvers/trajectory.js +++ b/dist/main/solvers/trajectory.js @@ -88,8 +88,7 @@ export class Trajectory { const { x, y, z } = maneuvre.position; const pos = new THREE.Vector3(x, y, z); addSprite(i, sprite, pos); - const { type } = maneuvre.context; - if (type == "ejection") { + if (maneuvre.context.type == "ejection") { const sprite = createSprite(escapeSprite, 0xFFFFFF, false, spritesSize); const pos = orbit.positionFromTrueAnomaly(step.drawAngles.end); addSprite(i, sprite, pos); diff --git a/src/main/solvers/trajectory.ts b/src/main/solvers/trajectory.ts index 4e18e84..0aa8425 100644 --- a/src/main/solvers/trajectory.ts +++ b/src/main/solvers/trajectory.ts @@ -29,6 +29,9 @@ export class Trajectory { } } + /** + * Preloads all the sprite materials in the `sprites` map. + */ public static preloadSpriteMaterials(){ const textureLoader = new THREE.TextureLoader(); const loaded = (name: string) => { @@ -45,6 +48,10 @@ export class Trajectory { textureLoader.load("sprites/maneuver.png", loaded("maneuver")); } + /** + * Draws the tajectory to the scene. + * @param resolution The resolution of the canvas + */ public draw(resolution: {width: number, height: number}){ const numSteps = this.steps.length; this._displayedSteps = Array(numSteps).fill(true); @@ -55,6 +62,10 @@ export class Trajectory { this._calculateFlybyDetails(); } + /** + * Computes all the leg arcs orbits, adds them to the scene and stores them. + * @param resolution The resolution of the canvas + */ private _createTrajectoryArcs(resolution: {width: number, height: number}){ this._orbitObjects = []; @@ -80,7 +91,12 @@ export class Trajectory { } } + /** + * Adds the various sprites to the scene and the collections for managment. + */ private _createManeuvreSprites(){ + // Empty the sprite collection, for each step there is a list + // of sprites (initally empty). this._spriteObjects = []; for(let i = 0; i < this.steps.length; i++){ this._spriteObjects.push([]); @@ -94,6 +110,7 @@ export class Trajectory { const maneuverSprite = Trajectory.sprites.get("maneuver"); const addSprite = (i: number, sprite: THREE.Sprite, pos: THREE.Vector3) => { + // adds a sprite to the sprite collection and the corresponding group sprite.position.set(pos.x, pos.y, pos.z); sprite.position.multiplyScalar(scale); const group = this.system.objectsOfBody(this.steps[i].attractorId); @@ -107,18 +124,20 @@ export class Trajectory { const {maneuvre, flyby} = step; if(maneuvre){ + // if there is a maneuver, add the maneuver sprite const sprite = createSprite(maneuverSprite, 0xFFFFFF, false, spritesSize); const {x, y, z} = maneuvre.position; const pos = new THREE.Vector3(x, y, z); addSprite(i, sprite, pos); - const {type} = maneuvre.context; - if(type == "ejection"){ + if(maneuvre.context.type == "ejection"){ + // if the maneuver is an ejection, add the ejection maneuver sprite const sprite = createSprite(escapeSprite, 0xFFFFFF, false, spritesSize); const pos = orbit.positionFromTrueAnomaly(step.drawAngles.end); addSprite(i, sprite, pos); } } else if(flyby){ + // if the maneuver is a flyby, add the encounter and escape sprites const sprite1 = createSprite(encounterSprite, 0xFFFFFF, false, spritesSize); const sprite2 = createSprite(escapeSprite, 0xFFFFFF, false, spritesSize); const pos1 = orbit.positionFromTrueAnomaly(step.drawAngles.begin); @@ -127,6 +146,7 @@ export class Trajectory { addSprite(i, sprite2, pos2); } else if(i == this.steps.length - 2){ + // if it's insertion orbit, add the circularization burn maneuver sprite const sprite = createSprite(encounterSprite, 0xFFFFFF, false, spritesSize); const pos = orbit.positionFromTrueAnomaly(step.drawAngles.begin); addSprite(i, sprite, pos); @@ -134,6 +154,9 @@ export class Trajectory { } const updateSpritesDisplay = (camController: CameraController) => { + // display maneuver sprites only if we are close enough to the body + // that contains them, and if the steps to which belong these maneuvers is + // actually displayed const camPos = camController.camera.position; const {scale} = this.config.rendering; const {spriteDispSOIMul} = this.config.solarSystem; @@ -156,10 +179,15 @@ export class Trajectory { } }; + // Add the display update as a callback of the system's update + // function which is called once each frame. const id = this.system.addCustomUpdate(updateSpritesDisplay); this._spritesUpdateFunId = id; } + /** + * Computes the maneuver details from the data given in the steps. + */ private _calculateManeuvresDetails(){ const departureDate = this.steps[0].dateOfStart; @@ -196,6 +224,9 @@ export class Trajectory { } } + /** + * Computes the flyby details from the data given in the steps. + */ private _calculateFlybyDetails(){ const departureDate = this.steps[0].dateOfStart; for(const {flyby} of this.steps){ @@ -216,10 +247,18 @@ export class Trajectory { } } + /** + * Fills the various HTML elements of the result panel with the data and events needed. + * @param resultItems The list of HTML items attached to the result panel + * @param systemTime The system time manager + * @param controls The camera controller + */ public fillResultControls(resultItems: ResultPannelItems, systemTime: TimeSelector, controls: CameraController){ const depDate = new KSPTime(this.steps[0].dateOfStart, this.config.time); + // total delta-V resultItems.totalDVSpan.innerHTML = this._totalDeltaV.toFixed(1); + // departure date resultItems.depDateSpan.innerHTML = depDate.stringYDHMS("hms", "ut"); const onDateClick = (date: number) => () => { @@ -228,17 +267,19 @@ export class Trajectory { systemTime.time.dateSeconds = date; systemTime.update(); }; - + // set the system time to the departure date time when the span is clicked resultItems.depDateSpan.onclick = onDateClick(depDate.dateSeconds); + // configure the step slider const {stepSlider} = resultItems; stepSlider.setMinMax(0, this.steps.length - 1); stepSlider.input((index: number) => this._displayStepsUpTo(index)); stepSlider.value = this.steps.length - 1; - + // information about each selector options const selectorOptions: DetailsSelectorOption[] = []; + // keep index for the numbering of each maneuver and flybys let maneuvreIdx = 0, flybyIdx = 0; let optionNumber = 0; @@ -249,6 +290,7 @@ export class Trajectory { const step = this.steps[details.stepIndex]; const context = (step.maneuvre).context; + // name of the options to display in the selector, if it's a maneuver let optionName: string; if(context.type == "ejection") { const startBodyName = this.system.bodyFromId(step.attractorId).name; @@ -271,6 +313,7 @@ export class Trajectory { selectorOptions.push(option); } else if(flyby){ + // details the options in the selector, if it's a flyby const details = this._flybys[flybyIdx]; const bodyName = this.system.bodyFromId(details.bodyId).name; const optionName = `${++optionNumber}: ${bodyName} flyby`; @@ -285,11 +328,14 @@ export class Trajectory { } } + // retrieve the list of option names only from their details const optionNames = selectorOptions.map(opt => opt.text); const {detailsSelector} = resultItems; detailsSelector.fill(optionNames); detailsSelector.change((_: string, index: number) => { + // Fill the result panel with the correct data depending on what option + // is selected in the selector const option = selectorOptions[index]; if(option.type == "maneuver"){ @@ -334,6 +380,10 @@ export class Trajectory { }*/ } + /** + * Sets the visibility of the steps up to the provided indedx. + * @param index The index of the last step to display + */ private _displayStepsUpTo(index: number){ for(let i = 0; i < this.steps.length; i++){ const orbitLine = this._orbitObjects[i]; @@ -347,6 +397,9 @@ export class Trajectory { } } + /** + * Computes and returns the total delta-V of the trajectory + */ private get _totalDeltaV(){ let total = 0; for(const details of this._maneuvres){ @@ -358,6 +411,9 @@ export class Trajectory { return total; } + /** + * Removes all objects/events relative to this trajectory from the scene. + */ public remove() { for(const object of this._orbitObjects) { if(object.parent) object.parent.remove(object);