-
Notifications
You must be signed in to change notification settings - Fork 58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Makeup Assignment #1 #6
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,5 +3,46 @@ | |
#include "ICamera.h" | ||
#include "ray.h" | ||
|
||
// --- IMPLENET class CCameraEnvironmental --- | ||
#define _USE_MATH_DEFINES | ||
#include <math.h> | ||
// --- IMPLEMENT class CCameraEnvironmental --- | ||
// --- PUT YOUR CODE HERE --- | ||
|
||
class CCameraEnvironmental : public ICamera | ||
{ | ||
public: | ||
CCameraEnvironmental(Size resolution, const Vec3f& pos, float angle) | ||
: ICamera(resolution) | ||
, m_pos(pos) | ||
{ | ||
} | ||
virtual ~CCameraEnvironmental(void) = default; | ||
|
||
virtual void InitRay(Ray& ray, int x, int y) override | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like your implementation, it general it looks correct. After a closer look, there are some error. You need to spend a bit more time for debugging. |
||
{ | ||
// --- PUT YOUR CODE HERE --- | ||
float dx = x; | ||
float dy = y; | ||
|
||
auto height = getResolution().height; | ||
auto width = getResolution().width; | ||
|
||
double theta = 2 * M_PI * dx / height; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here dx should be decided by width and not height. |
||
double phi = acos(1 - 2 * dy / width); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here would be enough to have phi changing from 0 to Pi. arccosine is not needed. |
||
double x1 = sin(phi) * cos(theta); | ||
double y1 = sin(phi) * sin(theta); | ||
double z = cos(phi); | ||
Vec3f spherePoint = Vec3f(x1, y1, z); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this point is on the unit sphere, which is located in the origin. So you can use it as direction vector. Next, you forgot the coordinate system transformation, in the WCS y axis looks up, in the sphere you generate, z axis looks up |
||
|
||
ray.org = m_pos; | ||
ray.dir = normalize(spherePoint - m_pos); | ||
ray.t = std::numeric_limits<float>::infinity(); | ||
|
||
} | ||
|
||
|
||
private: | ||
// input values | ||
Vec3f m_pos; ///< Camera origin (center of projection) | ||
}; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggest the following implementation based on yours:
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,44 @@ | |
|
||
#include "IPrim.h" | ||
#include "ray.h" | ||
#include "PrimPlane.h" | ||
|
||
// --- IMPLENET class CPrimDisc --- | ||
// --- PUT YOUR CODE HERE --- | ||
// --- PUT YOUR CODE HERE --- | ||
|
||
class CPrimDisc : public IPrim { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would recommend to derive the disc from plane primitive here, however the implementation is fine |
||
public: | ||
|
||
|
||
CPrimDisc(const Vec3f& origin, const Vec3f& normal, double radius) | ||
: IPrim(), | ||
m_origin(origin), | ||
m_normal(normal), | ||
m_radius(radius) | ||
{} | ||
|
||
virtual ~CPrimDisc(void) = default; | ||
|
||
|
||
virtual bool intersect(Ray& ray) const override | ||
{ | ||
auto plane = CPrimPlane(m_origin, m_normal); | ||
|
||
Ray rayCpy = ray; | ||
if (!plane.intersect(rayCpy)) | ||
return false; | ||
auto pt = rayCpy.org + rayCpy.dir * rayCpy.t; | ||
auto d = norm(pt - m_origin); | ||
if (d > m_radius) | ||
return false; | ||
if (rayCpy.t > ray.t) | ||
return false; | ||
ray.t = rayCpy.t; | ||
return true; | ||
} | ||
|
||
private: | ||
Vec3f m_origin; | ||
Vec3f m_normal; | ||
double m_radius; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,7 +31,22 @@ class CPrimPlane : public IPrim | |
virtual bool intersect(Ray& ray) const override | ||
{ | ||
// --- PUT YOUR CODE HERE --- | ||
return false; | ||
float num = m_normal.dot(m_origin - ray.org); | ||
float den = m_normal.dot(ray.dir); | ||
if (den == 0) | ||
{ | ||
return -1; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it is a Boolean function, it should be false. This error gives the yellow line on horizon in your renders. |
||
} | ||
|
||
float t = num / den; | ||
if (t > ray.t || t < Epsilon) | ||
{ | ||
return false; | ||
} | ||
|
||
ray.t = t; | ||
|
||
return true; | ||
} | ||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,7 +31,25 @@ class CPrimTriangle : public IPrim | |
virtual bool intersect(Ray& ray) const override | ||
{ | ||
// --- PUT YOUR CODE HERE --- | ||
return false; | ||
Vec3f nab = (m_b - ray.org).cross(m_a - ray.org); | ||
Vec3f nbc = (m_c - ray.org).cross(m_b - ray.org); | ||
Vec3f nca = (m_a - ray.org).cross(m_c - ray.org); | ||
|
||
float area = nab.dot(ray.dir) + nbc.dot(ray.dir) + nca.dot(ray.dir); | ||
float lambda1 = nab.dot(ray.dir) / area; | ||
float lambda2 = nbc.dot(ray.dir) / area; | ||
float lambda3 = nca.dot(ray.dir) / area; | ||
if (lambda1 < 0 || lambda2 < 0 || lambda3 < 0) { | ||
return false; | ||
} | ||
|
||
Vec3f p = m_a * lambda1 + m_b * lambda2 + m_c * lambda3; | ||
float t = p[0] / ray.dir[0]; | ||
if (t < Epsilon || t > ray.t) { | ||
return false; | ||
} | ||
ray.t = t; | ||
return true; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. triangles are rendered only in the right part of the screen. I think somewhere inside this algorithm an error. Perhaps in the line |
||
} | ||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Env camera has no angle