Browse Source

Add a world generator based on another raytracer file format I made in the past and add a crude tool to run it.

it does not render properly, there are some major differences between both engine especially in the material definition. Will need more work, but is not urgent.
Godzil 4 years ago
parent
commit
c9021974f6
4 changed files with 289 additions and 179 deletions
  1. 24 0
      source/include/worldbuilder.h
  2. 218 179
      source/worldbuilder/hw3file.cpp
  3. 5 0
      tests/CMakeLists.txt
  4. 42 0
      tests/hw3render.cpp

+ 24 - 0
source/include/worldbuilder.h

@@ -10,6 +10,7 @@
 #define DORAYME_WORLDBUILDER_H
 
 #include <world.h>
+#include <camera.h>
 
 /* 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);
 };
 

+ 218 - 179
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 <stdio.h>
-#include <stdlib.h>
 #include <string.h>
-#include <stdint.h>
 #include <ctype.h>
-#include <math.h>
+
+#include <worldbuilder.h>
+#include <sphere.h>
+#include <matrix.h>
+#include <transformation.h>
 
 #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])
 {
 }
 
-#if 0
-void cmdMaxVerts (scene *sc, uint32_t curLine, char *first, float argv[15])
+static void cmdTrans    (Hw3File *w, uint32_t curLine, double argv[15])
 {
-    sc->vertexCount = (uint32_t) argv[0];
-    sc->vertex = new point[sc->vertexCount];
-    sc->curVertex = 0;
+    Matrix m = translation(argv[0], argv[1], argv[2]);
+    w->applyTransformMatrix(m);
 }
 
-void cmdMaxVertN (scene *sc, uint32_t curLine, char *first, float argv[15])
+static void cmdRotate   (Hw3File *w, uint32_t curLine, double argv[15])
 {
-    /* ignore for now */
+    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);
 }
 
-void cmdVertex   (scene *sc, uint32_t curLine, char *first, float argv[15])
+static void cmdScale    (Hw3File *w, uint32_t curLine, double argv[15])
 {
-    sc->vertex[sc->curVertex].set(argv[0], argv[1], argv[2]);
-    sc->curVertex++;
+    Matrix m = scaling(argv[0], argv[1], argv[2]);
+
+    w->applyTransformMatrix(m);
 }
 
-void cmdVertexN  (scene *sc, uint32_t curLine, char *first, float argv[15])
+static void cmdPushT    (Hw3File *w, uint32_t curLine, double argv[15])
 {
-    /* ignore for now */
+    w->pushTransformMatrix();
 }
 
-void cmdTri      (scene *sc, uint32_t curLine, char *first, float argv[15])
+static void cmdPopT     (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++;
+    w->popTransformMatrix();
 }
 
