Skip to content

Commit

Permalink
better angular size calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
BarthPaleologue committed Oct 24, 2023
1 parent f2d1377 commit 5b7a0c1
Show file tree
Hide file tree
Showing 11 changed files with 47 additions and 33 deletions.
19 changes: 8 additions & 11 deletions src/ts/controller/chunks/chunkTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { Vector3 } from "@babylonjs/core/Maths/math.vector";
import { PhysicsAggregate } from "@babylonjs/core/Physics/v2/physicsAggregate";
import { TransformNode } from "@babylonjs/core/Meshes";
import { getRotationQuaternion } from "../uberCore/transforms/basicTransform";
import { Camera } from "@babylonjs/core/Cameras/camera";
import { getAngularSize, isSizeOnScreenEnough } from "../../utils/isObjectVisibleOnScreen";

/**
* A quadTree is defined recursively
Expand Down Expand Up @@ -136,10 +138,10 @@ export class ChunkTree {

// if view ray goes through planet then we don't need to load more chunks
/*const direction = tree.mesh.getAbsolutePosition().subtract(observerPositionW);
const rayDir = direction.normalizeToNew();
const rayDir = direction.normalizeToNew();
const [intersect, t0, t1] = rayIntersectSphere(observerPositionW, rayDir, this.parent.getAbsolutePosition(), this.rootChunkLength / 2);
if (intersect && t0 ** 2 > direction.lengthSquared()) return tree;*/
const [intersect, t0, t1] = rayIntersectSphere(observerPositionW, rayDir, this.parent.getAbsolutePosition(), this.rootChunkLength / 2);
if (intersect && t0 ** 2 > direction.lengthSquared()) return tree;*/

