This commit is contained in:
Perttu Ahola 2014-10-19 23:39:35 +03:00
parent ddb0e2e8c8
commit b9b47ee6d9
11 changed files with 346 additions and 73 deletions

View File

@ -127,6 +127,31 @@ function M.init()
", d="..math.floor(d)..", #data="..data:GetSize()..
", node="..node:GetID())
do
local zone_node = replicate.main_scene:CreateChild("Zone")
local zone = zone_node:CreateComponent("Zone")
local cs = M.chunk_size_voxels
zone.boundingBox = magic.BoundingBox(
node_p - magic.Vector3(cs.x, cs.y, cs.z)/2,
node_p + magic.Vector3(cs.x, cs.y, cs.z)/2
)
local has_sunlight = buildat.voxel_heuristic_has_sunlight(
data, voxel_reg)
if has_sunlight then
zone.ambientColor = magic.Color(0.1, 0.1, 0.1)
zone.fogColor = magic.Color(0.6, 0.7, 0.8)
else
zone.ambientColor = magic.Color(0, 0, 0)
zone.fogColor = magic.Color(0, 0, 0)
end
--zone.ambientColor = magic.Color(
-- math.random(), math.random(), math.random())
--zone.fogEnd = 10 + math.random() * 50
zone.fogStart = 10
zone.fogEnd = camera_far_clip * 1.2
--zone.ambientGradient = true
end
local near_trigger_d = nil
local near_weight = nil
local far_trigger_d = nil

View File

@ -344,9 +344,10 @@ struct Module: public interface::Module, public voxelworld::Interface
// TODO: Load from disk or something
//pv::Region region(-1, 0, -1, 1, 0, 1);
pv::Region region(-1, -1, -1, 1, 1, 1);
//pv::Region region(-1, -1, -1, 1, 1, 1);
//pv::Region region(-2, -1, -2, 2, 1, 2);
//pv::Region region(-3, -1, -3, 3, 1, 3);
pv::Region region(-5, -1, 0, 0, 1, 5);
//pv::Region region(-5, -1, -5, 5, 1, 5);
//pv::Region region(-6, -1, -6, 6, 1, 6);
//pv::Region region(-8, -1, -8, 8, 1, 8);
@ -624,6 +625,25 @@ struct Module: public interface::Module, public voxelworld::Interface
n->SetVar(StringHash("buildat_voxel_data"), Variant(
PODVector<uint8_t>((const uint8_t*)data.c_str(), data.size())));
{
// Y-seethrough (1 = can see, 0 = can't see)
pv::Region yst_region(0, 0, 0, w, 0, d);
pv::RawVolume<uint8_t> yst_volume(yst_region);
auto lc = yst_region.getLowerCorner();
auto uc = yst_region.getUpperCorner();
for(int z = lc.getZ(); z <= uc.getZ(); z++){
for(int y = lc.getY(); y <= uc.getY(); y++){
for(int x = lc.getX(); x <= uc.getX(); x++){
volume.setVoxelAt(x, y, z, 1);
}
}
}
ss_ data = interface::serialize_volume_compressed(yst_volume);
n->SetVar(StringHash("buildat_voxel_yst_data"), Variant(
PODVector<uint8_t>((const uint8_t*)data.c_str(),
data.size())));
}
// There are no collision shapes initially, but add the rigid body now
RigidBody *body = n->CreateComponent<RigidBody>(LOCAL);
body->SetFriction(0.75f);

View File

