Files
engine/examples/obj-loader.ts
2024-12-09 11:10:22 +08:00

81 lines
2.5 KiB
TypeScript

/**
* @title OBJ Loader Use Model Mesh
* @category Mesh
* @thumbnail https://mdn.alipayobjects.com/merchant_appfe/afts/img/A*ZnBlT4UNh0IAAAAAAAAAAAAADiR2AQ/original
*/
import {
AssetPromise,
BlinnPhongMaterial,
Camera,
Color,
DirectLight,
LoadItem,
Loader,
MeshRenderer,
MeshTopology,
ModelMesh,
ResourceManager,
Vector3,
WebGLEngine,
request,
resourceLoader
} from "@galacean/engine";
import { OrbitControl } from "@galacean/engine-toolkit-controls";
@resourceLoader("OBJ", ["obj"])
class OBJLoader extends Loader<ModelMesh> {
load(item: LoadItem, resourceManager: ResourceManager): AssetPromise<ModelMesh> {
return request<string>(item.url!, { ...item, type: "text" }).then((text: string) => {
const lines = text.split(/\n/);
const positions: Vector3[] = [];
const indices: number[] = [];
lines
.map((lineText) => lineText.split(" "))
.forEach((parseTexts) => {
if (parseTexts[0] === "v") {
positions.push(
new Vector3(parseFloat(parseTexts[1]), parseFloat(parseTexts[2]), parseFloat(parseTexts[3]))
);
} else if (parseTexts[0] === "f") {
indices.push(parseInt(parseTexts[1]) - 1, parseInt(parseTexts[2]) - 1, parseInt(parseTexts[3]) - 1);
}
});
const mesh = new ModelMesh(resourceManager.engine);
mesh.setPositions(positions);
mesh.setIndices(Uint16Array.from(indices));
mesh.addSubMesh(0, indices.length, MeshTopology.Triangles);
mesh.uploadData(false);
return mesh;
});
}
}
WebGLEngine.create({ canvas: "canvas" }).then((engine) => {
engine.canvas.resizeByClientSize();
const scene = engine.sceneManager.activeScene;
const rootEntity = scene.createRootEntity();
// init camera
const cameraEntity = rootEntity.createChild("camera");
cameraEntity.addComponent(Camera);
cameraEntity.addComponent(OrbitControl);
cameraEntity.transform.setPosition(0.5, 0.5, 0.5);
cameraEntity.transform.lookAt(new Vector3(0, 0, 0));
// init light
rootEntity.addComponent(DirectLight);
engine.resourceManager
.load<ModelMesh>("https://gw.alipayobjects.com/os/bmw-prod/b885a803-5315-44f0-af54-6787ec47ed1b.obj")
.then((mesh) => {
renderer.mesh = mesh;
});
// init cube
const cubeEntity = rootEntity.createChild("cube");
const renderer = cubeEntity.addComponent(MeshRenderer);
const material = new BlinnPhongMaterial(engine);
material.baseColor = new Color(1, 0.25, 0.25, 1);
renderer.setMaterial(material);
engine.run();
});