Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Input Manager #977

Merged
merged 17 commits into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion engine/Assets/Scripts/Drivers/WheelDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -218,4 +218,4 @@ private void VelocityControl() {
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -238,4 +238,4 @@ public enum SynthesisColor {
AcceptCancelButtonText
}
}
}
}
1 change: 0 additions & 1 deletion fission/src/aps/APS.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { MainHUD_AddToast } from "@/components/MainHUD"
import { Random } from "@/util/Random"

const APS_AUTH_KEY = "aps_auth"
Expand Down
7 changes: 4 additions & 3 deletions fission/src/mirabuf/MirabufSceneObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,10 @@ class MirabufSceneObject extends SceneObject {
colliderMesh.position.setFromMatrixPosition(transform)
colliderMesh.rotation.setFromRotationMatrix(transform)

const comTransform = JoltMat44_ThreeMatrix4(body.GetCenterOfMassTransform())
comMesh.position.setFromMatrixPosition(comTransform)
comMesh.rotation.setFromRotationMatrix(comTransform)
const comTransform = JoltMat44_ThreeMatrix4(body.GetCenterOfMassTransform());

comMesh.position.setFromMatrixPosition(comTransform);
comMesh.rotation.setFromRotationMatrix(comTransform);
}
})
}
Expand Down
34 changes: 21 additions & 13 deletions fission/src/systems/World.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import * as THREE from "three"

import PhysicsSystem from "./physics/PhysicsSystem"
import SceneRenderer from "./scene/SceneRenderer"
import SimulationSystem from "./simulation/SimulationSystem"
import PhysicsSystem from "./physics/PhysicsSystem";
import SceneRenderer from "./scene/SceneRenderer";
import SimulationSystem from "./simulation/SimulationSystem";
import InputSystem from "./input/InputSystem";

