Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[client] 3d models code and assets cleanup #2633

Merged
merged 14 commits into from
Jan 17, 2025
2 changes: 1 addition & 1 deletion .knip.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"**/vitest**",
"client/apps/game/src/setupTests.ts",

"client/sdk/packages/eternum/global.d.ts",
"client/sdk/packages/core/global.d.ts",

"**/**__test__**/**",
"**/**__tests__**/**",
Expand Down
102 changes: 63 additions & 39 deletions client/apps/game/src/three/managers/building-preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import { HoverSound } from "@/three/sound/hover-sound";
import { BuildingType, ResourceIdToMiningType, ResourceMiningTypes, ResourcesIds } from "@bibliothecadao/eternum";
import { useUIStore } from "@bibliothecadao/react";
import * as THREE from "three";
import { BUILDINGS_GROUPS } from "../scenes/constants";

export class BuildingPreview {
private previewBuilding: { type: BuildingType; resource?: ResourcesIds } | null = null;
private modelLoadPromises: Promise<void>[] = [];
private buildingModels: Map<BuildingType | ResourceMiningTypes, THREE.Group> = new Map();
private buildingModels: Map<BUILDINGS_GROUPS, Map<string, THREE.Group>> = new Map();
private currentHexHovered: THREE.Vector3 | null = null;
private hoverSound: HoverSound;

Expand All @@ -19,55 +20,76 @@ export class BuildingPreview {

private loadBuildingModels() {
const loader = gltfLoader;
for (const [building, path] of Object.entries(buildingModelPaths)) {
const loadPromise = new Promise<void>((resolve, reject) => {
loader.load(
path,
(gltf) => {
const model = gltf.scene as THREE.Group;
model.position.set(0, -100, 0);
gltf.scene.traverse((child: any) => {
if (child.isMesh) {
child.material.color.set(PREVIEW_BUILD_COLOR_VALID);
child.material.transparent = true;
child.material.opacity = 0.75;
}
});
this.buildingModels.set((building + "") as any, model);
resolve();
},
undefined,
(error) => {
console.error(`Error loading ${building} model:`, error);
reject(error);
},
);
});
this.modelLoadPromises.push(loadPromise);
for (const group of Object.values(BUILDINGS_GROUPS)) {
const groupPaths = buildingModelPaths[group];
if (!this.buildingModels.has(group)) {
this.buildingModels.set(group, new Map());
}
const groupMap = this.buildingModels.get(group)!;

for (const [building, path] of Object.entries(groupPaths)) {
const loadPromise = new Promise<void>((resolve, reject) => {
loader.load(
path,
(gltf) => {
const model = gltf.scene as THREE.Group;
model.position.set(0, -100, 0);
gltf.scene.traverse((child: any) => {
if (child.isMesh) {
child.material.color.set(PREVIEW_BUILD_COLOR_VALID);
child.material.transparent = true;
child.material.opacity = 0.75;
}
});
groupMap.set(building as any, model);
resolve();
},
undefined,
(error) => {
console.error(`Error loading ${building} model:`, error);
reject(error);
},
);
});
this.modelLoadPromises.push(loadPromise);
}
}

Promise.all(this.modelLoadPromises).then(() => {});
}

public getBuildingModel(building: BuildingType | ResourceMiningTypes): THREE.Group | null {
return this.buildingModels.get((building + "") as any) || null;
public getBuildingModel(
group: BUILDINGS_GROUPS | null,
building: BuildingType | ResourceMiningTypes | null,
): THREE.Group | null {
if (!group || !building) return null;
const categoryMap = this.buildingModels.get(group);
console.log("categoryMap", categoryMap);
if (categoryMap) {
console.log("building", categoryMap.get(building + ""));
return categoryMap.get(building + "") || null;
}
return null;
}

public getBuildingType() {
public getBuildingType(): {
buildingGroup: BUILDINGS_GROUPS | null;
buildingType: BuildingType | ResourceMiningTypes | null;
} {
const building = this.previewBuilding;
if (!building) return null;
const buildingType = building.resource ? ResourceIdToMiningType[building.resource as ResourcesIds] : building.type;
return buildingType;
if (!building) return { buildingGroup: null, buildingType: null };
const buildingGroup = building.resource ? BUILDINGS_GROUPS.RESOURCES_MINING : BUILDINGS_GROUPS.BUILDINGS;
const buildingType = building.resource ? ResourceIdToMiningType[building.resource as ResourcesIds]! : building.type;
return { buildingGroup, buildingType };
}

public setPreviewBuilding(building: { type: BuildingType; resource?: ResourcesIds }) {
if (this.previewBuilding) {
this.clearPreviewBuilding();
}
this.previewBuilding = building;
const buildingType = building.resource ? ResourceIdToMiningType[building.resource as ResourcesIds] : building.type;
const model = this.getBuildingModel(buildingType as BuildingType | ResourceMiningTypes);

const { buildingGroup, buildingType } = this.getBuildingType();
const model = this.getBuildingModel(buildingGroup, buildingType as BuildingType | ResourceMiningTypes);
if (model) {
this.scene.add(model);
}
Expand All @@ -79,7 +101,8 @@ export class BuildingPreview {

public clearPreviewBuilding() {
if (this.previewBuilding) {
const model = this.getBuildingModel(this.getBuildingType() as BuildingType | ResourceMiningTypes);
const { buildingGroup, buildingType } = this.getBuildingType();
const model = this.getBuildingModel(buildingGroup, buildingType as BuildingType | ResourceMiningTypes);
if (model) {
this.scene.remove(model);
this.previewBuilding = null;
Expand All @@ -94,8 +117,8 @@ export class BuildingPreview {
this.hoverSound.play(isSoundOn, effectsLevel);
this.currentHexHovered = position;
}

const model = this.getBuildingModel(this.getBuildingType() as BuildingType | ResourceMiningTypes);
const { buildingGroup, buildingType } = this.getBuildingType();
const model = this.getBuildingModel(buildingGroup, buildingType as BuildingType | ResourceMiningTypes);
if (model) {
model.position.copy(position);
model.updateMatrixWorld();
Expand All @@ -105,7 +128,8 @@ export class BuildingPreview {

public setBuildingColor(color: THREE.Color) {
if (this.previewBuilding) {
const model = this.getBuildingModel(this.getBuildingType() as BuildingType | ResourceMiningTypes);
const { buildingGroup, buildingType } = this.getBuildingType();
const model = this.getBuildingModel(buildingGroup, buildingType as BuildingType | ResourceMiningTypes);
if (model) {
model.traverse((child: any) => {
if (child.isMesh) {
Expand Down
Loading
Loading