2013-09-05 21:58:58 -07:00
|
|
|
/* scene.c
|
|
|
|
*
|
|
|
|
* Definition of Scene-related functions.
|
|
|
|
*
|
|
|
|
* Eryn Wells <eryn@erynwells.me>
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2013-09-06 21:15:56 -07:00
|
|
|
#include <math.h>
|
2013-09-06 14:52:03 -07:00
|
|
|
#include <stdlib.h>
|
2013-09-07 16:10:50 -07:00
|
|
|
|
2013-09-05 21:58:58 -07:00
|
|
|
#include "scene.h"
|
|
|
|
|
|
|
|
|
2013-09-07 16:10:50 -07:00
|
|
|
struct _ObjectList
|
|
|
|
{
|
|
|
|
Object *object;
|
|
|
|
ObjectList *next;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-09-06 21:15:56 -07:00
|
|
|
Color _scene_trace(Scene *scene, const Ray ray, const int depth);
|
|
|
|
|
|
|
|
|
2013-09-05 21:58:58 -07:00
|
|
|
/*
|
|
|
|
* scene_init --
|
2013-09-06 14:52:03 -07:00
|
|
|
*
|
|
|
|
* Initialize and return a new Scene. If the Scene could not be created, NULL is returned.
|
2013-09-05 21:58:58 -07:00
|
|
|
*/
|
2013-09-06 14:52:03 -07:00
|
|
|
Scene *
|
|
|
|
scene_init()
|
2013-09-05 21:58:58 -07:00
|
|
|
{
|
2013-09-06 14:52:03 -07:00
|
|
|
Scene *new_scene = malloc(sizeof(Scene));
|
|
|
|
if (!new_scene) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set some default values.
|
|
|
|
new_scene->height = 0;
|
|
|
|
new_scene->width = 0;
|
2013-09-06 19:01:15 -07:00
|
|
|
new_scene->camera = camera_init();
|
2013-09-06 14:52:03 -07:00
|
|
|
|
|
|
|
return new_scene;
|
2013-09-05 21:58:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* scene_destroy --
|
2013-09-06 14:52:03 -07:00
|
|
|
*
|
|
|
|
* Cleanup a Scene.
|
2013-09-05 21:58:58 -07:00
|
|
|
*/
|
|
|
|
void
|
|
|
|
scene_destroy(Scene *scene)
|
2013-09-06 14:52:03 -07:00
|
|
|
{
|
|
|
|
if (scene == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-09-06 19:01:15 -07:00
|
|
|
camera_destroy(scene->camera);
|
2013-09-06 14:52:03 -07:00
|
|
|
free(scene);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* scene_load --
|
|
|
|
*
|
|
|
|
* Load a scene from a file into the given Scene object.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
scene_load(Scene *scene, FILE *scene_file)
|
2013-09-05 21:58:58 -07:00
|
|
|
{ }
|
2013-09-05 22:08:55 -07:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* scene_render --
|
2013-09-06 14:52:03 -07:00
|
|
|
*
|
|
|
|
* Render the given Scene.
|
2013-09-05 22:08:55 -07:00
|
|
|
*/
|
|
|
|
void
|
|
|
|
scene_render(Scene *scene)
|
|
|
|
{
|
2013-09-06 23:03:08 -07:00
|
|
|
scene->pixels = malloc(sizeof(Color) * scene->height * scene->width);
|
|
|
|
if (scene->pixels == NULL) {
|
2013-09-06 21:15:56 -07:00
|
|
|
// TODO: Print an error.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-09-07 16:10:29 -07:00
|
|
|
scene->width = 640;
|
|
|
|
scene->height = 480;
|
|
|
|
|
2013-09-06 21:15:56 -07:00
|
|
|
float fov = 30.0;
|
|
|
|
float aspect_ratio = scene->width / scene->height;
|
|
|
|
float angle = tan(M_PI * 0.5 * fov / 180.0);
|
|
|
|
|
|
|
|
float xx, yy;
|
|
|
|
Ray primary_ray;
|
|
|
|
Vector3 direction;
|
2013-09-05 22:08:55 -07:00
|
|
|
for (int y = 0; y < scene->height; y++) {
|
|
|
|
for (int x = 0; x < scene->width; x++) {
|
2013-09-06 21:15:56 -07:00
|
|
|
// Compute (x, y) of ray direction.
|
|
|
|
xx = (2 * ((x + 0.5) / scene->width) - 1) * angle * aspect_ratio;
|
|
|
|
yy = (1 - 2 * ((y + 0.5) / scene->height)) * angle;
|
|
|
|
|
|
|
|
// Assemble a ray and trace it.
|
|
|
|
direction = vector_init(xx, yy, 1);
|
2013-09-07 18:26:59 -07:00
|
|
|
primary_ray = ray_init(ZeroVector3, vector_normalize(direction));
|
2013-09-06 23:03:08 -07:00
|
|
|
scene->pixels[y * scene->height + x] = _scene_trace(scene, primary_ray, 0);
|
2013-09-05 22:08:55 -07:00
|
|
|
}
|
|
|
|
}
|
2013-09-07 16:10:29 -07:00
|
|
|
|
|
|
|
scene->is_rendered = 1;
|
2013-09-05 22:08:55 -07:00
|
|
|
}
|
2013-09-06 21:15:56 -07:00
|
|
|
|
|
|
|
|
2013-09-07 18:41:33 -07:00
|
|
|
/*
|
|
|
|
* scene_add_object --
|
|
|
|
*
|
|
|
|
* Add an Object to the Scene.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
scene_add_object(Scene *scene, Object *obj)
|
|
|
|
{
|
|
|
|
ObjectList *ol = malloc(sizeof(ObjectList));
|
|
|
|
if (ol == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ol->object = obj;
|
|
|
|
ol->next = NULL;
|
|
|
|
|
|
|
|
ObjectList *ptr = scene->objects;
|
|
|
|
while (ptr != NULL) {
|
|
|
|
if (ptr->next == NULL) {
|
|
|
|
ptr->next = ol;
|
|
|
|
}
|
|
|
|
ptr = ptr->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-09-06 21:15:56 -07:00
|
|
|
Color
|
|
|
|
_scene_trace(Scene *scene, const Ray ray, const int depth)
|
|
|
|
{
|
2013-09-07 18:26:59 -07:00
|
|
|
Color out_color = {0, 0, 0};
|
2013-09-06 21:15:56 -07:00
|
|
|
|
|
|
|
return out_color;
|
|
|
|
}
|