class World {
private static _isAlive: boolean = false
Expand All @@ -11,6 +12,7 @@ class World {
private static _sceneRenderer: SceneRenderer
private static _physicsSystem: PhysicsSystem
private static _simulationSystem: SimulationSystem
private static _inputSystem: InputSystem

public static get isAlive() {
return World._isAlive
Expand All @@ -25,33 +27,39 @@ class World {
public static get SimulationSystem() {
return World._simulationSystem
}
public static get InputSystem() {
return World._inputSystem
}

public static InitWorld() {
if (World._isAlive) return

World._clock = new THREE.Clock()
World._isAlive = true

World._sceneRenderer = new SceneRenderer()
World._physicsSystem = new PhysicsSystem()
World._simulationSystem = new SimulationSystem()
World._sceneRenderer = new SceneRenderer();
World._physicsSystem = new PhysicsSystem();
World._simulationSystem = new SimulationSystem();
World._inputSystem = new InputSystem();
}

public static DestroyWorld() {
if (!World._isAlive) return

World._isAlive = false

World._physicsSystem.Destroy()
World._sceneRenderer.Destroy()
World._simulationSystem.Destroy()
World._physicsSystem.Destroy();
World._sceneRenderer.Destroy();
World._simulationSystem.Destroy();
World._inputSystem.Destroy();
}

public static UpdateWorld() {
const deltaT = World._clock.getDelta()
World._simulationSystem.Update(deltaT)
World._physicsSystem.Update(deltaT)
World._sceneRenderer.Update(deltaT)
const deltaT = World._clock.getDelta();
World._simulationSystem.Update(deltaT);
World._physicsSystem.Update(deltaT);
World._inputSystem.Update(deltaT);
World._sceneRenderer.Update(deltaT);
}
}

Expand Down
130 changes: 130 additions & 0 deletions fission/src/systems/input/InputSystem.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import WorldSystem from "../WorldSystem";

declare global {
type ModifierState = {
alt: boolean
ctrl: boolean
shift: boolean
meta: boolean
}

type Input = {
name: string
keyCode: string
isGlobal: boolean
modifiers: ModifierState
}
}

export const emptyModifierState: ModifierState = { ctrl: false, alt: false, shift: false, meta: false };

// When a robot is loaded, default inputs replace any unassigned inputs
const defaultInputs: { [key: string]: Input } = {
"intake": { name: "intake", keyCode: "KeyE", isGlobal: true, modifiers: emptyModifierState },
"shootGamepiece": { name: "shootGamepiece", keyCode: "KeyQ", isGlobal: true, modifiers: emptyModifierState },
"enableGodMode": { name: "enableGodMode", keyCode: "KeyG", isGlobal: true, modifiers: emptyModifierState },

"arcadeForward": { name: "arcadeForward", keyCode: "KeyW", isGlobal: false, modifiers: emptyModifierState },
"arcadeBackward": { name: "arcadeBackward", keyCode: "KeyS", isGlobal: false, modifiers: emptyModifierState },
"arcadeLeft": { name: "arcadeLeft", keyCode: "KeyA", isGlobal: false, modifiers: emptyModifierState },
"arcadeRight": { name: "arcadeRight", keyCode: "KeyD", isGlobal: false, modifiers: emptyModifierState },
}

class InputSystem extends WorldSystem {
public static allInputs: { [key: string]: Input } = { }
private static _currentModifierState: ModifierState;

// Inputs global to all of synthesis like camera controls
public static get globalInputs(): { [key: string]: Input } {
return Object.fromEntries(
Object.entries(InputSystem.allInputs)
.filter(([_, input]) => input.isGlobal));
}

// Robot specific controls like driving
public static get robotInputs(): { [key: string]: Input } {
return Object.fromEntries(
Object.entries(InputSystem.allInputs)
.filter(([_, input]) => !input.isGlobal));
}

// A list of keys currently being pressed
private static _keysPressed: { [key: string]: boolean } = {};

constructor() {
super();

this.HandleKeyDown = this.HandleKeyDown.bind(this);
document.addEventListener('keydown', this.HandleKeyDown);

this.HandleKeyUp = this.HandleKeyUp.bind(this);
document.addEventListener('keyup', this.HandleKeyUp);

// TODO: Load saved inputs from mira (robot specific) & global inputs

for (const key in defaultInputs) {
if (Object.prototype.hasOwnProperty.call(defaultInputs, key)) {
InputSystem.allInputs[key] = defaultInputs[key];
}
}
}

public Update(_: number): void {
if (!document.hasFocus()) {
for (const keyCode in InputSystem._keysPressed)
delete InputSystem._keysPressed[keyCode];
return;
}

InputSystem._currentModifierState = { ctrl: InputSystem.isKeyPressed("ControlLeft") || InputSystem.isKeyPressed("ControlRight"), alt: InputSystem.isKeyPressed("AltLeft") || InputSystem.isKeyPressed("AltRight"), shift: InputSystem.isKeyPressed("ShiftLeft") || InputSystem.isKeyPressed("ShiftRight"), meta: InputSystem.isKeyPressed("MetaLeft") || InputSystem.isKeyPressed("MetaRight") }
}

public Destroy(): void {
document.removeEventListener('keydown', this.HandleKeyDown);
document.removeEventListener('keyup', this.HandleKeyUp);
}

// Called when any key is pressed
private HandleKeyDown(event: KeyboardEvent) {
InputSystem._keysPressed[event.code] = true;
}

// Called when any key is released
private HandleKeyUp(event: KeyboardEvent) {
InputSystem._keysPressed[event.code] = false;
}

// Returns true if the given key is currently down
private static isKeyPressed(key: string): boolean {
return !!InputSystem._keysPressed[key];
}

// If an input exists, return true if it is pressed
public static getInput(inputName: string) : boolean {
// Checks if there is an input assigned to this action
if (inputName in this.allInputs) {
const targetInput = this.allInputs[inputName];

// Check for input modifiers
if (!this.CompareModifiers(InputSystem._currentModifierState, targetInput.modifiers))
return false;

return this.isKeyPressed(targetInput.keyCode);
}

// If the input does not exist, returns false
return false;
}

// Combines two inputs into a positive/negative axis
public static GetAxis(positive: string, negative: string) {
return (this.getInput(positive) ? 1 : 0) - (this.getInput(negative) ? 1 : 0);
}

// Returns true if two modifier states are identical
private static CompareModifiers(state1: ModifierState, state2: ModifierState) : boolean {
return state1.alt == state2.alt && state1.ctrl == state2.ctrl && state1.meta == state2.meta && state1.shift == state2.shift;
}
}

export default InputSystem;
17 changes: 10 additions & 7 deletions fission/src/systems/simulation/SimulationSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ class SimulationLayer {
private _drivers: Driver[]
private _stimuli: Stimulus[]

public get brain() {
return this._brain
}
public get brain() { return this._brain; }
public get drivers() { return this._drivers; }
public get stimuli() { return this._stimuli; }

constructor(mechanism: Mechanism) {
this._mechanism = mechanism
Expand Down Expand Up @@ -101,10 +101,13 @@ class SimulationLayer {
public SetBrain<T extends Brain>(brain: T | undefined) {
if (this._brain) this._brain.Disable()

this._brain = brain

if (this._brain) this._brain.Enable()
this._brain = brain;

if (this._brain) {
this._brain.Enable();
}
}
}

export default SimulationSystem
export default SimulationSystem;
export {SimulationLayer};
35 changes: 35 additions & 0 deletions fission/src/systems/simulation/behavior/ArcadeDriveBehavior.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import WheelDriver from "../driver/WheelDriver";
import WheelRotationStimulus from "../stimulus/WheelStimulus";
import Behavior from "./Behavior";
import InputSystem from "@/systems/input/InputSystem";

class ArcadeDriveBehavior extends Behavior {
leftWheels: WheelDriver[];
rightWheels: WheelDriver[];

private _driveSpeed = 30;
private _turnSpeed = 30;

constructor(leftWheels: WheelDriver[], rightWheels: WheelDriver[], leftStimuli: WheelRotationStimulus[], rightStimuli: WheelRotationStimulus[]) {
super(leftWheels.concat(rightWheels), leftStimuli.concat(rightStimuli));

this.leftWheels = leftWheels;
this.rightWheels = rightWheels;
}

// Sets the drivetrains target linear and rotational velocity
private DriveSpeeds(linearVelocity: number, rotationVelocity: number) {
const leftSpeed = linearVelocity + rotationVelocity;
const rightSpeed = linearVelocity - rotationVelocity;

this.leftWheels.forEach((wheel) => wheel.targetWheelSpeed = leftSpeed);
this.rightWheels.forEach((wheel) => wheel.targetWheelSpeed = rightSpeed);
}

public Update(_: number): void {
this.DriveSpeeds(InputSystem.GetAxis("arcadeForward", "arcadeBackward")*this._driveSpeed,
InputSystem.GetAxis("arcadeRight", "arcadeLeft")*this._turnSpeed);
}
}

export default ArcadeDriveBehavior;
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ abstract class Behavior {
this._drivers = drivers
this._stimuli = stimuli
}

public abstract Update(deltaT: number): void;
}

export default Behavior
37 changes: 37 additions & 0 deletions fission/src/systems/simulation/behavior/GenericArmBehavior.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import HingeDriver from "../driver/HingeDriver";
import HingeStimulus from "../stimulus/HingeStimulus";
import Behavior from "./Behavior";
import InputSystem, { emptyModifierState } from "@/systems/input/InputSystem";

class GenericArmBehavior extends Behavior {
private _hingeDriver: HingeDriver;

private _positiveInput: string;
private _negativeInput: string;

private _rotationalSpeed = 30;

constructor(hingeDriver: HingeDriver, hingeStimulus: HingeStimulus, jointIndex: number) {
super([hingeDriver], [hingeStimulus]);
this._hingeDriver = hingeDriver;

this._positiveInput = "joint " + jointIndex + " Positive";
this._negativeInput = "joint " + jointIndex + " Negative";

// TODO: load inputs from mira
InputSystem.allInputs[this._positiveInput] = { name: this._positiveInput, keyCode: "Digit" + jointIndex.toString(), isGlobal: false, modifiers: emptyModifierState };
InputSystem.allInputs[this._negativeInput] = { name: this._negativeInput, keyCode: "Digit" + jointIndex.toString(), isGlobal: false,
modifiers: { ctrl: false, alt: false, shift: true, meta: false } };
}

// Sets the arms target rotational velocity
rotateArm(rotationalVelocity: number) {
this._hingeDriver.targetVelocity = rotationalVelocity;
}

public Update(_: number): void {
this.rotateArm(InputSystem.GetAxis(this._positiveInput, this._negativeInput)*this._rotationalSpeed);
}
}

export default GenericArmBehavior;
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import SliderDriver from "../driver/SliderDriver";
import SliderStimulus from "../stimulus/SliderStimulus";
import Behavior from "./Behavior";
import InputSystem, { emptyModifierState } from "@/systems/input/InputSystem";

class GenericElevatorBehavior extends Behavior {
private _sliderDriver: SliderDriver;

private _positiveInput: string;
private _negativeInput: string;

private _linearSpeed = 1;

constructor(sliderDriver: SliderDriver, sliderStimulus: SliderStimulus, jointIndex: number) {
super([sliderDriver], [sliderStimulus]);
this._sliderDriver = sliderDriver;

this._positiveInput = "joint " + jointIndex + " Positive";
this._negativeInput = "joint " + jointIndex + " Negative";

// TODO: load inputs from mira
InputSystem.allInputs[this._positiveInput] = { name: this._positiveInput, keyCode: "Digit" + jointIndex.toString(), isGlobal: false, modifiers: emptyModifierState };
InputSystem.allInputs[this._negativeInput] = { name: this._negativeInput, keyCode: "Digit" + jointIndex.toString(), isGlobal: false,
modifiers: { ctrl: false, alt: false, shift: true, meta: false } };
}

// Changes the elevators target position
moveElevator(positionDelta: number) {
this._sliderDriver.targetPosition += positionDelta;
}

public Update(deltaT: number): void {
this.moveElevator(InputSystem.GetAxis(this._positiveInput, this._negativeInput)*this._linearSpeed*deltaT);
}
}

export default GenericElevatorBehavior;
Loading
Loading