Skip to content

Commit

Permalink
feat(map): fade doodads in and out based on distance
Browse files Browse the repository at this point in the history
  • Loading branch information
fallenoak committed Feb 4, 2024
1 parent f9b8106 commit 199ec9e
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 4 deletions.
9 changes: 7 additions & 2 deletions src/lib/map/DoodadManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { AssetHost } from '../asset.js';
import { MapAreaSpec, MapDoodadDefSpec } from './loader/types.js';
import MapLight from './light/MapLight.js';
import Model from '../model/Model.js';
import { getFade } from '../world.js';

type DoodadManagerOptions = {
host: AssetHost;
Expand Down Expand Up @@ -34,19 +35,23 @@ class DoodadManager {
});
}

cull(cullingFrustum: THREE.Frustum) {
cull(cullingFrustum: THREE.Frustum, cameraPosition: THREE.Vector3) {
for (const [areaId, areaGroup] of this.#loadedAreas.entries()) {
const areaBounds = this.#areaBounds.get(areaId);
const areaVisible = cullingFrustum.intersectsSphere(areaBounds);

areaGroup.visible = areaVisible;

for (const doodad of areaGroup.children as Model[]) {
const distance = cameraPosition.distanceTo(doodad.position);
const fade = getFade(distance, doodad.sizeCategory);

const doodadVisible =
areaVisible && cullingFrustum.intersectsSphere(doodad.boundingSphereWorld);
areaVisible && fade > 0.0 && cullingFrustum.intersectsSphere(doodad.boundingSphereWorld);

if (doodadVisible) {
doodad.show();
doodad.alpha = fade;
} else {
doodad.hide();
}
Expand Down
2 changes: 1 addition & 1 deletion src/lib/map/MapManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ class MapManager extends EventTarget {
// Cull entire groups to save on frustum intersection cost
this.#cullGroups();

this.#doodadManager.cull(this.#cullingFrustum);
this.#doodadManager.cull(this.#cullingFrustum, camera.position);
this.#doodadManager.update(deltaTime);
}

Expand Down
28 changes: 27 additions & 1 deletion src/lib/model/Model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,23 @@ import * as THREE from 'three';
import ModelMaterial from './ModelMaterial.js';
import ModelAnimator from './ModelAnimator.js';
import ModelAnimation from './ModelAnimation.js';
import { getSizeCategory } from '../world.js';

class Model extends THREE.Object3D {
animation: ModelAnimation;

diffuseColor: THREE.Color;
emissiveColor: THREE.Color;
alpha: 1.0;
alpha = 1.0;

#mesh: THREE.Mesh;
#skinned: boolean;

#boundingSphereWorld = new THREE.Sphere();

#size = 0.0;
#sizeCategory = 0;

constructor(
geometry: THREE.BufferGeometry,
materials: THREE.Material[],
Expand Down Expand Up @@ -62,6 +66,14 @@ class Model extends THREE.Object3D {
return this.#boundingSphereWorld;
}

get size() {
return this.#size;
}

get sizeCategory() {
return this.#sizeCategory;
}

get skinned() {
return this.#skinned;
}
Expand Down Expand Up @@ -91,9 +103,23 @@ class Model extends THREE.Object3D {
updateMatrixWorld(force?: boolean) {
super.updateMatrixWorld(force);

this.#updateBounds();
this.#updateSize();
}

#updateBounds() {
this.#boundingSphereWorld.copy(this.boundingSphere).applyMatrix4(this.matrixWorld);
}

#updateSize() {
const sizeX = (this.boundingBox.max.x - this.boundingBox.min.x) * this.scale.x;
const sizeY = (this.boundingBox.max.y - this.boundingBox.min.y) * this.scale.y;
const sizeZ = (this.boundingBox.max.z - this.boundingBox.min.z) * this.scale.z;

this.#size = Math.max(sizeX, sizeY, sizeZ);
this.#sizeCategory = getSizeCategory(this.#size);
}

#onBeforeRender(
renderer: THREE.WebGLRenderer,
scene: THREE.Scene,
Expand Down
26 changes: 26 additions & 0 deletions src/lib/world.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,31 @@ const getSizeCategory = (size: number) => {
return f;
};

const getFade = (distance: number, sizeCategory: number) => {
const min = WORLD_FADE_DIST_MIN[sizeCategory];
const max = WORLD_FADE_DIST_MAX[sizeCategory];

if (distance < min) {
return 1.0;
}

if (distance > max) {
return 0.0;
}

const fade = 1.0 - (distance - min) / (max - min);

if (fade <= 0.0099999998) {
return 0.0;
}

if (fade > 0.99000001) {
return 1.0;
}

return fade;
};

const scaleFadeDist = (scale: number) => {
for (let i = 0; i < WORLD_FADE_SIZE_DEFAULT.length; i++) {
const first = i === 0;
Expand All @@ -37,6 +62,7 @@ const scaleFadeDist = (scale: number) => {
scaleFadeDist(1.5);

export {
getFade,
getSizeCategory,
scaleFadeDist,
WORLD_FADE_SIZE,
Expand Down

0 comments on commit 199ec9e

Please sign in to comment.