#include <gp/coord.h>
#include <gp/colors.h>
#include "frame_buffer.h"
struct Scene {
vector<pCoor> coors_os;
vector<uint32_t> colors;
};
void
prep_scene(Scene& s, const HW02_Info& hw02_info)
{
vector<pCoor>& coors_os = s.coors_os;
vector<uint32_t>& colors = s.colors;
uint32_t color_white = 0xffffff;
uint32_t color_red [[maybe_unused]] = 0xff0000;
uint32_t color_blue [[maybe_unused]] = 0xff;
uint32_t color_green [[maybe_unused]] = 0xff00;
coors_os << pCoor( 0, 0, 0 ) << pCoor( 9, 6, -9 ) << pCoor( 0, 7, -5 );
colors << color_white;
coors_os << pCoor(7,4,-2) << pCoor(-3,5,-9) << pCoor(9,2,-2);
colors << color_blue;
colors << color_lsu_spirit_gold << color_lsu_spirit_purple;
coors_os << pCoor(-7,0,-2) << pCoor(-7,2,-2) << pCoor(-5,0,-2);
coors_os << pCoor(-7,2,-2) << pCoor(-5,2,-2) << pCoor(-5,0,-2);
pCoor pc2(-3.8,2,-2), pc3(-2.75,0,-2);
pCoor pc4 = pc3 + 0.2 * pVect(pc3,pc2);
coors_os << pCoor(-4,2,-2) << pc2 << pc3;
coors_os << pCoor(-4,2,-2) << pCoor(-3.25,0,-2) << pc3;
coors_os << pc4 << pCoor(-2,2,-2) << pc3;
colors << color_green << color_lsu_spirit_purple << color_lsu_spirit_gold;
const pCoor p1 [[maybe_unused]] = hw02_info.p1;
const pCoor p2 [[maybe_unused]] = hw02_info.p2;
const pCoor p3 [[maybe_unused]] = hw02_info.p3;
const pCoor p4 [[maybe_unused]] = hw02_info.p4;
const int n_pieces [[maybe_unused]] = hw02_info.n_pieces;
pVect vx(p1,p2), vz(p1,p4);
pNorm ax(vx), ay( cross(vz,ax) );
pVect vy = ay * ax.magnitude;
float r2or1 = pNorm(p1,p3).magnitude / ax.magnitude;
float delta_theta = 2 * M_PI / n_pieces;
for ( int i=0; i<n_pieces; i++ )
{
float theta = i * delta_theta;
pVect v = vx * cosf(theta) + vy * sinf(theta);
pVect v2 = v * r2or1;
coors_os << p1 + v << p1 + v2 << p4 + v;
coors_os << p1 + v2 << p4 + v2 << p4 + v;
colors << color_lemon_chiffon << color_lemon_chiffon;
}
}
void
render_ray_trace_os
(pFrame_Buffer& demo_frame_buffer, const HW02_Info& hw02_info)
{
Scene s;
vector<pCoor>& coors_os = s.coors_os;
vector<uint32_t>& colors = s.colors;
prep_scene(s,hw02_info);
const uint win_width = demo_frame_buffer.width_get();
const uint win_height = demo_frame_buffer.height_get();
const float aspect = 1.0 * win_width / win_height;
const float width_m = 1.6;
const float height_m = width_m / aspect;
const float qn = 1;
pMatrix_Translate center_eye(-hw02_info.eye_location);
pMatrix_Rotation rotate_eye(hw02_info.eye_direction,pVect(0,0,-1));
pMatrix eye_from_object = rotate_eye * center_eye;
pMatrix object_from_eye = pMatrix_Translate(hw02_info.eye_location)
* pMatrix_Rotation(pVect(0,0,-1),hw02_info.eye_direction);
vector<pCoor> coors_es = eye_from_object * coors_os;
pCoor light_location_o = object_from_eye*hw02_info.light_location;
pCoor window_ll_e( -width_m/2, -height_m/2, -qn); pCoor window_ul_e( -width_m/2, height_m/2, -qn); pCoor window_lr_e( +width_m/2, -height_m/2, -qn);
pCoor window_ll_o = object_from_eye * window_ll_e;
pCoor window_ul_o = object_from_eye * window_ul_e;
pCoor window_lr_o = object_from_eye * window_lr_e;
pCoor eye_location = hw02_info.eye_location; pVect window_dx_o = pVect( window_ll_o, window_lr_o ) / win_width;
pVect window_dy_o = pVect( window_ll_o, window_ul_o ) / win_height;
#pragma omp parallel for
for ( uint yw = 0; yw < win_height; yw++ )
for ( uint xw = 0; xw < win_width; xw++ )
{
pCoor px_o = window_ll_o + window_dx_o * xw + window_dy_o * yw;
pVect ray( eye_location, px_o );
float tmin = 1e10; auto ic = colors.begin();
for ( auto it = coors_os.begin(); it != coors_os.end(); )
{
pCoor o0 = *it++, o1 = *it++, o2 = *it++;
uint32_t color = *ic++;
pVect tn(o0,o1,o2);
float t = dot( pVect( eye_location, o0 ), tn ) / dot( ray, tn );
if ( t >= tmin || t < 1 ) continue;
pCoor s = eye_location + t * ray;
pVect v01(o0,o1), v02(o0,o2), v0s(o0,s);
pVect v01i = cross(tn,v01); float b2 = dot(v0s,v01i) / dot( v02,v01i );
if ( b2 < 0 || b2 > 1 ) continue;
pVect v02i = cross(tn,v02);
float b1 = dot( v0s, v02i) / dot(v01,v02i);
if ( b1 < 0 || b1 + b2 > 1 ) continue;
pNorm s_to_l(s,light_location_o);
float ill = max( 0.1f, fabs( dot(s_to_l,pNorm(tn)) ) );
pColor ci = pColor(color) * ill * hw02_info.light_intensity;
tmin = t;
demo_frame_buffer[ xw + yw * win_width ] = ci.int_rgb();
}
}
}
void
render_ray_trace
(pFrame_Buffer& demo_frame_buffer, const HW02_Info& hw02_info)
{
Scene s;
vector<pCoor>& coors_os = s.coors_os;
vector<uint32_t>& colors = s.colors;
prep_scene(s,hw02_info);
const uint win_width = demo_frame_buffer.width_get();
const uint win_height = demo_frame_buffer.height_get();
const float aspect = 1.0 * win_width / win_height;
const float width_m = 1.6;
const float height_m = width_m / aspect;
const float qn = 1;
pMatrix_Translate center_eye(-hw02_info.eye_location);
pMatrix_Rotation rotate_eye(hw02_info.eye_direction,pVect(0,0,-1));
pMatrix eye_from_object = rotate_eye * center_eye;
vector<pCoor> coors_es = eye_from_object * coors_os;
pCoor window_ll_e( -width_m/2, -height_m/2, -qn); pCoor window_ul_e( -width_m/2, height_m/2, -qn); pCoor window_lr_e( +width_m/2, -height_m/2, -qn);
pVect window_dx_e = pVect( window_ll_e, window_lr_e ) / win_width;
pVect window_dy_e = pVect( window_ll_e, window_ul_e ) / win_height;
#pragma omp parallel for
for ( uint yw = 0; yw < win_height; yw++ )
for ( uint xw = 0; xw < win_width; xw++ )
{
pCoor px_e = window_ll_e + window_dx_e * xw + window_dy_e * yw;
pVect ray( pCoor(0,0,0), px_e );
float tmin = 1e10; auto ic = colors.begin();
for ( auto it = coors_es.begin(); it != coors_es.end(); )
{
pCoor e0 = *it++, e1 = *it++, e2 = *it++;
uint32_t color = *ic++;
pVect tn(e0,e1,e2); float t = dot( pVect(pCoor(0,0,0),e0), tn ) / dot( ray, tn );
if ( t >= tmin || t < 1 ) continue;
pCoor s = t * ray;
pVect v01(e0,e1), v02(e0,e2), v0s(e0,s);
pVect v01i = cross(tn,v01); float b2 = dot(v0s,v01i) / dot( v02,v01i );
if ( b2 < 0 || b2 > 1 ) continue;
pVect v02i = cross(tn,v02);
float b1 = dot( v0s, v02i) / dot(v01,v02i);
if ( b1 < 0 || b1 + b2 > 1 ) continue;
pNorm s_to_l( s, hw02_info.light_location );
float ill = max( 0.1f, fabs( dot(s_to_l,pNorm(tn)) ) );
pColor ci = pColor(color) * ill * hw02_info.light_intensity;
tmin = t;
demo_frame_buffer[ xw + yw * win_width ] = ci.int_rgb();
}
}
}
int
main(int argc, char **argv)
{
pFrame_Buffer demo_frame_buffer(argc,argv);
Render render( demo_frame_buffer );
RENDER_INSERT(render, render_ray_trace);
RENDER_INSERT(render, render_ray_trace_os);
render.run();
return 0;
}