day 5
This commit is contained in:
+105
-9
@@ -1,6 +1,12 @@
|
||||
import { Object3D } from "three";
|
||||
import { Box3, BoxGeometry, Mesh, Object3D, Vector3 } from "three";
|
||||
import { ThreeC } from "../ThreeC";
|
||||
import { PhysicsBody, PhysicsLayer } from "../PhysicsC";
|
||||
import { PhysicsTriggerC } from "./PhysicsTriggerC";
|
||||
import { PropC } from "./PropC";
|
||||
import { resolvePropType } from "../Resources/PropDropTable";
|
||||
|
||||
const MAP_PHYSICS_LAYERS = ["Colliders", "Lootable"];
|
||||
const GATHER_TRIGGER_PADDING = 0.2;
|
||||
|
||||
export class Map {
|
||||
static Init() {
|
||||
@@ -14,19 +20,109 @@ export class Map {
|
||||
ThreeC.setShadowsStateForChildren(mapObject, true, true);
|
||||
ThreeC.addToScene(mapObject);
|
||||
|
||||
const colliders = mapObject.getObjectByName("Colliders");
|
||||
if (colliders) {
|
||||
colliders.visible = false;
|
||||
this.buildColliders(colliders);
|
||||
PhysicsTriggerC.init();
|
||||
this.buildPhysics(mapObject);
|
||||
}
|
||||
|
||||
private static buildPhysics(mapObject: Object3D) {
|
||||
for (const layerName of MAP_PHYSICS_LAYERS) {
|
||||
const layer = mapObject.getObjectByName(layerName);
|
||||
if (!layer) {
|
||||
console.warn(`Map physics layer not found: ${layerName}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (layerName === "Colliders") {
|
||||
layer.visible = false;
|
||||
this.addWallPhysics(layer);
|
||||
continue;
|
||||
}
|
||||
|
||||
layer.children.forEach((lootableObject) => {
|
||||
this.setupLootableObject(lootableObject);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static buildColliders(collidersRoot: Object3D) {
|
||||
collidersRoot.traverse((child) => {
|
||||
if (child === collidersRoot) return;
|
||||
if ((child as any).isMesh) {
|
||||
private static addWallPhysics(root: Object3D) {
|
||||
root.traverse((child) => {
|
||||
if (child === root) return;
|
||||
if ((child as Mesh).isMesh) {
|
||||
new PhysicsBody(child, false, 0, PhysicsLayer.Wall, PhysicsLayer.Player);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static setupLootableObject(lootableObject: Object3D) {
|
||||
const propType = resolvePropType(lootableObject.name);
|
||||
const prop = new PropC(lootableObject, propType);
|
||||
const colliderMesh = this.findMesh(lootableObject, (name) => name.includes("collider"));
|
||||
const visualMeshes = this.getVisualMeshes(lootableObject);
|
||||
|
||||
if (colliderMesh) {
|
||||
colliderMesh.visible = false;
|
||||
prop.addWallBody(
|
||||
new PhysicsBody(colliderMesh, false, 0, PhysicsLayer.Wall, PhysicsLayer.Player),
|
||||
);
|
||||
} else {
|
||||
visualMeshes.forEach((mesh) => {
|
||||
prop.addWallBody(
|
||||
new PhysicsBody(mesh, false, 0, PhysicsLayer.Wall, PhysicsLayer.Player),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
PhysicsTriggerC.register(this.createGatherTrigger(lootableObject), lootableObject);
|
||||
}
|
||||
|
||||
private static findMesh(
|
||||
root: Object3D,
|
||||
matcher: (name: string) => boolean,
|
||||
): Mesh | null {
|
||||
let found: Mesh | null = null;
|
||||
|
||||
root.traverse((child) => {
|
||||
if (found) return;
|
||||
if ((child as Mesh).isMesh && matcher(child.name.toLowerCase())) {
|
||||
found = child as Mesh;
|
||||
}
|
||||
});
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
private static getVisualMeshes(root: Object3D): Mesh[] {
|
||||
const visualMeshes: Mesh[] = [];
|
||||
|
||||
root.traverse((child) => {
|
||||
if (!(child as Mesh).isMesh) return;
|
||||
|
||||
const name = child.name.toLowerCase();
|
||||
if (name.includes("collider") || name.includes("trigger") || name.includes("gathertrigger")) return;
|
||||
|
||||
visualMeshes.push(child as Mesh);
|
||||
});
|
||||
|
||||
return visualMeshes;
|
||||
}
|
||||
|
||||
private static createGatherTrigger(lootableObject: Object3D): Mesh {
|
||||
lootableObject.updateWorldMatrix(true, true);
|
||||
|
||||
const size = new Vector3();
|
||||
new Box3().setFromObject(lootableObject).getSize(size);
|
||||
|
||||
const triggerMesh = new Mesh(
|
||||
new BoxGeometry(
|
||||
size.x + GATHER_TRIGGER_PADDING * 2,
|
||||
size.y + GATHER_TRIGGER_PADDING * 2,
|
||||
size.z + GATHER_TRIGGER_PADDING * 2,
|
||||
),
|
||||
);
|
||||
triggerMesh.visible = false;
|
||||
triggerMesh.name = "GatherTrigger";
|
||||
lootableObject.add(triggerMesh);
|
||||
|
||||
return triggerMesh;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user