From 2ab09b50e59e9cf99551415e77b4604c013b0d7c Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 3 Jun 2024 09:57:15 +0200 Subject: [PATCH] Add example for the LuaRotation class and fix it at the same time (#3285) * Add example for LuaRotation class and make it work again --- .../examples/rotation/luarotation/example.lua | 16 +++++++++ .../examples/rotation/luarotation/lua.asset | 34 ++++++++++++++++++ modules/base/rotation/luarotation.cpp | 36 +++++++++---------- modules/base/rotation/luarotation.h | 3 +- 4 files changed, 68 insertions(+), 21 deletions(-) create mode 100644 data/assets/examples/rotation/luarotation/example.lua create mode 100644 data/assets/examples/rotation/luarotation/lua.asset diff --git a/data/assets/examples/rotation/luarotation/example.lua b/data/assets/examples/rotation/luarotation/example.lua new file mode 100644 index 0000000000..d795b9514a --- /dev/null +++ b/data/assets/examples/rotation/luarotation/example.lua @@ -0,0 +1,16 @@ +-- The `rotation` function takes exactly three arguments and returns the 9 values that +-- make up the final rotation matrix as a table. +-- The three parameters are all provided as the number of seconds past the J2000 epoch +-- (2000-01-01 12:00:00), which can be both fractional numbers as well as negative numbers +-- for dates earlier than the epoch. +-- 1. `simulationTime` is the value of the in-game clock for the current frame +-- 2. `prevSimulationTime` is the value of the in-game clock for the previous frame +-- 3. `wallTime` is the value of the computer clock as seconds past the epoch +function rotation(simulationTime, prevSimulationTime, wallTime) + -- Create a rotation around the x axis + return { + 1, 0, 0, + 0, math.cos(simulationTime), -math.sin(simulationTime), + 0, math.sin(simulationTime), math.cos(simulationTime) + } +end diff --git a/data/assets/examples/rotation/luarotation/lua.asset b/data/assets/examples/rotation/luarotation/lua.asset new file mode 100644 index 0000000000..88a3b7ee22 --- /dev/null +++ b/data/assets/examples/rotation/luarotation/lua.asset @@ -0,0 +1,34 @@ +-- Basic +-- This asset creates a SceneGraphNode that only displays coordinate axes. The rotation of +-- coordinate axes are determined by executing a Lua file that returns the rotation matrix +-- to be used. +-- +-- ```{literalinclude} example.lua +-- :language: lua +-- :caption: The script file that is used in this example +-- ``` + +local Node = { + Identifier = "LuaRotation_Example", + Transform = { + Rotation = { + Type = "LuaRotation", + Script = asset.resource("example.lua") + } + }, + Renderable = { + Type = "RenderableCartesianAxes" + }, + GUI = { + Name = "Basic", + Path = "/Examples/LuaRotation" + } +} + +asset.onInitialize(function() + openspace.addSceneGraphNode(Node) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(Node) +end) diff --git a/modules/base/rotation/luarotation.cpp b/modules/base/rotation/luarotation.cpp index 7608fb7664..f432c3cb24 100644 --- a/modules/base/rotation/luarotation.cpp +++ b/modules/base/rotation/luarotation.cpp @@ -41,15 +41,17 @@ namespace { "This value is the path to the Lua script that will be executed to compute the " "rotation for this transformation. The script needs to define a function " "'rotation' that takes the current simulation time in seconds past the J2000 " - "epoch as the first argument, the current wall time as milliseconds past the " - "J2000 epoch as the second argument and computes the rotation returned as 9 " - "values.", + "epoch as the first argument, the simulation time in seconds past the J2000 " + "epoch of the last frame as the second argument, and the current wall time as " + "milliseconds past the J2000 epoch as the third argument. It computes the rotation " + "value factors returned as a table containing the 9 values that make up the " + "resulting rotation matrix.", openspace::properties::Property::Visibility::AdvancedUser }; struct [[codegen::Dictionary(LuaRotation)]] Parameters { // [[codegen::verbatim(ScriptInfo.description)]] - std::string script; + std::filesystem::path script; }; #include "luarotation_codegen.cpp" } // namespace @@ -60,23 +62,24 @@ documentation::Documentation LuaRotation::Documentation() { return codegen::doc("base_transform_rotation_lua"); } -LuaRotation::LuaRotation() +LuaRotation::LuaRotation(const ghoul::Dictionary& dictionary) : _luaScriptFile(ScriptInfo) - , _state(ghoul::lua::LuaState::IncludeStandardLibrary::No) + , _state( + ghoul::lua::LuaState::IncludeStandardLibrary::Yes, + ghoul::lua::LuaState::StrictState::No + ) { - addProperty(_luaScriptFile); + const Parameters p = codegen::bake(dictionary); _luaScriptFile.onChange([this]() { requireUpdate(); _fileHandle = std::make_unique(_luaScriptFile.value()); _fileHandle->setCallback([this]() { requireUpdate(); }); }); -} -LuaRotation::LuaRotation(const ghoul::Dictionary& dictionary) : LuaRotation() { - const Parameters p = codegen::bake(dictionary); + addProperty(_luaScriptFile); - _luaScriptFile = absPath(p.script).string(); + _luaScriptFile = p.script.string(); } glm::dmat3 LuaRotation::matrix(const UpdateData& data) const { @@ -107,20 +110,15 @@ glm::dmat3 LuaRotation::matrix(const UpdateData& data) const { ghoul::lua::push(_state, duration_cast(now.time_since_epoch()).count()); // Execute the scaling function - const int success = lua_pcall(_state, 2, 9, 0); + const int success = lua_pcall(_state, 3, 1, 0); if (success != 0) { LERRORC( "LuaRotation", std::format("Error executing 'rotation': {}", lua_tostring(_state, -1)) ); } - - std::array values; - for (int i = 0; i < 9; i++) { - values[i] = luaL_checknumber(_state, -1 - i); - } - - return glm::make_mat3(values.data()); + const glm::dmat3 rotation = ghoul::lua::value(_state); + return rotation; } } // namespace openspace diff --git a/modules/base/rotation/luarotation.h b/modules/base/rotation/luarotation.h index da0e5ab17a..b9c127edf1 100644 --- a/modules/base/rotation/luarotation.h +++ b/modules/base/rotation/luarotation.h @@ -39,8 +39,7 @@ namespace documentation { struct Documentation; } class LuaRotation : public Rotation { public: - LuaRotation(); - LuaRotation(const ghoul::Dictionary& dictionary); + explicit LuaRotation(const ghoul::Dictionary& dictionary); glm::dmat3 matrix(const UpdateData& data) const override;