Skip to content

Commit

Permalink
start working on custom ldraw loading mechanism
Browse files Browse the repository at this point in the history
  • Loading branch information
ghackenberg committed Dec 2, 2023
1 parent 16e6384 commit 86119d5
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 7 deletions.
1 change: 1 addition & 0 deletions packages/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"plausible-tracker": "^0.3.8",
"process": "^0.11.10",
"productboard-common": "^0.0.1",
"productboard-ldraw": "^0.0.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-helmet": "^6.1.0",
Expand Down
73 changes: 67 additions & 6 deletions packages/frontend/src/scripts/loaders/ldraw.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { Group, LoadingManager } from "three"
import axios from "axios"
import * as THREE from "three"
import { LDrawLoader } from "three/examples/jsm/loaders/LDrawLoader"

import { Model, Parser, Reference } from "productboard-ldraw"

import { CacheAPI } from "../clients/cache"

const TEXT_DECODER = new TextDecoder()

const LOADING_MANAGER = new LoadingManager().setURLModifier(url => {
const LOADING_MANAGER = new THREE.LoadingManager().setURLModifier(url => {
if (url.indexOf('/') == -1) {
return `/rest/parts/${url}`
} else {
Expand All @@ -15,27 +18,85 @@ const LOADING_MANAGER = new LoadingManager().setURLModifier(url => {

const LDRAW_LOADER = new LDrawLoader(LOADING_MANAGER)

/*
LDRAW_LOADER.preloadMaterials('/rest/parts/LDConfig.ldr').then(() => {
// console.log('Materials loaded!')
}).catch(error => {
console.error(error)
})
*/

export async function loadLDrawModel(path: string) {
const file = await CacheAPI.loadFile(path)
return parseLDrawModel(TEXT_DECODER.decode(file))
}

export async function loadLDrawPath(path: string) {
const response = await axios.get(path)
return parseLDrawModel(response.data)
}

export async function parseLDrawModel(data: string) {
return new Promise<Group>(resolve => {
return new Promise<THREE.Group>(resolve => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(LDRAW_LOADER as any).parse(data, (group: Group) => {
(LDRAW_LOADER as any).parse(data, (group: THREE.Group) => {
// Fix coordinates
group.rotation.x = Math.PI
// Resolve
resolve(group)
})
})
}

const PARSER = new Parser()

export class LDrawModelHandle {
private active = true

public readonly root = new THREE.Group()

constructor(private path: string) {
CacheAPI.loadFile(path).then(data => this.parseData(data))
}

public stop() {
this.active = false
}

private parseData(data: ArrayBuffer) {
if (this.active) {
this.parseText(TEXT_DECODER.decode(data))
}
}
private parseText(text: string) {
if (this.active) {
this.processModel(new THREE.MeshBasicMaterial({ color: 0x00ff00 }), new THREE.LineBasicMaterial({ color: 0x0000ff }), this.root, PARSER.parse(text, this.path))
}
}

private processModel(face: THREE.Material, edge: THREE.Material, parent: THREE.Group, model: Model) {
for (const reference of model.references) {
this.processReference(face, edge, parent, model, reference)
}
}
private async processReference(face: THREE.Material, edge: THREE.Material, parent: THREE.Group, model: Model, reference: Reference) {
const position = reference.position
const orientation = reference.orientation
const child = new THREE.Group()
child.name = reference.file
child.matrix.set(
orientation.a, orientation.b, orientation.c, 0,
orientation.d, orientation.e, orientation.f, 0,
orientation.g, orientation.h, orientation.i, 0,
position.x, position.y, position.z, 1
)
parent.add(child)
if (model.fileIndex[reference.file]) {
this.processModel(face, edge, child, model.fileIndex[reference.file])
} else {
if (reference.file.indexOf('/') == -1) {
parent.add(await loadLDrawPath(`/rest/parts/${reference.file}`))
} else {
parent.add(await loadLDrawPath(`/rest/parts/${reference.file.substring(reference.file.lastIndexOf('/') + 1)}`))
}
}
}
}
5 changes: 5 additions & 0 deletions packages/ldraw/src/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ export class Model {
public colors: Color[] = []
public files: Model[] = []

public colorIndex: {[code: number]: Color} = {}
public fileIndex: {[name: string]: Model} = {}

constructor(public url: string= undefined, public parent: Model = null) {}

private addEntry(entry: Entry) {
Expand Down Expand Up @@ -119,9 +122,11 @@ export class Model {

addColor(color: Color) {
this.colors.push(color)
this.colorIndex[color.code] = color
}
addFile(file: Model) {
this.files.push(file)
this.fileIndex[file.url] = file
}

}
2 changes: 1 addition & 1 deletion packages/ldraw/src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class Parser {

const lines = text.split('\n')
for (const line of lines) {
this.parseEntry(context, line)
this.parseEntry(context, line.trim())
}
}

Expand Down

0 comments on commit 86119d5

Please sign in to comment.