mesh work
This commit is contained in:
parent
f6f4ee884a
commit
4dc3a57730
|
@ -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>
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
// Needed for placement new/delete.
|
||||
#include <new>
|
||||
#include <initializer_list>
|
||||
|
||||
namespace orange
|
||||
{
|
||||
|
|
|
@ -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); }
|
||||
|
||||
|
|
|
@ -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>;
|
||||
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue