Skip to content

Commit

Permalink
Merge pull request #14 from Triadica/gamepad
Browse files Browse the repository at this point in the history
connecting to gamepad
  • Loading branch information
NoEgAm authored Feb 29, 2024
2 parents 5c90c89 + baa9c6c commit f645ae4
Show file tree
Hide file tree
Showing 8 changed files with 294 additions and 103 deletions.
25 changes: 25 additions & 0 deletions calcit.cirru

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions compact.cirru
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@
|tabs $ %{} :CodeEntry (:doc |)
:code $ quote
def tabs $ [] (:: :fireworks |Fireworks :dark) (:: :lorenz |Lorenz :dark) (:: :aizawa |Aizawa :dark) (:: :fourwing "|Four Wing" :dark) (:: :fractal |Fractal :dark) (:: :collision |Collision :dark) (:: :bounce |Bounce :dark) (:: :feday |FEDAY :dark) (:: :bifurcation "\"Bifurcation" :dark) (:: :ball-spin "\"Ball Spin" :dark) (:: :lifegame "\"Lifegame" :dark) (:: :lifegame-trail "\"Lifegame Trail" :dark) (:: :bounce-trail "|Bounce Trail" :dark) (:: :orbit-spark "|Orbit Spark" :dark) (:: :chen |Chen :dark) (:: :sprott |Sprott :dark) (:: :lorenz83 |Lorenz83 :dark)
|threshold $ %{} :CodeEntry (:doc |)
:code $ quote
def threshold $ js/parseFloat
or (get-env "\"threshold") "\"0.016"
|use-gamepad? $ %{} :CodeEntry (:doc |)
:code $ quote
def use-gamepad? $ get-env "\"gamepad"
:ns $ %{} :CodeEntry (:doc |)
:code $ quote
ns app.config $ :require
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
"devDependencies": {
"@webgpu/types": "^0.1.40",
"bottom-tip": "^0.1.5",
"query-string": "^8.1.0",
"query-string": "^9.0.0",
"typescript": "^5.3.3",
"vite": "^5.0.12"
"vite": "^5.1.4"
},
"dependencies": {
"@calcit/procs": "^0.8.19",
"@calcit/procs": "^0.8.37",
"@triadica/touch-control": "^0.0.4-a1",
"ismobilejs": "^1.1.1"
},
Expand Down
9 changes: 9 additions & 0 deletions src/config.mts
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
import isMobilejs from "ismobilejs";
import queryString from "query-string";

export let isMobile = isMobilejs(window.navigator).any; // TODO test

const parsed = queryString.parse(location.search);

export let useGamepad = parsed["gamepad"];

export let threshold = parseFloat((parsed["threshold"] as string) || "0.016");

export let useRemoveContrl = parsed["remote-control"];
40 changes: 40 additions & 0 deletions src/control.mts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { setupGamepadControl } from "./gamepad";
import {
moveViewerBy,
rotateGlanceBy,
spinGlanceBy,
changeScaleBy,
atomViewerScale,
} from "./perspective.mjs";
import { ControlStates } from "@triadica/touch-control";
import { threshold } from "./config.mjs";

/** 2D point */
export type V2 = [number, number];
Expand Down Expand Up @@ -60,3 +63,40 @@ export function registerShaderResult(
) {
window.__lagopusHandleCompilationInfo = f;
}

let someValue = (x: number) => {
return Math.abs(x) > threshold ? x : 0;
};

export let loadGamepadControl = () => {
console.log("loading gamepad control");
setupGamepadControl((axes, buttons) => {
let scale = atomViewerScale.deref();
let ss = 1 / scale;
// left/right, up/down, front/back
moveViewerBy(
someValue(axes.rightX) * 10 * ss,
-someValue(axes.rightY) * 10 * ss,
someValue(axes.leftY) * 10 * ss
);
rotateGlanceBy(
-0.1 * someValue(axes.leftX),
0.05 * (buttons.up.value - buttons.down.value)
);

spinGlanceBy(0.1 * (buttons.right.value - buttons.left.value));

if (buttons.l2.value > 0.5) {
changeScaleBy(0.01);
}
if (buttons.r2.value > 0.5) {
changeScaleBy(-0.01);
}

registerShaderResult((e, code) => {
if (e.messages.length) {
console.error(e);
}
});
});
};
106 changes: 106 additions & 0 deletions src/gamepad.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
let controllers: Record<number, Gamepad> = {};

let looper: any;

export type GameAxes = {
leftX: number;
leftY: number;
rightX: number;
rightY: number;
};

export type GameButtons = {
face1: GamepadButton;
face2: GamepadButton;
face3: GamepadButton;
face4: GamepadButton;
l1: GamepadButton;
r1: GamepadButton;
l2: GamepadButton;
r2: GamepadButton;
select: GamepadButton;
start: GamepadButton;
l3: GamepadButton;
r3: GamepadButton;
up: GamepadButton;
down: GamepadButton;
left: GamepadButton;
right: GamepadButton;
};

let handler = (axes: GameAxes, buttons: GameButtons) => {
console.log("default...");
};

export let setupGamepadControl = (
f: (axes: GameAxes, buttons: GameButtons) => void
) => {
handler = f;
window.addEventListener("gamepadconnected", connecthandler);
window.addEventListener("gamepaddisconnected", disconnecthandler);
};

let connecthandler = (e: GamepadEvent) => {
console.log("Gamepad", e);

controllers[e.gamepad.index] = e.gamepad;
gameLoop();
};

let disconnecthandler = (e: GamepadEvent) => {
delete controllers[e.gamepad.index];
cancelAnimationFrame(looper);
};

let gameLoop = () => {
const gamepads = navigator.getGamepads();
let gp = gamepads[0];
let [
face1,
face2,
face3,
face4,
l1,
r1,
l2,
r2,
select,
start,
l3,
r3,
up,
down,
left,
right,
] = gp.buttons;
let [leftX, leftY, rightX, rightY] = gp.axes;

handler(
{
leftX,
leftY,
rightX,
rightY,
},
{
// face1,
// face2,
// face3,
// face4,
l1,
r1,
l2,
r2,
// select,
// start,
// l3,
// r3,
up,
down,
left,
right,
} as GameButtons
);

looper = setTimeout(gameLoop, 10);
};
10 changes: 7 additions & 3 deletions src/setup.mts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {
resetCanvasSize,
setupRemoteControl,
} from "./index.mjs";
import { useGamepad, useRemoveContrl } from "./config.mjs";
import { loadGamepadControl } from "./control.mjs";

export async function setupInitials(canvas: HTMLCanvasElement) {
const adapter = await navigator.gpu.requestAdapter();
Expand All @@ -26,9 +28,11 @@ export async function setupInitials(canvas: HTMLCanvasElement) {
renderControl();
startControlLoop(10, onControlEvent);

const parsed = queryString.parse(location.search);

if (parsed["remote-control"]) {
if (useRemoveContrl) {
setupRemoteControl();
}

if (useGamepad) {
loadGamepadControl();
}
}
Loading

0 comments on commit f645ae4

Please sign in to comment.