This commit is contained in:
Brian Beck 2025-09-11 21:08:56 -07:00
parent 267db90813
commit 8509faf6bc
782 changed files with 165 additions and 21 deletions

View file

@ -9,7 +9,7 @@ import {
import { parseTerrainBuffer } from "@/src/terrain"; import { parseTerrainBuffer } from "@/src/terrain";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"; import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { getTerrainFile, parseMissionScript } from "@/src/mission"; import { getTerrainFile, iterObjects, parseMissionScript } from "@/src/mission";
const BASE_URL = "/t2-mapper"; const BASE_URL = "/t2-mapper";
const RESOURCE_ROOT_URL = `${BASE_URL}/base/`; const RESOURCE_ROOT_URL = `${BASE_URL}/base/`;
@ -33,6 +33,14 @@ function terrainTextureToUrl(name: string) {
} }
} }
function textureToUrl(name: string) {
try {
return getUrlForPath(`textures/${name}.png`);
} catch (err) {
return `${BASE_URL}/black.png`;
}
}
function uint16ToFloat32(src: Uint16Array) { function uint16ToFloat32(src: Uint16Array) {
const out = new Float32Array(src.length); const out = new Float32Array(src.length);
for (let i = 0; i < src.length; i++) { for (let i = 0; i < src.length; i++) {
@ -78,7 +86,7 @@ const missions = getResourceList()
export default function HomePage() { export default function HomePage() {
const canvasRef = useRef<HTMLCanvasElement>(null); const canvasRef = useRef<HTMLCanvasElement>(null);
const [missionName, setMissionName] = useState("TWL_Damnation"); const [missionName, setMissionName] = useState("TWL2_WoodyMyrk");
const threeContext = useRef<Record<string, any>>({}); const threeContext = useRef<Record<string, any>>({});
useEffect(() => { useEffect(() => {
@ -138,14 +146,14 @@ export default function HomePage() {
scene.add(light); scene.add(light);
const controls = new OrbitControls(camera, renderer.domElement); const controls = new OrbitControls(camera, renderer.domElement);
controls.target.set(0, 0, 0); controls.minDistance = 10;
controls.maxDistance = 1000;
camera.position.set(0, 0, 512);
controls.target.set(0, -128, 0);
controls.update(); controls.update();
const keys = { w: false, a: false, s: false, d: false }; const keys = { w: false, a: false, s: false, d: false };
camera.position.set(100, 15, 100);
camera.lookAt(0, 0, -200);
const onKeyDown = (e) => { const onKeyDown = (e) => {
if (e.code === "KeyW") keys.w = true; if (e.code === "KeyW") keys.w = true;
if (e.code === "KeyA") keys.a = true; if (e.code === "KeyA") keys.a = true;
@ -221,7 +229,7 @@ export default function HomePage() {
threeContext.current; threeContext.current;
let cancel = false; let cancel = false;
let mesh: THREE.Mesh; let root: THREE.Group;
async function loadMap() { async function loadMap() {
const mission = await loadMission(missionName); const mission = await loadMission(missionName);
@ -361,22 +369,62 @@ uniform float tiling5;
); );
}; };
mesh = new THREE.Mesh(geom, mat); root = new THREE.Group();
const mesh = new THREE.Mesh(geom, mat);
root.add(mesh);
for (const obj of iterObjects(mission.objects)) {
const getProperty = (name) =>
obj.properties.find((p) => p.target.name === name);
switch (obj.className) {
case "WaterBlock": {
break;
const position = getProperty("position").value;
const scale = getProperty("scale").value;
const rotation = getProperty("rotation").value;
const surfaceTexture = getProperty("surfaceTexture").value;
const [x, y, z] = position.split(" ").map((s) => parseFloat(s));
const [ax, ay, az, angle] = rotation
.split(" ")
.map((s) => parseFloat(s));
const q = new THREE.Quaternion();
q.setFromAxisAngle(new THREE.Vector3(ax, az, ay), angle);
const [scaleX, scaleY, scaleZ] = scale
.split(" ")
.map((s) => parseFloat(s) / 2);
const geometry = new THREE.BoxGeometry(scaleX, scaleZ, scaleY);
const material = new THREE.MeshStandardMaterial({
map: setupColor(textureLoader.load(textureToUrl(surfaceTexture))),
});
const water = new THREE.Mesh(geometry, material);
water.position.set(x, z, y);
water.quaternion.copy(q);
root.add(water);
break;
}
}
}
if (cancel) { if (cancel) {
return; return;
} }
scene.add(mesh); scene.add(root);
} }
loadMap(); loadMap();
return () => { return () => {
cancel = true; cancel = true;
if (mesh) { root.removeFromParent();
mesh.removeFromParent();
}
}; };
}, [missionName]); }, [missionName]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show more