Selaa lähdekoodia

OBJFile now use group instead of it own list.
Change the group function to find group by name, and now name group when needed, and change tests to use group name instead of number.

Also now the default group is the base group, not a separate group.

Bonus: Add a destructor to cleanup memory
Added a function to get base group. OBJFile will still behave as a valid shape, but now we can skip it in the generated world by adding the base group instead.

Code is now cleaner.

Godzil 4 vuotta sitten
vanhempi
commit
15a861802a
3 muutettua tiedostoa jossa 86 lisäystä ja 74 poistoa
  1. 10 4
      source/include/objfile.h
  2. 67 64
      source/shapes/objfile.cpp
  3. 9 6
      tests/objfile_test.cpp

+ 10 - 4
source/include/objfile.h

@@ -18,9 +18,9 @@
 class OBJFile : public Shape
 {
 private:
-    uint32_t allocatedFaceGroupCount;
-    Group* *faceGroupList;
-    uint32_t faceGroupCount;
+    Group *baseGroup;
+
+    Group *currentGroup;
 
     uint32_t allocatedVertexCount;
     Point* *vertexList;
@@ -51,16 +51,20 @@ public:
     OBJFile();
     OBJFile(const char *filepath);
 
+    ~OBJFile();
+
     int parseOBJFile(const char *content);
 
     /* OBJ file expect the first vertice to be 1 and not 0 */
     Point vertices(uint32_t i) { return *this->vertexList[i - 1]; };
     Vector verticesNormal(uint32_t i) { return *this->vertexNormalList[i - 1]; };
-    Group *groups(uint32_t i) { return this->faceGroupList[i];  };
+    Group *groups(const char *groupName);
     Intersect intersect(Ray r);
     BoundingBox getLocalBounds();
     BoundingBox getBounds();
 
+    Shape *getBaseGroup() { return this->baseGroup; };
+
     bool includes(Shape *b);
 
     void updateBoundingBox();
@@ -69,4 +73,6 @@ public:
     void dumpMe(FILE * fp);
 };
 
+#define OBJ_DEFAULT_GROUP "_DefaultObjGroup_"
+
 #endif /* DORAYME_OBJFILE_H */

+ 67 - 64
source/shapes/objfile.cpp

@@ -26,23 +26,49 @@ OBJFile::OBJFile() : Shape(Shape::OBJFILE), ignoredLines(0)
 {
     stats.addOBJFile();
 
-    this->allocatedFaceGroupCount = MIN_ALLOC;
-    this->faceGroupList = (Group **)calloc(sizeof(Group **), MIN_ALLOC);
-    this->faceGroupCount = 0;
-
     this->allocatedVertexCount = MIN_ALLOC;
     this->vertexList = (Point **)calloc(sizeof(Point **), MIN_ALLOC);
     this->vertexCount = 0;
 
-
     this->allocatedVertexNormalCount = MIN_ALLOC;
     this->vertexNormalList = (Vector **)calloc(sizeof(Vector **), MIN_ALLOC);
     this->vertexNormalCount = 0;
 
-    /* There is always a default group */
-    this->addGroup(new Group());
+    /* The base group */
+    this->baseGroup = new Group(OBJ_DEFAULT_GROUP);
+    this->currentGroup = this->baseGroup;
 };
 
