small clean up

This commit is contained in:
Evert Prants 2022-04-10 11:33:52 +03:00
parent 37ac9143a2
commit b5d64b2aed
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
11 changed files with 96 additions and 1360 deletions

1292
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,8 @@
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1", "test": "echo \"Error: no test specified\" && exit 1",
"build:prod": "tsc && webpack --mode=production", "build:prod": "NODE_ENV=production tsc && webpack --mode=production",
"server": "NODE_ENV=production node dist/server/",
"watch": "concurrently \"tsc -w\" \"nodemon dist/server/\" \"webpack --mode=development -w\"" "watch": "concurrently \"tsc -w\" \"nodemon dist/server/\" \"webpack --mode=development -w\""
}, },
"keywords": [], "keywords": [],
@ -15,7 +16,6 @@
"connect-redis": "^6.1.3", "connect-redis": "^6.1.3",
"express": "^4.17.3", "express": "^4.17.3",
"express-session": "^1.17.2", "express-session": "^1.17.2",
"jimp": "^0.16.1",
"passport": "^0.5.2", "passport": "^0.5.2",
"passport-icynet": "^0.0.2", "passport-icynet": "^0.0.2",
"redis": "^3.1.2", "redis": "^3.1.2",

View File

@ -25,7 +25,7 @@ export class Game {
public renderer = new Renderer(); public renderer = new Renderer();
private videoTest = new VideoPlayer(); private videoTest = new VideoPlayer(24, 12);
constructor(public socket: Socket) {} constructor(public socket: Socket) {}
@ -56,7 +56,7 @@ export class Game {
this.socket.emit('chat-send', message); this.socket.emit('chat-send', message);
}); });
this.renderer.registerRenderFunction((dt: number) => { this.renderer.registerUpdateFunction((dt: number) => {
this.update(dt); this.update(dt);
}); });
} }

View File

