新增verletworld

This commit is contained in:
yhh
2020-06-10 20:29:16 +08:00
parent fa4c3c5d0b
commit 74cbb4c9fd
4 changed files with 92 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
class Composite {
private _constraints: Constraint[] = [];
public particles: Particle[] = [];
/**
* 处理解决所有约束条件
*/
public solveConstraints(){
for (let i = this._constraints.length - 1; i >= 0; i --){
this._constraints[i].solve();
}
}
public updateParticles(deltaTimeSquared: number, gravity: Vector2){
for (let j = 0; j < this.particles.length; j ++){
let p = this.particles[j];
if (p.isPinned){
p.position = p.pinnedPosition;
continue;
}
p.applyForce(Vector2.multiply(new Vector2(p.mass, p.mass), gravity));
}
}
}

View File

@@ -0,0 +1,5 @@
abstract class Constraint {
public composite: Composite;
public abstract solve();
}

View File

@@ -0,0 +1,17 @@
class Particle {
public position: Vector2;
public lastPosition: Vector2;
public isPinned: boolean;
public pinnedPosition;
public acceleration: Vector2;
public mass: number = 1;
constructor(position: Vector2){
this.position = position;
this.lastPosition = position;
}
public applyForce(force: Vector2){
this.acceleration = Vector2.add(this.acceleration, new Vector2(force.x / this.mass, force.y / this.mass));
}
}

View File

@@ -0,0 +1,45 @@
/**
* 基于verlet 物理引擎进行改造的物理引擎 ts重写
* https://github.com/subprotocol/verlet-js
*/
class VerletWorld {
public gravity: Vector2 = new Vector2(0, 980);
public maximumStepIterations = 5;
public constraintIterations = 3;
public simulationBounds: Rectangle;
private _leftOverTime: number;
private _iterationSteps: number;
private _fixedDeltaTime = 1 / 60;
private _composites: Composite[] = [];
private _fixedDeltaTimeSq: number;
constructor(simulationBounds?: Rectangle){
this.simulationBounds = simulationBounds;
this._fixedDeltaTimeSq = Math.pow(this._fixedDeltaTime, 2);
}
public update(){
this.updateTiming();
for (let iteration = 1; iteration <= this._iterationSteps; iteration ++){
for (let i = this._composites.length - 1; i >= 0; i --){
let composite = this._composites[i];
for (let s = 0; s < this.constraintIterations; s++){
composite.solveConstraints();
}
composite.updateParticles(this._fixedDeltaTimeSq, this.gravity);
}
}
}
private updateTiming(){
this._leftOverTime += Time.deltaTime;
this._iterationSteps = Math.trunc(this._leftOverTime / this._fixedDeltaTime);
this._leftOverTime -= this._iterationSteps * this._fixedDeltaTime;
this._iterationSteps = Math.min(this._iterationSteps, this.maximumStepIterations);
}
}