+OBJFile::~OBJFile()
+{
+    int i;
+    if (vertexCount > 0)
+    {
+        for(i = 0; i < vertexCount; i++)
+        {
+            delete this->vertexList[i];
+            this->vertexList[i] = nullptr;
+        }
+    }
+    free(this->vertexList);
+    this->vertexList = nullptr;
+
+    if (vertexNormalCount > 0)
+    {
+        for(i = 0; i < vertexNormalCount; i++)
+        {
+            delete this->vertexNormalList[i];
+            this->vertexNormalList[i] = nullptr;
+        }
+    }
+    free(this->vertexNormalList);
+    this->vertexNormalList = nullptr;
+
+    /* It is not our responsibility to clear the group object as this object may be destroyed before the
+     * render is done
+     */
+}
+
 OBJFile::OBJFile(const char *filepath) : OBJFile()
 {
     FILE *fp;
@@ -71,18 +97,13 @@ OBJFile::OBJFile(const char *filepath) : OBJFile()
 
 void OBJFile::addGroup(Group *group)
 {
-    if ((this->faceGroupCount + 1) > this->allocatedFaceGroupCount)
-    {
-        this->allocatedFaceGroupCount *= 2;
-        this->faceGroupList = (Group **)realloc(this->faceGroupList, sizeof(Group **) * this->allocatedFaceGroupCount);
-    }
+    this->baseGroup->addObject(group);
 
     group->parent = this;
     group->updateTransform();
-
-    this->faceGroupList[this->faceGroupCount++] = group;
-
     this->bounds | group->getBounds();
+
+    this->currentGroup = group;
 }
 
 void OBJFile::addVertex(Point *vertex)
@@ -107,44 +128,40 @@ void OBJFile::addVertexNormal(Vector *vertexNormal)
     this->vertexNormalList[this->vertexNormalCount++] = vertexNormal;
 }
 
-Intersect OBJFile::intersect(Ray r)
+Group *OBJFile::groups(const char *groupName)
 {
-    Intersect ret;
-    int i, j;
-    if (this->faceGroupCount > 0)
+    if (strncmp(groupName, this->baseGroup->getName(), strlen(groupName)) == 0)
     {
-        if (this->bounds.intesectMe(r))
-        {
-            for (i = 0 ; i < this->faceGroupCount ; i++)
-            {
-                Intersect xs = this->faceGroupList[i]->intersect(r);
-                if (xs.count() > 0)
-                {
-                    for (j = 0 ; j < xs.count() ; j++)
-                    {
-                        ret.add(xs[j]);
-                    }
-                }
-            }
-        }
+        return this->baseGroup;
     }
-    return ret;
-}
 
-bool OBJFile::includes(Shape *b)
-{
     int i;
-    if (this->faceGroupCount > 0)
+    for(i = 0; i < this->baseGroup->getObjectCount(); i++)
     {
-        for (i = 0 ; i < this->faceGroupCount ; i++)
+        Shape *cur = (*this->baseGroup)[i];
+
+        if (cur->getType() == Shape::GROUP)
         {
-            if (this->faceGroupList[i] == b)
+            Group *curGrp = (Group *)cur;
+            if (strncmp(groupName, curGrp->getName(), strlen(groupName)) == 0)
             {
-                return true;
+                return curGrp;
             }
         }
     }
-    return false;
+
+    /* Not found */
+    return nullptr;
+}
+
+Intersect OBJFile::intersect(Ray r)
+{
+    return this->baseGroup->intersect(r);
+}
+
+bool OBJFile::includes(Shape *b)
+{
+    return this->baseGroup->includes(b);
 }
 
 Intersect OBJFile::localIntersect(Ray r)
@@ -173,14 +190,7 @@ void OBJFile::updateBoundingBox()
     int i;
     this->bounds.reset();
 
-    for(i = 0; i < this->faceGroupCount; i++)
-    {
-        if (this->faceGroupList[i]->haveFiniteBounds())
-        {
-            BoundingBox objB = this->faceGroupList[i]->getBounds();
-            this->bounds | objB;
-        }
-    }
+    this->bounds | this->baseGroup->getBounds();
 }
 
 void OBJFile::updateTransform()
@@ -188,10 +198,8 @@ void OBJFile::updateTransform()
     int i;
 
     Shape::updateTransform();
