<aside> ⁉️ 궁금한 내용, 오타, 수정사항, 문의사항은 아래 깃허브 이슈 혹은 노션 블록 댓글로 달아주시면 바로 확인해드립니다! 도움이 되셨다면 아래 링크를 통해 🌟 한번 꾹 눌러주세요 ‼️
</aside>
GaepoMorningEagles/mini_raytracing_in_c
이번 장에서는 여러가지 오브젝트(도형)들을 하나의 오브젝트로 다루기 위해 object라는 리스트를 만드려고 한다.
object 리스트에 대해 알아보고 리스트를 만든다. 이 전에 만든 함수들을 object 리스트에 맞게 수정한다.
6단원까지는 sphere 하나의 object를 구현하고 저장하였지만 앞으로 여러가지의 object를 추가할 수 있게 하기 위해서 코드의 수정이 필요하다. 우선 여러가지의 object를 저장할 수 있어야하고 그 object들을 한번에 가지고 다닐 수 있어야한다. ray는 여러개의 object 중 가장 가까이에 있는 object에 히트를 해야한다.
우리는 object라는 리스트를 만들어 각 도형의 정보를 저장할 것이다. 그리고 기존에 sphere에만 적용 가능했던 함수들을 조금씩 손봐줄 예정이다.
먼저 다음과 같은 구조체를 만들어서 structures.h에 추가해주자.
...
// 3. 오브젝트 구조체
// 추가
typedef struct s_object t_object;
// 추가 끝
typedef struct s_sphere t_sphere;
...
# define FALSE 0
# define TRUE 1
// 추가
typedef int t_object_type;
# define SP 0
// 추가 끝
...
// 오브젝트 구조체
// 추가
struct s_object
{
t_object_type type;
void *element;
void *next;
};
// 추가 끝
#endif
Code1 : [miniRT/include/structures.h]
Object 리스트 안에 type은 object 리스트를 봤을 때 현재 리스트가 가리키는 도형이 무엇인지 바로 알 수 있기 위해 추가하였다. 그리고 우리는 sphere라는 도형은 매크로 SP로 type을 지정했다. 리스트의 element에 각 도형의 데이터를 저장할 것이다.
object 리스트를 구현했으니 hit함수를 추가하여 object를 받을 수 있게 하자. 그리고 ray_color와 hit_sphere도 t_sphere에만 한정되지 않는 함수로 바꾸어 주자.
t_point3 ray_at(t_ray *ray, double t);
// 추가
t_color3 ray_color(t_ray *ray, t_object *world); // 수정.
// trace/hit/
t_bool hit(t_object *obj, t_ray *ray, t_hit_record *rec);
t_bool hit_obj(t_object *obj, t_ray *ray, t_hit_record *rec);
t_bool hit_sphere(t_object *world, t_ray *ray, t_hit_record *rec);
// 추가 끝
...
Code2 : [miniRT/include/trace.h]
// 추가
#include "trace.h"
t_bool hit(t_object *world, t_ray *ray, t_hit_record *rec)
{
t_bool hit_anything;
t_hit_record temp_rec;
temp_rec = *rec; // temp_rec의 tmin, tmax 값 초기화를 위해.
hit_anything = FALSE;
while(world)
{
if (hit_obj(world, ray, &temp_rec))
{
hit_anything = TRUE;
temp_rec.tmax = temp_rec.t;
*rec = temp_rec;
}
world = world->next;
}
return (hit_anything);
}
// hit_obj는 오브젝트 타입에 맞는 hit함수로 연결해주는 관문
t_bool hit_obj(t_object *world, t_ray *ray, t_hit_record *rec)
{
t_bool hit_result;
hit_result = FALSE;
if (world->type == SP)
hit_result = hit_sphere(world, ray, rec); //hit_sphere의 첫번째 인자도 t_sphere *에서 t_object *로 수정해주자.
return (hit_result);
}
// 추가 끝