Skip to content

Commit 9dc0435

Browse files
committed
WIP Add pro meshes for surfaces
Pro meshes not yet affected by surface map, leaving small gaps in the terrain
1 parent 006de1b commit 9dc0435

File tree

17 files changed

+282
-54
lines changed

17 files changed

+282
-54
lines changed

src/game/LevelLoader.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export interface LevelConfData {
1515
fullName: string
1616
generateSpiders: boolean
1717
video: string
18+
meshBasename: string
1819
textureBasename: string
1920
roofTexture: string
2021
rockFallStyle: RockFallStyle
@@ -72,6 +73,7 @@ export class LevelLoader {
7273
video: levelConf.video,
7374
mapWidth: terrainMap.width,
7475
mapHeight: terrainMap.height,
76+
meshBasename: textureSet.meshBasename,
7577
textureBasename: textureSet.textureBasename,
7678
roofTexture: textureSet.roofTexture,
7779
rockFallStyle: rockFallStyle,

src/game/SceneManager.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ export class SceneManager implements Updatable {
8787
EventBroker.subscribe(EventKey.BUILDINGS_CHANGED, () => {
8888
this.setBuildModeSelection(undefined) // TODO Check dependencies precisely
8989
})
90+
EventBroker.subscribe(EventKey.COMMAND_CHANGE_PREFERENCES, (event) => {
91+
this.terrain.forEachSurface((s) => s.mesh.setProMeshEnabled(SaveGameManager.preferences.wallDetails))
92+
})
9093
}
9194

9295
setActiveCamera(camera: PerspectiveCamera) {
@@ -135,10 +138,8 @@ export class SceneManager implements Updatable {
135138
this.setBuildModeSelection(undefined)
136139

137140
this.floorGroup = new Group()
138-
this.floorGroup.scale.setScalar(TILESIZE)
139141
this.roofGroup = new Group()
140142
this.roofGroup.visible = false
141-
this.roofGroup.scale.setScalar(TILESIZE)
142143
this.terrain = TerrainLoader.loadTerrain(levelConf, this.worldMgr)
143144
this.terrain.forEachSurface((s) => {
144145
this.floorGroup.add(s.mesh)

src/game/TerrainLoader.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ export class TerrainLoader {
8383
case SurfaceType.LAVA5:
8484
// fallthrough
8585
case SurfaceType.WATER:
86-
worldMgr.ecs.addComponent(surface.entity, new FluidSurfaceComponent(surface.x, surface.y, surface.mesh.geometry.attributes.uv))
86+
worldMgr.ecs.addComponent(surface.entity, new FluidSurfaceComponent(surface.x, surface.y, surface.mesh.lowMesh.geometry.attributes.uv))
8787
break
8888
case SurfaceType.SLUG_HOLE:
8989
terrain.slugHoles.add(surface)

src/game/model/building/BuildPlacementMarkerMesh.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ import { BufferGeometry, Mesh, MeshPhongMaterial, Vector2 } from 'three'
22
import { TILESIZE } from '../../../params'
33
import { SceneManager } from '../../SceneManager'
44
import { Surface } from '../../terrain/Surface'
5+
import { SurfaceMesh } from '../../terrain/SurfaceMesh'
56

67
export class BuildPlacementMarkerMesh extends Mesh<BufferGeometry, MeshPhongMaterial> {
78
sceneMgr: SceneManager
8-
lastSurfaceMesh?: Mesh
9+
lastSurfaceMesh?: SurfaceMesh
910

1011
constructor(sceneMgr: SceneManager) {
1112
super(new BufferGeometry(), new MeshPhongMaterial({
@@ -28,7 +29,7 @@ export class BuildPlacementMarkerMesh extends Mesh<BufferGeometry, MeshPhongMate
2829
this.position.copy(surfaceMesh.position.clone().multiplyScalar(TILESIZE))
2930
this.position.y += TILESIZE / 20
3031
this.geometry?.dispose()
31-
this.geometry = surfaceMesh.geometry.clone()
32+
this.geometry = surfaceMesh.lowMesh.geometry.clone()
3233
}
3334

3435
setColor(hexColor: number) {

src/game/system/LaserShotSystem.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ export class LaserShotSystem extends AbstractGameSystem {
8888
this.worldMgr.sceneMgr.addPositionalAudio(soundParent, 'SFX_LaserHit', false)
8989
this.worldMgr.sceneMgr.addMiscAnim(GameConfig.instance.miscObjects.boulderExplode, rockyIntersection.point, PRNG.animation.random() * 2 * Math.PI, false)
9090
} else {
91-
const floorIntersection = this.raycaster.intersectObjects<SurfaceMesh>(this.worldMgr.sceneMgr.floorGroup.children, false)[0]
91+
const floorIntersection = this.raycaster.intersectObjects<SurfaceMesh>(this.worldMgr.sceneMgr.floorGroup.children, true)[0]
9292
if (floorIntersection) {
9393
beamLength = floorIntersection.distance
9494
const surface = floorIntersection.object.userData.selectable

src/game/terrain/Surface.ts

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { BackSide, Raycaster, Vector2, Vector3 } from 'three'
1+
import { Raycaster, Vector2, Vector3 } from 'three'
22
import { SoundManager } from '../../audio/SoundManager'
33
import { DeselectAll, SelectionChanged, UpdateRadarSurface, UpdateRadarTerrain } from '../../event/LocalEvents'
44
import { CavernDiscovered, JobCreateEvent, OreFoundEvent, WorldLocationEvent } from '../../event/WorldEvents'
@@ -13,7 +13,7 @@ import { DrillJob } from '../model/job/surface/DrillJob'
1313
import { ReinforceJob } from '../model/job/surface/ReinforceJob'
1414
import { GameEntity } from '../ECS'
1515
import { SurfaceVertex } from './SurfaceGeometry'
16-
import { SurfaceMesh } from './SurfaceMesh'
16+
import { RoofMesh, SurfaceMesh } from './SurfaceMesh'
1717
import { SurfaceType } from './SurfaceType'
1818
import { Terrain } from './Terrain'
1919
import { WALL_TYPE, WallType } from './WallType'
@@ -34,6 +34,8 @@ import { PRNG } from '../factory/PRNG'
3434
import { GameState } from '../model/GameState'
3535
import { CompleteSurfaceJob } from '../model/job/surface/CompleteSurfaceJob'
3636
import { MaterialEntity } from '../model/material/MaterialEntity'
37+
import { ResourceManager } from '../../resource/ResourceManager'
38+
import { SaveGameManager } from '../../resource/SaveGameManager'
3739

3840
export class Surface {
3941
readonly worldMgr: WorldManager
@@ -53,7 +55,7 @@ export class Surface {
5355
drillProgress: number = 0
5456

5557
readonly mesh: SurfaceMesh
56-
readonly roofMesh: SurfaceMesh
58+
readonly roofMesh: RoofMesh
5759
wallType: WallType = WALL_TYPE.floor
5860
needsMeshUpdate: boolean = false
5961

@@ -83,15 +85,10 @@ export class Surface {
8385
this.rubblePositions = [this.getRandomPosition(), this.getRandomPosition(), this.getRandomPosition(), this.getRandomPosition()]
8486
break
8587
}
86-
// TODO Use pro meshes for high wall details in FPV
87-
// const proMesh = ResourceManager.getLwoModel(this.terrain.textureSet.meshBasename + '01b.lwo')
88-
// proMesh.position.copy(this.mesh.position)
89-
// proMesh.scale.setScalar(1 / TILESIZE)
90-
// this.terrain.floorGroup.add(proMesh)
9188
this.mesh = new SurfaceMesh(x, y, {selectable: this, surface: this})
92-
this.roofMesh = new SurfaceMesh(x, y, {})
93-
this.roofMesh.material.side = BackSide
94-
this.roofMesh.position.y = 3
89+
this.mesh.setProMeshEnabled(SaveGameManager.preferences.wallDetails)
90+
const roofTexture = ResourceManager.getSurfaceTexture(this.terrain.levelConf.roofTexture, 0) ?? null // TODO Move to config handling
91+
this.roofMesh = new RoofMesh(x, y, roofTexture)
9592
}
9693

9794
private updateObjectName() {
@@ -143,7 +140,7 @@ export class Surface {
143140
case SurfaceType.LAVA5:
144141
// fallthrough
145142
case SurfaceType.WATER:
146-
this.worldMgr.ecs.addComponent(this.entity, new FluidSurfaceComponent(this.x, this.y, this.mesh.geometry.attributes.uv))
143+
this.worldMgr.ecs.addComponent(this.entity, new FluidSurfaceComponent(this.x, this.y, this.mesh.lowMesh.geometry.attributes.uv))
147144
break
148145
case SurfaceType.HIDDEN_CAVERN:
149146
this.surfaceType = SurfaceType.GROUND
@@ -351,7 +348,7 @@ export class Surface {
351348
this.terrain.pathFinder.updateSurface(this)
352349
}
353350

354-
private getVertex(x: number, y: number, s1: Surface, s2: Surface, s3: Surface): SurfaceVertex {
351+
getVertex(x: number, y: number, s1: Surface, s2: Surface, s3: Surface): SurfaceVertex {
355352
const high = [this, s1, s2, s3].some((s) => !s.discovered) || ![this, s1, s2, s3].some((s) => s.surfaceType.floor)
356353
const minSeamProgress = Math.min(this.getSeamProgress(), s1.getSeamProgress(), s2.getSeamProgress(), s3.getSeamProgress())
357354
const offset = this.terrain.getHeightOffset(x, y)
@@ -365,9 +362,9 @@ export class Surface {
365362
private updateWallType(topLeft: SurfaceVertex, topRight: SurfaceVertex, bottomRight: SurfaceVertex, bottomLeft: SurfaceVertex) {
366363
let wallType: WallType = Surface.getWallType(topLeft.high, topRight.high, bottomRight.high, bottomLeft.high)
367364
if (wallType === WALL_TYPE.wall && topLeft.high === bottomRight.high) wallType = WALL_TYPE.weirdCrevice
368-
this.wallType = wallType
365+
this.wallType = wallType // TODO Update wall type only when necessary
369366
this.mesh.setHeights(wallType, topLeft, topRight, bottomRight, bottomLeft)
370-
this.roofMesh.setHeights(wallType, topLeft.flipY(), topRight.flipY(), bottomRight.flipY(), bottomLeft.flipY())
367+
this.roofMesh.setHeights(wallType, topLeft, topRight, bottomRight, bottomLeft)
371368
if (this.wallType !== WALL_TYPE.wall) this.cancelReinforceJobs()
372369
if (this.wallType < WALL_TYPE.wall) this.worldMgr.ecs.removeComponent(this.entity, EmergeComponent)
373370
}
@@ -426,8 +423,9 @@ export class Surface {
426423
suffix = this.surfaceType.shaping ? '0' + this.surfaceType.matIndex : this.surfaceType.matIndex
427424
}
428425
const textureFilepath = this.terrain.levelConf.textureBasename + suffix + '.bmp'
429-
this.mesh.setTexture(textureFilepath, rotation)
430-
this.roofMesh.setTexture(this.terrain.levelConf.roofTexture, rotation)
426+
const proMeshSuffix = suffix.startsWith('1') ? '10' : suffix
427+
const proMeshFilepath = (this.terrain.levelConf.meshBasename + proMeshSuffix).toLowerCase()
428+
this.mesh.setTexture(textureFilepath, rotation, proMeshFilepath)
431429
}
432430

433431
private determinePowerPathTextureNameSuffixAndRotation(rotation: number, suffix: string) {
@@ -480,7 +478,7 @@ export class Surface {
480478
select(): boolean {
481479
if (!this.isSelectable()) return false
482480
this.selected = true
483-
this.mesh.setHighlightColor(0x6060a0)
481+
this.setHighlightColor(0x6060a0)
484482
if (this.surfaceType.floor) SoundManager.playSfxSound('SFX_Floor')
485483
else if (this.surfaceType.shaping) SoundManager.playSfxSound('SFX_Wall')
486484
if (DEV_MODE) console.log(`Surface selected ${this.x}/${this.y}`, this)
@@ -502,7 +500,11 @@ export class Surface {
502500
} else if (this.drillJob) {
503501
color = 0xa0a0a0
504502
}
505-
this.mesh.setHighlightColor(color)
503+
this.setHighlightColor(color)
504+
}
505+
506+
setHighlightColor(hex: number) {
507+
this.mesh.setHighlightColor(hex)
506508
}
507509

508510
hasRubble(): boolean {
@@ -595,7 +597,7 @@ export class Surface {
595597
const wasPath = this.surfaceType === SurfaceType.POWER_PATH || this.surfaceType === SurfaceType.POWER_PATH_BUILDING
596598
this.surfaceType = surfaceType
597599
if (this.surfaceType === SurfaceType.WATER || this.surfaceType === SurfaceType.LAVA5) {
598-
this.worldMgr.ecs.addComponent(this.entity, new FluidSurfaceComponent(this.x, this.y, this.mesh.geometry.attributes.uv))
600+
this.worldMgr.ecs.addComponent(this.entity, new FluidSurfaceComponent(this.x, this.y, this.mesh.lowMesh.geometry.attributes.uv))
599601
} else {
600602
this.worldMgr.ecs.removeComponent(this.entity, FluidSurfaceComponent)
601603
}

src/game/terrain/SurfaceGeometry.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { BufferGeometry, Vector2, Vector3 } from 'three'
22
import { BufferAttribute } from 'three/src/core/BufferAttribute'
33
import { WALL_TYPE, WallType } from './WallType'
4+
import { TILESIZE } from '../../params'
45

56
export class SurfaceGeometry extends BufferGeometry {
67
constructor() {
@@ -13,10 +14,10 @@ export class SurfaceGeometry extends BufferGeometry {
1314
setHeights(wallType: WallType, topLeft: SurfaceVertex, topRight: SurfaceVertex, bottomRight: SurfaceVertex, bottomLeft: SurfaceVertex) {
1415
const uvOffset = SurfaceGeometry.determineUvOffset(wallType, topLeft.high, bottomRight.high, topRight.high, bottomLeft.high)
1516

16-
const topLeftVertex = new Vector3(0, topLeft.height, 0)
17-
const topRightVertex = new Vector3(1, topRight.height, 0)
18-
const bottomRightVertex = new Vector3(1, bottomRight.height, 1)
19-
const bottomLeftVertex = new Vector3(0, bottomLeft.height, 1)
17+
const topLeftVertex = new Vector3(0, topLeft.height, 0).multiplyScalar(TILESIZE)
18+
const topRightVertex = new Vector3(1, topRight.height, 0).multiplyScalar(TILESIZE)
19+
const bottomRightVertex = new Vector3(1, bottomRight.height, 1).multiplyScalar(TILESIZE)
20+
const bottomLeftVertex = new Vector3(0, bottomLeft.height, 1).multiplyScalar(TILESIZE)
2021

2122
const vertices: Vector3[] = []
2223
const normals: Vector3[] = []

src/game/terrain/SurfaceMesh.ts

Lines changed: 113 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,113 @@
1-
import { Mesh, MeshPhongMaterial } from 'three'
1+
import { BackSide, Group, Mesh, MeshPhongMaterial, Texture } from 'three'
22
import { ResourceManager } from '../../resource/ResourceManager'
33
import { SurfaceGeometry, SurfaceVertex } from './SurfaceGeometry'
4-
import { WallType } from './WallType'
4+
import { WALL_TYPE, WallType } from './WallType'
55
import { ObjectPointer } from '../../scene/ObjectPointer'
66
import { Surface } from './Surface'
7+
import { TILESIZE } from '../../params'
8+
import { SceneMesh } from '../../scene/SceneMesh'
79

810
export interface SurfaceMeshUserData {
911
selectable?: Surface
1012
surface?: Surface
1113
}
1214

13-
export class SurfaceMesh extends Mesh<SurfaceGeometry, MeshPhongMaterial> {
14-
declare userData: SurfaceMeshUserData
15+
export class SurfaceMesh extends Group {
16+
proMeshEnabled: boolean = false
17+
lowMesh: SurfaceMeshLow
1518
objectPointer?: ObjectPointer // Only available for surfaces with tuto block id
19+
proMesh?: SceneMesh
20+
21+
constructor(readonly x: number, readonly y: number, readonly userData: SurfaceMeshUserData) {
22+
super()
23+
this.lowMesh = new SurfaceMeshLow(x, y, userData)
24+
this.add(this.lowMesh)
25+
}
26+
27+
setProMeshEnabled(state: boolean) {
28+
this.proMeshEnabled = state
29+
if (this.proMesh) this.proMesh.visible = this.proMeshEnabled
30+
this.lowMesh.visible = !this.proMesh?.visible
31+
}
32+
33+
setHighlightColor(hex: number) {
34+
this.lowMesh.setHighlightColor(hex)
35+
this.proMesh?.material.forEach((m) => m.color.setHex(hex))
36+
}
37+
38+
setTexture(textureFilepath: string, textureRotation: number, proMeshFilepath: string) {
39+
this.lowMesh.setTexture(textureFilepath, textureRotation)
40+
this.updateProMesh(proMeshFilepath)
41+
}
42+
43+
updateProMesh(proMeshFilepath: string) {
44+
const surface = this.userData.surface!
45+
// TODO Keep the shape of the surface separately
46+
const adjacent = surface.terrain.getAdjacent(this.x, this.y)
47+
const topLeftVertex = surface.getVertex(this.x, this.y, adjacent.left, adjacent.topLeft, adjacent.top)
48+
const topRightVertex = surface.getVertex(this.x + 1, this.y, adjacent.top, adjacent.topRight, adjacent.right)
49+
const bottomRightVertex = surface.getVertex(this.x + 1, this.y + 1, adjacent.right, adjacent.bottomRight, adjacent.bottom)
50+
const bottomLeftVertex = surface.getVertex(this.x, this.y + 1, adjacent.bottom, adjacent.bottomLeft, adjacent.left)
51+
if (this.proMesh) {
52+
this.remove(this.proMesh)
53+
this.proMesh.dispose()
54+
this.proMesh = undefined
55+
}
56+
if (surface.wallType === WALL_TYPE.corner || surface.wallType === WALL_TYPE.wall || surface.wallType === WALL_TYPE.invertedCorner ||
57+
(surface.wallType === WALL_TYPE.floor && surface.hasRubble())) {
58+
this.proMesh = ResourceManager.proMeshes.get(proMeshFilepath)?.clone(true)
59+
if (!this.proMesh) console.warn(`Could not find surface pro mesh for "${proMeshFilepath}"`)
60+
}
61+
if (this.proMesh) {
62+
this.proMesh.userData = this.userData
63+
this.proMesh.rotation.y = SurfaceMesh.getWallAngle(surface.wallType, topLeftVertex.high, topRightVertex.high, bottomRightVertex.high, bottomLeftVertex.high)
64+
// TODO Tear pro mesh to fit surface map offsets and close gaps in terrain
65+
const posY = (topLeftVertex.offset + topRightVertex.offset + bottomRightVertex.offset + bottomLeftVertex.offset) / 4
66+
this.proMesh.position.set(this.x + 0.5, posY, this.y + 0.5).multiplyScalar(TILESIZE)
67+
this.add(this.proMesh)
68+
}
69+
if (this.proMesh) this.proMesh.visible = this.proMeshEnabled
70+
this.lowMesh.visible = !this.proMesh?.visible
71+
}
72+
73+
private static getWallAngle(wallType: WallType, topLeftHigh: boolean, topRightHigh: boolean, bottomRightHigh: boolean, bottomLeftHigh: boolean): number {
74+
switch (wallType) {
75+
case WALL_TYPE.corner:
76+
if (topLeftHigh) return Math.PI / 2
77+
else if (bottomLeftHigh) return Math.PI
78+
else if (bottomRightHigh) return -Math.PI / 2
79+
return 0
80+
case WALL_TYPE.invertedCorner:
81+
if (!topLeftHigh) return -Math.PI / 2
82+
else if (!bottomLeftHigh) return 0
83+
else if (!bottomRightHigh) return Math.PI / 2
84+
return Math.PI
85+
case WALL_TYPE.wall:
86+
if (topLeftHigh && topRightHigh) return 0
87+
else if (topLeftHigh && bottomLeftHigh) return Math.PI / 2
88+
else if (topRightHigh && bottomRightHigh) return -Math.PI / 2
89+
else return Math.PI
90+
}
91+
return 0
92+
}
93+
94+
setHeights(wallType: WallType, topLeft: SurfaceVertex, topRight: SurfaceVertex, bottomRight: SurfaceVertex, bottomLeft: SurfaceVertex) {
95+
this.lowMesh.setHeights(wallType, topLeft, topRight, bottomRight, bottomLeft)
96+
}
97+
98+
dispose() {
99+
this.removeFromParent()
100+
this.lowMesh.dispose()
101+
this.proMesh?.dispose()
102+
}
103+
}
104+
105+
class SurfaceMeshLow extends Mesh<SurfaceGeometry, MeshPhongMaterial> {
106+
declare userData: SurfaceMeshUserData
16107

17108
constructor(x: number, y: number, userData: SurfaceMeshUserData) {
18109
super(new SurfaceGeometry(), new MeshPhongMaterial({shininess: 0}))
19-
this.position.set(x, 0, y)
110+
this.position.set(x, 0, y).multiplyScalar(TILESIZE)
20111
this.userData = userData
21112
}
22113

@@ -40,3 +131,20 @@ export class SurfaceMesh extends Mesh<SurfaceGeometry, MeshPhongMaterial> {
40131
this.material.dispose()
41132
}
42133
}
134+
135+
export class RoofMesh extends Mesh<SurfaceGeometry, MeshPhongMaterial> {
136+
constructor(x: number, y: number, texture: Texture | null) { // three.js uses null instead of undefined
137+
super(new SurfaceGeometry(), new MeshPhongMaterial({shininess: 0, side: BackSide, map: texture}))
138+
this.position.set(x, 3, y).multiplyScalar(TILESIZE)
139+
}
140+
141+
setHeights(wallType: WallType, topLeft: SurfaceVertex, topRight: SurfaceVertex, bottomRight: SurfaceVertex, bottomLeft: SurfaceVertex) {
142+
this.geometry.setHeights(wallType, topLeft.flipY(), topRight.flipY(), bottomRight.flipY(), bottomLeft.flipY())
143+
}
144+
145+
dispose() {
146+
this.removeFromParent()
147+
this.geometry.dispose()
148+
this.material.dispose()
149+
}
150+
}

src/gui/overlay/PausePanel.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@ export class PausePanel extends MenuBasePanel {
2020
this.layersByKey.get('menu4')!.itemsTrigger[0].onClick = () => this.onRestartGame()
2121
const advOptions = this.layersByKey.get('menu5')!
2222
const wallDetailsToggle = advOptions.itemsCycle[0]
23-
wallDetailsToggle.disabled = true // TODO Implement wall details with pro meshes
2423
wallDetailsToggle.setState(SaveGameManager.preferences.wallDetails)
24+
wallDetailsToggle.onStateChanged = (state) => {
25+
SaveGameManager.preferences.wallDetails = state
26+
this.publishEvent(new ChangePreferences())
27+
}
2528
const musicToggle = advOptions.itemsCycle[1]
2629
musicToggle.setState(SaveGameManager.preferences.toggleMusic)
2730
musicToggle.onStateChanged = (state) => {

src/nerp/NerpRunner.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ export class NerpRunner {
268268
const tutoBlocks = this.tutoBlocksById.getOrUpdate(tutoBlockId, () => [])
269269
tutoBlocks.forEach((t) => {
270270
if (enabled) {
271-
t.mesh.objectPointer?.setTargetPosition(t.getCenterWorld(), t.mesh)
271+
t.mesh.objectPointer?.setTargetPosition(t.getCenterWorld(), t)
272272
} else {
273273
t.mesh.objectPointer?.hide()
274274
}

0 commit comments

Comments
 (0)