summaryrefslogtreecommitdiff
path: root/frontend/2d/_collisions
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/2d/_collisions')
-rw-r--r--frontend/2d/_collisions/collisions_1.js125
-rw-r--r--frontend/2d/_collisions/part_1.html63
2 files changed, 188 insertions, 0 deletions
diff --git a/frontend/2d/_collisions/collisions_1.js b/frontend/2d/_collisions/collisions_1.js
new file mode 100644
index 0000000..ac325c2
--- /dev/null
+++ b/frontend/2d/_collisions/collisions_1.js
@@ -0,0 +1,125 @@
+/// <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/math/line2.js" />
+/// <reference path="../../_shared/math/collision.js" />
+/// <reference path="../../_shared/2d/program_common.js" />
+
+(function() {
+
+ function main() {
+ // Define Constants
+ const CIRCLE_RADIUS = 16;
+ const GRAVITY = 9.8;
+ const COF_OF_RESTITUITION = 0.7;
+
+ // Retrieve context
+ const lProgramContext = getContext('#collision_1');
+
+ 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 Circle-Line Collisions');
+ lProgramContext.load().then(function(pProgramInfo) {
+ const mCircle = circle(lProgramContext.gl, CIRCLE_RADIUS, 30, [
+ { x: 1, y: 0, z: 0, w: 1 },
+ { x: 0, y: 1, z: 0, w: 1 },
+ { x: 0, y: 0, z: 1, w: 1 }
+ ], vec2(lProgramContext.width / 2.0, lProgramContext.height / 2.0 + 100));
+
+ const mline = line2({ x: 100, y: 100 }, { x: lProgramContext.width - 100, y: 200 }, lProgramContext.gl,
+ { x: 1, y: 0, z: 0, w: 1 }, 2.0);
+
+ /**
+ * Run the update method of a single circle
+ *
+ * @param {circle} pCircle
+ * @param {number} pDeltaTimeSeconds
+ */
+ function updateCircle(pCircle, pDeltaTimeSeconds) {
+ // Same physics updates from part 1
+ applyForce(pCircle, vec2(0, -1.0 * (pCircle.mass * GRAVITY)));
+ const lCurrentAcceleration = scaleVec2(pCircle.force, 1.0 / pCircle.mass);
+ pCircle.prevVelocity = pCircle.velocity;
+ pCircle.velocity = addVec2(pCircle.velocity, scaleVec2(lCurrentAcceleration, pDeltaTimeSeconds));
+ pCircle.prevPos = { ...pCircle.position };
+ pCircle.position = addVec2(pCircle.position, scaleVec2(pCircle.velocity, pDeltaTimeSeconds));
+ pCircle.force = vec2();
+
+ // Same physics updates from part 2
+ const lMomentOfInertia = getMomentOfInertia(pCircle);
+ const lAngularAcceleration = pCircle.torque / lMomentOfInertia;
+ pCircle.rotationVelocity += lAngularAcceleration * pDeltaTimeSeconds;
+ pCircle.rotationRadians += pCircle.rotationVelocity * pDeltaTimeSeconds;
+ pCircle.torque = 0;
+
+ pCircle.model = rotateMatrix2d(translateMatrix(mat4(), pCircle.position.x, pCircle.position.y, 0), pCircle.rotationRadians);
+ }
+
+ function update(pDeltaTimeSeconds) {
+ pDeltaTimeSeconds = pDeltaTimeSeconds;
+ updateCircle(mCircle, pDeltaTimeSeconds);
+ collision(pDeltaTimeSeconds);
+ render();
+ }
+
+ function collision(pDeltaTimeSeconds) {
+ lineCircleCollision2(mCircle, mline);
+ return false;
+ }
+
+ function render() {
+ 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);
+
+ renderCircle(lProgramContext.gl, pProgramInfo, mCircle);
+ renderLine2(lProgramContext.gl, pProgramInfo, mline);
+ }
+
+ const TORQUE_MULTIPLIER = 100.0; // TODO: This may be unncessary
+ function applyForce(pCircle, pForceVector, pPointOfApplication) {
+ if (pPointOfApplication !== undefined) {
+ const lOriginToPointOfApp = subVec2(vec2(), pPointOfApplication),
+ lPerpVec = vec2(-lOriginToPointOfApp.y, lOriginToPointOfApp.x);
+
+ pCircle.torque += TORQUE_MULTIPLIER * dot2(lPerpVec, pForceVector);
+ }
+
+ pCircle.force = addVec2(pCircle.force, pForceVector);
+ }
+
+ function cleanup() {
+ lProgramContext.gl.deleteBuffer(mCircle.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();
+ }
+
+ const lExitRequestFunc = requestUpdateLoop(update, cleanup);
+ lProgramContext.stopButton.on('click', reset);
+ });
+ }
+
+ lProgramContext.playButton.on('click', run);
+ }
+
+ $(document).ready(main);
+})() \ No newline at end of file
diff --git a/frontend/2d/_collisions/part_1.html b/frontend/2d/_collisions/part_1.html
new file mode 100644
index 0000000..06a4b3d
--- /dev/null
+++ b/frontend/2d/_collisions/part_1.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <script src="/scripts/jquery-3.5.1.min.js"></script>
+ <script src="/index.js"></script>
+ <link rel="stylesheet" href="/index.css">
+ <link rel="shortcut icon" href="/favicon/favicon.ico" type="image/x-icon">
+ <link href="https://fonts.googleapis.com/css?family=Open+Sans:400,600,300" rel="stylesheet" type="text/css">
+ <title>Physics for Games</title>
+
+ <script src="/_shared/math/vec2.js"></script>
+ <script src="/_shared/math/mat4.js"></script>
+ <script src="/_shared/math/circle.js"></script>
+ <script src="/_shared/math/line2.js"></script>
+ <script src="/_shared/math/collision.js"></script>
+ <script src="/_shared/2d/shader.js"></script>
+ <script src="/_shared/2d/program_common.js"></script>
+ <script src="collisions_1.js"></script>
+ </head>
+ <body>
+ <header>
+ <h1>Physics for Games</h1>
+ </header>
+ <main>
+ <nav>
+ </nav>
+ <section>
+ <h1>Part 1: Circle-Line</h1>
+ <article>
+ <p>
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+ </p>
+ <div id="collision_1" class="opengl_canvas_container">
+ <canvas width="640" height="480"></canvas>
+ <div class="opengl_canvas_sidebar">
+ <ul class="opengl_value_tracker">
+ <li><b>Linear Force:</b><span id="rigidbody_1_force_field">N/A</span></li>
+ <li><b>Linear Acceleration:</b><span id="rigidbody_1_acceleration_field">N/A</span></li>
+ <li><b>Linear Velocity:</b><span id="rigidbody_1_velocity_field">N/A</span></li>
+ <li><b>Linear Position:</b><span id="rigidbody_1_position_field">N/A</span></li>
+ </ul>
+ <form id="rigidbody_1_force_submit_button" style="text-align: right; padding: 0.5rem;">
+ <div 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>
+ <input type="submit" value="Apply Force"></input>
+ </form>
+ </div>
+ <button class="play_button">
+ Play
+ </button>
+ <button class="stop_button">
+ Stop
+ </button>
+ </div>
+ </article>
+ </section>
+ </main>
+ </body>
+</html> \ No newline at end of file