summaryrefslogtreecommitdiff
path: root/frontend/2d/_rigidbody/rigidbody_2.js
diff options
context:
space:
mode:
authorMatthew Kosarek <matthew.kosarek@vention.cc>2021-02-25 20:50:12 -0500
committerMatthew Kosarek <matthew.kosarek@vention.cc>2021-02-25 20:50:12 -0500
commit026abdb98ad30209df0e88795f25b1f74556585e (patch)
tree39c7e60ea78331ada41fc71bc5f6e5b91b5fd75c /frontend/2d/_rigidbody/rigidbody_2.js
parentf0d1398b0d1b1a7c5bd1d4e0b3488b7f1aa74364 (diff)
Updated the sidebar for usability's sake
Diffstat (limited to 'frontend/2d/_rigidbody/rigidbody_2.js')
-rw-r--r--frontend/2d/_rigidbody/rigidbody_2.js146
1 files changed, 146 insertions, 0 deletions
diff --git a/frontend/2d/_rigidbody/rigidbody_2.js b/frontend/2d/_rigidbody/rigidbody_2.js
new file mode 100644
index 0000000..4632b11
--- /dev/null
+++ b/frontend/2d/_rigidbody/rigidbody_2.js
@@ -0,0 +1,146 @@
+/// <reference path="../../scripts/jquery-3.5.1.min.js"/>
+/// <reference path="../../_shared/math/vec2.js" />
+/// <reference path="../../_shared/math/mat4.js" />
+/// <reference path="../../_shared/2d/shader.js" />
+/// <reference path="../../_shared/math/circle.js" />
+/// <reference path="../../_shared/2d/program_common.js" />
+
+(function() {
+ function main() {
+ // Define Constants
+ const CIRCLE_RADIUS = 16;
+ const GRAVITY = 9.8;
+
+ // Retrieve context
+ const lProgramContext = getContext('#rigidbody_2');
+
+ if (lProgramContext.gl === null) {
+ console.error('Unable to initialize WebGL. Your browser or machine may not support it.');
+ return;
+ }
+
+ lProgramContext.gl.clearColor(0.0, 0.0, 0.0, 1.0);
+ lProgramContext.gl.clear(lProgramContext.gl.COLOR_BUFFER_BIT);
+
+ function run() {
+ console.log('Running Rigid Body 2');
+ lProgramContext.load().then(function(pProgramInfo) {
+ const lCircle = circle(lProgramContext.gl, CIRCLE_RADIUS, 30, [
+ { x: 1, y: 1, z: 0, w: 1 },
+ { x: 1, y: 0, z: 1, w: 1 },
+ { x: 0, y: 1, z: 1, w: 1 },
+ { x: 0, y: 1, z: 0, w: 1 }
+ ], vec2(lProgramContext.width / 2.0, lProgramContext.height / 2.0));
+
+ function update(pDeltaTimeSeconds) {
+ // Same physics updates from part 1
+ applyForce(vec2(0, -1.0 * (lCircle.mass * GRAVITY)));
+ const lCurrentAcceleration = scaleVec2(lCircle.force, 1.0 / lCircle.mass);
+ lCircle.velocity = addVec2(lCircle.velocity, scaleVec2(lCurrentAcceleration, pDeltaTimeSeconds));
+ lCircle.position = addVec2(lCircle.position, scaleVec2(lCircle.velocity, pDeltaTimeSeconds));
+ lCircle.force = vec2();
+
+ // Angular code starts here
+
+ // Retrieve the moment of inertia for our shape (Ours is a circle by default)
+ const lMomentOfInertia = getMomentOfInertia(lCircle);
+
+ // Calculate the angular acceperation (omega = T / I)
+ const lAngularAcceleration = lCircle.torque / lMomentOfInertia;
+
+ // Calculate the rotation in radians
+ lCircle.rotationVelocity += lAngularAcceleration * pDeltaTimeSeconds;
+ lCircle.rotationRadians += lCircle.rotationVelocity * pDeltaTimeSeconds;
+ lCircle.torque = 0;
+
+ // Calculate the model as previously, but this time, also rotate it
+ lCircle.model = rotateMatrix2d(translateMatrix(mat4(), lCircle.position.x, lCircle.position.y, 0), lCircle.rotationRadians);
+
+ // Render Code only
+ lProgramContext.gl.clearColor(0.0, 0.0, 0.0, 1.0);
+ lProgramContext.gl.clearDepth(1.0);
+ lProgramContext.gl.enable(lProgramContext.gl.DEPTH_TEST);
+ lProgramContext.gl.depthFunc(lProgramContext.gl.LEQUAL);
+ lProgramContext.gl.clear(lProgramContext.gl.COLOR_BUFFER_BIT | lProgramContext.gl.DEPTH_BUFFER_BIT);
+
+ lProgramContext.gl.useProgram(pProgramInfo.program);
+ lProgramContext.gl.uniformMatrix4fv(pProgramInfo.uniformLocations.projection, false, lProgramContext.perspective);
+ lProgramContext.gl.uniformMatrix4fv(pProgramInfo.uniformLocations.model, false, lCircle.model);
+
+ renderCircle(lProgramContext.gl, pProgramInfo, lCircle);
+ }
+
+ const TORQUE_MULTIPLIER = 100.0; // TODO: This may be unncessary
+
+ function applyForce(pForceVector, pPointOfApplication) {
+ if (pPointOfApplication !== undefined) {
+ const lOriginToPointOfApp = subVec2(vec2(), pPointOfApplication), // The point of application is relative to the model (i.e. the center of the circle, not the scene)
+ lPerpVec = vec2(-lOriginToPointOfApp.y, lOriginToPointOfApp.x); // Retrieve the perpendicular vector
+
+ // Calculate the torque from the perp dot (T = r_perp . F)
+ lCircle.torque += TORQUE_MULTIPLIER * dot2(lPerpVec, pForceVector);
+ }
+
+ lCircle.force = addVec2(lCircle.force, pForceVector);
+ }
+
+ function cleanup() {
+ lProgramContext.gl.deleteBuffer(lCircle.buffer);
+ lProgramContext.gl.deleteProgram(pProgramInfo.program);
+ lProgramContext.gl.clearColor(0.0, 0.0, 0.0, 1.0);
+ lProgramContext.gl.clear(lProgramContext.gl.COLOR_BUFFER_BIT);
+ }
+
+ function reset() {
+ lExitRequestFunc();
+ lProgramContext.reset();
+ $('#rigidbody_2_force_submit_button').unbind('submit').submit(false);
+ }
+
+ const lExitRequestFunc = requestUpdateLoop(update, cleanup);
+ lProgramContext.stopButton.on('click', reset);
+ $('#rigidbody_2_force_submit_button').submit(function(pEv) {
+ pEv.preventDefault();
+ pEv.stopPropagation();
+
+ // Read in the force vector from the form
+ const lForceGroup = $('#rigidbody_2_force_input'),
+ lPositionGroup = $('#rigidbody_2_position_input');
+
+ let lForceVectorX = lForceGroup.find('.vec2_x_input').val(),
+ lForceVectorY = lForceGroup.find('.vec2_y_input').val();
+
+ if (lForceVectorX.length === 0) {
+ lForceVectorX = 0;
+ }
+
+ if (lForceVectorY.length === 0) {
+ lForceVectorY = 5000;
+ }
+
+ // Read in the point of application vector from the form
+ let lPositionGroupX = lPositionGroup.find('.vec2_x_input').val(),
+ lPositionGroupY = lPositionGroup.find('.vec2_y_input').val();
+
+ if (lPositionGroupX.length === 0) {
+ lPositionGroupX = -Math.sqrt(2) / 2;
+ }
+
+ if (lPositionGroupY.length === 0) {
+ lPositionGroupY = -Math.sqrt(2) / 2;
+ }
+
+ const lForceVector = vec2(Number(lForceVectorX), Number(lForceVectorY));
+ const lPointOfApplication = scaleVec2(normalize2(vec2(Number(lPositionGroupX), Number(lPositionGroupY))), lCircle.radius);
+
+ applyForce(lForceVector, lPointOfApplication);
+ });
+ });
+ }
+
+ lProgramContext.playButton.on('click', run);
+ $('#rigidbody_2_force_submit_button').submit(false);
+ }
+
+ $(document).ready(main);
+})() \ No newline at end of file