<aside> ⁉️ 궁금한 내용, 오타, 수정사항, 문의사항은 아래 깃허브 이슈 혹은 노션 블록 댓글로 달아주시면 바로 확인해드립니다! 도움이 되셨다면 아래 링크를 통해 🌟 한번 꾹 눌러주세요 ‼️

</aside>

GaepoMorningEagles/mini_raytracing_in_c


7. 오브젝트

이번 장에서는 여러가지 오브젝트(도형)들을 하나의 오브젝트로 다루기 위해 object라는 리스트를 만드려고 한다.

7.1. 실습목표

object 리스트에 대해 알아보고 리스트를 만든다. 이 전에 만든 함수들을 object 리스트에 맞게 수정한다.

7.2. 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에 각 도형의 데이터를 저장할 것이다.

7.3. object 적용

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);
}
// 추가 끝