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])
{
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>

View File

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

View File

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

View File

@ -267,9 +267,21 @@ namespace orange
return a == Vec<T, Size>::Identity;
}
using Vec1 = Vec<float, 1>;
using Vec2 = Vec<float, 2>;
using Vec3 = Vec<float, 3>;
using Vec4 = Vec<float, 4>;
template <typename T, size_t Size>
constexpr Vec<T, Size> Min(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 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;
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* end = buffer.data + buffer.size;
while (obj != end)
@ -21,7 +58,7 @@ Result<VoidResult> ParseOBJ(StringView buffer)
SmallVector<char, 8> element;
stream::ReadString(obj, end, " #\n", element);
if (element == "v" || element == "vn" || element == "vt")
if (element == "v" || element == "vt" || element == "vn")
{
float vtx[3]{};
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))
vtx[i] = *r_float;
else
return Result<VoidResult>::Error();
return Result<MeshData>::Error();
}
element.PushBack('\0');
log::info("Found: %s %f %f %f", element.Data(), vtx[0], vtx[1], vtx[2]);
if (element == "v")
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")
{
@ -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],
indices[1][0], indices[1][1], indices[1][2],
indices[2][0], indices[2][1], indices[2][2]);
for (int i = 0; i < 3; i++)
{
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())
{
@ -80,7 +137,7 @@ Result<VoidResult> ParseOBJ(StringView buffer)
stream::AdvancePast(obj, end, "\n");
};
return Result<VoidResult>::Success();
return Result<MeshData>::Success(data);
}
int main(int argc, char** argv)
@ -107,9 +164,7 @@ int main(int argc, char** argv)
if (!r_objData)
return 1;
ParseOBJ(*r_objData);
return 0;
auto r_mesh = ParseOBJ(*r_objData);
while (r_window->Update())
{