summaryrefslogtreecommitdiff
path: root/frontend/2d
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/2d')
-rw-r--r--frontend/2d/_collisions/circle_line.js3
-rw-r--r--frontend/2d/_collisions/rectangle_line.js105
2 files changed, 102 insertions, 6 deletions
diff --git a/frontend/2d/_collisions/circle_line.js b/frontend/2d/_collisions/circle_line.js
index e5898f0..0736e2c 100644
--- a/frontend/2d/_collisions/circle_line.js
+++ b/frontend/2d/_collisions/circle_line.js
@@ -125,7 +125,8 @@
circleObject.position = lSubdividedCircle.position;
circleObject.velocity = addVec2(lSubdividedCircle.velocity, scaleVec2(lCollisionNormal, lImpulseMagnitude / circleObject.mass));
- circleObject.rotationVelocity = lSubdividedCircle.rotationVelocity + dot2(lFirstPerp, scaleVec2(lCollisionNormal, lImpulseMagnitude));
+ circleObject.rotationVelocity = lSubdividedCircle.rotationVelocity
+ + dot2(lFirstPerp, scaleVec2(lCollisionNormal, lImpulseMagnitude)) / getCircleMomentOfInertia(circleObject);
updateCircle(circleObject, pDeltaTimeSeconds - lSubdividedDeltaTime);
diff --git a/frontend/2d/_collisions/rectangle_line.js b/frontend/2d/_collisions/rectangle_line.js
index ac73f71..dec5108 100644
--- a/frontend/2d/_collisions/rectangle_line.js
+++ b/frontend/2d/_collisions/rectangle_line.js
@@ -34,7 +34,8 @@
rectangleObject = rectangle(programContext.gl, {
width: 50,
- height: 25,
+ height: 50,
+ mass: 1,
color: { x: 0.3, y: 0.5, z: 0.1, w: 0.7 },
position: vec2(programContext.width / 2.0 - 100, programContext.height / 2.0 + 100)
});
@@ -43,16 +44,16 @@
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));
+ { x: 1, y: 0, z: 0, w: 1 }, 10000000.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));
+ { x: 1, y: 1, z: 0, w: 1 }, 10000000.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));
+ { x: 0, y: 1, z: 0, w: 1 }, 10000000.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));
+ { x: 0, y: 1, z: 0, w: 1 }, 10000000.0));
exitRequestFunc = requestUpdateLoop(update, cleanup);
@@ -68,7 +69,101 @@
}
function collision(pDeltaTimeSeconds) {
+ for (var lineIdx = 0; lineIdx < lineObjectList.length; lineIdx++) {
+ var lLine = lineObjectList[lineIdx];
+
+ if (areIntersecting(rectangleObject, lLine, pDeltaTimeSeconds)) {
+ break;
+ }
+ }
+ }
+
+ function doesPointIntersect(pPoint, pLine) {
+ const EPSILON = 0.98;
+ return distanceFromPoint2ToLine2(pPoint, pLine) <= EPSILON;
+ }
+
+ function getIntersectionInformation(pRectangle, pCollisionPoint, pLine) {
+ var lCollisionNormal = pLine.normal,
+ lRectCollisionPoint_WorldCoords = multMat4ByVec2(pRectangle.model, pCollisionPoint),
+ lRectPosition = pRectangle.position,
+ lTrueRectCollisionPoint = normalize2(subVec2(lRectPosition, lRectCollisionPoint_WorldCoords));
+
+ console.log(lTrueRectCollisionPoint);
+
+ return {
+ relativeVelocity: subVec2(pRectangle.velocity, pLine.velocity),
+ collisionNormal: lCollisionNormal,
+ rectangleCollisionPoint: lTrueRectCollisionPoint
+ }
+ }
+
+ function areIntersecting(pRectangle, pLine, pDeltaTimeSeconds) {
+ var lCollisionPoint = undefined,
+ lCheckCollision = function(pRectangle) {
+ var lLowerLeft = multMat4ByVec2(pRectangle.model, vec2(-pRectangle.width / 2.0, -pRectangle.height / 2.0)),
+ lUpperLeft = multMat4ByVec2(pRectangle.model, vec2(-pRectangle.width / 2.0, pRectangle.height / 2.0)),
+ lUpperRight = multMat4ByVec2(pRectangle.model, vec2(pRectangle.width / 2.0, pRectangle.height / 2.0)),
+ lLowerRight = multMat4ByVec2(pRectangle.model, vec2(pRectangle.width / 2.0, -pRectangle.height / 2.0));
+
+ if (doesPointIntersect(lLowerLeft, pLine)) {
+ console.log('Lwer left');
+ lCollisionPoint = vec2(-pRectangle.width / 2.0, -pRectangle.height / 2.0);
+ return true;
+ } else if (doesPointIntersect(lUpperLeft, pLine)) {
+ console.log('Upper left');
+ lCollisionPoint = vec2(-pRectangle.width / 2.0, pRectangle.height / 2.0);
+ return true;
+ } else if (doesPointIntersect(lUpperRight, pLine)) {
+ console.log('Upepr right');
+ lCollisionPoint = vec2(pRectangle.width / 2.0, pRectangle.height / 2.0);
+ return true;
+ } else if (doesPointIntersect(lLowerRight, pLine)) {
+ console.log('Lower right');
+ lCollisionPoint = vec2(pRectangle.width / 2.0, -pRectangle.height / 2.0);
+ return true;
+ }
+
+ return false;
+ };
+
+ if (!lCheckCollision(pRectangle)) {
+ return;
+ }
+
+ // Subdivide until we find the exact moment where we intersected
+ var lSubdividedDeltaTime = pDeltaTimeSeconds,
+ lSubRectangle = undefined;
+ do {
+ lSubRectangle = JSON.parse(JSON.stringify(pRectangle));
+ lSubRectangle.position = {...pRectangle.prevPos};
+ lSubRectangle.velocity = {...pRectangle.prevVelocity};
+ lSubRectangle.getMomentOfInertia = pRectangle.getMomentOfInertia;
+ lSubdividedDeltaTime = lSubdividedDeltaTime / 2.0;
+ updateRigidBody2(lSubRectangle, lSubdividedDeltaTime);
+ if (lSubdividedDeltaTime === 0) {
+ console.error('This should NOT be happening');
+ break;
+ }
+ } while (lCheckCollision(lSubRectangle));
+ var lIntersectionResult = getIntersectionInformation(lSubRectangle, lCollisionPoint, pLine),
+ lRelativeVelocity = lIntersectionResult.relativeVelocity,
+ lCollisionNormal = lIntersectionResult.collisionNormal,
+ lRectPerp = getPerp2(lIntersectionResult.rectangleCollisionPoint);
+
+ const lNumerator = dot2(scaleVec2(lRelativeVelocity, -(1.0 + 1.0)), lCollisionNormal);
+ const lLinearDenomPart = dot2(lCollisionNormal, (scaleVec2(lCollisionNormal, 1.0 / pRectangle.mass)));
+ const lRotationalDenomPart = (Math.pow(dot2(lRectPerp, lCollisionNormal), 2) / pRectangle.getMomentOfInertia());
+
+ const lImpulseMagnitude = lNumerator / (lLinearDenomPart + lRotationalDenomPart);
+
+ pRectangle.position = lSubRectangle.position;
+ pRectangle.velocity = addVec2(lSubRectangle.velocity, scaleVec2(lCollisionNormal, lImpulseMagnitude / pRectangle.mass));
+ pRectangle.rotationVelocity = lSubRectangle.rotationVelocity + dot2(lRectPerp, scaleVec2(lCollisionNormal, lImpulseMagnitude)) / pRectangle.getMomentOfInertia();
+
+ updateRigidBody2(pRectangle, pDeltaTimeSeconds - lSubdividedDeltaTime);
+ return true;
}
function render() {