-    for (i = 0 ; i < this->faceGroupCount ; i++)
-    {
-        this->faceGroupList[i]->updateTransform();
-    }
+
+    this->baseGroup->updateTransform();
 
     /* Once the full stack being notified of the changes, let's update the
      * bounding box
@@ -204,12 +212,7 @@ void OBJFile::dumpMe(FILE * fp)
     int i;
     fprintf(fp, "\"Type\": \"OBJFile\",\n");
     fprintf(fp, "\"Objects\": {\n");
-    for(i = 0; i < this->faceGroupCount; i++)
-    {
-        fprintf(fp, "\"%d\": {\n", i);
-        this->faceGroupList[i]->dumpMe(fp);
-        fprintf(fp, "},\n");
-    }
+    this->baseGroup->dumpMe(fp);
     fprintf(fp, "},\n");
 
     Shape::dumpMe(fp);
@@ -399,7 +402,7 @@ int OBJFile::execLine(int argc, char *argv[], uint32_t currentLine)
                                        this->verticesNormal(vn[2]),
                                        this->verticesNormal(vn[3]));
             }
-            this->faceGroupList[this->faceGroupCount - 1]->addObject(t);
+            this->currentGroup->addObject(t);
             ret = 0;
         }
         else if (argc > 4)
@@ -423,7 +426,7 @@ int OBJFile::execLine(int argc, char *argv[], uint32_t currentLine)
                                            this->verticesNormal(vn[i]),
                                            this->verticesNormal(vn[i + 1]));
                 }
-                this->faceGroupList[this->faceGroupCount - 1]->addObject(t);
+                this->currentGroup->addObject(t);
             }
             ret = 0;
         }
@@ -436,7 +439,7 @@ int OBJFile::execLine(int argc, char *argv[], uint32_t currentLine)
     {
         if (argc == 2)
         {
-            this->addGroup(new Group());
+            this->addGroup(new Group(argv[1]));
         }
         else
         {
@@ -444,4 +447,4 @@ int OBJFile::execLine(int argc, char *argv[], uint32_t currentLine)
         }
     }
     return ret;
-}
+}

+ 9 - 6
tests/objfile_test.cpp

@@ -55,7 +55,7 @@ TEST(OBJFileTest, Parsing_triangle_faces)
     OBJFile parser = OBJFile();
     parser.parseOBJFile(file);
 
-    Group *g0 = parser.groups(0);
+    Group *g0 = parser.groups(OBJ_DEFAULT_GROUP);
 
     Triangle *t1 = (Triangle *)(*g0)[0];
     Triangle *t2 = (Triangle *)(*g0)[1];
@@ -82,7 +82,7 @@ TEST(OBJFileTest, Triangulating_polygons)
     OBJFile parser = OBJFile();
     parser.parseOBJFile(file);
 
-    Group *g0 = parser.groups(0);
+    Group *g0 = parser.groups(OBJ_DEFAULT_GROUP);
 
     Triangle *t1 = (Triangle *)(*g0)[0];
     Triangle *t2 = (Triangle *)(*g0)[1];
@@ -105,9 +105,12 @@ TEST(OBJFileTest, Triangle_in_groups)
 {
     OBJFile parser = OBJFile("triangles.obj");
 
-    /* TODO: Add group name search/test */
-    Group *g1 = parser.groups(1);
-    Group *g2 = parser.groups(2);
+    Group *g1 = parser.groups("FirstGroup");
+    Group *g2 = parser.groups("SecondGroup");
+
+    /* The groups must exists */
+    ASSERT_NE(g1, nullptr);
+    ASSERT_NE(g2, nullptr);
 
     Triangle *t1 = (Triangle *)(*g1)[0];
     Triangle *t2 = (Triangle *)(*g2)[0];
@@ -151,7 +154,7 @@ TEST(OBJFileTest, Faces_with_normal)
     OBJFile parser = OBJFile();
     parser.parseOBJFile(file);
 
-    Group *g0 = parser.groups(0);
+    Group *g0 = parser.groups(OBJ_DEFAULT_GROUP);
 
     SmoothTriangle *t1 = (SmoothTriangle *)(*g0)[0];
     SmoothTriangle *t2 = (SmoothTriangle *)(*g0)[1];