Skip to content

Commit

Permalink
fix: add close-up variant of the sun-earth line [PT-188059193]
Browse files Browse the repository at this point in the history
  • Loading branch information
pjanik committed Aug 21, 2024
1 parent 1650beb commit ca151c4
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 45 deletions.
97 changes: 53 additions & 44 deletions src/grasp-seasons/3d-models/sun-earth-line.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,24 @@ import * as THREE from "three";
import { IModelParams } from "../types";
import * as c from "./constants";

const POINTER_RADIUS = 200000 * c.SF;
const POINTER_TUBE = 60000 * c.SF;
const HEIGHT = 1; // arrow will be rescaled dynamically based on earth-sun distance that changes through the year
const RADIUS = 1500000 * c.SF;
const LARGE_HEAD_RADIUS = RADIUS * 7;
const LARGE_HEAD_HEIGHT = HEIGHT * 0.2;
const SMALL_HEAD_RADIUS = RADIUS * 5;
const SMALL_HEAD_HEIGHT = HEIGHT * 0.03;
const SMALL_ARROW_SCALE = 0.15;

export default class {
_arrow!: THREE.Object3D;
_arrowHead!: THREE.Object3D;
_smallArrowHead!: THREE.Object3D;
_arrowMesh!: THREE.Object3D;
_earthRadius: number;
_pointerMesh!: THREE.Object3D;
_refVector: THREE.Vector3;
_earthPos?: THREE.Vector3;

rootObject!: THREE.Object3D;
constructor(props: IModelParams) {
const simple = props.type === "orbit-view";
Expand All @@ -19,74 +29,73 @@ export default class {
this._earthRadius = simple ? c.SIMPLE_EARTH_RADIUS : c.EARTH_RADIUS;

this._init3DObjects(simple);
this.setOrbitViewStyle();
}

setEarthPos(newPos: THREE.Vector3) {
const sunRealRadius = c.SIMPLE_SUN_RADIUS * 1.41; // match edge of the Sun PNG-based sprite
this._earthPos = newPos.clone();
// match edge of the Sun PNG-based sprite
const sunRealRadius = c.SIMPLE_SUN_RADIUS * (this._smallArrowHead.visible ? 1.1 : 1.41);
const len = newPos.length() - this._earthRadius - sunRealRadius;
let angleDiff = newPos.angleTo(this._refVector);
if (newPos.z < 0) angleDiff *= -1;
this.rootObject.rotation.y = angleDiff;
if (this._pointerMesh) {
this._pointerMesh.position.x = -len;
}
this._arrow.position.x = -len - sunRealRadius;
this._arrow.scale.x = len;
}

_init3DObjects(simple: boolean) {
this._arrow = this._initArrow(simple);

const container = new THREE.Object3D();
container.add(this._arrow);
const pivot = new THREE.Object3D();
pivot.add(container);

if (!simple) {
this._pointerMesh = this._initPointer();
container.add(this._pointerMesh);
}
pivot.add(this._arrow);

this.rootObject = pivot;
}

_initPointer() {
const container = new THREE.Object3D();

for (let i = 2; i < 8; i++) {
const radius = POINTER_RADIUS * Math.pow(i, 1.5);
const material = new THREE.MeshPhongMaterial({ color: c.SUN_COLOR, transparent: true, opacity: 1 - i * 0.125 });
const geometry = new THREE.TorusGeometry(radius, POINTER_TUBE, 6, 16 * i);
const mesh = new THREE.Mesh(geometry, material);
mesh.rotation.y = Math.PI * 0.5;
// Based on circle equation: x^2 + y^2 = r^2
mesh.position.x = Math.sqrt(Math.pow(this._earthRadius, 2) - Math.pow(radius, 2)) - this._earthRadius;
container.add(mesh);
}

return container;
}

_initArrow(simple: boolean) {
const HEIGHT = 1; // arrow will be rescaled dynamically based on earth-sun distance that changes through the year
const RADIUS = simple ? 1500000 * c.SF : 100000 * c.SF;
const HEAD_RADIUS = RADIUS * (simple ? 7 : 2);
const HEAD_HEIGHT = HEIGHT * 0.2;
const geometry = new THREE.CylinderGeometry(RADIUS, RADIUS, HEIGHT, 32);
const material = new THREE.MeshPhongMaterial({ color: 0xff0000, emissive: c.SUN_COLOR });
const mesh = new THREE.Mesh(geometry, material);
const material = new THREE.MeshPhongMaterial({ color: c.SUN_COLOR, emissive: c.SUN_COLOR });
this._arrowMesh = new THREE.Mesh(geometry, material);

const arrowHeadGeo = new THREE.CylinderGeometry(0, LARGE_HEAD_RADIUS, LARGE_HEAD_HEIGHT, 32);
this._arrowHead = new THREE.Mesh(arrowHeadGeo, material);
this._arrowHead.position.y = HEIGHT * 0.5;
this._arrowMesh.add(this._arrowHead);

const arrowHeadGeo = new THREE.CylinderGeometry(0, HEAD_RADIUS, HEAD_HEIGHT, 32);
const arrowHeadMesh = new THREE.Mesh(arrowHeadGeo, material);
arrowHeadMesh.position.y = HEIGHT * 0.5;
mesh.add(arrowHeadMesh);
const smallArrowHeadGeo = new THREE.CylinderGeometry(0, SMALL_HEAD_RADIUS, SMALL_HEAD_HEIGHT, 32);
this._smallArrowHead = new THREE.Mesh(smallArrowHeadGeo, material);
this._smallArrowHead.position.y = HEIGHT * 0.5;
this._arrowMesh.add(this._smallArrowHead);

mesh.position.x = 0.5 * HEIGHT + 0.5 * HEAD_HEIGHT;
mesh.rotation.z = Math.PI * 0.5;
this._arrowMesh.position.x = 0.5 * HEIGHT + 0.5 * LARGE_HEAD_HEIGHT;
this._arrowMesh.rotation.z = Math.PI * 0.5;

const container = new THREE.Object3D();
container.add(mesh);
container.add(this._arrowMesh);

return container;
}

setCloseUpStyle() {
this._arrowMesh.scale.z = SMALL_ARROW_SCALE;
this._arrowMesh.scale.x = SMALL_ARROW_SCALE;
this._smallArrowHead.visible = true;
this._arrowHead.visible = false;
this._arrowMesh.position.x = 0.5 * HEIGHT + 0.5 * SMALL_HEAD_HEIGHT;
if (this._earthPos) {
this.setEarthPos(this._earthPos);
}
}

setOrbitViewStyle() {
this._arrowMesh.scale.z = 1;
this._arrowMesh.scale.x = 1;
this._smallArrowHead.visible = false;
this._arrowHead.visible = true;
this._arrowMesh.position.x = 0.5 * HEIGHT + 0.5 * LARGE_HEAD_HEIGHT;
if (this._earthPos) {
this.setEarthPos(this._earthPos);
}
}
}
3 changes: 2 additions & 1 deletion src/grasp-seasons/3d-views/orbit-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ export default class OrbitView extends BaseView {

setupEarthCloseUpView() {
this.registerInteractionHandler(this.latLogDraggingInteraction);
this.sunEarthLine.rootObject.visible = false;
this.monthLabels.forEach((label) => label.visible = false);
this.sunEarthLine.setCloseUpStyle();
this.earthAxis.setCloseUpStyle();
this.latLongMarker.setCloseUpStyle();
}
Expand All @@ -142,6 +142,7 @@ export default class OrbitView extends BaseView {
this.registerInteractionHandler(this.earthDraggingInteraction);
this.sunEarthLine.rootObject.visible = true;
this.monthLabels.forEach((label) => label.visible = true);
this.sunEarthLine.setOrbitViewStyle();
this.earthAxis.setOrbitViewStyle();
this.latLongMarker.setOrbitViewStyle();
}
Expand Down

0 comments on commit ca151c4

Please sign in to comment.