Skip to content

Commit

Permalink
Intake/Scoring Collisions (#1035)
Browse files Browse the repository at this point in the history
  • Loading branch information
HunterBarclay authored Jul 26, 2024
2 parents 06b0cb3 + bfe788a commit f467f95
Show file tree
Hide file tree
Showing 20 changed files with 742 additions and 75 deletions.
13 changes: 12 additions & 1 deletion fission/src/Synthesis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ import Lazy from "./util/Lazy.ts"
import DebugPanel from "./ui/panels/DebugPanel.tsx"
import NewInputSchemeModal from "./ui/modals/configuring/theme-editor/NewInputSchemeModal.tsx"
import AssignNewSchemeModal from "./ui/modals/configuring/theme-editor/AssignNewSchemeModal.tsx"
import PreferencesSystem from "./systems/preferences/PreferencesSystem.ts"

const worker = new Lazy<Worker>(() => new WPILibWSWorker())

Expand Down Expand Up @@ -119,6 +120,16 @@ function Synthesis() {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])

useEffect(() => {
let scoreboardExists = false
panelElements.forEach(x => {
if (x.key == "scoreboard") scoreboardExists = true
})
if (PreferencesSystem.getGlobalPreference("RenderScoreboard") && !scoreboardExists) {
openPanel("scoreboard")
}
})

return (
<AnimatePresence key={"animate-presence"}>
<Skybox key={"skybox"} />
Expand Down Expand Up @@ -203,7 +214,7 @@ const initialPanels: ReactElement[] = [
<RobotSwitchPanel key="multibot" panelId="multibot" openLocation="right" sidePadding={8} />,
<DriverStationPanel key="driver-station" panelId="driver-station" />,
<SpawnLocationsPanel key="spawn-locations" panelId="spawn-locations" />,
<ScoreboardPanel key="scoreboard" panelId="scoreboard" />,
<ScoreboardPanel key="scoreboard" panelId="scoreboard" openLocation="top" sidePadding={8} />,
<ConfigureGamepiecePickupPanel
key="config-gamepiece-pickup"
panelId="config-gamepiece-pickup"
Expand Down
18 changes: 18 additions & 0 deletions fission/src/mirabuf/EjectableSceneObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
ThreeVector3_JoltVec3,
} from "@/util/TypeConversions"
import * as THREE from "three"
import ScoringZoneSceneObject from "./ScoringZoneSceneObject"

class EjectableSceneObject extends SceneObject {
private _parentAssembly: MirabufSceneObject
Expand All @@ -23,6 +24,10 @@ class EjectableSceneObject extends SceneObject {
return this._gamePieceBodyId
}

public get parentBodyId() {
return this._parentBodyId
}

public constructor(parentAssembly: MirabufSceneObject, gamePieceBody: Jolt.BodyID) {
super()

Expand All @@ -43,6 +48,19 @@ class EjectableSceneObject extends SceneObject {

World.PhysicsSystem.DisablePhysicsForBody(this._gamePieceBodyId)

// Checks if the gamepiece comes from a zone for persistent point score updates
// because gamepieces removed by intake are not detected in the collision listener
const zones = [...World.SceneRenderer.sceneObjects.entries()]
.filter(x => {
const y = x[1] instanceof ScoringZoneSceneObject
return y
})
.map(x => x[1]) as ScoringZoneSceneObject[]

zones.forEach(x => {
if (this._gamePieceBodyId) ScoringZoneSceneObject.RemoveGamepiece(x, this._gamePieceBodyId)
})

console.debug("Ejectable created successfully!")
}
}
Expand Down
42 changes: 29 additions & 13 deletions fission/src/mirabuf/IntakeSensorSceneObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {
ThreeQuaternion_JoltQuat,
ThreeVector3_JoltVec3,
} from "@/util/TypeConversions"
import { OnContactPersistedEvent } from "@/systems/physics/ContactEvents"
import InputSystem from "@/systems/input/InputSystem"

class IntakeSensorSceneObject extends SceneObject {
private _parentAssembly: MirabufSceneObject
Expand All @@ -18,6 +20,7 @@ class IntakeSensorSceneObject extends SceneObject {

private _joltBodyId?: Jolt.BodyID
private _mesh?: THREE.Mesh
private _collision?: (e: OnContactPersistedEvent) => void

public constructor(parentAssembly: MirabufSceneObject) {
super()
Expand Down Expand Up @@ -49,6 +52,23 @@ class IntakeSensorSceneObject extends SceneObject {
)
World.SceneRenderer.scene.add(this._mesh)

this._collision = (event: OnContactPersistedEvent) => {
if (InputSystem.getInput("intake", this._parentAssembly.brain?.brainIndex ?? -1)) {
if (this._joltBodyId && !World.PhysicsSystem.isPaused) {
const body1 = event.message.body1
const body2 = event.message.body2

if (body1.GetIndexAndSequenceNumber() == this._joltBodyId.GetIndexAndSequenceNumber()) {
this.IntakeCollision(body2)
} else if (body2.GetIndexAndSequenceNumber() == this._joltBodyId.GetIndexAndSequenceNumber()) {
this.IntakeCollision(body1)
}
}
}
}

OnContactPersistedEvent.AddListener(this._collision)

console.debug("Intake sensor created successfully!")
}
}
Expand All @@ -70,19 +90,6 @@ class IntakeSensorSceneObject extends SceneObject {
this._mesh.position.setFromMatrixPosition(bodyTransform)
this._mesh.rotation.setFromRotationMatrix(bodyTransform)
}

if (!World.PhysicsSystem.isPaused) {
// TEMPORARY GAME PIECE DETECTION
const hitRes = World.PhysicsSystem.RayCast(ThreeVector3_JoltVec3(position), new JOLT.Vec3(0, 0, 3))
if (hitRes) {
const gpAssoc = <RigidNodeAssociate>World.PhysicsSystem.GetBodyAssociation(hitRes.data.mBodyID)
// This works, however the check for game piece is doing two checks.
if (gpAssoc?.isGamePiece) {
console.debug("Found game piece!")
this._parentAssembly.SetEjectable(hitRes.data.mBodyID, false)
}
}
}
}
}

Expand All @@ -98,6 +105,15 @@ class IntakeSensorSceneObject extends SceneObject {
World.SceneRenderer.scene.remove(this._mesh)
}
}

