diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/intersect/intersect.cpp | 18 | ||||
-rw-r--r-- | src/intersect/normals.cpp | 9 | ||||
-rw-r--r-- | src/physics/physics.cpp | 138 | ||||
-rw-r--r-- | src/raytracer/raytracer.cpp | 2 |
4 files changed, 140 insertions, 27 deletions
diff --git a/src/intersect/intersect.cpp b/src/intersect/intersect.cpp index 71cae49..d5ab015 100644 --- a/src/intersect/intersect.cpp +++ b/src/intersect/intersect.cpp @@ -63,7 +63,7 @@ glm::vec4 intersectCone( float radius = 0.5f; float a = d.x*d.x + d.z*d.z - .25f*(d.y*d.y) - .25f*(d[3]*d[3]); float b = 2.f*(p.x*d.x + p.z*d.z) - .5f*(p.y*d.y) + .25f*d.y - .5f*(p[3]*d[3]) + .25f*d[3]; - float c = p.x*p.x + p.z*p.z - .25f*(p.y*p.y) + .25f*p.y - .25f*(p[3]*p[3]) + .25f*p[3] - 1/8.f; + float c = p.x*p.x + p.z*p.z - .25f*(p.y*p.y) + .25f*p.y - .25f*(p[3]*p[3]) + .25f*p[3] - 1/16.f; float discriminant = b*b - 4*a*c; if (discriminant >= 0) @@ -97,7 +97,7 @@ glm::vec4 intersectCone( auto pwBase = p + twBase * d; if ( twBase > 0 && - pwBase.x*pwBase.x + pwBase.z*pwBase.z <= pwBase.y*pwBase.y -.25f && + pwBase.x*pwBase.x + pwBase.z*pwBase.z <= pwBase.y*pwBase.y + .25f && pwBase.y >= -.5f && pwBase.y <= .5f ) { @@ -109,7 +109,7 @@ glm::vec4 intersectCone( auto pyBase = p + tyBase * d; if ( tyBase > 0 && - pyBase.x*pyBase.x + pyBase.z*pyBase.z <= pyBase[3]*pyBase[3] -.25f && + pyBase.x*pyBase.x + pyBase.z*pyBase.z <= pyBase[3]*pyBase[3] +.25f && pyBase[3] >= -.5f && pyBase[3] <= .5f ) { @@ -174,21 +174,23 @@ glm::vec4 intersectCylinder( if ( tTop > 0 && pTop.x*pTop.x + pTop.z*pTop.z <= radius*radius && - pTop.y >= -.5f && pTop.y <= .5f && - pTop[3] >= -.5f && pTop[3] <= .5f) + pTop.y >= -.5f && pTop.y <= .5f //&& +// pTop[3] >= -.5f && pTop[3] <= .5f + ) { t = std::min(t, tTop); } // implicit p_y + t*d_y = -.5f, Bottom base - float tBase = (.5f - p.y - p[3]) / (d[3] + d.y); + float tBase = (-.5f - p.y - p[3]) / (d[3] + d.y); auto pBase = p + tBase * d; if ( tBase > 0 && pBase.x*pBase.x + pBase.z*pBase.z <= radius*radius && - pBase.y >= -.5f && pBase.y <= .5f && - pBase[3] >= -.5f && pBase[3] <= .5f) + pBase.y >= -.5f && pBase.y <= .5f //&& +// pBase[3] >= -.5f && pBase[3] <= .5f + ) { t = std::min(t, tBase); } diff --git a/src/intersect/normals.cpp b/src/intersect/normals.cpp index 84db534..f9b0ea1 100644 --- a/src/intersect/normals.cpp +++ b/src/intersect/normals.cpp @@ -2,6 +2,7 @@ // Created by Michael Foiani on 11/4/23. // +#include <iostream> #include "raytracer/raytracer.h" glm::vec4 getConeNormal( @@ -11,7 +12,7 @@ glm::vec4 getConeNormal( { return {0.f, -1.f, 0.f, 0.f}; } - if (RayTracer::floatEquals(intersectPointObject[3], -.5f)) // normal for w base + if (RayTracer::floatEquals(intersectPointObject.w, -.5f)) // normal for w base { return {0.f, 0.f, 0.f, -1.f}; } @@ -19,7 +20,7 @@ glm::vec4 getConeNormal( { return {0.f, 1.f, 0.f, 0.f}; } - if (RayTracer::floatEquals(intersectPointObject[3], .5f)) // normal for w top + if (RayTracer::floatEquals(intersectPointObject.w, .5f)) // normal for w top { return {0.f, 0.f, 0.f, 1.f}; } @@ -81,11 +82,11 @@ glm::vec4 getCubeNormal( { return {0.f, 0.f, 1.f, 0.f}; } - if (RayTracer::floatEquals(intersectPointObject[3], -.5f)) // neg w + if (RayTracer::floatEquals(intersectPointObject.w, -.5f)) // neg w { return {0.f, 0.f, 0.f, -1.f}; } - if (RayTracer::floatEquals(intersectPointObject[3], .5f)) // pos w + if (RayTracer::floatEquals(intersectPointObject.w, .5f)) // pos w { return {0.f, 0.f, 0.f, 1.f}; } diff --git a/src/physics/physics.cpp b/src/physics/physics.cpp index 6b95bbe..111c25a 100644 --- a/src/physics/physics.cpp +++ b/src/physics/physics.cpp @@ -4,10 +4,94 @@ #include <iostream> #include "physics.h" -bool Physics::checkForSphereCollision(RenderShapeData ¤tShape, RenderShapeData &shape) +bool sphereCube(RenderShapeData &sphere, RenderShapeData &cube) { - glm::vec4 currentCenter = currentShape.translation4d; - glm::vec4 shapeCenter = shape.translation4d; + // get center of cube + glm::vec4 cubeCenter = cube.translation4d; + // get the width, height, depth, & yawl of cube's box + glm::vec4 cubeScales = glm::vec4(cube.ctm[0][0], cube.ctm[1][1], cube.ctm[2][2], cube.ctm[3][3]); + + // note: assumption that cube is axis aligned + glm::vec4 maxes = cubeCenter + cubeScales / 2.f; + glm::vec4 mins = cubeCenter - cubeScales / 2.f; + + // get the center of sphere + glm::vec4 sphereCenter = sphere.translation4d; + // get radius of sphere + // note: assumption that sphere is not scaled (TODO: make radius adaptive) + float radius = .5f; + + // hit detection algorithm + float distSquared = radius * radius; + if (sphereCenter.x < mins.x) distSquared -= (sphereCenter.x - mins.x)*(sphereCenter.x - mins.x); + else if (sphereCenter.x > maxes.x) distSquared -= (sphereCenter.x - maxes.x)*(sphereCenter.x - maxes.x); + if (sphereCenter.y < mins.y) distSquared -= (sphereCenter.y - mins.y)*(sphereCenter.y - mins.y); + else if (sphereCenter.y > maxes.y) distSquared -= (sphereCenter.y - maxes.y)*(sphereCenter.y - maxes.y); + if (sphereCenter.z < mins.z) distSquared -= (sphereCenter.z - mins.z)*(sphereCenter.z - mins.z); + else if (sphereCenter.z > maxes.z) distSquared -= (sphereCenter.z - maxes.z)*(sphereCenter.z - maxes.z); + if (sphereCenter.w < mins.w) distSquared -= (sphereCenter.w - mins.w)*(sphereCenter.w - mins.w); + else if (sphereCenter.w > maxes.w) distSquared -= (sphereCenter.w - maxes.w)*(sphereCenter.w - maxes.w); + + if (distSquared > 0) { + std::cout << "distanceSquared: " << distSquared << std::endl; + + // update velocity of the objects, based on math, assuming the objects are the same mass + sphere.velocity *= -1.f; + cube.velocity *= -1.f; + + // move the objects in new dir so they don't collide again + sphere.translation4d += sphere.velocity; + cube.translation4d += cube.velocity; + } + + return distSquared > 0; +} + +bool cubeCube(RenderShapeData &c1, RenderShapeData &c2) { + // get the width, height, depth, & yawl of cubes boxes + glm::vec4 cube1Scales = glm::vec4(c1.ctm[0][0], c1.ctm[1][1], c1.ctm[2][2], c1.ctm[3][3]); + glm::vec4 cube2Scales = glm::vec4(c2.ctm[0][0], c2.ctm[1][1], c2.ctm[2][2], c2.ctm[3][3]); + + // get the center of cubes + glm::vec4 cube1Center = c1.translation4d; + glm::vec4 cube2Center = c2.translation4d; + + // note: assumption that cube is axis aligned + glm::vec4 cube1Maxes = cube1Center + cube1Scales / 2.f; + glm::vec4 cube1Mins = cube1Center - cube1Scales / 2.f; + glm::vec4 cube2Maxes = cube2Center + cube2Scales / 2.f; + glm::vec4 cube2Mins = cube2Center - cube2Scales / 2.f; + + // hit detection algorithm + // see if x overlap + bool xOverlap = cube1Maxes.x >= cube2Mins.x && cube1Mins.x <= cube2Maxes.x; + // see if y overlap + bool yOverlap = cube1Maxes.y >= cube2Mins.y && cube1Mins.y <= cube2Maxes.y; + // see if z overlap + bool zOverlap = cube1Maxes.z >= cube2Mins.z && cube1Mins.z <= cube2Maxes.z; + // see if w overlap + bool wOverlap = cube1Maxes.w >= cube2Mins.w && cube1Mins.w <= cube2Maxes.w; + + bool intersect = xOverlap && yOverlap && zOverlap && wOverlap; + if (intersect) { + std::cout << "intersect: " << intersect << std::endl; + + // update velocity of the objects, based on math, assuming the objects are the same mass + c1.velocity *= -1.f; + c1.velocity *= -1.f; + + // move the objects in new dir so they don't collide again + c1.translation4d += c2.velocity; + c1.translation4d += c2.velocity; + } + + return intersect; +} + +bool sphereSphere(RenderShapeData &s1, RenderShapeData &s2) +{ + glm::vec4 currentCenter = s1.translation4d; + glm::vec4 shapeCenter = s2.translation4d; // define a radius vector float radius = .5; float distance = glm::distance(currentCenter, shapeCenter); @@ -17,14 +101,33 @@ bool Physics::checkForSphereCollision(RenderShapeData ¤tShape, RenderShape // update velocity if (distance <= radius + radius) { - currentShape.velocity *= -1.f; - // move a little in other direction so it doesn't flip again - currentShape.translation4d += currentShape.velocity; + std::cout << "distance: " << distance << std::endl; + s1.velocity *= -1.f; + s2.velocity *= -1.f; + + // move the objects in new dir so they don't collide again + s1.translation4d += s1.velocity; + s2.translation4d += s2.velocity; } return distance <= radius + radius; } +bool Physics::checkForSphereCollision(RenderShapeData ¤tShape, RenderShapeData &otherShape) +{ + switch (otherShape.primitive.type) + { + case PrimitiveType::PRIMITIVE_CUBE: + return sphereCube(currentShape, otherShape); + case PrimitiveType::PRIMITIVE_SPHERE: + return sphereSphere(currentShape, otherShape); + default: + break; + } + + return false; +} + bool Physics::checkForConeCollision(RenderShapeData ¤tShape, RenderShapeData &shape) { return false; @@ -35,20 +138,27 @@ bool Physics::checkForCylinderCollision(RenderShapeData ¤tShape, RenderSha return false; } -bool Physics::checkForCubeCollision(RenderShapeData ¤tShape, RenderShapeData &shape) +bool Physics::checkForCubeCollision(RenderShapeData ¤tShape, RenderShapeData &otherShape) { - return false; + switch (otherShape.primitive.type) + { + case PrimitiveType::PRIMITIVE_CUBE: + return cubeCube(currentShape, otherShape); + case PrimitiveType::PRIMITIVE_SPHERE: + return sphereCube(otherShape, currentShape); + default: + break; + } } void Physics::handleCollisions(std::vector<RenderShapeData> &shapes) { - for (auto &shape : shapes) + for (int i = 0; i < shapes.size(); i++) { - for (auto &otherShape : shapes) + auto shape = shapes[i]; + + for (int j = i + 1; j < shapes.size(); j++) { - if (shape.ctm == otherShape.ctm && shape.translation4d == otherShape.translation4d) - { - continue; - } + auto otherShape = shapes[j]; switch (shape.primitive.type) { case PrimitiveType::PRIMITIVE_CONE: diff --git a/src/raytracer/raytracer.cpp b/src/raytracer/raytracer.cpp index 65f898d..4d48848 100644 --- a/src/raytracer/raytracer.cpp +++ b/src/raytracer/raytracer.cpp @@ -52,7 +52,7 @@ void RayTracer::render(RGBA *imageData, const RayTraceScene &scene) { if (settings.currentTime < settings.maxTime) { // still more to render // render the next frame settings.currentTime++; - settings.w++; +// settings.w++; // update physics Physics::updateShapePositions(m_metaData.shapes); |