Integrate foliage rendering system into RuntimeHost
This commit is contained in:
@@ -41,6 +41,7 @@ import {
|
|||||||
createModelInstanceRenderGroup,
|
createModelInstanceRenderGroup,
|
||||||
disposeModelInstance
|
disposeModelInstance
|
||||||
} from "../assets/model-instance-rendering";
|
} from "../assets/model-instance-rendering";
|
||||||
|
import { FoliageInstancedRenderer } from "../foliage/foliage-instanced-renderer";
|
||||||
import type { LoadedModelAsset } from "../assets/gltf-model-import";
|
import type { LoadedModelAsset } from "../assets/gltf-model-import";
|
||||||
import type { LoadedImageAsset } from "../assets/image-assets";
|
import type { LoadedImageAsset } from "../assets/image-assets";
|
||||||
import type { LoadedAudioAsset } from "../assets/audio-assets";
|
import type { LoadedAudioAsset } from "../assets/audio-assets";
|
||||||
@@ -759,6 +760,11 @@ export class RuntimeHost {
|
|||||||
LightVolumeRenderObjects
|
LightVolumeRenderObjects
|
||||||
>();
|
>();
|
||||||
private readonly modelRenderObjects = new Map<string, Group>();
|
private readonly modelRenderObjects = new Map<string, Group>();
|
||||||
|
private readonly foliageRenderer = new FoliageInstancedRenderer({
|
||||||
|
onRebuilt: () => {
|
||||||
|
this.applyShadowState();
|
||||||
|
}
|
||||||
|
});
|
||||||
private readonly materialTextureCache = new Map<
|
private readonly materialTextureCache = new Map<
|
||||||
string,
|
string,
|
||||||
CachedMaterialTexture
|
CachedMaterialTexture
|
||||||
@@ -882,6 +888,7 @@ export class RuntimeHost {
|
|||||||
this.scene.add(this.lightVolumeGroup);
|
this.scene.add(this.lightVolumeGroup);
|
||||||
this.scene.add(this.brushGroup);
|
this.scene.add(this.brushGroup);
|
||||||
this.scene.add(this.terrainGroup);
|
this.scene.add(this.terrainGroup);
|
||||||
|
this.scene.add(this.foliageRenderer.group);
|
||||||
this.scene.add(this.modelGroup);
|
this.scene.add(this.modelGroup);
|
||||||
this.targetingLuxMesh.renderOrder = 10000;
|
this.targetingLuxMesh.renderOrder = 10000;
|
||||||
this.targetingLuxGlowMesh.renderOrder = 9999;
|
this.targetingLuxGlowMesh.renderOrder = 9999;
|
||||||
@@ -1208,6 +1215,7 @@ export class RuntimeHost {
|
|||||||
this.rebuildLightVolumes(runtimeScene.volumes.light);
|
this.rebuildLightVolumes(runtimeScene.volumes.light);
|
||||||
this.rebuildBrushMeshes(runtimeScene.brushes);
|
this.rebuildBrushMeshes(runtimeScene.brushes);
|
||||||
this.rebuildTerrainMeshes(runtimeScene.terrains);
|
this.rebuildTerrainMeshes(runtimeScene.terrains);
|
||||||
|
this.rebuildFoliage(runtimeScene);
|
||||||
this.rebuildModelRenderObjects(
|
this.rebuildModelRenderObjects(
|
||||||
runtimeScene.modelInstances,
|
runtimeScene.modelInstances,
|
||||||
runtimeScene.npcDefinitions
|
runtimeScene.npcDefinitions
|
||||||
@@ -1404,6 +1412,7 @@ export class RuntimeHost {
|
|||||||
this.clearLightVolumes();
|
this.clearLightVolumes();
|
||||||
this.clearBrushMeshes();
|
this.clearBrushMeshes();
|
||||||
this.clearTerrainMeshes();
|
this.clearTerrainMeshes();
|
||||||
|
this.foliageRenderer.dispose();
|
||||||
this.clearModelRenderObjects();
|
this.clearModelRenderObjects();
|
||||||
this.collisionWorldRequestId += 1;
|
this.collisionWorldRequestId += 1;
|
||||||
this.clearCollisionWorld();
|
this.clearCollisionWorld();
|
||||||
@@ -3163,6 +3172,11 @@ export class RuntimeHost {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applyAdvancedRenderingRenderableShadowFlags(
|
||||||
|
this.foliageRenderer.group,
|
||||||
|
shadowsEnabled
|
||||||
|
);
|
||||||
|
|
||||||
for (const renderGroup of this.modelRenderObjects.values()) {
|
for (const renderGroup of this.modelRenderObjects.values()) {
|
||||||
applyAdvancedRenderingRenderableShadowFlags(renderGroup, shadowsEnabled);
|
applyAdvancedRenderingRenderableShadowFlags(renderGroup, shadowsEnabled);
|
||||||
}
|
}
|
||||||
@@ -5012,6 +5026,14 @@ export class RuntimeHost {
|
|||||||
this.terrainMeshes.clear();
|
this.terrainMeshes.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private rebuildFoliage(runtimeScene: RuntimeSceneDefinition) {
|
||||||
|
this.foliageRenderer.sync({
|
||||||
|
terrains: runtimeScene.foliage.terrains,
|
||||||
|
foliageLayers: runtimeScene.foliage.layers,
|
||||||
|
foliagePrototypes: runtimeScene.foliage.prototypes
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private disposeUniqueMaterials(materials: Material[]) {
|
private disposeUniqueMaterials(materials: Material[]) {
|
||||||
for (const material of new Set(materials)) {
|
for (const material of new Set(materials)) {
|
||||||
material.dispose();
|
material.dispose();
|
||||||
|
|||||||
@@ -61,12 +61,19 @@ import {
|
|||||||
type ScenePathPoint
|
type ScenePathPoint
|
||||||
} from "../document/paths";
|
} from "../document/paths";
|
||||||
import {
|
import {
|
||||||
|
cloneTerrain,
|
||||||
getTerrainBounds,
|
getTerrainBounds,
|
||||||
getTerrainFootprintDepth,
|
getTerrainFootprintDepth,
|
||||||
getTerrainFootprintWidth,
|
getTerrainFootprintWidth,
|
||||||
getTerrains,
|
getTerrains,
|
||||||
type Terrain
|
type Terrain
|
||||||
} from "../document/terrains";
|
} from "../document/terrains";
|
||||||
|
import {
|
||||||
|
cloneFoliageLayerRegistry,
|
||||||
|
cloneFoliagePrototypeRegistry,
|
||||||
|
type FoliageLayerRegistry,
|
||||||
|
type FoliagePrototypeRegistry
|
||||||
|
} from "../foliage/foliage";
|
||||||
import {
|
import {
|
||||||
cloneWorldSettings,
|
cloneWorldSettings,
|
||||||
type WorldSettings
|
type WorldSettings
|
||||||
@@ -496,6 +503,12 @@ export interface RuntimePath {
|
|||||||
totalLength: number;
|
totalLength: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface RuntimeFoliageDefinition {
|
||||||
|
terrains: Terrain[];
|
||||||
|
layers: FoliageLayerRegistry;
|
||||||
|
prototypes: FoliagePrototypeRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
export interface RuntimeEntityCollection {
|
export interface RuntimeEntityCollection {
|
||||||
playerStarts: RuntimePlayerStart[];
|
playerStarts: RuntimePlayerStart[];
|
||||||
sceneEntries: RuntimeSceneEntry[];
|
sceneEntries: RuntimeSceneEntry[];
|
||||||
@@ -527,6 +540,7 @@ export interface RuntimeSceneDefinition {
|
|||||||
staticColliders: RuntimeSceneCollider[];
|
staticColliders: RuntimeSceneCollider[];
|
||||||
colliders: RuntimeSceneCollider[];
|
colliders: RuntimeSceneCollider[];
|
||||||
sceneBounds: RuntimeSceneBounds | null;
|
sceneBounds: RuntimeSceneBounds | null;
|
||||||
|
foliage: RuntimeFoliageDefinition;
|
||||||
modelInstances: RuntimeModelInstance[];
|
modelInstances: RuntimeModelInstance[];
|
||||||
paths: RuntimePath[];
|
paths: RuntimePath[];
|
||||||
npcDefinitions: RuntimeNpcDefinition[];
|
npcDefinitions: RuntimeNpcDefinition[];
|
||||||
@@ -1895,6 +1909,11 @@ export function buildRuntimeSceneFromDocument(
|
|||||||
const terrains = enabledTerrains.map((terrain) =>
|
const terrains = enabledTerrains.map((terrain) =>
|
||||||
buildRuntimeTerrain(terrain, document)
|
buildRuntimeTerrain(terrain, document)
|
||||||
);
|
);
|
||||||
|
const foliage: RuntimeFoliageDefinition = {
|
||||||
|
terrains: enabledTerrains.map((terrain) => cloneTerrain(terrain)),
|
||||||
|
layers: cloneFoliageLayerRegistry(document.foliageLayers),
|
||||||
|
prototypes: cloneFoliagePrototypeRegistry(document.foliagePrototypes)
|
||||||
|
};
|
||||||
const staticColliders: RuntimeSceneCollider[] = [];
|
const staticColliders: RuntimeSceneCollider[] = [];
|
||||||
const volumes: RuntimeBoxVolumeCollection = {
|
const volumes: RuntimeBoxVolumeCollection = {
|
||||||
fog: [],
|
fog: [],
|
||||||
@@ -2069,6 +2088,7 @@ export function buildRuntimeSceneFromDocument(
|
|||||||
staticColliders,
|
staticColliders,
|
||||||
colliders,
|
colliders,
|
||||||
sceneBounds: combinedSceneBounds,
|
sceneBounds: combinedSceneBounds,
|
||||||
|
foliage,
|
||||||
modelInstances,
|
modelInstances,
|
||||||
paths,
|
paths,
|
||||||
npcDefinitions: collections.npcDefinitions,
|
npcDefinitions: collections.npcDefinitions,
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ import {
|
|||||||
disposeModelInstance,
|
disposeModelInstance,
|
||||||
syncModelInstanceSelectionShell
|
syncModelInstanceSelectionShell
|
||||||
} from "../assets/model-instance-rendering";
|
} from "../assets/model-instance-rendering";
|
||||||
|
import { FoliageInstancedRenderer } from "../foliage/foliage-instanced-renderer";
|
||||||
import type { LoadedModelAsset } from "../assets/gltf-model-import";
|
import type { LoadedModelAsset } from "../assets/gltf-model-import";
|
||||||
import type { LoadedImageAsset } from "../assets/image-assets";
|
import type { LoadedImageAsset } from "../assets/image-assets";
|
||||||
import type { ProjectAssetRecord } from "../assets/project-assets";
|
import type { ProjectAssetRecord } from "../assets/project-assets";
|
||||||
@@ -840,6 +841,11 @@ export class ViewportHost {
|
|||||||
LightVolumeRenderObjects
|
LightVolumeRenderObjects
|
||||||
>();
|
>();
|
||||||
private readonly modelRenderObjects = new Map<string, Group>();
|
private readonly modelRenderObjects = new Map<string, Group>();
|
||||||
|
private readonly foliageRenderer = new FoliageInstancedRenderer({
|
||||||
|
onRebuilt: () => {
|
||||||
|
this.applyShadowState();
|
||||||
|
}
|
||||||
|
});
|
||||||
private readonly materialTextureCache = new Map<
|
private readonly materialTextureCache = new Map<
|
||||||
string,
|
string,
|
||||||
CachedMaterialTexture
|
CachedMaterialTexture
|
||||||
@@ -1043,6 +1049,8 @@ export class ViewportHost {
|
|||||||
this.scene.add(this.lightVolumeGroup);
|
this.scene.add(this.lightVolumeGroup);
|
||||||
this.scene.add(this.brushGroup);
|
this.scene.add(this.brushGroup);
|
||||||
this.scene.add(this.terrainGroup);
|
this.scene.add(this.terrainGroup);
|
||||||
|
this.scene.add(this.foliageRenderer.group);
|
||||||
|
this.syncFoliageVisibility();
|
||||||
this.terrainBrushPreviewGroup.visible = false;
|
this.terrainBrushPreviewGroup.visible = false;
|
||||||
this.terrainBrushPreviewLine.frustumCulled = false;
|
this.terrainBrushPreviewLine.frustumCulled = false;
|
||||||
this.terrainBrushPreviewCenter.frustumCulled = false;
|
this.terrainBrushPreviewCenter.frustumCulled = false;
|
||||||
@@ -1358,6 +1366,7 @@ export class ViewportHost {
|
|||||||
this.currentActiveSelectionId
|
this.currentActiveSelectionId
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
this.rebuildFoliage(document);
|
||||||
this.rebuildPaths(document, this.currentSelection);
|
this.rebuildPaths(document, this.currentSelection);
|
||||||
this.rebuildEntityMarkers(document, this.currentSelection);
|
this.rebuildEntityMarkers(document, this.currentSelection);
|
||||||
this.rebuildModelInstances(document, this.currentSelection);
|
this.rebuildModelInstances(document, this.currentSelection);
|
||||||
@@ -1813,6 +1822,7 @@ export class ViewportHost {
|
|||||||
this.clearLightVolumes();
|
this.clearLightVolumes();
|
||||||
this.clearBrushMeshes();
|
this.clearBrushMeshes();
|
||||||
this.clearTerrains();
|
this.clearTerrains();
|
||||||
|
this.foliageRenderer.dispose();
|
||||||
this.clearPaths();
|
this.clearPaths();
|
||||||
this.clearEntityMarkers();
|
this.clearEntityMarkers();
|
||||||
this.creationPreviewChangeHandler = null;
|
this.creationPreviewChangeHandler = null;
|
||||||
|
|||||||
Reference in New Issue
Block a user