-void cmdTriN     (scene *sc, uint32_t curLine, char *first, float argv[15])
+static void cmdLPoint   (Hw3File *w, uint32_t curLine, double argv[15])
 {
-    /* ignore for noz */
+    /* 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]);
 }
-#endif
 
-void cmdTrans    (scene *sc, uint32_t curLine, char *first, float argv[15])
+static void cmdColour  (Hw3File *w, uint32_t curLine, double argv[15])
 {
-    matrix m;
-    m.translation(argv[0], argv[1], argv[2]);
-    sc->applyTransform(m);
+    w->currentColour = Colour(argv[0], argv[1], argv[2]);
 }
 
-void cmdRotate   (scene *sc, uint32_t curLine, char *first, float argv[15])
+static void cmdDiffuse  (Hw3File *w, uint32_t curLine, double argv[15])
 {
-    matrix m;
-    vector axis;
-    axis.set(argv[0], argv[1], argv[2]);
-    m.rotation(axis, argv[3]);
-    sc->applyTransform(m);
+    w->currentDiffuse = (argv[0] + argv[1] + argv[2]) / 3;
 }
 
-void cmdScale    (scene *sc, uint32_t curLine, char *first, float argv[15])
+static void cmdSpecular (Hw3File *w, uint32_t curLine, double argv[15])
 {
-    matrix m;
-    m.scale(argv[0], argv[1], argv[2]);
-    sc->applyTransform(m);
+    w->currentSpecular = (argv[0] + argv[1] + argv[2]) / 3;
 }
 
-void cmdPushT    (scene *sc, uint32_t curLine, char *first, float argv[15])
+static void cmdShine    (Hw3File *w, uint32_t curLine, double argv[15])
 {
-    sc->pushMatrix();
+    w->currentReflective = argv[0];
 }
 
-void cmdPopT     (scene *sc, uint32_t curLine, char *first, float argv[15])
+static void cmdEmission (Hw3File *w, uint32_t curLine, double argv[15])
 {
-    sc->popMatrix();
+    w->currentEmission = (argv[0] + argv[1] + argv[2]) / 3;
 }
 
 #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;
 }
-#endif
 
-void cmdAmbient  (scene *sc, uint32_t curLine, char *first, float argv[15])
+static void cmdMaxVertN (Hw3File *w, uint32_t curLine, double argv[15])
 {
-    sc->ambient = color(argv[0], argv[1], argv[2]);
+    /* ignore for now */
 }
 
-void cmdDiffuse  (scene *sc, uint32_t curLine, char *first, float argv[15])
+static void cmdVertex   (Hw3File *w, uint32_t curLine, double argv[15])
 {
-    sc->diffuse = color(argv[0], argv[1], argv[2]);
+    sc->vertex[sc->curVertex].set(argv[0], argv[1], argv[2]);
+    sc->curVertex++;
 }
 
-void cmdSpecular (scene *sc, uint32_t curLine, char *first, float argv[15])
+static void cmdVertexN  (Hw3File *w, uint32_t curLine, double argv[15])
 {
-    sc->specular = color(argv[0], argv[1], argv[2]);
+    /* ignore for now */
 }
 
-void cmdShine    (scene *sc, uint32_t curLine, char *first, float argv[15])
+static void cmdTri      (Hw3File *w, uint32_t curLine, double argv[15])
 {
-    sc->shininess = argv[0];
+    /* 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 cmdEmission (scene *sc, uint32_t curLine, char *first, float argv[15])
+static cmd_def commandList[] =
 {
-    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)
-        {
-            delete sc;
-            sc = NULL;
-        }
-        else
+        char buffer[512];
+        int line = 0;
+        while(!feof(fp))
         {
-            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))
+            {
+                continue; /* Ingore empty line or commented lines */
+            }
+
+            for (i = 0; i < CMD_COUNT; i++)
             {
-                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++)
+                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)
                                 {
-                                    buff[l++] = buffer[j];
+                                    strcpy(first, buff);
                                 }
-                                else
+                                if (strlen(buff) > 0)
                                 {
-                                    buff[l] = 0;
-                                    l = 0;
-                                    if (k == 0)
-                                    {
-                                        strcpy(first, buff);
-                                    }
-                                    if (strlen(buff) > 0)
-                                    {
-                                        value[k++] = atof(buff);
-                                    }
+                                    value[k++] = atof(buff);
                                 }
                             }
-                            if (k != abs(commandList[i].numparam))
-                            {
-                                printf("line %d malformed: given %d parameter, expected %d\n%s", line, k, abs(commandList[i].numparam), buffer);
-                                sc = NULL;
-                                goto exit;
-                            }
                         }
-                        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
+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;
+}

+ 5 - 0
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)

+ 42 - 0
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 <stdio.h>
+
+#include <world.h>
+#include <worldbuilder.h>
+#include <light.h>
+#include <sphere.h>
+#include <material.h>
+#include <colour.h>
+#include <canvas.h>
+#include <camera.h>
+#include <transformation.h>
+
+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;
+}