From d6435142245c019523b9385048d6d79bdd2565f2 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Sun, 8 Mar 2015 11:11:17 +0100 Subject: [PATCH] stair shape --- src/shape.cpp | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/shape.hpp | 21 +++++++ src/world.cpp | 9 ++- src/world.hpp | 3 + 4 files changed, 194 insertions(+), 2 deletions(-) diff --git a/src/shape.cpp b/src/shape.cpp index e974d06..3df4257 100644 --- a/src/shape.cpp +++ b/src/shape.cpp @@ -101,4 +101,167 @@ bool CuboidShape::Intersects(const Ray &ray, const glm::mat4 &M, float &dist, gl 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 }) +, 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::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); +} + +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); + bool bot_hit = Intersection(ray, bot, M, &bot_dist, &bot_norm); + + if (top_hit) { + if (bot_hit) { + if (top_dist < bot_dist) { + dist = top_dist; + norm = top_norm; + return true; + } else { + dist = bot_dist; + norm = bot_norm; + return true; + } + } else { + dist = top_dist; + norm = top_norm; + return true; + } + } else if (bot_hit) { + dist = bot_dist; + norm = bot_norm; + return true; + } else { + return false; + } +} + + } diff --git a/src/shape.hpp b/src/shape.hpp index 438fa10..434f427 100644 --- a/src/shape.hpp +++ b/src/shape.hpp @@ -43,6 +43,27 @@ private: }; + +class StairShape +: public Shape { + +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; + + bool Intersects(const Ray &, const glm::mat4 &, float &, glm::vec3 &) const override; + +private: + AABB top, bot; + +}; + } #endif diff --git a/src/world.cpp b/src/world.cpp index c1d1f5a..6ce0700 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -150,7 +150,7 @@ void Chunk::Update() { model.Clear(); model.Reserve(VertexCount()); - for (int i = 0; i < Size(); ++i) { + for (size_t i = 0; i < Size(); ++i) { if (blocks[i].type->visible) { blocks[i].type->FillModel(ToCoords(i), model); } @@ -164,15 +164,20 @@ void Chunk::Update() { World::World() : blockType() , blockShape({{ 0.0f, 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f }}) +, stairShape({{ 0.0f, 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f }}, { 0.5f, 0.5f }) , slabShape({{ 0.0f, 0.0f, 0.0f }, { 1.0f, 0.5f, 1.0f }}) , chunks() { blockType.Add(BlockType{ true, { 1.0f, 1.0f, 1.0f }, &blockShape }); // white block + blockType.Add(BlockType{ true, { 1.0f, 1.0f, 1.0f }, &stairShape }); // white stair blockType.Add(BlockType{ true, { 1.0f, 1.0f, 1.0f }, &slabShape }); // white slab blockType.Add(BlockType{ true, { 1.0f, 0.0f, 0.0f }, &blockShape }); // red block + blockType.Add(BlockType{ true, { 1.0f, 0.0f, 0.0f }, &stairShape }); // red stair blockType.Add(BlockType{ true, { 1.0f, 0.0f, 0.0f }, &slabShape }); // red slab blockType.Add(BlockType{ true, { 0.0f, 1.0f, 0.0f }, &blockShape }); // green block + blockType.Add(BlockType{ true, { 0.0f, 1.0f, 0.0f }, &stairShape }); // green stair blockType.Add(BlockType{ true, { 0.0f, 1.0f, 0.0f }, &slabShape }); // green slab blockType.Add(BlockType{ true, { 0.0f, 0.0f, 1.0f }, &blockShape }); // blue block + blockType.Add(BlockType{ true, { 0.0f, 0.0f, 1.0f }, &stairShape }); // blue stair blockType.Add(BlockType{ true, { 0.0f, 0.0f, 1.0f }, &slabShape }); // blue slab } @@ -191,7 +196,7 @@ Chunk &World::Generate(const glm::vec3 &pos) { chunks.emplace_back(); Chunk &chunk = chunks.back(); chunk.Position(pos); - for (int i = 1; i < 9; ++i) { + for (size_t i = 1; i < blockType.Size(); ++i) { chunk.BlockAt(i) = Block(blockType[i]); chunk.BlockAt(i + 257) = Block(blockType[i]); chunk.BlockAt(i + 514) = Block(blockType[i]); diff --git a/src/world.hpp b/src/world.hpp index 83fd3e8..6fabe9a 100644 --- a/src/world.hpp +++ b/src/world.hpp @@ -69,6 +69,8 @@ public: public: int Add(const BlockType &); + size_t Size() const { return types.size(); } + BlockType *operator [](int id) { return &types[id]; } const BlockType *Get(int id) const { return &types[id]; } @@ -184,6 +186,7 @@ private: private: BlockTypeRegistry blockType; CuboidShape blockShape; + StairShape stairShape; CuboidShape slabShape; std::list chunks; -- 2.39.2