skycraft: sexier spaceship

now with wavefront .obj format support
This commit is contained in:
Paul Mathieu 2022-11-09 00:44:48 -08:00
parent b6cc6ca35b
commit 7354dcb929
3 changed files with 3818 additions and 2 deletions

View File

@ -6,6 +6,7 @@ import {makeFace, makeBufferFromFaces} from '../geometry';
import { loadStlModel } from './stl'; import { loadStlModel } from './stl';
import * as linalg from './linalg'; import * as linalg from './linalg';
import { memoize } from '../memoize'; import { memoize } from '../memoize';
import { loadObjModel } from './obj';
const VSHADER = ` const VSHADER = `
attribute vec3 aPosition; attribute vec3 aPosition;
@ -1118,7 +1119,7 @@ function getObjects(context, body, parentPosition) {
const shipOrientation = [ const shipOrientation = [
se3.rotationOnly(player.tf), se3.rotationOnly(player.tf),
se3.rotationOnly(context.camera.tf), se3.rotationOnly(context.camera.tf),
se3.rotxyz(-Math.PI / 2, 0, Math.PI / 2), se3.rotxyz(-Math.PI / 2, Math.PI / 2, Math.PI / 2),
].reduce(se3.product); ].reduce(se3.product);
const shipPos = player.position; const shipPos = player.position;
objects.push({ objects.push({
@ -1267,7 +1268,7 @@ async function main() {
// [ ] better lighting // [ ] better lighting
// [x] optimize geometry generation // [x] optimize geometry generation
const modelPromise = loadStlModel('spaceship.stl'); const modelPromise = loadObjModel('spaceship.obj');
const context = { const context = {
gl, gl,

72
skycraft/obj.js Normal file
View File

@ -0,0 +1,72 @@
function parseObjLine(line, obj) {
line = line.trim();
if (line[0] === '#' || line.length < 1) {
return;
}
const elements = line.split(/\s+/);
obj[elements[0]].push(elements.slice(1));
}
function getFaces(obj) {
return obj.f.map(f => {
const face = {
'vertices': [],
'normals': [],
'textures': [],
};
if (f.length === 4) { // add duplicate vertices to make triangles
f.splice(3, 0, f[0]);
f.splice(4, 0, f[2]);
}
f.forEach(v => {
const [vidx, vtidx, vnidx] = v.split('/');
face.vertices.push((obj.v[vidx - 1] || []).map(Number));
face.normals.push((obj.vn[vnidx - 1] || []).map(Number));
//face.textures.push((obj.vt[vtidx] || []).map(Number));
face.textures.push([0, 0]);
});
return face;
});
}
export async function loadObjModel(url) {
const stlDataStream = (await fetch(url)).body;
const faces = [];
const obj = new Proxy({}, {
get: (target, name) =>{
if (!(name in target)) {
target[name] = [];
}
return target[name];
},
});
return new Promise((resolve, reject) => {
let partialLine = "";
const reader = stlDataStream.getReader();
const decoder = new TextDecoder();
function pump() {
reader.read().then(({ done, value }) => {
if (done) {
parseObjLine(partialLine, obj);
return resolve(getFaces(obj));
}
const textInput = decoder.decode(value);
const lines = textInput.split('\n');
if (lines.length > 1) {
parseObjLine(partialLine + lines[0], obj);
partialLine = "";
lines.slice(0, -1).forEach(line => {
parseObjLine(line, obj);
});
}
partialLine = partialLine + lines.at(-1);
pump();
});
}
pump();
});
}

3743
skycraft/spaceship.obj Normal file

File diff suppressed because it is too large Load Diff