-Subproject commit d49b4a9e4d4b4afe6f483139f3c37db58376bfae
+Subproject commit 82ab37629683a73061240c2d7da64f0a612fde42
public:
explicit AssetLoader(const std::string &base);
- void LoadBlockTypes(const std::string &set_name, BlockTypeRegistry &, TextureIndex &) const;
+ void LoadBlockTypes(
+ const std::string &set_name,
+ BlockTypeRegistry &,
+ TextureIndex &,
+ const ShapeRegistry &) const;
CubeMap LoadCubeMap(const std::string &name) const;
Font LoadFont(const std::string &name, int size) const;
void LoadShapes(const std::string &set_name, ShapeRegistry &) const;
}
-void AssetLoader::LoadBlockTypes(const string &set_name, BlockTypeRegistry ®, TextureIndex &tex_index) const {
+void AssetLoader::LoadBlockTypes(
+ const string &set_name,
+ BlockTypeRegistry ®,
+ TextureIndex &tex_index,
+ const ShapeRegistry &shapes
+) const {
string full = data + set_name + ".types";
std::ifstream file(full);
if (!file) {
type.commonness = in.GetFloat();
} else if (name == "shape") {
in.ReadIdentifier(shape_name);
- if (shape_name == "block") {
- type.shape = &block_shape;
- type.fill = { true, true, true, true, true, true };
- } else if (shape_name == "slab") {
- type.shape = &slab_shape;
- type.fill = { false, true, false, false, false, false };
- } else if (shape_name == "stair") {
- type.shape = &stair_shape;
- type.fill = { false, true, false, false, false, true };
- } else {
- throw runtime_error("unknown block shape: " + shape_name);
- }
+ type.shape = &shapes.Get(shape_name);
} else {
- throw runtime_error("unknown block property: " + name);
+ std::cerr << "warning: unknown block type property " << name << std::endl;
+ while (in.Peek().type != Token::SEMICOLON) {
+ in.Next();
+ }
}
in.Skip(Token::SEMICOLON);
}
}
TextureIndex tex_index;
master.GetEnv().loader.LoadShapes("default", shapes);
- master.GetEnv().loader.LoadBlockTypes("default", block_types, tex_index);
+ master.GetEnv().loader.LoadBlockTypes("default", block_types, tex_index, shapes);
+ skeletons.Load(shapes, tex_index);
interface.SetInventorySlots(block_types.size() - 1);
chunk_renderer.LoadTextures(master.GetEnv().loader, tex_index);
chunk_renderer.FogDensity(master.GetWorldConf().fog_density);
- skeletons.Load();
loop_timer.Start();
if (save.Exists(player)) {
save.Read(player);
#ifndef BLANK_MODEL_COLLISIONBOUNDS_HPP_
#define BLANK_MODEL_COLLISIONBOUNDS_HPP_
-#include "../graphics/BlockMesh.hpp"
-#include "../graphics/EntityMesh.hpp"
#include "../graphics/OutlineMesh.hpp"
#include <glm/glm.hpp>
struct CollisionBounds {
- /// the number of vertices (and normals) this shape has
- size_t VertexCount() const noexcept { return vtx_pos.size(); }
- /// the number of vertex indices this shape has
- size_t VertexIndexCount() const noexcept { return vtx_idx.size(); }
-
- const EntityMesh::Normal &VertexNormal(size_t idx) const noexcept { return vtx_nrm[idx]; }
- EntityMesh::Normal VertexNormal(
- size_t idx, const glm::mat4 &transform
- ) const noexcept {
- return EntityMesh::Normal(transform * glm::vec4(vtx_nrm[idx], 0.0f));
- }
-
- /// fill given buffers with this shape's elements with an
- /// optional transform and offset
- void Vertices(
- EntityMesh::Buffer &out,
- float tex_offset = 0.0f
- ) const;
- void Vertices(
- EntityMesh::Buffer &out,
- const glm::mat4 &transform,
- float tex_offset = 0.0f,
- EntityMesh::Index idx_offset = 0
- ) const;
- void Vertices(
- BlockMesh::Buffer &out,
- const glm::mat4 &transform,
- float tex_offset = 0.0f,
- BlockMesh::Index idx_offset = 0
- ) const;
-
/// the number of vertices this shape's outline has
- size_t OutlineCount() const { return out_pos.size(); }
+ std::size_t OutlineCount() const { return out_pos.size(); }
/// the number of vertex indices this shape's outline has
- size_t OutlineIndexCount() const { return out_idx.size(); }
+ std::size_t OutlineIndexCount() const { return out_idx.size(); }
- /// fill given buffers with this shape's outline's elements
+ /// fill given buffers with these bounds' outline's elements
void Outline(OutlineMesh::Buffer &out) const;
/// Check if given ray would pass though this shape if it were
) const noexcept = 0;
protected:
- void SetShape(
- const EntityMesh::Positions &pos,
- const EntityMesh::Normals &nrm,
- const EntityMesh::Indices &idx);
- void SetTexture(
- const BlockMesh::TexCoords &tex_coords);
void SetOutline(
const OutlineMesh::Positions &pos,
const OutlineMesh::Indices &idx);
private:
- EntityMesh::Positions vtx_pos;
- EntityMesh::Normals vtx_nrm;
- EntityMesh::Indices vtx_idx;
-
- BlockMesh::TexCoords vtx_tex_coords;
-
OutlineMesh::Positions out_pos;
OutlineMesh::Indices out_idx;
#ifndef BLANK_MODEL_SHAPE_HPP_
#define BLANK_MODEL_SHAPE_HPP_
+#include "CollisionBounds.hpp"
+#include "geometry.hpp"
#include "../graphics/BlockMesh.hpp"
#include "../graphics/EntityMesh.hpp"
+#include "../world/Block.hpp"
#include <memory>
#include <vector>
namespace blank {
-struct CollisionBounds;
class TokenStreamReader;
class Shape {
+public:
+ struct Faces {
+ bool face[Block::FACE_COUNT];
+ Faces &operator =(const Faces &other) noexcept {
+ for (int i = 0; i < Block::FACE_COUNT; ++i) {
+ face[i] = other.face[i];
+ }
+ return *this;
+ }
+ bool operator [](Block::Face f) const noexcept {
+ return face[f];
+ }
+ };
+
+
public:
Shape();
void Read(TokenStreamReader &);
+ bool FaceFilled(Block::Face face) const noexcept {
+ return fill[face];
+ }
+
+ std::size_t VertexCount() const noexcept { return vertices.size(); }
+ std::size_t IndexCount() const noexcept { return indices.size(); }
+
+ const glm::vec3 &VertexNormal(size_t idx) const noexcept {
+ return vertices[idx].normal;
+ }
+ glm::vec3 VertexNormal(size_t idx, const glm::mat4 &M) const noexcept {
+ return glm::vec3(M * glm::vec4(VertexNormal(idx), 0.0f));
+ }
+
void Fill(
EntityMesh::Buffer &,
const std::vector<float> &tex_map
std::size_t idx_offset = 0
) const;
+ size_t OutlineCount() const noexcept;
+ size_t OutlineIndexCount() const noexcept;
+ void Outline(OutlineMesh::Buffer &out) const;
+
+ bool Intersects(
+ const Ray &,
+ const glm::mat4 &,
+ float &dist,
+ glm::vec3 &normal
+ ) const noexcept;
+ bool Intersects(
+ const glm::mat4 &M,
+ const AABB &box,
+ const glm::mat4 &box_M,
+ float &depth,
+ glm::vec3 &normal
+ ) const noexcept;
+
private:
static float TexR(const std::vector<float> &, std::size_t) noexcept;
};
std::vector<Vertex> vertices;
std::vector<std::size_t> indices;
+ Faces fill;
};
class Model;
class EntityMesh;
+class ShapeRegistry;
+class TextureIndex;
class Skeletons {
~Skeletons();
void LoadHeadless();
- void Load();
+ void Load(const ShapeRegistry &, TextureIndex &);
size_type size() const noexcept { return skeletons.size(); }
namespace blank {
-void CollisionBounds::Vertices(
- EntityMesh::Buffer &out,
- float tex_offset
-) const {
- for (const auto &pos : vtx_pos) {
- out.vertices.emplace_back(pos);
- }
- for (const auto &coord : vtx_tex_coords) {
- out.tex_coords.emplace_back(coord.x, coord.y, coord.z + tex_offset);
- }
- for (const auto &nrm : vtx_nrm) {
- out.normals.emplace_back(nrm);
- }
- for (auto idx : vtx_idx) {
- out.indices.emplace_back(idx);
- }
-}
-
-void CollisionBounds::Vertices(
- EntityMesh::Buffer &out,
- const glm::mat4 &transform,
- float tex_offset,
- EntityMesh::Index idx_offset
-) const {
- for (const auto &pos : vtx_pos) {
- out.vertices.emplace_back(transform * glm::vec4(pos, 1.0f));
- }
- for (const auto &coord : vtx_tex_coords) {
- out.tex_coords.emplace_back(coord.x, coord.y, coord.z + tex_offset);
- }
- for (const auto &nrm : vtx_nrm) {
- out.normals.emplace_back(transform * glm::vec4(nrm, 0.0f));
- }
- for (auto idx : vtx_idx) {
- out.indices.emplace_back(idx_offset + idx);
- }
-}
-
-void CollisionBounds::Vertices(
- BlockMesh::Buffer &out,
- const glm::mat4 &transform,
- float tex_offset,
- BlockMesh::Index idx_offset
-) const {
- for (const auto &pos : vtx_pos) {
- out.vertices.emplace_back(transform * glm::vec4(pos, 1.0f));
- }
- for (const auto &coord : vtx_tex_coords) {
- out.tex_coords.emplace_back(coord.x, coord.y, coord.z + tex_offset);
- }
- for (auto idx : vtx_idx) {
- out.indices.emplace_back(idx_offset + idx);
- }
-}
-
void CollisionBounds::Outline(OutlineMesh::Buffer &out) const {
out.vertices.insert(out.vertices.end(), out_pos.begin(), out_pos.end());
out.indices.insert(out.indices.end(), out_idx.begin(), out_idx.end());
}
-void CollisionBounds::SetShape(
- const EntityMesh::Positions &pos,
- const EntityMesh::Normals &nrm,
- const EntityMesh::Indices &idx
-) {
- vtx_pos = pos;
- vtx_nrm = nrm;
- vtx_idx = idx;
-}
-
-void CollisionBounds::SetTexture(
- const BlockMesh::TexCoords &tex_coords
-) {
- vtx_tex_coords = tex_coords;
-}
-
void CollisionBounds::SetOutline(
const OutlineMesh::Positions &pos,
const OutlineMesh::Indices &idx
}
-NullBounds::NullBounds()
-: CollisionBounds() {
-
-}
-
-bool NullBounds::Intersects(
- const Ray &,
- const glm::mat4 &,
- float &, glm::vec3 &
-) const noexcept {
- return false;
-}
-
-bool NullBounds::Intersects(
- const glm::mat4 &,
- const AABB &,
- const glm::mat4 &,
- float &,
- glm::vec3 &
-) const noexcept {
- return false;
-}
-
-
CuboidBounds::CuboidBounds(const AABB &b)
: CollisionBounds()
, bb(b) {
bb.Adjust();
- SetShape({
- { bb.min.x, bb.min.y, bb.max.z }, // front
- { bb.max.x, bb.min.y, bb.max.z },
- { bb.min.x, bb.max.y, bb.max.z },
- { bb.max.x, bb.max.y, bb.max.z },
- { bb.min.x, bb.min.y, bb.min.z }, // back
- { bb.min.x, bb.max.y, bb.min.z },
- { bb.max.x, bb.min.y, bb.min.z },
- { bb.max.x, bb.max.y, bb.min.z },
- { bb.min.x, bb.max.y, bb.min.z }, // top
- { bb.min.x, bb.max.y, bb.max.z },
- { bb.max.x, bb.max.y, bb.min.z },
- { bb.max.x, bb.max.y, bb.max.z },
- { bb.min.x, bb.min.y, bb.min.z }, // bottom
- { bb.max.x, bb.min.y, bb.min.z },
- { bb.min.x, bb.min.y, bb.max.z },
- { bb.max.x, bb.min.y, bb.max.z },
- { bb.min.x, bb.min.y, bb.min.z }, // left
- { bb.min.x, bb.min.y, bb.max.z },
- { bb.min.x, bb.max.y, bb.min.z },
- { bb.min.x, bb.max.y, bb.max.z },
- { bb.max.x, bb.min.y, bb.min.z }, // right
- { bb.max.x, bb.max.y, bb.min.z },
- { bb.max.x, bb.min.y, bb.max.z },
- { bb.max.x, bb.max.y, bb.max.z },
- }, {
- { 0.0f, 0.0f, 1.0f }, // front
- { 0.0f, 0.0f, 1.0f },
- { 0.0f, 0.0f, 1.0f },
- { 0.0f, 0.0f, 1.0f },
- { 0.0f, 0.0f, -1.0f }, // back
- { 0.0f, 0.0f, -1.0f },
- { 0.0f, 0.0f, -1.0f },
- { 0.0f, 0.0f, -1.0f },
- { 0.0f, 1.0f, 0.0f }, // top
- { 0.0f, 1.0f, 0.0f },
- { 0.0f, 1.0f, 0.0f },
- { 0.0f, 1.0f, 0.0f },
- { 0.0f, -1.0f, 0.0f }, // bottom
- { 0.0f, -1.0f, 0.0f },
- { 0.0f, -1.0f, 0.0f },
- { 0.0f, -1.0f, 0.0f },
- { -1.0f, 0.0f, 0.0f }, // left
- { -1.0f, 0.0f, 0.0f },
- { -1.0f, 0.0f, 0.0f },
- { -1.0f, 0.0f, 0.0f },
- { 1.0f, 0.0f, 0.0f }, // right
- { 1.0f, 0.0f, 0.0f },
- { 1.0f, 0.0f, 0.0f },
- { 1.0f, 0.0f, 0.0f },
- }, {
- 0, 1, 2, 2, 1, 3, // front
- 4, 5, 6, 6, 5, 7, // back
- 8, 9, 10, 10, 9, 11, // top
- 12, 13, 14, 14, 13, 15, // bottom
- 16, 17, 18, 18, 17, 19, // left
- 20, 21, 22, 22, 21, 23, // right
- });
- SetTexture({
- { 0.0f, 1.0f, 0.0f }, // front
- { 1.0f, 1.0f, 0.0f },
- { 0.0f, 0.0f, 0.0f },
- { 1.0f, 0.0f, 0.0f },
- { 1.0f, 1.0f, 0.0f }, // back
- { 1.0f, 0.0f, 0.0f },
- { 0.0f, 1.0f, 0.0f },
- { 0.0f, 0.0f, 0.0f },
- { 0.0f, 0.0f, 0.0f }, // top
- { 0.0f, 1.0f, 0.0f },
- { 1.0f, 0.0f, 0.0f },
- { 1.0f, 1.0f, 0.0f },
- { 1.0f, 0.0f, 0.0f }, // bottom
- { 0.0f, 0.0f, 0.0f },
- { 1.0f, 1.0f, 0.0f },
- { 0.0f, 1.0f, 0.0f },
- { 0.0f, 1.0f, 0.0f }, // left
- { 1.0f, 1.0f, 0.0f },
- { 0.0f, 0.0f, 0.0f },
- { 1.0f, 0.0f, 0.0f },
- { 1.0f, 1.0f, 0.0f }, // right
- { 1.0f, 0.0f, 0.0f },
- { 0.0f, 1.0f, 0.0f },
- { 0.0f, 0.0f, 0.0f },
- });
SetOutline({
{ bb.min.x, bb.min.y, bb.min.z }, // back
{ bb.max.x, bb.min.y, bb.min.z },
: CollisionBounds()
, top({ { bb.min.x, clip.y, bb.min.z }, { bb.max.x, bb.max.y, clip.x } })
, bot({ bb.min, { bb.max.x, clip.y, bb.max.z } }) {
- SetShape({
- { top.min.x, top.min.y, top.max.z }, // front, upper
- { top.max.x, top.min.y, top.max.z },
- { top.min.x, top.max.y, top.max.z },
- { top.max.x, top.max.y, top.max.z },
- { bot.min.x, bot.min.y, bot.max.z }, // front, lower
- { bot.max.x, bot.min.y, bot.max.z },
- { bot.min.x, bot.max.y, bot.max.z },
- { bot.max.x, bot.max.y, bot.max.z },
- { bot.min.x, bot.min.y, bot.min.z }, // back
- { bot.min.x, top.max.y, bot.min.z },
- { top.max.x, bot.min.y, bot.min.z },
- { top.max.x, top.max.y, bot.min.z },
- { top.min.x, top.max.y, top.min.z }, // top, upper
- { top.min.x, top.max.y, top.max.z },
- { top.max.x, top.max.y, top.min.z },
- { top.max.x, top.max.y, top.max.z },
- { bot.min.x, bot.max.y, top.max.z }, // top, lower
- { bot.min.x, bot.max.y, bot.max.z },
- { bot.max.x, bot.max.y, top.max.z },
- { bot.max.x, bot.max.y, bot.max.z },
- { bot.min.x, bot.min.y, bot.min.z }, // bottom
- { bot.max.x, bot.min.y, bot.min.z },
- { bot.min.x, bot.min.y, bot.max.z },
- { bot.max.x, bot.min.y, bot.max.z },
- { top.min.x, top.min.y, top.min.z }, // left, upper
- { top.min.x, top.min.y, top.max.z },
- { top.min.x, top.max.y, top.min.z },
- { top.min.x, top.max.y, top.max.z },
- { bot.min.x, bot.min.y, bot.min.z }, // left, lower
- { bot.min.x, bot.min.y, bot.max.z },
- { bot.min.x, bot.max.y, bot.min.z },
- { bot.min.x, bot.max.y, bot.max.z },
- { top.max.x, top.min.y, top.min.z }, // right, upper
- { top.max.x, top.max.y, top.min.z },
- { top.max.x, top.min.y, top.max.z },
- { top.max.x, top.max.y, top.max.z },
- { bot.max.x, bot.min.y, bot.min.z }, // right, lower
- { bot.max.x, bot.max.y, bot.min.z },
- { bot.max.x, bot.min.y, bot.max.z },
- { bot.max.x, bot.max.y, bot.max.z },
- }, {
- { 0.0f, 0.0f, 1.0f }, // front x2
- { 0.0f, 0.0f, 1.0f },
- { 0.0f, 0.0f, 1.0f },
- { 0.0f, 0.0f, 1.0f },
- { 0.0f, 0.0f, 1.0f },
- { 0.0f, 0.0f, 1.0f },
- { 0.0f, 0.0f, 1.0f },
- { 0.0f, 0.0f, 1.0f },
- { 0.0f, 0.0f, -1.0f }, // back
- { 0.0f, 0.0f, -1.0f },
- { 0.0f, 0.0f, -1.0f },
- { 0.0f, 0.0f, -1.0f },
- { 0.0f, 1.0f, 0.0f }, // top x2
- { 0.0f, 1.0f, 0.0f },
- { 0.0f, 1.0f, 0.0f },
- { 0.0f, 1.0f, 0.0f },
- { 0.0f, 1.0f, 0.0f },
- { 0.0f, 1.0f, 0.0f },
- { 0.0f, 1.0f, 0.0f },
- { 0.0f, 1.0f, 0.0f },
- { 0.0f, -1.0f, 0.0f }, // bottom
- { 0.0f, -1.0f, 0.0f },
- { 0.0f, -1.0f, 0.0f },
- { 0.0f, -1.0f, 0.0f },
- { -1.0f, 0.0f, 0.0f }, // left x2
- { -1.0f, 0.0f, 0.0f },
- { -1.0f, 0.0f, 0.0f },
- { -1.0f, 0.0f, 0.0f },
- { -1.0f, 0.0f, 0.0f },
- { -1.0f, 0.0f, 0.0f },
- { -1.0f, 0.0f, 0.0f },
- { -1.0f, 0.0f, 0.0f },
- { 1.0f, 0.0f, 0.0f }, // right x2
- { 1.0f, 0.0f, 0.0f },
- { 1.0f, 0.0f, 0.0f },
- { 1.0f, 0.0f, 0.0f },
- { 1.0f, 0.0f, 0.0f },
- { 1.0f, 0.0f, 0.0f },
- { 1.0f, 0.0f, 0.0f },
- { 1.0f, 0.0f, 0.0f },
- }, {
- 0, 1, 2, 2, 1, 3, // front, upper
- 4, 5, 6, 6, 5, 7, // front, lower
- 8, 9, 10, 10, 9, 11, // back
- 12, 13, 14, 14, 13, 15, // top, upper
- 16, 17, 18, 18, 17, 19, // top, lower
- 20, 21, 22, 22, 21, 23, // bottom
- 24, 25, 26, 26, 25, 27, // left, upper
- 28, 29, 30, 30, 29, 31, // left, lower
- 32, 33, 34, 34, 33, 35, // right, upper
- 36, 37, 38, 38, 37, 39, // right, lower
- });
- SetTexture({
- { 0.0f, 0.5f, 0.0f }, // front, upper
- { 1.0f, 0.5f, 0.0f },
- { 0.0f, 0.0f, 0.0f },
- { 1.0f, 0.0f, 0.0f },
- { 0.0f, 1.0f, 0.0f }, // front, lower
- { 1.0f, 1.0f, 0.0f },
- { 0.0f, 0.5f, 0.0f },
- { 1.0f, 0.5f, 0.0f },
- { 1.0f, 1.0f, 0.0f }, // back
- { 1.0f, 0.0f, 0.0f },
- { 0.0f, 1.0f, 0.0f },
- { 0.0f, 0.0f, 0.0f },
- { 0.0f, 0.0f, 0.0f }, // top, upper
- { 0.0f, 0.5f, 0.0f },
- { 1.0f, 0.0f, 0.0f },
- { 1.0f, 0.5f, 0.0f },
- { 0.0f, 0.5f, 0.0f }, // top, lower
- { 0.0f, 1.0f, 0.0f },
- { 1.0f, 0.5f, 0.0f },
- { 1.0f, 1.0f, 0.0f },
- { 1.0f, 0.0f, 0.0f }, // bottom
- { 0.0f, 0.0f, 0.0f },
- { 1.0f, 1.0f, 0.0f },
- { 0.0f, 1.0f, 0.0f },
- { 0.0f, 0.5f, 0.0f }, // left, upper
- { 0.5f, 0.5f, 0.0f },
- { 0.0f, 0.0f, 0.0f },
- { 0.5f, 0.0f, 0.0f },
- { 0.0f, 1.0f, 0.0f }, // left, lower
- { 1.0f, 1.0f, 0.0f },
- { 0.0f, 0.5f, 0.0f },
- { 1.0f, 0.5f, 0.0f },
- { 1.0f, 0.5f, 0.0f }, // right, upper
- { 1.0f, 0.0f, 0.0f },
- { 0.5f, 0.5f, 0.0f },
- { 0.5f, 0.0f, 0.0f },
- { 1.0f, 1.0f, 0.0f }, // right, lower
- { 1.0f, 0.5f, 0.0f },
- { 0.0f, 1.0f, 0.0f },
- { 0.0f, 0.5f, 0.0f },
- });
SetOutline({
{ bot.min.x, bot.min.y, bot.min.z }, // bottom
{ bot.max.x, bot.min.y, bot.min.z },
namespace blank {
-class NullBounds
-: public CollisionBounds {
-
-public:
- NullBounds();
-
- bool Intersects(const Ray &, const glm::mat4 &, float &, glm::vec3 &) const noexcept override;
- bool Intersects(const glm::mat4 &, const AABB &, const glm::mat4 &, float &, glm::vec3 &) const noexcept override;
-
-};
-
-
class CuboidBounds
: public CollisionBounds {
#include "Instance.hpp"
#include "Skeletons.hpp"
-#include "bounds.hpp"
+#include "Shape.hpp"
+#include "ShapeRegistry.hpp"
+#include "../app/TextureIndex.hpp"
#include "../graphics/DirectionalLighting.hpp"
#include "../graphics/EntityMesh.hpp"
void Skeletons::LoadHeadless() {
skeletons.clear();
skeletons.reserve(4);
+ AABB bounds{{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f }};
{
- AABB bounds{{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f }};
skeletons.emplace_back(new Model);
skeletons[0]->ID(1);
skeletons[0]->Bounds(bounds);
}
{
- AABB bounds{{ -0.5f, -0.25f, -0.5f }, { 0.5f, 0.25f, 0.5f }};
skeletons.emplace_back(new Model);
skeletons[1]->ID(2);
skeletons[1]->Bounds(bounds);
}
{
- AABB bounds{{ -0.25f, -0.5f, -0.25f }, { 0.25f, 0.5f, 0.25f }};
skeletons.emplace_back(new Model);
skeletons[2]->ID(3);
skeletons[2]->Bounds(bounds);
}
{
- AABB bounds{{ -0.25f, -0.5f, -0.35f }, { 0.25f, 0.5f, 0.35f }};
skeletons.emplace_back(new Model);
skeletons[3]->ID(4);
skeletons[3]->Bounds(bounds);
}
}
-void Skeletons::Load() {
+void Skeletons::Load(const ShapeRegistry &shapes, TextureIndex &tex_index) {
LoadHeadless();
meshes.resize(4);
+ const Shape &shape = shapes.Get("player_head_block");
EntityMesh::Buffer buf;
+ std::vector<float> tex_map;
+ tex_map.push_back(tex_index.GetID("rock-1"));
+ tex_map.push_back(tex_index.GetID("rock-face"));
+ buf.Reserve(shape.VertexCount(), shape.IndexCount());
{
- CuboidBounds shape(skeletons[0]->Bounds());
- shape.Vertices(buf, 3.0f);
+ shape.Fill(buf, tex_map);
buf.hsl_mods.resize(shape.VertexCount(), { 0.0f, 1.0f, 1.0f });
buf.rgb_mods.resize(shape.VertexCount(), { 1.0f, 1.0f, 0.0f });
meshes[0].Update(buf);
skeletons[0]->SetNodeMesh(&meshes[0]);
}
{
- CuboidBounds shape(skeletons[1]->Bounds());
buf.Clear();
- shape.Vertices(buf, 0.0f);
+ shape.Fill(buf, tex_map);
buf.hsl_mods.resize(shape.VertexCount(), { 0.0f, 1.0f, 1.0f });
buf.rgb_mods.resize(shape.VertexCount(), { 0.0f, 1.0f, 1.0f });
meshes[1].Update(buf);
skeletons[1]->SetNodeMesh(&meshes[1]);
}
{
- StairBounds shape(skeletons[2]->Bounds(), { 0.4f, 0.4f });
buf.Clear();
- shape.Vertices(buf, 1.0f);
+ shape.Fill(buf, tex_map);
buf.hsl_mods.resize(shape.VertexCount(), { 0.0f, 1.0f, 1.0f });
buf.rgb_mods.resize(shape.VertexCount(), { 1.0f, 0.0f, 1.0f });
meshes[2].Update(buf);
skeletons[2]->SetNodeMesh(&meshes[2]);
}
{
- CuboidBounds shape(skeletons[3]->Bounds());
buf.Clear();
- shape.Vertices(buf, 2.0f);
+ shape.Fill(buf, tex_map);
buf.hsl_mods.resize(shape.VertexCount(), { 0.0f, 1.0f, 1.0f });
buf.rgb_mods.resize(shape.VertexCount(), { 1.0f, 0.25f, 0.5f });
meshes[3].Update(buf);
Shape::Shape()
: bounds()
, vertices()
-, indices() {
+, indices()
+, fill({ false, false, false, false, false, false }) {
}
bounds.reset();
vertices.clear();
indices.clear();
+ fill = { false, false, false, false, false, false };
string name;
in.Skip(Token::ANGLE_BRACKET_OPEN);
if (in.Peek().type == Token::COMMA) {
in.Skip(Token::COMMA);
}
+ vertices.push_back(vtx);
}
in.Skip(Token::ANGLE_BRACKET_CLOSE);
}
in.Skip(Token::ANGLE_BRACKET_CLOSE);
+ } else if (name == "fill") {
+ in.Skip(Token::BRACKET_OPEN);
+ fill.face[Block::FACE_UP] = in.GetBool();
+ in.Skip(Token::COMMA);
+ fill.face[Block::FACE_DOWN] = in.GetBool();
+ in.Skip(Token::COMMA);
+ fill.face[Block::FACE_RIGHT] = in.GetBool();
+ in.Skip(Token::COMMA);
+ fill.face[Block::FACE_LEFT] = in.GetBool();
+ in.Skip(Token::COMMA);
+ fill.face[Block::FACE_FRONT] = in.GetBool();
+ in.Skip(Token::COMMA);
+ fill.face[Block::FACE_BACK] = in.GetBool();
+ in.Skip(Token::BRACKET_CLOSE);
+
} else {
// try to skip, might fail though
while (in.Peek().type != Token::SEMICOLON) {
}
}
+size_t Shape::OutlineCount() const noexcept {
+ if (bounds) {
+ return bounds->OutlineCount();
+ } else {
+ return 0;
+ }
+}
+
+size_t Shape::OutlineIndexCount() const noexcept {
+ if (bounds) {
+ return bounds->OutlineIndexCount();
+ } else {
+ return 0;
+ }
+}
+
+void Shape::Outline(OutlineMesh::Buffer &out) const {
+ if (bounds) {
+ bounds->Outline(out);
+ }
+}
+
+bool Shape::Intersects(
+ const Ray &ray,
+ const glm::mat4 &M,
+ float &dist,
+ glm::vec3 &normal
+) const noexcept {
+ if (bounds) {
+ return bounds->Intersects(ray, M, dist, normal);
+ } else {
+ return false;
+ }
+}
+
+bool Shape::Intersects(
+ const glm::mat4 &M,
+ const AABB &box,
+ const glm::mat4 &box_M,
+ float &depth,
+ glm::vec3 &normal
+) const noexcept {
+ if (bounds) {
+ return bounds->Intersects(M, box, box_M, depth, normal);
+ } else {
+ return false;
+ }
+}
+
ShapeRegistry::ShapeRegistry()
: shapes() {
, loop_timer(16) {
TextureIndex tex_index;
env.loader.LoadShapes("default", shapes);
- env.loader.LoadBlockTypes("default", block_types, tex_index);
+ env.loader.LoadBlockTypes("default", block_types, tex_index, shapes);
generator.LoadTypes(block_types);
skeletons.LoadHeadless();
spawner.LimitSkeletons(1, skeletons.size());
, unload(env, world.Chunks(), save) {
TextureIndex tex_index;
env.loader.LoadShapes("default", shapes);
- env.loader.LoadBlockTypes("default", block_types, tex_index);
+ env.loader.LoadBlockTypes("default", block_types, tex_index, shapes);
+ skeletons.Load(shapes, tex_index);
interface.SetInventorySlots(block_types.size() - 1);
generator.LoadTypes(block_types);
chunk_renderer.LoadTextures(env.loader, tex_index);
chunk_renderer.FogDensity(wc.fog_density);
- skeletons.Load();
spawner.LimitSkeletons(0, skeletons.size());
if (save.Exists(player)) {
save.Read(player);
#include "../graphics/BlockMesh.hpp"
#include "../graphics/EntityMesh.hpp"
#include "../graphics/OutlineMesh.hpp"
-#include "../model/bounds.hpp"
+#include "../model/Shape.hpp"
#include <glm/glm.hpp>
#include <vector>
/// attributes of a type of block
struct BlockType {
- const CollisionBounds *shape;
+ const Shape *shape;
std::vector<float> textures;
glm::vec3 hsl_mod;
glm::vec3 rgb_mod;
/// commonness factor, random chance is multiplied by this
float commonness;
- struct Faces {
- bool face[Block::FACE_COUNT];
- Faces &operator =(const Faces &other) noexcept {
- for (int i = 0; i < Block::FACE_COUNT; ++i) {
- face[i] = other.face[i];
- }
- return *this;
- }
- bool operator [](Block::Face f) const noexcept {
- return face[f];
- }
- } fill;
-
BlockType() noexcept;
- static const NullBounds DEFAULT_SHAPE;
-
bool FaceFilled(const Block &block, Block::Face face) const noexcept {
- return fill[block.OrientedFace(face)];
+ return shape && shape->FaceFilled(block.OrientedFace(face));
}
void FillEntityMesh(
EntityMesh::Buffer &m,
- const glm::mat4 &transform = glm::mat4(1.0f),
- EntityMesh::Index idx_offset = 0
+ const glm::mat4 &transform = glm::mat4(1.0f)
) const noexcept;
void FillBlockMesh(
BlockMesh::Buffer &m,
namespace blank {
-const NullBounds BlockType::DEFAULT_SHAPE;
-
-
std::ostream &operator <<(std::ostream &out, const Block &block) {
return out << "Block(" << block.type << ", " << block.GetFace() << ", " << block.GetTurn() << ')';
}
BlockType::BlockType() noexcept
-: shape(&DEFAULT_SHAPE)
+: shape(nullptr)
, textures()
, hsl_mod(0.0f, 1.0f, 1.0f)
, rgb_mod(1.0f, 1.0f, 1.0f)
, min_richness(-1.0f)
, mid_richness(0.0f)
, max_richness(1.0f)
-, commonness(1.0f)
-, fill({ false, false, false, false, false, false }) {
+, commonness(1.0f) {
}
void BlockType::FillEntityMesh(
EntityMesh::Buffer &buf,
- const glm::mat4 &transform,
- EntityMesh::Index idx_offset
+ const glm::mat4 &transform
) const noexcept {
- if (textures.empty()) {
- shape->Vertices(buf, transform, 0.0f, idx_offset);
- } else {
- shape->Vertices(buf, transform, textures[0], idx_offset);
- }
+ if (!shape) return;
+ shape->Fill(buf, transform, textures);
buf.hsl_mods.insert(buf.hsl_mods.end(), shape->VertexCount(), hsl_mod);
buf.rgb_mods.insert(buf.rgb_mods.end(), shape->VertexCount(), rgb_mod);
}
const glm::mat4 &transform,
BlockMesh::Index idx_offset
) const noexcept {
- if (textures.empty()) {
- shape->Vertices(buf, transform, 0.0f, idx_offset);
- } else {
- shape->Vertices(buf, transform, textures[0], idx_offset);
- }
+ if (!shape) return;
+ shape->Fill(buf, transform, textures, idx_offset);
buf.hsl_mods.insert(buf.hsl_mods.end(), shape->VertexCount(), hsl_mod);
buf.rgb_mods.insert(buf.rgb_mods.end(), shape->VertexCount(), rgb_mod);
}
void BlockType::FillOutlineMesh(OutlineMesh::Buffer &buf) const noexcept {
+ if (!shape) return;
shape->Outline(buf);
buf.colors.insert(buf.colors.end(), shape->OutlineCount(), outline_color);
}
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x, ++idx) {
const BlockType &type = Type(idx);
- if (!type.visible) {
+ if (!type.collision || !type.shape) {
continue;
}
float cur_dist;
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x, ++idx) {
const BlockType &type = Type(idx);
- if (!type.collision) {
+ if (!type.collision || !type.shape) {
continue;
}
if (type.shape->Intersects(Mchunk * ToTransform(Pos(x, y, z), idx), box, Mbox, penetration, normal)) {
void Chunk::Update(BlockMesh &model) noexcept {
int vtx_count = 0, idx_count = 0;
for (const auto &block : blocks) {
- const CollisionBounds *shape = Type(block).shape;
- vtx_count += shape->VertexCount();
- idx_count += shape->VertexIndexCount();
+ const BlockType &type = Type(block);
+ if (type.visible && type.shape) {
+ vtx_count += type.shape->VertexCount();
+ idx_count += type.shape->IndexCount();
+ }
}
buf.Clear();
buf.Reserve(vtx_count, idx_count);
- int idx = 0;
- BlockMesh::Index vtx_counter = 0;
- for (size_t z = 0; z < depth; ++z) {
- for (size_t y = 0; y < height; ++y) {
- for (size_t x = 0; x < width; ++x, ++idx) {
- const BlockType &type = Type(BlockAt(idx));
- const Pos pos(x, y, z);
-
- if (!type.visible || Obstructed(pos).All()) continue;
-
- type.FillBlockMesh(buf, ToTransform(pos, idx), vtx_counter);
- size_t vtx_begin = vtx_counter;
- vtx_counter += type.shape->VertexCount();
-
- for (size_t vtx = vtx_begin; vtx < vtx_counter; ++vtx) {
- buf.lights.emplace_back(GetVertexLight(
- pos,
- buf.vertices[vtx],
- type.shape->VertexNormal(vtx - vtx_begin, BlockAt(idx).Transform())
- ));
+ if (idx_count > 0) {
+ int idx = 0;
+ BlockMesh::Index vtx_counter = 0;
+ for (size_t z = 0; z < depth; ++z) {
+ for (size_t y = 0; y < height; ++y) {
+ for (size_t x = 0; x < width; ++x, ++idx) {
+ const BlockType &type = Type(BlockAt(idx));
+ const Pos pos(x, y, z);
+
+ if (!type.visible || !type.shape || Obstructed(pos).All()) continue;
+
+ type.FillBlockMesh(buf, ToTransform(pos, idx), vtx_counter);
+ size_t vtx_begin = vtx_counter;
+ vtx_counter += type.shape->VertexCount();
+
+ for (size_t vtx = vtx_begin; vtx < vtx_counter; ++vtx) {
+ buf.lights.emplace_back(GetVertexLight(
+ pos,
+ buf.vertices[vtx],
+ type.shape->VertexNormal(vtx - vtx_begin, BlockAt(idx).Transform())
+ ));
+ }
}
}
}