@ -63,6 +63,9 @@ buildat.safe.SpatialUpdateQueue = function()
}
end
-- TODO: Implement sandbox unwrapping in C++ and remove these from here
-- (already done in lua_bindings/voxel.cpp)
function buildat.safe.set_simple_voxel_model(safe_node, w, h, d, safe_buffer)
if not getmetatable(safe_node) or
getmetatable(safe_node).type_name ~= "Node" then
@ -184,6 +187,20 @@ function buildat.safe.clear_voxel_physics_boxes(safe_node)
__buildat_clear_voxel_physics_boxes(node)
end
function buildat.safe.voxel_heuristic_has_sunlight(safe_buffer, ...)
buffer = nil
if type(safe_buffer) == 'string' then
buffer = safe_buffer
else
if not getmetatable(safe_buffer) or
getmetatable(safe_buffer).type_name ~= "VectorBuffer" then
error("safe_buffer is not a sandboxed VectorBuffer instance")
end
buffer = getmetatable(safe_buffer).unsafe
end
return __buildat_voxel_heuristic_has_sunlight(buffer, ...)
end
local Vector3_prototype = {
x = 0,
y = 0,

View File

@ -235,8 +235,9 @@ function M.define(dst, util)
})
util.wc("BoundingBox", {
unsafe_constructor = util.wrap_function({"number", "number"},
function(min, max) -- TOOD: Many alternative constructors
unsafe_constructor = util.wrap_function({
{"number", "Vector3"}, {"number", "Vector3"}},
function(min, max)
return util.wrap_instance("BoundingBox", BoundingBox(min, max))
end),
instance_meta = {
@ -285,6 +286,8 @@ function M.define(dst, util)
shadowBias = util.simple_property("BiasParameters"),
shadowCascade = util.simple_property("CascadeParameters"),
color = util.simple_property("Color"),
range = util.simple_property("number"),
fadeDistance = util.simple_property("number"),
},
})
@ -335,6 +338,10 @@ function M.define(dst, util)
fogColor = util.simple_property(dst.Color),
fogStart = util.simple_property("number"),
fogEnd = util.simple_property("number"),
priority = util.simple_property("number"),
heightFog = util.simple_property("boolean"),
override = util.simple_property("boolean"),
ambientGradient = util.simple_property("boolean"),
},
})

View File

