aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/intersect/intersect.cpp18
-rw-r--r--src/intersect/normals.cpp9
-rw-r--r--src/physics/physics.cpp138
-rw-r--r--src/raytracer/raytracer.cpp2
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 &currentShape, 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 &currentShape, 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 &currentShape, 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 &currentShape, RenderShapeData &shape)
{
return false;
@@ -35,20 +138,27 @@ bool Physics::checkForCylinderCollision(RenderShapeData &currentShape, RenderSha
return false;
}
-bool Physics::checkForCubeCollision(RenderShapeData &currentShape, RenderShapeData &shape)
+bool Physics::checkForCubeCollision(RenderShapeData &currentShape, 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);