From 76b6fa0ce8cfaaab8e2052bdd43266ded8e404b6 Mon Sep 17 00:00:00 2001 From: Matthew Kosarek Date: Tue, 25 May 2021 20:58:53 -0400 Subject: Finally able to remove all of those unneeded javascript files --- 2d/_collisions/circle_line.html | 51 --------- 2d/_collisions/circle_line.js | 179 -------------------------------- 2d/_collisions/pill_line.html | 1 - 2d/_collisions/pill_pill.html | 1 - 2d/_collisions/polygon_polygon.html | 1 - 2d/_collisions/rectangle_line.html | 1 - 2d/_collisions/rectangle_rectangle.html | 1 - 2d/rigidbody/rigidbody_1.html | 1 - _shared/2d/program_common.js | 75 ------------- _shared/2d/shader.js | 76 -------------- _shared/2d/shaders/orthographic.frag | 5 - _shared/2d/shaders/orthographic.vert | 13 --- _shared/math/circle.js | 112 -------------------- _shared/math/collision.js | 26 ----- _shared/math/line2.js | 63 ----------- _shared/math/mat4.js | 63 ----------- _shared/math/point2.js | 16 --- _shared/math/rectangle.js | 32 ------ _shared/math/rigidbody2.js | 57 ---------- _shared/math/vec2.js | 64 ------------ index.html | 1 - roadmap.html | 8 +- roadmap.html.content | 7 +- scripts/jquery-3.5.1.min.js | 1 - transpiler/pages.txt | 1 - 25 files changed, 8 insertions(+), 848 deletions(-) delete mode 100644 2d/_collisions/circle_line.html delete mode 100644 2d/_collisions/circle_line.js delete mode 100644 _shared/2d/program_common.js delete mode 100644 _shared/2d/shader.js delete mode 100644 _shared/2d/shaders/orthographic.frag delete mode 100644 _shared/2d/shaders/orthographic.vert delete mode 100644 _shared/math/circle.js delete mode 100644 _shared/math/collision.js delete mode 100644 _shared/math/line2.js delete mode 100644 _shared/math/mat4.js delete mode 100644 _shared/math/point2.js delete mode 100644 _shared/math/rectangle.js delete mode 100644 _shared/math/rigidbody2.js delete mode 100644 _shared/math/vec2.js delete mode 100644 scripts/jquery-3.5.1.min.js diff --git a/2d/_collisions/circle_line.html b/2d/_collisions/circle_line.html deleted file mode 100644 index 791d1ed..0000000 --- a/2d/_collisions/circle_line.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - - Physics for Games - - - - - - - - - - - - -
-

Physics for Games

-
-
- -
-

Circle-Line

-
-

- 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. -

