新增verletworld
This commit is contained in:
25
source/src/Utils/Verlet/Composites/Composite.ts
Normal file
25
source/src/Utils/Verlet/Composites/Composite.ts
Normal 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
5
source/src/Utils/Verlet/Constraint/Constraint.ts
Normal file
5
source/src/Utils/Verlet/Constraint/Constraint.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
abstract class Constraint {
|
||||||
|
public composite: Composite;
|
||||||
|
|
||||||
|
public abstract solve();
|
||||||
|
}
|
||||||
17
source/src/Utils/Verlet/Particle.ts
Normal file
17
source/src/Utils/Verlet/Particle.ts
Normal 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
45
source/src/Utils/Verlet/VerletWorld.ts
Normal file
45
source/src/Utils/Verlet/VerletWorld.ts
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user