Feature/get navigation state (#1001)

Implement lua function getNavigationState
This commit is contained in:
Emil Axelsson
2019-10-30 14:26:53 +01:00
committed by GitHub
parent da8beff8e9
commit 98079cea3c
3 changed files with 103 additions and 10 deletions
@@ -136,6 +136,7 @@ public:
WebsocketCameraStates::AxisNormalize shouldNormalize =
WebsocketCameraStates::AxisNormalize::No);
NavigationState navigationState() const;
NavigationState navigationState(const SceneGraphNode& referenceFrame) const;
void saveNavigationState(const std::string& filepath,
+31 -10
View File
@@ -337,6 +337,18 @@ void NavigationHandler::keyboardCallback(Key key, KeyModifier modifier, KeyActio
_inputState.keyboardCallback(key, modifier, action);
}
NavigationHandler::NavigationState NavigationHandler::navigationState() const {
const SceneGraphNode* referenceFrame = _orbitalNavigator.followingAnchorRotation() ?
_orbitalNavigator.anchorNode() :
sceneGraph()->root();
ghoul_assert(
referenceFrame,
"The root will always exist and the anchor node ought to be reset when removed"
);
return navigationState(*referenceFrame);
}
NavigationHandler::NavigationState NavigationHandler::navigationState(
const SceneGraphNode& referenceFrame) const
{
@@ -383,12 +395,9 @@ NavigationHandler::NavigationState NavigationHandler::navigationState(
void NavigationHandler::saveNavigationState(const std::string& filepath,
const std::string& referenceFrameIdentifier)
{
const SceneGraphNode* referenceFrame = _orbitalNavigator.followingAnchorRotation() ?
_orbitalNavigator.anchorNode() :
sceneGraph()->root();
NavigationHandler::NavigationState state;
if (!referenceFrameIdentifier.empty()) {
referenceFrame = sceneGraphNode(referenceFrameIdentifier);
const SceneGraphNode* referenceFrame = sceneGraphNode(referenceFrameIdentifier);
if (!referenceFrame) {
LERROR(fmt::format(
"Could not find node '{}' to use as reference frame",
@@ -396,17 +405,18 @@ void NavigationHandler::saveNavigationState(const std::string& filepath,
));
return;
}
state = navigationState(*referenceFrame).dictionary();
} else {
state = navigationState().dictionary();
}
if (!filepath.empty()) {
std::string absolutePath = absPath(filepath);
LINFO(fmt::format("Saving camera position: {}", absolutePath));
ghoul::Dictionary cameraDict = navigationState(*referenceFrame).dictionary();
ghoul::DictionaryLuaFormatter formatter;
std::ofstream ofs(absolutePath.c_str());
ofs << "return " << formatter.format(cameraDict);
ofs << "return " << formatter.format(state.dictionary());
ofs.close();
}
}
@@ -558,13 +568,24 @@ scripting::LuaLibrary NavigationHandler::luaLibrary() {
return {
"navigation",
{
{
"getNavigationState",
&luascriptfunctions::getNavigationState,
{},
"[string]",
"Return the current navigation state as a lua table. The optional "
"argument is the scene graph node to use as reference frame. By default, "
"the reference frame will picked based on whether the orbital navigator "
"is currently following the anchor node rotation. If it is, the anchor "
"will be chosen as reference frame. If not, the reference frame will be "
"set to the scene graph root."
},
{
"setNavigationState",
&luascriptfunctions::setNavigationState,
{},
"table",
"Set the navigation state. "
"The argument must be a valid Navigation State."
"Set the navigation state. The argument must be a valid Navigation State."
},
{
"saveNavigationState",
+71
View File
@@ -46,6 +46,77 @@ int loadNavigationState(lua_State* L) {
return 0;
}
int getNavigationState(lua_State* L) {
const int n = ghoul::lua::checkArgumentsAndThrow(
L,
{ 0, 1 },
"lua::getNavigationState"
);
interaction::NavigationHandler::NavigationState state;
if (n == 1) {
const std::string referenceFrameIdentifier = ghoul::lua::value<std::string>(L, 1);
const SceneGraphNode* referenceFrame = sceneGraphNode(referenceFrameIdentifier);
if (!referenceFrame) {
LERROR(fmt::format(
"Could not find node '{}' to use as reference frame",
referenceFrameIdentifier
));
lua_settop(L, 0);
return 0;
}
state = global::navigationHandler.navigationState(*referenceFrame);
}
else {
state = global::navigationHandler.navigationState();
}
lua_settop(L, 0);
const auto pushVector = [](lua_State* L, const glm::dvec3& v) {
lua_newtable(L);
ghoul::lua::push(L, 1, v.x);
lua_rawset(L, -3);
ghoul::lua::push(L, 2, v.y);
lua_rawset(L, -3);
ghoul::lua::push(L, 3, v.z);
lua_rawset(L, -3);
};
lua_newtable(L);
ghoul::lua::push(L, "Anchor", state.anchor);
lua_rawset(L, -3);
if (!state.aim.empty()) {
ghoul::lua::push(L, "Aim", state.aim);
lua_rawset(L, -3);
}
if (!state.referenceFrame.empty()) {
ghoul::lua::push(L, "ReferenceFrame", state.referenceFrame);
lua_rawset(L, -3);
}
ghoul::lua::push(L, "Position");
pushVector(L, state.position);
lua_rawset(L, -3);
if (state.up.has_value()) {
ghoul::lua::push(L, "Up");
pushVector(L, state.up.value());
lua_rawset(L, -3);
}
if (state.yaw != 0) {
ghoul::lua::push(L, "Yaw", state.yaw);
lua_rawset(L, -3);
}
if (state.pitch != 0) {
ghoul::lua::push(L, "Pitch", state.pitch);
lua_rawset(L, -3);
}
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
}
int setNavigationState(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::setNavigationState");