-
- -
- -
- - -
-
-
-
- - \ No newline at end of file diff --git a/2d/_collisions/circle_line.js b/2d/_collisions/circle_line.js deleted file mode 100644 index 0736e2c..0000000 --- a/2d/_collisions/circle_line.js +++ /dev/null @@ -1,179 +0,0 @@ -/// -/// -/// -/// -/// -/// -/// -/// - -(function() { - // Define Constants - const CIRCLE_RADIUS = 16; - const GRAVITY = 20.0; - const COF_OF_RESTITUITION = 0.75; - const TORQUE_MULTIPLIER = 100.0; // TODO: This may be unncessary - - var programContext, - circleObject, - lineObjectList, - programInfo, - exitRequestFunc; - - function main() { - programContext = getContext('#circle_line_collision'); - - if (programContext.gl === null) { - console.error('Unable to initialize WebGL. Your browser or machine may not support it.'); - return; - } - - programContext.gl.clearColor(0.1, 0.15, 0.2, 1.0); - programContext.gl.clear(programContext.gl.COLOR_BUFFER_BIT); - programContext.playButton.on('click', run); - } - - function run() { - console.log('Running Circle-Line Collisions'); - programContext.load().then(function(pProgramInfo) { - programInfo = pProgramInfo; - circleObject = circle(programContext.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(programContext.width * (3.0 / 4.0), programContext.height / 2.0 + 100)); - - circleObject.velocity = vec2(0, -50); - - lineObjectList = []; - - lineObjectList.push(line2({ x: 100, y: 100 }, { x: programContext.width - 100, y: 200 }, programContext.gl, - { x: 1, y: 0, z: 0, w: 1 }, 2.0)); - - lineObjectList.push(line2({ x: 100, y: 200 }, { x: programContext.width - 100, y: 100 }, programContext.gl, - { x: 1, y: 1, z: 0, w: 1 }, 2.0)); - - lineObjectList.push(line2({ x: 100, y: 0 }, { x: 100, y: programContext.height }, programContext.gl, - { x: 0, y: 1, z: 0, w: 1 }, 2.0)); - - lineObjectList.push(line2({ x: programContext.width - 100, y: 0 }, { x: programContext.width - 100, y: programContext.height }, programContext.gl, - { x: 0, y: 1, z: 0, w: 1 }, 2.0)); - - - exitRequestFunc = requestUpdateLoop(update, cleanup); - programContext.stopButton.on('click', reset); - }); - } - - function update(pDeltaTimeSeconds) { - pDeltaTimeSeconds = pDeltaTimeSeconds; - updateCircle(circleObject, pDeltaTimeSeconds); - collision(pDeltaTimeSeconds); - render(); - } - - function updateCircle(pCircle, pDeltaTimeSeconds) { - 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(); - - const lMomentOfInertia = getCircleMomentOfInertia(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 collision(pDeltaTimeSeconds) { - lineObjectList.forEach(function(lineObject) { - if (!lineCircleCollision2(circleObject, lineObject)) { - return; - } - - var lSubdividedDeltaTime = pDeltaTimeSeconds, - lSubdividedCircle = undefined; - - do { - lSubdividedCircle = JSON.parse(JSON.stringify(circleObject)); - lSubdividedCircle.position = {...circleObject.prevPos}; - lSubdividedCircle.velocity = {...circleObject.prevVelocity}; - lSubdividedDeltaTime = lSubdividedDeltaTime / 2.0; - updateCircle(lSubdividedCircle, lSubdividedDeltaTime); - if (lSubdividedDeltaTime === 0) { - console.error('This should NOT be happening'); - break; - } - } while (lineCircleCollision2(lSubdividedCircle, lineObject)) - - const lIntersectionResult = getLineCircleCollison2Data(lSubdividedCircle, lineObject), - lRelativeVelocity = lIntersectionResult.relativeVelocity, - lCollisionNormal = lIntersectionResult.collisionNormal, - lFirstPerp = getPerp2(lIntersectionResult.firstPointOfApplication), - lSecondPerp = getPerp2(lIntersectionResult.secondPointOfApplication); - - const lNumerator = dot2(scaleVec2(lRelativeVelocity, -(1.0 + COF_OF_RESTITUITION)), lCollisionNormal); - const lLinearDenomPart = dot2(lCollisionNormal, (scaleVec2(lCollisionNormal, 1 / circleObject.mass))); - const lRotationalDenomPart = (Math.pow(dot2(lFirstPerp, lCollisionNormal), 2) / getCircleMomentOfInertia(circleObject)); - - const lImpulseMagnitude = lNumerator / (lLinearDenomPart + lRotationalDenomPart); - - circleObject.position = lSubdividedCircle.position; - circleObject.velocity = addVec2(lSubdividedCircle.velocity, scaleVec2(lCollisionNormal, lImpulseMagnitude / circleObject.mass)); - circleObject.rotationVelocity = lSubdividedCircle.rotationVelocity - + dot2(lFirstPerp, scaleVec2(lCollisionNormal, lImpulseMagnitude)) / getCircleMomentOfInertia(circleObject); - - updateCircle(circleObject, pDeltaTimeSeconds - lSubdividedDeltaTime); - - return; - }) - } - - 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 render() { - programContext.gl.clearColor(0.1, 0.15, 0.2, 1.0); - programContext.gl.clearDepth(1.0); - programContext.gl.enable(programContext.gl.DEPTH_TEST); - programContext.gl.depthFunc(programContext.gl.LEQUAL); - programContext.gl.clear(programContext.gl.COLOR_BUFFER_BIT | programContext.gl.DEPTH_BUFFER_BIT); - programContext.gl.useProgram(programInfo.program); - programContext.gl.uniformMatrix4fv(programInfo.uniformLocations.projection, false, programContext.perspective); - - renderCircle(programContext.gl, programInfo, circleObject); - lineObjectList.forEach(function(lineObject) { - renderLine2(programContext.gl, programInfo, lineObject); - }); - } - - function cleanup() { - programContext.gl.deleteBuffer(circleObject.buffer); - lineObjectList.forEach(function(lineObject) { - programContext.gl.deleteBuffer(lineObject.buffer); - }); - programContext.gl.deleteProgram(programInfo.program); - programContext.gl.clearColor(0.1, 0.15, 0.2, 1.0); - programContext.gl.clear(programContext.gl.COLOR_BUFFER_BIT); - } - - function reset() { - exitRequestFunc(); - programContext.reset(); - } - - $(document).ready(main); -})() \ No newline at end of file diff --git a/2d/_collisions/pill_line.html b/2d/_collisions/pill_line.html index fbe9251..de96b37 100644 --- a/2d/_collisions/pill_line.html +++ b/2d/_collisions/pill_line.html @@ -20,7 +20,6 @@
  • Linear Forces
  • -
  • Circle-Line
  • Rectangle-Line
  • Rectangle-Rectangle
  • Pill-Line
  • diff --git a/2d/_collisions/pill_pill.html b/2d/_collisions/pill_pill.html index b8fa01c..2d47542 100644 --- a/2d/_collisions/pill_pill.html +++ b/2d/_collisions/pill_pill.html @@ -20,7 +20,6 @@
  • Linear Forces
  • -
  • Circle-Line
  • Rectangle-Line
  • Rectangle-Rectangle
  • Pill-Line
  • diff --git a/2d/_collisions/polygon_polygon.html b/2d/_collisions/polygon_polygon.html index 44496fb..1bdb759 100644 --- a/2d/_collisions/polygon_polygon.html +++ b/2d/_collisions/polygon_polygon.html @@ -20,7 +20,6 @@
  • Linear Forces
  • -
  • Circle-Line
  • Rectangle-Line
  • Rectangle-Rectangle
  • Pill-Line
  • diff --git a/2d/_collisions/rectangle_line.html b/2d/_collisions/rectangle_line.html index e9720d1..bb5d1e8 100644 --- a/2d/_collisions/rectangle_line.html +++ b/2d/_collisions/rectangle_line.html @@ -20,7 +20,6 @@
  • Linear Forces
  • -
  • Circle-Line
  • Rectangle-Line
  • Rectangle-Rectangle
  • Pill-Line
  • diff --git a/2d/_collisions/rectangle_rectangle.html b/2d/_collisions/rectangle_rectangle.html index cfa2810..3c4e80e 100644 --- a/2d/_collisions/rectangle_rectangle.html +++ b/2d/_collisions/rectangle_rectangle.html @@ -20,7 +20,6 @@
  • Linear Forces
  • -
  • Circle-Line
  • Rectangle-Line
  • Rectangle-Rectangle
  • Pill-Line
  • diff --git a/2d/rigidbody/rigidbody_1.html b/2d/rigidbody/rigidbody_1.html index 83cc237..aba12e9 100644 --- a/2d/rigidbody/rigidbody_1.html +++ b/2d/rigidbody/rigidbody_1.html @@ -20,7 +20,6 @@
  • Linear Forces
  • -
  • Circle-Line
  • Rectangle-Line
  • Rectangle-Rectangle
  • Pill-Line
  • diff --git a/_shared/2d/program_common.js b/_shared/2d/program_common.js deleted file mode 100644 index 48d0a6b..0000000 --- a/_shared/2d/program_common.js +++ /dev/null @@ -1,75 +0,0 @@ -/// -/// - -function getContext(pId, pOnRun) { - const lCanvas = $(pId).find('canvas'), - lPlayButton = $(pId).find('.play_button'), - lStopButton = $(pId).find('.stop_button'), - lGl = lCanvas[0].getContext('webgl'), - lWidth = lCanvas.width(), - lHeight = lCanvas.height(); - - return { - canvas: lCanvas, - playButton: lPlayButton, - stopButton: lStopButton, - gl: lGl, - width: lWidth, - height: lHeight, - perspective: orthographic(0, lWidth, 0, lHeight), - load: function() { - lPlayButton.empty().append($('
    ').addClass('spin-loader')); - return loadOrthographicShader(lGl).then(function(pProgramInfo) { - lPlayButton.css('display', 'none'); - lStopButton.css('display', 'block'); - return pProgramInfo; - }); - }, - reset: function() { - lPlayButton.css('display', 'block'); - lPlayButton.empty().text('Play'); - lStopButton.css('display', 'none'); - lStopButton.on('click', undefined); - } - }; -} - -function requestUpdateLoop(pFunction, pOnExit) { - let lDeltaTimeSeconds = undefined, - lLastTimeSeconds = undefined, - lIsRunning = true; - - function update(pTimeStamp) { - if (!lIsRunning) { - if (pOnExit) { - pOnExit(); - } - return; - } - - pTimeStamp = pTimeStamp / 1000.0; // Convert to seconds - - // Time calculation - if (lLastTimeSeconds === undefined) { - lLastTimeSeconds = pTimeStamp; - lDeltaTimeSeconds = 0; - } else { - lDeltaTimeSeconds = pTimeStamp - lLastTimeSeconds; - lLastTimeSeconds = pTimeStamp; - } - - while (lDeltaTimeSeconds > 0) { - pFunction(lDeltaTimeSeconds); - lDeltaTimeSeconds -= 0.16; - } - requestAnimationFrame(update); - } - - requestAnimationFrame(update); - - function lExit() { - lIsRunning = false; - } - - return lExit; -} \ No newline at end of file diff --git a/_shared/2d/shader.js b/_shared/2d/shader.js deleted file mode 100644 index 7e85a9e..0000000 --- a/_shared/2d/shader.js +++ /dev/null @@ -1,76 +0,0 @@ -function loadShader(pGl, pShaderType, pShaderSource) { - const lShader = pGl.createShader(pShaderType); - pGl.shaderSource(lShader, pShaderSource); - pGl.compileShader(lShader); - if (!pGl.getShaderParameter(lShader, pGl.COMPILE_STATUS)) { - alert('An error occurred compiling the shaders: ' + pGl.getShaderInfoLog(lShader)); - pGl.deleteShader(lShader); - return null; - } - - return lShader; -} - -function loadOrthographicShader(pGl) { - var lVertex, lFragment; - - function lLoadShaders() { - const lVertexShader = loadShader(pGl, pGl.VERTEX_SHADER, lVertex); - const lFragmentShader = loadShader(pGl, pGl.FRAGMENT_SHADER, lFragment); - - const lShaderProgram = pGl.createProgram(); - pGl.attachShader(lShaderProgram, lVertexShader); - pGl.attachShader(lShaderProgram, lFragmentShader); - pGl.linkProgram(lShaderProgram); - - if (!pGl.getProgramParameter(lShaderProgram, pGl.LINK_STATUS)) { - alert('Unable to initialize the shader program: ' + pGl.getProgramInfoLog(lShaderProgram)); - return null; - } - - var lRetval = { - program: lShaderProgram, - attributeLocations: { - position: pGl.getAttribLocation(lShaderProgram, 'position'), - color: pGl.getAttribLocation(lShaderProgram, 'color') - }, - uniformLocations: { - projection: pGl.getUniformLocation(lShaderProgram, 'projection'), - model: pGl.getUniformLocation(lShaderProgram, 'model') - } - }; - - lRetval.renderShape = function(pShape) { - pGl.uniformMatrix4fv(lRetval.uniformLocations.model, false, pShape.model); - pGl.bindBuffer(pGl.ARRAY_BUFFER, pShape.buffer); - { - pGl.enableVertexAttribArray(lRetval.attributeLocations.position); - pGl.vertexAttribPointer(lRetval.attributeLocations.position, 2, pGl.FLOAT, false, BYTES_PER_FLOAT * 6, 0); - - pGl.enableVertexAttribArray(lRetval.attributeLocations.color); - pGl.vertexAttribPointer(lRetval.attributeLocations.color, 4, pGl.FLOAT, false, BYTES_PER_FLOAT * 6, BYTES_PER_FLOAT * 2); - } - - pGl.drawArrays(pGl.TRIANGLES, 0, pShape.vertexCount); - } - - return lRetval; - } - - return fetch('/_shared/2d/shaders/orthographic.vert').then(function(pResponse) { - if (pResponse.status === 200) { - return pResponse.text().then(function(pShader) { - lVertex = pShader; - - return fetch('/_shared/2d/shaders/orthographic.frag').then(function(pResponse) { - if (pResponse.status === 200) { - return pResponse.text().then(function(pShader) { - lFragment = pShader; - return lLoadShaders(); - }); - } - }); - }); - } - }); -} \ No newline at end of file diff --git a/_shared/2d/shaders/orthographic.frag b/_shared/2d/shaders/orthographic.frag deleted file mode 100644 index 84b6b2e..0000000 --- a/_shared/2d/shaders/orthographic.frag +++ /dev/null @@ -1,5 +0,0 @@ -varying lowp vec4 VertexColor; - -void main() { - gl_FragColor = VertexColor; -} \ No newline at end of file diff --git a/_shared/2d/shaders/orthographic.vert b/_shared/2d/shaders/orthographic.vert deleted file mode 100644 index 0356f9c..0000000 --- a/_shared/2d/shaders/orthographic.vert +++ /dev/null @@ -1,13 +0,0 @@ -attribute vec2 position; -attribute vec4 color; - -uniform mat4 projection; -uniform mat4 model; - -varying lowp vec4 VertexColor; - -void main() { - vec4 fragmentPosition = projection * model * vec4(position, 1, 1); - gl_Position = fragmentPosition; - VertexColor = color; -} \ No newline at end of file diff --git a/_shared/math/circle.js b/_shared/math/circle.js deleted file mode 100644 index ba33021..0000000 --- a/_shared/math/circle.js +++ /dev/null @@ -1,112 +0,0 @@ -/// -/// - -const BYTES_PER_FLOAT = 4; - -/** - * Initializes a new circle object for the WebGL context. - * - * @param {WebGLRenderingContext} pGl - * @param {number} pRadius - * @param {number} pSegments - * @param {Array} pColorList - * @param {vec2} pInitialPosition - * @param {number} pMass - */ -function circle(pGl, pRadius, pSegments, pColorList, pInitialPosition, pMass) { - const lBuffer = pGl.createBuffer(); - - pGl.bindBuffer(pGl.ARRAY_BUFFER, lBuffer); - - var lBufferedData = []; - vertexCount = 0; - - const lAngleIncrements = (360.0 / pSegments) * (Math.PI / 180.0); - for (let lSegIdx = 0; lSegIdx < pSegments; lSegIdx++) { - const lAngle = lAngleIncrements * lSegIdx, - lNextAngle = lAngleIncrements * (lSegIdx + 1), - lColorIndex = Math.floor(pColorList.length * (lSegIdx / pSegments)), - lColor = pColorList[lColorIndex]; // TODO: Calculate which one to use - - lBufferedData = lBufferedData.concat([ - 0, 0, lColor.x, lColor.y, lColor.z, lColor.w, - pRadius * Math.sin(lAngle), pRadius * Math.cos(lAngle), lColor.x, lColor.y, lColor.z, lColor.w, - pRadius * Math.sin(lNextAngle), pRadius * Math.cos(lNextAngle), lColor.x, lColor.y, lColor.z, lColor.w - ]); - - vertexCount += 3; - } - - pGl.bufferData(pGl.ARRAY_BUFFER, new Float32Array(lBufferedData), pGl.STATIC_DRAW) - pGl.bindBuffer(pGl.ARRAY_BUFFER, undefined); - - return { - buffer: lBuffer, - vertexCount: vertexCount, - prevPos: vec2(), - position: pInitialPosition || vec2(), - prevVelocity: vec2(), - velocity: vec2(), - force: vec2(), - torque: 0, - mass: pMass === undefined ? 1 : pMass, - rotationVelocity: 0, - rotationRadians: 0, - model: translateMatrix(mat4(), pInitialPosition ? pInitialPosition.x : 0, pInitialPosition ? pInitialPosition.y : 0, 0), - radius: pRadius - }; -} - -function renderCircle(pGl, pProgramInfo, pCircle) { - pGl.uniformMatrix4fv(pProgramInfo.uniformLocations.model, false, pCircle.model); - pGl.bindBuffer(pGl.ARRAY_BUFFER, pCircle.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.TRIANGLE_STRIP, 0, pCircle.vertexCount); -} - -function getCircleMomentOfInertia(pCircle) { - return (Math.PI * Math.pow(pCircle.radius, 4)) / 4; -} - -function doCirclesIntersect(pFirst, pSecond) { - const lDistanceBetween = Math.pow(pFirst.position.x - pSecond.position.x, 2) - + Math.pow(pFirst.position.y - pSecond.position.y, 2) - return lDistanceBetween <= Math.pow(pFirst.radius + pSecond.radius, 2); -} - -/** - * Returns intersection information about the intersecting circles. - * - * Warning! Only use this if doCirclesIntersect returned true for these circles. - * - * @param {circle} pFirst - * @param {circle} pSecond - */ -function getIntersectionDataForCircles(pFirst, pSecond) { - // The collision normal is simply the difference between the two current positions - const lCollisionNormal = normalize2(subVec2(pFirst.position, pSecond.position)); - const lCollisionPoint = vec2( - ((pFirst.position.x * pSecond.radius) + (pSecond.position.x * pFirst.radius)) / (pFirst.radius + pSecond.radius), - ((pFirst.position.y * pSecond.radius) + (pSecond.position.y * pFirst.radius)) / (pFirst.radius + pSecond.radius) - ); - - return { - relativeVelocity: subVec2(pFirst.velocity, pSecond.velocity), - collisionNormal: lCollisionNormal, - //firstPointOfApplication: addVec2(scaleVec2(normalize2(pFirst.velocity), pFirst.radius), pFirst.position), - //secondPointOfApplication: addVec2(scaleVec2(normalize2(pSecond.velocity), pSecond.radius), pSecond.position) - firstPointOfApplication: subVec2(lCollisionPoint, pFirst.position), - secondPointOfApplication: subVec2(lCollisionPoint, pSecond.position) - } -} - -function freeCircle(pGl, pCircle) { - pGl.deleteBuffer(pCircle.buffer); -} \ No newline at end of file diff --git a/_shared/math/collision.js b/_shared/math/collision.js deleted file mode 100644 index 8e4be7d..0000000 --- a/_shared/math/collision.js +++ /dev/null @@ -1,26 +0,0 @@ -/// -/// -/// -/// -/// - -/** - * - * @param {circle} pCircle - * @param {line2} pLine - */ -function lineCircleCollision2(pCircle, pLine) { - return distanceFromPoint2ToLine2(pCircle.position, pLine) <= pCircle.radius; -} - -function getLineCircleCollison2Data(pCircle, pLine) { - const lCollisionNormal = pLine.normal, - lCollisionPoint = addVec2(pCircle.position, scaleVec2(negate2(lCollisionNormal), pCircle.radius)); - - return { - relativeVelocity: subVec2(pCircle.velocity, pLine.velocity), - collisionNormal: lCollisionNormal, - firstPointOfApplication: subVec2(lCollisionPoint, pCircle.position), - secondPointOfApplication: subVec2(lCollisionPoint, pLine.start) - } -} \ No newline at end of file diff --git a/_shared/math/line2.js b/_shared/math/line2.js deleted file mode 100644 index 8b30c1c..0000000 --- a/_shared/math/line2.js +++ /dev/null @@ -1,63 +0,0 @@ -/// -/// - -/** - * Creates a new line object - * @param {vec2} pStart - * @param {vec2} pEnd - * @param {WebGLRenderingContext} pGl - */ -function line2(pStart, pEnd, pGl, pColor, pMass) { - 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, - normal: normalize2(getPerp2(lDiffVector)), - length: length2(lDiffVector), - mass: pMass, - direction: normalize2(lDiffVector), - velocity: vec2(0, 0), - position: vec2() - }; -} - -function getLine2MomentOfInertia(pLine) { - return (1.0 / 12.0) * pLine.mass * Math.pow(pLine.length, 2); -} - -function getLine2MidPoint(pLine) { - return { - x: (pLine.end.x + pLine.start.x) / 2.0, - y: (pLine.end.y + pLine.start.y) / 2.0 - } -} - -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/_shared/math/mat4.js b/_shared/math/mat4.js deleted file mode 100644 index d31a20e..0000000 --- a/_shared/math/mat4.js +++ /dev/null @@ -1,63 +0,0 @@ -function mat4() { - return [ - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - ] -} - -function orthographic(pLeft, pRight, pBottom, pTop) { - const lResult = mat4(); - lResult[0] = 2.0 / (pRight - pLeft); - lResult[5] = 2.0 / (pTop - pBottom); - lResult[10] = 1.0; - lResult[12] = -(pRight + pLeft) / (pRight - pLeft); - lResult[13] = -(pTop + pBottom) / (pTop - pBottom); - return lResult; -} - -function translateMatrix(m, x, y, z) { - m = [...m]; - m[12] += x; - m[13] += y; - m[14] += z; - return m; -} - -function rotateMatrix2d(m, angle) { - m = [...m]; - m[0] = Math.cos(angle); - m[1] = -Math.sin(angle); - m[4] = Math.sin(angle); - m[5] = Math.cos(angle); - return m; -} - -function scaleMatrix(m, x, y, z) { - m = [...m]; - m[0] = m[0] * x; - m[5] = m[5] * y; - m[10] = m[10] * z; - return m; -} - -function multMat4ByVec2(matrix, vec) { - var lInnerVec = {...vec}; - lInnerVec.z = 0.0; - lInnerVec.w = 1.0; - - return { - x: lInnerVec.x * matrix[0] + lInnerVec.y * matrix[4] + lInnerVec.z * matrix[8] + lInnerVec.w * matrix[12], - y: lInnerVec.x * matrix[1] + lInnerVec.y * matrix[5] + lInnerVec.z * matrix[9] + lInnerVec.w * matrix[13] - }; -} - -function multMat4ByVec4(matrix, vec) { - return { - x: vec.x * matrix[0] + vec.y * matrix[4] + vec.z * matrix[8] + vec.w * matrix[12], - y: vec.x * matrix[1] + vec.y * matrix[5] + vec.z * matrix[9] + vec.w * matrix[13], - z: vec.x * matrix[2] + vec.y * matrix[6] + vec.z * matrix[10] + vec.w * matrix[14], - w: vec.x * matrix[3] + vec.y * matrix[7] + vec.z * matrix[11] + vec.w * matrix[15] - }; -} \ No newline at end of file diff --git a/_shared/math/point2.js b/_shared/math/point2.js deleted file mode 100644 index eeacd91..0000000 --- a/_shared/math/point2.js +++ /dev/null @@ -1,16 +0,0 @@ -function point2(x = 0, y = 0) { - return { x: x, y: y }; -} - -function distanceFromPoint2ToLine2(pPoint, pLine) { - // Check out this wikapedia article for more information: - // https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line - var x0 = pPoint.x, - y0 = pPoint.y, - x1 = pLine.start.x, - y1 = pLine.start.y, - x2 = pLine.end.x, - y2 = pLine.end.y; - - return Math.abs((x2 - x1) * (y1 - y0) - (x1 - x0) * (y2 - y1)) / Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)); -} \ No newline at end of file diff --git a/_shared/math/rectangle.js b/_shared/math/rectangle.js deleted file mode 100644 index 012c460..0000000 --- a/_shared/math/rectangle.js +++ /dev/null @@ -1,32 +0,0 @@ -/// - -function rectangle(pGl, pData) { - var lBuffer = pGl.createBuffer(), - lColor = pData.color || { x: 1, y: 0, z: 0, w: 1 }; - - pGl.bindBuffer(pGl.ARRAY_BUFFER, lBuffer); - - var lBufferedData = [ - -pData.width / 2.0, -pData.height / 2.0, lColor.x, lColor.y, lColor.z, lColor.w, - -pData.width / 2.0, pData.height / 2.0, lColor.x, lColor.y, lColor.z, lColor.w, - pData.width / 2.0, pData.height / 2.0, lColor.x, lColor.y, lColor.z, lColor.w, - pData.width / 2.0, pData.height /2.0, lColor.x, lColor.y, lColor.z, lColor.w, - pData.width / 2.0, -pData.height / 2.0, lColor.x, lColor.y, lColor.z, lColor.w, - -pData.width / 2.0, -pData.height / 2.0, lColor.x, lColor.y, lColor.z, lColor.w - ]; - - pGl.bufferData(pGl.ARRAY_BUFFER, new Float32Array(lBufferedData), pGl.STATIC_DRAW) - pGl.bindBuffer(pGl.ARRAY_BUFFER, undefined); - - pData.getMomentOfInertia = function() { - return (1.0 / 12.0) * pData.mass * (pData.height * pData.height + pData.width * pData.width); - }; - - return makeRigidBody2({ - vertexCount: 6, - buffer: lBuffer, - width: pData.width, - height: pData.height, - model: translateMatrix(mat4(), pData.position ? pData.position.x : 0, pData.position ? pData.position.y : 0, 0), - }, pData); -} \ No newline at end of file diff --git a/_shared/math/rigidbody2.js b/_shared/math/rigidbody2.js deleted file mode 100644 index 0b18d0c..0000000 --- a/_shared/math/rigidbody2.js +++ /dev/null @@ -1,57 +0,0 @@ -/// -/// -/// -/// -/// - -const GRAVITY = 9.8; -const BYTES_PER_FLOAT = 4; - -/** - * - * @param {Shape} pObject a 2D shape like a circle, rectangle, or line - * @param {Object} pData initial data for the rigidboy - */ -function makeRigidBody2(pObject, pData) { - pObject.velocity = vec2(); - pObject.prevVelocity = pObject.velocity; - pObject.position = pData.position || vec2(); - pObject.prevPosition = pObject.position; - pObject.force = vec2(); - pObject.rotationVelocity = 0; - pObject.rotationRadians = 0; - pObject.torque = 0; - pObject.mass = pData.mass !== undefined ? pData.mass : 1.0; - pObject.getMomentOfInertia = pData.getMomentOfInertia; - - return pObject; -} - -function updateRigidBody2(pRigidbody, pDeltaTimeSeconds) { - applyForceRigidbody2(pRigidbody, vec2(0, -1.0 * (pRigidbody.mass * GRAVITY))); - const lCurrentAcceleration = scaleVec2(pRigidbody.force, 1.0 / pRigidbody.mass); - pRigidbody.prevVelocity = pRigidbody.velocity; - pRigidbody.velocity = addVec2(pRigidbody.velocity, scaleVec2(lCurrentAcceleration, pDeltaTimeSeconds)); - pRigidbody.prevPos = { ...pRigidbody.position }; - pRigidbody.position = addVec2(pRigidbody.position, scaleVec2(pRigidbody.velocity, pDeltaTimeSeconds)); - pRigidbody.force = vec2(); - - const lMomentOfInertia = pRigidbody.getMomentOfInertia(pRigidbody); - const lAngularAcceleration = pRigidbody.torque / lMomentOfInertia; - pRigidbody.rotationVelocity += lAngularAcceleration * pDeltaTimeSeconds; - pRigidbody.rotationRadians += pRigidbody.rotationVelocity * pDeltaTimeSeconds; - pRigidbody.torque = 0; - - pRigidbody.model = rotateMatrix2d(translateMatrix(mat4(), pRigidbody.position.x, pRigidbody.position.y, 0), pRigidbody.rotationRadians); -} - -function applyForceRigidbody2(pRigidbody, pForceVector, pPointOfApplication) { - if (pPointOfApplication !== undefined) { - const lOriginToPointOfApp = subVec2(vec2(), pPointOfApplication), - lPerpVec = vec2(-lOriginToPointOfApp.y, lOriginToPointOfApp.x); - - pRigidbody.torque += TORQUE_MULTIPLIER * dot2(lPerpVec, pForceVector); - } - - pRigidbody.force = addVec2(pRigidbody.force, pForceVector); -} diff --git a/_shared/math/vec2.js b/_shared/math/vec2.js deleted file mode 100644 index 11e71cd..0000000 --- a/_shared/math/vec2.js +++ /dev/null @@ -1,64 +0,0 @@ -function vec2(x = 0, y = 0) { - return { x: x, y: y}; -} - -function addVec2(v1, v2) { - return { - x: v1.x + v2.x, - y: v1.y + v2.y - }; -} - -function subVec2(v1, v2) { - return { - x: v1.x - v2.x, - y: v1.y - v2.y - }; -} - -function scaleVec2(v, s) { - return { - x: v.x * s, - y: v.y * s - }; -} - -function dot2(v1, v2) { - return v1.x * v2.x + v1.y * v2.y; -} - -function length2(v) { - return Math.sqrt(v.x * v.x + v.y * v.y); -} - -function normalize2(v) { - const lLength = length2(v); - const lInverseLength = lLength === 0 ? 1.0 : 1.0 / length2(v); - return { x: v.x * lInverseLength, y: v.y * lInverseLength }; -} - -function vec2str(v) { - return `(${v.x.toFixed(2)}, ${v.y.toFixed(2)})`; -} - -function getPerp2(v) { - return { - x: -v.y, - y: v.x - }; -} - -function negate2(v) { - return { - x: -v.x, - y: -v.y - }; -} - -// Algorithm plucked from: https://matthew-brett.github.io/teaching/rotation_2d.html -function rotateAboutOrigin2(v, angle) { - return { - x: v.x * Math.cos(angle) - v.y * Math.sin(angle), - y: v.x * Math.sin(angle) + v.y * Math.cos(angle), - }; -} \ No newline at end of file diff --git a/index.html b/index.html index ef30197..41a36e7 100644 --- a/index.html +++ b/index.html @@ -20,7 +20,6 @@
  • Linear Forces
  • -
  • Circle-Line
  • Rectangle-Line
  • Rectangle-Rectangle
  • Pill-Line
  • diff --git a/roadmap.html b/roadmap.html index 3c0e457..1e39c4d 100644 --- a/roadmap.html +++ b/roadmap.html @@ -20,7 +20,6 @@
  • Linear Forces
  • -
  • Circle-Line
  • Rectangle-Line
  • Rectangle-Rectangle
  • Pill-Line
  • @@ -73,7 +72,7 @@ } .done { - color: lightgreen; + color: green; } .halfway { @@ -100,7 +99,8 @@

    May/June 2021: More Collisions

      -
    • SAT Collisions for Convex Polygons with Explanation
    • +
    • SAT Collisions for Convex Polygons with Explanation
    • +
    • Rigidbody Demos
    • Pill Collisions
    • Remove (or hide) ellipse collision pages for now
    • 3D scene setup
    • @@ -150,7 +150,7 @@
    • Getting started with WASM docs
    • Wasm examples
    -

    +

    Everything above has a due date of April 30th, 2021. None of it is that hard, so this should be a very doable timeline.

    diff --git a/roadmap.html.content b/roadmap.html.content index 5509dc8..e228cec 100644 --- a/roadmap.html.content +++ b/roadmap.html.content @@ -24,7 +24,7 @@ } .done { - color: lightgreen; + color: green; } .halfway { @@ -51,7 +51,8 @@

    May/June 2021: More Collisions

      -
    • SAT Collisions for Convex Polygons with Explanation
    • +
    • SAT Collisions for Convex Polygons with Explanation
    • +
    • Rigidbody Demos
    • Pill Collisions
    • Remove (or hide) ellipse collision pages for now
    • 3D scene setup
    • @@ -101,7 +102,7 @@
    • Getting started with WASM docs
    • Wasm examples
    -

    +

    Everything above has a due date of April 30th, 2021. None of it is that hard, so this should be a very doable timeline.

    diff --git a/scripts/jquery-3.5.1.min.js b/scripts/jquery-3.5.1.min.js deleted file mode 100644 index 4e83e2d..0000000 --- a/scripts/jquery-3.5.1.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.5.1",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,j=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function qe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="
    ",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=$e(y.pixelPosition,function(e,t){if(t)return t=Be(e,n),Me.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0"Rigidbody" >>/2d/rigidbody/rigidbody_1.html "Linear Forces" >"Collisions" ->>/2d/_collisions/circle_line.html "Circle-Line" >>/2d/_collisions/rectangle_line.html "Rectangle-Line" >>/2d/_collisions/rectangle_rectangle.html "Rectangle-Rectangle" >>/2d/_collisions/pill_line.html "Pill-Line" -- cgit v1.2.1