@ -27,94 +27,144 @@ local scene = replicate.main_scene
magic.input:SetMouseVisible(false)
-- Set up zone (global visual parameters)
local zone_node = scene:CreateChild("Zone")
local zone = zone_node:CreateComponent("Zone")
zone.boundingBox = magic.BoundingBox(-1000, 1000)
--zone.ambientColor = magic.Color(0.15, 0.15, 0.15)
zone.ambientColor = magic.Color(0.1, 0.1, 0.1)
--zone.ambientColor = magic.Color(0, 0, 0)
zone.fogColor = magic.Color(0.6, 0.7, 0.8)
zone.fogStart = 10
zone.fogEnd = FOG_END
--[[
do
local zone_node = scene:CreateChild("Zone")
local zone = zone_node:CreateComponent("Zone")
zone.boundingBox = magic.BoundingBox(-1000, 1000)
zone.ambientColor = magic.Color(0.1, 0.1, 0.1)
--zone.ambientColor = magic.Color(0, 0, 0)
zone.fogColor = magic.Color(0.6, 0.7, 0.8)
--zone.fogColor = magic.Color(0, 0, 0)
zone.fogStart = 10
zone.fogEnd = FOG_END
end
--]]
-- Add lights
--local node = scene:CreateChild("DirectionalLight")
--node.direction = magic.Vector3(0.0, -1.0, 0.0)
--local light = node:CreateComponent("Light")
--light.lightType = magic.LIGHT_DIRECTIONAL
--light.castShadows = true
--light.brightness = 0.1
--light.color = magic.Color(1.0, 1.0, 1.0)
do
--[[
local dirs = {
magic.Vector3( 1.0, -1.0, 1.0),
magic.Vector3( 1.0, -1.0, -1.0),
magic.Vector3(-1.0, -1.0, -1.0),
magic.Vector3(-1.0, -1.0, 1.0),
}
for _, dir in ipairs(dirs) do
local node = scene:CreateChild("DirectionalLight")
node.direction = dir
local light = node:CreateComponent("Light")
light.lightType = magic.LIGHT_DIRECTIONAL
light.castShadows = true
light.brightness = 0.2
light.color = magic.Color(0.7, 0.7, 1.0)
end
--]]
local node = scene:CreateChild("DirectionalLight")
node.direction = magic.Vector3(-0.6, -1.0, 0.8)
local light = node:CreateComponent("Light")
light.lightType = magic.LIGHT_DIRECTIONAL
light.castShadows = true
light.brightness = 0.8
light.color = magic.Color(1.0, 1.0, 0.95)
local node = scene:CreateChild("DirectionalLight")
node.direction = magic.Vector3(-0.6, -1.0, 0.8)
local light = node:CreateComponent("Light")
light.lightType = magic.LIGHT_DIRECTIONAL
light.castShadows = true
light.brightness = 0.8
light.color = magic.Color(1.0, 1.0, 0.95)
local node = scene:CreateChild("DirectionalLight")
node.direction = magic.Vector3(0.3, -1.0, -0.4)
local light = node:CreateComponent("Light")
light.lightType = magic.LIGHT_DIRECTIONAL
light.castShadows = true
light.brightness = 0.2
light.color = magic.Color(0.7, 0.7, 1.0)
---[[
local node = scene:CreateChild("DirectionalLight")
node.direction = magic.Vector3(0.3, -1.0, -0.4)
local light = node:CreateComponent("Light")
light.lightType = magic.LIGHT_DIRECTIONAL
light.castShadows = true
light.brightness = 0.2
light.color = magic.Color(0.7, 0.7, 1.0)
--]]
--[[
local node = scene:CreateChild("DirectionalLight")
node.direction = magic.Vector3(0.0, -1.0, 0.0)
local light = node:CreateComponent("Light")
light.lightType = magic.LIGHT_DIRECTIONAL
light.castShadows = false
light.brightness = 0.05
light.color = magic.Color(1.0, 1.0, 1.0)
--]]
end
-- Add a node that the player can use to walk around with
local player_node = scene:CreateChild("Player")
--player_node.position = magic.Vector3(0, 30, 0)
player_node.position = magic.Vector3(55, 30, 40)
player_node.direction = magic.Vector3(-1, 0, 0.4)
--player_node:Yaw(-177.49858)
---[[
local body = player_node:CreateComponent("RigidBody")
--body.mass = 70.0
body.friction = 0
--body.linearVelocity = magic.Vector3(0, -10, 0)
body.angularFactor = magic.Vector3(0, 0, 0)
body.gravityOverride = magic.Vector3(0, -15.0, 0) -- A bit more than normally
local shape = player_node:CreateComponent("CollisionShape")
--shape:SetBox(magic.Vector3(1, 1.7*PLAYER_SCALE, 1))
shape:SetCapsule(PLAYER_WIDTH, PLAYER_HEIGHT)
--]]
local player_shape = player_node:CreateComponent("CollisionShape")
do
--player_node.position = magic.Vector3(0, 30, 0)
--player_node.position = magic.Vector3(55, 30, 40)
player_node.position = magic.Vector3(-5, 1, 257)
player_node.direction = magic.Vector3(-1, 0, 0.4)
--player_node:Yaw(-177.49858)
---[[
local body = player_node:CreateComponent("RigidBody")
--body.mass = 70.0
body.friction = 0
--body.linearVelocity = magic.Vector3(0, -10, 0)
body.angularFactor = magic.Vector3(0, 0, 0)
body.gravityOverride = magic.Vector3(0, -15.0, 0) -- A bit more than normally
--player_shape:SetBox(magic.Vector3(1, 1.7*PLAYER_SCALE, 1))
player_shape:SetCapsule(PLAYER_WIDTH, PLAYER_HEIGHT)
--]]
end
local player_touches_ground = false
local player_crouched = false
-- Add a camera so we can look at the scene
local camera_node = player_node:CreateChild("Camera")
camera_node.position = magic.Vector3(0, 0.411*PLAYER_HEIGHT, 0)
--camera_node:Pitch(13.60000)
local camera = camera_node:CreateComponent("Camera")
camera.nearClip = 0.3
camera.farClip = RENDER_DISTANCE
camera.fov = 75
do
camera_node.position = magic.Vector3(0, 0.411*PLAYER_HEIGHT, 0)
--camera_node:Pitch(13.60000)
local camera = camera_node:CreateComponent("Camera")
camera.nearClip = 0.3
camera.farClip = RENDER_DISTANCE
camera.fov = 75
-- And this thing so the camera is shown on the screen
local viewport = magic.Viewport:new(scene, camera_node:GetComponent("Camera"))
magic.renderer:SetViewport(0, viewport)
-- And this thing so the camera is shown on the screen
local viewport = magic.Viewport:new(scene, camera_node:GetComponent("Camera"))
magic.renderer:SetViewport(0, viewport)
end
-- Tell about the camera to the voxel world so it can do stuff based on the
-- camera's position and other properties
voxelworld.set_camera(camera_node)
--[[
-- Add a light to the camera
do
local node = camera_node:CreateChild("Light")
local light = node:CreateComponent("Light")
light.lightType = magic.LIGHT_POINT
light.castShadows = false
light.brightness = 0.15
light.color = magic.Color(1.0, 1.0, 0.8)
light.range = 10.0
light.fadeDistance = 10.0
end
--]]
-- Add some text
local title_text = magic.ui.root:CreateChild("Text")
title_text:SetText("digger/init.lua")
title_text:SetFont(magic.cache:GetResource("Font", "Fonts/Anonymous Pro.ttf"), 15)
title_text.horizontalAlignment = magic.HA_CENTER
title_text.verticalAlignment = magic.VA_CENTER
title_text:SetPosition(0, -magic.ui.root.height/2 + 20)
local misc_text = magic.ui.root:CreateChild("Text")
misc_text:SetText("")
misc_text:SetFont(magic.cache:GetResource("Font", "Fonts/Anonymous Pro.ttf"), 15)
misc_text.horizontalAlignment = magic.HA_CENTER
misc_text.verticalAlignment = magic.VA_CENTER
misc_text:SetPosition(0, -magic.ui.root.height/2 + 40)
do
title_text:SetText("digger/init.lua")
title_text:SetFont(magic.cache:GetResource("Font", "Fonts/Anonymous Pro.ttf"), 15)
title_text.horizontalAlignment = magic.HA_CENTER
title_text.verticalAlignment = magic.VA_CENTER
title_text:SetPosition(0, -magic.ui.root.height/2 + 20)
misc_text:SetText("")
misc_text:SetFont(magic.cache:GetResource("Font", "Fonts/Anonymous Pro.ttf"), 15)
misc_text.horizontalAlignment = magic.HA_CENTER
misc_text.verticalAlignment = magic.VA_CENTER
misc_text:SetPosition(0, -magic.ui.root.height/2 + 40)
end
-- Unfocus UI
magic.ui:SetFocusElement(nil)
magic.SubscribeToEvent("KeyDown", function(event_type, event_data)
@ -210,13 +260,13 @@ magic.SubscribeToEvent("Update", function(event_type, event_data)
end
if not player_crouched then
shape:SetCapsule(PLAYER_WIDTH, PLAYER_HEIGHT/2)
player_shape:SetCapsule(PLAYER_WIDTH, PLAYER_HEIGHT/2)
camera_node.position = magic.Vector3(0, 0.411*PLAYER_HEIGHT/2, 0)
player_crouched = true
end
else
if player_crouched then
shape:SetCapsule(PLAYER_WIDTH, PLAYER_HEIGHT)
player_shape:SetCapsule(PLAYER_WIDTH, PLAYER_HEIGHT)
player_node:Translate(magic.Vector3(0, PLAYER_HEIGHT/4, 0))
camera_node.position = magic.Vector3(0, 0.411*PLAYER_HEIGHT, 0)
player_crouched = false

View File

@ -321,6 +321,11 @@ struct Module: public interface::Module
ivoxelworld->set_voxel(p, VoxelInstance(1));
continue;
}
if(y >= 2 && y <= 3 && z >= 256 && z <= 258 &&
x >= -112 && x <= -5){
ivoxelworld->set_voxel(p, VoxelInstance(1));
continue;
}
if(z > 37 && z < 50 && y > 20){
ivoxelworld->set_voxel(p, VoxelInstance(1));
continue;
@ -424,7 +429,7 @@ struct Module: public interface::Module
for(int y = lc.getY(); y <= uc.getY(); y++){
for(int x = lc.getX(); x <= uc.getX(); x++){
ivoxelworld->set_voxel(
voxel_p + pv::Vector3DInt32(x, y, z), v);
voxel_p + pv::Vector3DInt32(x, y, z), v);
}
}
}