if (this._collision) OnContactPersistedEvent.RemoveListener(this._collision)
}

private IntakeCollision(gpID: Jolt.BodyID) {
const associate = <RigidNodeAssociate>World.PhysicsSystem.GetBodyAssociation(gpID)
if (associate?.isGamePiece) {
this._parentAssembly.SetEjectable(gpID, false)
}
}
}

Expand Down
31 changes: 30 additions & 1 deletion fission/src/mirabuf/MirabufSceneObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import PreferencesSystem from "@/systems/preferences/PreferencesSystem"
import { MiraType } from "./MirabufLoader"
import IntakeSensorSceneObject from "./IntakeSensorSceneObject"
import EjectableSceneObject from "./EjectableSceneObject"
import ScoringZoneSceneObject from "./ScoringZoneSceneObject"
import { SceneOverlayTag } from "@/ui/components/SceneOverlayEvents"
import { ProgressHandle } from "@/ui/components/ProgressNotificationData"

Expand Down Expand Up @@ -45,6 +46,7 @@ class MirabufSceneObject extends SceneObject {

private _intakeSensor?: IntakeSensorSceneObject
private _ejectable?: EjectableSceneObject
private _scoringZones: ScoringZoneSceneObject[] = []

private _nameTag: SceneOverlayTag | undefined

Expand Down Expand Up @@ -84,6 +86,10 @@ class MirabufSceneObject extends SceneObject {
return this._mirabufInstance.parser.rootNode
}

public get brain() {
return this._brain
}

public constructor(mirabufInstance: MirabufInstance, assemblyName: string, progressHandle?: ProgressHandle) {
super()

Expand Down Expand Up @@ -148,10 +154,12 @@ class MirabufSceneObject extends SceneObject {

// Intake
this.UpdateIntakeSensor()

this.UpdateScoringZones()
}

public Update(): void {
if (InputSystem.currentModifierState.ctrl && InputSystem.currentModifierState.shift && this._ejectable) {
if (InputSystem.getInput("eject", this._brain?.brainIndex ?? -1)) {
this.Eject()
}

Expand Down Expand Up @@ -241,6 +249,9 @@ class MirabufSceneObject extends SceneObject {
this._ejectable = undefined
}

this._scoringZones.forEach(zone => World.SceneRenderer.RemoveSceneObject(zone.id))
this._scoringZones = []

this._mechanism.nodeToBody.forEach(bodyId => {
World.PhysicsSystem.RemoveBodyAssocation(bodyId)
})
Expand Down Expand Up @@ -330,6 +341,7 @@ class MirabufSceneObject extends SceneObject {
}

if (!this._ejectorPreferences || !this._ejectorPreferences.parentNode || !bodyId) {
console.log(`Configure an ejectable first.`)
return false
}

Expand All @@ -338,6 +350,23 @@ class MirabufSceneObject extends SceneObject {
return true
}

public UpdateScoringZones(render?: boolean) {
this._scoringZones.forEach(zone => World.SceneRenderer.RemoveSceneObject(zone.id))
this._scoringZones = []

if (this._fieldPreferences && this._fieldPreferences.scoringZones) {
for (let i = 0; i < this._fieldPreferences.scoringZones.length; i++) {
const newZone = new ScoringZoneSceneObject(
this,
i,
render ?? PreferencesSystem.getGlobalPreference("RenderScoringZones")
)
this._scoringZones.push(newZone)
World.SceneRenderer.RegisterSceneObject(newZone)
}
}
}

/**
* Changes the mode of the mirabuf object from being interacted with to being placed.
*/
Expand Down
Loading

0 comments on commit f467f95

Please sign in to comment.