From 749bb67c6cedd66398b6dc2c198e7a160c19d004 Mon Sep 17 00:00:00 2001 From: Hartmut Seichter Date: Tue, 2 Feb 2021 23:23:40 +0100 Subject: [PATCH] major overhaul for Lua API and additions for using texture coordinates Signed-off-by: Hartmut Seichter --- src/binding/src/script_core.cpp | 149 ++++++++++++++---------- src/core/include/pw/core/axisangle.hpp | 10 +- src/core/include/pw/core/geometry.hpp | 7 +- src/core/include/pw/core/matrixbase.hpp | 13 +-- src/core/include/pw/core/point.hpp | 2 + src/core/include/pw/core/size.hpp | 2 + src/core/src/geometry.cpp | 6 +- src/scripts/demos/simple_003.lua | 58 ++++----- src/scripts/tests/test_core.lua | 121 ++++++++++++++----- src/visual/src/renderer.cpp | 16 +++ 10 files changed, 242 insertions(+), 142 deletions(-) diff --git a/src/binding/src/script_core.cpp b/src/binding/src/script_core.cpp index 610f42b..4d2c360 100644 --- a/src/binding/src/script_core.cpp +++ b/src/binding/src/script_core.cpp @@ -31,7 +31,7 @@ vector3 table_to_vector3(sol::table t) } template -std::vector convert_sequence(sol::table t) +std::vector convert_sequence(sol::state& lua,sol::table t) { const std::size_t sz = t.size(); std::vector res(sz); @@ -46,46 +46,54 @@ std::vector convert_sequence(sol::table t) void register_core_function(sol::state& lua,sol::table& ns) { - typedef real_t Scalar; - - ns.set("pi",pw::pi()); + ns.set("pi",pw::pi()); - ns.new_usertype("matrix4x4" - , sol::call_constructor,sol::constructors() - , "row",&matrix4x4::row - , "column",&matrix4x4::column - , "set_identity",&matrix4x4::set_identity - , "inverse",&matrix4x4::inverse - , "identity",sol::readonly_property(matrix4x4::identity) - // , "set",[](sol::this_state s,sol::table t) { for (int i = 0;i < t.size();i++) s.Ldata[i] = t[i-1]; }) - // , "get",[]() ->sol::table { return sol::table(); } - - ); - - ns.new_usertype("vector2" - ,sol::call_constructor,sol::constructors() - ,"x", sol::property(sol::resolve(&vector2::x), [](vector2& v,vector2::value_type val){ v.x() = val;}) - ,"y", sol::property(sol::resolve(&vector2::y), [](vector2& v,vector2::value_type val){ v.y() = val;}) + ns.new_usertype("matrix4x4", + sol::call_constructor,sol::constructors(), + "row",&matrix4x4::row, + "column",&matrix4x4::column, + "inverse",sol::readonly_property(&matrix4x4::inverse), + "identity",sol::readonly_property(matrix4x4::identity), + sol::meta_function::multiplication,[](const matrix4x4& a,const vector4& b) { return vector4(a * b); } ); + ns.new_usertype("vector2", + sol::call_constructor,sol::constructors(), + "x", sol::property(sol::resolve(&vector2::x), [](vector2& v,vector2::value_type val){ v.x() = val;}), + "y", sol::property(sol::resolve(&vector2::y), [](vector2& v,vector2::value_type val){ v.y() = val;}), + "dot",&vector2::dot, + sol::meta_function::addition,[](const vector2& a,const vector2& b){ return vector2(a + b); }, + sol::meta_function::subtraction,[](const vector2& a,const vector2& b){ return vector2(a - b); }, + "data",sol::property([](vector2& s) { return std::ref(s.data);} ), + "table",sol::property([](const vector2& s){ return sol::as_table(std::array{s.x(),s.y()}); }, + [](vector2& s,const sol::table& t) { s.data[0] = t[1]; s.data[1] = t[2];} ) + ); + ns.new_usertype("vector3" - ,sol::constructors() + ,sol::call_constructor,sol::constructors() ,"x", sol::property(sol::resolve(&vector3::x), [](vector3& v,vector3::value_type val){ v.x() = val;}) ,"y", sol::property(sol::resolve(&vector3::y), [](vector3& v,vector3::value_type val){ v.y() = val;}) ,"z", sol::property(sol::resolve(&vector3::z), [](vector3& v,vector3::value_type val){ v.z() = val;}) ,"cross",&vector3::cross - ,"transposed",&vector3::transposed + ,"normalize",&vector3::normalize + ,"norm",sol::readonly_property(&vector3::norm) + ,"squared_norm",sol::readonly_property(&vector3::squared_norm) + ,"dot",&vector3::dot + ,"transposed",sol::readonly_property(&vector3::transposed) + ,"normalized",sol::readonly_property(&vector3::normalized) ,"lerp",&vector3::lerp - ,"forward",&vector3::forward - ,"backward",&vector3::backward - ,"left",&vector3::left - ,"right",&vector3::right - ,"up",&vector3::up - ,"down",&vector3::down - ,sol::meta_function::addition,&vector3::operator+ - ,sol::meta_function::subtraction,&vector3::operator- - ,sol::meta_function::multiplication,&vector3::operator* + ,"forward",sol::readonly_property(&vector3::forward) + ,"backward",sol::readonly_property(&vector3::backward) + ,"left",sol::readonly_property(&vector3::left) + ,"right",sol::readonly_property(&vector3::right) + ,"up",sol::readonly_property(&vector3::up) + ,"down",sol::readonly_property(&vector3::down) + ,sol::meta_function::addition,[](const vector3& a,const vector3& b){ return vector3(a + b); } + ,sol::meta_function::subtraction,[](const vector3& a,const vector3& b){ return vector3(a - b); } + ,"data",sol::property([](vector3& s) { return std::ref(s.data);} ) + ,"table",sol::property([](const vector3& s){ return sol::as_table(std::array{s.x(),s.y(),s.z()}); }, + [](vector3& s,const sol::table& t) { s.data[0] = t[1]; s.data[1] = t[2]; s.data[2] = t[3];} ) ); ns.new_usertype("vector4" @@ -94,50 +102,51 @@ void register_core_function(sol::state& lua,sol::table& ns) ,"y", sol::property(sol::resolve(&vector4::y), [](vector4& v,vector4::value_type val){ v.y() = val;}) ,"z", sol::property(sol::resolve(&vector4::z), [](vector4& v,vector4::value_type val){ v.z() = val;}) ,"w", sol::property(sol::resolve(&vector4::w), [](vector4& v,vector4::value_type val){ v.w() = val;}) - ,"project",&vector4::project + ,"project",sol::readonly_property(&vector4::project) + ,sol::meta_function::multiplication,[](const matrix4x4& a,const vector4& b) { return vector4(a * b); } ); - ns.new_usertype("quaternion" - ,sol::constructors() - ,"x", sol::property(sol::resolve(&quaternion::x), [](quaternion& v,quaternion::value_type val){ v.x() = val;}) - ,"y", sol::property(sol::resolve(&quaternion::y), [](quaternion& v,quaternion::value_type val){ v.y() = val;}) - ,"z", sol::property(sol::resolve(&quaternion::z), [](quaternion& v,quaternion::value_type val){ v.z() = val;}) - ,"w", sol::property(sol::resolve(&quaternion::w), [](quaternion& v,quaternion::value_type val){ v.w() = val;}) - ,"identity",sol::readonly_property(&quaternion::identity) - ,"dot",&quaternion::dot - ,"inverse",sol::readonly_property(&quaternion::inverse) - ,"normalized",&quaternion::normalized - ,"lerp",&quaternion::lerp - ,"slerp",&quaternion::slerp - ,"matrix",&quaternion::to_matrix - ); + ns.new_usertype("quaternion", + sol::call_constructor,sol::constructors(), + "x", sol::property(sol::resolve(&quaternion::x), [](quaternion& v,quaternion::value_type val){ v.x() = val;}), + "y", sol::property(sol::resolve(&quaternion::y), [](quaternion& v,quaternion::value_type val){ v.y() = val;}), + "z", sol::property(sol::resolve(&quaternion::z), [](quaternion& v,quaternion::value_type val){ v.z() = val;}), + "w", sol::property(sol::resolve(&quaternion::w), [](quaternion& v,quaternion::value_type val){ v.w() = val;}), + "identity",sol::readonly_property(&quaternion::identity), + "dot",&quaternion::dot, + "inverse",sol::readonly_property(&quaternion::inverse), + "normalized",sol::readonly_property([](const quaternion& q){ return quaternion{ q.normalized() };}), + "lerp",[](const quaternion& a,const quaternion& b,quaternion::value_type t) { return quaternion{ quaternion::lerp(a,b,t) }; }, + "slerp",[](const quaternion& a,const quaternion& b,quaternion::value_type t) { return quaternion{ quaternion::slerp(a,b,t) }; }, + "to_matrix",sol::readonly_property(&quaternion::to_matrix) + ); ns.new_usertype("axisangle", - sol::constructors(), - "axis",&axisangle::axis, - "angle",&axisangle::angle, + sol::call_constructor,sol::constructors(), + "axis",sol::property(&axisangle::axis,&axisangle::axis), + "angle",sol::property(&axisangle::angle,&axisangle::angle), "from_matrix",&axisangle::from_matrix, "to_matrix",&axisangle::to_matrix ); ns.new_usertype("size" - , sol::call_constructor, sol::constructors() + , sol::call_constructor, sol::constructors() , "width",&size::width , "height",&size::height , "cast_to_float",&size::cast ); ns.new_usertype("sizef" - , sol::call_constructor, sol::constructors() + , sol::call_constructor, sol::constructors() , "width",&sizef::width , "height",&sizef::height , "cast_to_int",&sizef::cast ); ns.new_usertype("point", - sol::constructors(), + sol::call_constructor,sol::constructors(), "x",&point::x, "y",&point::y ); @@ -157,15 +166,33 @@ void register_core_function(sol::state& lua,sol::table& ns) "reset",&time::reset ); - ns.new_usertype("geometry" - ,sol::constructors() - ,"primitive_topology", sol::property(&geometry::primitive_topology,&geometry::set_primitive_topology) -// ,"vertices", sol::property(&geometry::ref_vertices,&geometry::ref_vertices) - ,"vertices", sol::property(&geometry::vertices,&geometry::set_vertices) - ,"indices", sol::property(&geometry::ref_indices,&geometry::ref_indices) -// ,"texture_coordinates", sol::property(&geometry::ref_texture_coordinates,&geometry::ref_texture_coordinates) - ,"compute_normals", &geometry::compute_normals - ); + ns.new_usertype("geometry", + sol::call_constructor,sol::constructors(), + "primitive_topology", sol::property(&geometry::primitive_topology,&geometry::set_primitive_topology), + "compute_normals", &geometry::compute_normals, + "indices",sol::property( [](const geometry& g){ return sol::as_table(g.indices());}, + [](geometry& g,sol::table t){ + std::vector vals; + for (std::size_t i = 0; i < t.size();i++) vals.push_back(t[i+1]); + g.set_indices(vals); }), + "vertices",sol::property( [](const geometry& g){ return sol::as_table(g.vertices());}, + [](geometry &g,sol::nested val) { + g.set_vertices(val.value()); + } + ), + "normals",sol::property( [](const geometry& g){ return sol::as_table(g.vertices());}, + [](geometry& g,sol::table t){ + vector3_array vals; + for (std::size_t i = 0; i < t.size();i++) vals.push_back(t[i+1]); + g.set_normals(vals); } + ), + "texture_coordinates",sol::property( + [](const geometry& g){ return sol::as_table(g.texture_coordinates());}, + [](geometry &g,sol::nested> val) + { + g.set_texture_coordinates(val.value()); + }) + ); ns.new_enum("primitive_topology_type" diff --git a/src/core/include/pw/core/axisangle.hpp b/src/core/include/pw/core/axisangle.hpp index 06378fc..0ad6575 100644 --- a/src/core/include/pw/core/axisangle.hpp +++ b/src/core/include/pw/core/axisangle.hpp @@ -30,8 +30,8 @@ namespace pw { template struct axisangle_ { - typedef T value_type; - typedef vector3_ axis_type; + using value_type = T; + using axis_type = vector3_; axis_type axis; T angle; @@ -41,9 +41,9 @@ struct axisangle_ { angle(0) {} - axisangle_(const vector3_ &axis,const T &angle) - : axis(axis) - , angle(angle) + axisangle_(vector3_ axis,T angle) + : axis(std::move(axis)) + , angle(std::move(angle)) { } diff --git a/src/core/include/pw/core/geometry.hpp b/src/core/include/pw/core/geometry.hpp index 2b7a120..35e7af3 100644 --- a/src/core/include/pw/core/geometry.hpp +++ b/src/core/include/pw/core/geometry.hpp @@ -68,17 +68,12 @@ public: void set_indices(indices_t v); const indices_t& indices() const; - indices_t& ref_indices() { return _indices; } - void set_normals(vector3_array v); const vector3_array& normals() const; - void add_texture_coordinates(vector2_array v); + void set_texture_coordinates(std::vector v); const std::vector& texture_coordinates() const { return _texture_coords;} - std::vector& ref_texture_coordinates() { return _texture_coords; } - - void transform(const matrix4x4& m); void compute_normals(); diff --git a/src/core/include/pw/core/matrixbase.hpp b/src/core/include/pw/core/matrixbase.hpp index e666be4..1cd1e5b 100644 --- a/src/core/include/pw/core/matrixbase.hpp +++ b/src/core/include/pw/core/matrixbase.hpp @@ -91,16 +91,13 @@ struct matrixbase_ { return derived().data[i]; } - static T dot(const Derived &a,const Derived &b) { -#if 0 - Derived r; for (size_t i = 0;i < a.size();i++) r[i] = a[i] * b[i]; - return std::accumulate(std::begin(r), std::end(r), T(0)); -#else - return std::inner_product(std::begin(a),std::end(a),std::begin(b),T(0)); -#endif + static constexpr T dot(const Derived &a,const Derived &b) + { + return std::inner_product(std::begin(a),std::end(a),std::begin(b),T(0)); } - static const Derived lerp(const Derived &a,const Derived &b,const T& t) { + static constexpr Derived lerp(const Derived &a,const Derived &b,const T& t) + { return a + (b - a) * t; } diff --git a/src/core/include/pw/core/point.hpp b/src/core/include/pw/core/point.hpp index 724c8a0..a07a1a3 100644 --- a/src/core/include/pw/core/point.hpp +++ b/src/core/include/pw/core/point.hpp @@ -30,6 +30,8 @@ namespace pw { template struct point_ { + using value_type = T_; + T_ x, y; point_() = default; diff --git a/src/core/include/pw/core/size.hpp b/src/core/include/pw/core/size.hpp index c84d305..7e0d651 100644 --- a/src/core/include/pw/core/size.hpp +++ b/src/core/include/pw/core/size.hpp @@ -30,6 +30,8 @@ namespace pw { template struct size_ { + using value_type = T_; + T_ width,height; size_() = default; diff --git a/src/core/src/geometry.cpp b/src/core/src/geometry.cpp index e3ccc47..35ab967 100644 --- a/src/core/src/geometry.cpp +++ b/src/core/src/geometry.cpp @@ -111,10 +111,10 @@ void geometry::set_normals(vector3_array v) const vector3_array &geometry::normals() const { return _normals; } - -void geometry::add_texture_coordinates(vector2_array v) +void geometry::set_texture_coordinates(std::vector v) { - _texture_coords.push_back(v); + _change_count++; + _texture_coords = v; } diff --git a/src/scripts/demos/simple_003.lua b/src/scripts/demos/simple_003.lua index 3b1baca..0da4b33 100644 --- a/src/scripts/demos/simple_003.lua +++ b/src/scripts/demos/simple_003.lua @@ -33,53 +33,45 @@ w.title = "pixwerx - bare rendering" w.size = pw.size(640,480) -- move window -w.position = pw.point.new(100,100) +w.position = pw.point(100,100) -- create a new geometry -local g = pw.geometry:new() - - --- create texture coordinates -local tc = { pw.vector2(1.0,1.0), - pw.vector2(1.0,0.0), - pw.vector2(0.0,1.0), - pw.vector2(0.0,0.0) } - ---g:add_texture_coordinates(tc) - ---print(g) +local g = pw.geometry() g.primitive_topology = pw.primitive_topology_type.triangle_list -- meh +-- create texture coordinates +g.texture_coordinates = { { + { 1.0, 1.0 }, + { 1.0, 0.0 }, + { 0.0, 1.0 }, + { 0.0, 0.0 } +} } + z = -5.0 s = 1 +-- indices +g.indices = { + 0, 1, 2, + 2, 3, 0 + } + +print(g.indices,#g.indices) + + -- geometry can only build with indexed facesets -g.vertices:add(pw.vector3.new(-s, s, z)) -- 0 -g.vertices:add(pw.vector3.new(-s,-s, z)) -- 1 -g.vertices:add(pw.vector3.new( s,-s, z)) -- 2 -g.vertices:add(pw.vector3.new( s, s, z)) -- 3 +g.vertices = { + { -s,-s, z }, + { s,-s, z }, + { s, s, z } +} ---g.vertices = { --- { -s , s , z }, ---} - - -print(#g.vertices,g.vertices) - -os.exit() -- 0 --- 3 -- | \ | -- 1 --- 2 -g.indices:add(0) -g.indices:add(1) -g.indices:add(2) - -g.indices:add(2) -g.indices:add(3) -g.indices:add(0) @@ -148,7 +140,7 @@ end w.on_update = function(self) -- set view matrix with look_at - view matrix is moving the world - hence inverse! - mv = pw.matrixtransform.look_at(cam_pos,cam_pos + pw.vector3.forward(),pw.vector3.up()):inverse() + mv = pw.matrixtransform.look_at(cam_pos,cam_pos + pw.vector3.forward,pw.vector3.up).inverse -- compute aspect ratio from canvas size aspect_ratio = self.client_size.width / self.client_size.height diff --git a/src/scripts/tests/test_core.lua b/src/scripts/tests/test_core.lua index a1cb76c..4ed421a 100644 --- a/src/scripts/tests/test_core.lua +++ b/src/scripts/tests/test_core.lua @@ -6,45 +6,114 @@ pw.script:load_all() -- vector3 -local v1 = pw.vector3.new(3,2,1) +local v1 = pw.vector3(3,2,1) print("v1 ",v1.x,v1.y,v1.z) --- quaternion -local q = pw.quaternion.new() -q = pw.quaternion.identity -print("q",q.x,q.y,q.z,q.w) -qi = q.inverse -print("q.inverse",qi.x,qi.y,qi.z,qi.w) -local q2 = pw.quaternion.new(0,0,0,1) +local v2 = pw.vector3(1,2,3) +print("v2 ",v2.x,v2.y,v2.z) + +local v_up = pw.vector3.up +print("v_up",v_up.x,v_up.y,v_up.z) + +local v3 = v1 + v2 +print(v1 + v2) +print("v3 ",v3.x,v3.y,v3.z) +print("v3.norm",v3.norm) +print("v3.squared_norm",v3.squared_norm) + +print(v1,v1.arr,v1.data[2]) + +local v4 = v3 + +print("v4",v4) + +print(v4.table) + +v4.table = { 11, 22, 33 } + +print("v4 ", v4.x, v4.y, v4.z) + + +local m4 = pw.matrix4x4.identity + +v44 = m4 * v4 + +print("v44 ", v44.x, v44.y, v44.z) + + +-- quaternion +local q = pw.quaternion.identity + +print("q",q.x,q.y,q.z,q.w) + +qi = q.inverse + +print("q.inverse",qi.x,qi.y,qi.z,qi.w) + +local q2 = pw.quaternion(1,1,1,2) + +local qn = q2.normalized +print("q2.normalized",qn.x,qn.y,qn.z,qn.w) + +local ql = pw.quaternion.lerp(q,q2,0.5).normalized +print("q-qi lerp",ql.x,ql.y,ql.z,ql.w) + +local qsl = pw.quaternion.slerp(q,q2,0.5).normalized +print("q-qi slerp",qsl.x,qsl.y,qsl.z,qsl.w) --- bug! --- qm = pw.quaternion.lerp(q,qi,0.5) -- axisangle -local aa = pw.axisangle.new(v1,0.707) +local aa = pw.axisangle(pw.vector3.up,0.707) print("aa.axis",aa.axis.x,aa.axis.y,aa.axis.z) print("aa.angle",aa.angle) --- mesh -local somemesh = pw.mesh.new() - -somemesh.indices:add(0) -somemesh.vertices:add(pw.vector3.new(3,4,5)) - --- -print(somemesh.vertices) -print(somemesh.indices) +local g = pw.geometry() +g.indices = { 11, 22, 33 } -for i=1,#somemesh.indices do - print(i," - ", somemesh.indices:get(i)) +-- alert! the returned table is a copy! +table.insert(g.indices,44) + +print("#g.indices ",#g.indices) + +-- to insert one needs to set the whole table +local temp = g.indices +temp[#temp + 1] = 44 +g.indices = temp + + +for k,v in ipairs(g.indices) do + print("index: ",k,v) end -for k,v in ipairs(somemesh.indices) do - print(k,v) +g.vertices = { + { 11, 11, 11 }, + { 22, 22, 22 }, + { 33, 33, 33 } +} + +-- now look at the vertices +for k,v in ipairs(g.vertices) do + print("vertex: ",k,v.x,v.y,v.z) end -for k,v in ipairs(somemesh.vertices) do - print(k,v) + +-- now look at the texture coordinates + +g.texture_coordinates = { +{ + { 0, 0 }, + { 1, 0 }, + { 1, 1 }, + { 0, 1 } +} +} + +for k,v in ipairs(g.texture_coordinates) do + for ki,vi in ipairs(v) do + print("texture_coord",k,ki,vi.x,vi.y) + end end + + diff --git a/src/visual/src/renderer.cpp b/src/visual/src/renderer.cpp index 19aed5e..d687cf3 100644 --- a/src/visual/src/renderer.cpp +++ b/src/visual/src/renderer.cpp @@ -67,6 +67,22 @@ struct renderer::impl { GL_STATIC_DRAW); glEnableVertexAttribArray(0); + if (!m.normals().empty()) + { + + // normals + glBindBuffer(GL_ARRAY_BUFFER,_vbo); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); + glBufferData(GL_ARRAY_BUFFER, + m.normals().size() * sizeof(vector3), + m.normals().data(), + GL_STATIC_DRAW); + glEnableVertexAttribArray(1); + + // + + } + // stop binding glBindVertexArray(0);