Minor cleanups

This commit is contained in:
Emma Broman
2020-10-27 08:52:12 +01:00
parent 353b950fc6
commit 74c1979400
9 changed files with 286 additions and 270 deletions

View File

@@ -45,59 +45,63 @@
namespace {
constexpr const char* _loggerCat = "AutoNavigationHandler";
constexpr const openspace::properties::Property::PropertyInfo DefaultCurveOptionInfo = {
constexpr openspace::properties::Property::PropertyInfo DefaultCurveOptionInfo = {
"DefaultCurveOption",
"Default Curve Option",
"The defualt curve type chosen when generating a path, if none is specified."
};
constexpr const openspace::properties::Property::PropertyInfo IncludeRollInfo = {
constexpr openspace::properties::Property::PropertyInfo IncludeRollInfo = {
"IncludeRollInfo",
"Include Roll",
"If disabled, roll is removed from the interpolation of camera orientation."
};
constexpr const openspace::properties::Property::PropertyInfo StopAtTargetsPerDefaultInfo = {
constexpr openspace::properties::Property::PropertyInfo StopAtTargetsPerDefaultInfo = {
"StopAtTargetsPerDefault",
"Stop At Targets Per Default",
"Applied during path creation. If enabled, stops are automatically added between"
" the path segments. The user must then choose to continue the path after reaching a target"
"Applied during path creation. If enabled, stops are automatically added "
"between the path segments. The user must then choose to continue the path "
"after reaching a target"
};
constexpr const openspace::properties::Property::PropertyInfo DefaultStopBehaviorInfo = {
constexpr openspace::properties::Property::PropertyInfo DefaultStopBehaviorInfo = {
"DefaultStopBehavior",
"Default Stop Behavior",
"The default camera behavior that is applied when the camera reaches and stops at a target."
"The default camera behavior that is applied when the camera reaches and stops "
"at a target."
};
constexpr const openspace::properties::Property::PropertyInfo ApplyStopBehaviorWhenIdleInfo = {
constexpr openspace::properties::Property::PropertyInfo ApplyStopBehaviorWhenIdleInfo = {
"ApplyStopBehaviorWhenIdle",
"Apply Stop Behavior When Idle",
"If enabled, the camera is controlled using the default stop behavior even when no path is playing."
"If enabled, the camera is controlled using the default stop behavior even when"
"no path is playing."
};
constexpr const openspace::properties::Property::PropertyInfo RelevantNodeTagsInfo = {
constexpr openspace::properties::Property::PropertyInfo RelevantNodeTagsInfo = {
"RelevantNodeTags",
"Relevant Node Tags",
"List of tags for the nodes that are relevant for path creation, for example when avoiding collisions."
"List of tags for the nodes that are relevant for path creation, for example "
"when avoiding collisions."
};
constexpr const openspace::properties::Property::PropertyInfo DefaultPositionOffsetAngleInfo = {
constexpr openspace::properties::Property::PropertyInfo DefaultPositionOffsetAngleInfo = {
"DefaultPositionOffsetAngle",
"Default Position Offset Angle",
"Used for creating a default position at a target node. The angle (in degrees) "
"specifies the deviation from the line connecting the target node and the sun, in "
"the direction of the camera position at the start of the path."
"specifies the deviation from the line connecting the target node and the sun, "
"in the direction of the camera position at the start of the path."
};
constexpr const openspace::properties::Property::PropertyInfo NumberSimulationStepsInfo = {
constexpr openspace::properties::Property::PropertyInfo NumberSimulationStepsInfo = {
"NumberSimulationSteps",
"Number Simulation Steps",
"The number of steps used to simulate the camera motion, per frame. A larger number "
"increases the precision, at the cost of reduced efficiency."
"The number of steps used to simulate the camera motion, per frame. A larger "
"number increases the precision, at the cost of reduced efficiency."
};
constexpr const openspace::properties::Property::PropertyInfo SpeedScaleInfo = {
constexpr openspace::properties::Property::PropertyInfo SpeedScaleInfo = {
"SpeedScale",
"Speed Scale",
"Scale factor that affects the default speed for a camera path."
@@ -439,9 +443,12 @@ Waypoint AutoNavigationHandler::lastWayPoint() {
}
void AutoNavigationHandler::removeRollRotation(CameraPose& pose, double deltaTime) {
glm::dvec3 anchorPos = anchor()->worldPosition();
const double notTooCloseDistance = deltaTime * glm::distance(anchorPos, pose.position);
glm::dvec3 cameraDir = glm::normalize(pose.rotation * Camera::ViewDirectionCameraSpace);
const glm::dvec3 anchorPos = anchor()->worldPosition();
const glm::dvec3 cameraDir = glm::normalize(
pose.rotation * Camera::ViewDirectionCameraSpace
);
const double anchorToPosDistance = glm::distance(anchorPos, pose.position);
const double notTooCloseDistance = deltaTime * anchorToPosDistance;
glm::dvec3 lookAtPos = pose.position + notTooCloseDistance * cameraDir;
glm::dquat rollFreeRotation = helpers::getLookAtQuaternion(
pose.position,
@@ -623,7 +630,8 @@ Waypoint AutoNavigationHandler::computeDefaultWaypoint(const TargetNodeInstructi
stepDirection = glm::normalize(nodePos - closeNode->worldPosition());
}
else {
// Go to a point that is being lit up by the sun, slightly offsetted from sun direction
// Go to a point that is being lit up by the sun, slightly offsetted from sun
// direction
const glm::dvec3 sunPos = glm::dvec3(0.0, 0.0, 0.0);
const glm::dvec3 prevPos = lastWayPoint().position();
const glm::dvec3 targetToPrev = prevPos - nodePos;

View File

@@ -92,42 +92,47 @@ scripting::LuaLibrary AutoNavigationModule::luaLibrary() const {
&autonavigation::luascriptfunctions::goTo,
{},
"string, [double]",
"TODO: Description. Go to the node with the given name with optional duration."
"Mov the camera to the node with the specified. The optional parameter "
"specifies the duration of the motion."
},
{
"generatePath",
&autonavigation::luascriptfunctions::generatePath,
{},
"table",
"Generate the path as described by the lua table input argument. TODO: Describe how a path instruction is defined?. "
"Generate the path as described by the lua table input argument. "
},
{
"generatePathFromFile",
&autonavigation::luascriptfunctions::generatePathFromFile,
{},
"string",
"Read an input file with lua instructions and use those to generate a camera path. TODO: Describe how a path instruction is defined?. "
"Read an input file with lua instructions and use those to generate a camera "
"path. "
},
{
"getPathPositions",
&autonavigation::luascriptfunctions::getPathPositions,
{},
"number",
"FOR DEBUG. Sample positions along the path. The input argument is the number of samples per path segment. "
"FOR DEBUG. Sample positions along the path. The input argument is the "
"number of samples per path segment. "
},
{
"getPathOrientations",
&autonavigation::luascriptfunctions::getPathOrientations,
{},
"number",
"FOR DEBUG. Sample orientations along the path. The input argument is the number of samples per path segment. "
"FOR DEBUG. Sample orientations along the path. The input argument is the "
"number of samples per path segment. "
},
{
"getPathViewDirections",
&autonavigation::luascriptfunctions::getPathViewDirections,
{},
"number",
"FOR DEBUG. Sample view directions along the path. The input argument is the number of samples per path segment. "
"FOR DEBUG. Sample view directions along the path. The input argument is "
"the number of samples per path segment. "
},
{
"getControlPoints",

View File

@@ -39,275 +39,276 @@
namespace openspace::autonavigation::luascriptfunctions {
const double EPSILON = 1e-12;
const double EPSILON = 1e-12;
int continuePath(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::continuePath");
int continuePath(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::continuePath");
AutoNavigationModule* module = global::moduleEngine->module<AutoNavigationModule>();
AutoNavigationHandler& handler = module->AutoNavigationHandler();
handler.continuePath();
AutoNavigationModule* module = global::moduleEngine->module<AutoNavigationModule>();
AutoNavigationHandler& handler = module->AutoNavigationHandler();
handler.continuePath();
return 0;
return 0;
}
int stopPath(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::stopPath");
AutoNavigationModule* module = global::moduleEngine->module<AutoNavigationModule>();
AutoNavigationHandler& handler = module->AutoNavigationHandler();
handler.abortPath();
return 0;
}
int goTo(lua_State* L) {
int nArguments = ghoul::lua::checkArgumentsAndThrow(L, { 1, 2 }, "lua::goTo");
const std::string& nodeIdentifier = ghoul::lua::value<std::string>(L, 1);
if (!sceneGraphNode(nodeIdentifier)) {
lua_settop(L, 0);
return ghoul::lua::luaError(L, "Unknown node name: " + nodeIdentifier);
}
int stopPath(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::stopPath");
ghoul::Dictionary insDict;
insDict.setValue("Target", nodeIdentifier);
AutoNavigationModule* module = global::moduleEngine->module<AutoNavigationModule>();
AutoNavigationHandler& handler = module->AutoNavigationHandler();
handler.abortPath();
return 0;
}
int goTo(lua_State* L) {
int nArguments = ghoul::lua::checkArgumentsAndThrow(L, { 1, 2 }, "lua::goTo");
const std::string& nodeIdentifier = ghoul::lua::value<std::string>(L, 1);
if (!sceneGraphNode(nodeIdentifier)) {
if (nArguments > 1) {
double duration = ghoul::lua::value<double>(L, 2);
if (duration <= EPSILON) {
lua_settop(L, 0);
return ghoul::lua::luaError(L, "Unknown node name: " + nodeIdentifier);
return ghoul::lua::luaError(L, "Duration must be larger than zero.");
}
ghoul::Dictionary insDict;
insDict.setValue("Target", nodeIdentifier);
if (nArguments > 1) {
double duration = ghoul::lua::value<double>(L, 2);
if (duration <= EPSILON) {
lua_settop(L, 0);
return ghoul::lua::luaError(L, "Duration must be larger than zero.");
}
insDict.setValue("Duration", duration);
}
PathSpecification spec = PathSpecification(TargetNodeInstruction{insDict});
AutoNavigationModule* module = global::moduleEngine->module<AutoNavigationModule>();
AutoNavigationHandler& handler = module->AutoNavigationHandler();
handler.createPath(spec);
lua_settop(L, 0);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
insDict.setValue("Duration", duration);
}
int generatePath(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::generatePath");
PathSpecification spec = PathSpecification(TargetNodeInstruction{insDict});
ghoul::Dictionary dictionary;
ghoul::lua::luaDictionaryFromState(L, dictionary);
PathSpecification spec(dictionary);
AutoNavigationModule* module = global::moduleEngine->module<AutoNavigationModule>();
AutoNavigationHandler& handler = module->AutoNavigationHandler();
handler.createPath(spec);
if (spec.instructions()->empty()) {
lua_settop(L, 0);
return ghoul::lua::luaError(
L, fmt::format("No instructions for camera path generation were provided.")
);
}
lua_settop(L, 0);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
AutoNavigationModule* module = global::moduleEngine->module<AutoNavigationModule>();
AutoNavigationHandler& handler = module->AutoNavigationHandler();
handler.createPath(spec);
int generatePath(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::generatePath");
ghoul::Dictionary dictionary;
ghoul::lua::luaDictionaryFromState(L, dictionary);
PathSpecification spec(dictionary);
if (spec.instructions()->empty()) {
lua_settop(L, 0);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
return ghoul::lua::luaError(
L, fmt::format("No instructions for camera path generation were provided.")
);
}
int generatePathFromFile(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::generatePathFromFile");
AutoNavigationModule* module = global::moduleEngine->module<AutoNavigationModule>();
AutoNavigationHandler& handler = module->AutoNavigationHandler();
handler.createPath(spec);
const std::string& filepath = ghoul::lua::value<std::string>(L, 1, ghoul::lua::PopValue::Yes);
lua_settop(L, 0);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
if (filepath.empty()) {
return ghoul::lua::luaError(L, "filepath string is empty");
}
int generatePathFromFile(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::generatePathFromFile");
const std::string absolutePath = absPath(filepath);
const std::string& filepath = ghoul::lua::value<std::string>(L, 1, ghoul::lua::PopValue::Yes);
LINFOC("AutoNavigationModule", fmt::format("Reading path instructions from file: {}", absolutePath));
if (!FileSys.fileExists(absolutePath)) {
throw ghoul::FileNotFoundError(absolutePath, "PathSpecification");
}
// Try to read the dictionary
ghoul::Dictionary dictionary;
try {
ghoul::lua::loadDictionaryFromFile(absolutePath, dictionary);
openspace::documentation::testSpecificationAndThrow(
PathSpecification::Documentation(),
dictionary,
"PathSpecification"
);
}
catch (ghoul::RuntimeError& e) {
return ghoul::lua::luaError(
L, fmt::format("Unable to read dictionary from file: {}", e.message)
);
}
PathSpecification spec(dictionary);
if (spec.instructions()->empty()) {
return ghoul::lua::luaError(
L, fmt::format("No instructions for camera path generation were provided.")
);
}
LINFOC("AutoNavigationModule", "Reading succeeded. Creating path");
AutoNavigationModule* module = global::moduleEngine->module<AutoNavigationModule>();
AutoNavigationHandler& handler = module->AutoNavigationHandler();
handler.createPath(spec);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
if (filepath.empty()) {
return ghoul::lua::luaError(L, "filepath string is empty");
}
// TODO: remove when not needed
// Created for debugging. Access info for rendereable path
int getPathPositions(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::getPathPositions");
const std::string absolutePath = absPath(filepath);
const int pointsPerSegment = (int)ghoul::lua::value<lua_Number>(L, 1);
LINFOC("AutoNavigationModule", fmt::format(
"Reading path instructions from file: {}", absolutePath
));
// Get sample positions from the current curve
AutoNavigationModule* module = global::moduleEngine->module<AutoNavigationModule>();
AutoNavigationHandler& handler = module->AutoNavigationHandler();
std::vector<glm::dvec3> points = handler.getCurvePositions(pointsPerSegment);
if (!FileSys.fileExists(absolutePath)) {
throw ghoul::FileNotFoundError(absolutePath, "PathSpecification");
}
// Push the points to the Lua stack:
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);
};
// Try to read the dictionary
ghoul::Dictionary dictionary;
try {
ghoul::lua::loadDictionaryFromFile(absolutePath, dictionary);
openspace::documentation::testSpecificationAndThrow(
PathSpecification::Documentation(),
dictionary,
"PathSpecification"
);
}
catch (ghoul::RuntimeError& e) {
return ghoul::lua::luaError(
L, fmt::format("Unable to read dictionary from file: {}", e.message)
);
}
PathSpecification spec(dictionary);
if (spec.instructions()->empty()) {
return ghoul::lua::luaError(
L, fmt::format("No instructions for camera path generation were provided.")
);
}
LINFOC("AutoNavigationModule", "Reading succeeded. Creating path");
AutoNavigationModule* module = global::moduleEngine->module<AutoNavigationModule>();
AutoNavigationHandler& handler = module->AutoNavigationHandler();
handler.createPath(spec);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
// TODO: remove when not needed
// Created for debugging. Access info for rendereable path
int getPathPositions(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::getPathPositions");
const int pointsPerSegment = (int)ghoul::lua::value<lua_Number>(L, 1);
// Get sample positions from the current curve
AutoNavigationModule* module = global::moduleEngine->module<AutoNavigationModule>();
AutoNavigationHandler& handler = module->AutoNavigationHandler();
std::vector<glm::dvec3> points = handler.getCurvePositions(pointsPerSegment);
// Push the points to the Lua stack:
lua_settop(L, 0);
const auto pushVector = [](lua_State* L, const glm::dvec3& v) {
lua_newtable(L);
for (int i = 0; i < points.size(); ++i) {
ghoul::lua::push(L, i+1);
pushVector(L, points[i]);
lua_rawset(L, -3);
}
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);
};
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
lua_newtable(L);
for (int i = 0; i < points.size(); ++i) {
ghoul::lua::push(L, i+1);
pushVector(L, points[i]);
lua_rawset(L, -3);
}
// TODO: remove when not needed
// Created for debugging. Access info for rendereable path
int getPathOrientations(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::getPathPositions");
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
}
const int pointsPerSegment = (int)ghoul::lua::value<lua_Number>(L, 1);
// TODO: remove when not needed
// Created for debugging. Access info for rendereable path
int getPathOrientations(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::getPathPositions");
// Get sample positions from the current curve
AutoNavigationModule* module = global::moduleEngine->module<AutoNavigationModule>();
AutoNavigationHandler& handler = module->AutoNavigationHandler();
std::vector<glm::dquat> orientations = handler.getCurveOrientations(pointsPerSegment);
const int pointsPerSegment = (int)ghoul::lua::value<lua_Number>(L, 1);
// Push the rotation to the Lua stack:
lua_settop(L, 0);
const auto pushVector = [](lua_State* L, const glm::dquat& v) {
lua_newtable(L);
ghoul::lua::push(L, 1, v.w);
lua_rawset(L, -4);
ghoul::lua::push(L, 2, v.x);
lua_rawset(L, -4);
ghoul::lua::push(L, 3, v.y);
lua_rawset(L, -4);
ghoul::lua::push(L, 4, v.z);
lua_rawset(L, -4);
};
// Get sample positions from the current curve
AutoNavigationModule* module = global::moduleEngine->module<AutoNavigationModule>();
AutoNavigationHandler& handler = module->AutoNavigationHandler();
std::vector<glm::dquat> orientations = handler.getCurveOrientations(pointsPerSegment);
// Push the rotation to the Lua stack:
lua_settop(L, 0);
const auto pushVector = [](lua_State* L, const glm::dquat& v) {
lua_newtable(L);
for (int i = 0; i < orientations.size(); ++i) {
ghoul::lua::push(L, i + 1);
pushVector(L, orientations[i]);
lua_rawset(L, -4);
}
ghoul::lua::push(L, 1, v.w);
lua_rawset(L, -4);
ghoul::lua::push(L, 2, v.x);
lua_rawset(L, -4);
ghoul::lua::push(L, 3, v.y);
lua_rawset(L, -4);
ghoul::lua::push(L, 4, v.z);
lua_rawset(L, -4);
};
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
lua_newtable(L);
for (int i = 0; i < orientations.size(); ++i) {
ghoul::lua::push(L, i + 1);
pushVector(L, orientations[i]);
lua_rawset(L, -4);
}
// TODO: remove when not needed
// Created for debugging. Access info for rendereable path
int getPathViewDirections(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::getPathViewDirections");
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
}
const int pointsPerSegment = (int)ghoul::lua::value<lua_Number>(L, 1);
// TODO: remove when not needed
// Created for debugging. Access info for rendereable path
int getPathViewDirections(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::getPathViewDirections");
// Get sample positions from the current curve
AutoNavigationModule* module = global::moduleEngine->module<AutoNavigationModule>();
AutoNavigationHandler& handler = module->AutoNavigationHandler();
std::vector<glm::dvec3> viewDirections = handler.getCurveViewDirections(pointsPerSegment);
const int pointsPerSegment = (int)ghoul::lua::value<lua_Number>(L, 1);
// Push the rotation to the Lua stack:
// Push the points to the Lua stack:
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);
};
// Get sample positions from the current curve
AutoNavigationModule* module = global::moduleEngine->module<AutoNavigationModule>();
AutoNavigationHandler& handler = module->AutoNavigationHandler();
std::vector<glm::dvec3> viewDirections = handler.getCurveViewDirections(pointsPerSegment);
// Push the points to the Lua stack:
lua_settop(L, 0);
const auto pushVector = [](lua_State* L, const glm::dvec3& v) {
lua_newtable(L);
for (int i = 0; i < viewDirections.size(); ++i) {
ghoul::lua::push(L, i + 1);
pushVector(L, viewDirections[i]);
lua_rawset(L, -3);
}
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);
};
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
// Push the rotation to the Lua stack:
lua_newtable(L);
for (int i = 0; i < viewDirections.size(); ++i) {
ghoul::lua::push(L, i + 1);
pushVector(L, viewDirections[i]);
lua_rawset(L, -3);
}
// TODO: remove when not needed
// Created for debugging. Access info for rendering of control points
int getControlPoints(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::getControlPoints");
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
}
// Get sample positions from the current curve
AutoNavigationModule* module = global::moduleEngine->module<AutoNavigationModule>();
AutoNavigationHandler& handler = module->AutoNavigationHandler();
std::vector<glm::dvec3> points = handler.getControlPoints();
// TODO: remove when not needed
// Created for debugging. Access info for rendering of control points
int getControlPoints(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::getControlPoints");
// Push the points to the Lua stack:
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);
};
// Get sample positions from the current curve
AutoNavigationModule* module = global::moduleEngine->module<AutoNavigationModule>();
AutoNavigationHandler& handler = module->AutoNavigationHandler();
std::vector<glm::dvec3> points = handler.getControlPoints();
// Push the points to the Lua stack:
lua_settop(L, 0);
const auto pushVector = [](lua_State* L, const glm::dvec3& v) {
lua_newtable(L);
for (int i = 0; i < points.size(); ++i) {
ghoul::lua::push(L, i+1);
pushVector(L, points[i]);
lua_rawset(L, -3);
}
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);
};
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
lua_newtable(L);
for (int i = 0; i < points.size(); ++i) {
ghoul::lua::push(L, i+1);
pushVector(L, points[i]);
lua_rawset(L, -3);
}
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
}
} // namespace openspace::autonavigation::luascriptfunctions

View File

@@ -84,7 +84,6 @@ AvoidCollisionCurve::AvoidCollisionCurve(const Waypoint& start, const Waypoint&
double cosAngleToTarget = glm::dot(normalize(-startViewDirection), normalize(startToEnd));
bool targetInOppositeDirection = cosAngleToTarget > 0.7;
// TODO: reduce magical numbers / create constants
if (targetInOppositeDirection) {
glm::dquat midleRotation = glm::slerp(start.rotation(), end.rotation(), 0.5);
glm::dvec3 middleViewDirection = midleRotation * glm::dvec3(0.0, 0.0, -1.0);

View File

@@ -98,9 +98,10 @@ namespace openspace::autonavigation::helpers {
namespace openspace::autonavigation::interpolation {
// Based on implementation by Mika Rantanen https://qroph.github.io/2018/07/30/smooth-paths-using-catmull-rom-splines.html
// Based on implementation by Mika Rantanen
// https://qroph.github.io/2018/07/30/smooth-paths-using-catmull-rom-splines.html
glm::dvec3 catmullRom(double t, const glm::dvec3& p0, const glm::dvec3& p1,
const glm::dvec3& p2, const glm::dvec3& p3, double alpha)
const glm::dvec3& p2, const glm::dvec3& p3, double alpha)
{
glm::dvec3 m01, m02, m23, m13;
@@ -121,15 +122,14 @@ namespace openspace::autonavigation::interpolation {
glm::dvec3 c = m1;
glm::dvec3 d = p1;
return
a * t * t * t +
b * t * t +
c * t +
d;
return a * t * t * t
+ b * t * t
+ c * t
+ d;
}
glm::dvec3 cubicBezier(double t, const glm::dvec3& cp1, const glm::dvec3& cp2,
const glm::dvec3& cp3, const glm::dvec3& cp4)
const glm::dvec3& cp3, const glm::dvec3& cp4)
{
ghoul_assert(t >= 0 && t <= 1.0, "Interpolation variable out of range [0, 1]");
@@ -157,9 +157,9 @@ namespace openspace::autonavigation::interpolation {
const double t3 = t2 * t;
// calculate basis functions
double const a0 = (2.0*t3) - (3.0*t2) + 1.0;
double const a1 = (-2.0*t3) + (3.0*t2);
double const b0 = t3 - (2.0*t2) + t;
double const a0 = (2.0 * t3) - (3.0 * t2) + 1.0;
double const a1 = (-2.0 * t3) + (3.0 * t2);
double const b0 = t3 - (2.0 * t2) + t;
double const b1 = t3 - t2;
return (a0 * p1) + (a1 * p2) + (b0 * tangent1) + (b1 * tangent2);
@@ -167,7 +167,7 @@ namespace openspace::autonavigation::interpolation {
// uniform if tKnots are equally spaced, or else non uniform
glm::dvec3 piecewiseCubicBezier(double t, const std::vector<glm::dvec3>& points,
const std::vector<double>& tKnots)
const std::vector<double>& tKnots)
{
ghoul_assert(points.size() > 4, "Minimum of four control points needed for interpolation!");
ghoul_assert((points.size() - 1) % 3 == 0, "A vector containing 3n + 1 control points must be provided!");
@@ -189,12 +189,17 @@ namespace openspace::autonavigation::interpolation {
unsigned int idx = segmentIdx * 3;
// Interpolate using De Casteljau's algorithm
return interpolation::cubicBezier(tScaled, points[idx], points[idx + 1],
points[idx + 2], points[idx + 3]);
return interpolation::cubicBezier(
tScaled,
points[idx],
points[idx + 1],
points[idx + 2],
points[idx + 3]
);
}
glm::dvec3 piecewiseLinear(double t, const std::vector<glm::dvec3>& points,
const std::vector<double>& tKnots)
const std::vector<double>& tKnots)
{
ghoul_assert(points.size() == tKnots.size(), "Must have equal number of points and times!");
ghoul_assert(points.size() > 2, "Minimum of two control points needed for interpolation!");

View File

@@ -152,8 +152,8 @@ documentation::Documentation PathSpecification::Documentation() {
// create correct type of instruction and present and throw error with useful
// error message if we failed.
void PathSpecification::tryReadInstruction(int index, std::string type,
ghoul::Dictionary& dictionary)
void PathSpecification::tryReadInstruction(int index, const std::string& type,
const ghoul::Dictionary& dictionary)
{
if (type == KeyTypeTargetNode) {
try {

View File

@@ -52,13 +52,12 @@ public:
const bool hasStartState() const;
private:
void tryReadInstruction(int index, std::string type, ghoul::Dictionary& dictionary);
void tryReadInstruction(int index, const std::string& type,
const ghoul::Dictionary& dictionary);
std::vector<std::unique_ptr<Instruction>> _instructions;
std::optional<bool> _stopAtTargets;
std::optional<NavigationState> _startState;
// TODO: maxSpeed or speedFactor or something?
};
} // namespace openspace::autonavigation

View File

@@ -37,7 +37,7 @@ namespace {
namespace openspace::autonavigation {
WaypointNodeDetails::WaypointNodeDetails(const std::string nodeIdentifier) {
WaypointNodeDetails::WaypointNodeDetails(const std::string& nodeIdentifier) {
const SceneGraphNode* node = sceneGraphNode(nodeIdentifier);
if (!node) {
LERROR(fmt::format("Could not find node '{}'.", nodeIdentifier));
@@ -54,7 +54,6 @@ double WaypointNodeDetails::findValidBoundingSphere(const SceneGraphNode* node)
global::moduleEngine->module<AutoNavigationModule>()->minValidBoundingSphere();
if (bs < minValidBoundingSphere) {
// If the bs of the target is too small, try to find a good value in a child node.
// Only check the closest children, to avoid deep traversal in the scene graph.
// Also, the possibility to find a bounding sphere represents the visual size of

View File

@@ -39,12 +39,12 @@ struct CameraPose {
// The waypoint node is the anchor or target node.
struct WaypointNodeDetails {
WaypointNodeDetails() = default;
WaypointNodeDetails(const std::string nodeIdentifier);
WaypointNodeDetails(const std::string& nodeIdentifier);
static double findValidBoundingSphere(const SceneGraphNode* node);
std::string identifier;
double validBoundingSphere; // to be able to handle nodes with faulty bounding spheres
double validBoundingSphere = 0.0; // to be able to handle nodes with faulty bounding spheres
};
struct Waypoint {