From f0d1398b0d1b1a7c5bd1d4e0b3488b7f1aa74364 Mon Sep 17 00:00:00 2001 From: Matthew Kosarek Date: Tue, 23 Feb 2021 19:39:16 -0500 Subject: Big rework of the directory structure to make it more orderly for my brain --- frontend/_rigidbody/2d/rigidbody_2.js | 146 ++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 frontend/_rigidbody/2d/rigidbody_2.js (limited to 'frontend/_rigidbody/2d/rigidbody_2.js') diff --git a/frontend/_rigidbody/2d/rigidbody_2.js b/frontend/_rigidbody/2d/rigidbody_2.js new file mode 100644 index 0000000..4632b11 --- /dev/null +++ b/frontend/_rigidbody/2d/rigidbody_2.js @@ -0,0 +1,146 @@ +/// +/// +/// +/// +/// +/// + +(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 -- cgit v1.2.1