Skip to content
This repository has been archived by the owner on Aug 29, 2024. It is now read-only.

Commit

Permalink
Merge pull request #74 from topology-foundation/develop
Browse files Browse the repository at this point in the history
Merge develop
  • Loading branch information
d-roak authored Jul 8, 2024
2 parents 6a578f8 + 74dcc21 commit b597a3e
Show file tree
Hide file tree
Showing 30 changed files with 13,762 additions and 2,509 deletions.
15,280 changes: 12,888 additions & 2,392 deletions package-lock.json

Large diffs are not rendered by default.

16 changes: 11 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"format": "prettier --write ."
"dev": "vite dev",
"format": "prettier --write .",
"postinstall": "patch-package",
"prepare": "svelte-kit sync",
"preview": "vite preview"
},
"devDependencies": {
"@sveltejs/adapter-auto": "^3.0.0",
Expand All @@ -18,6 +20,7 @@
"@types/lodash-es": "^4.17.12",
"@types/three": "^0.159.0",
"autoprefixer": "^10.4.19",
"patch-package": "^8.0.0",
"postcss": "^8.4.39",
"prettier": "^3.3.2",
"prettier-plugin-svelte": "^3.2.5",
Expand All @@ -26,7 +29,8 @@
"tailwindcss": "^3.4.3",
"tslib": "^2.6.3",
"typescript": "^5.5.2",
"vite": "^5.3.2"
"vite": "^5.3.2",
"vite-plugin-node-polyfills": "^0.22.0"
},
"type": "module",
"dependencies": {
Expand All @@ -36,6 +40,7 @@
"@threlte/extras": "^8.11.4",
"@threlte/rapier": "^2.0.1",
"@threlte/theatre": "^2.1.7",
"@topology-foundation/node": "^0.0.20",
"@tweenjs/tween.js": "^23.1.2",
"bits-ui": "^0.21.11",
"clsx": "^2.1.1",
Expand All @@ -44,6 +49,7 @@
"lucide-svelte": "^0.397.0",
"svelte-tweakpane-ui": "^1.3.0",
"tailwind-merge": "^2.3.0",
"three": "^0.159.0"
"three": "^0.159.0",
"util": "^0.12.5"
}
}
14 changes: 11 additions & 3 deletions src/lib/components/App.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { onMount } from "svelte";
import { onMount, onDestroy } from "svelte";
import { Canvas } from "@threlte/core";
import { World } from "@threlte/rapier";
import Scene from "./Scene.svelte";
Expand All @@ -9,13 +9,20 @@
import Position from "./ui/position/position.svelte";
import { debugMode } from "$lib/store/player";
import Settings from "./ui/settings.svelte";
import { topologyInit } from "$lib/topology";
import Update from "../topology/Update.svelte";
import SprayWheel from "./ui/sprayWheel.svelte";
import { startSpraySubscription } from "../paint";
let keyboard: any;
let unsubscribe: () => void;
onMount(() => {
onMount(async () => {
unsubscribe = startSpraySubscription();
selectedKeyboard.subscribe((value) => {
keyboard = { value };
});
await topologyInit();
});
$: if (keyboard && keyboard.value) {
Expand All @@ -24,8 +31,9 @@
</script>

<div class="absolute">
<Ui />
<SprayWheel />
</div>
<Update />

<div>
<div class="absolute z-10 right-0 p-5 bg-white">
Expand Down
119 changes: 103 additions & 16 deletions src/lib/components/Player.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,44 @@
import type { RigidBody as RapierRigidBody } from "@dimforge/rapier3d-compat";
import { T, useTask, useThrelte } from "@threlte/core";
import { RigidBody, CollisionGroups, Collider } from "@threlte/rapier";
import { PerspectiveCamera, Vector3, Raycaster } from "three";
import {
PerspectiveCamera,
Vector3,
Vector2,
Raycaster,
CircleGeometry,
MeshBasicMaterial,
Mesh,
} from "three";
import PointerLockControls from "./PointerLockControls.svelte";
import { paintMode } from "$lib/store/player";
import { setPlayerPosition } from "$lib/store/player";
import {
setPlayerPosition,
playerPosition,
addSprayData,
selectedSpray,
} from "$lib/store/player";
import { tweened } from "svelte/motion";
import { cubicOut } from "svelte/easing";
import { onMount } from "svelte";
import { handlePainting } from "./player/paintLogic";
import { createEventHandlers } from "./player/eventHandler";
import { get } from "svelte/store";
import { width, height } from "$lib/store/wall";
export let position: [x: number, y: number, z: number] = [0, 0, 0];
let maxSprayDistance = 20;
let radius = 0.3;
let height = 1.7;
let h = 1.7;
export let speed = 6;
let jumpForce = 10;
let rigidBody: RapierRigidBody;
let lock: () => void;
let cam: PerspectiveCamera;
let dot: Mesh;
const t = new Vector3();
const { scene } = useThrelte();
const raycaster = new Raycaster();
Expand All @@ -33,6 +51,11 @@
let intervalId: any;
onMount(() => {
const dotGeometry = new CircleGeometry(0.01, 32);
const dotMaterial = new MeshBasicMaterial({ color: 0xffffff });
dot = new Mesh(dotGeometry, dotMaterial);
dot.position.set(0, 0, -0.5);
cam.add(dot);
intervalId = setInterval(handlePainting, 16);
return () => clearInterval(intervalId);
});
Expand All @@ -50,7 +73,13 @@
handleMovement(forward, backward, left, right, jump);
handleGrounding();
handleOutOfBounds();
setPlayerPosition(position);
const currentPlayerPosition = get(playerPosition);
setPlayerPosition(
new Vector3(...position),
cam.rotation.clone(),
currentPlayerPosition.state,
);
handleCursor();
});
function handleMovement(
Expand Down Expand Up @@ -78,7 +107,7 @@
raycaster.set(new Vector3(pos.x, pos.y, pos.z), new Vector3(0, -1, 0));
const intersects = raycaster.intersectObject(scene, true);
touchingGround =
intersects.length > 0 && intersects[0].distance < height / 2 + 0.5;
intersects.length > 0 && intersects[0].distance < h / 2 + 0.5;
}
function handleOutOfBounds() {
Expand All @@ -88,20 +117,78 @@
cam.rotation.set(0, 0, 0);
}
}
let lastSprayTime = 0;
function handleCursor() {
const now = Date.now();
if (now - lastSprayTime < 3000) {
if (dot.material instanceof MeshBasicMaterial) {
dot.material.color.set(0xffffff);
}
return;
}
raycaster.setFromCamera(new Vector2(0, 0), cam);
const wallIntersects = raycaster.intersectObjects(scene.children, true);
const intersectsWithSplashWall = wallIntersects.find(
(intersect) => intersect.object.name === "SplashWall",
);
if (intersectsWithSplashWall && dot.material instanceof MeshBasicMaterial) {
const distance = intersectsWithSplashWall.distance;
if (distance <= maxSprayDistance) {
dot.material.color.set(0xff0000);
} else {
dot.material.color.set(0xffffff);
}
}
}
// Paint mode handler
$: {
if ($paintMode && cam) {
let coord = cam.position;
const distanceFromWall = Math.abs(coord.z + 50);
zoomLevel.set(distanceFromWall / 10);
} else if (!$paintMode && cam) {
zoomLevel.set(1);
function handleSpray() {
const now = Date.now();
if (now - lastSprayTime < 3000) {
return;
}
lastSprayTime = now;
raycaster.setFromCamera(new Vector2(0, 0), cam);
const wallIntersects = raycaster.intersectObjects(scene.children, true);
const intersectsWithSplashWall = wallIntersects.find(
(intersect) => intersect.object.name === "SplashWall",
);
if (intersectsWithSplashWall && dot.material instanceof MeshBasicMaterial) {
const distance = intersectsWithSplashWall.distance;
if (distance <= maxSprayDistance) {
const uv = intersectsWithSplashWall.uv;
if (uv) {
const sprayData = {
id: $selectedSpray,
offset: { x: uv.x * width, y: uv.y * height },
timestamp: Math.floor(Date.now() / 1000),
};
addSprayData(sprayData);
}
}
}
}
// // Paint mode handler
// $: {
// if ($paintMode && cam) {
// let coord = cam.position;
// const distanceFromWall = Math.abs(coord.z + 50);
// zoomLevel.set(distanceFromWall / 10);
// } else if (!$paintMode && cam) {
// zoomLevel.set(1);
// }
// }
</script>

<svelte:window on:keydown|preventDefault={onKeyDown} on:keyup={onKeyUp} />
<svelte:window
on:keydown|preventDefault={onKeyDown}
on:keyup={onKeyUp}
on:click={handleSpray}
/>

<T.Group position.y={0.9}>
<T.PerspectiveCamera
Expand All @@ -128,14 +215,14 @@
<CollisionGroups groups={[0]}>
<Collider
shape={"capsule"}
args={[height / 2 - radius, radius]}
args={[h / 2 - radius, radius]}
friction={0}
restitution={0}
/>
</CollisionGroups>

<CollisionGroups groups={[15]}>
<T.Group position={[0, -height / 2 + radius, 0]}>
<T.Group position={[0, -h / 2 + radius, 0]}>
<Collider sensor shape={"ball"} args={[radius * 1.2]} restitution={0} />
</T.Group>
</CollisionGroups>
Expand Down
85 changes: 85 additions & 0 deletions src/lib/components/PlayersRendering.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<script lang="ts">
import { onMount, onDestroy } from "svelte";
import { T, useFrame } from "@threlte/core";
import { PlayerData, players } from "$lib/store/playersData";
import type { PlayerID } from "$lib/store/playersData";
import { addOrUpdatePlayer, removePlayer } from "$lib/store/playersManager";
import { initializePlayerData, startP2PUpdates } from "$lib/store/fakeP2P";
import { Vector3, Euler } from "three";
import Player from "./Player.svelte";
import { nodeId } from "$lib/topology";
let playerModels: Map<PlayerID, any> = new Map();
let playerArray: PlayerData[] = [];
function createPlayerModel() {
return {
position: new Vector3(),
rotation: new Euler(),
};
}
function updatePlayerState(
model: any,
state: "idle" | "running" | "walking" | "jumping",
): void {
// Do more stuff
}
function updatePlayerModel(player: PlayerData) {
// Find or create the 3D model for the player
let model = playerModels.get(player.id);
if (!model) {
model = createPlayerModel();
playerModels.set(player.id, model);
}
model.position.copy(player.position);
model.rotation.copy(player.rotation);
updatePlayerState(model, player.state);
}
function updatePlayerArray() {
playerArray = Array.from(players.values());
}
useFrame(() => {
players.forEach((player) => updatePlayerModel(player));
updatePlayerArray();
});
onMount(async () => {
// //Sets up the mock data of the users
// await initializePlayerData();
// startP2PUpdates((id, x, y, z, rotationX, rotationY, rotationZ, state) => {
// addOrUpdatePlayer(id, x, y, z, rotationX, rotationY, rotationZ, state);
// updatePlayerArray();
// }, 60); // 60Hz = 16.17
});
onDestroy(() => {
players.clear();
});
function stringToColor(str: string): number {
let hash = 0;
for (let i = 0; i < str.length; i++) {
hash = str.charCodeAt(i) + ((hash << 5) - hash);
}
let c = (hash & 0x00ffffff).toString(16).toUpperCase();
return parseInt("0x" + "00000".substring(0, 6 - c.length) + c);
}
</script>

{#if playerArray}
{#each playerArray as player (player.id)}
<T.Group
position={[player.position.x, player.position.y, player.position.z]}
>
<T.Mesh>
<T.SphereGeometry args={[0.5, 32, 32]} position={[0, 1, 0]} />
<T.MeshBasicMaterial color={stringToColor(nodeId)} />
</T.Mesh>
</T.Group>
{/each}
{/if}
Loading

0 comments on commit b597a3e

Please sign in to comment.