diff --git a/source/include/worldbuilder.h b/source/include/worldbuilder.h index cc2755c..0a3e5c2 100644 --- a/source/include/worldbuilder.h +++ b/source/include/worldbuilder.h @@ -10,6 +10,7 @@ #define DORAYME_WORLDBUILDER_H #include +#include /* Let's keep a single header for now, will see later */ @@ -22,7 +23,30 @@ public: /* Not implemented yet */ class Hw3File : public World { +private: + Matrix transformStack[50]; + uint32_t transStackCount; + public: + double currentAmbient; + double currentShininess; + double currentSpecular; + double currentDiffuse; + double currentEmission; + double currentReflective; + double currentTransparency; + double currentRefIndex; + + Colour currentColour; + Matrix cam; + double camFoV; + +public: + Matrix getTransformMatrix(); + void popTransformMatrix(); + void pushTransformMatrix(); + void applyTransformMatrix(Matrix t); + Hw3File(const char *filename); }; diff --git a/source/worldbuilder/hw3file.cpp b/source/worldbuilder/hw3file.cpp index 49edc9a..71823f2 100644 --- a/source/worldbuilder/hw3file.cpp +++ b/source/worldbuilder/hw3file.cpp @@ -7,18 +7,20 @@ * */ /* Don't build for now */ -#if 0 + /* This file is parsing a text format from another raytracer I made in the past. */ #include -#include #include -#include #include -#include + +#include +#include +#include +#include #define IS_CMD(_cmd) (strncmp(buffer, _cmd, sizeof(_cmd)) == 0) -typedef void (*cmdFunc)(scene *sc, uint32_t curLine, char *first, float argv[15]); +typedef void (*cmdFunc)(Hw3File *w, uint32_t curLine, double argv[15]); typedef struct cmd_def { @@ -27,111 +29,127 @@ typedef struct cmd_def cmdFunc f; } cmd_def; -void cmdCamera (scene *sc, uint32_t curLine, char *first, float argv[15]) +static void cmdCamera (Hw3File *w, uint32_t curLine, double argv[15]) { - sc->cam.seteye(point(argv[0], argv[1], argv[2])); - sc->cam.setat(point(argv[3], argv[4], argv[5])); - sc->cam.setup(vector(argv[6], argv[7], argv[8])); - sc->cam.setfovy(argv[9]); + w->cam = viewTransform(Point(argv[0], argv[1], argv[2]), + Point(argv[3], argv[4], argv[5]), + Vector(argv[6], argv[7], argv[8])); + + w->camFoV = deg_to_rad(argv[9]); } -void cmdSphere (scene *sc, uint32_t curLine, char *first, float argv[15]) +/* 0: X, 1: Y, 2: Z + * 3: Radius + */ +static void cmdSphere (Hw3File *w, uint32_t curLine, double argv[15]) { + printf("Adding a sphere...\n"); /* Instanciate a sphere */ - sphere *sp = new sphere(point(argv[0], argv[1], argv[2]), argv[3], sc->getMatrix()); - sp->ambient = sc->ambient; - sp->diffuse = sc->diffuse; - sp->specular = sc->specular; - sp->emission = sc->emission; - sp->shininess = sc->shininess; - sp->sourceLine = curLine; - sc->o[sc->o_count] = sp; - sc->o_count++; + Sphere *shape = new Sphere(); + + Matrix pos = translation(argv[0], argv[1], argv[2]) * scaling(argv[3], argv[3], argv[3]); + + shape->setTransform(w->getTransformMatrix() * pos); + + shape->material.ambient = w->currentAmbient; + shape->material.reflective = w->currentReflective; + shape->material.shininess = w->currentShininess; + shape->material.specular = w->currentSpecular; + shape->material.diffuse = w->currentDiffuse; + shape->material.colour = w->currentColour; + shape->material.transparency = w->currentTransparency; + shape->material.refractiveIndex = w->currentRefIndex; + + w->addObject(shape); } -void cmdCube (scene *sc, uint32_t curLine, char *first, float argv[15]) +static void cmdCube (Hw3File *w, uint32_t curLine, double argv[15]) { } +static void cmdTrans (Hw3File *w, uint32_t curLine, double argv[15]) +{ + Matrix m = translation(argv[0], argv[1], argv[2]); + w->applyTransformMatrix(m); +} + +static void cmdRotate (Hw3File *w, uint32_t curLine, double argv[15]) +{ + Matrix m = Matrix4().identity(); + if (argv[2] != 0) + { + m = m * rotationZ(argv[3]); + } + if (argv[1] != 0) + { + m = m * rotationY(argv[3]); + } + if (argv[0] != 0) + { + m = m * rotationX(argv[3]); + } + + w->applyTransformMatrix(m); +} + +static void cmdScale (Hw3File *w, uint32_t curLine, double argv[15]) +{ + Matrix m = scaling(argv[0], argv[1], argv[2]); + + w->applyTransformMatrix(m); +} + +static void cmdPushT (Hw3File *w, uint32_t curLine, double argv[15]) +{ + w->pushTransformMatrix(); +} + +static void cmdPopT (Hw3File *w, uint32_t curLine, double argv[15]) +{ + w->popTransformMatrix(); +} + +static void cmdLPoint (Hw3File *w, uint32_t curLine, double argv[15]) +{ + /* create point light */ + Light *l = new Light(POINT_LIGHT, Point(argv[0], argv[1], argv[2]), Colour(argv[3], argv[4], argv[5])); + + w->addLight(l); +} + +static void cmdAmbient (Hw3File *w, uint32_t curLine, double argv[15]) +{ + //w->currentAmbient = (argv[0] + argv[1] + argv[2]) / 3; + w->currentColour = Colour(argv[0], argv[1], argv[2]); +} + +static void cmdColour (Hw3File *w, uint32_t curLine, double argv[15]) +{ + w->currentColour = Colour(argv[0], argv[1], argv[2]); +} + +static void cmdDiffuse (Hw3File *w, uint32_t curLine, double argv[15]) +{ + w->currentDiffuse = (argv[0] + argv[1] + argv[2]) / 3; +} + +static void cmdSpecular (Hw3File *w, uint32_t curLine, double argv[15]) +{ + w->currentSpecular = (argv[0] + argv[1] + argv[2]) / 3; +} + +static void cmdShine (Hw3File *w, uint32_t curLine, double argv[15]) +{ + w->currentReflective = argv[0]; +} + +static void cmdEmission (Hw3File *w, uint32_t curLine, double argv[15]) +{ + w->currentEmission = (argv[0] + argv[1] + argv[2]) / 3; +} + #if 0 -void cmdMaxVerts (scene *sc, uint32_t curLine, char *first, float argv[15]) -{ - sc->vertexCount = (uint32_t) argv[0]; - sc->vertex = new point[sc->vertexCount]; - sc->curVertex = 0; -} - -void cmdMaxVertN (scene *sc, uint32_t curLine, char *first, float argv[15]) -{ - /* ignore for now */ -} - -void cmdVertex (scene *sc, uint32_t curLine, char *first, float argv[15]) -{ - sc->vertex[sc->curVertex].set(argv[0], argv[1], argv[2]); - sc->curVertex++; -} - -void cmdVertexN (scene *sc, uint32_t curLine, char *first, float argv[15]) -{ - /* ignore for now */ -} - -void cmdTri (scene *sc, uint32_t curLine, char *first, float argv[15]) -{ - /* arg are vertex numbers */ - triangle *tr = new triangle(sc->vertex[(int)argv[0]], sc->vertex[(int)argv[1]], sc->vertex[(int)argv[2]], sc->getMatrix()); - tr->ambient = sc->ambient; - tr->diffuse = sc->diffuse; - tr->specular = sc->specular; - tr->emission = sc->emission; - tr->shininess = sc->shininess; - tr->sourceLine = curLine; - sc->o[sc->o_count] = tr; - sc->o_count++; -} - -void cmdTriN (scene *sc, uint32_t curLine, char *first, float argv[15]) -{ - /* ignore for noz */ -} -#endif - -void cmdTrans (scene *sc, uint32_t curLine, char *first, float argv[15]) -{ - matrix m; - m.translation(argv[0], argv[1], argv[2]); - sc->applyTransform(m); -} - -void cmdRotate (scene *sc, uint32_t curLine, char *first, float argv[15]) -{ - matrix m; - vector axis; - axis.set(argv[0], argv[1], argv[2]); - m.rotation(axis, argv[3]); - sc->applyTransform(m); -} - -void cmdScale (scene *sc, uint32_t curLine, char *first, float argv[15]) -{ - matrix m; - m.scale(argv[0], argv[1], argv[2]); - sc->applyTransform(m); -} - -void cmdPushT (scene *sc, uint32_t curLine, char *first, float argv[15]) -{ - sc->pushMatrix(); -} - -void cmdPopT (scene *sc, uint32_t curLine, char *first, float argv[15]) -{ - sc->popMatrix(); -} - -#if 0 -void cmdLDire (scene *sc, uint32_t curLine, char *first, float argv[15]) +static void cmdLDire (Hw3File *w, uint32_t curLine, double argv[15]) { /* create directional light */ light *cur = new light(); @@ -145,163 +163,184 @@ void cmdLDire (scene *sc, uint32_t curLine, char *first, float argv[15]) sc->l[sc->l_count] = cur; sc->l_count++; } -#endif -void cmdLPoint (scene *sc, uint32_t curLine, char *first, float argv[15]) +static void cmdAtten (Hw3File *w, uint32_t curLine, double argv[15]) { - /* create point light */ - light *cur = new light(); - - cur->type = LIGHT_POINT; - cur->attenuation = sc->attenuation; - - cur->position.set(argv[0], argv[1], argv[2]); - cur->lightcolor.set(argv[3], argv[4], argv[5]); - sc->l[sc->l_count] = cur; - sc->l_count++; + sc->attenuation = Vector(argv[0], argv[1], argv[2]); } -#if 0 -void cmdAtten (scene *sc, uint32_t curLine, char *first, float argv[15]) +static void cmdMaxVerts (Hw3File *w, uint32_t curLine, double argv[15]) { - sc->attenuation = vector(argv[0], argv[1], argv[2]); + sc->vertexCount = (uint32_t) argv[0]; + sc->vertex = new point[sc->vertexCount]; + sc->curVertex = 0; +} + +static void cmdMaxVertN (Hw3File *w, uint32_t curLine, double argv[15]) +{ + /* ignore for now */ +} + +static void cmdVertex (Hw3File *w, uint32_t curLine, double argv[15]) +{ + sc->vertex[sc->curVertex].set(argv[0], argv[1], argv[2]); + sc->curVertex++; +} + +static void cmdVertexN (Hw3File *w, uint32_t curLine, double argv[15]) +{ + /* ignore for now */ +} + +static void cmdTri (Hw3File *w, uint32_t curLine, double argv[15]) +{ + /* arg are vertex numbers */ + triangle *tr = new triangle(sc->vertex[(int)argv[0]], sc->vertex[(int)argv[1]], sc->vertex[(int)argv[2]], sc->getMatrix()); + tr->ambient = sc->ambient; + tr->diffuse = sc->diffuse; + tr->specular = sc->specular; + tr->emission = sc->emission; + tr->shininess = sc->shininess; + tr->sourceLine = curLine; + sc->o[sc->o_count] = tr; + sc->o_count++; } #endif -void cmdAmbient (scene *sc, uint32_t curLine, char *first, float argv[15]) +static cmd_def commandList[] = { - sc->ambient = color(argv[0], argv[1], argv[2]); -} - -void cmdDiffuse (scene *sc, uint32_t curLine, char *first, float argv[15]) -{ - sc->diffuse = color(argv[0], argv[1], argv[2]); -} - -void cmdSpecular (scene *sc, uint32_t curLine, char *first, float argv[15]) -{ - sc->specular = color(argv[0], argv[1], argv[2]); -} - -void cmdShine (scene *sc, uint32_t curLine, char *first, float argv[15]) -{ - sc->shininess = argv[0]; -} - -void cmdEmission (scene *sc, uint32_t curLine, char *first, float argv[15]) -{ - sc->emission = color(argv[0], argv[1], argv[2]); -} - -cmd_def commandList[] = - { - /* Camera */ - { "camera", 10, cmdCamera }, - /* Geometry */ - { "sphere", 4, cmdSphere }, - //{ "maxverts", 1, cmdMaxVerts }, - //{ "maxvertnorms", 1, cmdMaxVertN }, - //{ "vertex", 3, cmdVertex }, - //{ "vertexnormal", 6, cmdVertexN }, - //{ "tri", 3, cmdTri }, - //{ "trinormal", 3, cmdTriN }, - //{ "cube", 1, cmdCube }, - /* transformation */ - { "translate", 3, cmdTrans }, - { "rotate", 4, cmdRotate }, - { "scale", 3, cmdScale }, - { "pushTransform", 0, cmdPushT }, - { "popTransform", 0, cmdPopT }, - /* Lights */ - //{ "directional", 6, cmdLDire }, - { "point", 6, cmdLPoint }, - //{ "attenuation", 3, cmdAtten }, - /* Materials */ - { "ambient", 3, cmdAmbient }, - { "diffuse", 3, cmdDiffuse }, - { "specular", 3, cmdSpecular }, - { "shininess", 1, cmdShine }, - { "emission", 3, cmdEmission }, - }; + /* Camera */ + {"camera", 10, cmdCamera}, + /* Geometry */ + {"sphere", 4, cmdSphere}, + //{ "maxverts", 1, cmdMaxVerts }, + //{ "maxvertnorms", 1, cmdMaxVertN }, + //{ "vertex", 3, cmdVertex }, + //{ "vertexnormal", 6, cmdVertexN }, + //{ "tri", 3, cmdTri }, + //{ "trinormal", 3, cmdTriN }, + //{ "cube", 1, cmdCube }, + /* transformation */ + {"translate", 3, cmdTrans}, + {"rotate", 4, cmdRotate}, + {"scale", 3, cmdScale}, + {"pushTransform", 0, cmdPushT}, + {"popTransform", 0, cmdPopT}, + /* Lights */ + //{ "directional", 6, cmdLDire }, + {"point", 6, cmdLPoint}, + //{ "attenuation", 3, cmdAtten }, + /* Materials */ + {"color", 3, cmdColour}, + {"ambient", 3, cmdAmbient}, + {"diffuse", 3, cmdDiffuse}, + {"specular", 3, cmdSpecular}, + {"shininess", 1, cmdShine}, + {"emission", 3, cmdEmission}, +}; #define CMD_COUNT (sizeof(commandList) / sizeof(cmd_def)) -scene *readfile::read(char *filename) +Hw3File::Hw3File(const char *filename) : transStackCount(0), currentColour(Colour(1, 1, 1)), + currentEmission(0), currentShininess(200), currentAmbient(0.1), + currentDiffuse(0.9), currentSpecular(0.9), camFoV(0) { FILE *fp; - scene *sc = new scene; - if (sc != NULL) + + this->popTransformMatrix(); + + fp = fopen(filename, "rt"); + if (fp != NULL) { - fp = fopen(filename, "rt"); - if (fp == NULL) + char buffer[512]; + int line = 0; + while(!feof(fp)) { - delete sc; - sc = NULL; - } - else - { - char buffer[512]; - int line = 0; - while(!feof(fp)) + uint32_t i; + + line++; + + memset(buffer, 0, 512); + fgets(buffer, 512, fp); + + if ((buffer[0] == '#') || (strlen(buffer) < 2)) { - uint32_t i; - line++; - memset(buffer, 0, 512); - fgets(buffer, 512, fp); - if ((buffer[0] == '#') || (strlen(buffer) < 2)) - continue; /* Ingore empty line or commented lines */ - //printf("::%d:> %s", strlen(buffer), buffer); - for (i = 0; i < CMD_COUNT; i++) + continue; /* Ingore empty line or commented lines */ + } + + for (i = 0; i < CMD_COUNT; i++) + { + if (strncmp(buffer, commandList[i].name, strlen(commandList[i].name)) == 0) { - if (strncmp(buffer, commandList[i].name, strlen(commandList[i].name)) == 0) + char first[512]; + double value[15]; + if (commandList[i].numparam != 0) { - char first[512]; - float value[15]; - if (commandList[i].numparam != 0) + size_t j; + int k = 0, l = 0; + char buff[512]; + for(j = strlen(commandList[i].name); j < strlen(buffer); j++) { - size_t j; - int k = 0, l = 0; - char buff[512]; - for(j = strlen(commandList[i].name); j < strlen(buffer); j++) + if (!isspace(buffer[j])) { - if (!isspace(buffer[j])) - { - buff[l++] = buffer[j]; - } - else - { - buff[l] = 0; - l = 0; - if (k == 0) - { - strcpy(first, buff); - } - if (strlen(buff) > 0) - { - value[k++] = atof(buff); - } - } + buff[l++] = buffer[j]; } - if (k != abs(commandList[i].numparam)) + else { - printf("line %d malformed: given %d parameter, expected %d\n%s", line, k, abs(commandList[i].numparam), buffer); - sc = NULL; - goto exit; + buff[l] = 0; + l = 0; + if (k == 0) + { + strcpy(first, buff); + } + if (strlen(buff) > 0) + { + value[k++] = atof(buff); + } } } - commandList[i].f(sc, line, first, value); - break; + if (k != abs(commandList[i].numparam)) + { + printf("line %d malformed: given %d parameter, expected %d\n%s", line, k, abs(commandList[i].numparam), buffer); + goto exit; + } } + commandList[i].f(this, line, value); + break; } } -#ifdef USE_OCTREE - sc->createOctree(); -#endif } } exit: - return sc; + return; } -#endif \ No newline at end of file +Matrix Hw3File::getTransformMatrix() +{ + return this->transformStack[this->transStackCount]; +} + +void Hw3File::popTransformMatrix() +{ + if (this->transStackCount == 0) + { + this->transformStack[0] = Matrix4().identity(); + } + else + { + this->transformStack[this->transStackCount] = Matrix4().identity(); + this->transStackCount --; + } +} + +void Hw3File::pushTransformMatrix() +{ + this->transStackCount ++; + this->transformStack[this->transStackCount] = this->transformStack[this->transStackCount - 1]; +} + +void Hw3File::applyTransformMatrix(Matrix t) +{ + this->transformStack[this->transStackCount] = this->transformStack[this->transStackCount] * t; +} \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2606c59..2d4d5eb 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -19,6 +19,11 @@ gtest_discover_tests(testMyRays ) +add_executable(hw3render) +target_include_directories(hw3render PUBLIC ../source/include) +target_sources(hw3render PRIVATE hw3render.cpp) +target_link_libraries(hw3render rayonnement) + add_executable(ch5_test) target_include_directories(ch5_test PUBLIC ../source/include) target_sources(ch5_test PRIVATE ch5_test.cpp) diff --git a/tests/hw3render.cpp b/tests/hw3render.cpp new file mode 100644 index 0000000..d78eba3 --- /dev/null +++ b/tests/hw3render.cpp @@ -0,0 +1,42 @@ +/* + * DoRayMe - a quick and dirty Raytracer + * Renderer using hw3 files as world builder. + * + * Created by Manoƫl Trapier + * Copyright (c) 2020 986-Studio. + * + */ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + if(argc != 2) + { + printf("usage: %s file.hw3\n", argv[0]); + return -1; + } + + Hw3File world = Hw3File(argv[1]); + + /* Set the camera resolution */ + Camera cam = Camera(640, 480, world.camFoV); + + cam.setTransform(world.cam); + + /* Now render it */ + Canvas image = cam.render(world); + + image.SaveAsPNG("hw3render.png"); + + return 0; +} \ No newline at end of file