mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-05-06 11:29:55 -05:00
Make it possible to add two copies of the sky browser, which will make it possible to display many copies in a dome environment and have an interactive copy on the master node
This commit is contained in:
@@ -105,6 +105,12 @@ protected:
|
||||
virtual void bindTexture() = 0;
|
||||
virtual void unbindTexture();
|
||||
|
||||
glm::vec3 sphericalToRae(glm::vec3 spherical) const;
|
||||
glm::vec3 raeToSpherical(glm::vec3 rae) const;
|
||||
glm::vec3 cartesianToSpherical(const glm::vec3& cartesian) const;
|
||||
glm::vec3 sphericalToCartesian(glm::vec3 spherical) const;
|
||||
glm::vec3 sanitizeSphericalCoordinates(glm::vec3 spherical) const;
|
||||
|
||||
properties::BoolProperty _enabled;
|
||||
properties::BoolProperty _usePerspectiveProjection;
|
||||
properties::BoolProperty _useRadiusAzimuthElevation;
|
||||
|
||||
@@ -72,6 +72,10 @@ public:
|
||||
private:
|
||||
properties::DoubleProperty _animationSpeed;
|
||||
properties::FloatProperty _textureQuality;
|
||||
properties::BoolProperty _renderCopy1;
|
||||
properties::Vec3Property _copyPosition1;
|
||||
properties::BoolProperty _renderCopy2;
|
||||
properties::Vec3Property _copyPosition2;
|
||||
|
||||
void bindTexture() override;
|
||||
|
||||
|
||||
@@ -54,12 +54,50 @@ namespace {
|
||||
"frame rate."
|
||||
};
|
||||
|
||||
constexpr const openspace::properties::Property::PropertyInfo RenderCopy1Info = {
|
||||
"RenderCopy1",
|
||||
"Render A Copy Of The Sky Browser",
|
||||
"Render a copy of this sky browser at an additional position. This copy will not "
|
||||
"be interactive."
|
||||
};
|
||||
|
||||
constexpr const openspace::properties::Property::PropertyInfo CopyPosition1Info = {
|
||||
"CopyPosition1",
|
||||
"Position Of First Copy Of Sky Browser",
|
||||
"The (radius, azimuth, elevation) position where the copy will be placed. "
|
||||
};
|
||||
|
||||
constexpr const openspace::properties::Property::PropertyInfo RenderCopy2Info = {
|
||||
"RenderCopy2",
|
||||
"Render An Additional Copy Of The Sky Browser",
|
||||
"Render a copy of this sky browser at an additional position. This copy will not "
|
||||
"be interactive."
|
||||
};
|
||||
|
||||
constexpr const openspace::properties::Property::PropertyInfo CopyPosition2Info = {
|
||||
"CopyPosition2",
|
||||
"Position Of Second Copy Of Sky Browser",
|
||||
"The (radius, azimuth, elevation) position where the copy will be placed. "
|
||||
};
|
||||
|
||||
struct [[codegen::Dictionary(ScreenSpaceSkyBrowser)]] Parameters {
|
||||
// [[codegen::verbatim(AnimationSpeedInfo.description)]]
|
||||
std::optional<double> animationSpeed;
|
||||
|
||||
// [[codegen::verbatim(TextureQualityInfo.description)]]
|
||||
std::optional<float> textureQuality;
|
||||
|
||||
// [[codegen::verbatim(RenderCopy1Info.description)]]
|
||||
std::optional<bool> renderCopy1;
|
||||
|
||||
// [[codegen::verbatim(CopyPosition1Info.description)]]
|
||||
std::optional<glm::vec3> copyPosition1;
|
||||
|
||||
// [[codegen::verbatim(RenderCopy2Info.description)]]
|
||||
std::optional<bool> renderCopy2;
|
||||
|
||||
// [[codegen::verbatim(CopyPosition2Info.description)]]
|
||||
std::optional<glm::vec3> copyPosition2;
|
||||
};
|
||||
|
||||
#include "screenspaceskybrowser_codegen.cpp"
|
||||
@@ -87,11 +125,23 @@ glm::ivec3 randomBorderColor(glm::ivec3 highlight) {
|
||||
|
||||
namespace openspace {
|
||||
|
||||
ScreenSpaceSkyBrowser::ScreenSpaceSkyBrowser(const ghoul::Dictionary& dictionary)
|
||||
ScreenSpaceSkyBrowser::ScreenSpaceSkyBrowser(const ghoul::Dictionary& dictionary)
|
||||
: ScreenSpaceRenderable(dictionary)
|
||||
, WwtCommunicator(dictionary)
|
||||
, _animationSpeed(AnimationSpeedInfo, 5.0, 0.1, 10.0)
|
||||
, _textureQuality(TextureQualityInfo, 1.f, 0.25f, 1.f)
|
||||
, _renderCopy1(RenderCopy1Info)
|
||||
, _copyPosition1(CopyPosition1Info,
|
||||
glm::vec3(2.1f, 0.f, 0.f),
|
||||
glm::vec3(-4.f, -4.f, 0.f),
|
||||
glm::vec3(4.f, 4.f, 10.f)
|
||||
)
|
||||
, _renderCopy2(RenderCopy2Info)
|
||||
, _copyPosition2(CopyPosition2Info,
|
||||
glm::vec3(2.1f, 0.f, 0.f),
|
||||
glm::vec3(-4.f, -4.f, 0.f),
|
||||
glm::vec3(4.f, 4.f, 10.f)
|
||||
)
|
||||
{
|
||||
_identifier = makeUniqueIdentifier(_identifier);
|
||||
|
||||
@@ -99,11 +149,19 @@ ScreenSpaceSkyBrowser::ScreenSpaceSkyBrowser(const ghoul::Dictionary& dictionary
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
_textureQuality = p.textureQuality.value_or(_textureQuality);
|
||||
_animationSpeed = p.animationSpeed.value_or(_animationSpeed);
|
||||
_renderCopy1 = p.renderCopy1.value_or(_renderCopy1);
|
||||
_copyPosition1 = p.copyPosition1.value_or(_copyPosition1);
|
||||
_renderCopy2 = p.renderCopy1.value_or(_renderCopy2);
|
||||
_copyPosition2 = p.copyPosition1.value_or(_copyPosition2);
|
||||
|
||||
addProperty(_url);
|
||||
addProperty(_browserPixeldimensions);
|
||||
addProperty(_reload);
|
||||
addProperty(_textureQuality);
|
||||
addProperty(_renderCopy1);
|
||||
addProperty(_copyPosition1);
|
||||
addProperty(_renderCopy2);
|
||||
addProperty(_copyPosition2);
|
||||
|
||||
_textureQuality.onChange([this]() {
|
||||
_textureDimensionsIsDirty = true;
|
||||
@@ -209,8 +267,26 @@ void ScreenSpaceSkyBrowser::render() {
|
||||
scaleMatrix()
|
||||
);
|
||||
|
||||
// scale and translation probably
|
||||
//if(global::windowDelegate->isMaster() && property)
|
||||
// Render a copy that is not interactive
|
||||
if (_renderCopy1) {
|
||||
glm::vec3 spherical = sphericalToCartesian(raeToSpherical(_copyPosition1));
|
||||
draw(
|
||||
globalRotationMatrix() *
|
||||
glm::translate(glm::mat4(1.f), spherical)*
|
||||
localRotationMatrix() *
|
||||
scaleMatrix()
|
||||
);
|
||||
}
|
||||
// Render a copy that is not interactive
|
||||
if (_renderCopy2) {
|
||||
glm::vec3 spherical = sphericalToCartesian(raeToSpherical(_copyPosition2));
|
||||
draw(
|
||||
globalRotationMatrix() *
|
||||
glm::translate(glm::mat4(1.f), spherical) *
|
||||
localRotationMatrix() *
|
||||
scaleMatrix()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -142,84 +142,6 @@ namespace {
|
||||
return glm::mod(value - min, max - min) + min;
|
||||
}
|
||||
|
||||
glm::vec3 sanitizeSphericalCoordinates(glm::vec3 spherical) {
|
||||
const float r = spherical.x;
|
||||
float phi = spherical.z;
|
||||
|
||||
// Sanitize coordinates.
|
||||
float theta = wrap(spherical.y, 0.f, glm::two_pi<float>());
|
||||
if (theta > glm::pi<float>()) {
|
||||
theta = glm::two_pi<float>() - theta;
|
||||
phi += glm::pi<float>();
|
||||
}
|
||||
|
||||
return glm::vec3(r, theta, phi);
|
||||
}
|
||||
|
||||
glm::vec3 sphericalToCartesian(glm::vec3 spherical) {
|
||||
// First convert to ISO convention spherical coordinates according to
|
||||
// https://en.wikipedia.org/wiki/Spherical_coordinate_system
|
||||
// (radius, theta, phi), where theta is the polar angle from the z axis,
|
||||
// and phi is the azimuth.
|
||||
|
||||
const glm::vec3 sanitized = sanitizeSphericalCoordinates(std::move(spherical));
|
||||
const float x = sanitized[0] * sin(sanitized[1]) * cos(sanitized[2]);
|
||||
const float y = sanitized[0] * sin(sanitized[1]) * sin(sanitized[2]);
|
||||
const float z = sanitized[0] * cos(sanitized[1]);
|
||||
|
||||
// Now, convert rotate the coordinate system, so that z maps to y,
|
||||
// and y maps to -z. We want the pole to be in y instead of z.
|
||||
return glm::vec3(x, -z, y);
|
||||
}
|
||||
|
||||
glm::vec3 cartesianToSpherical(const glm::vec3& cartesian) {
|
||||
// Rotate cartesian coordinates.
|
||||
glm::vec3 rotated = glm::vec3(cartesian.x, cartesian.z, -cartesian.y);
|
||||
|
||||
const float r = sqrt(
|
||||
pow(rotated.x, 2.f) + pow(rotated.y, 2.f) + pow(rotated.z, 2.f)
|
||||
);
|
||||
const float theta = acos(rotated.z/r);
|
||||
const float phi = atan2(rotated.y, rotated.x);
|
||||
return sanitizeSphericalCoordinates(glm::vec3(r, theta, phi));
|
||||
}
|
||||
|
||||
// Radius, azimiuth, elevation to spherical coordinates.
|
||||
glm::vec3 raeToSpherical(glm::vec3 rae) {
|
||||
//return rae;
|
||||
const float r = rae.x;
|
||||
|
||||
// Polar angle, theta, is elevation + pi/2.
|
||||
const float theta = rae.z + glm::half_pi<float>();
|
||||
|
||||
// Azimuth in ISO spherical coordiantes (phi) is angle from x,
|
||||
// as opposed to from negative y on screen.
|
||||
const float phi = rae.y - glm::half_pi<float>();
|
||||
|
||||
return glm::vec3(r, theta, phi);
|
||||
}
|
||||
|
||||
// Spherical coordinates to radius, azimuth and elevation.
|
||||
glm::vec3 sphericalToRae(glm::vec3 spherical) {
|
||||
//return spherical;
|
||||
const float r = spherical.x;
|
||||
|
||||
// Azimuth on screen is angle from negative y, as opposed to from x.
|
||||
float azimuth = spherical.z + glm::half_pi<float>();
|
||||
|
||||
// Elevation is polar angle - pi/2
|
||||
float elevation = wrap(
|
||||
spherical.y - glm::half_pi<float>(),
|
||||
-glm::pi<float>(),
|
||||
glm::pi<float>()
|
||||
);
|
||||
|
||||
return glm::vec3(
|
||||
r,
|
||||
wrap(azimuth, -glm::pi<float>(), glm::pi<float>()),
|
||||
wrap(elevation, -glm::pi<float>(), glm::pi<float>())
|
||||
);
|
||||
}
|
||||
|
||||
struct [[codegen::Dictionary(ScreenSpaceRenderable)]] Parameters {
|
||||
// The type of the Screenspace renderable that is to be created. The available
|
||||
@@ -668,4 +590,84 @@ void ScreenSpaceRenderable::draw(glm::mat4 modelTransform) {
|
||||
|
||||
void ScreenSpaceRenderable::unbindTexture() {}
|
||||
|
||||
glm::vec3 ScreenSpaceRenderable::sanitizeSphericalCoordinates(glm::vec3 spherical) const {
|
||||
const float r = spherical.x;
|
||||
float phi = spherical.z;
|
||||
|
||||
// Sanitize coordinates.
|
||||
float theta = wrap(spherical.y, 0.f, glm::two_pi<float>());
|
||||
if (theta > glm::pi<float>()) {
|
||||
theta = glm::two_pi<float>() - theta;
|
||||
phi += glm::pi<float>();
|
||||
}
|
||||
|
||||
return glm::vec3(r, theta, phi);
|
||||
}
|
||||
|
||||
glm::vec3 ScreenSpaceRenderable::sphericalToCartesian(glm::vec3 spherical) const {
|
||||
// First convert to ISO convention spherical coordinates according to
|
||||
// https://en.wikipedia.org/wiki/Spherical_coordinate_system
|
||||
// (radius, theta, phi), where theta is the polar angle from the z axis,
|
||||
// and phi is the azimuth.
|
||||
|
||||
const glm::vec3 sanitized = sanitizeSphericalCoordinates(std::move(spherical));
|
||||
const float x = sanitized[0] * sin(sanitized[1]) * cos(sanitized[2]);
|
||||
const float y = sanitized[0] * sin(sanitized[1]) * sin(sanitized[2]);
|
||||
const float z = sanitized[0] * cos(sanitized[1]);
|
||||
|
||||
// Now, convert rotate the coordinate system, so that z maps to y,
|
||||
// and y maps to -z. We want the pole to be in y instead of z.
|
||||
return glm::vec3(x, -z, y);
|
||||
}
|
||||
|
||||
glm::vec3 ScreenSpaceRenderable::cartesianToSpherical(const glm::vec3& cartesian) const {
|
||||
// Rotate cartesian coordinates.
|
||||
glm::vec3 rotated = glm::vec3(cartesian.x, cartesian.z, -cartesian.y);
|
||||
|
||||
const float r = sqrt(
|
||||
pow(rotated.x, 2.f) + pow(rotated.y, 2.f) + pow(rotated.z, 2.f)
|
||||
);
|
||||
const float theta = acos(rotated.z / r);
|
||||
const float phi = atan2(rotated.y, rotated.x);
|
||||
return sanitizeSphericalCoordinates(glm::vec3(r, theta, phi));
|
||||
}
|
||||
|
||||
// Radius, azimiuth, elevation to spherical coordinates.
|
||||
glm::vec3 ScreenSpaceRenderable::raeToSpherical(glm::vec3 rae) const {
|
||||
//return rae;
|
||||
const float r = rae.x;
|
||||
|
||||
// Polar angle, theta, is elevation + pi/2.
|
||||
const float theta = rae.z + glm::half_pi<float>();
|
||||
|
||||
// Azimuth in ISO spherical coordiantes (phi) is angle from x,
|
||||
// as opposed to from negative y on screen.
|
||||
const float phi = rae.y - glm::half_pi<float>();
|
||||
|
||||
return glm::vec3(r, theta, phi);
|
||||
}
|
||||
|
||||
// Spherical coordinates to radius, azimuth and elevation.
|
||||
glm::vec3 ScreenSpaceRenderable::sphericalToRae(glm::vec3 spherical) const {
|
||||
//return spherical;
|
||||
const float r = spherical.x;
|
||||
|
||||
// Azimuth on screen is angle from negative y, as opposed to from x.
|
||||
float azimuth = spherical.z + glm::half_pi<float>();
|
||||
|
||||
// Elevation is polar angle - pi/2
|
||||
float elevation = wrap(
|
||||
spherical.y - glm::half_pi<float>(),
|
||||
-glm::pi<float>(),
|
||||
glm::pi<float>()
|
||||
);
|
||||
|
||||
return glm::vec3(
|
||||
r,
|
||||
wrap(azimuth, -glm::pi<float>(), glm::pi<float>()),
|
||||
wrap(elevation, -glm::pi<float>(), glm::pi<float>())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
Reference in New Issue
Block a user