@awayfl/awayfl-player
Version:
Flash Player emulator for executing SWF files (published for FP versions 6 and up) in javascript
121 lines (120 loc) • 4.57 kB
JavaScript
import { __extends } from "tslib";
import { b2Vec2 } from "../../Common/Math";
import { b2Color } from "../../Common/b2Color";
import { b2Controller } from "./b2Controller";
/**
* Calculates buoyancy forces for fluids in the form of a half plane
*/
var b2BuoyancyController = /** @class */ (function (_super) {
__extends(b2BuoyancyController, _super);
function b2BuoyancyController() {
var _this = _super !== null && _super.apply(this, arguments) || this;
/**
* The outer surface normal
*/
_this.normal = new b2Vec2(0, -1);
/**
* The height of the fluid surface along the normal
*/
_this.offset = 0;
/**
* The fluid density
*/
_this.density = 0;
/**
* Fluid velocity, for drag calculations
*/
_this.velocity = new b2Vec2(0, 0);
/**
* Linear drag co-efficient
*/
_this.linearDrag = 2;
/**
* Linear drag co-efficient
*/
_this.angularDrag = 1;
/**
* If false, bodies are assumed to be uniformly dense, otherwise use the shapes densities
*/
_this.useDensity = false; //False by default to prevent a gotcha
/**
* If true, gravity is taken from the world instead of the gravity parameter.
*/
_this.useWorldGravity = true;
/**
* Gravity vector, if the world's gravity is not used
*/
_this.gravity = null;
return _this;
}
b2BuoyancyController.prototype.Step = function (step) {
if (!this.m_bodyList)
return;
if (this.useWorldGravity) {
this.gravity = this.GetWorld().GetGravity().Copy();
}
for (var i = this.m_bodyList; i; i = i.nextBody) {
var body = i.body;
if (body.IsAwake() == false) {
//Buoyancy force is just a function of position,
//so unlike most forces, it is safe to ignore sleeping bodes
continue;
}
var areac = new b2Vec2();
var massc = new b2Vec2();
var area = 0.0;
var mass = 0.0;
for (var fixture = body.GetFixtureList(); fixture; fixture = fixture.GetNext()) {
var sc = new b2Vec2();
var sarea = fixture.GetShape().ComputeSubmergedArea(this.normal, this.offset, body.GetTransform(), sc);
area += sarea;
areac.x += sarea * sc.x;
areac.y += sarea * sc.y;
var shapeDensity;
if (this.useDensity) {
//TODO: Figure out what to do now density is gone
shapeDensity = 1;
}
else {
shapeDensity = 1;
}
mass += sarea * shapeDensity;
massc.x += sarea * sc.x * shapeDensity;
massc.y += sarea * sc.y * shapeDensity;
}
areac.x /= area;
areac.y /= area;
massc.x /= mass;
massc.y /= mass;
if (area < Number.MIN_VALUE)
continue;
//Buoyancy
var buoyancyForce = this.gravity.GetNegative();
buoyancyForce.Multiply(this.density * area);
body.ApplyForce(buoyancyForce, massc);
//Linear drag
var dragForce = body.GetLinearVelocityFromWorldPoint(areac);
dragForce.Subtract(this.velocity);
dragForce.Multiply(-this.linearDrag * area);
body.ApplyForce(dragForce, areac);
//Angular drag
//TODO: Something that makes more physical sense?
body.ApplyTorque(-body.GetInertia() / body.GetMass() * area * body.GetAngularVelocity() * this.angularDrag);
}
};
b2BuoyancyController.prototype.Draw = function (debugDraw) {
var r = 1000;
//Would like to draw a semi-transparent box
//But debug draw doesn't support that
var p1 = new b2Vec2();
var p2 = new b2Vec2();
p1.x = this.normal.x * this.offset + this.normal.y * r;
p1.y = this.normal.y * this.offset - this.normal.x * r;
p2.x = this.normal.x * this.offset - this.normal.y * r;
p2.y = this.normal.y * this.offset + this.normal.x * r;
var color = new b2Color(0, 0, 1);
debugDraw.DrawSegment(p1, p2, color);
};
return b2BuoyancyController;
}(b2Controller));
export { b2BuoyancyController };