View File

@ -995,6 +995,31 @@ void set_voxel_physics_boxes(Node *node, Context *context,
set_voxel_physics_boxes(node, context, result_boxes, true);
}
bool voxel_heuristic_has_sunlight(pv::RawVolume<VoxelInstance> &volume,
VoxelRegistry *voxel_reg)
{
auto region = volume.getEnclosingRegion();
auto &lc = region.getLowerCorner();
auto &uc = region.getUpperCorner();
int num = 0;
int y = uc.getY()-1;
for(int z = lc.getZ()+1; z <= uc.getZ()-1; z++){
for(int x = lc.getX()+1; x <= uc.getX()-1; x++){
VoxelInstance v = volume.getVoxelAt(x, y, z);
const interface::CachedVoxelDefinition *def = voxel_reg->get_cached(v);
if(!def)
throw Exception(ss_()+"Undefined voxel: "+itos(v.getId()));
// TODO: Some proper lighting property
bool light_passes = (!def || !def->physically_solid);
if(light_passes)
num++;
}
}
log_w(MODULE, "num=%i", num);
return (num >= 3);
}
} // namespace mesh
} // namespace interface
// vim: set noet ts=4 sw=4:

View File

@ -9,6 +9,8 @@
namespace interface {
// pv::RawVolume<VoxelInstance>
ss_ serialize_volume_simple(const pv::RawVolume<VoxelInstance> &volume)
{
std::ostringstream os(std::ios::binary);
@ -105,5 +107,103 @@ up_<pv::RawVolume<VoxelInstance>> deserialize_volume(const ss_ &data)
return up_<pv::RawVolume<VoxelInstance>>();
}
// pv::RawVolume<uint8_t>
ss_ serialize_volume_simple(const pv::RawVolume<uint8_t> &volume)
{
std::ostringstream os(std::ios::binary);
{
cereal::PortableBinaryOutputArchive ar(os);
ar((uint8_t)2); // Format
ar((int32_t)volume.getWidth());
ar((int32_t)volume.getHeight());
ar((int32_t)volume.getDepth());
auto region = volume.getEnclosingRegion();
auto lc = region.getLowerCorner();
auto uc = region.getUpperCorner();
for(size_t i = 0; i<volume.m_dataSize; i++){
const uint8_t &v = volume.m_pData[i];
ar(v);
}
}
return os.str();
}
ss_ serialize_volume_compressed(const pv::RawVolume<uint8_t> &volume)
{
std::ostringstream os(std::ios::binary);
{
cereal::PortableBinaryOutputArchive ar(os);
ar((uint8_t)3); // Format
ar((int32_t)volume.getWidth());
ar((int32_t)volume.getHeight());
ar((int32_t)volume.getDepth());
std::ostringstream raw_os(std::ios::binary);
{
cereal::PortableBinaryOutputArchive ar(raw_os);
auto region = volume.getEnclosingRegion();
auto lc = region.getLowerCorner();
auto uc = region.getUpperCorner();
for(size_t i = 0; i<volume.m_dataSize; i++){
const uint8_t &v = volume.m_pData[i];
ar(v);
}
}
std::ostringstream compressed_os(std::ios::binary);
// NOTE: 4 uses 98% and 1 uses 58% of the CPU time of 6
interface::compress_zlib(raw_os.str(), compressed_os, 6);
ar(compressed_os.str());
}
return os.str();
}
up_<pv::RawVolume<uint8_t>> deserialize_volume_uint8(const ss_ &data)
{
std::istringstream is(data, std::ios::binary);
cereal::PortableBinaryInputArchive ar(is);
int8_t format = 0;
ar(format);
if(format == 2){
int32_t w = 0;
int32_t h = 0;
int32_t d = 0;
ar(w, h, d);
pv::Region region(0, 0, 0, w-1, h-1, d-1);
up_<pv::RawVolume<uint8_t>> volume(
new pv::RawVolume<uint8_t>(region));
for(size_t i = 0; i<volume->m_dataSize; i++){
uint8_t v;
ar(v);
volume->m_pData[i] = v;
}
return volume;
}
if(format == 3){
int32_t w = 0;
int32_t h = 0;
int32_t d = 0;
ar(w, h, d);
pv::Region region(0, 0, 0, w-1, h-1, d-1);
up_<pv::RawVolume<uint8_t>> volume(
new pv::RawVolume<uint8_t>(region));
ss_ compressed_data;
ar(compressed_data);
std::istringstream compressed_is(compressed_data, std::ios::binary);
std::ostringstream raw_os(std::ios::binary);
decompress_zlib(compressed_is, raw_os);
{
std::istringstream raw_is(raw_os.str(), std::ios::binary);
cereal::PortableBinaryInputArchive ar(raw_is);
for(size_t i = 0; i<volume->m_dataSize; i++){
uint8_t v;
ar(v);
volume->m_pData[i] = v;
}
}
return volume;
}
return up_<pv::RawVolume<uint8_t>>();
}
}
// vim: set noet ts=4 sw=4:

