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 { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
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 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) {
const out = new Float32Array(src.length);
for (let i = 0; i < src.length; i++) {
@ -78,7 +86,7 @@ const missions = getResourceList()
export default function HomePage() {
const canvasRef = useRef<HTMLCanvasElement>(null);
const [missionName, setMissionName] = useState("TWL_Damnation");
const [missionName, setMissionName] = useState("TWL2_WoodyMyrk");
const threeContext = useRef<Record<string, any>>({});
useEffect(() => {
@ -138,14 +146,14 @@ export default function HomePage() {
scene.add(light);
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();
const keys = { w: false, a: false, s: false, d: false };
camera.position.set(100, 15, 100);
camera.lookAt(0, 0, -200);
const onKeyDown = (e) => {
if (e.code === "KeyW") keys.w = true;
if (e.code === "KeyA") keys.a = true;
@ -221,7 +229,7 @@ export default function HomePage() {
threeContext.current;
let cancel = false;
let mesh: THREE.Mesh;
let root: THREE.Group;
async function loadMap() {
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) {
return;
}
scene.add(mesh);
scene.add(root);
}
loadMap();
return () => {
cancel = true;
if (mesh) {
mesh.removeFromParent();
}
root.removeFromParent();
};
}, [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