mirror of
https://github.com/recastnavigation/recastnavigation.git
synced 2026-10-15 21:35:44 +00:00
Moved mesh loading to a method in Mesh class
This commit is contained in:
@@ -20,7 +20,6 @@
|
||||
|
||||
#include "PartitionedMesh.h"
|
||||
#include "DebugDraw.h"
|
||||
#include "MeshLoaderObj.h"
|
||||
#include "Recast.h"
|
||||
#include "Sample.h"
|
||||
|
||||
@@ -134,6 +133,214 @@ char* parseRow(char* buf, char* bufEnd, char* row, int len)
|
||||
row[n] = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
bool isectSegAABB(const float* sp, const float* sq, const float* amin, const float* amax, float& tmin, float& tmax)
|
||||
{
|
||||
static const float EPS = 1e-6f;
|
||||
|
||||
float d[]{sq[0] - sp[0], sq[1] - sp[1], sq[2] - sp[2]};
|
||||
tmin = 0.0;
|
||||
tmax = 1.0f;
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (fabsf(d[i]) < EPS)
|
||||
{
|
||||
if (sp[i] < amin[i] || sp[i] > amax[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const float ood = 1.0f / d[i];
|
||||
float t1 = (amin[i] - sp[i]) * ood;
|
||||
float t2 = (amax[i] - sp[i]) * ood;
|
||||
if (t1 > t2)
|
||||
{
|
||||
float tmp = t1;
|
||||
t1 = t2;
|
||||
t2 = tmp;
|
||||
}
|
||||
if (t1 > tmin)
|
||||
{
|
||||
tmin = t1;
|
||||
}
|
||||
if (t2 < tmax)
|
||||
{
|
||||
tmax = t2;
|
||||
}
|
||||
if (tmin > tmax)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
char* readRow(char* buf, char* bufEnd, char* row, int len)
|
||||
{
|
||||
// skip leading whitespace
|
||||
for (; buf < bufEnd; ++buf)
|
||||
{
|
||||
char c = *buf;
|
||||
if (c != '\\' && c != '\r' && c != '\n' && c != '\t' && c != ' ')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int n = 0;
|
||||
for (; buf < bufEnd; ++buf)
|
||||
{
|
||||
char c = *buf;
|
||||
|
||||
if (c == '\n')
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (c == '\\' || c == '\r')
|
||||
{
|
||||
// skip
|
||||
continue;
|
||||
}
|
||||
|
||||
// Copy character
|
||||
row[n++] = c;
|
||||
if (n >= len - 1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
row[n] = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
int readFace(char* row, int* data, int maxDataLen, int vertCount)
|
||||
{
|
||||
int numVertices = 0;
|
||||
while (*row != '\0')
|
||||
{
|
||||
// Skip initial white space
|
||||
while (*row != '\0' && (*row == ' ' || *row == '\t'))
|
||||
{
|
||||
row++;
|
||||
}
|
||||
|
||||
char* s = row;
|
||||
// Find vertex delimiter and terminate the string there for conversion.
|
||||
while (*row != '\0' && *row != ' ' && *row != '\t')
|
||||
{
|
||||
if (*row == '/')
|
||||
{
|
||||
*row = '\0';
|
||||
}
|
||||
row++;
|
||||
}
|
||||
|
||||
if (*s == '\0')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int vertexIndex = atoi(s);
|
||||
data[numVertices++] = vertexIndex < 0 ? vertexIndex + vertCount : vertexIndex - 1;
|
||||
if (numVertices >= maxDataLen)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return numVertices;
|
||||
}
|
||||
}
|
||||
|
||||
void Mesh::readFromObj(char *buf, size_t bufLen)
|
||||
{
|
||||
char* src = buf;
|
||||
char* srcEnd = buf + bufLen;
|
||||
char row[512];
|
||||
int face[32];
|
||||
float x, y, z;
|
||||
int numVertices;
|
||||
|
||||
while (src < srcEnd)
|
||||
{
|
||||
// Parse one row
|
||||
row[0] = '\0';
|
||||
src = readRow(src, srcEnd, row, sizeof(row) / sizeof(row[0]));
|
||||
|
||||
if (row[0] == '#')
|
||||
{
|
||||
// Comment
|
||||
continue;
|
||||
}
|
||||
if (row[0] == 'v' && row[1] != 'n' && row[1] != 't')
|
||||
{
|
||||
// Vertex pos
|
||||
sscanf(row + 1, "%f %f %f", &x, &y, &z);
|
||||
verts.push_back(x);
|
||||
verts.push_back(y);
|
||||
verts.push_back(z);
|
||||
}
|
||||
if (row[0] == 'f')
|
||||
{
|
||||
// Face
|
||||
const int vertCount = static_cast<int>(verts.size()) / 3;
|
||||
numVertices = readFace(row + 1, face, sizeof(face) / sizeof(face[0]), vertCount);
|
||||
for (int i = 2; i < numVertices; ++i)
|
||||
{
|
||||
const int a = face[0];
|
||||
const int b = face[i - 1];
|
||||
const int c = face[i];
|
||||
if (a < 0 || a >= vertCount || b < 0 || b >= vertCount || c < 0 || c >= vertCount)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
tris.push_back(a);
|
||||
tris.push_back(b);
|
||||
tris.push_back(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate face normals.
|
||||
normals.resize(tris.size());
|
||||
for (int i = 0; i < static_cast<int>(tris.size()); i += 3)
|
||||
{
|
||||
const float* vertex0 = &verts[tris[i + 0] * 3];
|
||||
const float* vertex1 = &verts[tris[i + 1] * 3];
|
||||
const float* vertex2 = &verts[tris[i + 2] * 3];
|
||||
|
||||
// Construct two triangle edges
|
||||
float edge0[3];
|
||||
float edge1[3];
|
||||
for (int j = 0; j < 3; ++j)
|
||||
{
|
||||
edge0[j] = vertex1[j] - vertex0[j];
|
||||
edge1[j] = vertex2[j] - vertex0[j];
|
||||
}
|
||||
|
||||
float* normal = &normals[i];
|
||||
|
||||
// Cross product
|
||||
normal[0] = edge0[1] * edge1[2] - edge0[2] * edge1[1];
|
||||
normal[1] = edge0[2] * edge1[0] - edge0[0] * edge1[2];
|
||||
normal[2] = edge0[0] * edge1[1] - edge0[1] * edge1[0];
|
||||
|
||||
// Normalize
|
||||
float normalLength = sqrtf(normal[0] * normal[0] + normal[1] * normal[1] + normal[2] * normal[2]);
|
||||
if (normalLength > 0)
|
||||
{
|
||||
normalLength = 1.0f / normalLength;
|
||||
normal[0] *= normalLength;
|
||||
normal[1] *= normalLength;
|
||||
normal[2] *= normalLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InputGeom::~InputGeom()
|
||||
@@ -163,7 +370,8 @@ bool InputGeom::loadMesh(rcContext* ctx, const std::string& filepath)
|
||||
offMeshConCount = 0;
|
||||
convexVolumeCount = 0;
|
||||
|
||||
parseObjData(buffer, bufferLen, mesh.verts, mesh.tris, mesh.normals);
|
||||
mesh.reset();
|
||||
mesh.readFromObj(buffer, bufferLen);
|
||||
rcCalcBounds(mesh.verts.data(), mesh.getVertCount(), meshBoundsMin, meshBoundsMax);
|
||||
|
||||
delete partitionedMesh;
|
||||
@@ -408,52 +616,6 @@ bool InputGeom::saveGeomSet(const BuildSettings* settings)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool isectSegAABB(const float* sp, const float* sq, const float* amin, const float* amax, float& tmin, float& tmax)
|
||||
{
|
||||
static const float EPS = 1e-6f;
|
||||
|
||||
float d[]{sq[0] - sp[0], sq[1] - sp[1], sq[2] - sp[2]};
|
||||
tmin = 0.0;
|
||||
tmax = 1.0f;
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (fabsf(d[i]) < EPS)
|
||||
{
|
||||
if (sp[i] < amin[i] || sp[i] > amax[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const float ood = 1.0f / d[i];
|
||||
float t1 = (amin[i] - sp[i]) * ood;
|
||||
float t2 = (amax[i] - sp[i]) * ood;
|
||||
if (t1 > t2)
|
||||
{
|
||||
float tmp = t1;
|
||||
t1 = t2;
|
||||
t2 = tmp;
|
||||
}
|
||||
if (t1 > tmin)
|
||||
{
|
||||
tmin = t1;
|
||||
}
|
||||
if (t2 < tmax)
|
||||
{
|
||||
tmax = t2;
|
||||
}
|
||||
if (tmin > tmax)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InputGeom::raycastMesh(float* src, float* dst, float& tmin)
|
||||
{
|
||||
// Prune hit ray.
|
||||
|
||||
Reference in New Issue
Block a user