lua_bindings: VoxelName, AtlasSegmentDefinition, VoxelDefinition and VoxelRegistry::add_voxel()

master
Perttu Ahola 2014-10-19 18:48:07 +03:00
parent 17b09fabdb
commit 6d7a88dad2
5 changed files with 209 additions and 4 deletions

View File

@ -12,6 +12,9 @@ buildat.safe.disconnect = __buildat_disconnect
buildat.safe.get_time_us = __buildat_get_time_us
buildat.safe.profiler_block_begin = __buildat_profiler_block_begin
buildat.safe.profiler_block_end = __buildat_profiler_block_end
buildat.safe.VoxelName = __buildat_VoxelName
buildat.safe.AtlasSegmentDefinition = __buildat_AtlasSegmentDefinition
buildat.safe.VoxelDefinition = __buildat_VoxelDefinition
buildat.safe.createVoxelRegistry = __buildat_createVoxelRegistry
buildat.safe.createAtlasRegistry = __buildat_createAtlasRegistry

View File

@ -222,3 +222,37 @@ SubscribeToEvent(object, event_name, callback)
- Return value: Name of the generated global callback which can be unusbscbribed
from Urho3D via UnsubscribeFromEvent(event_name, callback_name).
Miscellaneous
=============
You can create a client-side voxel registry like this:
local voxel_reg = buildat.createVoxelRegistry()
local atlas_reg = buildat.createAtlasRegistry()
do
local vdef = buildat.VoxelDefinition()
vdef.name.block_name = "rock"
vdef.name.segment_x = 0
vdef.name.segment_y = 0
vdef.name.segment_z = 0
vdef.name.rotation_primary = 0
vdef.name.rotation_secondary = 0
vdef.handler_module = ""
local textures = {}
for i = 1, 6 do
local seg = buildat.AtlasSegmentDefinition()
seg.resource_name = "main/rock.png"
seg.total_segments = magic.IntVector2(1, 1)
seg.select_segment = magic.IntVector2(0, 0)
table.insert(textures, seg)
end
vdef.textures = textures
vdef.edge_material_id = buildat.VoxelDefinition.EDGEMATERIALID_GROUND
vdef.physically_solid = true
voxel_reg:add_voxel(vdef)
voxel_reg:add_voxel(vdef)
voxel_reg:add_voxel(vdef)
voxel_reg:add_voxel(vdef)
end

View File

