block,voxel,atlas: Initial interfaces
This commit is contained in:
parent
42f3a4b47d
commit
f516f4984d
@ -92,7 +92,10 @@ if(BUILD_CLIENT)
|
|||||||
src/impl/tcpsocket.cpp
|
src/impl/tcpsocket.cpp
|
||||||
src/impl/sha1.cpp
|
src/impl/sha1.cpp
|
||||||
src/impl/packet_stream.cpp
|
src/impl/packet_stream.cpp
|
||||||
|
src/impl/mesh.cpp
|
||||||
|
src/impl/atlas.cpp
|
||||||
src/impl/voxel.cpp
|
src/impl/voxel.cpp
|
||||||
|
src/impl/block.cpp
|
||||||
src/lua_bindings/util.cpp
|
src/lua_bindings/util.cpp
|
||||||
src/lua_bindings/init.cpp
|
src/lua_bindings/init.cpp
|
||||||
src/lua_bindings/misc.cpp
|
src/lua_bindings/misc.cpp
|
||||||
@ -132,7 +135,10 @@ if(BUILD_SERVER)
|
|||||||
src/impl/module.cpp
|
src/impl/module.cpp
|
||||||
src/impl/sha1.cpp
|
src/impl/sha1.cpp
|
||||||
src/impl/packet_stream.cpp
|
src/impl/packet_stream.cpp
|
||||||
|
src/impl/mesh.cpp
|
||||||
|
src/impl/atlas.cpp
|
||||||
src/impl/voxel.cpp
|
src/impl/voxel.cpp
|
||||||
|
src/impl/block.cpp
|
||||||
)
|
)
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(SERVER_CORE_SRCS ${SERVER_CORE_SRCS} src/impl/windows/file_watch.cpp)
|
set(SERVER_CORE_SRCS ${SERVER_CORE_SRCS} src/impl/windows/file_watch.cpp)
|
||||||
|
@ -153,6 +153,12 @@ A way to define voxel properties:
|
|||||||
- interface::VoxelInstance
|
- interface::VoxelInstance
|
||||||
- The voxel world is handled by builtin/voxelworld on the server, and is built
|
- The voxel world is handled by builtin/voxelworld on the server, and is built
|
||||||
in to the client. VoxelRegistry is part of builtin/voxelworld on the server.
|
in to the client. VoxelRegistry is part of builtin/voxelworld on the server.
|
||||||
|
- How are voxel texture definitions stored?
|
||||||
|
- They are references to one of many texture atlases (many are needed in
|
||||||
|
case of high-resolution textures)
|
||||||
|
- They are an index into a texture atlas id
|
||||||
|
- A texture atlas definition is a list of texture resource names
|
||||||
|
- One texture atlas contains textures of one resolution
|
||||||
|
|
||||||
A way to define block properties:
|
A way to define block properties:
|
||||||
- interface::-based because the client has to support blocks directly:
|
- interface::-based because the client has to support blocks directly:
|
||||||
|
129
src/impl/atlas.cpp
Normal file
129
src/impl/atlas.cpp
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
// Copyright 2014 Perttu Ahola <celeron55@gmail.com>
|
||||||
|
#include "interface/atlas.h"
|
||||||
|
#include <Context.h>
|
||||||
|
#include <ResourceCache.h>
|
||||||
|
#include <Texture2D.h>
|
||||||
|
|
||||||
|
namespace interface {
|
||||||
|
|
||||||
|
struct CTextureAtlasRegistry: public TextureAtlasRegistry
|
||||||
|
{
|
||||||
|
magic::Context *m_context;
|
||||||
|
sv_<TextureAtlasDefinition> m_defs;
|
||||||
|
sv_<TextureAtlasCache> m_cache;
|
||||||
|
|
||||||
|
CTextureAtlasRegistry(magic::Context *context):
|
||||||
|
m_context(context)
|
||||||
|
{}
|
||||||
|
|
||||||
|
const AtlasSegmentReference add_segment(
|
||||||
|
const AtlasSegmentDefinition &segment_def)
|
||||||
|
{
|
||||||
|
throw Exception("Not implemented");
|
||||||
|
// Get Texture2D resource
|
||||||
|
magic::ResourceCache *magic_cache =
|
||||||
|
m_context->GetSubsystem<magic::ResourceCache>();
|
||||||
|
magic::Texture2D *texture = magic_cache->GetResource<magic::Texture2D>(
|
||||||
|
segment_def.resource_name);
|
||||||
|
// Get resolution of texture
|
||||||
|
magic::IntVector2 texture_size(texture->GetWidth(), texture->GetHeight());
|
||||||
|
// Try to find a texture atlas for this texture size
|
||||||
|
TextureAtlasDefinition *atlas_def = NULL;
|
||||||
|
for(TextureAtlasDefinition &def0 : m_defs){
|
||||||
|
if(def0.segment_resolution == texture_size){
|
||||||
|
size_t max = def0.total_segments.x_ * def0.total_segments.y_;
|
||||||
|
if(atlas_def->segments.size() >= max)
|
||||||
|
continue; // Full
|
||||||
|
atlas_def = &def0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If not found, create a texture atlas for this texture size
|
||||||
|
if(!atlas_def){
|
||||||
|
// Create a new texture atlas
|
||||||
|
m_defs.resize(m_defs.size()+1);
|
||||||
|
atlas_def = &m_defs[m_defs.size()-1];
|
||||||
|
atlas_def->id = m_defs.size()-1;
|
||||||
|
// Calculate segment resolution
|
||||||
|
atlas_def->segment_resolution = magic::IntVector2(
|
||||||
|
texture_size.x_ / segment_def.total_segments.x_,
|
||||||
|
texture_size.y_ / segment_def.total_segments.y_
|
||||||
|
);
|
||||||
|
// Calculate total segments based on segment resolution
|
||||||
|
int max_res = 2048;
|
||||||
|
atlas_def->total_segments = magic::IntVector2(
|
||||||
|
max_res / atlas_def->segment_resolution.x_,
|
||||||
|
max_res / atlas_def->segment_resolution.y_,
|
||||||
|
);
|
||||||
|
// Create texture for new atlas
|
||||||
|
// TODO: Extend cache to fit this atlas if it doesn't yet
|
||||||
|
// TODO: Set texture of cached atlas
|
||||||
|
}
|
||||||
|
// TODO: Add this definition to the atlas
|
||||||
|
}
|
||||||
|
|
||||||
|
const TextureAtlasDefinition* get_atlas_definition(uint atlas_id)
|
||||||
|
{
|
||||||
|
if(atlas_id >= m_defs.size())
|
||||||
|
return NULL;
|
||||||
|
return &m_defs[atlas_id];
|
||||||
|
}
|
||||||
|
|
||||||
|
const AtlasSegmentDefinition* get_segment_definition(
|
||||||
|
const AtlasSegmentReference &ref)
|
||||||
|
{
|
||||||
|
const TextureAtlasDefinition *atlas = get_atlas_definition(ref.atlas_id);
|
||||||
|
if(!atlas)
|
||||||
|
return NULL;
|
||||||
|
if(ref.segment_id >= atlas->segments.size())
|
||||||
|
return NULL;
|
||||||
|
return &atlas->segments[ref.segment_id];
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_segment_cache(AtlasSegmentCache &cache,
|
||||||
|
const AtlasSegmentDefinition &def, const TextureAtlasDefinition &atlas)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
// TODO: Get Texture2D resource
|
||||||
|
// TODO: Check that resolution of texture matches with atlas
|
||||||
|
// TODO:
|
||||||
|
}
|
||||||
|
|
||||||
|
const AtlasSegmentCache* get_texture(const AtlasSegmentReference &ref)
|
||||||
|
{
|
||||||
|
if(ref.atlas_id >= m_cache.size()){
|
||||||
|
if(ref.atlas_id >= m_defs.size())
|
||||||
|
return NULL;
|
||||||
|
// New atlases are left with valid=false
|
||||||
|
m_cache.resize(m_defs.size());
|
||||||
|
}
|
||||||
|
TextureAtlasCache &cache = m_cache[ref.atlas_id];
|
||||||
|
if(!cache.valid){
|
||||||
|
const auto &id = ref.atlas_id;
|
||||||
|
cache.segment_resolution = m_defs[id].segment_resolution;
|
||||||
|
cache.total_segments = m_defs[id].total_segments;
|
||||||
|
// New segments are left with valid=false
|
||||||
|
cache.segments.resize(m_defs[id].segments.size());
|
||||||
|
cache.valid = true;
|
||||||
|
}
|
||||||
|
if(ref.segment_id >= cache.segments.size())
|
||||||
|
return NULL;
|
||||||
|
AtlasSegmentCache &seg_cache = cache.segments[ref.segment_id];
|
||||||
|
if(seg_cache.valid)
|
||||||
|
return &seg_cache;
|
||||||
|
TextureAtlasDefinition &atlas_def = m_defs[ref.atlas_id];
|
||||||
|
const AtlasSegmentDefinition &seg_def = atlas_def.segments[ref.segment_id];
|
||||||
|
update_segment_cache(seg_cache, seg_def, atlas_def);
|
||||||
|
seg_cache.valid = true;
|
||||||
|
return &seg_cache;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TextureAtlasRegistry* createTextureAtlasRegistry(magic::Context *context)
|
||||||
|
{
|
||||||
|
return new CTextureAtlasRegistry(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// vim: set noet ts=4 sw=4:
|
48
src/impl/block.cpp
Normal file
48
src/impl/block.cpp
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
// Copyright 2014 Perttu Ahola <celeron55@gmail.com>
|
||||||
|
#include "interface/block.h"
|
||||||
|
|
||||||
|
namespace interface {
|
||||||
|
|
||||||
|
struct CBlockRegistry: public BlockRegistry
|
||||||
|
{
|
||||||
|
VoxelRegistry *m_voxel_reg;
|
||||||
|
sv_<BlockDefinition> m_defs;
|
||||||
|
|
||||||
|
CBlockRegistry(VoxelRegistry *voxel_reg):
|
||||||
|
m_voxel_reg(voxel_reg)
|
||||||
|
{}
|
||||||
|
|
||||||
|
BlockTypeId add_block_with_predefined_segments(const BlockDefinition &def)
|
||||||
|
{
|
||||||
|
throw Exception("Not implemented");
|
||||||
|
return BLOCKTYPEID_UNDEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockTypeId add_block_generate_segments(const BlockSourceDefinition &def)
|
||||||
|
{
|
||||||
|
throw Exception("Not implemented");
|
||||||
|
return BLOCKTYPEID_UNDEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
const BlockDefinition* get(const BlockTypeId &id)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const BlockDefinition* get(const BlockName &name)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Network serialization
|
||||||
|
// TODO: Ability to track changes (just some kind of set_dirty()?)
|
||||||
|
};
|
||||||
|
|
||||||
|
BlockRegistry* createBlockRegistry(VoxelRegistry *voxel_reg)
|
||||||
|
{
|
||||||
|
return new CBlockRegistry(voxel_reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// vim: set noet ts=4 sw=4:
|
102
src/impl/mesh.cpp
Normal file
102
src/impl/mesh.cpp
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
// Copyright 2014 Perttu Ahola <celeron55@gmail.com>
|
||||||
|
#include "interface/mesh.h"
|
||||||
|
#include <PolyVoxCore/SimpleVolume.h>
|
||||||
|
#include <PolyVoxCore/SurfaceMesh.h>
|
||||||
|
#include <PolyVoxCore/CubicSurfaceExtractorWithNormals.h>
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
|
||||||
|
#include <Scene.h>
|
||||||
|
#include <Node.h>
|
||||||
|
#include <StaticModel.h>
|
||||||
|
#include <Model.h>
|
||||||
|
#include <Geometry.h>
|
||||||
|
#include <IndexBuffer.h>
|
||||||
|
#include <VertexBuffer.h>
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
namespace magic = Urho3D;
|
||||||
|
namespace pv = PolyVox;
|
||||||
|
|
||||||
|
// Just do this; Urho3D's stuff doesn't really clash with anything in buildat
|
||||||
|
using namespace Urho3D;
|
||||||
|
|
||||||
|
namespace interface {
|
||||||
|
|
||||||
|
// Creates a model from a string; eg. (2, 2, 2, "11101111")
|
||||||
|
Model* create_simple_voxel_model(Context *context,
|
||||||
|
int w, int h, int d, const ss_ &source_data)
|
||||||
|
{
|
||||||
|
if(w < 0 || h < 0 || d < 0)
|
||||||
|
throw Exception("Negative dimension");
|
||||||
|
if(w * h * d != (int)source_data.size())
|
||||||
|
throw Exception("Mismatched data size");
|
||||||
|
pv::SimpleVolume<uint8_t> volData(pv::Region(
|
||||||
|
pv::Vector3DInt32(-1, -1, -1),
|
||||||
|
pv::Vector3DInt32(w, h, d)));
|
||||||
|
size_t i = 0;
|
||||||
|
for(int z = 0; z < d; z++)
|
||||||
|
for(int y = 0; y < h; y++)
|
||||||
|
for(int x = 0; x < w; x++){
|
||||||
|
char c = source_data[i++];
|
||||||
|
volData.setVoxelAt(x, y, z, c == '0' ? 0 : 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
pv::SurfaceMesh<pv::PositionMaterialNormal> pv_mesh;
|
||||||
|
pv::CubicSurfaceExtractorWithNormals<pv::SimpleVolume<uint8_t>>
|
||||||
|
surfaceExtractor(&volData, volData.getEnclosingRegion(), &pv_mesh);
|
||||||
|
surfaceExtractor.execute();
|
||||||
|
|
||||||
|
const sv_<uint32_t> &pv_indices = pv_mesh.getIndices();
|
||||||
|
const sv_<pv::PositionMaterialNormal> &pv_vertices = pv_mesh.getVertices();
|
||||||
|
|
||||||
|
const size_t num_vertices = pv_vertices.size();
|
||||||
|
const size_t num_indices = pv_indices.size();
|
||||||
|
|
||||||
|
sv_<float> vertex_data;
|
||||||
|
vertex_data.resize(num_vertices * 6); // vertex + normal
|
||||||
|
for(size_t i = 0; i < num_vertices; i++){
|
||||||
|
vertex_data[i*6 + 0] = pv_vertices[i].position.getX() - w/2.0f - 0.5f;
|
||||||
|
vertex_data[i*6 + 1] = pv_vertices[i].position.getY() - h/2.0f - 0.5f;
|
||||||
|
vertex_data[i*6 + 2] = pv_vertices[i].position.getZ() - d/2.0f - 0.5f;
|
||||||
|
vertex_data[i*6 + 3] = pv_vertices[i].normal.getX();
|
||||||
|
vertex_data[i*6 + 4] = pv_vertices[i].normal.getY();
|
||||||
|
vertex_data[i*6 + 5] = pv_vertices[i].normal.getZ();
|
||||||
|
}
|
||||||
|
|
||||||
|
sv_<short> index_data;
|
||||||
|
index_data.resize(num_indices);
|
||||||
|
for(size_t i = 0; i < num_indices; i++){
|
||||||
|
if(pv_indices[i] >= 0x10000)
|
||||||
|
throw Exception("Index too large");
|
||||||
|
index_data[i] = pv_indices[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedPtr<VertexBuffer> vb(new VertexBuffer(context));
|
||||||
|
// Shadowed buffer needed for raycasts to work, and so that data can be
|
||||||
|
// automatically restored on device loss
|
||||||
|
vb->SetShadowed(true);
|
||||||
|
vb->SetSize(num_vertices, magic::MASK_POSITION | magic::MASK_NORMAL);
|
||||||
|
vb->SetData(&vertex_data[0]);
|
||||||
|
|
||||||
|
SharedPtr<IndexBuffer> ib(new IndexBuffer(context));
|
||||||
|
ib->SetShadowed(true);
|
||||||
|
ib->SetSize(num_indices, false);
|
||||||
|
ib->SetData(&index_data[0]);
|
||||||
|
|
||||||
|
SharedPtr<Geometry> geom(new Geometry(context));
|
||||||
|
geom->SetVertexBuffer(0, vb);
|
||||||
|
geom->SetIndexBuffer(ib);
|
||||||
|
geom->SetDrawRange(TRIANGLE_LIST, 0, num_indices);
|
||||||
|
|
||||||
|
Model *fromScratchModel = new Model(context);
|
||||||
|
fromScratchModel->SetNumGeometries(1);
|
||||||
|
fromScratchModel->SetGeometry(0, 0, geom);
|
||||||
|
fromScratchModel->SetBoundingBox(BoundingBox(
|
||||||
|
Vector3(-0.5f*w, -0.5f*h, -0.5f*d), Vector3(0.5f*w, 0.5f*h, 0.5f*d)));
|
||||||
|
|
||||||
|
return fromScratchModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace interface
|
||||||
|
// vim: set noet ts=4 sw=4:
|
@ -1,102 +1,49 @@
|
|||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
// Copyright 2014 Perttu Ahola <celeron55@gmail.com>
|
// Copyright 2014 Perttu Ahola <celeron55@gmail.com>
|
||||||
#include "interface/voxel.h"
|
#include "interface/voxel.h"
|
||||||
#include <PolyVoxCore/SimpleVolume.h>
|
|
||||||
#include <PolyVoxCore/SurfaceMesh.h>
|
|
||||||
#include <PolyVoxCore/CubicSurfaceExtractorWithNormals.h>
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
|
|
||||||
#include <Scene.h>
|
|
||||||
#include <Node.h>
|
|
||||||
#include <StaticModel.h>
|
|
||||||
#include <Model.h>
|
|
||||||
#include <Geometry.h>
|
|
||||||
#include <IndexBuffer.h>
|
|
||||||
#include <VertexBuffer.h>
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
|
|
||||||
namespace magic = Urho3D;
|
|
||||||
namespace pv = PolyVox;
|
|
||||||
|
|
||||||
// Just do this; Urho3D's stuff doesn't really clash with anything in buildat
|
|
||||||
using namespace Urho3D;
|
|
||||||
|
|
||||||
namespace interface {
|
namespace interface {
|
||||||
|
|
||||||
// Creates a model from a string; eg. (2, 2, 2, "11101111")
|
struct CVoxelRegistry: public VoxelRegistry
|
||||||
Model* create_simple_voxel_model(Context *context,
|
|
||||||
int w, int h, int d, const ss_ &source_data)
|
|
||||||
{
|
{
|
||||||
if(w < 0 || h < 0 || d < 0)
|
TextureAtlasRegistry *m_atlas_reg;
|
||||||
throw Exception("Negative dimension");
|
sv_<VoxelDefinition> m_defs;
|
||||||
if(w * h * d != (int)source_data.size())
|
sv_<CachedVoxelDefinition> m_cached_defs;
|
||||||
throw Exception("Mismatched data size");
|
|
||||||
pv::SimpleVolume<uint8_t> volData(pv::Region(
|
CVoxelRegistry(TextureAtlasRegistry *atlas_reg):
|
||||||
pv::Vector3DInt32(-1, -1, -1),
|
m_atlas_reg(atlas_reg)
|
||||||
pv::Vector3DInt32(w, h, d)));
|
{}
|
||||||
size_t i = 0;
|
|
||||||
for(int z = 0; z < d; z++)
|
VoxelTypeId add_voxel(const VoxelDefinition &def)
|
||||||
for(int y = 0; y < h; y++)
|
{
|
||||||
for(int x = 0; x < w; x++){
|
throw Exception("Not implemented");
|
||||||
char c = source_data[i++];
|
return VOXELTYPEID_UNDEFINED;
|
||||||
volData.setVoxelAt(x, y, z, c == '0' ? 0 : 255);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pv::SurfaceMesh<pv::PositionMaterialNormal> pv_mesh;
|
const VoxelDefinition* get(const VoxelTypeId &id)
|
||||||
pv::CubicSurfaceExtractorWithNormals<pv::SimpleVolume<uint8_t>>
|
{
|
||||||
surfaceExtractor(&volData, volData.getEnclosingRegion(), &pv_mesh);
|
return NULL;
|
||||||
surfaceExtractor.execute();
|
|
||||||
|
|
||||||
const sv_<uint32_t> &pv_indices = pv_mesh.getIndices();
|
|
||||||
const sv_<pv::PositionMaterialNormal> &pv_vertices = pv_mesh.getVertices();
|
|
||||||
|
|
||||||
const size_t num_vertices = pv_vertices.size();
|
|
||||||
const size_t num_indices = pv_indices.size();
|
|
||||||
|
|
||||||
sv_<float> vertex_data;
|
|
||||||
vertex_data.resize(num_vertices * 6); // vertex + normal
|
|
||||||
for(size_t i = 0; i < num_vertices; i++){
|
|
||||||
vertex_data[i*6 + 0] = pv_vertices[i].position.getX() - w/2.0f - 0.5f;
|
|
||||||
vertex_data[i*6 + 1] = pv_vertices[i].position.getY() - h/2.0f - 0.5f;
|
|
||||||
vertex_data[i*6 + 2] = pv_vertices[i].position.getZ() - d/2.0f - 0.5f;
|
|
||||||
vertex_data[i*6 + 3] = pv_vertices[i].normal.getX();
|
|
||||||
vertex_data[i*6 + 4] = pv_vertices[i].normal.getY();
|
|
||||||
vertex_data[i*6 + 5] = pv_vertices[i].normal.getZ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sv_<short> index_data;
|
const VoxelDefinition* get(const VoxelName &name)
|
||||||
index_data.resize(num_indices);
|
{
|
||||||
for(size_t i = 0; i < num_indices; i++){
|
return NULL;
|
||||||
if(pv_indices[i] >= 0x10000)
|
|
||||||
throw Exception("Index too large");
|
|
||||||
index_data[i] = pv_indices[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<VertexBuffer> vb(new VertexBuffer(context));
|
const CachedVoxelDefinition* get_cached(const VoxelTypeId &id)
|
||||||
// Shadowed buffer needed for raycasts to work, and so that data can be
|
{
|
||||||
// automatically restored on device loss
|
return NULL;
|
||||||
vb->SetShadowed(true);
|
}
|
||||||
vb->SetSize(num_vertices, magic::MASK_POSITION | magic::MASK_NORMAL);
|
|
||||||
vb->SetData(&vertex_data[0]);
|
|
||||||
|
|
||||||
SharedPtr<IndexBuffer> ib(new IndexBuffer(context));
|
|
||||||
ib->SetShadowed(true);
|
|
||||||
ib->SetSize(num_indices, false);
|
|
||||||
ib->SetData(&index_data[0]);
|
|
||||||
|
|
||||||
SharedPtr<Geometry> geom(new Geometry(context));
|
// TODO: Network serialization
|
||||||
geom->SetVertexBuffer(0, vb);
|
// TODO: Ability to track changes (just some kind of set_dirty()?)
|
||||||
geom->SetIndexBuffer(ib);
|
};
|
||||||
geom->SetDrawRange(TRIANGLE_LIST, 0, num_indices);
|
|
||||||
|
|
||||||
Model *fromScratchModel = new Model(context);
|
VoxelRegistry* createVoxelRegistry(TextureAtlasRegistry *atlas_reg)
|
||||||
fromScratchModel->SetNumGeometries(1);
|
{
|
||||||
fromScratchModel->SetGeometry(0, 0, geom);
|
return new CVoxelRegistry(atlas_reg);
|
||||||
fromScratchModel->SetBoundingBox(BoundingBox(
|
|
||||||
Vector3(-0.5f*w, -0.5f*h, -0.5f*d), Vector3(0.5f*w, 0.5f*h, 0.5f*d)));
|
|
||||||
|
|
||||||
return fromScratchModel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace interface
|
}
|
||||||
// vim: set noet ts=4 sw=4:
|
// vim: set noet ts=4 sw=4:
|
||||||
|
73
src/interface/atlas.h
Normal file
73
src/interface/atlas.h
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
// Copyright 2014 Perttu Ahola <celeron55@gmail.com>
|
||||||
|
#pragma once
|
||||||
|
#include "core/types.h"
|
||||||
|
#include <Vector2.h>
|
||||||
|
|
||||||
|
namespace Urho3D
|
||||||
|
{
|
||||||
|
class Context;
|
||||||
|
class Texture2D;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace interface
|
||||||
|
{
|
||||||
|
namespace magic = Urho3D;
|
||||||
|
|
||||||
|
struct AtlasSegmentReference
|
||||||
|
{
|
||||||
|
uint atlas_id = 0;
|
||||||
|
uint segment_id = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AtlasSegmentDefinition
|
||||||
|
{
|
||||||
|
ss_ resource_name;
|
||||||
|
magic::IntVector2 total_segments;
|
||||||
|
magic::IntVector2 select_segment;
|
||||||
|
// TODO: Rotation
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AtlasSegmentCache
|
||||||
|
{
|
||||||
|
bool valid = false;
|
||||||
|
magic::Texture2D *texture = NULL;
|
||||||
|
magic::Vector2 coord0;
|
||||||
|
magic::Vector2 coord1;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TextureAtlasDefinition
|
||||||
|
{
|
||||||
|
uint id;
|
||||||
|
magic::IntVector2 segment_resolution;
|
||||||
|
magic::IntVector2 total_segments;
|
||||||
|
sv_<AtlasSegmentDefinition> segments;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TextureAtlasCache
|
||||||
|
{
|
||||||
|
bool valid = false;
|
||||||
|
magic::Texture2D *texture = NULL;
|
||||||
|
magic::IntVector2 segment_resolution;
|
||||||
|
magic::IntVector2 total_segments;
|
||||||
|
sv_<AtlasSegmentCache> segments;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TextureAtlasRegistry
|
||||||
|
{
|
||||||
|
virtual ~TextureAtlasRegistry(){}
|
||||||
|
|
||||||
|
virtual const AtlasSegmentReference add_segment(
|
||||||
|
const AtlasSegmentDefinition &segment_def) = 0;
|
||||||
|
|
||||||
|
virtual const TextureAtlasDefinition* get_atlas_definition(
|
||||||
|
uint atlas_id) = 0;
|
||||||
|
virtual const AtlasSegmentDefinition* get_segment_definition(
|
||||||
|
const AtlasSegmentReference &ref) = 0;
|
||||||
|
virtual const AtlasSegmentCache* get_texture(
|
||||||
|
const AtlasSegmentReference &ref) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
TextureAtlasRegistry* createTextureAtlasRegistry(magic::Context *context);
|
||||||
|
}
|
||||||
|
// vim: set noet ts=4 sw=4:
|
52
src/interface/block.h
Normal file
52
src/interface/block.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
// Copyright 2014 Perttu Ahola <celeron55@gmail.com>
|
||||||
|
#pragma once
|
||||||
|
#include "core/types.h"
|
||||||
|
#include <PolyVoxCore/Vector.h>
|
||||||
|
#include "interface/voxel.h"
|
||||||
|
|
||||||
|
namespace interface
|
||||||
|
{
|
||||||
|
namespace pv = PolyVox;
|
||||||
|
|
||||||
|
typedef ss_ BlockName;
|
||||||
|
typedef uint32_t BlockTypeId;
|
||||||
|
static constexpr uint32_t BLOCKTYPEID_UNDEFINED = 0;
|
||||||
|
|
||||||
|
struct BlockDefinition
|
||||||
|
{
|
||||||
|
BlockName name;
|
||||||
|
BlockTypeId id;
|
||||||
|
uint8_t num_rotations = 0; // Supported: 0, 4, 24
|
||||||
|
pv::Vector3DUint8 size = pv::Vector3DUint8(0,0,0); // Size in voxels
|
||||||
|
sv_<VoxelTypeId> segments; // Rotations*voxels
|
||||||
|
};
|
||||||
|
|
||||||
|
// Voxels and a BlockDefinition can be generated based on this
|
||||||
|
struct BlockSourceDefinition
|
||||||
|
{
|
||||||
|
BlockName name;
|
||||||
|
uint8_t num_rotations = 0; // Supported: 0, 4, 24
|
||||||
|
pv::Vector3DUint8 size = pv::Vector3DUint8(0,0,0); // Size in voxels
|
||||||
|
sv_<ss_> side_textures; // 6 resource names
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BlockRegistry
|
||||||
|
{
|
||||||
|
virtual ~BlockRegistry(){}
|
||||||
|
|
||||||
|
virtual BlockTypeId add_block_with_predefined_segments(
|
||||||
|
const BlockDefinition &def) = 0;
|
||||||
|
virtual BlockTypeId add_block_generate_segments(
|
||||||
|
const BlockSourceDefinition &def) =0;
|
||||||
|
|
||||||
|
virtual const BlockDefinition* get(const BlockTypeId &id) = 0;
|
||||||
|
virtual const BlockDefinition* get(const BlockName &name) = 0;
|
||||||
|
|
||||||
|
// TODO: Network serialization
|
||||||
|
// TODO: Ability to track changes (just some kind of set_dirty()?)
|
||||||
|
};
|
||||||
|
|
||||||
|
BlockRegistry* createBlockRegistry(VoxelRegistry *voxel_reg);
|
||||||
|
}
|
||||||
|
// vim: set noet ts=4 sw=4:
|
19
src/interface/mesh.h
Normal file
19
src/interface/mesh.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
// Copyright 2014 Perttu Ahola <celeron55@gmail.com>
|
||||||
|
#pragma once
|
||||||
|
#include "core/types.h"
|
||||||
|
|
||||||
|
namespace Urho3D
|
||||||
|
{
|
||||||
|
class Context;
|
||||||
|
class Model;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace interface
|
||||||
|
{
|
||||||
|
using namespace Urho3D;
|
||||||
|
|
||||||
|
Model* create_simple_voxel_model(Context *context, int w, int h, int d,
|
||||||
|
const ss_ &source_data);
|
||||||
|
}
|
||||||
|
// vim: set noet ts=4 sw=4:
|
@ -2,18 +2,76 @@
|
|||||||
// Copyright 2014 Perttu Ahola <celeron55@gmail.com>
|
// Copyright 2014 Perttu Ahola <celeron55@gmail.com>
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "core/types.h"
|
#include "core/types.h"
|
||||||
|
#include "interface/atlas.h"
|
||||||
namespace Urho3D
|
#include <PolyVoxCore/Vector.h>
|
||||||
{
|
|
||||||
class Context;
|
|
||||||
class Model;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace interface
|
namespace interface
|
||||||
{
|
{
|
||||||
using namespace Urho3D;
|
namespace pv = PolyVox;
|
||||||
|
|
||||||
Model* create_simple_voxel_model(Context *context, int w, int h, int d,
|
typedef uint32_t VoxelTypeId;
|
||||||
const ss_ &source_data);
|
static constexpr uint32_t VOXELTYPEID_MAX = 1398101-1;
|
||||||
|
static constexpr uint32_t VOXELTYPEID_UNDEFINED = 0;
|
||||||
|
|
||||||
|
struct VoxelName
|
||||||
|
{
|
||||||
|
ss_ block_name; // Name of the block this was instanced from
|
||||||
|
uint segment_x = 0; // Which segment of the block this was instanced from
|
||||||
|
uint segment_y = 0;
|
||||||
|
uint segment_z = 0;
|
||||||
|
uint rotation_primary = 0; // 4 possible rotations when looking at a face
|
||||||
|
uint rotation_secondary = 0; // 6 possible directions for a face to point to
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VoxelDefinition
|
||||||
|
{
|
||||||
|
VoxelName name;
|
||||||
|
VoxelTypeId id = VOXELTYPEID_UNDEFINED;
|
||||||
|
// Textures (voxels have 6 sides)
|
||||||
|
// These must be definitions (not references) because each client has to
|
||||||
|
// be able to construct their atlases from different texture sizes
|
||||||
|
AtlasSegmentDefinition textures[6];
|
||||||
|
// Other properties
|
||||||
|
ss_ handler_module;
|
||||||
|
// TODO: Flag for whether all faces should be always drawn (in case the
|
||||||
|
// textures contain holes)
|
||||||
|
// TODO: Flag for whether this voxel is physically solid
|
||||||
|
// TODO: Some kind of property for defining whether this is a thing for
|
||||||
|
// which adjacent voxels of the same thing type don't have faces,
|
||||||
|
// and what thing type that is in this case
|
||||||
|
};
|
||||||
|
|
||||||
|
// This definition should be as small as practical so that large portions of
|
||||||
|
// the definition array can fit in CPU cache
|
||||||
|
// (the absolute maximum number of these is VOXELTYPEID_MAX+1)
|
||||||
|
struct CachedVoxelDefinition
|
||||||
|
{
|
||||||
|
const AtlasSegmentCache *textures[6] = {NULL};
|
||||||
|
ss_ handler_module;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VoxelRegistry
|
||||||
|
{
|
||||||
|
virtual ~VoxelRegistry(){}
|
||||||
|
|
||||||
|
virtual VoxelTypeId add_voxel(const VoxelDefinition &def) = 0;
|
||||||
|
|
||||||
|
virtual const VoxelDefinition* get(const VoxelTypeId &id) = 0;
|
||||||
|
virtual const VoxelDefinition* get(const VoxelName &name) = 0;
|
||||||
|
virtual const CachedVoxelDefinition* get_cached(const VoxelTypeId &id) = 0;
|
||||||
|
|
||||||
|
// TODO: Network serialization
|
||||||
|
// TODO: Ability to track changes (just some kind of set_dirty()?)
|
||||||
|
};
|
||||||
|
|
||||||
|
VoxelRegistry* createVoxelRegistry(TextureAtlasRegistry *atlas_reg);
|
||||||
|
|
||||||
|
struct VoxelInstance
|
||||||
|
{
|
||||||
|
uint32_t data;
|
||||||
|
|
||||||
|
VoxelTypeId getId(){ return data & 0x001fffff; }
|
||||||
|
uint8_t getMSB(){ return (data>>24) & 0xff; }
|
||||||
|
};
|
||||||
}
|
}
|
||||||
// vim: set noet ts=4 sw=4:
|
// vim: set noet ts=4 sw=4:
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include "lua_bindings/util.h"
|
#include "lua_bindings/util.h"
|
||||||
#include "core/log.h"
|
#include "core/log.h"
|
||||||
#include "client/app.h"
|
#include "client/app.h"
|
||||||
#include "interface/voxel.h"
|
#include "interface/mesh.h"
|
||||||
#include <tolua++.h>
|
#include <tolua++.h>
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
|
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user