Refactor start base to use GLB model instead of procedural geometry
All checks were successful
Build / build (push) Successful in 1m20s

- Create buildStarBase function in src/starBase.ts
- Load base.glb model asynchronously with SceneLoader
- Extract child mesh from imported model similar to ship implementation
- Pass position parameter to buildStarBase function
- Update levelDeserializer to call buildStarBase instead of creating cylinder
- Add static physics body with MESH shape for proper collision
- Add debug logging for base mesh loading and bounds
- Remove inline cylinder creation code from createStartBase

The start base now uses a proper 3D model instead of a simple cylinder,
providing better visual quality and more accurate collision detection.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Michael Mainguy 2025-10-31 15:59:46 -05:00
parent b4608e10d8
commit 3e36662031
3 changed files with 47 additions and 25 deletions

BIN
public/base.glb Normal file

Binary file not shown.

View File

@ -28,6 +28,7 @@ import {
import { FireProceduralTexture } from "@babylonjs/procedural-textures";
import {createSphereLightmap} from "./sphereLightmap";
import { GameConfig } from "./gameConfig";
import buildStarBase from "./starBase";
import { MaterialFactory } from "./materialFactory";
import debugLog from './debug';
@ -60,7 +61,7 @@ export class LevelDeserializer {
debugLog('Deserializing level:', this.config.difficulty);
// Create entities
const startBase = this.createStartBase();
const startBase = await this.createStartBase();
const sun = this.createSun();
const planets = this.createPlanets();
const asteroids = await this.createAsteroids(scoreObservable);
@ -76,33 +77,14 @@ export class LevelDeserializer {
/**
* Create the start base from config
*/
private createStartBase(): AbstractMesh {
private async createStartBase(): Promise<AbstractMesh> {
const config = this.config.startBase;
const position = this.arrayToVector3(config.position);
const mesh = MeshBuilder.CreateCylinder("startBase", {
diameter: config.diameter,
height: config.height,
tessellation: 72
}, this.scene);
// Call the buildStarBase function to load and configure the base
const baseMesh = await buildStarBase(position);
mesh.position = this.arrayToVector3(config.position);
const material = new StandardMaterial("startBaseMaterial", this.scene);
if (config.color) {
material.diffuseColor = new Color3(config.color[0], config.color[1], config.color[2]);
} else {
material.diffuseColor = new Color3(1, 1, 0); // Default yellow
}
mesh.material = material;
// Only create physics if enabled in config
const gameConfig = GameConfig.getInstance();
if (gameConfig.physicsEnabled) {
const agg = new PhysicsAggregate(mesh, PhysicsShapeType.CONVEX_HULL, { mass: 0 }, this.scene);
agg.body.setMotionType(PhysicsMotionType.ANIMATED);
}
return mesh;
return baseMesh;
}
/**

40
src/starBase.ts Normal file
View File

@ -0,0 +1,40 @@
import {
AbstractMesh,
PhysicsAggregate,
PhysicsMotionType,
PhysicsShapeType,
SceneLoader,
Vector3
} from "@babylonjs/core";
import {DefaultScene} from "./defaultScene";
import {GameConfig} from "./gameConfig";
import {debug} from "openai/core";
import debugLog from "./debug";
/**
* Create and load the star base mesh
* @param position - Position for the star base
* @returns Promise resolving to the loaded star base mesh
*/
export default async function buildStarBase(position: Vector3): Promise<AbstractMesh> {
const scene = DefaultScene.MainScene;
// Load the base model
const importMesh = await SceneLoader.ImportMeshAsync(null, "./", "base.glb", scene);
const baseMesh = importMesh.meshes[0].getChildMeshes()[0];
debugLog('Star base mesh loaded:', baseMesh);
baseMesh.id = "starBase";
baseMesh.name = "starBase";
baseMesh.position = position;
debugLog('Ship Bounds radius', baseMesh.getBoundingInfo().boundingSphere.radiusWorld);
// Create physics if enabled
const config = GameConfig.getInstance();
if (config.physicsEnabled) {
const agg = new PhysicsAggregate(baseMesh, PhysicsShapeType.MESH, {
mass: 0
}, scene);
agg.body.setMotionType(PhysicsMotionType.STATIC);
}
return baseMesh;
}