Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cdd919c010 | |||
| cea2856fd0 | |||
| d245d6b460 | |||
| dba7aec6fa | |||
| d376d0ba6b | |||
| 242a3dcd37 | |||
| 225ac828df |
+10278
-5356
File diff suppressed because it is too large
Load Diff
+35051
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,124 @@
|
|||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
const INPUT_PATH = path.join(__dirname, "../public/map_raw.json");
|
||||||
|
const OUTPUT_PATH = path.join(__dirname, "../public/map.json");
|
||||||
|
|
||||||
|
const MESH_NAME_MAPPINGS = {
|
||||||
|
boitesauxlettres: "boiteauxlettres",
|
||||||
|
pyloneelectrique: "pylone",
|
||||||
|
eoliennes: "eolienne",
|
||||||
|
immeuble_1: "immeuble1",
|
||||||
|
buissons: "buisson",
|
||||||
|
panneauxquartier: "panneauaffichage",
|
||||||
|
};
|
||||||
|
|
||||||
|
const REMOVED_NODE_NAMES = new Set(["ROOT", "mc"]);
|
||||||
|
|
||||||
|
function cloneNode(node) {
|
||||||
|
return {
|
||||||
|
name: node.name,
|
||||||
|
type: node.type,
|
||||||
|
position: node.position,
|
||||||
|
rotation: node.rotation,
|
||||||
|
scale: node.scale,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapMeshName(node) {
|
||||||
|
if (node.type !== "Mesh") {
|
||||||
|
return cloneNode(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...cloneNode(node),
|
||||||
|
name: MESH_NAME_MAPPINGS[node.name] ?? node.name,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function createGroup(node, children = []) {
|
||||||
|
return {
|
||||||
|
...cloneNode(node),
|
||||||
|
name: node.name === "Neutre" ? "blocking" : node.name,
|
||||||
|
children,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function transformMap() {
|
||||||
|
console.log("Reading map_raw.json...");
|
||||||
|
const rawData = JSON.parse(fs.readFileSync(INPUT_PATH, "utf-8"));
|
||||||
|
console.log(`Found ${rawData.length} nodes in raw file`);
|
||||||
|
|
||||||
|
let removedCount = 0;
|
||||||
|
let renamedCount = 0;
|
||||||
|
|
||||||
|
const sceneRaw = rawData.find(
|
||||||
|
(node) => node.name === "Scene" && node.type === "Object3D",
|
||||||
|
);
|
||||||
|
const terrainRaw = rawData.find(
|
||||||
|
(node) => node.name === "terrain" && node.type === "Object3D",
|
||||||
|
);
|
||||||
|
const blockingRaw = rawData.find(
|
||||||
|
(node) => node.name === "Neutre" && node.type === "Object3D",
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!sceneRaw || !terrainRaw || !blockingRaw) {
|
||||||
|
throw new Error("Missing required Scene, terrain, or Neutre node");
|
||||||
|
}
|
||||||
|
|
||||||
|
const scene = createGroup(sceneRaw);
|
||||||
|
const terrain = createGroup(terrainRaw);
|
||||||
|
const blocking = createGroup(blockingRaw);
|
||||||
|
let currentGroup = null;
|
||||||
|
|
||||||
|
for (const rawNode of rawData) {
|
||||||
|
if (REMOVED_NODE_NAMES.has(rawNode.name)) {
|
||||||
|
removedCount++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rawNode.name === "Scene" || rawNode.name === "Neutre") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rawNode.name === "terrain" && rawNode.type === "Object3D") {
|
||||||
|
currentGroup = terrain;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rawNode.type === "Object3D") {
|
||||||
|
currentGroup = createGroup(rawNode);
|
||||||
|
blocking.children.push(currentGroup);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mappedNode = mapMeshName(rawNode);
|
||||||
|
if (mappedNode.name !== rawNode.name) {
|
||||||
|
renamedCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rawNode.name === "terrain" && currentGroup === terrain) {
|
||||||
|
terrain.children.push(mappedNode);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentGroup) {
|
||||||
|
currentGroup.children.push(mappedNode);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
blocking.children.push(mappedNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
scene.children = [terrain, blocking];
|
||||||
|
|
||||||
|
console.log(`\nTransformation complete:`);
|
||||||
|
console.log(` - Removed ${removedCount} mc/ROOT nodes`);
|
||||||
|
console.log(` - Renamed ${renamedCount} mesh nodes`);
|
||||||
|
console.log(` - Output: hierarchical Scene root`);
|
||||||
|
|
||||||
|
fs.writeFileSync(OUTPUT_PATH, JSON.stringify(scene, null, 2));
|
||||||
|
console.log(`\nWritten to ${OUTPUT_PATH}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
transformMap();
|
||||||
@@ -3,7 +3,6 @@ import type { RefObject } from "react";
|
|||||||
import type { Object3D } from "three";
|
import type { Object3D } from "three";
|
||||||
import { Octree } from "three/addons/math/Octree.js";
|
import { Octree } from "three/addons/math/Octree.js";
|
||||||
import type { OctreeReadyHandler } from "@/types/three/three";
|
import type { OctreeReadyHandler } from "@/types/three/three";
|
||||||
import { logger } from "@/utils/core/Logger";
|
|
||||||
|
|
||||||
export function useOctreeGraphNode(
|
export function useOctreeGraphNode(
|
||||||
graphNodeRef: RefObject<Object3D | null>,
|
graphNodeRef: RefObject<Object3D | null>,
|
||||||
@@ -18,25 +17,16 @@ export function useOctreeGraphNode(
|
|||||||
}, [rebuildKey]);
|
}, [rebuildKey]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
logger.debug("useOctreeGraphNode", "Check", {
|
|
||||||
enabled,
|
|
||||||
octreeBuilt: octreeBuilt.current,
|
|
||||||
hasGraphNode: !!graphNodeRef.current,
|
|
||||||
rebuildKey,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!enabled) return;
|
if (!enabled) return;
|
||||||
|
|
||||||
const graphNode = graphNodeRef.current;
|
const graphNode = graphNodeRef.current;
|
||||||
if (!enabled || octreeBuilt.current || !graphNode) return;
|
if (!enabled || octreeBuilt.current || !graphNode) return;
|
||||||
octreeBuilt.current = true;
|
octreeBuilt.current = true;
|
||||||
|
|
||||||
logger.info("useOctreeGraphNode", "Building octree from graph node");
|
|
||||||
graphNode.updateMatrixWorld(true);
|
graphNode.updateMatrixWorld(true);
|
||||||
|
|
||||||
const octree = new Octree();
|
const octree = new Octree();
|
||||||
octree.fromGraphNode(graphNode);
|
octree.fromGraphNode(graphNode);
|
||||||
logger.info("useOctreeGraphNode", "Octree built, calling onOctreeReady");
|
|
||||||
onOctreeReady(octree);
|
onOctreeReady(octree);
|
||||||
}, [enabled, graphNodeRef, onOctreeReady, rebuildKey]);
|
}, [enabled, graphNodeRef, onOctreeReady, rebuildKey]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { useCallback, useEffect, useState } from "react";
|
|||||||
import type { Octree } from "three/addons/math/Octree.js";
|
import type { Octree } from "three/addons/math/Octree.js";
|
||||||
import type { SceneMode } from "@/types/debug/debug";
|
import type { SceneMode } from "@/types/debug/debug";
|
||||||
import type { SceneLoadingChangeHandler } from "@/types/world/sceneLoading";
|
import type { SceneLoadingChangeHandler } from "@/types/world/sceneLoading";
|
||||||
import { logger } from "@/utils/core/Logger";
|
|
||||||
|
|
||||||
interface UseWorldSceneLoadingOptions {
|
interface UseWorldSceneLoadingOptions {
|
||||||
onLoadingStateChange?: SceneLoadingChangeHandler | undefined;
|
onLoadingStateChange?: SceneLoadingChangeHandler | undefined;
|
||||||
@@ -32,12 +31,10 @@ export function useWorldSceneLoading({
|
|||||||
(sceneMode === "physics" && octree !== null);
|
(sceneMode === "physics" && octree !== null);
|
||||||
|
|
||||||
const handleGameMapLoaded = useCallback(() => {
|
const handleGameMapLoaded = useCallback(() => {
|
||||||
logger.info("WorldSceneLoading", "GameMap loaded");
|
|
||||||
setGameMapLoaded(true);
|
setGameMapLoaded(true);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleGameStageLoaded = useCallback(() => {
|
const handleGameStageLoaded = useCallback(() => {
|
||||||
logger.info("WorldSceneLoading", "GameStage loaded");
|
|
||||||
setGameStageLoaded(true);
|
setGameStageLoaded(true);
|
||||||
onLoadingStateChange?.({
|
onLoadingStateChange?.({
|
||||||
currentStep: "Initialisation gameplay",
|
currentStep: "Initialisation gameplay",
|
||||||
@@ -48,7 +45,6 @@ export function useWorldSceneLoading({
|
|||||||
|
|
||||||
const handleOctreeReady = useCallback(
|
const handleOctreeReady = useCallback(
|
||||||
(nextOctree: Octree) => {
|
(nextOctree: Octree) => {
|
||||||
logger.info("WorldSceneLoading", "Octree ready");
|
|
||||||
setOctree(nextOctree);
|
setOctree(nextOctree);
|
||||||
onLoadingStateChange?.({
|
onLoadingStateChange?.({
|
||||||
currentStep: "Collision prête",
|
currentStep: "Collision prête",
|
||||||
|
|||||||
@@ -8,6 +8,10 @@ export interface MapNode {
|
|||||||
scale: Vector3Tuple;
|
scale: Vector3Tuple;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface HierarchicalMapNode extends MapNode {
|
||||||
|
children?: HierarchicalMapNode[];
|
||||||
|
}
|
||||||
|
|
||||||
export interface SceneData {
|
export interface SceneData {
|
||||||
mapNodes: MapNode[];
|
mapNodes: MapNode[];
|
||||||
models: Map<string, string>;
|
models: Map<string, string>;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ const MAP_JSON_PATH = "/map.json";
|
|||||||
const MODEL_FILE_NAMES = ["model.glb", "model.gltf"];
|
const MODEL_FILE_NAMES = ["model.glb", "model.gltf"];
|
||||||
const HTML_CONTENT_TYPE = "text/html";
|
const HTML_CONTENT_TYPE = "text/html";
|
||||||
const MAP_STRUCTURE_NODE_NAMES = new Set(["Scene", "blocking"]);
|
const MAP_STRUCTURE_NODE_NAMES = new Set(["Scene", "blocking"]);
|
||||||
|
const POSITION_PRECISION = 3;
|
||||||
type ModelEntry = [modelName: string, modelUrl: string];
|
type ModelEntry = [modelName: string, modelUrl: string];
|
||||||
|
|
||||||
let cachedSceneData: SceneData | null = null;
|
let cachedSceneData: SceneData | null = null;
|
||||||
@@ -45,7 +46,42 @@ async function loadMapSceneDataInternal(): Promise<SceneData | null> {
|
|||||||
|
|
||||||
const mapPayload: unknown = await response.json();
|
const mapPayload: unknown = await response.json();
|
||||||
const mapNodes = parseMapNodes(mapPayload);
|
const mapNodes = parseMapNodes(mapPayload);
|
||||||
return createSceneData(mapNodes);
|
const deduplicatedNodes = deduplicateMapNodes(mapNodes);
|
||||||
|
return createSceneData(deduplicatedNodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createPositionKey(node: MapNode): string {
|
||||||
|
const [x, y, z] = node.position;
|
||||||
|
const px = x.toFixed(POSITION_PRECISION);
|
||||||
|
const py = y.toFixed(POSITION_PRECISION);
|
||||||
|
const pz = z.toFixed(POSITION_PRECISION);
|
||||||
|
return `${node.name}:${px},${py},${pz}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function deduplicateMapNodes(nodes: MapNode[]): MapNode[] {
|
||||||
|
const seen = new Set<string>();
|
||||||
|
const result: MapNode[] = [];
|
||||||
|
|
||||||
|
const sortedNodes = [...nodes].sort((a, b) => {
|
||||||
|
if (a.type === "Object3D" && b.type !== "Object3D") return -1;
|
||||||
|
if (a.type !== "Object3D" && b.type === "Object3D") return 1;
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const node of sortedNodes) {
|
||||||
|
if (MAP_STRUCTURE_NODE_NAMES.has(node.name)) {
|
||||||
|
result.push(node);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const key = createPositionKey(node);
|
||||||
|
if (!seen.has(key)) {
|
||||||
|
seen.add(key);
|
||||||
|
result.push(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createSceneData(mapNodes: MapNode[]): Promise<SceneData> {
|
async function createSceneData(mapNodes: MapNode[]): Promise<SceneData> {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { MapNode } from "../../types/editor/editor";
|
import type { HierarchicalMapNode, MapNode } from "../../types/editor/editor";
|
||||||
|
|
||||||
function isRecord(value: unknown): value is Record<string, unknown> {
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||||
return typeof value === "object" && value !== null;
|
return typeof value === "object" && value !== null;
|
||||||
@@ -26,10 +26,43 @@ function isMapNode(value: unknown): value is MapNode {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseMapNodes(value: unknown): MapNode[] {
|
function isHierarchicalMapNode(value: unknown): value is HierarchicalMapNode {
|
||||||
if (!Array.isArray(value) || !value.every(isMapNode)) {
|
if (!isMapNode(value)) {
|
||||||
throw new Error("Invalid map node data");
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
if (!("children" in value)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
value.children === undefined ||
|
||||||
|
(Array.isArray(value.children) &&
|
||||||
|
value.children.every(isHierarchicalMapNode))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function flattenMapNode(node: HierarchicalMapNode): MapNode[] {
|
||||||
|
const mapNode: MapNode = {
|
||||||
|
name: node.name,
|
||||||
|
type: node.type,
|
||||||
|
position: node.position,
|
||||||
|
rotation: node.rotation,
|
||||||
|
scale: node.scale,
|
||||||
|
};
|
||||||
|
const childNodes = node.children?.flatMap(flattenMapNode) ?? [];
|
||||||
|
|
||||||
|
return [mapNode, ...childNodes];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseMapNodes(value: unknown): MapNode[] {
|
||||||
|
if (Array.isArray(value) && value.every(isHierarchicalMapNode)) {
|
||||||
|
return value.flatMap(flattenMapNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isHierarchicalMapNode(value)) {
|
||||||
|
return flattenMapNode(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error("Invalid map node data");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ function disposeMaterial(material: THREE.Material): void {
|
|||||||
material.dispose();
|
material.dispose();
|
||||||
|
|
||||||
for (const key of Object.keys(material)) {
|
for (const key of Object.keys(material)) {
|
||||||
const value = (material as Record<string, unknown>)[key];
|
const value = (material as unknown as Record<string, unknown>)[key];
|
||||||
if (value instanceof THREE.Texture) {
|
if (value instanceof THREE.Texture) {
|
||||||
value.dispose();
|
value.dispose();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ interface LoadedMapNode {
|
|||||||
const MAP_STRUCTURE_NODE_NAMES = new Set(["Scene", "blocking"]);
|
const MAP_STRUCTURE_NODE_NAMES = new Set(["Scene", "blocking"]);
|
||||||
const LITE_MAP_SKIPPED_NODE_NAMES = new Set([
|
const LITE_MAP_SKIPPED_NODE_NAMES = new Set([
|
||||||
"arbre",
|
"arbre",
|
||||||
"buissons",
|
"buisson",
|
||||||
"champdeble",
|
"champdeble",
|
||||||
"champdesoja",
|
"champdesoja",
|
||||||
"champsdetournesol",
|
"champsdetournesol",
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import { useOctreeGraphNode } from "@/hooks/three/useOctreeGraphNode";
|
|||||||
import type { MapNode } from "@/types/editor/editor";
|
import type { MapNode } from "@/types/editor/editor";
|
||||||
import type { OctreeReadyHandler } from "@/types/three/three";
|
import type { OctreeReadyHandler } from "@/types/three/three";
|
||||||
import type { SceneLoadingChangeHandler } from "@/types/world/sceneLoading";
|
import type { SceneLoadingChangeHandler } from "@/types/world/sceneLoading";
|
||||||
import { logger } from "@/utils/core/Logger";
|
|
||||||
import { logModelLoadError } from "@/utils/three/modelLoadLogger";
|
import { logModelLoadError } from "@/utils/three/modelLoadLogger";
|
||||||
|
|
||||||
export interface GameMapCollisionNode {
|
export interface GameMapCollisionNode {
|
||||||
@@ -109,14 +108,6 @@ export function GameMapCollision({
|
|||||||
const collisionReady =
|
const collisionReady =
|
||||||
mapReady && settledCollisionNodeCount >= collisionNodes.length;
|
mapReady && settledCollisionNodeCount >= collisionNodes.length;
|
||||||
|
|
||||||
logger.debug("GameMapCollision", "State", {
|
|
||||||
mapReady,
|
|
||||||
collisionNodesCount: collisionNodes.length,
|
|
||||||
settledCollisionNodeCount,
|
|
||||||
collisionReady,
|
|
||||||
buildOctree,
|
|
||||||
});
|
|
||||||
|
|
||||||
const notifyLoaded = useCallback(() => {
|
const notifyLoaded = useCallback(() => {
|
||||||
if (loadedNotifiedRef.current) return;
|
if (loadedNotifiedRef.current) return;
|
||||||
|
|
||||||
@@ -133,7 +124,6 @@ export function GameMapCollision({
|
|||||||
|
|
||||||
const handleOctreeReady = useCallback<OctreeReadyHandler>(
|
const handleOctreeReady = useCallback<OctreeReadyHandler>(
|
||||||
(octree) => {
|
(octree) => {
|
||||||
logger.info("GameMapCollision", "Octree built, calling onOctreeReady");
|
|
||||||
onLoadingStateChange?.({
|
onLoadingStateChange?.({
|
||||||
currentStep: "Collision prête",
|
currentStep: "Collision prête",
|
||||||
progress: 0.92,
|
progress: 0.92,
|
||||||
|
|||||||
@@ -81,7 +81,10 @@ export function InstancedVegetation({
|
|||||||
);
|
);
|
||||||
|
|
||||||
for (let i = 0; i < matrices.length; i++) {
|
for (let i = 0; i < matrices.length; i++) {
|
||||||
instancedMesh.setMatrixAt(i, matrices[i]);
|
const matrix = matrices[i];
|
||||||
|
if (matrix) {
|
||||||
|
instancedMesh.setMatrixAt(i, matrix);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
instancedMesh.instanceMatrix.needsUpdate = true;
|
instancedMesh.instanceMatrix.needsUpdate = true;
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import type { MapNode } from "@/types/editor/editor";
|
|||||||
import type { Vector3Tuple } from "@/types/three/three";
|
import type { Vector3Tuple } from "@/types/three/three";
|
||||||
import { getMapNodes, loadMapSceneData } from "@/utils/map/loadMapSceneData";
|
import { getMapNodes, loadMapSceneData } from "@/utils/map/loadMapSceneData";
|
||||||
import {
|
import {
|
||||||
VEGETATION_MAX_INSTANCES,
|
|
||||||
VEGETATION_TYPES,
|
VEGETATION_TYPES,
|
||||||
type VegetationType,
|
type VegetationType,
|
||||||
} from "@/world/vegetation/vegetationConfig";
|
} from "@/world/vegetation/vegetationConfig";
|
||||||
@@ -31,8 +30,9 @@ function extractVegetationData(mapNodes: MapNode[]): VegetationData {
|
|||||||
if (!config.enabled) continue;
|
if (!config.enabled) continue;
|
||||||
|
|
||||||
const instances = mapNodes
|
const instances = mapNodes
|
||||||
.filter((node) => node.name === config.mapName)
|
.filter(
|
||||||
.slice(0, VEGETATION_MAX_INSTANCES)
|
(node) => node.name === config.mapName && node.type === "Object3D",
|
||||||
|
)
|
||||||
.map(mapNodeToInstance);
|
.map(mapNodeToInstance);
|
||||||
|
|
||||||
if (instances.length > 0) {
|
if (instances.length > 0) {
|
||||||
|
|||||||
@@ -4,15 +4,13 @@ export const VEGETATION_LOD = {
|
|||||||
windFadeEnd: 70,
|
windFadeEnd: 70,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const VEGETATION_MAX_INSTANCES = 500;
|
|
||||||
|
|
||||||
export const VEGETATION_TYPES = {
|
export const VEGETATION_TYPES = {
|
||||||
buissons: {
|
buissons: {
|
||||||
mapName: "buissons",
|
mapName: "buisson",
|
||||||
modelPath: "/models/buisson/model.gltf",
|
modelPath: "/models/buisson/model.gltf",
|
||||||
castShadow: true,
|
castShadow: true,
|
||||||
receiveShadow: true,
|
receiveShadow: true,
|
||||||
enabled: false,
|
enabled: true,
|
||||||
windEnabled: false,
|
windEnabled: false,
|
||||||
windIntensity: 1.2,
|
windIntensity: 1.2,
|
||||||
},
|
},
|
||||||
@@ -39,7 +37,7 @@ export const VEGETATION_TYPES = {
|
|||||||
modelPath: "/models/champdeble/model.gltf",
|
modelPath: "/models/champdeble/model.gltf",
|
||||||
castShadow: true,
|
castShadow: true,
|
||||||
receiveShadow: true,
|
receiveShadow: true,
|
||||||
enabled: false,
|
enabled: true,
|
||||||
windEnabled: false,
|
windEnabled: false,
|
||||||
windIntensity: 1.0,
|
windIntensity: 1.0,
|
||||||
},
|
},
|
||||||
@@ -48,7 +46,7 @@ export const VEGETATION_TYPES = {
|
|||||||
modelPath: "/models/champdesoja/model.gltf",
|
modelPath: "/models/champdesoja/model.gltf",
|
||||||
castShadow: true,
|
castShadow: true,
|
||||||
receiveShadow: true,
|
receiveShadow: true,
|
||||||
enabled: false,
|
enabled: true,
|
||||||
windEnabled: false,
|
windEnabled: false,
|
||||||
windIntensity: 1.0,
|
windIntensity: 1.0,
|
||||||
},
|
},
|
||||||
@@ -57,7 +55,7 @@ export const VEGETATION_TYPES = {
|
|||||||
modelPath: "/models/champsdetournesol/model.gltf",
|
modelPath: "/models/champsdetournesol/model.gltf",
|
||||||
castShadow: true,
|
castShadow: true,
|
||||||
receiveShadow: true,
|
receiveShadow: true,
|
||||||
enabled: false,
|
enabled: true,
|
||||||
windEnabled: false,
|
windEnabled: false,
|
||||||
windIntensity: 0.9,
|
windIntensity: 0.9,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user