forked from LeenkxTeam/LNXSDK
137 lines
4.1 KiB
JavaScript
137 lines
4.1 KiB
JavaScript
|
const fs = require('fs');
|
||
|
const Recast = require("../haxerecast/recastjs/recast");
|
||
|
|
||
|
// Get mesh path and NavMesh config
|
||
|
const recast_settings = process.argv[3];
|
||
|
const path_mesh = './' + process.argv[2] + '.obj'
|
||
|
|
||
|
// Read OBJ file and build NavMesh
|
||
|
readObjFile(path_mesh, (error, vertices, vertexLength, indices, indexLength) => {
|
||
|
if (error) {
|
||
|
console.error('Error:', error);
|
||
|
} else {
|
||
|
buildNavMesh(vertices, vertexLength, indices, indexLength);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// Parse OBJ file
|
||
|
function readObjFile(objFilePath, callback) {
|
||
|
try {
|
||
|
// Read the OBJ file
|
||
|
const objFileContent = fs.readFileSync(objFilePath, 'utf-8');
|
||
|
|
||
|
// Process the OBJ content
|
||
|
const vertices = [];
|
||
|
const indices = [];
|
||
|
|
||
|
vertices.length
|
||
|
|
||
|
const lines = objFileContent.split('\n');
|
||
|
lines.forEach((line) => {
|
||
|
const parts = line.trim().split(/\s+/);
|
||
|
|
||
|
if (parts[0] === 'v') {
|
||
|
// Vertex data
|
||
|
const x = parseFloat(parts[1]);
|
||
|
const y = parseFloat(parts[2]);
|
||
|
const z = parseFloat(parts[3]);
|
||
|
vertices.push(x, y, z);
|
||
|
} else if (parts[0] === 'f') {
|
||
|
// Face data
|
||
|
const faceIndices = parts.slice(1).map((vertex) => parseInt(vertex.split('/')[0]) - 1);
|
||
|
indices.push(...faceIndices);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// Call the callback with the result
|
||
|
callback(null, vertices, vertices.length, indices, indices.length);
|
||
|
} catch (error) {
|
||
|
callback(error);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function buildNavMesh (vertices, vertexLength, indices, indexLength) {
|
||
|
|
||
|
recastSettings = JSON.parse(recast_settings);
|
||
|
|
||
|
Recast().then(function(Recast) {
|
||
|
|
||
|
// Copy recast config settings
|
||
|
var recastConfig = new Recast.rcConfig();
|
||
|
recastConfig.width = recastSettings.width;
|
||
|
recastConfig.height = recastSettings.height;
|
||
|
if(recastSettings.tiledMesh) {
|
||
|
recastConfig.tileSize = recastSettings.tileSize;
|
||
|
}
|
||
|
else {
|
||
|
recastConfig.tileSize = 0;
|
||
|
}
|
||
|
recastConfig.borderSize = recastSettings.borderSize;
|
||
|
recastConfig.cs = recastSettings.cellSize;
|
||
|
recastConfig.ch = recastSettings.cellHeight;
|
||
|
recastConfig.walkableSlopeAngle = recastSettings.walkableSlopeAngle;
|
||
|
recastConfig.walkableHeight = recastSettings.walkableHeight;
|
||
|
recastConfig.walkableClimb = recastSettings.walkableClimb;
|
||
|
recastConfig.walkableRadius = recastSettings.walkableRadius;
|
||
|
recastConfig.maxEdgeLen = recastSettings.maxEdgeLen;
|
||
|
recastConfig.maxSimplificationError = recastSettings.maxSimplificationError;
|
||
|
recastConfig.minRegionArea = recastSettings.minRegionArea;
|
||
|
recastConfig.mergeRegionArea = recastSettings.mergeRegionArea;
|
||
|
recastConfig.maxVertsPerPoly = recastSettings.maxVertsPerPoly;
|
||
|
recastConfig.detailSampleDist = recastSettings.detailSampleDist;
|
||
|
recastConfig.detailSampleMaxError = recastSettings.detailSampleMaxError;
|
||
|
|
||
|
// Init NavMesh
|
||
|
var navNesh = new Recast.NavMesh();
|
||
|
// Build NavMesh
|
||
|
navNesh.build(vertices, vertexLength, indices, indexLength, recastConfig);
|
||
|
// Create debug NavMesh for visualization
|
||
|
var debugNavMesh = navNesh.getDebugNavMesh();
|
||
|
|
||
|
var trianglesCount = debugNavMesh.getTriangleCount();
|
||
|
triangelVertices = []
|
||
|
triangleFaces = []
|
||
|
// Loop through triangles
|
||
|
for(let runTriangle = 0; runTriangle < trianglesCount; runTriangle++) {
|
||
|
var triangle = debugNavMesh.getTriangle(runTriangle);
|
||
|
// Get triangle vertices
|
||
|
var points = [triangle.getPoint(0),
|
||
|
triangle.getPoint(1),
|
||
|
triangle.getPoint(2)];
|
||
|
|
||
|
// Get vertex positon
|
||
|
for(var i in points) {
|
||
|
// y, z interchanged
|
||
|
triangelVertices.push([points[i].x, points[i].z, points[i].y]);
|
||
|
}
|
||
|
// Get triangle indices
|
||
|
var face = [3 * runTriangle + 1,
|
||
|
3 * runTriangle + 2,
|
||
|
3 * runTriangle + 3];
|
||
|
|
||
|
|
||
|
triangleFaces.push(face);
|
||
|
}
|
||
|
|
||
|
// Get OBJ format of triangles
|
||
|
var navMeshObj = saveGeometryToObj(triangelVertices, triangleFaces);
|
||
|
|
||
|
// Write to OBJ file
|
||
|
fs.writeFile(path_mesh, navMeshObj, function (err) {
|
||
|
if (err) throw err;
|
||
|
});
|
||
|
|
||
|
});
|
||
|
}
|
||
|
|
||
|
function saveGeometryToObj (vertices, faces) {
|
||
|
var buffer = '';
|
||
|
|
||
|
//Write Vertices
|
||
|
for (var i in vertices) buffer += 'v ' + (vertices[i][0]) + ' ' + vertices[i][1] + ' ' + vertices[i][2] + '\n';
|
||
|
|
||
|
//Write Faces
|
||
|
for (var i in faces) buffer += 'f ' + (faces[i][0]) + ' ' + faces[i][1] + ' ' + faces[i][2] + '\n';
|
||
|
|
||
|
return buffer;
|
||
|
}
|