26char*
ParseRow(
char* buf,
const char*
const bufEnd,
char* row,
const I32 len)
noexcept {
31 while (!done && buf < bufEnd) {
68 while (*row !=
'\0') {
70 while (*row !=
'\0' && (*row ==
' ' || *row ==
'\t')) {
76 while (*row !=
'\0' && *row !=
' ' && *row !=
'\t') {
87 const I32 vi = atoi(s);
88 data[j++] = vi < 0 ? vi + vcnt : vi - 1;
97 STUBBED(
"ToDo: Rework load/save to properly use a ByteBuffer instead of this const char* hackery. -Ionut");
106 tempBuffer >> tempVer;
112 std::memcpy(buf,
reinterpret_cast<const char*
>(tempBuffer.
contents()), tempBuffer.
storageSize());
120 while (src < srcEnd) {
123 src =
ParseRow(src, srcEnd, row,
sizeof row /
sizeof(
char));
128 if (row[0] ==
'v' && row[1] !=
'n' && row[1] !=
't') {
130 const I32 result = sscanf(row + 1,
"%f %f %f", &x, &y, &z);
137 for (
I32 i = 2; i < nv; ++i) {
138 const I32 a = face[0];
139 const I32 b = face[i - 1];
140 const I32 c = face[i];
162 F32 e0[3] = {}, e1[3] = {};
163 for (
I32 j = 0; j < 3; ++j) {
164 e0[j] = v1[j] - v0[j];
165 e1[j] = v2[j] - v0[j];
169 n[0] = e0[1] * e1[2] - e0[2] * e1[1];
170 n[1] = e0[2] * e1[0] - e0[0] * e1[2];
171 n[2] = e0[0] * e1[1] - e0[1] * e1[0];
172 F32 d = sqrtf(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]);
196 const F32* vp = vStart + i * 3;
197 tempBuffer <<
"v " << *vp <<
" " << *(vp + 1) <<
" " << *(vp + 2) <<
"\n";
200 const I32* tp = tStart + i * 3;
201 tempBuffer <<
"f " << *tp + 1 <<
" " << *(tp + 1) + 1 <<
" " << *(tp + 2) + 1 <<
"\n";
204 return tempBuffer.
dumpToFile(filePath, filename);
209 const bool delOriginals ) {
225 while (newCap < totalVertCt) {
239 while (newCap < totalTriCt) {
251 memcpy(bFacePt, b.
getTris(), bFaceSize *
sizeof(
I32));
253 for (
U32 i = 0; i <
to_U32(bFaceSize); i++) {
272 assert(modelData !=
nullptr);
274 if (modelData->getVertCount() + 1 > modelData->_vertexCapacity)
276 modelData->_vertexCapacity = !modelData->_vertexCapacity ? 8 : modelData->_vertexCapacity * 2;
278 modelData->_vertices.resize(modelData->_vertexCapacity * 3);
281 F32* dst = &modelData->_vertices[modelData->getVertCount() * 3];
286 modelData->_vertexCount++;
291 const U32 triangleIndexOffset,
293 if (modelData->getTriCount() + 1 > modelData->_triangleCapacity)
295 modelData->_triangleCapacity = !modelData->_triangleCapacity ? 8 : modelData->_triangleCapacity * 2;
297 modelData->_triangles.resize(modelData->_triangleCapacity * 3);
300 I32* dst = &modelData->_triangles[modelData->getTriCount() * 3];
302 *dst++ =
to_I32(triangleIndices.
x + triangleIndexOffset);
303 *dst++ =
to_I32(triangleIndices.
y + triangleIndexOffset);
304 *dst++ =
to_I32(triangleIndices.
z + triangleIndexOffset);
306 modelData->getAreaTypes().push_back(areaType);
307 modelData->_triangleCount++;
312 assert(sgn !=
nullptr);
320 const char* resourceName = sgn->
getNode().resourceName().c_str();
366 Object3D* obj =
nullptr;
369 obj = &sgn->
getNode<Object3D>();
373 obj =
Get(sgn->
getNode<WaterPlane>().getQuad());
375 assert(obj !=
nullptr);
376 geometry = obj->geometryBuffer().get();
377 assert(geometry !=
nullptr);
380 if (vertices.empty()) {
385 const auto& triangles = obj->getTriangles(obj->getGeometryPartitionID(0u));
386 if (triangles.empty()) {
396 AddVertex(&outData, nodeTransform * vert._position);
399 for (
const vec3<U32>& triangle : triangles) {
400 AddTriangle(&outData, triangle, currentTriangleIndexOffset, areaType);
403 std::array<vec3<F32>, 8> vertices = box.
getPoints();
405 for (
U32 i = 0; i < 8; i++) {
409 for (
U32 f = 0; f < 6; f++) {
410 for (
U32 v = 2; v < 4; v++) {
415 currentTriangleIndexOffset, areaType);
428 for (
U32 i = 0u; i < childCount; ++i) {
const F32 * getVerts() const noexcept
U32 getVertCount() const noexcept
U32 getTriCount() const noexcept
const I32 * getTris() const noexcept
std::array< vec3< F32 >, 8 > getPoints() const noexcept
F32 getHeight() const noexcept
const BoundingBox & getBoundingBox() const noexcept
size_t storageSize() const noexcept
Returns the total size (in bytes) of the underlying storage, regardles of wpos and rpos.
const Byte * contents() const noexcept
Returns a raw pointer to the underlying storage data. Does NOT depend on the read head position!...
bool loadFromFile(const ResourcePath &path, std::string_view fileName, const U8 version=BUFFER_FORMAT_VERSION)
bool dumpToFile(const ResourcePath &path, std::string_view fileName, const U8 version=BUFFER_FORMAT_VERSION)
Saves the entire buffer contents to file. Always appends the version at the end of the file.
const NavigationContext & navigationContext() const noexcept
bool navMeshDetailOverride() const noexcept
FORCE_INLINE T * get() const
Returns a pointer to a specific component. Returns null if the SGN does not have the component reques...
ChildContainer & getChildren() noexcept
const vector< Vertex > & getVertices() const noexcept
bool SaveMeshFile(const NavModelData &inData, const ResourcePath &filePath, const char *filename)
Save the navigation input geometry in Wavefront OBJ format.
constexpr U32 g_cubeFaces[6][4]
void AddVertex(NavModelData *modelData, const vec3< F32 > &vertex)
char * ParseRow(char *buf, const char *const bufEnd, char *row, I32 len) noexcept
constexpr U16 BYTE_BUFFER_VERSION
bool LoadMeshFile(NavModelData &outData, const ResourcePath &filePath, const char *fileName)
Load the input geometry from file (Wavefront OBJ format) and save it in 'outData'.
bool Parse(const BoundingBox &box, NavModelData &outData, SceneGraphNode *sgn)
Parsing method that calls itself recursively until all geometry has been parsed.
NavModelData MergeModels(NavModelData &a, NavModelData &b, bool delOriginals=false)
Merge the data from two navigation geometry sources.
I32 ParseFace(char *row, I32 *data, I32 n, I32 vcnt) noexcept
void AddTriangle(NavModelData *modelData, const vec3< U32 > &triangleIndices, U32 triangleIndexOffset=0, const SamplePolyAreas &areaType=SamplePolyAreas::SAMPLE_POLYAREA_GROUND)
const vec3< F32 > g_borderOffset(BORDER_PADDING)
constexpr F32 BORDER_PADDING
Str StringFormat(const char *fmt, Args &&...args)
constexpr U32 to_U32(const T value)
SceneNodeType
ToDo: Move particle emitter to components (it will make them way more dynamic) - Ionut.
FORCE_INLINE constexpr bool Is3DObject(const SceneNodeType type) noexcept
constexpr I32 to_I32(const T value)
static const mat4< F32 > MAT4_IDENTITY
FORCE_INLINE T * Get(const Handle< T > handle)
constexpr auto to_base(const Type value) -> Type
static NO_INLINE void d_printfn(const char *format, T &&... args)
static NO_INLINE void errorfn(const char *format, T &&... args)
static NO_INLINE void printfn(const char *format, T &&... args)
eastl::fixed_vector< SceneGraphNode *, 32, true > _data