From 3868e2ea7b6d0b9a5db1d8cd4428f4419228697c Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sun, 5 Oct 2014 23:37:53 +0300 Subject: [PATCH] games/geometry, impl/voxel: DOG DAMNIT IT'S VOXELS AND PHYSICS! --- games/geometry/main/client_lua/init.lua | 14 ++- games/geometry/main/main.cpp | 117 +++++++++++++++++++----- src/impl/voxel.cpp | 17 ++-- 3 files changed, 112 insertions(+), 36 deletions(-) diff --git a/games/geometry/main/client_lua/init.lua b/games/geometry/main/client_lua/init.lua index 190ec14..72ce7a1 100644 --- a/games/geometry/main/client_lua/init.lua +++ b/games/geometry/main/client_lua/init.lua @@ -52,7 +52,7 @@ function setup_simple_voxel_data(node) local w = node:GetVar("simple_voxel_w"):GetInt() local h = node:GetVar("simple_voxel_h"):GetInt() local d = node:GetVar("simple_voxel_d"):GetInt() - log:info("simple_voxel_data: "..dump(data)) + log:info("simple_voxel_data of "..dump(node:GetName())..": "..dump(data)) buildat.set_simple_voxel_model(node, w, h, d, data) node:SetScale(magic.Vector3(1, 1, 1)) @@ -61,10 +61,20 @@ function setup_simple_voxel_data(node) end magic.sub_sync_node_added({}, function(node) - local name = node:GetName() if not node:GetVar("simple_voxel_data"):IsEmpty() then setup_simple_voxel_data(node) end + local name = node:GetName() + --[[if name == "Testbox" then + local object = node:CreateComponent("StaticModel") + object.model = magic.cache:GetResource("Model", "Models/Box.mdl") + object.material = magic.Material:new() + object.material:SetTechnique(0, + magic.cache:GetResource("Technique", "Techniques/Diff.xml")) + object.material:SetTexture(magic.TU_DIFFUSE, + magic.cache:GetResource("Texture2D", "main/pink_texture.png")) + object.castShadows = true + end]] end) -- vim: set noet ts=4 sw=4: diff --git a/games/geometry/main/main.cpp b/games/geometry/main/main.cpp index 19d2ae9..e6861cf 100644 --- a/games/geometry/main/main.cpp +++ b/games/geometry/main/main.cpp @@ -5,6 +5,7 @@ #include "interface/module.h" #include "interface/server.h" #include "interface/event.h" +#include "interface/voxel.h" #include #include #include @@ -40,6 +41,7 @@ struct Module: public interface::Module void init() { m_server->sub_event(this, Event::t("core:start")); + m_server->sub_event(this, Event::t("core:continue")); m_server->sub_event(this, Event::t("core:tick")); m_server->sub_event(this, Event::t("client_file:files_transmitted")); } @@ -47,6 +49,7 @@ struct Module: public interface::Module void event(const Event::Type &type, const Event::Private *p) { EVENT_VOIDN("core:start", on_start) + EVENT_VOIDN("core:continue", on_continue) EVENT_TYPEN("core:tick", on_tick, interface::TickEvent) EVENT_TYPEN("client_file:files_transmitted", on_files_transmitted, client_file::FilesTransmitted) @@ -67,44 +70,108 @@ struct Module: public interface::Module light->SetCastShadows(true); } { - Node *n = scene->CreateChild("Plane"); - n->SetPosition(Vector3(0.0f, -0.5f, 0.0f)); - n->SetScale(Vector3(10.0f, 1.0f, 10.0f)); - RigidBody *body = n->CreateComponent(); - CollisionShape *shape = n->CreateComponent(); - shape->SetBox(Vector3::ONE); - body->SetFriction(0.75f); - StaticModel *object = n->CreateComponent(); - object->SetModel(cache->GetResource("Models/Box.mdl")); - object->SetMaterial( - cache->GetResource("Materials/Stone.xml")); - object->SetCastShadows(true); + Node *n = scene->CreateChild("Base"); } { - Node *n = scene->CreateChild("Box"); - n->SetPosition(Vector3(0.0f, 1.5f, 0.0f)); + Node *n = scene->CreateChild("Testbox"); + n->SetPosition(Vector3(0.0f, 6.0f, 0.0f)); n->SetScale(Vector3(1.0f, 1.0f, 1.0f)); - //RigidBody *body = n->CreateComponent(); - //CollisionShape *shape = n->CreateComponent(); - //shape->SetBox(Vector3::ONE); - //body->SetMass(1.0); - //body->SetFriction(0.75f); + /*int w = 1, h = 1, d = 1; + ss_ data = "1";*/ + int w = 2, h = 2, d = 1; + ss_ data = "0111"; // Crude way of dynamically defining a voxel model - n->SetVar(StringHash("simple_voxel_data"), Variant("11101111")); - n->SetVar(StringHash("simple_voxel_w"), Variant(2)); - n->SetVar(StringHash("simple_voxel_h"), Variant(2)); - n->SetVar(StringHash("simple_voxel_d"), Variant(2)); + n->SetVar(StringHash("simple_voxel_data"), Variant(data.c_str())); + n->SetVar(StringHash("simple_voxel_w"), Variant(w)); + n->SetVar(StringHash("simple_voxel_h"), Variant(h)); + n->SetVar(StringHash("simple_voxel_d"), Variant(d)); - // TODO: Load the same model in here and give it to the physics - // subsystem so that it can be collided to + // Load the same model in here and give it to the physics + // subsystem so that it can be collided to + SharedPtr model(interface:: + create_simple_voxel_model(context, w, h, d, data.c_str())); + + RigidBody *body = n->CreateComponent(); + body->SetFriction(0.75f); + body->SetMass(1.0); + CollisionShape *shape = n->CreateComponent(); + shape->SetConvexHull(model, 0, Vector3::ONE); + //shape->SetTriangleMesh(model, 0, Vector3::ONE); + //shape->SetBox(Vector3::ONE); + } + }); + + update_scene(); + } + + void on_continue() + { + update_scene(); + } + + void update_scene() + { + m_server->access_scene([&](Scene *scene) + { + Context *context = scene->GetContext(); + ResourceCache* cache = context->GetSubsystem(); + + { + Node *n = scene->GetChild("Base"); + n->SetScale(Vector3(1.0f, 1.0f, 1.0f)); + //n->SetPosition(Vector3(0.0f, 0.5f, 0.0f)); + n->SetPosition(Vector3(0.0f, 0.5f, 0.0f)); + //n->SetRotation(Quaternion(0, 90, 0)); + + int w = 10, h = 3, d = 10; + ss_ data = + "111111111100100000100000000000" + "111111111100000000000000000000" + "111111111100000000000000000000" + "111111111100000000000000000000" + "111111111100011000000001000000" + "111111111100011000000001000000" + "111111111100000000000000000000" + "111111111100000000000000000000" + "111111111100000000000000000000" + "111111111100000000000000000000" + ; + + // Crude way of dynamically defining a voxel model + n->SetVar(StringHash("simple_voxel_data"), Variant(data.c_str())); + n->SetVar(StringHash("simple_voxel_w"), Variant(w)); + n->SetVar(StringHash("simple_voxel_h"), Variant(h)); + n->SetVar(StringHash("simple_voxel_d"), Variant(d)); + + // Load the same model in here and give it to the physics + // subsystem so that it can be collided to + SharedPtr model(interface:: + create_simple_voxel_model(context, w, h, d, data.c_str())); + + RigidBody *body = n->CreateComponent(); + body->SetFriction(0.75f); + CollisionShape *shape = n->CreateComponent(); + shape->SetTriangleMesh(model, 0, Vector3::ONE); } }); } void on_tick(const interface::TickEvent &event) { + static uint a = 0; + if(((a++) % 50) == 0){ + m_server->access_scene([&](Scene *scene){ + Node *n = scene->GetChild("Testbox"); + //n->SetPosition(Vector3(0.0f, 8.0f, 0.0f)); + n->SetRotation(Quaternion(30, 60, 90)); + //n->SetPosition(Vector3(0.0f, 6.0f, 0.0f)); + //n->SetPosition(Vector3(0.0f, 4.0f, 0.0f)); + n->SetPosition(Vector3(-0.5f, 8.0f, 0.0f)); + }); + return; + } } void on_files_transmitted(const client_file::FilesTransmitted &event) diff --git a/src/impl/voxel.cpp b/src/impl/voxel.cpp index 072ea3c..7566e51 100644 --- a/src/impl/voxel.cpp +++ b/src/impl/voxel.cpp @@ -31,18 +31,15 @@ Model* create_simple_voxel_model(Context *context, throw Exception("Negative dimension"); if(w * h * d != (int)source_data.size()) throw Exception("Mismatched data size"); - int x_off = -w/2; - int y_off = -h/2; - int z_off = -d/2; pv::SimpleVolume volData(pv::Region( - pv::Vector3DInt32(x_off, y_off, z_off), - pv::Vector3DInt32(w + x_off, h + y_off, d + z_off))); + 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+x_off, y+y_off, z+z_off, c == '0' ? 0 : 255); + volData.setVoxelAt(x, y, z, c == '0' ? 0 : 255); } pv::SurfaceMesh pv_mesh; @@ -59,9 +56,9 @@ Model* create_simple_voxel_model(Context *context, sv_ 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(); - vertex_data[i*6 + 1] = pv_vertices[i].position.getY(); - vertex_data[i*6 + 2] = pv_vertices[i].position.getZ(); + 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(); @@ -70,6 +67,8 @@ Model* create_simple_voxel_model(Context *context, sv_ 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]; }