Skip to content

Commit 25acbce

Browse files
Merge dev
* 'dev' of github.com:Autodesk/synthesis: Formatting Batched Mesh For Chrome Versions < 139 Removed Unused Function Fix fix: prevent custom configs from showing as defaults feat: clean up match mode config parsing
2 parents 3199b56 + 90319aa commit 25acbce

File tree

7 files changed

+147
-120
lines changed

7 files changed

+147
-120
lines changed

fission/src/mirabuf/MirabufInstance.ts

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,25 @@ import { ParseErrorSeverity } from "./MirabufParser.ts"
88
type MirabufPartInstanceGUID = string
99

1010
const WIREFRAME = false
11+
const CHROME_VERSION_FOR_INSTANCED_MESH = 139
12+
13+
const detectInstancedMeshSupport = (): boolean => {
14+
const userAgent = navigator.userAgent
15+
const chromeMatch = userAgent.match(/Chrome\/(\d+)/)
16+
17+
if (chromeMatch) {
18+
const chromeVersion = parseInt(chromeMatch[1], 10)
19+
console.log(
20+
`Detected Chrome ${chromeVersion}, using ${chromeVersion >= CHROME_VERSION_FOR_INSTANCED_MESH ? "InstancedMesh" : "BatchedMesh"}`
21+
)
22+
return chromeVersion >= CHROME_VERSION_FOR_INSTANCED_MESH
23+
}
24+
25+
console.log(`Non-Chrome browser detected (${userAgent}), using BatchedMesh`)
26+
return false
27+
}
28+
29+
const USE_INSTANCED_MESH = detectInstancedMeshSupport()
1130

