summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Kosarek <mattkae@protonmail.com>2021-02-07 19:22:56 -0500
committerMatthew Kosarek <mattkae@protonmail.com>2021-02-07 19:22:56 -0500
commitcc6d3871008a89fcf48814596d7bfec05f2706e4 (patch)
tree993ce66cc5a3c96841dc52fea60df873ff2f3469
parent376e1a7f9207fffb1ec3027ac1e7f32db5de4922 (diff)
Added rotational dynamics to the examples
-rw-r--r--frontend/_rigidbody/circle.js2
-rw-r--r--frontend/_rigidbody/rigidbody_1.js10
-rw-r--r--frontend/_rigidbody/rigidbody_2.js77
-rw-r--r--frontend/index.css11
-rw-r--r--frontend/rigidbody.html25
5 files changed, 111 insertions, 14 deletions
diff --git a/frontend/_rigidbody/circle.js b/frontend/_rigidbody/circle.js
index c044597..194a772 100644
--- a/frontend/_rigidbody/circle.js
+++ b/frontend/_rigidbody/circle.js
@@ -33,7 +33,9 @@ function circle(pGl, pRadius, pSegments, pColorList, pInitialPosition) {
position: pInitialPosition || vec2(),
velocity: vec2(),
force: vec2(),
+ torque: 0,
mass: 1,
+ rotationVelocity: 0,
rotationRadians: 0,
model: mat4(),
radius: pRadius
diff --git a/frontend/_rigidbody/rigidbody_1.js b/frontend/_rigidbody/rigidbody_1.js
index 5021162..c5e4f0a 100644
--- a/frontend/_rigidbody/rigidbody_1.js
+++ b/frontend/_rigidbody/rigidbody_1.js
@@ -72,9 +72,17 @@ function main() {
ev.preventDefault();
ev.stopPropagation();
- const lXValue = $(this).find('.vec2_x_input').val(),
+ let lXValue = $(this).find('.vec2_x_input').val(),
lYValue = $(this).find('.vec2_y_input').val();
+ if (lXValue.length === 0) {
+ lXValue = 0;
+ }
+
+ if (lYValue.length === 0) {
+ lYValue = 5000;
+ }
+
console.log('Applying force: ' + lXValue + ', ' + lYValue);
lCircle.force = addVec2(lCircle.force, vec2(Number(lXValue), Number(lYValue)));
}
diff --git a/frontend/_rigidbody/rigidbody_2.js b/frontend/_rigidbody/rigidbody_2.js
index b41fa92..c41461e 100644
--- a/frontend/_rigidbody/rigidbody_2.js
+++ b/frontend/_rigidbody/rigidbody_2.js
@@ -24,23 +24,29 @@ function main() {
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));
+ { 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 previously
- const lGravityForce = vec2(0, -1.0 * (lCircle.mass * GRAVITY));
- lCircle.force = addVec2(lCircle.force, lGravityForce);
+ 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.rotationRadians += Math.PI * pDeltaTimeSeconds;
- lCircle.model = rotateMatrix2d(translateMatrix(mat4(), lCircle.position.x, lCircle.position.y, 0), lCircle.rotationRadians);
lCircle.force = vec2();
+ // Calculate rotation
+ const lMomentOfInertia = getMomentOfInertia(lCircle);
+ const lAngularAcceleration = lCircle.torque / lMomentOfInertia;
+
+ lCircle.rotationVelocity += lAngularAcceleration * pDeltaTimeSeconds;
+ lCircle.rotationRadians += lCircle.rotationVelocity * pDeltaTimeSeconds;
+ lCircle.model = rotateMatrix2d(translateMatrix(mat4(), lCircle.position.x, lCircle.position.y, 0), lCircle.rotationRadians);
+ lCircle.torque = 0;
+
// Render Code only
lProgramContext.gl.clearColor(0.0, 0.0, 0.0, 1.0);
lProgramContext.gl.clearDepth(1.0);
@@ -55,6 +61,19 @@ function main() {
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);
+
+ 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);
@@ -65,14 +84,52 @@ function main() {
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
diff --git a/frontend/index.css b/frontend/index.css
index 9139963..a718784 100644
--- a/frontend/index.css
+++ b/frontend/index.css
@@ -89,6 +89,8 @@ section > p {
Helpful inputs
*/
.vec2_input_group {
+ position: relative;
+ margin-top: 1rem;
display: flex;
flex-direction: row;
width: 100%;
@@ -96,6 +98,15 @@ section > p {
padding: 0.25rem;
}
+.vec2_input_group > label {
+ position: absolute;
+ top: -1rem;
+ left: 0rem;
+ font-size: 0.8rem;
+ font-weight: bold;
+ text-align: left;
+}
+
.vec2_input_group > input {
width: 45%;
}
diff --git a/frontend/rigidbody.html b/frontend/rigidbody.html
index 510c667..2cc32b7 100644
--- a/frontend/rigidbody.html
+++ b/frontend/rigidbody.html
@@ -113,8 +113,9 @@
</ul>
<form id="rigidbody_1_force_submit_button" style="text-align: right; padding: 0.5rem;">
<div class="vec2_input_group">
- <input class="vec2_x_input" type="number" value="0"/>
- <input class="vec2_y_input" type="number" value="5000"/>
+ <label>Force Vector</label>
+ <input class="vec2_x_input" type="number" placeholder="X (Default 0)"/>
+ <input class="vec2_y_input" type="number" placeholder="Y (Default 5000 N)"/>
</div>
<input type="submit" value="Apply Force"></input>
</form>
@@ -135,7 +136,25 @@
<div id="rigidbody_2" class="opengl_canvas_container">
<canvas width="640" height="480"></canvas>
<div class="opengl_canvas_sidebar">
-
+ <ul class="opengl_value_tracker">
+ <li><b>Force:</b><span id="rigidbody_1_force_field">N/A</span></li>
+ <li><b>Acceleration:</b><span id="rigidbody_2_acceleration_field">N/A</span></li>
+ <li><b>Velocity:</b><span id="rigidbody_2_velocity_field">N/A</span></li>
+ <li><b>Position:</b><span id="rigidbody_2_position_field">N/A</span></li>
+ </ul>
+ <form id="rigidbody_2_force_submit_button" style="text-align: right; padding: 0.5rem;">
+ <div id="rigidbody_2_force_input" class="vec2_input_group">
+ <label>Force Vector</label>
+ <input class="vec2_x_input" type="number" placeholder="X (Default 0)"/>
+ <input class="vec2_y_input" type="number" placeholder="Y (Default 5000 N)"/>
+ </div>
+ <div id="rigidbody_2_position_input" class="vec2_input_group">
+ <label>Point of Application (Unit Vector)</label>
+ <input class="vec2_x_input" type="number" placeholder="X (Default 2 Root 2)"/>
+ <input class="vec2_y_input" type="number" placeholder="Y (Default 2 Root 2)"/>
+ </div>
+ <input type="submit" value="Apply Force"></input>
+ </form>
</div>
<button class="play_button">
Play