summaryrefslogtreecommitdiff
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
parentf0d1398b0d1b1a7c5bd1d4e0b3488b7f1aa74364 (diff)
Updated the sidebar for usability's sake
-rw-r--r--frontend/2d/_collisions/collisions_1.js125
-rw-r--r--frontend/2d/_collisions/part_1.html (renamed from frontend/_collisions/2d/part_1.html)2
-rw-r--r--frontend/2d/_rigidbody/part_1.html (renamed from frontend/_rigidbody/2d/part_1.html)0
-rw-r--r--frontend/2d/_rigidbody/part_2.html (renamed from frontend/_rigidbody/2d/part_2.html)0
-rw-r--r--frontend/2d/_rigidbody/part_3.html (renamed from frontend/_rigidbody/2d/part_3.html)0
-rw-r--r--frontend/2d/_rigidbody/rigidbody_1.js (renamed from frontend/_rigidbody/2d/rigidbody_1.js)0
-rw-r--r--frontend/2d/_rigidbody/rigidbody_2.js (renamed from frontend/_rigidbody/2d/rigidbody_2.js)0
-rw-r--r--frontend/2d/_rigidbody/rigidbody_3a.js (renamed from frontend/_rigidbody/2d/rigidbody_3a.js)0
-rw-r--r--frontend/2d/_rigidbody/rigidbody_3b.js (renamed from frontend/_rigidbody/2d/rigidbody_3b.js)0
-rw-r--r--frontend/_collisions/2d/collisions_1.js0
-rw-r--r--frontend/_shared/math/collision.js23
-rw-r--r--frontend/_shared/math/line2.js49
-rw-r--r--frontend/index.css62
-rw-r--r--frontend/index.js25
-rw-r--r--frontend/navbar.html23
15 files changed, 288 insertions, 21 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/_collisions/2d/part_1.html b/frontend/2d/_collisions/part_1.html
index ab60b17..06a4b3d 100644
--- a/frontend/_collisions/2d/part_1.html
+++ b/frontend/2d/_collisions/part_1.html
@@ -12,6 +12,8 @@
<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>
diff --git a/frontend/_rigidbody/2d/part_1.html b/frontend/2d/_rigidbody/part_1.html
index ec0acbf..ec0acbf 100644
--- a/frontend/_rigidbody/2d/part_1.html
+++ b/frontend/2d/_rigidbody/part_1.html
diff --git a/frontend/_rigidbody/2d/part_2.html b/frontend/2d/_rigidbody/part_2.html
index 0291290..0291290 100644
--- a/frontend/_rigidbody/2d/part_2.html
+++ b/frontend/2d/_rigidbody/part_2.html
diff --git a/frontend/_rigidbody/2d/part_3.html b/frontend/2d/_rigidbody/part_3.html
index c1479da..c1479da 100644
--- a/frontend/_rigidbody/2d/part_3.html
+++ b/frontend/2d/_rigidbody/part_3.html
diff --git a/frontend/_rigidbody/2d/rigidbody_1.js b/frontend/2d/_rigidbody/rigidbody_1.js
index e49c7c9..e49c7c9 100644
--- a/frontend/_rigidbody/2d/rigidbody_1.js
+++ b/frontend/2d/_rigidbody/rigidbody_1.js
diff --git a/frontend/_rigidbody/2d/rigidbody_2.js b/frontend/2d/_rigidbody/rigidbody_2.js
index 4632b11..4632b11 100644
--- a/frontend/_rigidbody/2d/rigidbody_2.js
+++ b/frontend/2d/_rigidbody/rigidbody_2.js
diff --git a/frontend/_rigidbody/2d/rigidbody_3a.js b/frontend/2d/_rigidbody/rigidbody_3a.js
index d38f1da..d38f1da 100644
--- a/frontend/_rigidbody/2d/rigidbody_3a.js
+++ b/frontend/2d/_rigidbody/rigidbody_3a.js
diff --git a/frontend/_rigidbody/2d/rigidbody_3b.js b/frontend/2d/_rigidbody/rigidbody_3b.js
index 803161a..803161a 100644
--- a/frontend/_rigidbody/2d/rigidbody_3b.js
+++ b/frontend/2d/_rigidbody/rigidbody_3b.js
diff --git a/frontend/_collisions/2d/collisions_1.js b/frontend/_collisions/2d/collisions_1.js
deleted file mode 100644
index e69de29..0000000
--- a/frontend/_collisions/2d/collisions_1.js
+++ /dev/null
diff --git a/frontend/_shared/math/collision.js b/frontend/_shared/math/collision.js
new file mode 100644
index 0000000..74ec5d8
--- /dev/null
+++ b/frontend/_shared/math/collision.js
@@ -0,0 +1,23 @@
+/// <reference path="vec2.js" />
+/// <reference path="line2.js" />
+/// <reference path="circle.js" />
+/// <reference path="mat4.js" />
+
+/**
+ *
+ * @param {circle} pCricle
+ * @param {line2} pLine
+ */
+function lineCircleCollision2(pCricle, pLine) {
+ // We have a triangle formed by circle's position P and the two points of the line, A and B.
+ var lSlope = (pCricle.position.y - pLine.start.y) / (pCricle.position.x - pLine.start.x),
+ lAngle = Math.atan(lSlope),
+ lAngleDiff = lAngle - pLine.angle,
+ lPositionToStart = subVec2(pCricle.position, pLine.start),
+ lPosToStartLength = length2(lPositionToStart),
+ lHeight = lPosToStartLength * Math.sin(lAngleDiff);
+
+ if (Math.abs(lHeight - pCricle.radius) < pCricle.radius) {
+ console.log('Intersection');
+ }
+} \ No newline at end of file
diff --git a/frontend/_shared/math/line2.js b/frontend/_shared/math/line2.js
new file mode 100644
index 0000000..d8ab096
--- /dev/null
+++ b/frontend/_shared/math/line2.js
@@ -0,0 +1,49 @@
+/// <reference path="vec2.js" />
+/// <reference path="mat4.js" />
+
+/**
+ * Creates a new line object
+ * @param {vec2} pStart
+ * @param {vec2} pEnd
+ * @param {WebGLRenderingContext} pGl
+ */
+function line2(pStart, pEnd, pGl, pColor, pThickness) {
+ const lDiffVector = subVec2(pEnd, pStart);
+
+ const lBuffer = pGl.createBuffer();
+ pGl.bindBuffer(pGl.ARRAY_BUFFER, lBuffer);
+
+ var lBufferedData = [
+ pStart.x, pStart.y, pColor.x, pColor.y, pColor.z, pColor.w,
+ pEnd.x, pEnd.y, pColor.x, pColor.y, pColor.z, pColor.w
+ ];
+
+ pGl.bufferData(pGl.ARRAY_BUFFER, new Float32Array(lBufferedData), pGl.STATIC_DRAW)
+ pGl.bindBuffer(pGl.ARRAY_BUFFER, undefined);
+
+ var lSlope = (pEnd.y - pStart.y) / (pEnd.x - pStart.x);
+
+ return {
+ buffer: lBuffer,
+ start: pStart,
+ end: pEnd,
+ slope: lSlope,
+ angle: Math.atan(lSlope),
+ length: length2(lDiffVector),
+ direction: normalize2(lDiffVector)
+ };
+}
+
+function renderLine2(pGl, pProgramInfo, pLine) {
+ pGl.uniformMatrix4fv(pProgramInfo.uniformLocations.model, false, mat4()); // Model on a line is always default matrix
+ pGl.bindBuffer(pGl.ARRAY_BUFFER, pLine.buffer);
+ {
+ pGl.enableVertexAttribArray(pProgramInfo.attributeLocations.position);
+ pGl.vertexAttribPointer(pProgramInfo.attributeLocations.position, 2, pGl.FLOAT, false, BYTES_PER_FLOAT * 6, 0);
+
+ pGl.enableVertexAttribArray(pProgramInfo.attributeLocations.color);
+ pGl.vertexAttribPointer(pProgramInfo.attributeLocations.color, 4, pGl.FLOAT, false, BYTES_PER_FLOAT * 6, BYTES_PER_FLOAT * 2);
+ }
+
+ pGl.drawArrays(pGl.LINES, 0, 2);
+} \ No newline at end of file
diff --git a/frontend/index.css b/frontend/index.css
index 471f6f3..729768c 100644
--- a/frontend/index.css
+++ b/frontend/index.css
@@ -27,7 +27,7 @@ main {
display: flex;
flex-direction: row;
color: #1a1a1a;
- width: 1260px;
+ width: 1200px;
background-color: white;
flex: 1 1 100%;
height: 100%;
@@ -36,25 +36,73 @@ main {
}
section {
+ min-width: 74%;
+ width: 74%;
overflow-y: auto;
}
+/*
+ Navigation bar
+*/
nav {
- width: 25%;
+ width: 20%;
+ min-width: 20%;
+ max-width: 20%;
+ margin-right: 5%;
height: 100%;
display: flex;
flex-direction: column;
text-align: left;
font-size: 1rem;
+ user-select: none;
+ border-right: 1px solid black;;
}
-nav > ul {
+.outer-tree {
+ width: 100%;
list-style: none;
- padding-left: 0px;
+ padding: 0;
+ margin: 0;
+}
+
+.outer-tree > li > span {
+ display: block;
+ width: 100%;
+ cursor: pointer;
+ background: white;
+}
+
+.outer-tree > li > span:hover {
+ color: gray;
+}
+
+.outer-tree > li > span > i {
+ transition: 100ms ease-in-out transform;
+}
+
+.outer-tree li.expanded > span > i {
+ display: inline-block;
+ transform: rotate(180deg);
}
-nav > ul > li > ul {
+.inner-tree {
padding-left: 1rem;
+ display: none;
+ list-style: none;
+}
+
+.inner-tree > li > label {
+ color: blue;
+ font-weight: bold;
+ text-align: center;
+}
+
+.inner-tree > li > a {
+ margin-left: 0.5rem;
+}
+
+.outer-tree > li.expanded .inner-tree {
+ display: inherit;
}
nav a {
@@ -147,7 +195,7 @@ article .opengl_canvas_container .play_button {
height: 128px;
position: absolute;
top: calc(50% - 56px);
- left: calc(50% - 220px);
+ left: calc(50% - 184px);
border: 1px solid white;
color: white;
background-color: transparent;
@@ -172,7 +220,7 @@ article .opengl_canvas_container .stop_button {
height: 2rem;
border-radius: 2px;
top: 0.5rem;
- left: 536px;
+ left: 496px;
display: none;
}
diff --git a/frontend/index.js b/frontend/index.js
index d14ca95..b943463 100644
--- a/frontend/index.js
+++ b/frontend/index.js
@@ -6,8 +6,29 @@
$.get('/navbar.html', function(pData) {
$('nav').html(pData);
- const lPathName = window.location.pathname.length > 1 && window.location.pathname.startsWith('/') ? window.location.pathname.substr(1) : window.location.pathname;
- $('nav').find('a[href="' + lPathName + '"').addClass('nav-selected');
+ // Set selected tab as selected
+ $('nav').find('a').removeClass('nav-selected');
+ $('nav').find('a[href="' + window.location.pathname + '"').addClass('nav-selected');
+
+ // Set up tree callbacks
+ $('.outer-tree > li').click(function() {
+ $(this).toggleClass('expanded');
+ })
+
+ $('.inner-tree > li').click(function(pEv) {
+ pEv.stopPropagation();
+ })
+
+ // Open up the selected document from the navigation tree
+ var lSplitPath = window.location.pathname.split('/');
+ if (lSplitPath.length < 3) {
+ return;
+ }
+
+ if (lSplitPath[1] === '2d') {
+ $('nav > ul > li:first-child').addClass('expanded');
+ $('nav > ul > li:last-child').removeClass('expanded');
+ }
});
}
diff --git a/frontend/navbar.html b/frontend/navbar.html
index c55439b..73c4fd3 100644
--- a/frontend/navbar.html
+++ b/frontend/navbar.html
@@ -1,19 +1,18 @@
-<ul>
+<ul class="outer-tree">
<li>
- <span>Rigidbody</span>
- <ul>
- <li><a href="/">Introduction</a></li>
- <li><a href="/_rigidbody/2d/part_1.html">2D - Linear Forces</a></li>
- <li><a href="/_rigidbody/2d/part_2.html">2D - Rotational Forces</a></li>
- <li><a href="/_rigidbody/2d/part_3.html">2D - Collision Forces</a></li>
+ <span><i>&#9650;</i>2D</span>
+ <ul class="inner-tree">
+ <li><label>Rigidbody</label></li>
+ <li><a href="/" class="nav-selected">Introduction</a></li>
+ <li><a href="/2d/_rigidbody/part_1.html">2D - Linear Forces</a></li>
+ <li><a href="/2d/_rigidbody/part_2.html">2D - Rotational Forces</a></li>
+ <li><a href="/2d/_rigidbody/part_3.html">2D - Collision Forces</a></li>
+ <li><label>Collisions</label></li>
+ <li><a href="/2d/_collisions/part_1.html">Circle-Line</a></li>
</ul>
</li>
-
<li>
- <span>Collisions</span>
- <ul>
- <li><a href="/_collisions/2d/part_1.html">Circle-Line</a></li>
- </ul>
+ <span><i>&#9650;</i>3D</span>
</li>
</ul> \ No newline at end of file