UNPKG

@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
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 };