upatde(fabrik): zone + herbe
🔍 Lint / 🪄 Check lint (pull_request) Has been cancelled
🔍 Lint / 🎨 Check format (pull_request) Has been cancelled
🔍 Lint / 🔎 Typecheck (pull_request) Has been cancelled
📊 Quality / 🔒 Security Audit (pull_request) Has been cancelled
📊 Quality / 📋 Dependency Freshness (pull_request) Has been cancelled
📊 Quality / 📦 Bundle Size (pull_request) Has been cancelled
🔍 Lint / 🏗 Build (pull_request) Has been cancelled
🔍 Lint / 🪄 Check lint (pull_request) Has been cancelled
🔍 Lint / 🎨 Check format (pull_request) Has been cancelled
🔍 Lint / 🔎 Typecheck (pull_request) Has been cancelled
📊 Quality / 🔒 Security Audit (pull_request) Has been cancelled
📊 Quality / 📋 Dependency Freshness (pull_request) Has been cancelled
📊 Quality / 📦 Bundle Size (pull_request) Has been cancelled
🔍 Lint / 🏗 Build (pull_request) Has been cancelled
This commit is contained in:
@@ -15,7 +15,7 @@ export const EBIKE_DROP_PLAYER_TRANSFORM: CameraTransform = {
|
||||
rotation: [0, 0, 0],
|
||||
};
|
||||
|
||||
export const EBIKE_WORLD_POSITION: Vector3Tuple = [61.5, 10, 62.4];
|
||||
export const EBIKE_WORLD_POSITION: Vector3Tuple = [61.5, 8.4, 62.4];
|
||||
export const EBIKE_WORLD_ROTATION_Y = 2.4107;
|
||||
|
||||
export const EBIKE_INTRO_RIDE_DURATION_MS = 5000;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Vector3Tuple } from "@/types/three/three";
|
||||
import { LA_FABRIK_PLAYER_SPAWN } from "@/data/world/laFabrikConfig";
|
||||
|
||||
export const PLAYER_EYE_HEIGHT = 1.75;
|
||||
export const PLAYER_CAPSULE_RADIUS = 0.35;
|
||||
@@ -14,5 +15,5 @@ export const PLAYER_XZ_DAMPING_FACTOR = 8;
|
||||
export const PLAYER_FALL_RESPAWN_Y = -20;
|
||||
export const PLAYER_FALL_RESPAWN_DELAY = 3;
|
||||
|
||||
export const PLAYER_SPAWN_POSITION_GAME: Vector3Tuple = [59.5, 10, 64.64];
|
||||
export const PLAYER_SPAWN_POSITION_GAME: Vector3Tuple = LA_FABRIK_PLAYER_SPAWN;
|
||||
export const PLAYER_SPAWN_POSITION_PHYSICS: Vector3Tuple = [0, 3, 0];
|
||||
|
||||
@@ -11,6 +11,7 @@ export interface CharacterConfig {
|
||||
scale: Vector3Tuple;
|
||||
animations: readonly string[];
|
||||
defaultAnimation: string;
|
||||
snapToTerrain?: boolean;
|
||||
}
|
||||
|
||||
export const CHARACTER_CONFIGS = {
|
||||
@@ -28,11 +29,12 @@ export const CHARACTER_CONFIGS = {
|
||||
id: "gerant",
|
||||
label: "Gerant",
|
||||
modelPath: "/models/gerant-animated/model.gltf",
|
||||
position: [59.5, 0, 64.64],
|
||||
position: [59.5, 6.3, 64.64],
|
||||
rotation: [0, 2.41, 0],
|
||||
scale: [1, 1, 1],
|
||||
animations: ["idle", "walk"],
|
||||
defaultAnimation: "idle",
|
||||
snapToTerrain: false,
|
||||
},
|
||||
fermier: {
|
||||
id: "fermier",
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
import * as THREE from "three";
|
||||
import type { Vector3Tuple } from "@/types/three/three";
|
||||
|
||||
export const LA_FABRIK_CENTER: Vector3Tuple = [59.4973, 6.2746, 64.6354];
|
||||
export const LA_FABRIK_ROTATION_Y = 2.4107;
|
||||
export const LA_FABRIK_HALF_EXTENTS = {
|
||||
x: 8.5,
|
||||
z: 7.5,
|
||||
} as const;
|
||||
export const LA_FABRIK_FLOOR_Y = 6.3;
|
||||
export const LA_FABRIK_PLAYER_SPAWN: Vector3Tuple = [59.5, 8.05, 64.64];
|
||||
export const LA_FABRIK_INTERIOR_LIGHT_POSITION: Vector3Tuple = [59.5, 9, 64.64];
|
||||
|
||||
const _terrainMatrix = new THREE.Matrix4();
|
||||
const _meshWorldMatrix = new THREE.Matrix4();
|
||||
const _inverseMeshWorldMatrix = new THREE.Matrix4();
|
||||
const _worldPosition = new THREE.Vector3();
|
||||
|
||||
export function isInsideLaFabrikFootprint(
|
||||
x: number,
|
||||
z: number,
|
||||
padding = 0,
|
||||
): boolean {
|
||||
const dx = x - LA_FABRIK_CENTER[0];
|
||||
const dz = z - LA_FABRIK_CENTER[2];
|
||||
const cos = Math.cos(-LA_FABRIK_ROTATION_Y);
|
||||
const sin = Math.sin(-LA_FABRIK_ROTATION_Y);
|
||||
const localX = dx * cos - dz * sin;
|
||||
const localZ = dx * sin + dz * cos;
|
||||
|
||||
return (
|
||||
Math.abs(localX) <= LA_FABRIK_HALF_EXTENTS.x + padding &&
|
||||
Math.abs(localZ) <= LA_FABRIK_HALF_EXTENTS.z + padding
|
||||
);
|
||||
}
|
||||
|
||||
export function flattenLaFabrikTerrainFootprint(
|
||||
object: THREE.Object3D,
|
||||
position: Vector3Tuple,
|
||||
rotation: Vector3Tuple,
|
||||
scale: Vector3Tuple,
|
||||
): void {
|
||||
_terrainMatrix.compose(
|
||||
new THREE.Vector3(...position),
|
||||
new THREE.Quaternion().setFromEuler(new THREE.Euler(...rotation)),
|
||||
new THREE.Vector3(...scale),
|
||||
);
|
||||
object.updateMatrixWorld(true);
|
||||
|
||||
object.traverse((child) => {
|
||||
if (!(child instanceof THREE.Mesh)) return;
|
||||
const geometry = child.geometry;
|
||||
const positions = geometry.getAttribute("position");
|
||||
if (!positions) return;
|
||||
|
||||
_meshWorldMatrix.multiplyMatrices(_terrainMatrix, child.matrixWorld);
|
||||
_inverseMeshWorldMatrix.copy(_meshWorldMatrix).invert();
|
||||
|
||||
for (let index = 0; index < positions.count; index++) {
|
||||
_worldPosition
|
||||
.fromBufferAttribute(positions, index)
|
||||
.applyMatrix4(_meshWorldMatrix);
|
||||
|
||||
if (!isInsideLaFabrikFootprint(_worldPosition.x, _worldPosition.z, 0.8)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
_worldPosition.y = Math.min(_worldPosition.y, LA_FABRIK_FLOOR_Y - 0.35);
|
||||
_worldPosition.applyMatrix4(_inverseMeshWorldMatrix);
|
||||
positions.setXYZ(
|
||||
index,
|
||||
_worldPosition.x,
|
||||
_worldPosition.y,
|
||||
_worldPosition.z,
|
||||
);
|
||||
}
|
||||
|
||||
positions.needsUpdate = true;
|
||||
geometry.computeVertexNormals();
|
||||
geometry.computeBoundingBox();
|
||||
geometry.computeBoundingSphere();
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user