@ -38,6 +38,7 @@ namespace interface
typedef uint8_t EdgeMaterialId;
static constexpr EdgeMaterialId EDGEMATERIALID_EMPTY = 0;
static constexpr EdgeMaterialId EDGEMATERIALID_GROUND = 1;
// Values at and above 10 are freely usable.
struct VoxelDefinition
{

View File

@ -0,0 +1,27 @@
// http://www.apache.org/licenses/LICENSE-2.0
// Copyright 2014 Perttu Ahola <celeron55@gmail.com>
#pragma once
#include "core/types.h"
#include <luabind/luabind.hpp>
#define LUABIND_ENUM_CLASS(X) \
namespace luabind { \
template<> struct default_converter<X>: \
native_converter_base<X> \
{ \
static int compute_score(lua_State* L, int index){ \
return lua_type(L, index) == LUA_TNUMBER ? 0 : -1; \
} \
X to_cpp_deferred(lua_State* L, int index){ \
return X(lua_tonumber(L, index)); \
} \
void to_lua_deferred(lua_State* L, X const& x){ \
lua_pushinteger(L, (int)x); \
} \
}; \
template<> struct default_converter<X const&>: \
default_converter<X> \
{}; \
} \
// vim: set noet ts=4 sw=4:

View File

@ -1,16 +1,110 @@
// http://www.apache.org/licenses/LICENSE-2.0
// Copyright 2014 Perttu Ahola <celeron55@gmail.com>
#include "lua_bindings/util.h"
#include "core/log.h"
#include "interface/voxel.h"
#include "lua_bindings/util.h"
#include "lua_bindings/luabind_util.h"
#include <luabind/luabind.hpp>
#include <luabind/adopt_policy.hpp>
#include <luabind/object.hpp>
#include <tolua++.h>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#include <Vector2.h>
#pragma GCC diagnostic pop
#define MODULE "lua_bindings"
using interface::VoxelInstance;
using interface::VoxelRegistry;
#define GET_TOLUA_STUFF(result_name, index, type){ \
tolua_Error tolua_err; \
if(!tolua_isusertype(L, index, #type, 0, &tolua_err)){ \
tolua_error(L, __PRETTY_FUNCTION__, &tolua_err); \
throw Exception("Expected \"" #type "\""); \
} \
} \
type *result_name = (type*)tolua_tousertype(L, index, 0);
using namespace interface;
using Urho3D::IntVector2;
LUABIND_ENUM_CLASS(FaceDrawType);
namespace lua_bindings {
luabind::object asd_get_total_segments(
const AtlasSegmentDefinition &def, lua_State *L)
{
// TODO
return luabind::object();
}
void asd_set_total_segments(
AtlasSegmentDefinition &def, luabind::object value_safe, lua_State *L)
{
// This won't work
/*luabind::object value_meta = luabind::getmetatable(value_safe);
if(luabind::object_cast<ss_>(value_meta["type_name"]) != "IntVector2")
throw Exception("Value is not a sandboxed IntVector2");
luabind::object value = value_meta["unsafe"];
value.push(L);
int top_L = lua_gettop(L);
GET_TOLUA_STUFF(v, top_L, IntVector2);*/
// This works
lua_getmetatable(L, 2);
lua_getfield(L, -1, "type_name");
if(ss_(lua_tostring(L, -1)) != "IntVector2"){
lua_pop(L, 2); // type_name, metatable
throw Exception("Value is not a sandboxed IntVector2");
}
lua_pop(L, 1); // type_name
lua_getfield(L, -1, "unsafe");
int top_L = lua_gettop(L);
GET_TOLUA_STUFF(v, top_L, IntVector2);
def.total_segments = *v;
lua_pop(L, 2); // unsafe, metatable
}
luabind::object asd_get_select_segment(
const AtlasSegmentDefinition &def, lua_State *L)
{
// TODO
return luabind::object();
}
void asd_set_select_segment(
AtlasSegmentDefinition &def, luabind::object value, lua_State *L)
{
lua_getmetatable(L, 2);
lua_getfield(L, -1, "type_name");
if(ss_(lua_tostring(L, -1)) != "IntVector2"){
lua_pop(L, 2); // type_name, metatable
throw Exception("Value is not a sandboxed IntVector2");
}
lua_pop(L, 1); // type_name
lua_getfield(L, -1, "unsafe");
int top_L = lua_gettop(L);
GET_TOLUA_STUFF(v, top_L, IntVector2);
def.select_segment = *v;
lua_pop(L, 2); // unsafe, metatable
}
luabind::object vdef_get_textures(const VoxelDefinition &def, lua_State *L)
{
luabind::object result = luabind::newtable(L);
for(size_t i = 0; i < 6; i++){
result[i+1] = luabind::object(L, def.textures[i]);
}
return result;
}
void vdef_set_textures(VoxelDefinition &def, luabind::object value, lua_State *L)
{
for(size_t i = 0; i < 6; i++){
def.textures[i] = luabind::object_cast<AtlasSegmentDefinition>(
value[i+1]);
}
}
sp_<VoxelRegistry> createVoxelRegistry(lua_State *L)
{
return sp_<VoxelRegistry>(
@ -22,11 +116,57 @@ void init_voxel(lua_State *L)
using namespace luabind;
module(L)[
class_<VoxelName, bases<>, sp_<VoxelName>>("__buildat_VoxelName")
.def(constructor<>())
.def_readwrite("block_name", &VoxelName::block_name)
.def_readwrite("segment_x", &VoxelName::segment_x)
.def_readwrite("segment_y", &VoxelName::segment_y)
.def_readwrite("segment_z", &VoxelName::segment_z)
.def_readwrite("rotation_primary", &VoxelName::rotation_primary)
.def_readwrite("rotation_secondary", &VoxelName::rotation_secondary)
,
class_<AtlasSegmentDefinition, bases<>, sp_<AtlasSegmentDefinition>>(
"__buildat_AtlasSegmentDefinition")
.def(constructor<>())
.def_readwrite("resource_name",
&AtlasSegmentDefinition::resource_name)
.property("total_segments",
&asd_get_total_segments, &asd_set_total_segments)
.property("select_segment",
&asd_get_select_segment, &asd_set_select_segment)
.def_readwrite("lod_simulation",
&AtlasSegmentDefinition::lod_simulation)
,
class_<VoxelDefinition, bases<>, sp_<VoxelDefinition>>(
"__buildat_VoxelDefinition")
.def(constructor<>())
.def_readwrite("name", &VoxelDefinition::name)
.def_readwrite("id", &VoxelDefinition::id)
.property("textures", &vdef_get_textures, &vdef_set_textures)
.def_readwrite("face_draw_type", &VoxelDefinition::face_draw_type)
.def_readwrite("edge_material_id", &VoxelDefinition::edge_material_id)
.def_readwrite("physically_solid", &VoxelDefinition::physically_solid)
.enum_("FaceDrawType")[
value("FACEDRAWTYPE_NEVER", (int)FaceDrawType::NEVER),
value("FACEDRAWTYPE_ALWAYS", (int)FaceDrawType::ALWAYS),
value("FACEDRAWTYPE_ON_EDGE", (int)FaceDrawType::ON_EDGE)
]
.enum_("EdgeMaterialId")[
value("EDGEMATERIALID_EMPTY", EDGEMATERIALID_EMPTY),
value("EDGEMATERIALID_GROUND", EDGEMATERIALID_GROUND)
]
,
class_<VoxelRegistry, bases<>, sp_<VoxelRegistry>>("VoxelRegistry")
.def("add_voxel", &VoxelRegistry::add_voxel)
.def("get_by_id", (const VoxelDefinition*(VoxelRegistry::*)
(const VoxelTypeId&)) &VoxelRegistry::get)
.def("get_by_name", (const VoxelDefinition*(VoxelRegistry::*)
(const VoxelName&)) &VoxelRegistry::get)
.def("serialize", (ss_(VoxelRegistry::*) ())
&VoxelRegistry::serialize)
.def("deserialize", (void(VoxelRegistry::*) (const ss_ &))
&VoxelRegistry::deserialize),
&VoxelRegistry::deserialize)
,
def("__buildat_createVoxelRegistry", &createVoxelRegistry)
];
}