Skip to content

Commit 790d121

Browse files
committed
Merge branch 'dev' into zachr/1945/input-scheme-mode-conflict
2 parents bdf0df4 + 7f6410b commit 790d121

32 files changed

+1129
-497
lines changed

fission/src/mirabuf/EjectableSceneObject.ts

Lines changed: 63 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,21 @@ class EjectableSceneObject extends SceneObject {
2121
private _deltaTransformation?: THREE.Matrix4
2222
private _ejectVelocity?: number
2323

24+
// Animation state
25+
private _animationStartTime = 0
26+
private _animationDuration = EjectableSceneObject._defaultAnimationDuration
27+
private _startTranslation?: THREE.Vector3
28+
private _startRotation?: THREE.Quaternion
29+
30+
private static _defaultAnimationDuration = 0.5
31+
32+
public static setAnimationDuration(duration: number) {
33+
EjectableSceneObject._defaultAnimationDuration = duration
34+
}
35+
public static getAnimationDuration() {
36+
return EjectableSceneObject._defaultAnimationDuration
37+
}
38+
2439
public get gamePieceBodyId() {
2540
return this._gamePieceBodyId
2641
}
@@ -49,15 +64,24 @@ class EjectableSceneObject extends SceneObject {
4964
)
5065
this._ejectVelocity = this._parentAssembly.ejectorPreferences.ejectorVelocity
5166

67+
// Record start transform at the game piece center of mass
68+
const gpBody = World.physicsSystem.getBody(this._gamePieceBodyId)
69+
this._startTranslation = new THREE.Vector3(0, 0, 0)
70+
this._startRotation = new THREE.Quaternion(0, 0, 0, 1)
71+
convertJoltMat44ToThreeMatrix4(gpBody.GetCenterOfMassTransform()).decompose(
72+
this._startTranslation,
73+
this._startRotation,
74+
new THREE.Vector3(1, 1, 1)
75+
)
76+
77+
this._animationDuration = EjectableSceneObject._defaultAnimationDuration
78+
this._animationStartTime = performance.now()
79+
5280
World.physicsSystem.disablePhysicsForBody(this._gamePieceBodyId)
5381

54-
// Checks if the gamepiece comes from a zone for persistent point score updates
55-
// because gamepieces removed by intake are not detected in the collision listener
82+
// Remove from any scoring zones
5683
const zones = [...World.sceneRenderer.sceneObjects.entries()]
57-
.filter(x => {
58-
const y = x[1] instanceof ScoringZoneSceneObject
59-
return y
60-
})
84+
.filter(x => x[1] instanceof ScoringZoneSceneObject)
6185
.map(x => x[1]) as ScoringZoneSceneObject[]
6286

6387
zones.forEach(x => {
@@ -69,26 +93,51 @@ class EjectableSceneObject extends SceneObject {
6993
}
7094

7195
public update(): void {
96+
const now = performance.now()
97+
const elapsed = (now - this._animationStartTime) / 1000
98+
const tRaw = elapsed / this._animationDuration
99+
const t = Math.min(tRaw, 1)
100+
101+
// ease-in curve for gradual acceleration
102+
const easedT = t * t
103+
72104
if (this._parentBodyId && this._deltaTransformation && this._gamePieceBodyId) {
73105
if (!World.physicsSystem.isBodyAdded(this._gamePieceBodyId)) {
74106
this._gamePieceBodyId = undefined
75107
return
76108
}
77109

78-
// I had a think and free wrote this matrix math on a whim. It worked first try and I honestly can't quite remember how it works... -Hunter
79110
const gpBody = World.physicsSystem.getBody(this._gamePieceBodyId)
80111
const posToCOM = convertJoltMat44ToThreeMatrix4(gpBody.GetCenterOfMassTransform()).premultiply(
81112
convertJoltMat44ToThreeMatrix4(gpBody.GetWorldTransform()).invert()
82113
)
83114

84115
const body = World.physicsSystem.getBody(this._parentBodyId)
85-
const bodyTransform = posToCOM
86-
.invert()
87-
.premultiply(
88-
this._deltaTransformation
89-
.clone()
90-
.premultiply(convertJoltMat44ToThreeMatrix4(body.GetWorldTransform()))
91-
)
116+
let desiredPosition = new THREE.Vector3(0, 0, 0)
117+
let desiredRotation = new THREE.Quaternion(0, 0, 0, 1)
118+
119+
// Compute target world transform
120+
const desiredTransform = this._deltaTransformation
121+
.clone()
122+
.premultiply(convertJoltMat44ToThreeMatrix4(body.GetWorldTransform()))
123+
124+
desiredTransform.decompose(desiredPosition, desiredRotation, new THREE.Vector3(1, 1, 1))
125+
126+
if (t < 1 && this._startTranslation && this._startRotation) {
127+
// gradual acceleration via easedT
128+
desiredPosition = new THREE.Vector3().lerpVectors(this._startTranslation, desiredPosition, easedT)
129+
desiredRotation = new THREE.Quaternion().copy(this._startRotation).slerp(desiredRotation, easedT)
130+
}
131+
// } else if (t >= 1) {
132+
// // snap instantly and re-enable physics
133+
// World.physicsSystem.enablePhysicsForBody(this._gamePieceBodyId)
134+
// }
135+
136+
// apply the transform
137+
desiredTransform.identity().compose(desiredPosition, desiredRotation, new THREE.Vector3(1, 1, 1))
138+
139+
const bodyTransform = posToCOM.clone().invert().premultiply(desiredTransform)
140+
92141
const position = new THREE.Vector3(0, 0, 0)
93142
const rotation = new THREE.Quaternion(0, 0, 0, 1)
94143
bodyTransform.decompose(position, rotation, new THREE.Vector3(1, 1, 1))

fission/src/mirabuf/MirabufSceneObject.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ import WPILibBrain from "@/systems/simulation/wpilib_brain/WPILibBrain"
4545
import { OnContactAddedEvent } from "@/systems/physics/ContactEvents"
4646
import FieldMiraEditor from "./FieldMiraEditor"
4747

48+
import { DriveType } from "@/systems/simulation/behavior/Behavior.ts"
49+
4850
const DEBUG_BODIES = false
4951

5052
interface RnDebugMeshes {

fission/src/systems/MatchMode.ts

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,13 @@ export const DEFAULT_ENDGAME_TIME = 20
2020

2121
class MatchMode {
2222
private static _instance: MatchMode
23-
private _matchEnabled: boolean = false
2423
private _endgame: boolean = false
2524
private _matchModeType: MatchModeType = MatchModeType.SANDBOX
2625

26+
private setMatchModeType(val: MatchModeType) {
27+
this._matchModeType = val
28+
new MatchStateChangeEvent(val).dispatch()
29+
}
2730
private _initialTime: number = 0
2831
private _timeLeft: number = 0
2932
private _intervalId: number | null = null
@@ -77,7 +80,7 @@ class MatchMode {
7780

7881
autonomousModeStart(openModal: (modalName: string) => void) {
7982
SoundPlayer.play(MatchStart)
80-
this._matchModeType = MatchModeType.AUTONOMOUS
83+
this.setMatchModeType(MatchModeType.AUTONOMOUS)
8184
this.startTimer(this._matchModeConfig.autonomousTime, () => this.autonomousModeEnd(openModal))
8285
}
8386

@@ -88,7 +91,7 @@ class MatchMode {
8891

8992
teleopModeStart(openModal: (modalName: string) => void) {
9093
SoundPlayer.play(MatchResume)
91-
this._matchModeType = MatchModeType.TELEOP
94+
this.setMatchModeType(MatchModeType.TELEOP)
9295
this.startTimer(this._matchModeConfig.teleopTime, () => this.matchEnded(openModal))
9396
}
9497

@@ -98,22 +101,19 @@ class MatchMode {
98101
}
99102

100103
start(openModal: (modalName: string) => void) {
101-
this._matchEnabled = true
102104
this.autonomousModeStart(openModal)
103105
SimulationSystem.resetScores()
104106
}
105107

106108
matchEnded(openModal: (modalName: string) => void) {
107109
SoundPlayer.play(MatchEnd)
108110
clearInterval(this._intervalId as number)
109-
this._matchEnabled = false
110-
this._matchModeType = MatchModeType.MATCH_ENDED
111+
this.setMatchModeType(MatchModeType.MATCH_ENDED)
111112
if (openModal) openModal("match-results")
112113
}
113114

114115
sandboxModeStart() {
115-
this._matchEnabled = false
116-
this._matchModeType = MatchModeType.SANDBOX
116+
this.setMatchModeType(MatchModeType.SANDBOX)
117117
clearInterval(this._intervalId as number)
118118
this._initialTime = 0
119119
this._timeLeft = 0
@@ -122,7 +122,7 @@ class MatchMode {
122122
}
123123

124124
isMatchEnabled(): boolean {
125-
return this._matchEnabled
125+
return !(this._matchModeType == MatchModeType.SANDBOX || this._matchModeType == MatchModeType.MATCH_ENDED)
126126
}
127127

128128
isEndgame(): boolean {
@@ -158,3 +158,25 @@ export class UpdateTimeLeft extends Event {
158158
window.removeEventListener(UpdateTimeLeft.EVENT_KEY, func as (e: Event) => void)
159159
}
160160
}
161+
162+
export class MatchStateChangeEvent extends Event {
163+
public static readonly EVENT_KEY = "MatchEnd"
164+
165+
public readonly matchModeType: MatchModeType
166+
constructor(matchModeType: MatchModeType) {
167+
super(MatchStateChangeEvent.EVENT_KEY)
168+
this.matchModeType = matchModeType
169+
}
170+
171+
public dispatch(): void {
172+
window.dispatchEvent(this)
173+
}
174+
175+
public static addListener(func: (e: MatchStateChangeEvent) => void) {
176+
window.addEventListener(MatchStateChangeEvent.EVENT_KEY, func as (e: Event) => void)
177+
}
178+
179+
public static removeListener(func: (e: MatchStateChangeEvent) => void) {
180+
window.removeEventListener(MatchStateChangeEvent.EVENT_KEY, func as (e: Event) => void)
181+
}
182+
}

0 commit comments

Comments
 (0)