1231
export enum MaterialStyle {
1332
REGULAR = 0,
@@ -93,8 +112,8 @@ const transformGeometry = (geometry: THREE.BufferGeometry, mesh: mirabuf.IMesh)
93112
class MirabufInstance {
94113
private _mirabufParser: MirabufParser
95114
private _materials: Map<string, THREE.Material>
96-
private _meshes: Map<MirabufPartInstanceGUID, Array<[THREE.BatchedMesh, number]>>
97-
private _batches: Array<THREE.BatchedMesh>
115+
private _meshes: Map<MirabufPartInstanceGUID, Array<[THREE.InstancedMesh | THREE.BatchedMesh, number]>>
116+
private _batches: Array<THREE.InstancedMesh | THREE.BatchedMesh>
98117

99118
public get parser() {
100119
return this._mirabufParser
@@ -160,6 +179,63 @@ class MirabufInstance {
160179
* Creates ThreeJS meshes from the parsed mirabuf file.
161180
*/
162181
private createMeshes() {
182+
if (USE_INSTANCED_MESH) {
183+
this.createInstancedMeshes()
184+
} else {
185+
this.createBatchedMeshes()
186+
}
187+
}
188+
189+
/**
190+
* Creates InstancedMesh objects, as newer version of Chrome break with BatchedMesh
191+
*/
192+
private createInstancedMeshes() {
193+
const assembly = this._mirabufParser.assembly
194+
const instances = assembly.data!.parts!.partInstances!
195+
196+
Object.values(instances).forEach(instance => {
197+
const definition = assembly.data!.parts!.partDefinitions![instance.partDefinitionReference!]
198+
const bodies = definition?.bodies ?? []
199+
200+
bodies.forEach(body => {
201+
const mesh = body?.triangleMesh?.mesh
202+
if (!mesh?.verts || !mesh.normals || !mesh.uv || !mesh.indices) return
203+
204+
const appearanceOverride = body.appearanceOverride
205+
const material = WIREFRAME
206+
? new THREE.MeshStandardMaterial({ wireframe: true, color: 0x000000 })
207+
: appearanceOverride && this._materials.has(appearanceOverride)
208+
? this._materials.get(appearanceOverride)!
209+
: fillerMaterials[nextFillerMaterial++ % fillerMaterials.length]
210+
211+
const geometry = new THREE.BufferGeometry()
212+
transformGeometry(geometry, mesh)
213+
214+
// Create InstancedMesh with count of 1 for this body
215+
const instancedMesh = new THREE.InstancedMesh(geometry, material, 1)
216+
instancedMesh.castShadow = true
217+
instancedMesh.receiveShadow = true
218+
219+
const mat = this._mirabufParser.globalTransforms.get(instance.info!.GUID!)!
220+
instancedMesh.setMatrixAt(0, mat)
221+
instancedMesh.instanceMatrix.needsUpdate = true
222+
223+
this._batches.push(instancedMesh)
224+
225+
let bodies = this._meshes.get(instance.info!.GUID!)
226+
if (!bodies) {
227+
bodies = []
228+
this._meshes.set(instance.info!.GUID!, bodies)
229+
}
230+
bodies.push([instancedMesh, 0])
231+
})
232+
})
233+
}
234+
235+
/**
236+
* Creates BatchedMesh, more efficient, but broken in newer versions of Chrome
237+
*/
238+
private createBatchedMeshes() {
163239
const assembly = this._mirabufParser.assembly
164240
const instances = assembly.data!.parts!.partInstances!
165241

@@ -171,6 +247,7 @@ class MirabufInstance {
171247

172248
const batchMap = new Map<THREE.Material, Map<string, [mirabuf.IBody, Array<mirabuf.IPartInstance>]>>()
173249
const countMap = new Map<THREE.Material, BatchCounts>()
250+
174251
// Filter all instances by first material, then body
175252
Object.values(instances).forEach(instance => {
176253
const definition = assembly.data!.parts!.partDefinitions![instance.partDefinitionReference!]
@@ -180,7 +257,6 @@ class MirabufInstance {
180257
if (!mesh?.verts || !mesh.normals || !mesh.uv || !mesh.indices) return
181258

182259
const appearanceOverride = body.appearanceOverride
183-
184260
const material = WIREFRAME
185261
? new THREE.MeshStandardMaterial({ wireframe: true, color: 0x000000 })
186262
: appearanceOverride && this._materials.has(appearanceOverride)

fission/src/mirabuf/MirabufSceneObject.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,13 @@ class MirabufSceneObject extends SceneObject implements ContextSupplier {
471471
.clone()
472472
.premultiply(transform)
473473
const meshes = this._mirabufInstance.meshes.get(part) ?? []
474-
meshes.forEach(([batch, id]) => batch.setMatrixAt(id, partTransform))
474+
meshes.forEach(([mesh, index]) => {
475+
mesh.setMatrixAt(index, partTransform)
476+
// Only update instanceMatrix for InstancedMesh
477+
if ("instanceMatrix" in mesh) {
478+
mesh.instanceMatrix.needsUpdate = true
479+
}
480+
})
475481
})
476482
}
477483

fission/src/systems/match_mode/DefaultMatchModeConfigs.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,22 @@ class DefaultMatchModeConfigs {
6767
}
6868
}
6969

70+
static fallbackValues = (): MatchModeConfig => {
71+
return {
72+
id: "default",
73+
name: "Default",
74+
isDefault: true,
75+
autonomousTime: 15,
76+
teleopTime: 135,
77+
endgameTime: 20,
78+
ignoreRotation: true,
79+
maxHeight: Infinity,
80+
heightLimitPenalty: 2,
81+
sideMaxExtension: Infinity,
82+
sideExtensionPenalty: 2,
83+
}
84+
}
85+
7086
/** @returns {MatchModeConfig[]} New copies of the default match mode configs without reference to any others. */
7187
public static get defaultMatchModeConfigCopies(): MatchModeConfig[] {
7288
return [

fission/src/systems/match_mode/MatchMode.ts

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,13 @@ import beep from "@/assets/sound-files/beep.wav"
22
import MatchEnd from "@/assets/sound-files/MatchEnd.wav"
33
import MatchResume from "@/assets/sound-files/MatchResume.wav"
44
import MatchStart from "@/assets/sound-files/MatchStart.wav"
5-
import { globalOpenModal } from "@/ui/components/GlobalUIControls"
6-
import MatchResultsModal from "@/ui/modals/MatchResultsModal"
5+
import { globalOpenModal } from "@/components/GlobalUIControls.ts"
6+
import MatchResultsModal from "@/modals/MatchResultsModal.tsx"
7+
import DefaultMatchModeConfigs from "@/systems/match_mode/DefaultMatchModeConfigs.ts"
78
import type { MatchModeConfig } from "@/ui/panels/configuring/MatchModeConfigPanel"
89
import SimulationSystem from "../simulation/SimulationSystem"
910
import { SoundPlayer } from "../sound/SoundPlayer"
10-
import {
11-
DEFAULT_AUTONOMOUS_TIME,
12-
DEFAULT_ENDGAME_TIME,
13-
DEFAULT_HEIGHT_LIMIT_PENALTY,
14-
DEFAULT_IGNORE_ROTATION,
15-
DEFAULT_MAX_HEIGHT,
16-
DEFAULT_SIDE_EXTENSION_PENALTY,
17-
DEFAULT_SIDE_MAX_EXTENSION,
18-
DEFAULT_TELEOP_TIME,
19-
MatchModeType,
20-
} from "./MatchModeTypes"
11+
import { MatchModeType } from "./MatchModeTypes"
2112
import RobotDimensionTracker from "./RobotDimensionTracker"
2213

2314
class MatchMode {
@@ -35,19 +26,7 @@ class MatchMode {
3526
private _intervalId: number | null = null
3627

3728
// Match Mode Config
38-
private _matchModeConfig: MatchModeConfig = {
39-
id: "default",
40-
name: "Default",
41-
isDefault: true,
42-
autonomousTime: DEFAULT_AUTONOMOUS_TIME,
43-
teleopTime: DEFAULT_TELEOP_TIME,
44-
endgameTime: DEFAULT_ENDGAME_TIME,
45-
ignoreRotation: DEFAULT_IGNORE_ROTATION,
46-
maxHeight: DEFAULT_MAX_HEIGHT,
47-
heightLimitPenalty: DEFAULT_HEIGHT_LIMIT_PENALTY,
48-
sideExtensionPenalty: DEFAULT_SIDE_EXTENSION_PENALTY,
49-
sideMaxExtension: DEFAULT_SIDE_MAX_EXTENSION,
50-
}
29+
private _matchModeConfig: MatchModeConfig = DefaultMatchModeConfigs.fallbackValues()
5130

5231
private constructor() {}
5332

fission/src/systems/match_mode/MatchModeTypes.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,3 @@ export enum MatchModeType {
55
ENDGAME = "Endgame",
66
MATCH_ENDED = "Match Ended",
77
}
8-
9-
// Default match mode timing values
10-
export const DEFAULT_AUTONOMOUS_TIME = 15
11-
export const DEFAULT_TELEOP_TIME = 135
12-
export const DEFAULT_ENDGAME_TIME = 20
13-
export const DEFAULT_IGNORE_ROTATION = true
14-
export const DEFAULT_MAX_HEIGHT = Infinity
15-
export const DEFAULT_HEIGHT_LIMIT_PENALTY = 2
16-
export const DEFAULT_SIDE_MAX_EXTENSION = Infinity
17-
export const DEFAULT_SIDE_EXTENSION_PENALTY = 2

fission/src/test/RobotDimensionsTracker.test.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { MiraType } from "@/mirabuf/MirabufLoader"
33
import MirabufSceneObject from "@/mirabuf/MirabufSceneObject"
44
import RobotDimensionTracker from "@/systems/match_mode/RobotDimensionTracker"
55
import SimulationSystem from "@/systems/simulation/SimulationSystem"
6-
import World from "@/systems/World.ts"
6+
import World from "@/systems/World"
77

88
interface MockDimensions {
99
width: number
@@ -48,14 +48,6 @@ vi.mock("@/systems/match_mode/MatchMode", () => ({
4848
TELEOP: 2,
4949
MATCH_ENDED: 3,
5050
},
51-
DEFAULT_AUTONOMOUS_TIME: 15,
52-
DEFAULT_TELEOP_TIME: 135,
53-
DEFAULT_ENDGAME_TIME: 20,
54-
DEFAULT_IGNORE_ROTATION: true,
55-
DEFAULT_MAX_HEIGHT: Infinity,
56-
DEFAULT_HEIGHT_LIMIT_PENALTY: 2,
57-
DEFAULT_SIDE_MAX_EXTENSION: 1.5,
58-
DEFAULT_SIDE_EXTENSION_PENALTY: 2,
5951
}))
6052

6153
vi.mock("@/systems/simulation/SimulationSystem", () => ({

0 commit comments

Comments
 (0)