新增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