mirror of
https://github.com/manyfold3d/manyfold.git
synced 2026-10-23 04:02:19 -05:00
81 lines
2.5 KiB
TypeScript
81 lines
2.5 KiB
TypeScript
import { Controller } from '@hotwired/stimulus'
|
|
import f3d from 'f3d'
|
|
|
|
// Connects to data-controller="f3d-renderer"
|
|
export default class extends Controller {
|
|
|
|
engine: any;
|
|
|
|
async init (data: Uint8Array): Promise<void> {
|
|
const settings = {
|
|
canvas: this.element,
|
|
};
|
|
f3d(settings).then(async (F3D) => {
|
|
F3D.Engine.autoloadPlugins();
|
|
// Uncomment this to get an updated list of formats in dev
|
|
// console.log(`F3D supported types: ${F3D.Engine.getReadersInfo().map((reader) => (`${reader["extensions"][0]}: ${reader["mimeTypes"][0]}`)).flat()}`);
|
|
this.engine = F3D.Engine.create()
|
|
const options = this.engine.getOptions()
|
|
// background must be set to black for proper blending with transparent canvas
|
|
options.setAsString('render.background.color', '#000000')
|
|
|
|
// make it look nice
|
|
options.toggle('render.effect.antialiasing.enable')
|
|
options.toggle('render.effect.tone_mapping')
|
|
options.toggle('render.effect.ambient_occlusion')
|
|
|
|
options.toggle('scene.animation.autoplay', true)
|
|
|
|
// display widgets
|
|
options.toggle('render.grid.enable', true)
|
|
options.setAsString('render.grid.color', '#00ffff')
|
|
options.setAsString('render.grid.subdivisions', '0')
|
|
options.setAsString('render.grid.unit', '10')
|
|
|
|
// default to +Z
|
|
options.setAsString('scene.up_direction', '+Z')
|
|
|
|
const canvas = this.element
|
|
const scale = window.devicePixelRatio
|
|
console.log(scale * canvas.clientWidth)
|
|
console.log(scale * canvas.clientHeight)
|
|
this.engine.getWindow().setSize(scale * canvas.clientWidth, scale * canvas.clientHeight)
|
|
|
|
const scene = this.engine.getScene()
|
|
scene.clear()
|
|
try {
|
|
scene.addBuffer(data)
|
|
} catch (e) {
|
|
console.log('Unsupported file')
|
|
}
|
|
|
|
const camera = this.engine.getWindow().getCamera()
|
|
const foc = camera.focalPoint
|
|
const dir = [-1, 1, -0.5]
|
|
const pos = [0, 0, 0]
|
|
for (let i = 0; i < 3; i++) {
|
|
pos[i] = foc[i] - dir[i]
|
|
}
|
|
camera.position = pos
|
|
camera.resetToBounds(0.9)
|
|
this.engine.getWindow().render()
|
|
this.engine.getInteractor().start()
|
|
})
|
|
}
|
|
|
|
async onLoad () {
|
|
const url = this.element.dataset.previewUrl;
|
|
try {
|
|
const response = await fetch(url);
|
|
if (!response.ok) {
|
|
throw new Error(`Response status: ${response.status}`);
|
|
}
|
|
|
|
const result = await response.bytes();
|
|
this.init(result);
|
|
} catch (error) {
|
|
console.error(error.message);
|
|
}
|
|
}
|
|
}
|