Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/WolfireGames/overgrowth.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Source/AI/mesh_loader_obj.cpp')
-rw-r--r--Source/AI/mesh_loader_obj.cpp243
1 files changed, 243 insertions, 0 deletions
diff --git a/Source/AI/mesh_loader_obj.cpp b/Source/AI/mesh_loader_obj.cpp
new file mode 100644
index 00000000..50052a35
--- /dev/null
+++ b/Source/AI/mesh_loader_obj.cpp
@@ -0,0 +1,243 @@
+//-----------------------------------------------------------------------------
+// Name: mesh_loader_obj.cpp
+// Developer: External
+// Author:
+// Description: This is a utility file from the Recast project which has been
+// extracted and modified by Wolfire Games LLC
+// License: Read below
+//-----------------------------------------------------------------------------
+
+//
+// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would be
+// appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+// misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+//
+
+#include "mesh_loader_obj.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <cstring>
+#define _USE_MATH_DEFINES
+#include <math.h>
+#include <Compat/fileio.h>
+
+using std::string;
+
+rcMeshLoaderObj::rcMeshLoaderObj() :
+ m_scale(1.0f),
+ m_verts(0),
+ m_tris(0),
+ m_normals(0),
+ m_vertCount(0),
+ m_triCount(0)
+{
+}
+
+rcMeshLoaderObj::~rcMeshLoaderObj()
+{
+ delete [] m_verts;
+ delete [] m_normals;
+ delete [] m_tris;
+}
+
+void rcMeshLoaderObj::addVertex(float x, float y, float z, int& cap)
+{
+ if (m_vertCount+1 > cap)
+ {
+ cap = !cap ? 8 : cap*2;
+ float* nv = new float[cap*3];
+ if (m_vertCount)
+ memcpy(nv, m_verts, m_vertCount*3*sizeof(float));
+ delete [] m_verts;
+ m_verts = nv;
+ }
+ float* dst = &m_verts[m_vertCount*3];
+ *dst++ = x*m_scale;
+ *dst++ = y*m_scale;
+ *dst++ = z*m_scale;
+ m_vertCount++;
+}
+
+void rcMeshLoaderObj::addTriangle(int a, int b, int c, int& cap)
+{
+ if (m_triCount+1 > cap)
+ {
+ cap = !cap ? 8 : cap*2;
+ int* nv = new int[cap*3];
+ if (m_triCount)
+ memcpy(nv, m_tris, m_triCount*3*sizeof(int));
+ delete [] m_tris;
+ m_tris = nv;
+ }
+ int* dst = &m_tris[m_triCount*3];
+ *dst++ = a;
+ *dst++ = b;
+ *dst++ = c;
+ m_triCount++;
+}
+
+static char* parseRow(char* buf, char* bufEnd, char* row, int len)
+{
+ bool start = true;
+ bool done = false;
+ int n = 0;
+ while (!done && buf < bufEnd)
+ {
+ char c = *buf;
+ buf++;
+ // multirow
+ switch (c)
+ {
+ case '\\':
+ break;
+ case '\n':
+ if (start) break;
+ done = true;
+ break;
+ case '\r':
+ break;
+ case '\t':
+ case ' ':
+ if (start) break;
+ default:
+ start = false;
+ row[n++] = c;
+ if (n >= len-1)
+ done = true;
+ break;
+ }
+ }
+ row[n] = '\0';
+ return buf;
+}
+
+static int parseFace(char* row, int* data, int n, int vcnt)
+{
+ int j = 0;
+ while (*row != '\0')
+ {
+ // Skip initial white space
+ while (*row != '\0' && (*row == ' ' || *row == '\t'))
+ row++;
+ char* s = row;
+ // Find vertex delimiter and terminated the string there for conversion.
+ while (*row != '\0' && *row != ' ' && *row != '\t')
+ {
+ if (*row == '/') *row = '\0';
+ row++;
+ }
+ if (*s == '\0')
+ continue;
+ int vi = atoi(s);
+ data[j++] = vi < 0 ? vi+vcnt : vi-1;
+ if (j >= n) return j;
+ }
+ return j;
+}
+
+bool rcMeshLoaderObj::load(const string& filename)
+{
+ char* buf = 0;
+ FILE* fp = my_fopen(filename.c_str(), "rb");
+ if (!fp)
+ return false;
+ fseek(fp, 0, SEEK_END);
+ int bufSize = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+ buf = new char[bufSize];
+ if (!buf)
+ {
+ fclose(fp);
+ return false;
+ }
+ size_t readLen = fread(buf, bufSize, 1, fp);
+ fclose(fp);
+
+ if (readLen != 1)
+ {
+ delete[] buf;
+ return false;
+ }
+
+ char* src = buf;
+ char* srcEnd = buf + bufSize;
+ char row[512];
+ int face[32];
+ float x,y,z;
+ int nv;
+ int vcap = 0;
+ int tcap = 0;
+
+ while (src < srcEnd)
+ {
+ // Parse one row
+ row[0] = '\0';
+ src = parseRow(src, srcEnd, row, sizeof(row)/sizeof(char));
+ // Skip comments
+ if (row[0] == '#') continue;
+ if (row[0] == 'v' && row[1] != 'n' && row[1] != 't')
+ {
+ // Vertex pos
+ sscanf(row+1, "%f %f %f", &x, &y, &z);
+ addVertex(x, y, z, vcap);
+ }
+ if (row[0] == 'f')
+ {
+ // Faces
+ nv = parseFace(row+1, face, 32, m_vertCount);
+ for (int i = 2; i < nv; ++i)
+ {
+ const int a = face[0];
+ const int b = face[i-1];
+ const int c = face[i];
+ if (a < 0 || a >= m_vertCount || b < 0 || b >= m_vertCount || c < 0 || c >= m_vertCount)
+ continue;
+ addTriangle(a, b, c, tcap);
+ }
+ }
+ }
+
+ delete [] buf;
+
+ // Calculate normals.
+ m_normals = new float[m_triCount*3];
+ for (int i = 0; i < m_triCount*3; i += 3)
+ {
+ const float* v0 = &m_verts[m_tris[i]*3];
+ const float* v1 = &m_verts[m_tris[i+1]*3];
+ const float* v2 = &m_verts[m_tris[i+2]*3];
+ float e0[3], e1[3];
+ for (int j = 0; j < 3; ++j)
+ {
+ e0[j] = v1[j] - v0[j];
+ e1[j] = v2[j] - v0[j];
+ }
+ float* n = &m_normals[i];
+ n[0] = e0[1]*e1[2] - e0[2]*e1[1];
+ n[1] = e0[2]*e1[0] - e0[0]*e1[2];
+ n[2] = e0[0]*e1[1] - e0[1]*e1[0];
+ float d = sqrtf(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]);
+ if (d > 0)
+ {
+ d = 1.0f/d;
+ n[0] *= d;
+ n[1] *= d;
+ n[2] *= d;
+ }
+ }
+
+ m_filename = filename;
+ return true;
+}