Merge branch 'master' into issue/1466

This commit is contained in:
Malin Ejdbo
2021-02-17 14:25:55 +01:00
27 changed files with 734 additions and 252 deletions

View File

@@ -203,6 +203,12 @@ begin_header("Configuring Applications")
add_subdirectory("${OPENSPACE_APPS_DIR}")
end_header("End: Configuring Applications")
if (MSVC AND TARGET OpenSpace)
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT OpenSpace)
endif()
option(OPENSPACE_HAVE_TESTS "Activate the OpenSpace unit tests" ON)
if (OPENSPACE_HAVE_TESTS)
begin_header("Generating OpenSpace unit test")

View File

@@ -660,6 +660,17 @@ void mainCharCallback(unsigned int codepoint, int modifiers) {
void mainDropCallback(int amount, const char** paths) {
ghoul_assert(amount > 0, "Expected at least one file path");
ghoul_assert(paths, "expected non-nullptr");
for (int i = 0; i < amount; ++i) {
global::openSpaceEngine->handleDragDrop(paths[i]);
}
}
std::vector<std::byte> mainEncodeFun() {
ZoneScoped
LTRACE("main::mainEncodeFun(begin)");
@@ -1025,7 +1036,6 @@ int main(int argc, char* argv[]) {
{
using namespace ghoul::logging;
LogManager::initialize(LogLevel::Debug, LogManager::ImmediateFlush::Yes);
LogMgr.addLog(std::make_unique<ConsoleLog>());
#ifdef WIN32
if (IsDebuggerPresent()) {
LogMgr.addLog(std::make_unique<ghoul::logging::VisualStudioOutputLog>());
@@ -1252,6 +1262,7 @@ int main(int argc, char* argv[]) {
callbacks.mousePos = mainMousePosCallback;
callbacks.mouseScroll = mainMouseScrollCallback;
callbacks.character = mainCharCallback;
callbacks.drop = mainDropCallback;
callbacks.encode = mainEncodeFun;
callbacks.decode = mainDecodeFun;
Log::instance().setNotifyLevel(Log::Level::Debug);

View File

@@ -4,6 +4,14 @@ local DataPath = asset.syncedResource({
Identifier = "exoplanets_data",
Version = 2
})
asset.onInitialize(function ()
local p = "Modules.Exoplanets.DataFolder";
if(openspace.getPropertyValue(p) == "") then
openspace.setPropertyValueSingle(p, DataPath)
end
end)
asset.export("DataPath", DataPath)
asset.meta = {

View File

@@ -1,4 +1,5 @@
asset.require('./../habitable_zones/habitable_zone_textures')
local habitableZoneTextures =
asset.require('./../habitable_zones/habitable_zone_textures').TexturesPath
local TexturesPath = asset.syncedResource({
Name = "Exoplanet Textures",
@@ -6,6 +7,37 @@ local TexturesPath = asset.syncedResource({
Identifier = "exoplanets_textures",
Version = 2
})
asset.onInitialize(function ()
local starTexture = TexturesPath .. "/sun.jpg"
local noDataTexture = TexturesPath .. "/grid-32.png"
local discTexture = TexturesPath .. "/disc_bw_texture.png"
local hzTexture = habitableZoneTextures .. "/hot_to_cold_faded.png"
-- Set the default textures used for the exoplanet system creation
-- (Check if already set, to not override value in config file)
local p = "Modules.Exoplanets.StarTexture";
if(openspace.getPropertyValue(p) == "") then
openspace.setPropertyValueSingle(p, starTexture)
end
p = "Modules.Exoplanets.NoDataTexture";
if(openspace.getPropertyValue(p) == "") then
openspace.setPropertyValueSingle(p, noDataTexture)
end
p = "Modules.Exoplanets.OrbitDiscTexture";
if(openspace.getPropertyValue(p) == "") then
openspace.setPropertyValueSingle(p, discTexture)
end
p = "Modules.Exoplanets.HabitableZoneTexture";
if(openspace.getPropertyValue(p) == "") then
openspace.setPropertyValueSingle(p, hzTexture)
end
end)
asset.export("TexturesPath", TexturesPath)
asset.meta = {

View File

@@ -66,6 +66,8 @@ struct TestResult {
std::string offender;
/// The Reason that caused this offense
Reason reason;
/// An optional explanation for when a verification fails
std::string explanation;
};
/**
@@ -79,7 +81,7 @@ struct TestResult {
* The reason for the warning
*/
enum class Reason {
Deprecated ///< The value is marked as deprecated and should not used
Deprecated ///< The value is marked as deprecated and should not used
};
/// The offending key that caused the Warning. In the case of a nested table,

View File

@@ -158,6 +158,28 @@ struct StringVerifier : public TemplateVerifier<std::string> {
std::string type() const override;
};
/**
* A Verifier that checks whether a given key inside a ghoul::Dictionary is a string and
* refers to an existing file on disk.
*/
struct FileVerifier : public StringVerifier {
TestResult operator()(const ghoul::Dictionary& dict,
const std::string& key) const override;
std::string type() const override;
};
/**
* A Verifier that checks whether a given key inside a ghoul::Dictionary is a string and
* refers to an existing directory on disk.
*/
struct DirectoryVerifier : public StringVerifier {
TestResult operator()(const ghoul::Dictionary& dict,
const std::string& key) const override;
std::string type() const override;
};
/**
* A Verifier that checks whether a given key inside a ghoul::Dictionary is another
* ghoul::Dictionary. The constructor takes a list of DocumentationEntry%s, which are used
@@ -243,39 +265,48 @@ struct IntListVerifier : public TableVerifier {
*/
struct VectorVerifier {};
/**
* This Verifier checks whether the value is of type <code>glm::tvec2<T></code>
*/
/// This Verifier checks whether the value is of type <code>glm::tvec2<T></code>
template <typename T>
struct Vector2Verifier : public TemplateVerifier<glm::tvec2<T>>, public VectorVerifier {
std::string type() const override;
};
/**
* This Verifier checks whether the value is of type <code>glm::tvec3<T></code>
*/
/// This Verifier checks whether the value is of type <code>glm::tvec3<T></code>
template <typename T>
struct Vector3Verifier : public TemplateVerifier<glm::tvec3<T>>, public VectorVerifier {
std::string type() const override;
};
/**
* This Verifier checks whether the value is of type <code>glm::tvec4<T></code>
*/
/// This Verifier checks whether the value is of type <code>glm::tvec4<T></code>
template <typename T>
struct Vector4Verifier : public TemplateVerifier<glm::tvec4<T>>, public VectorVerifier {
std::string type() const override;
};
struct Color3Verifier : public Vector3Verifier<double> {
TestResult operator()(const ghoul::Dictionary& dictionary,
const std::string& key) const override;
std::string type() const override;
};
struct Color4Verifier : public Vector4Verifier<double> {
TestResult operator()(const ghoul::Dictionary& dictionary,
const std::string& key) const override;
std::string type() const override;
};
/**
* A Verifier that checks whether all values contained in a Table are of
* type <code>glm::tvec2<T></code>
*/
template <typename T>
struct Vector2ListVerifier : public TableVerifier {
Vector2ListVerifier(std::string elementDocumentation = "") : TableVerifier({
Vector2ListVerifier(std::string elementDocumentation = "")
: TableVerifier({
{ "*", new Vector2Verifier<T>, Optional::No, std::move(elementDocumentation) }
})
})
{}
std::string type() const override {
@@ -289,9 +320,10 @@ struct Vector2ListVerifier : public TableVerifier {
*/
template <typename T>
struct Vector3ListVerifier : public TableVerifier {
Vector3ListVerifier(std::string elementDocumentation = "") : TableVerifier({
{ "*", new Vector3Verifier<T>, Optional::No, std::move(elementDocumentation) }
})
Vector3ListVerifier(std::string elementDocumentation = "")
: TableVerifier({
{ "*", new Vector3Verifier<T>, Optional::No, std::move(elementDocumentation) }
})
{}
std::string type() const override {
@@ -305,15 +337,17 @@ struct Vector3ListVerifier : public TableVerifier {
*/
template <typename T>
struct Vector4ListVerifier : public TableVerifier {
Vector4ListVerifier(std::string elementDocumentation = "") : TableVerifier({
{ "*", new Vector4Verifier<T>, Optional::No, std::move(elementDocumentation) }
})
Vector4ListVerifier(std::string elementDocumentation = "")
: TableVerifier({
{ "*", new Vector4Verifier<T>, Optional::No, std::move(elementDocumentation) }
})
{}
std::string type() const override {
return "List of ints";
}
};
//----------------------------------------------------------------------------------------
// Matrix verifiers
//----------------------------------------------------------------------------------------
@@ -330,8 +364,7 @@ struct MatrixVerifier {};
* This Verifier checks whether the value is of type <code>glm::mat2x2<T></code>
*/
template <typename T>
struct Matrix2x2Verifier :
public TemplateVerifier<glm::tmat2x2<T>>, public MatrixVerifier
struct Matrix2x2Verifier : public TemplateVerifier<glm::tmat2x2<T>>, public MatrixVerifier
{
std::string type() const override;
};
@@ -340,8 +373,8 @@ struct Matrix2x2Verifier :
* This Verifier checks whether the value is of type <code>glm::mat2x3<T></code>
*/
template <typename T>
struct Matrix2x3Verifier :
public TemplateVerifier<glm::tmat2x3<T>>, public MatrixVerifier {
struct Matrix2x3Verifier : public TemplateVerifier<glm::tmat2x3<T>>, public MatrixVerifier
{
std::string type() const override;
};
@@ -349,8 +382,8 @@ struct Matrix2x3Verifier :
* This Verifier checks whether the value is of type <code>glm::mat2x4<T></code>
*/
template <typename T>
struct Matrix2x4Verifier :
public TemplateVerifier<glm::tmat2x4<T>>, public MatrixVerifier {
struct Matrix2x4Verifier : public TemplateVerifier<glm::tmat2x4<T>>, public MatrixVerifier
{
std::string type() const override;
};
@@ -358,8 +391,8 @@ struct Matrix2x4Verifier :
* This Verifier checks whether the value is of type <code>glm::mat3x2<T></code>
*/
template <typename T>
struct Matrix3x2Verifier :
public TemplateVerifier<glm::tmat3x2<T>>, public MatrixVerifier {
struct Matrix3x2Verifier : public TemplateVerifier<glm::tmat3x2<T>>, public MatrixVerifier
{
std::string type() const override;
};
@@ -367,8 +400,8 @@ struct Matrix3x2Verifier :
* This Verifier checks whether the value is of type <code>glm::mat3x3<T></code>
*/
template <typename T>
struct Matrix3x3Verifier :
public TemplateVerifier<glm::tmat3x3<T>>, public MatrixVerifier {
struct Matrix3x3Verifier : public TemplateVerifier<glm::tmat3x3<T>>, public MatrixVerifier
{
std::string type() const override;
};
@@ -376,8 +409,8 @@ struct Matrix3x3Verifier :
* This Verifier checks whether the value is of type <code>glm::mat3x4<T></code>
*/
template <typename T>
struct Matrix3x4Verifier :
public TemplateVerifier<glm::tmat3x4<T>>, public MatrixVerifier {
struct Matrix3x4Verifier : public TemplateVerifier<glm::tmat3x4<T>>, public MatrixVerifier
{
std::string type() const override;
};
@@ -385,8 +418,8 @@ struct Matrix3x4Verifier :
* This Verifier checks whether the value is of type <code>glm::mat4x2<T></code>
*/
template <typename T>
struct Matrix4x2Verifier :
public TemplateVerifier<glm::tmat4x2<T>>, public MatrixVerifier {
struct Matrix4x2Verifier : public TemplateVerifier<glm::tmat4x2<T>>, public MatrixVerifier
{
std::string type() const override;
};
@@ -394,8 +427,8 @@ struct Matrix4x2Verifier :
* This Verifier checks whether the value is of type <code>glm::mat4x3<T></code>
*/
template <typename T>
struct Matrix4x3Verifier :
public TemplateVerifier<glm::tmat4x3<T>>, public MatrixVerifier {
struct Matrix4x3Verifier : public TemplateVerifier<glm::tmat4x3<T>>, public MatrixVerifier
{
std::string type() const override;
};
@@ -403,8 +436,8 @@ struct Matrix4x3Verifier :
* This Verifier checks whether the value is of type <code>glm::mat4x4<T></code>
*/
template <typename T>
struct Matrix4x4Verifier :
public TemplateVerifier<glm::tmat4x4<T>>, public MatrixVerifier {
struct Matrix4x4Verifier : public TemplateVerifier<glm::tmat4x4<T>>, public MatrixVerifier
{
std::string type() const override;
};
@@ -465,18 +498,11 @@ struct OperatorVerifier : public T {
*/
template <typename T>
struct LessVerifier : public OperatorVerifier<T, std::less<typename T::Type>> {
static_assert(!std::is_base_of<BoolVerifier, T>::value, "T cannot be BoolVerifier");
static_assert(
!std::is_base_of<BoolVerifier, T>::value,
"T cannot be BoolVerifier"
);
static_assert(
!std::is_base_of<StringVerifier, T>::value,
"T cannot be StringVerifier"
);
static_assert(
!std::is_base_of<TableVerifier, T>::value,
"T cannot be TableVerifier"
!std::is_base_of<StringVerifier, T>::value, "T cannot be StringVerifier"
);
static_assert(!std::is_base_of<TableVerifier, T>::value, "T cannot be TableVerifier");
static_assert(
!std::is_base_of<VectorVerifier, T>::value,
"T cannot be VectorVerifier"
@@ -496,18 +522,12 @@ struct LessVerifier : public OperatorVerifier<T, std::less<typename T::Type>> {
*/
template <typename T>
struct LessEqualVerifier : public OperatorVerifier<T, std::less_equal<typename T::Type>> {
static_assert(
!std::is_base_of<BoolVerifier, T>::value,
"T cannot be BoolVerifier"
);
static_assert(!std::is_base_of<BoolVerifier, T>::value, "T cannot be BoolVerifier");
static_assert(
!std::is_base_of<StringVerifier, T>::value,
"T cannot be StringVerifier"
);
static_assert(
!std::is_base_of<TableVerifier, T>::value,
"T cannot be TableVerifier"
);
static_assert(!std::is_base_of<TableVerifier, T>::value, "T cannot be TableVerifier");
static_assert(
!std::is_base_of<VectorVerifier, T>::value,
"T cannot be VectorVerifier"
@@ -527,22 +547,16 @@ struct LessEqualVerifier : public OperatorVerifier<T, std::less_equal<typename T
*/
template <typename T>
struct GreaterVerifier : public OperatorVerifier<T, std::greater<typename T::Type>> {
static_assert(
!std::is_base_of<BoolVerifier, T>::value,
"T cannot be BoolVerifier"
);
static_assert(!std::is_base_of<BoolVerifier, T>::value, "T cannot be BoolVerifier");
static_assert(
!std::is_base_of<StringVerifier, T>::value,
"T cannot be StringVerifier"
);
static_assert(
!std::is_base_of<TableVerifier, T>::value,
"T cannot be TableVerifier"
);
);
static_assert(!std::is_base_of<TableVerifier, T>::value, "T cannot be TableVerifier");
static_assert(
!std::is_base_of<VectorVerifier, T>::value,
"T cannot be VectorVerifier"
);
);
using OperatorVerifier<T, std::greater<typename T::Type>>::OperatorVerifier;
@@ -560,18 +574,12 @@ template <typename T>
struct GreaterEqualVerifier : public OperatorVerifier<T,
std::greater_equal<typename T::Type>>
{
static_assert(
!std::is_base_of<BoolVerifier, T>::value,
"T cannot be BoolVerifier"
);
static_assert(!std::is_base_of<BoolVerifier, T>::value, "T cannot be BoolVerifier");
static_assert(
!std::is_base_of<StringVerifier, T>::value,
"T cannot be StringVerifier"
);
static_assert(
!std::is_base_of<TableVerifier, T>::value,
"T cannot be TableVerifier"
);
static_assert(!std::is_base_of<TableVerifier, T>::value, "T cannot be TableVerifier");
static_assert(
!std::is_base_of<VectorVerifier, T>::value,
"T cannot be VectorVerifier"

View File

@@ -86,6 +86,7 @@ public:
void touchDetectionCallback(TouchInput input);
void touchUpdateCallback(TouchInput input);
void touchExitCallback(TouchInput input);
void handleDragDrop(const std::string& file);
std::vector<std::byte> encode();
void decode(std::vector<std::byte> data);

View File

@@ -438,13 +438,11 @@ void RenderableModel::render(const RenderData& data, RendererTasks&) {
);
_program->setUniform(
_uniformCache.lightIntensities,
_lightIntensitiesBuffer.data(),
nLightSources
_lightIntensitiesBuffer
);
_program->setUniform(
_uniformCache.lightDirectionsViewSpace,
_lightDirectionsViewSpaceBuffer.data(),
nLightSources
_lightDirectionsViewSpaceBuffer
);
_program->setUniform(
_uniformCache.modelViewTransform,

View File

@@ -35,6 +35,7 @@
#include <ghoul/misc/profiling.h>
#include <ghoul/opengl/programobject.h>
#include <cmath>
#include <optional>
namespace {
constexpr const char* ProgramName = "EphemerisProgram";
@@ -144,64 +145,44 @@ namespace {
"atmospheres if needed."
};
struct [[codegen::Dictionary(RenderableTrail)]] Parameters {
// This object is used to compute locations along the path. Any Translation object
// can be used here
std::monostate translation [[codegen::reference("core_transform_translation")]];
// [[codegen::verbatim(LineColorInfo.description)]]
glm::vec3 color [[codegen::color()]];
// [[codegen::verbatim(EnableFadeInfo.description)]]
std::optional<bool> enableFade;
// [[codegen::verbatim(FadeInfo.description)]]
std::optional<float> fade;
// [[codegen::verbatim(LineWidthInfo.description)]]
std::optional<float> lineWidth;
// [[codegen::verbatim(PointSizeInfo.description)]]
std::optional<int> pointSize;
enum class RenderingMode {
Lines,
Points,
LinesPoints [[codegen::key("Lines+Points")]],
PointsLines [[codegen::key("Lines+Points")]]
};
// [[codegen::verbatim(RenderingModeInfo.description)]]
std::optional<RenderingMode> renderingMode [[codegen::key("Rendering")]];
};
#include "renderabletrail_codegen.cpp"
} // namespace
namespace openspace {
documentation::Documentation RenderableTrail::Documentation() {
using namespace documentation;
return {
"RenderableTrail",
"base_renderable_renderabletrail",
{
{
KeyTranslation,
new ReferencingVerifier("core_transform_translation"),
Optional::No,
"This object is used to compute locations along the path. Any "
"Translation object can be used here."
},
{
LineColorInfo.identifier,
new DoubleVector3Verifier,
Optional::No,
LineColorInfo.description
},
{
EnableFadeInfo.identifier,
new BoolVerifier,
Optional::Yes,
EnableFadeInfo.description
},
{
FadeInfo.identifier,
new DoubleVerifier,
Optional::Yes,
FadeInfo.description
},
{
LineWidthInfo.identifier,
new DoubleVerifier,
Optional::Yes,
LineWidthInfo.description
},
{
PointSizeInfo.identifier,
new DoubleVerifier,
Optional::Yes,
PointSizeInfo.description
},
{
RenderingModeInfo.identifier,
new StringInListVerifier(
// Taken from the RenderingModeConversion map above
{ "Lines", "Points", "Lines+Points", "Points+Lines" }
),
Optional::Yes,
RenderingModeInfo.description
}
}
};
documentation::Documentation doc = codegen::doc<Parameters>();
doc.id = "base_renderable_renderabletrail";
return doc;
}
RenderableTrail::Appearance::Appearance()
@@ -233,6 +214,8 @@ RenderableTrail::Appearance::Appearance()
RenderableTrail::RenderableTrail(const ghoul::Dictionary& dictionary)
: Renderable(dictionary)
{
const Parameters p = codegen::bake<Parameters>(dictionary);
setRenderBin(RenderBin::Overlay);
addProperty(_opacity);
@@ -241,36 +224,25 @@ RenderableTrail::RenderableTrail(const ghoul::Dictionary& dictionary)
);
addPropertySubOwner(_translation.get());
_appearance.lineColor = dictionary.value<glm::dvec3>(LineColorInfo.identifier);
_appearance.lineColor = p.color;
_appearance.useLineFade = p.enableFade.value_or(_appearance.useLineFade);
_appearance.lineFade = p.fade.value_or(_appearance.lineFade);
_appearance.lineWidth = p.lineWidth.value_or(_appearance.lineWidth);
_appearance.pointSize = p.pointSize.value_or(_appearance.pointSize);
if (dictionary.hasValue<bool>(EnableFadeInfo.identifier)) {
_appearance.useLineFade = dictionary.value<bool>(EnableFadeInfo.identifier);
}
if (dictionary.hasValue<double>(FadeInfo.identifier)) {
_appearance.lineFade = static_cast<float>(
dictionary.value<double>(FadeInfo.identifier)
);
}
if (dictionary.hasValue<double>(LineWidthInfo.identifier)) {
_appearance.lineWidth = static_cast<float>(dictionary.value<double>(
LineWidthInfo.identifier
));
}
if (dictionary.hasValue<double>(PointSizeInfo.identifier)) {
_appearance.pointSize = static_cast<int>(
dictionary.value<double>(PointSizeInfo.identifier)
);
}
// This map is not accessed out of order as long as the Documentation is adapted
// whenever the map changes. The documentation will check for valid values
if (dictionary.hasValue<std::string>(RenderingModeInfo.identifier)) {
_appearance.renderingModes = RenderingModeConversion.at(
dictionary.value<std::string>(RenderingModeInfo.identifier)
);
if (p.renderingMode.has_value()) {
switch (*p.renderingMode) {
case Parameters::RenderingMode::Lines:
_appearance.renderingModes = RenderingModeLines;
break;
case Parameters::RenderingMode::Points:
_appearance.renderingModes = RenderingModePoints;
break;
case Parameters::RenderingMode::LinesPoints:
case Parameters::RenderingMode::PointsLines:
_appearance.renderingModes = RenderingModeLinesPoints;
break;
}
}
else {
_appearance.renderingModes = RenderingModeLines;

View File

@@ -38,11 +38,166 @@
#include "exoplanetsmodule_lua.inl"
namespace {
constexpr const openspace::properties::Property::PropertyInfo DataFolderInfo = {
"DataFolder",
"Data Folder",
"The path to the folder containing the exoplanets data and lookup table"
};
constexpr const openspace::properties::Property::PropertyInfo StarTextureInfo = {
"StarTexture",
"Star Texture",
"The path to a grayscale image that is used for the host star surfaces"
};
constexpr const openspace::properties::Property::PropertyInfo NoDataTextureInfo = {
"NoDataTexture",
"No Data Star Texture",
"A path to a texture that is used to represent that there is missing data about "
"the star. For example no color information"
};
constexpr const openspace::properties::Property::PropertyInfo OrbitDiscTextureInfo =
{
"OrbitDiscTexture",
"Orbit Disc Texture",
"A path to a 1-dimensional image used as a transfer function for the "
"exoplanets' orbit uncertainty disc"
};
constexpr const openspace::properties::Property::PropertyInfo
HabitableZoneTextureInfo =
{
"HabitableZoneTexture",
"Habitable Zone Texture",
"A path to a 1-dimensional image used as a transfer function for the "
"habitable zone disc"
};
constexpr const openspace::properties::Property::PropertyInfo
ShowComparisonCircleInfo =
{
"ShowComparisonCircle",
"Show Comparison Circle",
"If true, the 1 AU size comparison circle is enabled per default when an "
"exoplanet system is created"
};
constexpr const openspace::properties::Property::PropertyInfo
ShowHabitableZoneInfo =
{
"ShowHabitableZone",
"Show Habitable Zone",
"If true, the habitable zone disc is enabled per default when an "
"exoplanet system is created"
};
constexpr const openspace::properties::Property::PropertyInfo UseOptimisticZoneInfo =
{
"UseOptimisticZone",
"Use Optimistic Zone Boundaries",
"If true, the habitable zone is computed with optimistic boundaries per default "
"when an exoplanet system is created"
};
constexpr const char ExoplanetsDataFileName[] = "exoplanets_data.bin";
constexpr const char LookupTableFileName[] = "lookup.txt";
struct [[codegen::Dictionary(ExoplanetsModule)]] Parameters {
// [[codegen::verbatim(DataFolderInfo.description)]]
std::optional<std::string> dataFolder;
// [[codegen::verbatim(StarTextureInfo.description)]]
std::optional<std::string> starTexture;
// [[codegen::verbatim(NoDataTextureInfo.description)]]
std::optional<std::string> noDataTexture;
// [[codegen::verbatim(OrbitDiscTextureInfo.description)]]
std::optional<std::string> orbitDiscTexture;
// [[codegen::verbatim(HabitableZoneTextureInfo.description)]]
std::optional<std::string> habitableZoneTexture;
// [[codegen::verbatim(ShowComparisonCircleInfo.description)]]
std::optional<bool> showComparisonCircle;
// [[codegen::verbatim(ShowHabitableZoneInfo.description)]]
std::optional<bool> showHabitableZone;
// [[codegen::verbatim(UseOptimisticZoneInfo.description)]]
std::optional<bool> useOptimisticZone;
};
#include "exoplanetsmodule_codegen.cpp"
} // namespace
namespace openspace {
using namespace exoplanets;
ExoplanetsModule::ExoplanetsModule() : OpenSpaceModule(Name) {}
ExoplanetsModule::ExoplanetsModule()
: OpenSpaceModule(Name)
, _exoplanetsDataFolder(DataFolderInfo)
, _starTexturePath(StarTextureInfo)
, _noDataTexturePath(NoDataTextureInfo)
, _orbitDiscTexturePath(OrbitDiscTextureInfo)
, _habitableZoneTexturePath(HabitableZoneTextureInfo)
, _showComparisonCircle(ShowComparisonCircleInfo, false)
, _showHabitableZone(ShowHabitableZoneInfo, true)
, _useOptimisticZone(UseOptimisticZoneInfo, true)
{
_exoplanetsDataFolder.setReadOnly(true);
addProperty(_exoplanetsDataFolder);
addProperty(_starTexturePath);
addProperty(_noDataTexturePath);
addProperty(_orbitDiscTexturePath);
addProperty(_habitableZoneTexturePath);
addProperty(_showComparisonCircle);
addProperty(_showHabitableZone);
addProperty(_useOptimisticZone);
}
std::string ExoplanetsModule::exoplanetsDataPath() const {
return absPath(
fmt::format("{}/{}", _exoplanetsDataFolder, ExoplanetsDataFileName)
);
};
std::string ExoplanetsModule::lookUpTablePath() const {
return absPath(
fmt::format("{}/{}", _exoplanetsDataFolder, LookupTableFileName)
);
};
std::string ExoplanetsModule::starTexturePath() const {
return _starTexturePath;
}
std::string ExoplanetsModule::noDataTexturePath() const {
return _noDataTexturePath;
}
std::string ExoplanetsModule::orbitDiscTexturePath() const {
return _orbitDiscTexturePath;
}
std::string ExoplanetsModule::habitableZoneTexturePath() const {
return _habitableZoneTexturePath;
}
bool ExoplanetsModule::showComparisonCircle() const {
return _showComparisonCircle;
}
bool ExoplanetsModule::showHabitableZone() const {
return _showHabitableZone;
}
bool ExoplanetsModule::useOptimisticZone() const {
return _useOptimisticZone;
}
scripting::LuaLibrary ExoplanetsModule::luaLibrary() const {
scripting::LuaLibrary res;
@@ -83,7 +238,18 @@ scripting::LuaLibrary ExoplanetsModule::luaLibrary() const {
return res;
}
void ExoplanetsModule::internalInitialize(const ghoul::Dictionary&) {
void ExoplanetsModule::internalInitialize(const ghoul::Dictionary& dict) {
const Parameters p = codegen::bake<Parameters>(dict);
_exoplanetsDataFolder = p.dataFolder.value_or(_exoplanetsDataFolder);
_starTexturePath = p.starTexture.value_or(_starTexturePath);
_noDataTexturePath = p.noDataTexture.value_or(_noDataTexturePath);
_orbitDiscTexturePath = p.orbitDiscTexture.value_or(_orbitDiscTexturePath);
_habitableZoneTexturePath = p.habitableZoneTexture.value_or(_habitableZoneTexturePath);
_showComparisonCircle = p.showComparisonCircle.value_or(_showComparisonCircle);
_showHabitableZone = p.showHabitableZone.value_or(_showHabitableZone);
_useOptimisticZone = p.useOptimisticZone.value_or(_useOptimisticZone);
auto fTask = FactoryManager::ref().factory<Task>();
auto fRenderable = FactoryManager::ref().factory<Renderable>();
ghoul_assert(fTask, "No task factory existed");

View File

@@ -28,6 +28,8 @@
#include <openspace/util/openspacemodule.h>
#include <openspace/documentation/documentation.h>
#include <openspace/properties/scalar/boolproperty.h>
#include <openspace/properties/stringproperty.h>
namespace openspace {
@@ -38,11 +40,30 @@ public:
ExoplanetsModule();
virtual ~ExoplanetsModule() = default;
std::string exoplanetsDataPath() const;
std::string lookUpTablePath() const;
std::string starTexturePath() const;
std::string noDataTexturePath() const;
std::string orbitDiscTexturePath() const;
std::string habitableZoneTexturePath() const;
bool showComparisonCircle() const;
bool showHabitableZone() const;
bool useOptimisticZone() const;
scripting::LuaLibrary luaLibrary() const override;
std::vector<documentation::Documentation> documentations() const override;
protected:
void internalInitialize(const ghoul::Dictionary&) override;
void internalInitialize(const ghoul::Dictionary& dict) override;
properties::StringProperty _exoplanetsDataFolder;
properties::StringProperty _starTexturePath;
properties::StringProperty _noDataTexturePath;
properties::StringProperty _orbitDiscTexturePath;
properties::StringProperty _habitableZoneTexturePath;
properties::BoolProperty _showComparisonCircle;
properties::BoolProperty _showHabitableZone;
properties::BoolProperty _useOptimisticZone;
};
} // namespace openspace

View File

@@ -24,6 +24,7 @@
#include <modules/exoplanets/exoplanetshelper.h>
#include <openspace/engine/globals.h>
#include <openspace/engine/moduleengine.h>
#include <openspace/query/query.h>
#include <openspace/scene/scenegraphnode.h>
#include <openspace/scripting/scriptengine.h>
@@ -40,47 +41,42 @@
namespace {
constexpr const char _loggerCat[] = "ExoplanetsModule";
constexpr const char ExoplanetsGuiPath[] = "/Milky Way/Exoplanets/Exoplanet Systems/";
// Lua cannot handle backslashes, so replace these with forward slashes
std::string formatPathToLua(const std::string& path) {
std::string resPath = path;
std::replace(resPath.begin(), resPath.end(), '\\', '/');
return resPath;
}
} // namespace
namespace openspace::exoplanets::luascriptfunctions {
constexpr const char ExoplanetsGuiPath[] = "/Milky Way/Exoplanets/Exoplanet Systems/";
constexpr const char LookUpTablePath[] = "${SYNC}/http/exoplanets_data/2/lookup.txt";
constexpr const char ExoplanetsDataPath[] =
"${SYNC}/http/exoplanets_data/2/exoplanets_data.bin";
constexpr const char StarTextureFile[] = "${SYNC}/http/exoplanets_textures/2/sun.jpg";
constexpr const char NoDataTextureFile[] =
"${SYNC}/http/exoplanets_textures/2/grid-32.png";
constexpr const char DiscTextureFile[] =
"${SYNC}/http/exoplanets_textures/2/disc_bw_texture.png";
constexpr const char HabitableZoneTextureFile[] =
"${SYNC}/http/habitable_zone_textures/1/hot_to_cold_faded.png";
constexpr const float AU = static_cast<float>(distanceconstants::AstronomicalUnit);
constexpr const float SolarRadius = static_cast<float>(distanceconstants::SolarRadius);
constexpr const float JupiterRadius = static_cast<float>(distanceconstants::JupiterRadius);
ExoplanetSystem findExoplanetSystemInData(std::string_view starName) {
ExoplanetSystem system;
const ExoplanetsModule* module = global::moduleEngine->module<ExoplanetsModule>();
std::ifstream data(absPath(ExoplanetsDataPath), std::ios::in | std::ios::binary);
const std::string binPath = module->exoplanetsDataPath();
std::ifstream data(absPath(binPath), std::ios::in | std::ios::binary);
if (!data.good()) {
LERROR(fmt::format(
"Failed to open exoplanets data file: '{}'", absPath(ExoplanetsDataPath)
));
LERROR(fmt::format("Failed to open exoplanets data file: '{}'", binPath));
return ExoplanetSystem();
}
std::ifstream lut(absPath(LookUpTablePath));
const std::string lutPath = module->lookUpTablePath();
std::ifstream lut(absPath(lutPath));
if (!lut.good()) {
LERROR(fmt::format(
"Failed to open exoplanets look-up table: '{}'", absPath(LookUpTablePath)
));
LERROR(fmt::format("Failed to open exoplanets look-up table: '{}'", lutPath));
return ExoplanetSystem();
}
ExoplanetSystem system;
// 1. search lut for the starname and return the corresponding location
// 2. go to that location in the data file
// 3. read sizeof(exoplanet) bytes into an exoplanet object.
@@ -167,6 +163,8 @@ void createExoplanetSystem(const std::string& starName) {
return;
}
const ExoplanetsModule* module = global::moduleEngine->module<ExoplanetsModule>();
const glm::dvec3 starPos =
static_cast<glm::dvec3>(starPosInParsec) * distanceconstants::Parsec;
const glm::dmat3 exoplanetSystemRotation = computeSystemRotation(starPos);
@@ -182,6 +180,7 @@ void createExoplanetSystem(const std::string& starName) {
if (!std::isnan(bv)) {
const glm::vec3 color = starColor(bv);
const std::string starTexture = module->starTexturePath();
colorLayers =
"{"
"Identifier = 'StarColor',"
@@ -192,18 +191,17 @@ void createExoplanetSystem(const std::string& starName) {
"},"
"{"
"Identifier = 'StarTexture',"
"FilePath = " +
fmt::format("openspace.absPath('{}')", StarTextureFile) + ","
"FilePath = openspace.absPath('" + formatPathToLua(starTexture) + "'),"
"BlendMode = 'Color',"
"Enabled = true"
"}";
}
else {
const std::string noDataTexture = module->noDataTexturePath();
colorLayers =
"{"
"Identifier = 'NoDataStarTexture',"
"FilePath = " +
fmt::format("openspace.absPath('{}')", NoDataTextureFile) + ","
"FilePath = openspace.absPath('" + formatPathToLua(noDataTexture) + "'),"
"BlendMode = 'Color',"
"Enabled = true"
"}";
@@ -313,7 +311,6 @@ void createExoplanetSystem(const std::string& starName) {
const std::string planetNode = "{"
"Identifier = '" + planetIdentifier + "',"
"Parent = '" + starIdentifier + "',"
"Enabled = true,"
"Renderable = {"
"Type = 'RenderableGlobe',"
"Enabled = " + enabled + ","
@@ -342,7 +339,6 @@ void createExoplanetSystem(const std::string& starName) {
const std::string planetTrailNode = "{"
"Identifier = '" + planetIdentifier + "_Trail',"
"Parent = '" + starIdentifier + "',"
"Enabled = true,"
"Renderable = {"
"Type = 'RenderableTrailOrbit',"
"Period = " + std::to_string(planet.per) + ","
@@ -376,13 +372,16 @@ void createExoplanetSystem(const std::string& starName) {
const float lowerOffset = static_cast<float>(planet.aLower / planet.a);
const float upperOffset = static_cast<float>(planet.aUpper / planet.a);
const std::string discTexture = module->orbitDiscTexturePath();
const std::string discNode = "{"
"Identifier = '" + planetIdentifier + "_Disc',"
"Parent = '" + starIdentifier + "',"
"Enabled = true,"
"Renderable = {"
"Type = 'RenderableOrbitDisc',"
"Texture = openspace.absPath('" + DiscTextureFile + "'),"
"Texture = openspace.absPath('" +
formatPathToLua(discTexture) +
"'),"
"Size = " + std::to_string(semiMajorAxisInMeter) + ","
"Eccentricity = " + std::to_string(planet.ecc) + ","
"Offset = { " +
@@ -410,7 +409,6 @@ void createExoplanetSystem(const std::string& starName) {
}
}
float meanInclination = 0.f;
for (const ExoplanetDataEntry& p : system.planetsData) {
meanInclination += p.i;
@@ -419,14 +417,16 @@ void createExoplanetSystem(const std::string& starName) {
const glm::dmat4 rotation = computeOrbitPlaneRotationMatrix(meanInclination);
const glm::dmat3 meanOrbitPlaneRotationMatrix = static_cast<glm::dmat3>(rotation);
// 1 AU Size Comparison Ring
const std::string ringIdentifier = starIdentifier + "_1AU_Ring";
const std::string ring = "{"
"Identifier = '" + starIdentifier + "_1AU_Ring',"
bool isCircleEnabled = module->showComparisonCircle();
const std::string isCircleEnabledString = isCircleEnabled ? "true" : "false";
// 1 AU Size Comparison Circle
const std::string circle = "{"
"Identifier = '" + starIdentifier + "_1AU_Circle',"
"Parent = '" + starIdentifier + "',"
"Enabled = false,"
"Renderable = {"
"Type = 'RenderableRadialGrid',"
"Enabled = " + isCircleEnabledString + ","
"OuterRadius = " + std::to_string(AU) + ","
"CircleSegments = 64,"
"LineWidth = 2.0,"
@@ -438,13 +438,13 @@ void createExoplanetSystem(const std::string& starName) {
"}"
"},"
"GUI = {"
"Name = '1 AU Size Comparison Ring',"
"Name = '1 AU Size Comparison Circle',"
"Path = '" + guiPath + "'"
"}"
"}";
openspace::global::scriptEngine->queueScript(
"openspace.addSceneGraphNode(" + ring + ");",
"openspace.addSceneGraphNode(" + circle + ");",
scripting::ScriptEngine::RemoteScripting::Yes
);
@@ -463,16 +463,24 @@ void createExoplanetSystem(const std::string& starName) {
"the greenhouse effect would not be able to maintain surface temperature "
"above freezing anywhere on the planet.";
const std::string hzTexture = module->habitableZoneTexturePath();
bool isHzEnabled = module->showHabitableZone();
const std::string isHzEnabledString = isHzEnabled ? "true" : "false";
bool useOptimistic = module->useOptimisticZone();
const std::string useOptimisticString = useOptimistic ? "true" : "false";
const std::string zoneDiscNode = "{"
"Identifier = '" + starIdentifier + "_HZ_Disc',"
"Parent = '" + starIdentifier + "',"
"Enabled = true,"
"Renderable = {"
"Type = 'RenderableHabitableZone',"
"Texture = openspace.absPath('" + HabitableZoneTextureFile + "'),"
"Enabled = " + isHzEnabledString + ","
"Texture = openspace.absPath('" + formatPathToLua(hzTexture) + "'),"
"Luminosity = " + std::to_string(system.starData.luminosity) + ","
"EffectiveTemperature = " + std::to_string(system.starData.teff) + ","
"Optimistic = true,"
"Optimistic = " + useOptimisticString + ","
"Opacity = 0.07"
"},"
"Transform = {"
@@ -545,21 +553,25 @@ int removeExoplanetSystem(lua_State* L) {
}
std::vector<std::string> hostStarsWithSufficientData() {
const ExoplanetsModule* module = global::moduleEngine->module<ExoplanetsModule>();
const std::string lutPath = module->lookUpTablePath();
std::ifstream lookupTableFile(absPath(lutPath));
if (!lookupTableFile.good()) {
LERROR(fmt::format("Failed to open lookup table file '{}'", lutPath));
return {};
}
const std::string binPath = module->exoplanetsDataPath();
std::ifstream data(absPath(binPath), std::ios::in | std::ios::binary);
if (!data.good()) {
LERROR(fmt::format("Failed to open data file '{}'", binPath));
return {};
}
std::vector<std::string> names;
std::string line;
std::ifstream lookupTableFile(absPath(LookUpTablePath));
if (!lookupTableFile.good()) {
LERROR(fmt::format("Failed to open lookup table file '{}'", LookUpTablePath));
return {};
}
std::ifstream data(absPath(ExoplanetsDataPath), std::ios::in | std::ios::binary);
if (!data.good()) {
LERROR(fmt::format("Failed to open data file '{}'", ExoplanetsDataPath));
return {};
}
// Read number of lines
int nExoplanets = 0;
while (std::getline(lookupTableFile, line)) {

View File

@@ -308,10 +308,10 @@ namespace {
struct [[codegen::Dictionary(RenderableStars)]] Parameters {
// The path to the SPECK file containing information about the stars being rendered
std::string speckFile [[codegen::key("File")]];
std::filesystem::path speckFile [[codegen::key("File")]];
// [[codegen::verbatim(ColorTextureInfo.description)]]
std::string colorMap;
std::filesystem::path colorMap;
enum class ColorOption {
Color,
@@ -350,7 +350,7 @@ namespace {
std::string renderMethod;
// [[codegen::verbatim(PsfTextureInfo.description)]]
std::string texture;
std::filesystem::path texture;
// [[codegen::verbatim(SizeCompositionOptionInfo.description)]]
std::optional<std::string> sizeComposition;
@@ -434,11 +434,11 @@ RenderableStars::RenderableStars(const ghoul::Dictionary& dictionary)
addProperty(_opacity);
registerUpdateRenderBinFromOpacity();
_speckFile = absPath(p.speckFile);
_speckFile = p.speckFile.string();
_speckFile.onChange([&]() { _speckFileIsDirty = true; });
addProperty(_speckFile);
_colorTexturePath = absPath(p.colorMap);
_colorTexturePath = p.colorMap.string();
_colorTextureFile = std::make_unique<File>(_colorTexturePath);
/*_shapeTexturePath = absPath(dictionary.value<std::string>(
@@ -525,7 +525,7 @@ RenderableStars::RenderableStars(const ghoul::Dictionary& dictionary)
_renderingMethodOption = RenderOptionTexture;
}
_pointSpreadFunctionTexturePath = absPath(p.texture);
_pointSpreadFunctionTexturePath = absPath(p.texture.string());
_pointSpreadFunctionFile = std::make_unique<File>(_pointSpreadFunctionTexturePath);
_pointSpreadFunctionTexturePath.onChange([&]() {
_pointSpreadFunctionTextureIsDirty = true;
@@ -1237,13 +1237,13 @@ void RenderableStars::loadShapeTexture() {
*/
void RenderableStars::loadData() {
std::string _file = _speckFile;
if (!FileSys.fileExists(absPath(_file))) {
std::string file = absPath(_speckFile);
if (!FileSys.fileExists(file)) {
return;
}
std::string cachedFile = FileSys.cacheManager()->cachedFilename(
_file,
file,
ghoul::filesystem::CacheManager::Persistent::Yes
);
@@ -1255,7 +1255,7 @@ void RenderableStars::loadData() {
bool hasCachedFile = FileSys.fileExists(cachedFile);
if (hasCachedFile) {
LINFO(fmt::format("Cached file '{}' used for Speck file '{}'",
cachedFile, _file
cachedFile, file
));
bool success = loadCachedFile(cachedFile);
@@ -1263,15 +1263,15 @@ void RenderableStars::loadData() {
return;
}
else {
FileSys.cacheManager()->removeCacheFile(_file);
FileSys.cacheManager()->removeCacheFile(file);
// Intentional fall-through to the 'else' computation to generate the cache
// file for the next run
}
}
else {
LINFO(fmt::format("Cache for Speck file '{}' not found", _file));
LINFO(fmt::format("Cache for Speck file '{}' not found", file));
}
LINFO(fmt::format("Loading Speck file '{}'", _file));
LINFO(fmt::format("Loading Speck file '{}'", file));
readSpeckFile();

View File

@@ -481,7 +481,7 @@ void RenderablePlanetProjection::imageProjectGPU(
if (_geometry->hasProperty("Radius")) {
std::any r = _geometry->property("Radius")->get();
if (glm::vec3* radius = std::any_cast<glm::vec3>(&r)){
_fboProgramObject->setUniform(_fboUniformCache.radius, radius);
_fboProgramObject->setUniform(_fboUniformCache.radius, *radius);
}
}
else {

View File

@@ -135,8 +135,8 @@ void BasicVolumeRaycaster::preRaycast(const RaycastData& data,
int nClips = static_cast<int>(clipNormals.size());
program.setUniform("nClips_" + id, nClips);
program.setUniform("clipNormals_" + id, clipNormals.data(), nClips);
program.setUniform("clipOffsets_" + id, clipOffsets.data(), nClips);
program.setUniform("clipNormals_" + id, clipNormals);
program.setUniform("clipOffsets_" + id, clipOffsets);
program.setUniform("opacity_" + id, _opacity);
program.setUniform("rNormalization_" + id, _rNormalization);
program.setUniform("rUpperBound_" + id, _rUpperBound);

View File

@@ -101,11 +101,15 @@ void GenerateRawVolumeTask::perform(const Task::ProgressCallback& progressCallba
ghoul::lua::LuaState state;
ghoul::lua::runScript(state, _valueFunctionLua);
#if (defined(NDEBUG) || defined(DEBUG))
ghoul::lua::verifyStackSize(state, 1);
#endif
int functionReference = luaL_ref(state, LUA_REGISTRYINDEX);
#if (defined(NDEBUG) || defined(DEBUG))
ghoul::lua::verifyStackSize(state, 0);
#endif
glm::vec3 domainSize = _upperDomainBound - _lowerDomainBound;
@@ -117,14 +121,18 @@ void GenerateRawVolumeTask::perform(const Task::ProgressCallback& progressCallba
glm::vec3 coord = _lowerDomainBound +
glm::vec3(cell) / glm::vec3(_dimensions) * domainSize;
#if (defined(NDEBUG) || defined(DEBUG))
ghoul::lua::verifyStackSize(state, 0);
#endif
lua_rawgeti(state, LUA_REGISTRYINDEX, functionReference);
lua_pushnumber(state, coord.x);
lua_pushnumber(state, coord.y);
lua_pushnumber(state, coord.z);
#if (defined(NDEBUG) || defined(DEBUG))
ghoul::lua::verifyStackSize(state, 4);
#endif
if (lua_pcall(state, 3, 1, 0) != LUA_OK) {
return;

View File

@@ -167,6 +167,11 @@ ModuleConfigurations = {
},
Space = {
ShowExceptions = false
},
Exoplanets = {
ShowComparisonCircle = false,
ShowHabitableZone = true,
UseOptimisticZone = true
}
}

View File

@@ -0,0 +1,43 @@
-- This script gets two parameters in its global scope:
-- filename: The full path for the file that was dropped on the application.
-- Example: C:/OpenSpace/openspace.cfg
-- basename: Only the name of the actual file with extension, but without the full rest
-- of the path.
-- Example: openspace.cfg
-- extension: The extention of the file
-- Example: .cfg
--
-- From this script, we need to return the script that we want to be executed in response
-- to the drag event. If we don't want anything to happen, don't return anything or
-- return an empty string
if filename == nil or filename == "" or
basename == nil or basename == "" or
extension == nil or extension == "" then
do return "" end
end
-- Lua doesn't enjoy \ that are used by Windows extensively. So we convert all \ into /
filename = filename:gsub("\\", "/")
basename = basename:gsub("\\", "/")
basename_without_extension = basename:sub(0, #basename - extension:len())
is_image_file = function(extension)
return extension == ".png" or extension == ".jpg" or extension == ".jpeg" or
extension == ".tif" or extension == ".tga" or extension == ".bmp" or
extension == ".psd" or extension == ".gif" or extension == ".hdr" or
extension == ".pic" or extension == ".pnm"
end
if is_image_file(extension) then
identifier = basename_without_extension:gsub(" ", "_")
return [[openspace.addScreenSpaceRenderable({
Identifier = "]] .. identifier .. [[",
Type = "ScreenSpaceImageLocal",
TexturePath = "]] .. filename .. [["
});]]
elseif extension == ".asset" then
return [[openspace.asset.add("]] .. filename .. [[")]]
elseif extension == ".osrec" or extension == ".osrectxt" then
return [[openspace.sessionRecording.startPlayback("]] .. basename .. [[")]]
end

View File

@@ -71,14 +71,18 @@ std::string to_string(const openspace::documentation::TestResult& value) {
}
else {
std::stringstream stream;
stream << "Failure." << '\n';
stream << "Specification Failure. ";
for (const TestResult::Offense& offense : value.offenses) {
stream << " " << ghoul::to_string(offense) << '\n';
stream << fmt::format(" {}", ghoul::to_string(offense));
if (!offense.explanation.empty()) {
stream << fmt::format(" ({})", offense.explanation);
}
stream << '\n';
}
for (const TestResult::Warning& warning : value.warnings) {
stream << " " << ghoul::to_string(warning) << '\n';
stream << fmt::format(" {}\n", ghoul::to_string(warning));
}
return stream.str();
@@ -129,17 +133,26 @@ namespace openspace::documentation {
const std::string DocumentationEntry::Wildcard = "*";
//std::string concatenate(const std::vector<TestResult::Offense>& offenses) {
// std::string result = "Error in specification (";
// for (const TestResult::Offense& o : offenses) {
// if (o.explanation.empty()) {
// result += fmt::format("{} ({}), ", o.offender, ghoul::to_string(o.reason));
// }
// else {
// result += fmt::format("{} ({}: {}), ", o.offender, ghoul::to_string(o.reason), o.explanation);
// }
// }
// result.pop_back();
// result.back() = ')';
// return result;
//}
SpecificationError::SpecificationError(TestResult res, std::string comp)
: ghoul::RuntimeError("Error in specification", std::move(comp))
, result(std::move(res))
{
ghoul_assert(!result.success, "Result's success must be false");
message += " (";
for (const TestResult::Offense& o : result.offenses) {
message += o.offender + ',';
}
message.back() = ')';
}
DocumentationEntry::DocumentationEntry(std::string k, std::shared_ptr<Verifier> v,

View File

@@ -27,6 +27,7 @@
#include <openspace/documentation/documentationengine.h>
#include <ghoul/misc/misc.h>
#include <algorithm>
#include <filesystem>
namespace openspace::documentation {
@@ -177,6 +178,121 @@ std::string StringVerifier::type() const {
return "String";
}
TestResult FileVerifier::operator()(const ghoul::Dictionary& dict,
const std::string& key) const
{
TestResult res = StringVerifier::operator()(dict, key);
if (!res.success) {
return res;
}
std::string file = dict.value<std::string>(key);
if (!std::filesystem::exists(file) || !std::filesystem::is_regular_file(file)) {
res.success = false;
TestResult::Offense off;
off.offender = key;
off.reason = TestResult::Offense::Reason::Verification;
off.explanation = "File did not exist";
res.offenses.push_back(off);
}
return res;
}
std::string FileVerifier::type() const {
return "File";
}
TestResult DirectoryVerifier::operator()(const ghoul::Dictionary& dict,
const std::string& key) const
{
TestResult res = StringVerifier::operator()(dict, key);
if (!res.success) {
return res;
}
std::string dir = dict.value<std::string>(key);
if (!std::filesystem::exists(dir) || !std::filesystem::is_directory(dir)) {
res.success = false;
TestResult::Offense off;
off.offender = key;
off.reason = TestResult::Offense::Reason::Verification;
off.explanation = "Directory did not exist";
res.offenses.push_back(off);
}
return res;
}
std::string DirectoryVerifier::type() const {
return "Directory";
}
TestResult Color3Verifier::operator()(const ghoul::Dictionary& dictionary,
const std::string& key) const
{
TestResult res = Vector3Verifier<double>::operator()(dictionary, key);
if (!res.success) {
return res;
}
glm::dvec3 values = dictionary.value<glm::dvec3>(key);
if (values.x < 0.0 || values.x > 1.0) {
res.success = false;
res.offenses.push_back({ key + ".x", TestResult::Offense::Reason::Verification });
}
if (values.y < 0.0 || values.y > 1.0) {
res.success = false;
res.offenses.push_back({ key + ".y", TestResult::Offense::Reason::Verification });
}
if (values.z < 0.0 || values.z > 1.0) {
res.success = false;
res.offenses.push_back({ key + ".z", TestResult::Offense::Reason::Verification });
}
return res;
}
std::string Color3Verifier::type() const {
return std::string("Color3");
}
TestResult Color4Verifier::operator()(const ghoul::Dictionary& dictionary,
const std::string& key) const
{
TestResult res = Vector4Verifier<double>::operator()(dictionary, key);
if (!res.success) {
return res;
}
std::vector<double> values = dictionary.value<std::vector<double>>(key);
if (values[0] < 0.0 || values[0] > 1.0) {
res.success = false;
res.offenses.push_back({ key + ".x", TestResult::Offense::Reason::Verification });
}
if (values[1] < 0.0 || values[1] > 1.0) {
res.success = false;
res.offenses.push_back({ key + ".y", TestResult::Offense::Reason::Verification });
}
if (values[2] < 0.0 || values[2] > 1.0) {
res.success = false;
res.offenses.push_back({ key + ".z", TestResult::Offense::Reason::Verification });
}
if (values[3] < 0.0 || values[3] > 1.0) {
res.success = false;
res.offenses.push_back({ key + ".a", TestResult::Offense::Reason::Verification });
}
return res;
}
std::string Color4Verifier::type() const {
return std::string("Color4");
}
template <>
TestResult TemplateVerifier<glm::ivec2>::operator()(const ghoul::Dictionary& dict,
const std::string& key) const

View File

@@ -58,7 +58,20 @@ void ModuleEngine::initialize(
if (it != moduleConfigurations.end()) {
configuration = it->second;
}
m->initialize(configuration);
try {
m->initialize(configuration);
}
catch (const documentation::SpecificationError& e) {
//LFATALC(e.component, e.message);
for (const documentation::TestResult::Offense& o : e.result.offenses) {
LERRORC(e.component, o.offender + ": " + ghoul::to_string(o.reason));
}
for (const documentation::TestResult::Warning& w : e.result.warnings) {
LWARNINGC(e.component, w.offender + ": " + ghoul::to_string(w.reason));
}
throw;
}
addPropertySubOwner(m);
}

View File

@@ -71,7 +71,6 @@
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/font/fontmanager.h>
#include <ghoul/font/fontrenderer.h>
#include <ghoul/logging/consolelog.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/logging/visualstudiooutputlog.h>
#include <ghoul/misc/profiling.h>
@@ -83,6 +82,7 @@
#include <ghoul/systemcapabilities/openglcapabilitiescomponent.h>
#include <glbinding/glbinding.h>
#include <glbinding-aux/types_to_string.h>
#include <filesystem>
#include <future>
#include <numeric>
#include <sstream>
@@ -234,7 +234,6 @@ void OpenSpaceEngine::initialize() {
using ImmediateFlush = ghoul::logging::LogManager::ImmediateFlush;
ghoul::logging::LogManager::initialize(level, ImmediateFlush(immediateFlush));
LogMgr.addLog(std::make_unique<ghoul::logging::ConsoleLog>());
for (const ghoul::Dictionary& log : global::configuration->logging.logs) {
try {
@@ -1444,6 +1443,52 @@ void OpenSpaceEngine::touchExitCallback(TouchInput input) {
}
}
void OpenSpaceEngine::handleDragDrop(const std::string& file) {
std::filesystem::path f(file);
ghoul::lua::LuaState s(ghoul::lua::LuaState::IncludeStandardLibrary::Yes);
std::string absolutePath = absPath("${SCRIPTS}/drag_drop_handler.lua");
int status = luaL_loadfile(s, absolutePath.c_str());
if (status != LUA_OK) {
std::string error = lua_tostring(s, -1);
LERROR(error);
return;
}
ghoul::lua::push(s, file);
lua_setglobal(s, "filename");
std::string basename = f.filename().string();
ghoul::lua::push(s, basename);
lua_setglobal(s, "basename");
std::string extension = f.extension().string();
std::transform(
extension.begin(), extension.end(),
extension.begin(),
[](char c) { return static_cast<char>(::tolower(c)); }
);
ghoul::lua::push(s, extension);
lua_setglobal(s, "extension");
status = lua_pcall(s, 0, 1, 0);
if (status != LUA_OK) {
std::string error = lua_tostring(s, -1);
LERROR(error);
return;
}
if (lua_isnil(s, -1)) {
LWARNING(fmt::format("Unhandled file dropped: {}", file));
return;
}
std::string script = ghoul::lua::value<std::string>(s);
global::scriptEngine->queueScript(
script,
scripting::ScriptEngine::RemoteScripting::Yes
);
}
std::vector<std::byte> OpenSpaceEngine::encode() {
ZoneScoped

View File

@@ -45,6 +45,9 @@ SceneGraphNode* sceneGraphNode(const std::string& name) {
const Renderable* renderable(const std::string& name) {
SceneGraphNode* node = sceneGraphNode(name);
if (!node) {
return nullptr;
}
return node->renderable();
}

View File

@@ -520,9 +520,8 @@ bool Asset::initialize() {
loader()->callOnInitialize(this);
}
catch (const ghoul::lua::LuaRuntimeException& e) {
LERROR(fmt::format(
"Failed to initialize asset {}; {}: {}", id(), e.component, e.message
));
LERROR(fmt::format("Failed to initialize asset {}", id()));
LERROR(fmt::format("{}: {}", e.component, e.message));
// TODO: rollback;
setState(State::InitializationFailed);
return false;

View File

@@ -648,10 +648,10 @@ int addSceneGraphNode(lua_State* L) {
global::renderEngine->scene()->initializeNode(node);
}
catch (const documentation::SpecificationError& e) {
LERRORC("Scene", ghoul::to_string(e.result));
return ghoul::lua::luaError(
L,
fmt::format("Error loading scene graph node: {}: {}",
e.what(), ghoul::to_string(e.result))
fmt::format("Error loading scene graph node: {}", e.what())
);
}
catch (const ghoul::RuntimeError& e) {