Skip to content

Commit 7212422

Browse files
committed
🚧 Fix #225
I found a way to avoid overwriting the `Preview.raycast` method, which should make selecting custom elements much more stable now.
1 parent 83a2030 commit 7212422

File tree

8 files changed

+94
-29
lines changed

8 files changed

+94
-29
lines changed

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import './mods/modelFormatConvertToMod'
3636
import './mods/modelFormatMod'
3737
import './mods/molangMod'
3838
import './mods/panelMod'
39-
import './mods/previewRaycastMod'
39+
// import './mods/previewRaycastMod'
4040
import './mods/projectSettingsActionOverride'
4141
import './mods/saveAllAnimationsActionMod'
4242
import './mods/saveProjectActionMod'

src/outliner/resizableOutlinerElement.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ new Property(ResizableOutlinerElement, 'string', 'visibility', { default: true }
115115
export const PREVIEW_CONTROLLER = new NodePreviewController(ResizableOutlinerElement, {
116116
setup(el: ResizableOutlinerElement) {
117117
const mesh = new THREE.Mesh()
118+
mesh.isElement = true
118119
mesh.fix_rotation = new THREE.Euler(0, 0, 0, 'ZYX')
119120
mesh.fix_rotation.x = Math.degToRad(el.rotation[0])
120121
mesh.fix_rotation.y = Math.degToRad(el.rotation[1])

src/outliner/textDisplay.ts

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -326,27 +326,40 @@ export class TextDisplay extends ResizableOutlinerElement {
326326
const font = await getVanillaFont()
327327
// Hide the geo while rendering
328328

329-
const { mesh, outline } = await font.generateTextMesh({
329+
const { mesh: newMesh, outline } = await font.generateTextMesh({
330330
jsonText,
331331
maxLineWidth: this.lineWidth,
332332
backgroundColor: this.backgroundColor,
333333
backgroundAlpha: this.backgroundAlpha,
334334
shadow: this.shadow,
335335
alignment: this.align,
336336
})
337-
mesh.name = this.uuid + '_text'
338-
const previousMesh = this.mesh.children.find(v => v.name === mesh.name)
337+
newMesh.name = this.uuid + '_text'
338+
const previousMesh = this.mesh.children.find(v => v.name === newMesh.name)
339339
if (previousMesh) this.mesh.remove(previousMesh)
340-
this.mesh.add(mesh)
340+
341+
const mesh = this.mesh as THREE.Mesh
342+
mesh.name = this.uuid
343+
mesh.geometry = (newMesh.children[0] as THREE.Mesh).geometry.clone()
344+
mesh.geometry.translate(
345+
newMesh.children[0].position.x,
346+
newMesh.children[0].position.y,
347+
newMesh.children[0].position.z
348+
)
349+
mesh.geometry.rotateY(Math.PI)
350+
mesh.geometry.scale(newMesh.scale.x, newMesh.scale.y, newMesh.scale.z)
351+
mesh.material = Canvas.transparentMaterial
352+
353+
mesh.add(newMesh)
341354

342355
outline.name = this.uuid + '_outline'
343356
outline.visible = this.selected
344-
this.mesh.outline = outline
345-
const previousOutline = this.mesh.children.find(v => v.name === outline.name)
346-
if (previousOutline) this.mesh.remove(previousOutline)
347-
this.mesh.add(outline)
348-
this.mesh.visible = this.visibility
349-
return mesh
357+
mesh.outline = outline
358+
const previousOutline = mesh.children.find(v => v.name === outline.name)
359+
if (previousOutline) mesh.remove(previousOutline)
360+
mesh.add(outline)
361+
mesh.visible = this.visibility
362+
return newMesh
350363
}
351364
}
352365
new Property(TextDisplay, 'string', 'text', { default: '"Hello World!"' })

src/outliner/vanillaBlockDisplay.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -229,16 +229,21 @@ export const PREVIEW_CONTROLLER = new NodePreviewController(VanillaBlockDisplay,
229229
.then(result => {
230230
if (!result?.mesh) return
231231

232-
el.mesh.clear()
232+
const mesh = el.mesh as THREE.Mesh
233+
mesh.name = el.uuid
234+
mesh.material = Canvas.wireframeMaterial
235+
mesh.geometry = result.boundingBox
236+
237+
mesh.clear()
233238
result.outline.name = el.uuid + '_outline'
234239
result.outline.visible = el.selected
235-
el.mesh.outline = result.outline
236-
el.mesh.add(result.mesh)
237-
el.mesh.add(result.outline)
240+
mesh.outline = result.outline
241+
mesh.add(result.mesh)
242+
mesh.add(result.outline)
238243

239244
el.preview_controller.updateHighlight(el)
240245
el.preview_controller.updateTransform(el)
241-
el.mesh.visible = el.visibility
246+
mesh.visible = el.visibility
242247
TickUpdates.selection = true
243248

244249
el.ready = true

src/outliner/vanillaItemDisplay.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -227,15 +227,18 @@ export const PREVIEW_CONTROLLER = new NodePreviewController(VanillaItemDisplay,
227227
void getItemModel(el.item)
228228
.then(result => {
229229
if (!result) return
230-
231-
el.mesh.clear()
232-
el.mesh.add(result.mesh)
233-
el.mesh.add(result.outline)
234-
el.mesh.outline = result.outline
230+
const mesh = el.mesh as THREE.Mesh
231+
mesh.name = el.uuid
232+
mesh.geometry = result.boundingBox
233+
mesh.material = Canvas.wireframeMaterial
234+
mesh.clear()
235+
mesh.add(result.mesh)
236+
mesh.add(result.outline)
237+
mesh.outline = result.outline
235238

236239
el.preview_controller.updateHighlight(el)
237240
el.preview_controller.updateTransform(el)
238-
el.mesh.visible = el.visibility
241+
mesh.visible = el.visibility
239242
TickUpdates.selection = true
240243

241244
el.ready = true

src/systems/minecraft/blockModelManager.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@ import {
1717
} from './model'
1818
import { TEXTURE_FRAG_SHADER, TEXTURE_VERT_SHADER } from './textureShaders'
1919

20-
type BlockModelMesh = { mesh: THREE.Mesh; outline: THREE.LineSegments; isBlock: true }
20+
type BlockModelMesh = {
21+
mesh: THREE.Mesh
22+
outline: THREE.LineSegments
23+
boundingBox: THREE.BufferGeometry
24+
isBlock: true
25+
}
2126

2227
const LOADER = new THREE.TextureLoader()
2328
const BLOCK_MODEL_CACHE = new Map<string, BlockModelMesh>()
@@ -59,6 +64,7 @@ export async function getBlockModel(block: string): Promise<BlockModelMesh | und
5964
result = {
6065
mesh: result.mesh.clone(true),
6166
outline: result.outline.clone(true),
67+
boundingBox: result.boundingBox.clone(),
6268
isBlock: true,
6369
}
6470
for (const child of result.mesh.children as THREE.Mesh[]) {
@@ -112,6 +118,7 @@ async function generateModelMesh(
112118
}
113119

114120
const mesh: THREE.Mesh = new THREE.Mesh()
121+
const boundingBoxes: THREE.BufferGeometry[] = []
115122
const outlineGeos: THREE.BufferGeometry[] = []
116123

117124
for (const element of model.elements) {
@@ -334,6 +341,7 @@ async function generateModelMesh(
334341
geometry.setAttribute('uv', new THREE.Float32BufferAttribute(uvs, 2))
335342
geometry.attributes.uv.needsUpdate = true
336343

344+
boundingBoxes.push(geometry.clone())
337345
const outlineGeo = new THREE.EdgesGeometry(geometry)
338346
outlineGeos.push(outlineGeo)
339347
const elementMesh = new THREE.Mesh(geometry, materials)
@@ -342,12 +350,13 @@ async function generateModelMesh(
342350

343351
const outlineGeo = mergeGeometries(outlineGeos)!
344352
const outline = new THREE.LineSegments(outlineGeo, Canvas.outlineMaterial)
353+
const boundingBox = mergeGeometries(boundingBoxes)!
345354

346355
outline.no_export = true
347356
outline.renderOrder = 2
348357
outline.frustumCulled = false
349358

350-
return { mesh, outline, isBlock: true }
359+
return { mesh, outline, boundingBox, isBlock: true }
351360
}
352361

353362
const TEXTURE_CACHE = new Map<string, THREE.Texture>()
@@ -423,6 +432,7 @@ export async function parseBlockState(block: IParsedBlock): Promise<BlockModelMe
423432
} else if (blockstate.multipart) {
424433
// throw new Error(`Multipart block states are not supported yet`)
425434
const mesh = new THREE.Mesh()
435+
const boundingBoxes: THREE.BufferGeometry[] = []
426436
const outlines: THREE.BufferGeometry[] = []
427437
for (const c of blockstate.multipart) {
428438
const result = await parseMultipartCase(block, c)
@@ -433,6 +443,10 @@ export async function parseBlockState(block: IParsedBlock): Promise<BlockModelMe
433443
newChild.rotateY(result.mesh.rotation.y)
434444
newChild.rotateX(result.mesh.rotation.x)
435445
mesh.add(newChild)
446+
const boundingBox = result.boundingBox.clone()
447+
boundingBox.rotateY(result.mesh.rotation.y)
448+
boundingBox.rotateX(result.mesh.rotation.x)
449+
boundingBoxes.push(boundingBox)
436450
}
437451
const outlineGeo = result.outline.geometry.clone()
438452
outlineGeo.rotateY(result.mesh.rotation.y)
@@ -448,12 +462,13 @@ export async function parseBlockState(block: IParsedBlock): Promise<BlockModelMe
448462

449463
const outlineGeo = mergeGeometries(outlines)!
450464
const outline = new THREE.LineSegments(outlineGeo, Canvas.outlineMaterial)
465+
const boundingBox = mergeGeometries(boundingBoxes)!
451466

452467
outline.no_export = true
453468
outline.renderOrder = 2
454469
outline.frustumCulled = false
455470

456-
return { mesh, outline, isBlock: true }
471+
return { mesh, outline, boundingBox, isBlock: true }
457472
}
458473

459474
throw new Error(`Unsupported block state '${block.resourceLocation}'`)

src/systems/minecraft/itemModelManager.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@ import { parseBlockModel } from './blockModelManager'
55
import { IItemModel } from './model'
66
import { TEXTURE_FRAG_SHADER, TEXTURE_VERT_SHADER } from './textureShaders'
77

8-
type ItemModelMesh = { mesh: THREE.Mesh; outline: THREE.LineSegments; isBlock?: boolean }
8+
type ItemModelMesh = {
9+
mesh: THREE.Mesh
10+
outline: THREE.LineSegments
11+
boundingBox: THREE.BufferGeometry
12+
isBlock?: boolean
13+
}
914

1015
const LOADER = new THREE.TextureLoader()
1116
const ITEM_MODEL_CACHE = new Map<string, ItemModelMesh>()
@@ -22,6 +27,7 @@ export async function getItemModel(item: string): Promise<ItemModelMesh | undefi
2227
result = {
2328
mesh: result.mesh.clone(true),
2429
outline: result.outline.clone(true),
30+
boundingBox: result.boundingBox.clone(),
2531
isBlock: result.isBlock,
2632
}
2733

@@ -81,6 +87,7 @@ async function parseItemModel(location: string, childModel?: IItemModel): Promis
8187

8288
async function generateItemMesh(location: string, model: IItemModel): Promise<ItemModelMesh> {
8389
const masterMesh = new THREE.Mesh()
90+
const boundingBoxes: THREE.BufferGeometry[] = []
8491
const outlineGeos: THREE.BufferGeometry[] = []
8592

8693
for (const textureResourceLoc of Object.values(model.textures)) {
@@ -267,14 +274,16 @@ async function generateItemMesh(location: string, model: IItemModel): Promise<It
267274
new THREE.BufferAttribute(new Float32Array(outlineVerts), 3)
268275
)
269276
outlineGeos.push(outlineGeo)
277+
boundingBoxes.push(mesh.geometry.clone())
270278
masterMesh.add(mesh)
271279
}
272280

273281
const outlineGeo = mergeGeometries(outlineGeos)
282+
const boundingBox = mergeGeometries(boundingBoxes)!
274283
const outline = new THREE.LineSegments(
275284
new THREE.EdgesGeometry(outlineGeo as THREE.BufferGeometry),
276285
Canvas.outlineMaterial
277286
)
278287

279-
return { mesh: masterMesh, outline }
288+
return { mesh: masterMesh, outline, boundingBox }
280289
}

test_blueprints/blockstates.ajblueprint

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,23 @@
323323
"align": "center",
324324
"uuid": "e1a16324-658b-a9af-1095-ca2a83c80595",
325325
"type": "animated_java:vanilla_block_display"
326+
},
327+
{
328+
"name": "text_display",
329+
"position": [0, 27, 0],
330+
"rotation": [0, 0, 0],
331+
"scale": [1, 1, 1],
332+
"visibility": true,
333+
"item": "minecraft:diamond",
334+
"config": {},
335+
"block": "minecraft:stone",
336+
"text": "\"My House!\"",
337+
"lineWidth": 200,
338+
"backgroundColor": "#000000",
339+
"backgroundAlpha": 0.25098,
340+
"align": "center",
341+
"uuid": "3988627b-b0c6-8a09-9d3f-230adeb648f8",
342+
"type": "animated_java:text_display"
326343
}
327344
],
328345
"outliner": [
@@ -342,7 +359,8 @@
342359
"dea933e7-4568-aae1-86c4-f761f5d0f2e2",
343360
"42bafea5-d05a-8106-0db4-0d1b0067a68e",
344361
"e1a16324-658b-a9af-1095-ca2a83c80595",
345-
"215cf9b7-1949-5e9b-b7b1-a35f59e58b2d"
362+
"215cf9b7-1949-5e9b-b7b1-a35f59e58b2d",
363+
"3988627b-b0c6-8a09-9d3f-230adeb648f8"
346364
],
347365
"textures": [],
348366
"variants": {
@@ -351,7 +369,8 @@
351369
"display_name": "Default",
352370
"uuid": "c79ede10-67d7-8730-033c-de43ab658b53",
353371
"texture_map": {},
354-
"excluded_nodes": []
372+
"excluded_nodes": [],
373+
"is_default": true
355374
},
356375
"list": []
357376
},

0 commit comments

Comments
 (0)