Obj
This commit is contained in:
parent
8a38007e35
commit
aeed8530ad
|
@ -6,5 +6,6 @@
|
||||||
|
|
||||||
namespace orange::fs
|
namespace orange::fs
|
||||||
{
|
{
|
||||||
Result<Buffer> OpenFileIntoBuffer(const char* path, bool text = false);
|
Result<Buffer> OpenFileIntoBuffer(const char* path);
|
||||||
|
Result<TextBuffer> OpenFileIntoTextBuffer(const char* path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace orange::stream
|
||||||
if (result.ec == std::errc{})
|
if (result.ec == std::errc{})
|
||||||
{
|
{
|
||||||
first = result.ptr;
|
first = result.ptr;
|
||||||
return Result<T>::Success(obj);
|
return Result<T>::Success(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result<T>::Error(BasicErrorCode::NotFound);
|
return Result<T>::Error(BasicErrorCode::NotFound);
|
||||||
|
@ -35,6 +35,11 @@ namespace orange::stream
|
||||||
return Parse<T>(first, first + strlen(first));
|
return Parse<T>(first, first + strlen(first));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool EndOfStream(const char* first, const char* end)
|
||||||
|
{
|
||||||
|
return first == end || *first == '\0';
|
||||||
|
}
|
||||||
|
|
||||||
inline bool CharMatches(char character, StringView delims)
|
inline bool CharMatches(char character, StringView delims)
|
||||||
{
|
{
|
||||||
for (auto delim : delims)
|
for (auto delim : delims)
|
||||||
|
@ -46,10 +51,10 @@ namespace orange::stream
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t Consume(const char*& first, StringView delims)
|
inline size_t Consume(const char*& first, const char* end, StringView delims)
|
||||||
{
|
{
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
while (CharMatches(*first, delims))
|
while (!EndOfStream(first, end) && CharMatches(*first, delims))
|
||||||
{
|
{
|
||||||
first++;
|
first++;
|
||||||
count++;
|
count++;
|
||||||
|
@ -58,16 +63,16 @@ namespace orange::stream
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t ConsumeSpace(const char*& first)
|
inline size_t ConsumeSpace(const char*& first, const char* end)
|
||||||
{
|
{
|
||||||
return Consume(first, " \t");
|
return Consume(first, end, " \t");
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename OutArray = SmallVector<char, 1>>
|
template <typename OutArray = SmallVector<char, 1>>
|
||||||
size_t ReadOrAdvance(const char*& first, StringView delims, size_t advancement = 0, OutArray* array = nullptr)
|
size_t ReadOrAdvance(const char*& first, const char* end, StringView delims, size_t advancement = 0, OutArray* array = nullptr)
|
||||||
{
|
{
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
while (!CharMatches(*first, delims) && *first != '\0')
|
while (!EndOfStream(first, end) && !CharMatches(*first, delims))
|
||||||
{
|
{
|
||||||
if (array)
|
if (array)
|
||||||
array->PushBack(*first);
|
array->PushBack(*first);
|
||||||
|
@ -75,7 +80,7 @@ namespace orange::stream
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*first == '\0')
|
if (EndOfStream(first, end))
|
||||||
return count;
|
return count;
|
||||||
|
|
||||||
first += advancement;
|
first += advancement;
|
||||||
|
@ -84,13 +89,13 @@ namespace orange::stream
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename OutArray = SmallVector<char, 1>>
|
template <typename OutArray = SmallVector<char, 1>>
|
||||||
size_t ReadString(const char*& first, StringView delims, OutArray& array)
|
size_t ReadString(const char*& first, const char* end, StringView delims, OutArray& array)
|
||||||
{
|
{
|
||||||
return ReadOrAdvance(first, delims, 0, &array);
|
return ReadOrAdvance(first, end, delims, 0, &array);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t AdvancePast(const char*& first, StringView delims)
|
inline size_t AdvancePast(const char*& first, const char* end, StringView delims)
|
||||||
{
|
{
|
||||||
return ReadOrAdvance(first, delims, 1);
|
return ReadOrAdvance(first, end, delims, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,6 +118,11 @@ namespace orange
|
||||||
Ptr(--m_size)->~T();
|
Ptr(--m_size)->~T();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Empty() const
|
||||||
|
{
|
||||||
|
return Size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
T& operator [] (size_t idx) { return *Ptr(idx); }
|
T& operator [] (size_t idx) { return *Ptr(idx); }
|
||||||
const T& operator [] (size_t idx) const { return *Ptr(idx); }
|
const T& operator [] (size_t idx) const { return *Ptr(idx); }
|
||||||
|
|
||||||
|
@ -171,4 +176,7 @@ namespace orange
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using Vector = SmallVector<T, sizeof(T) / sizeof(void*)>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,8 +58,11 @@ namespace orange
|
||||||
};
|
};
|
||||||
|
|
||||||
using BufferView = Span<uint8_t>;
|
using BufferView = Span<uint8_t>;
|
||||||
|
|
||||||
struct StringView : public Span<const char>
|
struct StringView : public Span<const char>
|
||||||
{
|
{
|
||||||
|
using Span<const char>::Span;
|
||||||
|
|
||||||
StringView(const char* str)
|
StringView(const char* str)
|
||||||
: Span<const char>{str, strlen(str)} {}
|
: Span<const char>{str, strlen(str)} {}
|
||||||
};
|
};
|
||||||
|
@ -70,4 +73,11 @@ namespace orange
|
||||||
|
|
||||||
~Buffer() { delete[] data; }
|
~Buffer() { delete[] data; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TextBuffer : public Span<char>
|
||||||
|
{
|
||||||
|
using Span<char>::Span;
|
||||||
|
|
||||||
|
~TextBuffer() { delete[] data; }
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,23 +10,25 @@
|
||||||
|
|
||||||
using namespace orange;
|
using namespace orange;
|
||||||
|
|
||||||
Result<VoidResult> ParseOBJ(BufferView buffer)
|
Result<VoidResult> ParseOBJ(StringView buffer)
|
||||||
{
|
{
|
||||||
const char* obj = (const char *)buffer.data;
|
const char* obj = buffer.data;
|
||||||
do
|
const char* end = buffer.data + buffer.size;
|
||||||
|
while (obj != end)
|
||||||
{
|
{
|
||||||
SmallVector<char, 8> element;
|
SmallVector<char, 8> element;
|
||||||
stream::ReadString(obj, " #\n", element);
|
stream::ReadString(obj, end, " #\n", element);
|
||||||
|
|
||||||
if (element == "v" || element == "vn" || element == "vt")
|
if (element == "v" || element == "vn" || element == "vt")
|
||||||
{
|
{
|
||||||
float vtx[3]{};
|
float vtx[3]{};
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
stream::ConsumeSpace(obj);
|
stream::ConsumeSpace(obj, end);
|
||||||
auto r_float = stream::Parse<float>(obj);
|
if (auto r_float = stream::Parse<float>(obj, end))
|
||||||
if (!r_float) return Result<VoidResult>::Error();
|
vtx[i] = *r_float;
|
||||||
vtx[i] = *r_float;
|
else
|
||||||
|
return Result<VoidResult>::Error();
|
||||||
}
|
}
|
||||||
|
|
||||||
element.PushBack('\0');
|
element.PushBack('\0');
|
||||||
|
@ -34,9 +36,9 @@ Result<VoidResult> ParseOBJ(BufferView buffer)
|
||||||
}
|
}
|
||||||
else if (element == "g" || element == "o")
|
else if (element == "g" || element == "o")
|
||||||
{
|
{
|
||||||
stream::ConsumeSpace(obj);
|
stream::ConsumeSpace(obj, end);
|
||||||
SmallVector<char, 32> name;
|
SmallVector<char, 32> name;
|
||||||
stream::ReadString(obj, " #\n", name);
|
stream::ReadString(obj, end, " #\n", name);
|
||||||
|
|
||||||
name.PushBack('\0');
|
name.PushBack('\0');
|
||||||
if (element == "g")
|
if (element == "g")
|
||||||
|
@ -49,18 +51,16 @@ Result<VoidResult> ParseOBJ(BufferView buffer)
|
||||||
int32_t indices[3][3]{};
|
int32_t indices[3][3]{};
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
stream::ConsumeSpace(obj);
|
stream::ConsumeSpace(obj, end);
|
||||||
|
|
||||||
for (int j = 0; j < 3; j++)
|
for (int j = 0; j < 3; j++)
|
||||||
{
|
{
|
||||||
indices[i][j] = -1;
|
indices[i][j] = -1;
|
||||||
|
|
||||||
if (j == 0 || stream::Consume(obj, "/"))
|
if (j == 0 || stream::Consume(obj, end, "/"))
|
||||||
{
|
{
|
||||||
auto r_int = stream::Parse<uint32_t>(obj);
|
if (auto r_int = stream::Parse<uint32_t>(obj, end))
|
||||||
if (!r_int) continue;
|
indices[i][j] = *r_int;
|
||||||
|
|
||||||
indices[i][j] = *r_int;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,14 +69,14 @@ Result<VoidResult> ParseOBJ(BufferView buffer)
|
||||||
indices[1][0], indices[1][1], indices[1][2],
|
indices[1][0], indices[1][1], indices[1][2],
|
||||||
indices[2][0], indices[2][1], indices[2][2]);
|
indices[2][0], indices[2][1], indices[2][2]);
|
||||||
}
|
}
|
||||||
else if (element.Size())
|
else if (!element.Empty())
|
||||||
{
|
{
|
||||||
element.PushBack('\0');
|
element.PushBack('\0');
|
||||||
log::info("Unknown element: %s", element.Data());
|
log::info("Unknown element: %s", element.Data());
|
||||||
}
|
}
|
||||||
|
|
||||||
stream::AdvancePast(obj, "\n");
|
stream::AdvancePast(obj, end, "\n");
|
||||||
} while (*obj != '\0');
|
};
|
||||||
|
|
||||||
return Result<VoidResult>::Success();
|
return Result<VoidResult>::Success();
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ int main(int argc, char** argv)
|
||||||
if (!r_swapchain)
|
if (!r_swapchain)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
auto r_objData = fs::OpenFileIntoBuffer("/home/joshua/chair.obj", true);
|
auto r_objData = fs::OpenFileIntoTextBuffer("/home/joshua/chair.obj");
|
||||||
if (!r_objData)
|
if (!r_objData)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
|
|
||||||
namespace orange::fs
|
namespace orange::fs
|
||||||
{
|
{
|
||||||
Result<Buffer> OpenFileIntoBuffer(const char* path, bool text)
|
Result<Buffer> OpenFileIntoBuffer(const char* path)
|
||||||
{
|
{
|
||||||
FILE* file = fopen(path, text ? "r" : "rb");
|
FILE* file = fopen(path, "rb");
|
||||||
if (!file)
|
if (!file)
|
||||||
Result<Buffer>::Error(BasicErrorCode::NotFound);
|
Result<Buffer>::Error(BasicErrorCode::NotFound);
|
||||||
fseek(file, 0, SEEK_END);
|
fseek(file, 0, SEEK_END);
|
||||||
|
@ -16,8 +16,23 @@ namespace orange::fs
|
||||||
uint8_t* data = new uint8_t[size];
|
uint8_t* data = new uint8_t[size];
|
||||||
fread(data, size, 1, file);
|
fread(data, size, 1, file);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
if (text) data[size++] = '\0';
|
|
||||||
|
|
||||||
return Result<Buffer>::Success(data, size);
|
return Result<Buffer>::Success(data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<TextBuffer> OpenFileIntoTextBuffer(const char* path)
|
||||||
|
{
|
||||||
|
FILE* file = fopen(path, "rb");
|
||||||
|
if (!file)
|
||||||
|
Result<TextBuffer>::Error(BasicErrorCode::NotFound);
|
||||||
|
fseek(file, 0, SEEK_END);
|
||||||
|
size_t size = size_t(ftell(file));
|
||||||
|
fseek(file, 0, SEEK_SET);
|
||||||
|
|
||||||
|
char* data = new char[size];
|
||||||
|
fread(data, size, 1, file);
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
return Result<TextBuffer>::Success(data, size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue