修复verlet报错

This commit is contained in:
yhh
2021-07-02 20:59:44 +08:00
parent 85bdd97d48
commit 13a001c258
11 changed files with 73 additions and 56 deletions
+2 -1
View File
@@ -3584,7 +3584,7 @@ declare module es {
* @param results * @param results
* @param layerMask * @param layerMask
*/ */
static overlapCircleAll(center: Vector2, randius: number, results: any[], layerMask?: number): number; static overlapCircleAll(center: Vector2, radius: number, results: Collider[], layerMask?: number): number;
/** /**
* 返回所有碰撞器与边界相交的碰撞器。bounds。请注意,这是一个broadphase检查,所以它只检查边界,不做单个碰撞到碰撞器的检查! * 返回所有碰撞器与边界相交的碰撞器。bounds。请注意,这是一个broadphase检查,所以它只检查边界,不做单个碰撞到碰撞器的检查!
* @param rect * @param rect
@@ -4132,6 +4132,7 @@ declare module es {
_fixedDeltaTime: number; _fixedDeltaTime: number;
_iterationSteps: number; _iterationSteps: number;
_fixedDeltaTimeSq: number; _fixedDeltaTimeSq: number;
onHandleDrag: Function;
constructor(simulationBounds?: Rectangle); constructor(simulationBounds?: Rectangle);
update(): void; update(): void;
constrainParticleToBounds(p: Particle): void; constrainParticleToBounds(p: Particle): void;
+29 -16
View File
@@ -1743,6 +1743,7 @@ var es;
this._worldTransform = es.Matrix2D.identity; this._worldTransform = es.Matrix2D.identity;
this._rotationMatrix = es.Matrix2D.identity; this._rotationMatrix = es.Matrix2D.identity;
this._translationMatrix = es.Matrix2D.identity; this._translationMatrix = es.Matrix2D.identity;
this._scaleMatrix = es.Matrix2D.identity;
this._children = []; this._children = [];
this._worldToLocalTransform = es.Matrix2D.identity; this._worldToLocalTransform = es.Matrix2D.identity;
this._worldInverseTransform = es.Matrix2D.identity; this._worldInverseTransform = es.Matrix2D.identity;
@@ -8803,13 +8804,9 @@ var es;
* @param results * @param results
* @param layerMask * @param layerMask
*/ */
Physics.overlapCircleAll = function (center, randius, results, layerMask) { Physics.overlapCircleAll = function (center, radius, results, layerMask) {
if (layerMask === void 0) { layerMask = -1; } if (layerMask === void 0) { layerMask = this.allLayers; }
if (results.length == 0) { return this._spatialHash.overlapCircle(center, radius, results, layerMask);
console.warn("传入了一个空的结果数组。不会返回任何结果");
return;
}
return this._spatialHash.overlapCircle(center, randius, results, layerMask);
}; };
/** /**
* 返回所有碰撞器与边界相交的碰撞器bounds请注意这是一个broadphase检查所以它只检查边界不做单个碰撞到碰撞器的检查! * 返回所有碰撞器与边界相交的碰撞器bounds请注意这是一个broadphase检查所以它只检查边界不做单个碰撞到碰撞器的检查!
@@ -9235,7 +9232,7 @@ var es;
var e_11, _a; var e_11, _a;
var bounds = new es.Rectangle(circleCenter.x - radius, circleCenter.y - radius, radius * 2, radius * 2); var bounds = new es.Rectangle(circleCenter.x - radius, circleCenter.y - radius, radius * 2, radius * 2);
this._overlapTestCircle.radius = radius; this._overlapTestCircle.radius = radius;
this._overlapTestCircle.position = circleCenter.clone(); this._overlapTestCircle.position = circleCenter;
var resultCounter = 0; var resultCounter = 0;
var potentials = this.aabbBroadphase(bounds, null, layerMask); var potentials = this.aabbBroadphase(bounds, null, layerMask);
try { try {
@@ -9263,7 +9260,7 @@ var es;
throw new Error("对这个对撞机类型的overlapCircle没有实现!"); throw new Error("对这个对撞机类型的overlapCircle没有实现!");
} }
// 如果我们所有的结果数据有了则返回 // 如果我们所有的结果数据有了则返回
if (resultCounter == results.length) if (resultCounter === results.length)
return resultCounter; return resultCounter;
} }
} }
@@ -10405,8 +10402,14 @@ var es;
(function (es) { (function (es) {
var Particle = /** @class */ (function () { var Particle = /** @class */ (function () {
function Particle(position) { function Particle(position) {
this.position = es.Vector2.zero;
this.lastPosition = es.Vector2.zero;
this.mass = 1; this.mass = 1;
this.radius = 0;
this.collidesWithColliders = true; this.collidesWithColliders = true;
this.isPinned = false;
this.acceleration = es.Vector2.zero;
this.pinnedPosition = es.Vector2.zero;
this.position = new es.Vector2(position.x, position.y); this.position = new es.Vector2(position.x, position.y);
this.lastPosition = new es.Vector2(position.x, position.y); this.lastPosition = new es.Vector2(position.x, position.y);
} }
@@ -10437,16 +10440,19 @@ var es;
var VerletWorld = /** @class */ (function () { var VerletWorld = /** @class */ (function () {
function VerletWorld(simulationBounds) { function VerletWorld(simulationBounds) {
if (simulationBounds === void 0) { simulationBounds = null; } if (simulationBounds === void 0) { simulationBounds = null; }
this.gravity = new es.Vector2(0, 980); this.gravity = new es.Vector2(0, -980);
this.constraintIterations = 3; this.constraintIterations = 3;
this.maximumStepIterations = 5; this.maximumStepIterations = 5;
this.allowDragging = true; this.allowDragging = true;
this.selectionRadiusSquared = 20 * 20; this.selectionRadiusSquared = 20 * 20;
this._composites = []; this._composites = [];
this._tempCircle = new es.Circle(1); this._tempCircle = new es.Circle(1);
this._leftOverTime = 0;
this._fixedDeltaTime = 1 / 60; this._fixedDeltaTime = 1 / 60;
this._iterationSteps = 0;
this._fixedDeltaTimeSq = 0;
this.simulationBounds = simulationBounds; this.simulationBounds = simulationBounds;
this._fixedDeltaTime = Math.pow(this._fixedDeltaTime, 2); this._fixedDeltaTimeSq = Math.pow(this._fixedDeltaTime, 2);
} }
VerletWorld.prototype.update = function () { VerletWorld.prototype.update = function () {
this.updateTiming(); this.updateTiming();
@@ -10531,6 +10537,8 @@ var es;
this._composites.splice(index, 1); this._composites.splice(index, 1);
}; };
VerletWorld.prototype.handleDragging = function () { VerletWorld.prototype.handleDragging = function () {
if (this.onHandleDrag)
this.onHandleDrag();
}; };
VerletWorld.prototype.getNearestParticle = function (position) { VerletWorld.prototype.getNearestParticle = function (position) {
var nearestSquaredDistance = this.selectionRadiusSquared; var nearestSquaredDistance = this.selectionRadiusSquared;
@@ -10731,6 +10739,8 @@ var es;
__extends(AngleConstraint, _super); __extends(AngleConstraint, _super);
function AngleConstraint(a, center, c, stiffness) { function AngleConstraint(a, center, c, stiffness) {
var _this = _super.call(this) || this; var _this = _super.call(this) || this;
_this.stiffness = 0;
_this.angleInRadius = 0;
_this._particleA = a; _this._particleA = a;
_this._centerParticle = center; _this._centerParticle = center;
_this._particleC = c; _this._particleC = c;
@@ -10768,7 +10778,10 @@ var es;
function DistanceConstraint(first, second, stiffness, distance) { function DistanceConstraint(first, second, stiffness, distance) {
if (distance === void 0) { distance = -1; } if (distance === void 0) { distance = -1; }
var _this = _super.call(this) || this; var _this = _super.call(this) || this;
_this.stiffness = 0;
_this.restingDistance = 0;
_this.tearSensitivity = Number.POSITIVE_INFINITY; _this.tearSensitivity = Number.POSITIVE_INFINITY;
_this.shouldApproximateCollisionsWithPoints = false;
_this.totalPointsToApproximateCollisionsWith = 5; _this.totalPointsToApproximateCollisionsWith = 5;
DistanceConstraint._polygon.create(2, 1); DistanceConstraint._polygon.create(2, 1);
_this._particleOne = first; _this._particleOne = first;
@@ -10777,12 +10790,12 @@ var es;
if (distance > -1) if (distance > -1)
_this.restingDistance = distance; _this.restingDistance = distance;
else else
_this.restingDistance = es.Vector2.distance(first.position, second.position); _this.restingDistance = first.position.distance(second.position);
return _this; return _this;
} }
DistanceConstraint.create = function (a, center, c, stiffness, angleInDegrees) { DistanceConstraint.create = function (a, center, c, stiffness, angleInDegrees) {
var aToCenter = es.Vector2.distance(a.position, center.position); var aToCenter = a.position.distance(center.position);
var cToCenter = es.Vector2.distance(c.position, center.position); var cToCenter = c.position.distance(center.position);
var distance = Math.sqrt(aToCenter * aToCenter + cToCenter * cToCenter - (2 * aToCenter * cToCenter * Math.cos(angleInDegrees * es.MathHelper.Deg2Rad))); var distance = Math.sqrt(aToCenter * aToCenter + cToCenter * cToCenter - (2 * aToCenter * cToCenter * Math.cos(angleInDegrees * es.MathHelper.Deg2Rad)));
return new DistanceConstraint(a, c, stiffness, distance); return new DistanceConstraint(a, c, stiffness, distance);
}; };
@@ -10800,7 +10813,7 @@ var es;
}; };
DistanceConstraint.prototype.solve = function () { DistanceConstraint.prototype.solve = function () {
var diff = this._particleOne.position.sub(this._particleTwo.position); var diff = this._particleOne.position.sub(this._particleTwo.position);
var d = diff.magnitude(); var d = diff.distance();
var difference = (this.restingDistance - d) / d; var difference = (this.restingDistance - d) / d;
if (d / this.restingDistance > this.tearSensitivity) { if (d / this.restingDistance > this.tearSensitivity) {
this.composite.removeConstraint(this); this.composite.removeConstraint(this);
@@ -10823,7 +10836,7 @@ var es;
var minY = Math.min(this._particleOne.position.y, this._particleTwo.position.y); var minY = Math.min(this._particleOne.position.y, this._particleTwo.position.y);
var maxY = Math.max(this._particleOne.position.y, this._particleTwo.position.y); var maxY = Math.max(this._particleOne.position.y, this._particleTwo.position.y);
DistanceConstraint._polygon.bounds = es.Rectangle.fromMinMax(minX, minY, maxX, maxY); DistanceConstraint._polygon.bounds = es.Rectangle.fromMinMax(minX, minY, maxX, maxY);
var midPoint; var midPoint = es.Vector2.zero;
this.preparePolygonForCollisionChecks(midPoint); this.preparePolygonForCollisionChecks(midPoint);
var colliders = es.Physics.boxcastBroadphase(DistanceConstraint._polygon.bounds, collidesWithLayers); var colliders = es.Physics.boxcastBroadphase(DistanceConstraint._polygon.bounds, collidesWithLayers);
for (var i = 0; i < colliders.length; i++) { for (var i = 0; i < colliders.length; i++) {
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -35,7 +35,7 @@ module es {
public _worldTransform = Matrix2D.identity; public _worldTransform = Matrix2D.identity;
public _rotationMatrix: Matrix2D = Matrix2D.identity; public _rotationMatrix: Matrix2D = Matrix2D.identity;
public _translationMatrix: Matrix2D = Matrix2D.identity; public _translationMatrix: Matrix2D = Matrix2D.identity;
public _scaleMatrix: Matrix2D; public _scaleMatrix: Matrix2D = Matrix2D.identity;
public _children: Transform[] = []; public _children: Transform[] = [];
constructor(entity: Entity) { constructor(entity: Entity) {
+7 -7
View File
@@ -67,13 +67,13 @@ module es {
* @param results * @param results
* @param layerMask * @param layerMask
*/ */
public static overlapCircleAll(center: Vector2, randius: number, results: any[], layerMask = -1) { public static overlapCircleAll(center: Vector2, radius: number, results: Collider[], layerMask: number = this.allLayers) {
if (results.length == 0) { return this._spatialHash.overlapCircle(
console.warn("传入了一个空的结果数组。不会返回任何结果"); center,
return; radius,
} results,
layerMask
return this._spatialHash.overlapCircle(center, randius, results, layerMask); );
} }
/** /**
+4 -4
View File
@@ -263,13 +263,13 @@ module es {
* @param layerMask * @param layerMask
*/ */
public overlapCircle(circleCenter: Vector2, radius: number, results: Collider[], layerMask): number { public overlapCircle(circleCenter: Vector2, radius: number, results: Collider[], layerMask): number {
let bounds = new Rectangle(circleCenter.x - radius, circleCenter.y - radius, radius * 2, radius * 2); const bounds = new Rectangle(circleCenter.x - radius, circleCenter.y - radius, radius * 2, radius * 2);
this._overlapTestCircle.radius = radius; this._overlapTestCircle.radius = radius;
this._overlapTestCircle.position = circleCenter.clone(); this._overlapTestCircle.position = circleCenter;
let resultCounter = 0; let resultCounter = 0;
let potentials = this.aabbBroadphase(bounds, null, layerMask); const potentials = this.aabbBroadphase(bounds, null, layerMask);
for (let collider of potentials) { for (let collider of potentials) {
if (collider instanceof BoxCollider) { if (collider instanceof BoxCollider) {
if (collider.shape.overlaps(this._overlapTestCircle)) { if (collider.shape.overlaps(this._overlapTestCircle)) {
@@ -291,7 +291,7 @@ module es {
} }
// 如果我们所有的结果数据有了则返回 // 如果我们所有的结果数据有了则返回
if (resultCounter == results.length) if (resultCounter === results.length)
return resultCounter; return resultCounter;
} }
@@ -1,8 +1,8 @@
///<reference path="./Constraint.ts" /> ///<reference path="./Constraint.ts" />
module es { module es {
export class AngleConstraint extends Constraint { export class AngleConstraint extends Constraint {
public stiffness: number; public stiffness: number = 0;
public angleInRadius: number; public angleInRadius: number = 0;
_particleA: Particle; _particleA: Particle;
_centerParticle: Particle; _centerParticle: Particle;
@@ -1,9 +1,9 @@
module es { module es {
export class DistanceConstraint extends Constraint { export class DistanceConstraint extends Constraint {
public stiffness: number; public stiffness: number = 0;
public restingDistance: number; public restingDistance: number = 0;
public tearSensitivity = Number.POSITIVE_INFINITY; public tearSensitivity = Number.POSITIVE_INFINITY;
public shouldApproximateCollisionsWithPoints: boolean; public shouldApproximateCollisionsWithPoints: boolean = false;
public totalPointsToApproximateCollisionsWith = 5; public totalPointsToApproximateCollisionsWith = 5;
_particleOne: Particle; _particleOne: Particle;
_particleTwo: Particle; _particleTwo: Particle;
@@ -20,12 +20,12 @@ module es {
if (distance > -1) if (distance > -1)
this.restingDistance = distance; this.restingDistance = distance;
else else
this.restingDistance = Vector2.distance(first.position, second.position); this.restingDistance = first.position.distance(second.position);
} }
public static create(a: Particle, center: Particle, c: Particle, stiffness: number, angleInDegrees: number) { public static create(a: Particle, center: Particle, c: Particle, stiffness: number, angleInDegrees: number) {
const aToCenter = Vector2.distance(a.position, center.position); const aToCenter = a.position.distance(center.position);
const cToCenter = Vector2.distance(c.position, center.position); const cToCenter = c.position.distance(center.position);
const distance = Math.sqrt(aToCenter * aToCenter + cToCenter * cToCenter - (2 * aToCenter * cToCenter * Math.cos(angleInDegrees * MathHelper.Deg2Rad))); const distance = Math.sqrt(aToCenter * aToCenter + cToCenter * cToCenter - (2 * aToCenter * cToCenter * Math.cos(angleInDegrees * MathHelper.Deg2Rad)));
return new DistanceConstraint(a, c, stiffness, distance); return new DistanceConstraint(a, c, stiffness, distance);
@@ -48,7 +48,7 @@ module es {
public solve(): void { public solve(): void {
const diff = this._particleOne.position.sub(this._particleTwo.position); const diff = this._particleOne.position.sub(this._particleTwo.position);
const d = diff.magnitude(); const d = diff.distance();
const difference = (this.restingDistance - d) / d; const difference = (this.restingDistance - d) / d;
if (d / this.restingDistance > this.tearSensitivity) { if (d / this.restingDistance > this.tearSensitivity) {
@@ -77,7 +77,7 @@ module es {
const maxY = Math.max(this._particleOne.position.y, this._particleTwo.position.y); const maxY = Math.max(this._particleOne.position.y, this._particleTwo.position.y);
DistanceConstraint._polygon.bounds = Rectangle.fromMinMax(minX, minY, maxX, maxY); DistanceConstraint._polygon.bounds = Rectangle.fromMinMax(minX, minY, maxX, maxY);
let midPoint: Vector2; let midPoint: Vector2 = Vector2.zero;
this.preparePolygonForCollisionChecks(midPoint); this.preparePolygonForCollisionChecks(midPoint);
const colliders = Physics.boxcastBroadphase(DistanceConstraint._polygon.bounds, collidesWithLayers); const colliders = Physics.boxcastBroadphase(DistanceConstraint._polygon.bounds, collidesWithLayers);
+6 -6
View File
@@ -1,13 +1,13 @@
module es { module es {
export class Particle { export class Particle {
public position: Vector2; public position: Vector2 = Vector2.zero;
public lastPosition: Vector2; public lastPosition: Vector2 = Vector2.zero;
public mass = 1; public mass = 1;
public radius: number; public radius: number = 0;
public collidesWithColliders: boolean = true; public collidesWithColliders: boolean = true;
public isPinned: boolean; public isPinned: boolean = false;
public acceleration: Vector2; public acceleration: Vector2 = Vector2.zero;
public pinnedPosition: Vector2; public pinnedPosition: Vector2 = Vector2.zero;
constructor(position: {x: number, y: number}) { constructor(position: {x: number, y: number}) {
this.position = new Vector2(position.x, position.y); this.position = new Vector2(position.x, position.y);
+9 -6
View File
@@ -1,6 +1,6 @@
module es { module es {
export class VerletWorld { export class VerletWorld {
public gravity: Vector2 = new Vector2(0, 980); public gravity: Vector2 = new Vector2(0, -980);
public constraintIterations = 3; public constraintIterations = 3;
public maximumStepIterations = 5; public maximumStepIterations = 5;
public simulationBounds: Rectangle; public simulationBounds: Rectangle;
@@ -11,14 +11,16 @@ module es {
public static _colliders: Collider[] = []; public static _colliders: Collider[] = [];
_tempCircle: Circle = new Circle(1); _tempCircle: Circle = new Circle(1);
_leftOverTime: number; _leftOverTime: number = 0;
_fixedDeltaTime: number = 1 / 60; _fixedDeltaTime: number = 1 / 60;
_iterationSteps: number; _iterationSteps: number = 0;
_fixedDeltaTimeSq: number; _fixedDeltaTimeSq: number = 0;
onHandleDrag: Function;
constructor(simulationBounds: Rectangle = null) { constructor(simulationBounds: Rectangle = null) {
this.simulationBounds = simulationBounds; this.simulationBounds = simulationBounds;
this._fixedDeltaTime = Math.pow(this._fixedDeltaTime, 2); this._fixedDeltaTimeSq = Math.pow(this._fixedDeltaTime, 2);
} }
public update() { public update() {
@@ -122,7 +124,8 @@ module es {
} }
handleDragging() { handleDragging() {
if (this.onHandleDrag)
this.onHandleDrag();
} }
public getNearestParticle(position: Vector2) { public getNearestParticle(position: Vector2) {