View File

@ -127,6 +127,11 @@ namespace interface
void set_voxel_physics_boxes(Node *node, Context *context,
pv::RawVolume<VoxelInstance> &volume,
VoxelRegistry *voxel_reg);
// Heuristics
bool voxel_heuristic_has_sunlight(pv::RawVolume<VoxelInstance> &volume,
VoxelRegistry *voxel_reg);
}
}
// vim: set noet ts=4 sw=4:

View File

@ -9,7 +9,10 @@ namespace interface
{
ss_ serialize_volume_simple(const pv::RawVolume<VoxelInstance> &volume);
ss_ serialize_volume_compressed(const pv::RawVolume<VoxelInstance> &volume);
up_<pv::RawVolume<VoxelInstance>> deserialize_volume(const ss_ &data);
ss_ serialize_volume_simple(const pv::RawVolume<uint8_t> &volume);
ss_ serialize_volume_compressed(const pv::RawVolume<uint8_t> &volume);
up_<pv::RawVolume<uint8_t>> deserialize_volume_8bit(const ss_ &data);
}
// vim: set noet ts=4 sw=4:

View File

@ -442,6 +442,21 @@ void clear_voxel_physics_boxes(const luabind::object &node_o)
node->RemoveComponent(previous_shapes[i]);
}
bool voxel_heuristic_has_sunlight(const luabind::object &buffer_o,
sp_<VoxelRegistry> voxel_reg, lua_State *L)
{
TRY_GET_TOLUA_STUFF(buf, 1, const VectorBuffer);
ss_ data;
if(buf == nullptr)
data = lua_tocppstring(L, 2);
else
data.assign((const char*)&buf->GetBuffer()[0], buf->GetBuffer().Size());
up_<pv::RawVolume<VoxelInstance>> volume = interface::deserialize_volume(data);
return interface::mesh::voxel_heuristic_has_sunlight(*volume, voxel_reg.get());
}
#define LUABIND_FUNC(name) def("__buildat_" #name, name)
void init_mesh(lua_State *L)
@ -454,7 +469,8 @@ void init_mesh(lua_State *L)
LUABIND_FUNC(set_voxel_lod_geometry),
LUABIND_FUNC(clear_voxel_geometry),
LUABIND_FUNC(set_voxel_physics_boxes),
LUABIND_FUNC(clear_voxel_physics_boxes)
LUABIND_FUNC(clear_voxel_physics_boxes),
LUABIND_FUNC(voxel_heuristic_has_sunlight)
];
}