Skip to content

Commit

Permalink
feat: 优化物理引擎
Browse files Browse the repository at this point in the history
  • Loading branch information
xjown committed May 20, 2024
1 parent 73c3e6f commit 506b18e
Show file tree
Hide file tree
Showing 10 changed files with 183 additions and 53 deletions.
56 changes: 56 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,65 @@
height: 100%;
width: 100%;
}
#mask {
background-color: black;
position: fixed;
z-index: 2;
opacity: 0.55;
border-radius: 3%;
display: none;
}
#tips {
padding: 10px;
z-index: 3;
cursor: pointer;
display: none;
}
.weapon {
display: flex;
color: #fff;
font-size: 12px;
align-items: center;
display: none;
}
.weapon:hover {
background-color: rgb(255, 230, 0);
color: #000;
}
.weapon div {
margin: 0 5px;
}
.weapon-left {
width: 50px;
height: 50px;
background-color: #585858;
border-radius: 3%;
line-height: 50px;
text-align: center;
font-size: 30px;
}
.weapon-right > p {
margin: 0;
font-size: 10px;
}
.weapon-right > p:first-child {
font-size: 16px;
}
</style>
</head>
<body>
<div id="mask">
<div id="tips">
<div class="weapon">
<div class="weapon-left">F</div>
<div class="weapon-right">
<p>AK47</p>
<p>♾️/30</p>
<p>按F键或点击拾取</p>
</div>
</div>
</div>
</div>
<div id="app">
<div id="loading">
<style>
Expand Down
27 changes: 21 additions & 6 deletions src/core/ammo/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ import { Object3D } from 'three';
class AmmoHelper {
static collisionFilterGroup = {
// 00000001
DefaultFilter: 1,
DefaultFilter: 1 << 0,
// 00000010
StaticFilter: 2,
StaticFilter: 1 << 1,
// 00000100
KinematicFilter: 4,
KinematicFilter: 1 << 2,
// 00001000
DebrisFilter: 8,
DebrisFilter: 1 << 3,
// 00010000
SensorTrigger: 16,
SensorTrigger: 1 << 4,
// 00100000
CharacterFilter: 32,
CharacterFilter: 1 << 5,
// 11111111
AllFilter: -1,
};
Expand Down Expand Up @@ -72,6 +72,21 @@ class AmmoHelper {
return ghostObj;
}

static IsTriggerOverlapping(
ghostObj: Ammo.btGhostObject,
rigidBody: Ammo.btRigidBody
) {
for (let i = 0; i < ghostObj.getNumOverlappingObjects(); i++) {
const body = Ammo.castObject<typeof Ammo.btRigidBody>(
ghostObj.getOverlappingObject(i),
Ammo.btRigidBody
);
if (body === rigidBody) return true;
}

return false;
}

/**
* 建立凸包
* @param object
Expand Down
2 changes: 1 addition & 1 deletion src/core/character/Man.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default class Man extends Character {
constructor() {
super();

this.mass = 1;
this.mass = 5;

this.size.x = 2;
this.size.y = 6;
Expand Down
20 changes: 13 additions & 7 deletions src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,18 @@ export default class Core {
const uiEntity = new Entity('ui');
uiEntity.addComponent(new UI());

// world
const worldEntity = new Entity('world');
worldEntity.addComponent(new WorldPhysics(this.physicsWorld));
worldEntity.addComponent(new World(this));
assets.push(worldEntity);

// player
const playerEntity = new Entity('player');
playerEntity.addComponent(new PlayPhysics(this.physicsWorld));
playerEntity.addComponent(new PlayControl(this));
assets.push(playerEntity);

// world
const worldEntity = new Entity('world');
worldEntity.addComponent(new WorldPhysics(this.physicsWorld));
worldEntity.addComponent(new World(this));
assets.push(worldEntity);

this.entityCollection.addEntity(playerEntity);
this.entityCollection.addEntity(uiEntity);
this.entityCollection.addEntity(worldEntity);
Expand Down Expand Up @@ -136,11 +136,17 @@ export default class Core {
);

// 设置重力
this.physicsWorld.setGravity(new Ammo.btVector3(0, -10, 0));
this.physicsWorld.setGravity(new Ammo.btVector3(0, -9.8, 0));

this.physicsWorld.setInternalTickCallback(
Ammo.addFunction(this._physicsUpdate.bind(this))
);

// 设置幽灵对象碰撞检测
this.physicsWorld
.getBroadphase()
.getOverlappingPairCache()
.setInternalGhostPairCallback(new Ammo.btGhostPairCallback());
}

private _RenderRespect() {
Expand Down
62 changes: 36 additions & 26 deletions src/core/player/PlayControl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,38 @@ import { boxHelper } from '@/core/helper';
import type Core from '../index';
import type ActionEvent from '../events/action';
import type Collision from '../collision';
import type World from '../world';
import type { World } from '../world';
import type PlayPhysics from './PlayPhysics';
import type {
Box3 as Box3Type,
Line3 as Line3Type,
Mesh as MeshType,
BoxGeometry as BoxGeometryType,
BufferGeometry as BufferGeometryType,
MeshBasicMaterial as MeshBasicMaterialType,
Vector3 as Vector3Type,
AnimationMixer as AnimationMixerType,
} from 'three';

export default class PlayControl extends Component {
private _instance: Core;
private _player!: MeshType<BoxGeometryType, MeshBasicMaterialType>;
private _player!: MeshType<BufferGeometryType, MeshBasicMaterialType>;
private _speed: number = 6;
private _basePlayerInfo = {
radius: 1,
firstPerson: true,
};
private _frameBox: Box3Type = new Box3();
private _frameLine: Line3Type = new Line3();
private _onFloor: boolean = false;
private _onFloor: boolean = true;
private _downDistance: Vector3Type = new Vector3(0, 0, 0);
private _gravity: number = 15;
private _mixer!: AnimationMixerType;
private _currentAction: string = 'idle';
private _maxFalling: number = 15;
private _event: ActionEvent;
private _worldEntity!: Component;
private _worldEntity!: World;
private _body!: Ammo.btRigidBody;
private _physicsWorld!: Component;
private _physicsWorld!: PlayPhysics;

public position: Vector3Type;
public character: Man;
Expand All @@ -55,11 +56,11 @@ export default class PlayControl extends Component {
}

initialize() {
this._physicsWorld = this.getComponent('playPhysics')!;
this._physicsWorld = this.getComponent('playPhysics')! as PlayPhysics;
this._worldEntity = this.FindEntity('world')?.getComponent(
'world'
) as Component;
this._body = this._physicsWorld.body as Ammo.btRigidBody;
) as World;
this._body = this._physicsWorld.body!;

this._createPlayer();

Expand All @@ -75,10 +76,10 @@ export default class PlayControl extends Component {

_createPlayer() {
this._player = new Mesh(
new BoxGeometry(
this.character.size.x,
this.character.size.y,
this.character.size.z
new CylinderGeometry(
this.character.size.z,
this.character.size.z,
this.character.size.y
),
new MeshBasicMaterial({ color: 0x00ff00 })
);
Expand All @@ -89,7 +90,11 @@ export default class PlayControl extends Component {
this._switchVisual();

this._player.visible = false;
this._player.position.set(0, 4, 0);
this._player.position.set(
this.position.x,
this.position.y,
this.position.z
);

this._instance.scene.add(this._player);
}
Expand All @@ -99,7 +104,7 @@ export default class PlayControl extends Component {
if (ms) {
const transform = new Ammo.btTransform();
ms.getWorldTransform(transform);

// console.log(transform.getOrigin().y());
// 调整摄像机
const cameraDistance = new Vector3().subVectors(
new Vector3(
Expand All @@ -109,6 +114,11 @@ export default class PlayControl extends Component {
),
this._instance.orbit_controls.target
);
this._player.position.set(
transform.getOrigin().x(),
transform.getOrigin().y(),
transform.getOrigin().z()
);

// const cameraDistance = new Vector3().subVectors(
// this.position,
Expand Down Expand Up @@ -137,14 +147,14 @@ export default class PlayControl extends Component {
}

update(time: number) {
this.position.set(
this._player.position.x,
this._player.position.y,
this._player.position.z
);
// this.position.set(
// this._player.position.x,
// this._player.position.y,
// this._player.position.z
// );

if ((this._worldEntity as World).getCollision().collisions) {
this._checkCollision(time);
// this._checkCollision(time);
this._updatePlayer(time);
}

Expand Down Expand Up @@ -175,9 +185,9 @@ export default class PlayControl extends Component {
const angle = this._instance.orbit_controls.getAzimuthalAngle();
const rotation = new Vector3(0, 0, 0);

this._downDistance.y = this._onFloor ? 0 : this._gravity * time * -1;
// this._downDistance.y = this._onFloor ? 0 : this._gravity * time * -1;

this._player.position.add(this._downDistance);
// this._player.position.add(this._downDistance);

if (this._event.downDowning.KeyW) {
rotation.set(0, 0, -1).applyAxisAngle(new Vector3(0, 1, 0), angle);
Expand All @@ -202,11 +212,11 @@ export default class PlayControl extends Component {
this._body.setLinearVelocity(physicsPos);
this._body.setAngularVelocity(new Ammo.btVector3(0, angle, 0));

this._player.position.addScaledVector(rotation, this._speed * time);
// this._player.position.addScaledVector(rotation, this._speed * time);

//此处必须更新。默认为自动更新,但是会慢一拍。如果不更新会导致计算距离不准确
// 详情 _checkCollision()方法 => moveStance变量
this._player.updateMatrixWorld();
// this._player.updateMatrixWorld();
}

private _switchVisual() {
Expand Down Expand Up @@ -354,7 +364,7 @@ export default class PlayControl extends Component {
// .applyMatrix4(this._player.matrixWorld)
// .copy(this._player.position.clone());

this.character.person.position.set(pos.x, pos.y, pos.z);
this.character.person.position.set(pos.x, pos.y + 1, pos.z);

this.character.person.translateY(-4);

Expand Down
13 changes: 6 additions & 7 deletions src/core/player/PlayPhysics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,14 @@ export default class PlayPhysics extends Component {
);

const localInertia = new Ammo.btVector3(0, 0, 0);
const boxShape = new Ammo.btBoxShape(
new Ammo.btVector3(
playControl.character.size.x,
playControl.character.size.y,
playControl.character.size.z
)

const boxShape = new Ammo.btCapsuleShape(
1,
playControl.character.size.y / 2 + 1
);

boxShape.calculateLocalInertia(playControl.character.mass, localInertia);
boxShape.setMargin(0.05);
boxShape.setMargin(0);

const motionState = new Ammo.btDefaultMotionState(transform);

Expand Down
17 changes: 17 additions & 0 deletions src/core/ui/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,23 @@ export default class UI extends Component {

initialize() {}

weaponTip(visible: boolean) {
const el = document.querySelector('.weapon')!;
this.mask(visible);
this.tip(visible);
el.style.display = visible ? 'flex' : 'none';
}

mask(visible: boolean) {
const el = document.querySelector('#mask')!;
el.style.display = visible ? 'block' : 'none';
}

tip(visible: boolean) {
const el = document.querySelector('#tips')!;
el.style.display = visible ? 'block' : 'none';
}

_loadingOff() {
this._event.addEventListener(STATIC_LOADED, () => {
const controlHandle = this._createControl();
Expand Down
4 changes: 2 additions & 2 deletions src/core/world/World.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default class World extends Component {
public collision: Collision;
public ak = {
position: { x: 20, y: 5, z: -15 },
size: { radius: 2.5, height: 5.2 },
size: { radius: 2.5, height: 10 },
};

constructor(instance: Core) {
Expand All @@ -43,7 +43,7 @@ export default class World extends Component {
item.castShadow = true;
}
if (item.name.includes('Light')) {
item.intensity *= 1000;
item.intensity *= 800;
}
if (item.name === 'home002') {
item.castShadow = true;
Expand Down
Loading

0 comments on commit 506b18e

Please sign in to comment.