const newTree = [
this.createChunk(walked.concat([0]), true),
Expand Down Expand Up @@ -196,19 +198,14 @@ export class ChunkTree {
return chunk;
}

public computeCulling(cameraPosition: Vector3): void {
public computeCulling(camera: Camera): void {
this.executeOnEveryChunk((chunk: PlanetChunk) => {
if (!chunk.isReady()) return;

chunk.mesh.setEnabled(true);
chunk.mesh.setEnabled(true); // this is needed to update the world matrix
chunk.transform.computeWorldMatrix(true);

const distance = Vector3.Distance(cameraPosition, chunk.transform.getAbsolutePosition());
const angularSize = (chunk.getBoundingRadius() * 2) / distance;

const chunkIsTooSmall = angularSize / Settings.FOV < 0.002;

chunk.mesh.setEnabled(!chunkIsTooSmall);
chunk.mesh.setEnabled(isSizeOnScreenEnough(chunk, camera));
});
}

Expand Down
2 changes: 1 addition & 1 deletion src/ts/controller/starSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ export class StarSystem {

for (const body of this.telluricPlanets.concat(this.satellites)) body.updateLOD(controller.getTransform().getAbsolutePosition());

for (const object of this.orbitalObjects) object.computeCulling(controller.getActiveCamera().getAbsolutePosition());
for (const object of this.orbitalObjects) object.computeCulling(controller.getActiveCamera());

for (const planet of this.planemosWithMaterial) planet.updateMaterial(controller, this.stellarObjects, deltaTime);

Expand Down
25 changes: 18 additions & 7 deletions src/ts/utils/isObjectVisibleOnScreen.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
import { Vector3 } from "@babylonjs/core/Maths/math";
import { BaseObject } from "../view/common";
import { Settings } from "../settings";
import { BoundingSphere, ITransformable } from "../view/common";
import { Camera } from "@babylonjs/core/Cameras/camera";

/**
* Computes the angular size in radians of an object viewed by a camera
* @param objectPosition
* @param objectRadius
* @param cameraPosition The position of the observer camera
* @see https://en.wikipedia.org/wiki/Angular_diameter
*/
export function getAngularSize(objectPosition: Vector3, objectRadius: number, cameraPosition: Vector3) {
const distance = Vector3.Distance(cameraPosition, objectPosition);
return 2 * Math.atan(objectRadius / distance);
}

/**
* Checks if the size of the object on the screen is bigger than the threshold
* @param object The object to check
* @param cameraPosition The position of the camera
* @param camera The camera looking at the object
* @param threshold The size threshold
* @returns Whether the object is bigger than the threshold
*/
export function isSizeOnScreenEnough(object: BaseObject, cameraPosition: Vector3, threshold = 0.002) {
const distance = Vector3.Distance(cameraPosition, object.transform.getAbsolutePosition());
const angularSize = (object.getBoundingRadius() * 2) / distance;
export function isSizeOnScreenEnough(object: BoundingSphere & ITransformable, camera: Camera, threshold = 0.002) {
const angularSize = getAngularSize(object.transform.getAbsolutePosition(), object.getBoundingRadius(), camera.globalPosition);

return angularSize / Settings.FOV > threshold;
return angularSize / camera.fov > threshold;
}
3 changes: 2 additions & 1 deletion src/ts/view/bodies/abstractObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { PostProcessType } from "../postProcesses/postProcessTypes";
import { Cullable } from "./cullable";
import { TransformNode } from "@babylonjs/core/Meshes";
import { getRotationQuaternion, setRotationQuaternion } from "../../controller/uberCore/transforms/basicTransform";
import { Camera } from "@babylonjs/core/Cameras/camera";

export interface NextState {
position: Vector3;
Expand Down Expand Up @@ -128,7 +129,7 @@ export abstract class AbstractObject implements OrbitalObject, BaseObject, Culla
setRotationQuaternion(this.transform, this.nextState.rotation);
}

public abstract computeCulling(cameraPosition: Vector3): void;
public abstract computeCulling(camera: Camera): void;

public dispose(): void {
this.transform.dispose();
Expand Down
4 changes: 2 additions & 2 deletions src/ts/view/bodies/cullable.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Vector3 } from "@babylonjs/core/Maths/math";
import { Camera } from "@babylonjs/core/Cameras/camera";

export interface Cullable {
computeCulling(cameraPosition: Vector3): void;
computeCulling(camera: Camera): void;
}
5 changes: 3 additions & 2 deletions src/ts/view/bodies/planemos/gasPlanet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Mesh } from "@babylonjs/core/Meshes/mesh";
import { PostProcessType } from "../../postProcesses/postProcessTypes";
import { Vector3 } from "@babylonjs/core/Maths/math.vector";
import { isSizeOnScreenEnough } from "../../../utils/isObjectVisibleOnScreen";
import { Camera } from "@babylonjs/core/Cameras/camera";

export class GasPlanet extends AbstractBody implements Planemo, PlanemoMaterial {
private readonly mesh: Mesh;
Expand Down Expand Up @@ -53,8 +54,8 @@ export class GasPlanet extends AbstractBody implements Planemo, PlanemoMaterial
this.material.update(controller, stellarObjects, deltaTime);
}

public override computeCulling(cameraPosition: Vector3): void {
this.mesh.isVisible = isSizeOnScreenEnough(this, cameraPosition);
public override computeCulling(camera: Camera): void {
this.mesh.isVisible = isSizeOnScreenEnough(this, camera);
}

public override dispose(): void {
Expand Down
4 changes: 2 additions & 2 deletions src/ts/view/bodies/planemos/mandelbulb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { UberScene } from "../../../controller/uberCore/uberScene";
import { Planemo } from "./planemo";
import { Axis } from "@babylonjs/core/Maths/math.axis";
import { PostProcessType } from "../../postProcesses/postProcessTypes";
import { Vector3 } from "@babylonjs/core/Maths/math.vector";
import { MandelbulbModel } from "../../../model/planemos/mandelbulbModel";
import { Camera } from "@babylonjs/core/Cameras/camera";

export class Mandelbulb extends AbstractBody implements Planemo {
readonly model: MandelbulbModel;
Expand All @@ -26,7 +26,7 @@ export class Mandelbulb extends AbstractBody implements Planemo {
this.transform.rotate(Axis.X, this.model.physicalProperties.axialTilt);
}

public override computeCulling(cameraPosition: Vector3): void {
public override computeCulling(camera: Camera): void {
// do nothing
}
}
5 changes: 3 additions & 2 deletions src/ts/view/bodies/planemos/telluricPlanemo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { StellarObject } from "../stellarObjects/stellarObject";
import { PostProcessType } from "../../postProcesses/postProcessTypes";
import { PhysicsAggregate } from "@babylonjs/core/Physics/v2/physicsAggregate";
import { PhysicsShapeType } from "@babylonjs/core/Physics/v2/IPhysicsEnginePlugin";
import { Camera } from "@babylonjs/core/Cameras/camera";

export class TelluricPlanemo extends AbstractBody implements Planemo, PlanemoMaterial {
readonly sides: ChunkTree[] = new Array(6); // stores the 6 sides of the sphere
Expand Down Expand Up @@ -105,8 +106,8 @@ export class TelluricPlanemo extends AbstractBody implements Planemo, PlanemoMat
return super.getRadius() + this.model.physicalProperties.oceanLevel;
}

public override computeCulling(cameraPosition: Vector3): void {
for (const side of this.sides) side.computeCulling(cameraPosition);
public override computeCulling(camera: Camera): void {
for (const side of this.sides) side.computeCulling(camera);
}

public override dispose(): void {
Expand Down
3 changes: 2 additions & 1 deletion src/ts/view/bodies/stellarObjects/blackHole.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Vector3 } from "@babylonjs/core/Maths/math.vector";
import { Scene } from "@babylonjs/core/scene";
import { Light } from "@babylonjs/core/Lights/light";
import { PostProcessType } from "../../postProcesses/postProcessTypes";
import { Camera } from "@babylonjs/core/Cameras/camera";

export class BlackHole extends AbstractBody {
readonly light: PointLight;
Expand All @@ -28,7 +29,7 @@ export class BlackHole extends AbstractBody {
this.postProcesses.push(PostProcessType.OVERLAY, PostProcessType.BLACK_HOLE);
}

public override computeCulling(cameraPosition: Vector3): void {
public override computeCulling(camera: Camera): void {
// nothing to do
}

Expand Down
5 changes: 3 additions & 2 deletions src/ts/view/bodies/stellarObjects/star.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { Assets } from "../../../controller/assets";
import { setRotationQuaternion } from "../../../controller/uberCore/transforms/basicTransform";
import { PhysicsAggregate } from "@babylonjs/core/Physics/v2/physicsAggregate";
import { PhysicsShapeType } from "@babylonjs/core";
import { Camera } from "@babylonjs/core/Cameras/camera";

export class Star extends AbstractBody {
readonly mesh: Mesh;
Expand Down Expand Up @@ -72,8 +73,8 @@ export class Star extends AbstractBody {
this.material.update(this.getInternalClock());
}

public override computeCulling(cameraPosition: Vector3): void {
this.mesh.isVisible = true;
public override computeCulling(camera: Camera): void {
//this.mesh.isVisible = true;
}

public override dispose(): void {
Expand Down
5 changes: 3 additions & 2 deletions src/ts/view/spaceStation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Axis } from "@babylonjs/core/Maths/math.axis";
import { PostProcessType } from "./postProcesses/postProcessTypes";
import { Vector3 } from "@babylonjs/core/Maths/math";
import { isSizeOnScreenEnough } from "../utils/isObjectVisibleOnScreen";
import { Camera } from "@babylonjs/core/Cameras/camera";

export class SpaceStation extends AbstractObject {
readonly model: SpaceStationModel;
Expand Down Expand Up @@ -43,8 +44,8 @@ export class SpaceStation extends AbstractObject {
return 2e3;
}

public override computeCulling(cameraPosition: Vector3): void {
const isVisible = isSizeOnScreenEnough(this, cameraPosition);
public override computeCulling(camera: Camera): void {
const isVisible = isSizeOnScreenEnough(this, camera);
for (const mesh of this.instance.getChildMeshes()) {
mesh.isVisible = isVisible;
}
Expand Down

0 comments on commit 5b7a0c1

Please sign in to comment.