@ -56,6 +56,9 @@ export class ThirdPersonCamera {
this.panning = false; this.panning = false;
} }
}, },
mouseleave: (e: MouseEvent) => {
this.panning = false;
},
mousemove: (e: MouseEvent) => this.dragEvent(e.clientX, e.clientY), mousemove: (e: MouseEvent) => this.dragEvent(e.clientX, e.clientY),
wheel: (e: WheelEvent) => { wheel: (e: WheelEvent) => {
e.deltaY < 0 ? (this.distance /= 1.2) : (this.distance *= 1.2); e.deltaY < 0 ? (this.distance /= 1.2) : (this.distance *= 1.2);

View File

@ -17,6 +17,8 @@ export class VideoPlayer {
public playable: boolean; public playable: boolean;
public geometry!: PlaneGeometry; public geometry!: PlaneGeometry;
constructor(public width: number, public height: number) {}
initialize() { initialize() {
this.texture = new VideoTexture(this.video); this.texture = new VideoTexture(this.video);
this.material = new MeshBasicMaterial({ this.material = new MeshBasicMaterial({
@ -24,8 +26,9 @@ export class VideoPlayer {
side: FrontSide, side: FrontSide,
toneMapped: false, toneMapped: false,
}); });
this.geometry = new PlaneGeometry(24, 12); this.geometry = new PlaneGeometry(this.width, this.height);
this.mesh = new Mesh(this.geometry, this.material); this.mesh = new Mesh(this.geometry, this.material);
this.video.addEventListener('canplay', () => { this.video.addEventListener('canplay', () => {
this.playable = true; this.playable = true;
}); });
@ -40,6 +43,7 @@ export class VideoPlayer {
} }
public setSource(source: string, autoplay = false) { public setSource(source: string, autoplay = false) {
this.video.pause();
if (this.hls) { if (this.hls) {
this.hls.stopLoad(); this.hls.stopLoad();
this.hls.destroy(); this.hls.destroy();
@ -64,6 +68,8 @@ export class VideoPlayer {
this.hls.on(Hls.Events.ERROR, (e, d) => { this.hls.on(Hls.Events.ERROR, (e, d) => {
if (d.fatal) { if (d.fatal) {
this.playable = false; this.playable = false;
this.video.pause();
this.hls.stopLoad();
} }
}); });
return; return;

View File

@ -1,13 +1,12 @@
import { IcyNetUser } from '../../common/types/user'; import { IcyNetUser } from '../../common/types/user';
import * as THREE from 'three';
import { PonyEntity } from './pony'; import { PonyEntity } from './pony';
import { import {
CharacterPacket,
FullStatePacket, FullStatePacket,
PositionUpdatePacket, PositionUpdatePacket,
} from '../../common/types/packet'; } from '../../common/types/packet';
import { CanvasUtils } from './canvas-utils'; import { CanvasUtils } from './canvas-utils';
import { ChatBubble } from './chat-bubble'; import { ChatBubble } from './chat-bubble';
import { Vector3, Scene, Euler } from 'three';
const chatBuilder = new CanvasUtils({ const chatBuilder = new CanvasUtils({
rounded: true, rounded: true,
@ -20,19 +19,19 @@ export class PlayerEntity extends PonyEntity {
private _lastFrame: any = null; private _lastFrame: any = null;
private _chats: ChatBubble[] = []; private _chats: ChatBubble[] = [];
private _p1 = new THREE.Vector3(); private _p1 = new Vector3();
private _p2 = new THREE.Vector3(); private _p2 = new Vector3();
private _q1 = new THREE.Vector3(); private _q1 = new Vector3();
private _q2 = new THREE.Vector3(); private _q2 = new Vector3();
private _pf = new THREE.Vector3(); private _pf = new Vector3();
private _qf = new THREE.Vector3(); private _qf = new Vector3();
constructor(public user: IcyNetUser) { constructor(public user: IcyNetUser) {
super(); super();
} }
public static fromUser(user: IcyNetUser, scene: THREE.Scene): PlayerEntity { public static fromUser(user: IcyNetUser, scene: Scene): PlayerEntity {
const entity = new PlayerEntity(user); const entity = new PlayerEntity(user);
entity.initialize(); entity.initialize();
entity.addNameTag(user.display_name); entity.addNameTag(user.display_name);
@ -40,15 +39,15 @@ export class PlayerEntity extends PonyEntity {
return entity; return entity;
} }
public setVelocity(velocity: THREE.Vector3) { public setVelocity(velocity: Vector3) {
this.velocity.copy(velocity); this.velocity.copy(velocity);
} }
public setAngularVelocity(velocity: THREE.Vector3) { public setAngularVelocity(velocity: Vector3) {
this.angularVelocity.copy(velocity); this.angularVelocity.copy(velocity);
} }
public setPosition(pos: THREE.Vector3) { public setPosition(pos: Vector3) {
this.container.position.copy(pos); this.container.position.copy(pos);
} }
@ -69,7 +68,7 @@ export class PlayerEntity extends PonyEntity {
this._chats.forEach((item) => { this._chats.forEach((item) => {
const scaled = item.tag.scale.y; const scaled = item.tag.scale.y;
item.tag.position.add(new THREE.Vector3(0, scaled, 0)); item.tag.position.add(new Vector3(0, scaled, 0));
}); });
this._chats.unshift(newChat); this._chats.unshift(newChat);
@ -94,11 +93,9 @@ export class PlayerEntity extends PonyEntity {
}, 5000); }, 5000);
} }
public setRotation(rot: THREE.Vector3 | THREE.Euler) { public setRotation(rot: Vector3 | Euler) {
this.container.rotation.copy( this.container.rotation.copy(
rot instanceof THREE.Euler rot instanceof Euler ? rot : new Euler(rot.x, rot.y, rot.z, 'XYZ'),
? rot
: new THREE.Euler(rot.x, rot.y, rot.z, 'XYZ'),
); );
} }
@ -123,22 +120,22 @@ export class PlayerEntity extends PonyEntity {
private setFromPacket(packet: FullStatePacket | PositionUpdatePacket) { private setFromPacket(packet: FullStatePacket | PositionUpdatePacket) {
if ((packet as FullStatePacket).velocity) { if ((packet as FullStatePacket).velocity) {
this.setVelocity( this.setVelocity(
new THREE.Vector3().fromArray((packet as FullStatePacket).velocity), new Vector3().fromArray((packet as FullStatePacket).velocity),
); );
} }
if ((packet as FullStatePacket).angular) { if ((packet as FullStatePacket).angular) {
this.setAngularVelocity( this.setAngularVelocity(
new THREE.Vector3().fromArray((packet as FullStatePacket).angular), new Vector3().fromArray((packet as FullStatePacket).angular),
); );
} }
if (packet.position) { if (packet.position) {
this.setPosition(new THREE.Vector3().fromArray(packet.position)); this.setPosition(new Vector3().fromArray(packet.position));
} }
if (packet.rotation) { if (packet.rotation) {
this.setRotation(new THREE.Euler().fromArray(packet.rotation)); this.setRotation(new Euler().fromArray(packet.rotation));
} }
if (packet.animState) { if (packet.animState) {

View File

@ -1,8 +1,7 @@
import * as THREE from 'three';
import { IcyNetUser } from '../../common/types/user'; import { IcyNetUser } from '../../common/types/user';
import { Socket } from 'socket.io-client'; import { Socket } from 'socket.io-client';
import { PonyEntity } from './pony'; import { PonyEntity } from './pony';
import { Vector2 } from 'three'; import { Scene, Vector2, Vector3 } from 'three';
export class Player extends PonyEntity { export class Player extends PonyEntity {
public keydownMap: { [x: string]: boolean } = {}; public keydownMap: { [x: string]: boolean } = {};
@ -11,18 +10,18 @@ export class Player extends PonyEntity {
/** /**
* Normal vector of the currently faced direction * Normal vector of the currently faced direction
*/ */
private _lookVector = new THREE.Vector3(); private _lookVector = new Vector3();
/** /**
* Direction of the current movement. * Direction of the current movement.
* X axis controls angular velocity, Y axis controls linear velocity direction by world coordinates. * X axis controls angular velocity, Y axis controls linear velocity direction by world coordinates.
*/ */
private _direction = new THREE.Vector2(); private _direction = new Vector2();
/** /**
* Joystick or other external movement usage. * Joystick or other external movement usage.
*/ */
private _externalDirection = new THREE.Vector2(); private _externalDirection = new Vector2();
/** /**
* Was external movement used this tick * Was external movement used this tick
@ -43,7 +42,7 @@ export class Player extends PonyEntity {
super(); super();
} }
public static fromUser(user: IcyNetUser, scene: THREE.Scene): Player { public static fromUser(user: IcyNetUser, scene: Scene): Player {
const entity = new Player(user); const entity = new Player(user);
entity.initialize(); entity.initialize();
scene.add(entity.container); scene.add(entity.container);
@ -75,7 +74,7 @@ export class Player extends PonyEntity {
} }
public moveCharacter(dt: number) { public moveCharacter(dt: number) {
const vector = new THREE.Vector2(); const vector = new Vector2();
const wasExternalForce = this._externalForce; const wasExternalForce = this._externalForce;
this._externalForce = false; this._externalForce = false;

View File

@ -1,6 +1,5 @@
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'; import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';
import { Color, Mesh, MeshStandardMaterial } from 'three';
// Instantiate a loader // Instantiate a loader
const loader = new GLTFLoader(); const loader = new GLTFLoader();
@ -27,11 +26,6 @@ class PonyModel {
// temp: disable frustum culling for eyes // temp: disable frustum culling for eyes
this.ponyModel.children[0].children[2].frustumCulled = false; this.ponyModel.children[0].children[2].frustumCulled = false;
// (
// (this.ponyModel.children[0].children[1] as Mesh)
// .material as MeshStandardMaterial
// ).color = new Color(0xffffff);
resolve(gltf.scene); resolve(gltf.scene);
// gltf.animations; // Array<THREE.AnimationClip> // gltf.animations; // Array<THREE.AnimationClip>

View File

@ -1,10 +1,17 @@
import * as SkeletonUtils from 'three/examples/jsm/utils/SkeletonUtils'; import * as SkeletonUtils from 'three/examples/jsm/utils/SkeletonUtils';
import * as THREE from 'three';
import modelLoaderInstance from './pony-loader'; import modelLoaderInstance from './pony-loader';
import { CharacterPacket, FullStatePacket } from '../../common/types/packet'; import { CharacterPacket, FullStatePacket } from '../../common/types/packet';
import { NameTag } from './nametag'; import { NameTag } from './nametag';
import { CanvasUtils } from './canvas-utils'; import { CanvasUtils } from './canvas-utils';
import { Mesh, MeshStandardMaterial, Color } from 'three'; import {
Mesh,
MeshStandardMaterial,
Color,
AnimationAction,
AnimationMixer,
Object3D,
Vector3,
} from 'three';
const nameTagBuilder = new CanvasUtils({ const nameTagBuilder = new CanvasUtils({
fill: false, fill: false,
@ -15,15 +22,15 @@ const nameTagBuilder = new CanvasUtils({
}); });
export class PonyEntity { export class PonyEntity {
public velocity = new THREE.Vector3(0, 0, 0); public velocity = new Vector3(0, 0, 0);
public angularVelocity = new THREE.Vector3(0, 0, 0); public angularVelocity = new Vector3(0, 0, 0);
public mixer!: THREE.AnimationMixer; public mixer!: AnimationMixer;
public container!: THREE.Object3D; public container!: Object3D;
public model!: THREE.Object3D; public model!: Object3D;
public material!: THREE.MeshStandardMaterial; public material!: MeshStandardMaterial;
public walkAnimationState = 0; public walkAnimationState = 0;
public idleAction: THREE.AnimationAction; public idleAction: AnimationAction;
public walkAction: THREE.AnimationAction; public walkAction: AnimationAction;
public nameTag?: NameTag; public nameTag?: NameTag;
public changes: FullStatePacket = {}; public changes: FullStatePacket = {};
@ -34,18 +41,18 @@ export class PonyEntity {
.material as MeshStandardMaterial .material as MeshStandardMaterial
).clone(); ).clone();
(this.model.children[0].children[1] as Mesh).material = this.material; (this.model.children[0].children[1] as Mesh).material = this.material;
this.mixer = new THREE.AnimationMixer(this.model); this.mixer = new AnimationMixer(this.model);
this.idleAction = this.mixer.clipAction(modelLoaderInstance.animations[0]); this.idleAction = this.mixer.clipAction(modelLoaderInstance.animations[0]);
this.walkAction = this.mixer.clipAction(modelLoaderInstance.animations[2]); this.walkAction = this.mixer.clipAction(modelLoaderInstance.animations[2]);
this.idleAction.play(); this.idleAction.play();
this.container = new THREE.Object3D(); this.container = new Object3D();
this.container.add(this.model); this.container.add(this.model);
} }
update(dt: number) { update(dt: number) {
this.container.position.add(this.velocity.clone().multiplyScalar(dt)); this.container.position.add(this.velocity.clone().multiplyScalar(dt));
this.container.rotation.setFromVector3( this.container.rotation.setFromVector3(
new THREE.Vector3( new Vector3(
this.container.rotation.x, this.container.rotation.x,
this.container.rotation.y, this.container.rotation.y,
this.container.rotation.z, this.container.rotation.z,

View File

@ -1,17 +1,27 @@
import * as THREE from 'three'; import {
Scene,
PerspectiveCamera,
WebGLRenderer,
DirectionalLight,
AmbientLight,
Mesh,
Clock,
BoxGeometry,
MeshToonMaterial,
} from 'three';
export class Renderer { export class Renderer {
public scene!: THREE.Scene; public scene!: Scene;
public camera!: THREE.PerspectiveCamera; public camera!: PerspectiveCamera;
public renderer!: THREE.WebGLRenderer; public renderer!: WebGLRenderer;
public sun!: THREE.DirectionalLight; public sun!: DirectionalLight;
public ambient!: THREE.AmbientLight; public ambient!: AmbientLight;
public ground!: THREE.Mesh; public ground!: Mesh;
private clock = new THREE.Clock(); private clock = new Clock();
private _renderFn?: (dt: number) => void; private _updateFn?: (dt: number) => void;
constructor() {} constructor() {}
@ -20,30 +30,30 @@ export class Renderer {
} }
initialize() { initialize() {
this.scene = new THREE.Scene(); this.scene = new Scene();
this.camera = new THREE.PerspectiveCamera( this.camera = new PerspectiveCamera(
75, 75,
window.innerWidth / window.innerHeight, window.innerWidth / window.innerHeight,
0.1, 0.1,
1000, 1000,
); );
this.renderer = new THREE.WebGLRenderer(); this.renderer = new WebGLRenderer();
this.renderer.setSize(window.innerWidth, window.innerHeight); this.renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(this.renderer.domElement); document.body.appendChild(this.renderer.domElement);
this.renderer.setClearColor(0x00ddff); this.renderer.setClearColor(0x00ddff);
this.sun = new THREE.DirectionalLight(0xffffff); this.sun = new DirectionalLight(0xffffff);
this.sun.position.set(10, 10, 0); this.sun.position.set(10, 10, 0);
this.scene.add(this.sun); this.scene.add(this.sun);
this.ambient = new THREE.AmbientLight(0xffffff, 0.5); this.ambient = new AmbientLight(0xffffff, 0.5);
this.scene.add(this.ambient); this.scene.add(this.ambient);
this.ground = new THREE.Mesh( this.ground = new Mesh(
new THREE.BoxGeometry(100, 1, 100, 10, 1, 10), new BoxGeometry(100, 1, 100, 10, 1, 10),
new THREE.MeshToonMaterial({ color: 0x32a852 }), new MeshToonMaterial({ color: 0x32a852 }),
); );
this.ground.position.set(0, -0.5, 0); this.ground.position.set(0, -0.5, 0);
@ -64,14 +74,14 @@ export class Renderer {
requestAnimationFrame(() => this.render()); requestAnimationFrame(() => this.render());
const delta = this.clock.getDelta(); const delta = this.clock.getDelta();
if (this._renderFn) { if (this._updateFn) {
this._renderFn(delta); this._updateFn(delta);
} }
this.renderer.render(this.scene, this.camera); this.renderer.render(this.scene, this.camera);
} }
public registerRenderFunction(fn: (dt: number) => void) { public registerUpdateFunction(fn: (dt: number) => void) {
this._renderFn = fn; this._updateFn = fn;
} }
} }

View File

@ -32,5 +32,5 @@ module.exports = {
path: path.resolve(__dirname, 'dist', 'public'), path: path.resolve(__dirname, 'dist', 'public'),
filename: 'bundle.js', filename: 'bundle.js',
}, },
devtool: 'source-map' devtool: process.env.NODE_ENV !== 'production' ? 'source-map' : undefined,
}; };