tweaks
This commit is contained in:
parent
77149c180b
commit
2f48411212
|
@ -122,17 +122,23 @@ export class GameplayComponent extends EngineComponent {
|
|||
}
|
||||
};
|
||||
|
||||
const initializedEvent = () => {
|
||||
const worldLoadedEvent = () => {
|
||||
this.loadCharacter('Diamond');
|
||||
};
|
||||
|
||||
const physicsLoadedEvent = () => {
|
||||
this.events.emit('initialized');
|
||||
};
|
||||
|
||||
window.addEventListener('keydown', keyDownEvent);
|
||||
window.addEventListener('keyup', keyUpEvent);
|
||||
this.events.addListener('initialized', initializedEvent);
|
||||
this.events.addListener('loadComplete', worldLoadedEvent);
|
||||
this.events.addListener('physicsComplete', physicsLoadedEvent);
|
||||
return () => {
|
||||
window.removeEventListener('keydown', keyDownEvent);
|
||||
window.removeEventListener('keyup', keyUpEvent);
|
||||
this.events.removeEventListener('initialized', initializedEvent);
|
||||
this.events.removeEventListener('loadComplete', worldLoadedEvent);
|
||||
this.events.removeEventListener('physicsComplete', physicsLoadedEvent);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import { EngineComponent } from '../types/engine-component';
|
|||
import { Renderer } from '../core/renderer';
|
||||
import { EventEmitter } from '../utils/events';
|
||||
import { Environment } from '../gameobjects/environment.object';
|
||||
import { environmentDefaults } from '..';
|
||||
|
||||
/**
|
||||
* This component manages game environment and world lighting.
|
||||
|
@ -25,11 +26,17 @@ export class EnvironmentComponent extends EngineComponent {
|
|||
|
||||
initialize(): void {
|
||||
this.renderer.scene.add(this.object);
|
||||
this.renderer.renderer.setClearColor(0x00aaff);
|
||||
this.renderer.renderer.setClearColor(environmentDefaults.clearColor);
|
||||
|
||||
this.ambient = new AmbientLight(0x8a8a8a, 1.0);
|
||||
this.directional = new DirectionalLight(0xffffff, 1);
|
||||
this.directional.position.set(1, 1, 1);
|
||||
this.ambient = new AmbientLight(
|
||||
environmentDefaults.ambientColor,
|
||||
environmentDefaults.ambientStrength
|
||||
);
|
||||
this.directional = new DirectionalLight(
|
||||
environmentDefaults.sunColor,
|
||||
environmentDefaults.sunStrength
|
||||
);
|
||||
this.directional.position.copy(environmentDefaults.sunPosition);
|
||||
|
||||
this.renderer.scene.add(this.ambient);
|
||||
this.renderer.scene.add(this.directional);
|
||||
|
|
|
@ -105,6 +105,7 @@ export class LevelComponent extends EngineComponent {
|
|||
|
||||
// Load world
|
||||
this.deserializeObject(save.world);
|
||||
this.world.deserialize(save.world);
|
||||
this.events.emit('loadComplete');
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ export class PhysicsWorldComponent extends EngineComponent {
|
|||
private physicsWorld!: Rapier.World;
|
||||
private physicsEngine!: typeof Rapier;
|
||||
private characterPhysics!: Rapier.KinematicCharacterController;
|
||||
private initEventFiredBeforeEngineLoad = false;
|
||||
private cleanUpEvents?: Function;
|
||||
private sceneInitialized = false;
|
||||
private trackedObjects: PhysicsTicking[] = [];
|
||||
|
@ -21,7 +20,6 @@ export class PhysicsWorldComponent extends EngineComponent {
|
|||
initialize(): void {
|
||||
this.world = this.renderer.scene.getObjectByName('World') as World;
|
||||
this.cleanUpEvents = this.bindEvents();
|
||||
this.createRapier();
|
||||
}
|
||||
|
||||
update(delta: number): void {
|
||||
|
@ -43,21 +41,13 @@ export class PhysicsWorldComponent extends EngineComponent {
|
|||
const world = new physicsEngine.World(gravity);
|
||||
this.physicsWorld = world;
|
||||
this.physicsEngine = physicsEngine;
|
||||
|
||||
if (this.initEventFiredBeforeEngineLoad) {
|
||||
this.initEventFiredBeforeEngineLoad = false;
|
||||
this.initializePhysicsScene();
|
||||
}
|
||||
this.initializePhysicsScene();
|
||||
});
|
||||
}
|
||||
|
||||
private bindEvents() {
|
||||
const initializeEvent = () => {
|
||||
if (!this.physicsWorld) {
|
||||
this.initEventFiredBeforeEngineLoad = true;
|
||||
return;
|
||||
}
|
||||
this.initializePhysicsScene();
|
||||
const worldLoadEvent = () => {
|
||||
this.createRapier();
|
||||
};
|
||||
|
||||
const sceneJoinEvent = (object: Object3D) => {
|
||||
|
@ -68,18 +58,19 @@ export class PhysicsWorldComponent extends EngineComponent {
|
|||
this.removePhysics(object);
|
||||
};
|
||||
|
||||
this.events.addListener('initialized', initializeEvent);
|
||||
this.events.addListener('loadComplete', worldLoadEvent);
|
||||
this.events.addListener('sceneJoin', sceneJoinEvent);
|
||||
this.events.addListener('sceneLeave', sceneLeaveEvent);
|
||||
|
||||
return () => {
|
||||
this.events.removeEventListener('initialized', initializeEvent);
|
||||
this.events.removeEventListener('loadComplete', worldLoadEvent);
|
||||
this.events.removeEventListener('sceneJoin', sceneJoinEvent);
|
||||
this.events.removeEventListener('sceneLeave', sceneLeaveEvent);
|
||||
};
|
||||
}
|
||||
|
||||
private applyPhysics(root: Object3D) {
|
||||
if (!this.physicsEngine) return;
|
||||
root.traverse((object) => {
|
||||
// Prevent double-init
|
||||
if (this.trackedObjects.some((entry) => entry.uuid === object.uuid))
|
||||
|
@ -139,5 +130,6 @@ export class PhysicsWorldComponent extends EngineComponent {
|
|||
this.applyPhysics(this.world);
|
||||
|
||||
this.sceneInitialized = true;
|
||||
this.events.emit('physicsComplete');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,5 +6,5 @@ export const environmentDefaults = {
|
|||
sunStrength: 1,
|
||||
ambientColor: new Color(0x8a8a8a),
|
||||
ambientStrength: 1,
|
||||
clearColor: new Color(0x00aaff),
|
||||
clearColor: new Color(0x47c2ff),
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { PhysicsObject } from './physics.object';
|
||||
import { gameObjectGeometries } from './geometries';
|
||||
import { BufferGeometry, Mesh, MeshPhongMaterial } from 'three';
|
||||
import { BufferGeometry, Mesh, MeshPhongMaterial, Vector3 } from 'three';
|
||||
import type Rapier from '@dimforge/rapier3d';
|
||||
|
||||
export class Brick extends PhysicsObject {
|
||||
|
@ -20,7 +20,7 @@ export class Brick extends PhysicsObject {
|
|||
world: Rapier.World,
|
||||
body?: Rapier.RigidBody
|
||||
) {
|
||||
const scale = this.scale.clone().divideScalar(2);
|
||||
const scale = this.getWorldScale(new Vector3()).divideScalar(2);
|
||||
const collider = factory.ColliderDesc.cuboid(
|
||||
Math.abs(scale.x),
|
||||
Math.abs(scale.y),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Mesh } from 'three';
|
||||
import { Mesh, Vector3 } from 'three';
|
||||
import { Brick } from './brick.object';
|
||||
import { gameObjectGeometries } from './geometries';
|
||||
import type Rapier from '@dimforge/rapier3d';
|
||||
|
@ -17,12 +17,10 @@ export class Capsule extends Brick {
|
|||
world: Rapier.World,
|
||||
body?: Rapier.RigidBody
|
||||
) {
|
||||
const height = this.scale.y / 2;
|
||||
const radius = (this.scale.x / 2 + this.scale.z / 2) / 2;
|
||||
const collider = factory.ColliderDesc.capsule(
|
||||
Math.abs(height),
|
||||
Math.abs(radius)
|
||||
);
|
||||
const scale = this.getWorldScale(new Vector3());
|
||||
const height = Math.abs(scale.y) / 2;
|
||||
const radius = (Math.abs(scale.x) + Math.abs(scale.z)) / 2;
|
||||
const collider = factory.ColliderDesc.capsule(height, radius);
|
||||
return world.createCollider(collider, body);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Mesh } from 'three';
|
||||
import { Mesh, Vector3 } from 'three';
|
||||
import { Brick } from './brick.object';
|
||||
import { gameObjectGeometries } from './geometries';
|
||||
import type Rapier from '@dimforge/rapier3d';
|
||||
|
@ -17,12 +17,10 @@ export class Cylinder extends Brick {
|
|||
world: Rapier.World,
|
||||
body?: Rapier.RigidBody
|
||||
) {
|
||||
const height = this.scale.y / 2;
|
||||
const radius = (this.scale.x / 2 + this.scale.z / 2) / 2;
|
||||
const collider = factory.ColliderDesc.cylinder(
|
||||
Math.abs(height),
|
||||
Math.abs(radius)
|
||||
);
|
||||
const scale = this.getWorldScale(new Vector3());
|
||||
const height = Math.abs(scale.y) / 2;
|
||||
const radius = (Math.abs(scale.x) / 2 + Math.abs(scale.z) / 2) / 2;
|
||||
const collider = factory.ColliderDesc.cylinder(height, radius);
|
||||
return world.createCollider(collider, body);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -320,7 +320,7 @@ export class Humanoid extends GameObject implements PhysicsTicking {
|
|||
}
|
||||
|
||||
private applyRotation(quat: Quaternion) {
|
||||
this.rigidBody?.setNextKinematicRotation(quat);
|
||||
this.rigidBody?.setRotation(quat, false);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
import { BufferGeometry, Mesh, MeshPhongMaterial, SkinnedMesh } from 'three';
|
||||
import {
|
||||
BufferGeometry,
|
||||
Mesh,
|
||||
MeshPhongMaterial,
|
||||
SkinnedMesh,
|
||||
Vector3,
|
||||
} from 'three';
|
||||
import { Brick } from '.';
|
||||
import type Rapier from '@dimforge/rapier3d';
|
||||
|
||||
|
@ -26,7 +32,7 @@ export class MeshPart extends Brick {
|
|||
world: Rapier.World,
|
||||
body?: Rapier.RigidBody
|
||||
) {
|
||||
const scale = this.scale.clone().divideScalar(2);
|
||||
const scale = this.getWorldScale(new Vector3()).divideScalar(2);
|
||||
const collider = factory.ColliderDesc.cuboid(
|
||||
Math.abs(scale.x),
|
||||
Math.abs(scale.y),
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { EditorProperty } from '..';
|
||||
import { EditorProperty, GameObject } from '..';
|
||||
import { PhysicsTicking } from '../physics/ticking';
|
||||
import type Rapier from '@dimforge/rapier3d';
|
||||
import { PhysicalObject } from './physical.object';
|
||||
import { Quaternion, Vector3 } from 'three';
|
||||
|
||||
export class PhysicsObject extends PhysicalObject implements PhysicsTicking {
|
||||
public objectType = 'PhysicsObject';
|
||||
|
@ -23,6 +24,10 @@ export class PhysicsObject extends PhysicalObject implements PhysicsTicking {
|
|||
@EditorProperty({ type: Number })
|
||||
public friction = 0.2;
|
||||
|
||||
private _tempVec = new Vector3();
|
||||
private _tempQuat = new Quaternion();
|
||||
private _tempQuat2 = new Quaternion();
|
||||
|
||||
initialize(physicsEngine: typeof Rapier, physicsWorld: Rapier.World): void {
|
||||
if (this.virtual) return;
|
||||
this.physicsWorldRef = physicsWorld;
|
||||
|
@ -35,9 +40,14 @@ export class PhysicsObject extends PhysicalObject implements PhysicsTicking {
|
|||
if (this.anchored) bodyDesc = physicsEngine.RigidBodyDesc.fixed();
|
||||
else bodyDesc = physicsEngine.RigidBodyDesc.dynamic();
|
||||
|
||||
const position = this.position.clone();
|
||||
const rotation = this.quaternion.clone();
|
||||
this.getWorldPosition(position);
|
||||
this.getWorldQuaternion(rotation);
|
||||
|
||||
bodyDesc
|
||||
.setTranslation(...this.position.toArray())
|
||||
.setRotation(this.quaternion)
|
||||
.setTranslation(...position.toArray())
|
||||
.setRotation(rotation)
|
||||
.setAdditionalMass(this.mass)
|
||||
.setLinearDamping(this.friction)
|
||||
.setAngularDamping(this.friction);
|
||||
|
@ -55,8 +65,16 @@ export class PhysicsObject extends PhysicalObject implements PhysicsTicking {
|
|||
|
||||
tick(dt: number): void {
|
||||
if (!this.rigidBody || this.virtual) return;
|
||||
this.position.copy(this.rigidBody.translation() as any);
|
||||
this.quaternion.copy(this.rigidBody.rotation() as any);
|
||||
this._tempVec.copy(this.rigidBody.translation() as any);
|
||||
this._tempQuat.copy(this.rigidBody.rotation() as any);
|
||||
if ((this.parent as GameObject)?.objectType !== 'World') {
|
||||
this.parent?.worldToLocal(this._tempVec);
|
||||
this.parent?.getWorldQuaternion(this._tempQuat2);
|
||||
this._tempQuat2.invert();
|
||||
this._tempQuat.premultiply(this._tempQuat2);
|
||||
}
|
||||
this.position.copy(this._tempVec);
|
||||
this.quaternion.copy(this._tempQuat);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Mesh } from 'three';
|
||||
import { Mesh, Vector3 } from 'three';
|
||||
import { Brick } from './brick.object';
|
||||
import { gameObjectGeometries } from './geometries';
|
||||
import type Rapier from '@dimforge/rapier3d';
|
||||
|
@ -17,8 +17,10 @@ export class Sphere extends Brick {
|
|||
world: Rapier.World,
|
||||
body?: Rapier.RigidBody
|
||||
) {
|
||||
const radius = Math.max(this.scale.x, this.scale.y, this.scale.z) / 2;
|
||||
const collider = factory.ColliderDesc.ball(Math.abs(radius));
|
||||
const scale = this.getWorldScale(new Vector3());
|
||||
const radius =
|
||||
Math.max(Math.abs(scale.x), Math.abs(scale.y), Math.abs(scale.z)) / 2;
|
||||
const collider = factory.ColliderDesc.ball(radius);
|
||||
return world.createCollider(collider, body);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,11 +17,12 @@ export class Torus extends Brick {
|
|||
world: Rapier.World,
|
||||
body?: Rapier.RigidBody
|
||||
) {
|
||||
const height = this.scale.y * 0.4;
|
||||
const radius = (this.scale.x + this.scale.z) / 2;
|
||||
const scale = this.getWorldScale(new Vector3());
|
||||
const height = Math.abs(scale.y) * 0.4;
|
||||
const radius = (Math.abs(scale.x) + Math.abs(scale.z)) / 2;
|
||||
const collider = factory.ColliderDesc.cylinder(
|
||||
Math.abs(height),
|
||||
Math.abs(radius) * 1.4
|
||||
height,
|
||||
radius * 1.4
|
||||
).setRotation(
|
||||
new Quaternion().setFromAxisAngle(new Vector3(1, 0, 0), Math.PI / 2)
|
||||
);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Matrix4, Mesh } from 'three';
|
||||
import { Matrix4, Mesh, Vector3 } from 'three';
|
||||
import { Brick } from './brick.object';
|
||||
import { gameObjectGeometries } from './geometries';
|
||||
import type Rapier from '@dimforge/rapier3d';
|
||||
|
@ -17,8 +17,9 @@ export class WedgeCorner extends Brick {
|
|||
world: Rapier.World,
|
||||
body?: Rapier.RigidBody
|
||||
) {
|
||||
const scale = this.getWorldScale(new Vector3());
|
||||
const mat = new Matrix4();
|
||||
mat.makeScale(...this.scale.toArray());
|
||||
mat.makeScale(...scale.toArray());
|
||||
const points = this.getGeometry()
|
||||
.getAttribute('position')
|
||||
.clone()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Matrix4, Mesh } from 'three';
|
||||
import { Matrix4, Mesh, Vector3 } from 'three';
|
||||
import { Brick } from './brick.object';
|
||||
import { gameObjectGeometries } from './geometries';
|
||||
import type Rapier from '@dimforge/rapier3d';
|
||||
|
@ -17,8 +17,9 @@ export class WedgeInnerCorner extends Brick {
|
|||
world: Rapier.World,
|
||||
body?: Rapier.RigidBody
|
||||
) {
|
||||
const scale = this.getWorldScale(new Vector3());
|
||||
const mat = new Matrix4();
|
||||
mat.makeScale(...this.scale.toArray());
|
||||
mat.makeScale(...scale.toArray());
|
||||
const points = this.getGeometry()
|
||||
.getAttribute('position')
|
||||
.clone()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Matrix4, Mesh } from 'three';
|
||||
import { Matrix4, Mesh, Vector3 } from 'three';
|
||||
import { Brick } from './brick.object';
|
||||
import { gameObjectGeometries } from './geometries';
|
||||
import type Rapier from '@dimforge/rapier3d';
|
||||
|
@ -17,8 +17,9 @@ export class Wedge extends Brick {
|
|||
world: Rapier.World,
|
||||
body?: Rapier.RigidBody
|
||||
) {
|
||||
const scale = this.getWorldScale(new Vector3());
|
||||
const mat = new Matrix4();
|
||||
mat.makeScale(...this.scale.toArray());
|
||||
mat.makeScale(...scale.toArray());
|
||||
const points = this.getGeometry()
|
||||
.getAttribute('position')
|
||||
.clone()
|
||||
|
|
|
@ -81,6 +81,7 @@ export type EngineEvents = {
|
|||
sceneLeave: (event: Object3D) => void;
|
||||
queueFree: (event: Object3D) => void;
|
||||
loadComplete: () => void;
|
||||
physicsComplete: () => void;
|
||||
initialized: () => void;
|
||||
reset: () => void;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue