From: Daniel Karbach Date: Mon, 9 Mar 2015 23:11:21 +0000 (+0100) Subject: use indices for model rendering X-Git-Url: http://git.localhorst.tv/?a=commitdiff_plain;h=82426ae2997d2b21703d2d5afb631a84736e975f;p=blank.git use indices for model rendering --- diff --git a/src/block.cpp b/src/block.cpp index e22d3e6..50c4a4f 100644 --- a/src/block.cpp +++ b/src/block.cpp @@ -5,23 +5,22 @@ namespace blank { const NullShape BlockType::DEFAULT_SHAPE; -void BlockType::FillVBO( - const glm::vec3 &pos, - std::vector &vertices, - std::vector &colors, - std::vector &normals +void BlockType::FillModel( + Model &model, + const glm::vec3 &pos_offset, + Model::Index idx_offset ) const { - shape->Vertices(vertices, pos); - colors.insert(colors.end(), shape->VertexCount(), color); - shape->Normals(normals); + shape->Vertices(model.vertices, model.normals, model.indices, pos_offset, idx_offset); + model.colors.insert(model.colors.end(), shape->VertexCount(), color); } -void BlockType::FillOutlineVBO( - std::vector &vertices, - std::vector &colors +void BlockType::FillOutlineModel( + OutlineModel &model, + const glm::vec3 &pos_offset, + OutlineModel::Index idx_offset ) const { - shape->Outline(vertices); - colors.insert(colors.end(), shape->OutlineCount(), outline_color); + shape->Outline(model.vertices, model.indices, pos_offset, idx_offset); + model.colors.insert(model.colors.end(), shape->OutlineCount(), outline_color); } diff --git a/src/block.hpp b/src/block.hpp index 0f567c4..1c1dddb 100644 --- a/src/block.hpp +++ b/src/block.hpp @@ -32,29 +32,17 @@ struct BlockType { static const NullShape DEFAULT_SHAPE; - void FillVBO( - const glm::vec3 &pos, - std::vector &vertices, - std::vector &colors, - std::vector &normals + void FillModel( + Model &m, + const glm::vec3 &pos_offset = { 0, 0, 0 }, + Model::Index idx_offset = 0 ) const; - - void FillModel(const glm::vec3 &pos, Model &m) const { - FillVBO(pos, m.vertices, m.colors, m.normals); - m.Invalidate(); - } - - - void FillOutlineVBO( - std::vector &vertices, - std::vector &colors + void FillOutlineModel( + OutlineModel &m, + const glm::vec3 &pos_offset = { 0, 0, 0 }, + OutlineModel::Index idx_offset = 0 ) const; - void FillOutlineModel(OutlineModel &m) const { - FillOutlineVBO(m.vertices, m.colors); - m.Invalidate(); - } - }; diff --git a/src/chunk.cpp b/src/chunk.cpp index e52a19f..52d17c0 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -111,20 +111,21 @@ glm::mat4 Chunk::Transform(const Pos &offset) const { } -int Chunk::VertexCount() const { - int count = 0; +void Chunk::Update() { + int vtx_count = 0, idx_count = 0; for (const auto &block : blocks) { - count += Type(block).shape->VertexCount(); + const Shape *shape = Type(block).shape; + vtx_count += shape->VertexCount(); + idx_count += shape->VertexIndexCount(); } - return count; -} - -void Chunk::Update() { model.Clear(); - model.Reserve(VertexCount()); + model.Reserve(vtx_count, idx_count); + Model::Index vtx_counter = 0; for (size_t i = 0; i < Size(); ++i) { - Type(blocks[i]).FillModel(ToCoords(i), model); + const BlockType &type = Type(blocks[i]); + type.FillModel(model, ToCoords(i), vtx_counter); + vtx_counter += type.shape->VertexCount(); } model.Invalidate(); diff --git a/src/chunk.hpp b/src/chunk.hpp index 28ba4e3..5c1cadb 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -75,7 +75,6 @@ public: void Draw(); private: - int VertexCount() const; void Update(); private: diff --git a/src/hud.cpp b/src/hud.cpp index ed5767d..d604011 100644 --- a/src/hud.cpp +++ b/src/hud.cpp @@ -27,6 +27,9 @@ HUD::HUD() { -10.0f, 0.0f, 0.0f }, { 10.0f, 0.0f, 0.0f }, { 0.0f, -10.0f, 0.0f }, { 0.0f, 10.0f, 0.0f }, }); + crosshair.indices = std::vector({ + 0, 1, 2, 3 + }); crosshair.colors.resize(4, { 10.0f, 10.0f, 10.0f }); crosshair.Invalidate(); } @@ -44,7 +47,7 @@ void HUD::Viewport(float x, float y, float width, float height) { void HUD::Display(const BlockType &type) { block.Clear(); - type.FillModel({ 0.0f, 0.0f, 0.0f }, block); + type.FillModel(block); block_visible = type.visible; } diff --git a/src/model.cpp b/src/model.cpp index 08b2924..0e358c5 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -33,6 +33,7 @@ Model &Model::operator =(Model &&other) { vertices = std::move(other.vertices); colors = std::move(other.colors); normals = std::move(other.normals); + indices = std::move(other.indices); for (int i = 0; i < ATTRIB_COUNT; ++i) { std::swap(handle[i], other.handle[i]); } @@ -45,13 +46,15 @@ void Model::Clear() { vertices.clear(); colors.clear(); normals.clear(); + indices.clear(); Invalidate(); } -void Model::Reserve(int s) { - vertices.reserve(s); - colors.reserve(s); - normals.reserve(s); +void Model::Reserve(int v, int i) { + vertices.reserve(v); + colors.reserve(v); + normals.reserve(v); + indices.reserve(i); } @@ -77,6 +80,9 @@ void Model::Update() { glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_NORMAL]); glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), normals.data(), GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle[ATTRIB_INDEX]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(Index), indices.data(), GL_STATIC_DRAW); + dirty = false; } @@ -119,10 +125,12 @@ void Model::Draw() { nullptr // offset ); - glDrawArrays( - GL_TRIANGLES, // how - 0, // start - vertices.size() // len + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle[ATTRIB_INDEX]); + glDrawElements( + GL_TRIANGLES, // how + indices.size(), // count + GL_UNSIGNED_INT, // type + nullptr // offset ); glDisableVertexAttribArray(ATTRIB_NORMAL); @@ -134,6 +142,7 @@ void Model::Draw() { OutlineModel::OutlineModel() : vertices() , colors() +, indices() , handle{} , dirty(false) { glGenBuffers(ATTRIB_COUNT, handle); @@ -147,12 +156,14 @@ OutlineModel::~OutlineModel() { void OutlineModel::Clear() { vertices.clear(); colors.clear(); + indices.clear(); Invalidate(); } -void OutlineModel::Reserve(int s) { - vertices.reserve(s); - colors.reserve(s); +void OutlineModel::Reserve(int v, int i) { + vertices.reserve(v); + colors.reserve(v); + indices.reserve(i); } @@ -169,6 +180,9 @@ void OutlineModel::Update() { glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_COLOR]); glBufferData(GL_ARRAY_BUFFER, colors.size() * sizeof(glm::vec3), colors.data(), GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle[ATTRIB_INDEX]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(Index), indices.data(), GL_STATIC_DRAW); + dirty = false; } @@ -203,10 +217,12 @@ void OutlineModel::Draw() { glEnable(GL_LINE_SMOOTH); glLineWidth(2.0f); - glDrawArrays( - GL_LINES, // how - 0, // start - vertices.size() // len + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle[ATTRIB_INDEX]); + glDrawElements( + GL_LINES, // how + indices.size(), // count + GL_UNSIGNED_SHORT, // type + nullptr // offset ); glDisableVertexAttribArray(ATTRIB_COLOR); diff --git a/src/model.hpp b/src/model.hpp index 4423cd7..6e9583b 100644 --- a/src/model.hpp +++ b/src/model.hpp @@ -10,10 +10,14 @@ namespace blank { class Model { +public: + using Index = unsigned int; + public: std::vector vertices; std::vector colors; std::vector normals; + std::vector indices; public: Model(); @@ -28,7 +32,7 @@ public: void Invalidate() { dirty = true; } void Clear(); - void Reserve(int); + void Reserve(int vtx_count, int idx_count); void Draw(); @@ -40,6 +44,7 @@ private: ATTRIB_VERTEX, ATTRIB_COLOR, ATTRIB_NORMAL, + ATTRIB_INDEX, ATTRIB_COUNT, }; @@ -51,9 +56,13 @@ private: class OutlineModel { +public: + using Index = unsigned short; + public: std::vector vertices; std::vector colors; + std::vector indices; public: OutlineModel(); @@ -65,7 +74,7 @@ public: void Invalidate() { dirty = true; } void Clear(); - void Reserve(int); + void Reserve(int vtx_count, int idx_count); void Draw(); @@ -76,6 +85,7 @@ private: enum Attribute { ATTRIB_VERTEX, ATTRIB_COLOR, + ATTRIB_INDEX, ATTRIB_COUNT, }; diff --git a/src/shape.cpp b/src/shape.cpp index e8bd2e6..615b8f9 100644 --- a/src/shape.cpp +++ b/src/shape.cpp @@ -3,261 +3,360 @@ namespace blank { -size_t NullShape::VertexCount() const { - return 0; -} - -void NullShape::Vertices(std::vector &out, const glm::vec3 &pos) const { +NullShape::NullShape() +: Shape(0, 0, 0, 0) { } -void NullShape::Normals(std::vector &out) const { +void NullShape::Vertices( + std::vector &, + std::vector &, + std::vector &, + const glm::vec3 &, + Model::Index +) const { } -size_t NullShape::OutlineCount() const { - return 0; -} - -void NullShape::Outline(std::vector &out, const glm::vec3 &pos) const { +void NullShape::Outline( + std::vector &, + std::vector &, + const glm::vec3 &, + OutlineModel::Index +) const { } -bool NullShape::Intersects(const Ray &, const glm::mat4 &, float &, glm::vec3 &) const { +bool NullShape::Intersects( + const Ray &, + const glm::mat4 &, + float &, glm::vec3 & +) const { return false; } CuboidShape::CuboidShape(const AABB &b) -: Shape() +: Shape(24, 36, 8, 24) , bb(b) { bb.Adjust(); } - -size_t CuboidShape::VertexCount() const { - return 36; -} - -void CuboidShape::Vertices(std::vector &out, const glm::vec3 &pos) const { - out.reserve(36); - out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z); // front - out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z); - out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z); - out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z); - out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.max.z); - out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z); - out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.min.z); // back - out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z); - out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z); - out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z); - out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z); - out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z); - out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z); // top - out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z); - out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z); - out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z); - out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z); - out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.max.z); - out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.min.z); // bottom - out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z); - out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z); - out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z); - out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z); - out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z); - out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.min.z); // left - out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z); - out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z); - out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z); - out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z); - out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z); - out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z); // right - out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z); - out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z); - out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z); - out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z); - out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.max.z); +void CuboidShape::Vertices( + std::vector &vtx, + std::vector &norm, + std::vector &index, + const glm::vec3 &pos, + Model::Index idx +) const { + vtx.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z); // front + vtx.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z); + vtx.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z); + vtx.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.max.z); + vtx.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.min.z); // back + vtx.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z); + vtx.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z); + vtx.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z); + vtx.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z); // top + vtx.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z); + vtx.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z); + vtx.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.max.z); + vtx.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.min.z); // bottom + vtx.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z); + vtx.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z); + vtx.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z); + vtx.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.min.z); // left + vtx.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z); + vtx.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z); + vtx.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z); + vtx.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z); // right + vtx.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z); + vtx.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z); + vtx.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.max.z); + + norm.insert(norm.end(), 4, glm::vec3( 0.0f, 0.0f, 1.0f)); // front + norm.insert(norm.end(), 4, glm::vec3( 0.0f, 0.0f, -1.0f)); // back + norm.insert(norm.end(), 4, glm::vec3( 0.0f, 1.0f, 0.0f)); // top + norm.insert(norm.end(), 4, glm::vec3( 0.0f, -1.0f, 0.0f)); // bottom + norm.insert(norm.end(), 4, glm::vec3(-1.0f, 0.0f, 0.0f)); // left + norm.insert(norm.end(), 4, glm::vec3( 1.0f, 0.0f, 0.0f)); // right + + index.emplace_back(idx + 0); // front + index.emplace_back(idx + 1); + index.emplace_back(idx + 2); + index.emplace_back(idx + 2); + index.emplace_back(idx + 1); + index.emplace_back(idx + 3); + index.emplace_back(idx + 4); // back + index.emplace_back(idx + 5); + index.emplace_back(idx + 6); + index.emplace_back(idx + 6); + index.emplace_back(idx + 5); + index.emplace_back(idx + 7); + index.emplace_back(idx + 8); // top + index.emplace_back(idx + 9); + index.emplace_back(idx + 10); + index.emplace_back(idx + 10); + index.emplace_back(idx + 9); + index.emplace_back(idx + 11); + index.emplace_back(idx + 12); // bottom + index.emplace_back(idx + 13); + index.emplace_back(idx + 14); + index.emplace_back(idx + 14); + index.emplace_back(idx + 13); + index.emplace_back(idx + 15); + index.emplace_back(idx + 16); // left + index.emplace_back(idx + 17); + index.emplace_back(idx + 18); + index.emplace_back(idx + 18); + index.emplace_back(idx + 17); + index.emplace_back(idx + 19); + index.emplace_back(idx + 20); // right + index.emplace_back(idx + 21); + index.emplace_back(idx + 22); + index.emplace_back(idx + 22); + index.emplace_back(idx + 21); + index.emplace_back(idx + 23); } -void CuboidShape::Normals(std::vector &out) const { - out.reserve(36); - out.insert(out.end(), 6, glm::vec3( 0.0f, 0.0f, 1.0f)); // front - out.insert(out.end(), 6, glm::vec3( 0.0f, 0.0f, -1.0f)); // back - out.insert(out.end(), 6, glm::vec3( 0.0f, 1.0f, 0.0f)); // top - out.insert(out.end(), 6, glm::vec3( 0.0f, -1.0f, 0.0f)); // bottom - out.insert(out.end(), 6, glm::vec3(-1.0f, 0.0f, 0.0f)); // left - out.insert(out.end(), 6, glm::vec3( 1.0f, 0.0f, 0.0f)); // right -} - - -size_t CuboidShape::OutlineCount() const { - return 24; +void CuboidShape::Outline( + std::vector &vtx, + std::vector &index, + const glm::vec3 &pos, + OutlineModel::Index idx +) const { + vtx.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.min.z); // back + vtx.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z); + vtx.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z); + vtx.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z); + vtx.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z); // front + vtx.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z); + vtx.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z); + vtx.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.max.z); + + index.emplace_back(idx + 0); // back + index.emplace_back(idx + 1); + index.emplace_back(idx + 1); + index.emplace_back(idx + 3); + index.emplace_back(idx + 3); + index.emplace_back(idx + 2); + index.emplace_back(idx + 2); + index.emplace_back(idx + 0); + index.emplace_back(idx + 4); // front + index.emplace_back(idx + 5); + index.emplace_back(idx + 5); + index.emplace_back(idx + 7); + index.emplace_back(idx + 7); + index.emplace_back(idx + 6); + index.emplace_back(idx + 6); + index.emplace_back(idx + 4); + index.emplace_back(idx + 0); // sides + index.emplace_back(idx + 4); + index.emplace_back(idx + 1); + index.emplace_back(idx + 5); + index.emplace_back(idx + 2); + index.emplace_back(idx + 6); + index.emplace_back(idx + 3); + index.emplace_back(idx + 7); } -void CuboidShape::Outline(std::vector &out, const glm::vec3 &pos) const { - out.reserve(24); - out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.min.z); - out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z); - out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z); - out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z); - out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z); - out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z); - out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z); - out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.min.z); - out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.min.z); - out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z); - out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z); - out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z); - out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z); - out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.max.z); - out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z); - out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z); - out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z); - out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z); - out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z); - out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.max.z); - out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.max.z); - out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z); - out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z); - out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z); -} - -bool CuboidShape::Intersects(const Ray &ray, const glm::mat4 &M, float &dist, glm::vec3 &normal) const { +bool CuboidShape::Intersects( + const Ray &ray, + const glm::mat4 &M, + float &dist, glm::vec3 &normal +) const { return Intersection(ray, bb, M, &dist, &normal); } StairShape::StairShape(const AABB &bb, const glm::vec2 &clip) -: top({ { clip.x, clip.y, bb.min.z }, bb.max }) +: Shape(40, 60, 12, 36) +, top({ { clip.x, clip.y, bb.min.z }, bb.max }) , bot({ bb.min, { bb.max.x, clip.y, bb.max.z } }) { } -size_t StairShape::VertexCount() const { - return 60; -} - -void StairShape::Vertices(std::vector &out, const glm::vec3 &pos) const { - out.reserve(60); - out.emplace_back(pos.x + top.min.x, pos.y + top.min.y, pos.z + top.max.z); // front, upper - out.emplace_back(pos.x + top.max.x, pos.y + top.min.y, pos.z + top.max.z); - out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.max.z); - out.emplace_back(pos.x + top.max.x, pos.y + top.min.y, pos.z + top.max.z); - out.emplace_back(pos.x + top.max.x, pos.y + top.max.y, pos.z + top.max.z); - out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.max.z); - out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.max.z); // front, lower - out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.max.z); - out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.max.z); - out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.max.z); - out.emplace_back(pos.x + bot.max.x, pos.y + bot.max.y, pos.z + bot.max.z); - out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.max.z); - out.emplace_back(pos.x + top.min.x, pos.y + top.min.y, pos.z + top.min.z); // back, upper - out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.min.z); - out.emplace_back(pos.x + top.max.x, pos.y + top.min.y, pos.z + top.min.z); - out.emplace_back(pos.x + top.max.x, pos.y + top.min.y, pos.z + top.min.z); - out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.min.z); - out.emplace_back(pos.x + top.max.x, pos.y + top.max.y, pos.z + top.min.z); - out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.min.z); // back, lower - out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.min.z); - out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.min.z); - out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.min.z); - out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.min.z); - out.emplace_back(pos.x + bot.max.x, pos.y + bot.max.y, pos.z + bot.min.z); - out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.min.z); // top, upper - out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.max.z); - out.emplace_back(pos.x + top.max.x, pos.y + top.max.y, pos.z + top.min.z); - out.emplace_back(pos.x + top.max.x, pos.y + top.max.y, pos.z + top.min.z); - out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.max.z); - out.emplace_back(pos.x + top.max.x, pos.y + top.max.y, pos.z + top.max.z); - out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.min.z); // top, lower - out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.max.z); - out.emplace_back(pos.x + top.min.x, pos.y + bot.max.y, pos.z + bot.min.z); - out.emplace_back(pos.x + top.min.x, pos.y + bot.max.y, pos.z + bot.min.z); - out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.max.z); - out.emplace_back(pos.x + top.min.x, pos.y + bot.max.y, pos.z + bot.max.z); - out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.min.z); // bottom - out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.min.z); - out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.max.z); - out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.min.z); - out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.max.z); - out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.max.z); - out.emplace_back(pos.x + top.min.x, pos.y + top.min.y, pos.z + top.min.z); // left, upper - out.emplace_back(pos.x + top.min.x, pos.y + top.min.y, pos.z + top.max.z); - out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.min.z); - out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.min.z); - out.emplace_back(pos.x + top.min.x, pos.y + top.min.y, pos.z + top.max.z); - out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.max.z); - out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.min.z); // left, lower - out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.max.z); - out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.min.z); - out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.min.z); - out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.max.z); - out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.max.z); - out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.min.z); // right - out.emplace_back(pos.x + top.max.x, pos.y + top.max.y, pos.z + top.min.z); - out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.max.z); - out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.max.z); - out.emplace_back(pos.x + top.max.x, pos.y + top.max.y, pos.z + top.min.z); - out.emplace_back(pos.x + top.max.x, pos.y + top.max.y, pos.z + top.max.z); -} - -void StairShape::Normals(std::vector &out) const { - out.reserve(60); - out.insert(out.end(), 12, glm::vec3( 0.0f, 0.0f, 1.0f)); // front, x2 - out.insert(out.end(), 12, glm::vec3( 0.0f, 0.0f, -1.0f)); // back, x2 - out.insert(out.end(), 12, glm::vec3( 0.0f, 1.0f, 0.0f)); // top, x2 - out.insert(out.end(), 6, glm::vec3( 0.0f, -1.0f, 0.0f)); // bottom - out.insert(out.end(), 12, glm::vec3(-1.0f, 0.0f, 0.0f)); // left, x2 - out.insert(out.end(), 6, glm::vec3( 1.0f, 0.0f, 0.0f)); // right -} - - -size_t StairShape::OutlineCount() const { - return 36; +void StairShape::Vertices( + std::vector &vtx, + std::vector &norm, + std::vector &index, + const glm::vec3 &pos, + Model::Index idx +) const { + vtx.emplace_back(pos.x + top.min.x, pos.y + top.min.y, pos.z + top.max.z); // front, upper + vtx.emplace_back(pos.x + top.max.x, pos.y + top.min.y, pos.z + top.max.z); + vtx.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.max.z); + vtx.emplace_back(pos.x + top.max.x, pos.y + top.max.y, pos.z + top.max.z); + vtx.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.max.z); // front, lower + vtx.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.max.z); + vtx.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.max.z); + vtx.emplace_back(pos.x + bot.max.x, pos.y + bot.max.y, pos.z + bot.max.z); + vtx.emplace_back(pos.x + top.min.x, pos.y + top.min.y, pos.z + top.min.z); // back, upper + vtx.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.min.z); + vtx.emplace_back(pos.x + top.max.x, pos.y + top.min.y, pos.z + top.min.z); + vtx.emplace_back(pos.x + top.max.x, pos.y + top.max.y, pos.z + top.min.z); + vtx.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.min.z); // back, lower + vtx.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.min.z); + vtx.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.min.z); + vtx.emplace_back(pos.x + bot.max.x, pos.y + bot.max.y, pos.z + bot.min.z); + vtx.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.min.z); // top, upper + vtx.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.max.z); + vtx.emplace_back(pos.x + top.max.x, pos.y + top.max.y, pos.z + top.min.z); + vtx.emplace_back(pos.x + top.max.x, pos.y + top.max.y, pos.z + top.max.z); + vtx.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.min.z); // top, lower + vtx.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.max.z); + vtx.emplace_back(pos.x + top.min.x, pos.y + bot.max.y, pos.z + bot.min.z); + vtx.emplace_back(pos.x + top.min.x, pos.y + bot.max.y, pos.z + bot.max.z); + vtx.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.min.z); // bottom + vtx.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.min.z); + vtx.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.max.z); + vtx.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.max.z); + vtx.emplace_back(pos.x + top.min.x, pos.y + top.min.y, pos.z + top.min.z); // left, upper + vtx.emplace_back(pos.x + top.min.x, pos.y + top.min.y, pos.z + top.max.z); + vtx.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.min.z); + vtx.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.max.z); + vtx.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.min.z); // left, lower + vtx.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.max.z); + vtx.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.min.z); + vtx.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.max.z); + vtx.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.min.z); // right + vtx.emplace_back(pos.x + bot.max.x, pos.y + top.max.y, pos.z + bot.min.z); + vtx.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.max.z); + vtx.emplace_back(pos.x + bot.max.x, pos.y + top.max.y, pos.z + bot.max.z); + + norm.insert(norm.end(), 8, glm::vec3( 0.0f, 0.0f, 1.0f)); // front, x2 + norm.insert(norm.end(), 8, glm::vec3( 0.0f, 0.0f, -1.0f)); // back, x2 + norm.insert(norm.end(), 8, glm::vec3( 0.0f, 1.0f, 0.0f)); // top, x2 + norm.insert(norm.end(), 4, glm::vec3( 0.0f, -1.0f, 0.0f)); // bottom + norm.insert(norm.end(), 8, glm::vec3(-1.0f, 0.0f, 0.0f)); // left, x2 + norm.insert(norm.end(), 4, glm::vec3( 1.0f, 0.0f, 0.0f)); // right + + index.emplace_back(idx + 0); // front, upper + index.emplace_back(idx + 1); + index.emplace_back(idx + 2); + index.emplace_back(idx + 2); + index.emplace_back(idx + 1); + index.emplace_back(idx + 3); + index.emplace_back(idx + 4); // front, lower + index.emplace_back(idx + 5); + index.emplace_back(idx + 6); + index.emplace_back(idx + 6); + index.emplace_back(idx + 5); + index.emplace_back(idx + 7); + index.emplace_back(idx + 8); // back, upper + index.emplace_back(idx + 9); + index.emplace_back(idx + 10); + index.emplace_back(idx + 10); + index.emplace_back(idx + 9); + index.emplace_back(idx + 11); + index.emplace_back(idx + 12); // back, lower + index.emplace_back(idx + 13); + index.emplace_back(idx + 14); + index.emplace_back(idx + 14); + index.emplace_back(idx + 13); + index.emplace_back(idx + 15); + index.emplace_back(idx + 16); // top, upper + index.emplace_back(idx + 17); + index.emplace_back(idx + 18); + index.emplace_back(idx + 18); + index.emplace_back(idx + 17); + index.emplace_back(idx + 19); + index.emplace_back(idx + 20); // top, lower + index.emplace_back(idx + 21); + index.emplace_back(idx + 22); + index.emplace_back(idx + 22); + index.emplace_back(idx + 21); + index.emplace_back(idx + 23); + index.emplace_back(idx + 24); // bottom + index.emplace_back(idx + 25); + index.emplace_back(idx + 26); + index.emplace_back(idx + 26); + index.emplace_back(idx + 25); + index.emplace_back(idx + 27); + index.emplace_back(idx + 28); // left, upper + index.emplace_back(idx + 29); + index.emplace_back(idx + 30); + index.emplace_back(idx + 30); + index.emplace_back(idx + 29); + index.emplace_back(idx + 31); + index.emplace_back(idx + 32); // left, lower + index.emplace_back(idx + 33); + index.emplace_back(idx + 34); + index.emplace_back(idx + 34); + index.emplace_back(idx + 33); + index.emplace_back(idx + 35); + index.emplace_back(idx + 36); // right + index.emplace_back(idx + 37); + index.emplace_back(idx + 38); + index.emplace_back(idx + 38); + index.emplace_back(idx + 37); + index.emplace_back(idx + 39); } -void StairShape::Outline(std::vector &out, const glm::vec3 &pos) const { - out.reserve(36); - out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.min.z); // bottom - out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.min.z); - out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.min.z); - out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.max.z); - out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.max.z); - out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.max.z); - out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.max.z); - out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.min.z); - out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.min.z); // middle - out.emplace_back(pos.x + top.min.x, pos.y + bot.max.y, pos.z + bot.min.z); - out.emplace_back(pos.x + top.min.x, pos.y + bot.max.y, pos.z + bot.min.z); - out.emplace_back(pos.x + top.min.x, pos.y + bot.max.y, pos.z + bot.max.z); - out.emplace_back(pos.x + top.min.x, pos.y + bot.max.y, pos.z + bot.max.z); - out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.max.z); - out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.max.z); - out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.min.z); - out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + bot.min.z); // top - out.emplace_back(pos.x + bot.max.x, pos.y + top.max.y, pos.z + bot.min.z); - out.emplace_back(pos.x + bot.max.x, pos.y + top.max.y, pos.z + bot.min.z); - out.emplace_back(pos.x + bot.max.x, pos.y + top.max.y, pos.z + bot.max.z); - out.emplace_back(pos.x + bot.max.x, pos.y + top.max.y, pos.z + bot.max.z); - out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + bot.max.z); - out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + bot.max.z); - out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + bot.min.z); - out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.min.z); // verticals, ltr/btf - out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.min.z); - out.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.max.z); - out.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.max.z); - out.emplace_back(pos.x + top.min.x, pos.y + top.min.y, pos.z + bot.min.z); - out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + bot.min.z); - out.emplace_back(pos.x + top.min.x, pos.y + top.min.y, pos.z + bot.max.z); - out.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + bot.max.z); - out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.min.z); - out.emplace_back(pos.x + bot.max.x, pos.y + top.max.y, pos.z + bot.min.z); - out.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.max.z); - out.emplace_back(pos.x + bot.max.x, pos.y + top.max.y, pos.z + bot.max.z); +void StairShape::Outline( + std::vector &vtx, + std::vector &index, + const glm::vec3 &pos, + OutlineModel::Index idx +) const { + vtx.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.min.z); // bottom + vtx.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.min.z); + vtx.emplace_back(pos.x + bot.min.x, pos.y + bot.min.y, pos.z + bot.max.z); + vtx.emplace_back(pos.x + bot.max.x, pos.y + bot.min.y, pos.z + bot.max.z); + vtx.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + bot.min.z); // middle + vtx.emplace_back(pos.x + top.min.x, pos.y + bot.max.y, pos.z + bot.min.z); + vtx.emplace_back(pos.x + bot.min.x, pos.y + bot.max.y, pos.z + top.max.z); + vtx.emplace_back(pos.x + top.min.x, pos.y + bot.max.y, pos.z + top.max.z); + vtx.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.min.z); // top + vtx.emplace_back(pos.x + top.max.x, pos.y + top.max.y, pos.z + top.min.z); + vtx.emplace_back(pos.x + top.min.x, pos.y + top.max.y, pos.z + top.max.z); + vtx.emplace_back(pos.x + top.max.x, pos.y + top.max.y, pos.z + top.max.z); + + index.emplace_back(idx + 0); // bottom + index.emplace_back(idx + 1); + index.emplace_back(idx + 1); + index.emplace_back(idx + 3); + index.emplace_back(idx + 3); + index.emplace_back(idx + 2); + index.emplace_back(idx + 2); + index.emplace_back(idx + 0); + index.emplace_back(idx + 4); // middle + index.emplace_back(idx + 5); + index.emplace_back(idx + 5); + index.emplace_back(idx + 7); + index.emplace_back(idx + 7); + index.emplace_back(idx + 6); + index.emplace_back(idx + 6); + index.emplace_back(idx + 4); + index.emplace_back(idx + 8); // top + index.emplace_back(idx + 9); + index.emplace_back(idx + 9); + index.emplace_back(idx + 11); + index.emplace_back(idx + 11); + index.emplace_back(idx + 10); + index.emplace_back(idx + 10); + index.emplace_back(idx + 8); + index.emplace_back(idx + 0); // verticals + index.emplace_back(idx + 4); + index.emplace_back(idx + 2); + index.emplace_back(idx + 6); + index.emplace_back(idx + 5); + index.emplace_back(idx + 8); + index.emplace_back(idx + 7); + index.emplace_back(idx + 10); + index.emplace_back(idx + 1); + index.emplace_back(idx + 9); + index.emplace_back(idx + 3); + index.emplace_back(idx + 11); } -bool StairShape::Intersects(const Ray &ray, const glm::mat4 &M, float &dist, glm::vec3 &norm) const { +bool StairShape::Intersects( + const Ray &ray, + const glm::mat4 &M, + float &dist, + glm::vec3 &norm +) const { float top_dist, bot_dist; glm::vec3 top_norm, bot_norm; bool top_hit = Intersection(ray, top, M, &top_dist, &top_norm); diff --git a/src/shape.hpp b/src/shape.hpp index 66827d0..af19bb1 100644 --- a/src/shape.hpp +++ b/src/shape.hpp @@ -2,6 +2,7 @@ #define BLANK_SHAPE_HPP_ #include "geometry.hpp" +#include "model.hpp" #include #include @@ -11,14 +12,55 @@ namespace blank { struct Shape { - virtual size_t VertexCount() const = 0; - virtual void Vertices(std::vector &, const glm::vec3 &pos = { 0.0f, 0.0f, 0.0f }) const = 0; - virtual void Normals(std::vector &) const = 0; + /// the number of vertices (and normals) this shape has + size_t VertexCount() const { return vtx; } + /// the number of vertex indices this shape has + size_t VertexIndexCount() const { return vtx_idx; } + + /// fill given buffers with this shape's elements with an + /// optional offset + virtual void Vertices( + std::vector &vertex, + std::vector &normal, + std::vector &index, + const glm::vec3 &elem_offset = { 0.0f, 0.0f, 0.0f }, + Model::Index idx_offset = 0 + ) const = 0; + + /// the number of vertices this shape's outline has + size_t OutlineCount() const { return outl; } + /// the number of vertex indices this shape's outline has + size_t OutlineIndexCount() const { return outl_idx; } + + /// fill given buffers with this shape's outline's elements with + /// an optional offset + virtual void Outline( + std::vector &vertex, + std::vector &index, + const glm::vec3 &offset = { 0.0f, 0.0f, 0.0f }, + OutlineModel::Index idx_offset = 0 + ) const = 0; + + /// Check if given ray would pass though this shape if it were + /// transformed with given matrix. + /// If true, dist and normal hold the intersection distance and + /// normal, otherwise their content is undefined. + virtual bool Intersects( + const Ray &, + const glm::mat4 &, + float &dist, + glm::vec3 &normal + ) const = 0; + +protected: + Shape(size_t vtx, size_t vtx_idx, size_t outl, size_t outl_idx) + : vtx(vtx), vtx_idx(vtx_idx), outl(outl), outl_idx(outl_idx) { } - virtual size_t OutlineCount() const = 0; - virtual void Outline(std::vector &, const glm::vec3 &pos = { 0.0f, 0.0f, 0.0f }) const = 0; - - virtual bool Intersects(const Ray &, const glm::mat4 &, float &dist, glm::vec3 &normal) const = 0; +private: + size_t vtx; + size_t vtx_idx; + size_t outl; + size_t outl_idx; }; @@ -27,12 +69,22 @@ class NullShape : public Shape { public: - size_t VertexCount() const override; - void Vertices(std::vector &, const glm::vec3 &) const override; - void Normals(std::vector &) const override; - - size_t OutlineCount() const override; - void Outline(std::vector &, const glm::vec3 &) const override; + NullShape(); + + void Vertices( + std::vector &vertex, + std::vector &normal, + std::vector &index, + const glm::vec3 &elem_offset = { 0.0f, 0.0f, 0.0f }, + Model::Index idx_offset = 0 + ) const override; + + void Outline( + std::vector &vertex, + std::vector &index, + const glm::vec3 &offset = { 0.0f, 0.0f, 0.0f }, + OutlineModel::Index idx_offset = 0 + ) const override; bool Intersects(const Ray &, const glm::mat4 &, float &, glm::vec3 &) const override; @@ -45,12 +97,20 @@ class CuboidShape public: CuboidShape(const AABB &bounds); - size_t VertexCount() const override; - void Vertices(std::vector &, const glm::vec3 &) const override; - void Normals(std::vector &) const override; - - size_t OutlineCount() const override; - void Outline(std::vector &, const glm::vec3 &) const override; + void Vertices( + std::vector &vertex, + std::vector &normal, + std::vector &index, + const glm::vec3 &elem_offset = { 0.0f, 0.0f, 0.0f }, + Model::Index idx_offset = 0 + ) const override; + + void Outline( + std::vector &vertex, + std::vector &index, + const glm::vec3 &offset = { 0.0f, 0.0f, 0.0f }, + OutlineModel::Index idx_offset = 0 + ) const override; bool Intersects(const Ray &, const glm::mat4 &, float &, glm::vec3 &) const override; @@ -66,12 +126,20 @@ class StairShape public: StairShape(const AABB &bounds, const glm::vec2 &clip); - size_t VertexCount() const override; - void Vertices(std::vector &, const glm::vec3 &) const override; - void Normals(std::vector &) const override; - - size_t OutlineCount() const override; - void Outline(std::vector &, const glm::vec3 &) const override; + void Vertices( + std::vector &vertex, + std::vector &normal, + std::vector &index, + const glm::vec3 &elem_offset = { 0.0f, 0.0f, 0.0f }, + Model::Index idx_offset = 0 + ) const override; + + void Outline( + std::vector &vertex, + std::vector &index, + const glm::vec3 &offset = { 0.0f, 0.0f, 0.0f }, + OutlineModel::Index idx_offset = 0 + ) const override; bool Intersects(const Ray &, const glm::mat4 &, float &, glm::vec3 &) const override;