mesh work

This commit is contained in:
Joshua Ashton 2022-08-06 23:59:25 +00:00
parent f6f4ee884a
commit 4dc3a57730
5 changed files with 139 additions and 23 deletions

View File

@ -13,7 +13,12 @@ namespace orange
constexpr Array(const T components[Size]) constexpr Array(const T components[Size])
{ {
Copy(&components[0], &components[Size], m_data.begin()); Copy(&components[0], &components[Size], begin());
}
constexpr Array(std::initializer_list<T> list)
{
Copy(list.begin(), list.end(), begin());
} }
template <typename... Args> template <typename... Args>

View File

@ -4,6 +4,7 @@
// Needed for placement new/delete. // Needed for placement new/delete.
#include <new> #include <new>
#include <initializer_list>
namespace orange namespace orange
{ {

View File

@ -19,9 +19,26 @@ namespace orange
for (const auto& val : span) for (const auto& val : span)
PushBack(val); PushBack(val);
} }
constexpr SmallVector(std::initializer_list<T> list)
{
Reserve(list.size());
for (const auto& val : list)
PushBack(val);
}
SmallVector (const SmallVector&) = delete; SmallVector (const SmallVector& x)
SmallVector& operator = (const SmallVector&) = delete; {
Reserve(x.Size());
for (const auto& val : x)
PushBack(val);
}
SmallVector& operator = (const SmallVector& x)
{
Clear();
Reserve(x.Size());
for (const auto& val : x)
PushBack(val);
}
~SmallVector() ~SmallVector()
{ {
@ -70,6 +87,11 @@ namespace orange
const T* Data() const { return Ptr(0); } const T* Data() const { return Ptr(0); }
T* Data() { return Ptr(0); } T* Data() { return Ptr(0); }
void Clear()
{
Resize(0);
}
void Resize(size_t n) void Resize(size_t n)
{ {
Reserve(n); Reserve(n);
@ -83,23 +105,26 @@ namespace orange
m_size = n; m_size = n;
} }
void PushBack(const T& object) size_t PushBack(const T& object)
{ {
Reserve(m_size + 1); Reserve(m_size + 1);
new (Ptr(m_size++)) T(object); new (Ptr(m_size++)) T(object);
return m_size - 1;
} }
void PushBack(T&& object) size_t PushBack(T&& object)
{ {
Reserve(m_size + 1); Reserve(m_size + 1);
new (Ptr(m_size++)) T(Move(object)); new (Ptr(m_size++)) T(Move(object));
return m_size - 1;
} }
template<typename... Args> template<typename... Args>
void EmplaceBack(Args... args) size_t EmplaceBack(Args... args)
{ {
Reserve(m_size + 1); Reserve(m_size + 1);
new (Ptr(m_size++)) T(Forward<Args>(args)...); new (Ptr(m_size++)) T(Forward<Args>(args)...);
return m_size - 1;
} }
void Erase(size_t idx) void Erase(size_t idx)
@ -123,6 +148,24 @@ namespace orange
return Size() == 0; return Size() == 0;
} }
constexpr static size_t InvalidIdx = ~(0zu);
size_t FindIdx(const T& x) const
{
for (size_t i = 0; i < m_size; i++)
{
if (*Ptr(i) == x)
return i;
}
return InvalidIdx;
}
bool Contains(const T& x) const
{
return FindIdx(x) != InvalidIdx;
}
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); }

View File

@ -267,9 +267,21 @@ namespace orange
return a == Vec<T, Size>::Identity; return a == Vec<T, Size>::Identity;
} }
using Vec1 = Vec<float, 1>; template <typename T, size_t Size>
using Vec2 = Vec<float, 2>; constexpr Vec<T, Size> Min(const Vec<T, Size>& a, const Vec<T, Size>& b)
using Vec3 = Vec<float, 3>; {
using Vec4 = Vec<float, 4>; return TransformResult<Vec<T, Size>>(a.begin(), a.end(), b.begin(), [](T val_a, T val_b){ return Min(val_a, val_b); });
}
template <typename T, size_t Size>
constexpr Vec<T, Size> Max(const Vec<T, Size>& a, const Vec<T, Size>& b)
{
return TransformResult<Vec<T, Size>>(a.begin(), a.end(), b.begin(), [](T val_a, T val_b){ return Max(val_a, val_b); });
}
using vec1 = Vec<float, 1>;
using vec2 = Vec<float, 2>;
using vec3 = Vec<float, 3>;
using vec4 = Vec<float, 4>;
} }

View File

@ -12,8 +12,45 @@
using namespace orange; using namespace orange;
Result<VoidResult> ParseOBJ(StringView buffer) struct AABB
{ {
vec3 min;
vec3 max;
void Extend(vec3 pos)
{
min = Min(pos, min);
max = Max(pos, max);
}
};
struct Vertex
{
vec3 pos;
vec2 uv;
vec3 normal;
bool operator == (const Vertex& other) const
{
return pos == other.pos && uv == other.uv && normal == other.normal;
}
};
struct MeshData
{
Vector<Vertex> vertices;
Vector<uint16_t> indices;
AABB bounds;
};
Result<MeshData> ParseOBJ(StringView buffer)
{
MeshData data;
Vector<vec3> positions;
Vector<vec2> uvs;
Vector<vec3> normals;
const char* obj = buffer.data; const char* obj = buffer.data;
const char* end = buffer.data + buffer.size; const char* end = buffer.data + buffer.size;
while (obj != end) while (obj != end)
@ -21,7 +58,7 @@ Result<VoidResult> ParseOBJ(StringView buffer)
SmallVector<char, 8> element; SmallVector<char, 8> element;
stream::ReadString(obj, end, " #\n", element); stream::ReadString(obj, end, " #\n", element);
if (element == "v" || element == "vn" || element == "vt") if (element == "v" || element == "vt" || element == "vn")
{ {
float vtx[3]{}; float vtx[3]{};
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
@ -30,11 +67,15 @@ Result<VoidResult> ParseOBJ(StringView buffer)
if (auto r_float = stream::Parse<float>(obj, end)) if (auto r_float = stream::Parse<float>(obj, end))
vtx[i] = *r_float; vtx[i] = *r_float;
else else
return Result<VoidResult>::Error(); return Result<MeshData>::Error();
} }
element.PushBack('\0'); if (element == "v")
log::info("Found: %s %f %f %f", element.Data(), vtx[0], vtx[1], vtx[2]); positions.EmplaceBack(vtx[0], vtx[1], vtx[2]);
else if (element == "vt")
normals.EmplaceBack(vtx[0], vtx[1], vtx[2]);
else if (element == "vn")
uvs.EmplaceBack(vtx[0], vtx[1]);
} }
else if (element == "g" || element == "o") else if (element == "g" || element == "o")
{ {
@ -66,10 +107,26 @@ Result<VoidResult> ParseOBJ(StringView buffer)
} }
} }
} }
log::info("Found: f %d/%d/%d %d/%d/%d %d/%d/%d",
indices[0][0], indices[0][1], indices[0][2], for (int i = 0; i < 3; i++)
indices[1][0], indices[1][1], indices[1][2], {
indices[2][0], indices[2][1], indices[2][2]); Vertex vertex =
{
.pos = indices[i][0] != -1 ? positions[indices[i][0]] : vec3{},
.uv = indices[i][1] != -1 ? uvs [indices[i][1]] : vec2{},
.normal = indices[i][2] != -1 ? normals [indices[i][2]] : vec3{},
};
size_t vertexIdx = data.vertices.FindIdx(vertex);
if (vertexIdx == Vector<Vertex>::InvalidIdx)
{
data.bounds.Extend(vertex.pos);
vertexIdx = data.vertices.PushBack(vertex);
}
Assert(vertexIdx < UINT16_MAX);
data.indices.PushBack(uint16_t(vertexIdx));
}
} }
else if (!element.Empty()) else if (!element.Empty())
{ {
@ -80,7 +137,7 @@ Result<VoidResult> ParseOBJ(StringView buffer)
stream::AdvancePast(obj, end, "\n"); stream::AdvancePast(obj, end, "\n");
}; };
return Result<VoidResult>::Success(); return Result<MeshData>::Success(data);
} }
int main(int argc, char** argv) int main(int argc, char** argv)
@ -107,9 +164,7 @@ int main(int argc, char** argv)
if (!r_objData) if (!r_objData)
return 1; return 1;
ParseOBJ(*r_objData); auto r_mesh = ParseOBJ(*r_objData);
return 0;
while (r_window->Update()) while (r_window->Update())
{ {