diff options
author | Matthew Kosarek <matthew.kosarek@vention.cc> | 2021-02-25 20:50:12 -0500 |
---|---|---|
committer | Matthew Kosarek <matthew.kosarek@vention.cc> | 2021-02-25 20:50:12 -0500 |
commit | 026abdb98ad30209df0e88795f25b1f74556585e (patch) | |
tree | 39c7e60ea78331ada41fc71bc5f6e5b91b5fd75c | |
parent | f0d1398b0d1b1a7c5bd1d4e0b3488b7f1aa74364 (diff) |
Updated the sidebar for usability's sake
-rw-r--r-- | frontend/2d/_collisions/collisions_1.js | 125 | ||||
-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.js | 0 | ||||
-rw-r--r-- | frontend/_shared/math/collision.js | 23 | ||||
-rw-r--r-- | frontend/_shared/math/line2.js | 49 | ||||
-rw-r--r-- | frontend/index.css | 62 | ||||
-rw-r--r-- | frontend/index.js | 25 | ||||
-rw-r--r-- | frontend/navbar.html | 23 |
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>▲</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>▲</i>3D</span> </li> </ul>
\ No newline at end of file |