mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-05-03 09:20:26 -05:00
Merge branch 'master' into feature/min-max-distance
This commit is contained in:
@@ -91,7 +91,7 @@ function (get_module_attribute_supported path result)
|
||||
endfunction()
|
||||
|
||||
|
||||
# Returns the path for the 'module_name'. If the module has not been seen before by
|
||||
# Returns the path for the 'module_name'. If the module has not been seen before by
|
||||
# get_individual_modules, an empty string is returned
|
||||
function (find_path_for_module module_name module_names module_paths result)
|
||||
list(FIND module_names ${module_name} i)
|
||||
@@ -121,7 +121,7 @@ function (get_recursive_dependencies module_name module_path module_names module
|
||||
"${module_names}" "${module_paths}"
|
||||
res
|
||||
)
|
||||
# 1. We add "base" to the list of dependencies as we always want it
|
||||
# 1. We add "base" to the list of dependencies as we always want it
|
||||
# 2. We add dependencies in this order such that when we later traverse
|
||||
# this list, we automatically get them in the correct order (meaning
|
||||
# that we include a dependency first)
|
||||
@@ -241,7 +241,7 @@ foreach (val RANGE ${enabled_module_count})
|
||||
set(dependencies ${dependencies} ${deps})
|
||||
endforeach()
|
||||
|
||||
# We can remove the duplicates here. We constructed the list such that nested
|
||||
# We can remove the duplicates here. We constructed the list such that nested
|
||||
# dependencies are order left to right. REMOVE_DUPLICATES will keep the left most
|
||||
# value in the case of duplicates, so that will still work
|
||||
list(REMOVE_DUPLICATES dependencies)
|
||||
|
||||
@@ -38,7 +38,7 @@ source_group("Source Files" FILES ${SOURCE_FILES})
|
||||
|
||||
set(SHADER_FILES
|
||||
shaders/atmosphere_common.glsl
|
||||
shaders/atmosphere_deferred_vs.glsl
|
||||
shaders/atmosphere_deferred_vs.glsl
|
||||
shaders/atmosphere_deferred_fs.glsl
|
||||
shaders/calculation_gs.glsl
|
||||
shaders/calculation_vs.glsl
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
/*****************************************************************************************
|
||||
* Modified parts of the code (4D texture mechanism, analytical transmittance etc) *
|
||||
* from Eric Bruneton is used in the following code. *
|
||||
* from Eric Bruneton is used in the following code. *
|
||||
****************************************************************************************/
|
||||
|
||||
/**
|
||||
@@ -67,17 +67,17 @@ const float ATM_EPSILON = 1.0;
|
||||
// Calculate the distance of the ray starting at x (height r) until the planet's ground
|
||||
// or top of atmosphere
|
||||
// r := || vec(x) || e [0, Rt]
|
||||
// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r
|
||||
// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r
|
||||
float rayDistance(float r, float mu, float Rt, float Rg) {
|
||||
// The light ray starting at the observer in/on the atmosphere can have to possible end
|
||||
// points: the top of the atmosphere or the planet ground. So the shortest path is the
|
||||
// one we are looking for, otherwise we may be passing through the ground
|
||||
|
||||
|
||||
// cosine law
|
||||
float atmRadiusEps2 = (Rt + ATM_EPSILON) * (Rt + ATM_EPSILON);
|
||||
float mu2 = mu * mu;
|
||||
float r2 = r * r;
|
||||
float rayDistanceAtmosphere = -r * mu + sqrt(r2 * (mu2 - 1.0) + atmRadiusEps2);
|
||||
float rayDistanceAtmosphere = -r * mu + sqrt(r2 * (mu2 - 1.0) + atmRadiusEps2);
|
||||
float delta = r2 * (mu2 - 1.0) + Rg*Rg;
|
||||
|
||||
// Ray may be hitting ground
|
||||
@@ -108,7 +108,7 @@ void unmappingMuMuSunNu(float r, vec4 dhdH, int SAMPLES_MU, float Rg, float Rt,
|
||||
// Pre-calculations
|
||||
float r2 = r * r;
|
||||
float Rg2 = Rg * Rg;
|
||||
|
||||
|
||||
float halfSAMPLE_MU = float(SAMPLES_MU) / 2.0;
|
||||
// If the (vec(x) dot vec(v))/r is negative, i.e., the light ray has great probability
|
||||
// to touch the ground, we obtain mu considering the geometry of the ground
|
||||
@@ -130,7 +130,7 @@ void unmappingMuMuSunNu(float r, vec4 dhdH, int SAMPLES_MU, float Rg, float Rt,
|
||||
// cosine law: Rt^2 = r^2 + d^2 - 2rdcos(pi-theta) where cosine(theta) = mu
|
||||
mu = (Rt*Rt - r2 - d * d) / (2.0 * r * d);
|
||||
}
|
||||
|
||||
|
||||
float modValueMuSun = mod(fragment.x, float(SAMPLES_MU_S)) / (float(SAMPLES_MU_S) - 1.0);
|
||||
// The following mapping is different from the paper. See Collienne for an details.
|
||||
muSun = tan((2.0 * modValueMuSun - 1.0 + 0.26) * 1.1) / tan(1.26 * 1.1);
|
||||
@@ -148,7 +148,7 @@ vec3 transmittance(sampler2D tex, float r, float mu, float Rg, float Rt) {
|
||||
float u_r = sqrt((r - Rg) / (Rt - Rg));
|
||||
// See Collienne to understand the mapping
|
||||
float u_mu = atan((mu + 0.15) / 1.15 * tan(1.5)) / 1.5;
|
||||
|
||||
|
||||
return texture(tex, vec2(u_mu, u_r)).rgb;
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ vec3 transmittance(sampler2D tex, float r, float mu, float d, float Rg, float Rt
|
||||
// Here we use the transmittance property: T(x,v) = T(x,d)*T(d,v) to, given a distance
|
||||
// d, calculates that transmittance along that distance starting in x (height r):
|
||||
// T(x,d) = T(x,v)/T(d,v).
|
||||
//
|
||||
//
|
||||
// From cosine law: c^2 = a^2 + b^2 - 2*a*b*cos(ab)
|
||||
float ri = sqrt(d * d + r * r + 2.0 * r * d * mu);
|
||||
// mu_i = (vec(d) dot vec(v)) / r_i
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
/*****************************************************************************************
|
||||
* Modified parts of the code (4D texture mechanism) from Eric Bruneton is used in the *
|
||||
* following code. *
|
||||
* following code. *
|
||||
****************************************************************************************/
|
||||
|
||||
/**
|
||||
@@ -86,7 +86,7 @@ uniform sampler3D inscatterTexture;
|
||||
uniform sampler2D mainPositionTexture;
|
||||
uniform sampler2D mainNormalTexture;
|
||||
uniform sampler2D mainColorTexture;
|
||||
uniform dmat4 inverseModelTransformMatrix;
|
||||
uniform dmat4 inverseModelTransformMatrix;
|
||||
uniform dmat4 modelTransformMatrix;
|
||||
uniform dmat4 viewToWorldMatrix;
|
||||
uniform dmat4 projectionToModelTransformMatrix;
|
||||
@@ -129,13 +129,13 @@ float calcShadow(ShadowRenderingStruct shadowInfoArray[numberOfShadows], dvec3 p
|
||||
dvec3 scNorm = shadowInfoArray[0].sourceCasterVec;
|
||||
dvec3 pcProj = dot(pc, scNorm) * scNorm;
|
||||
dvec3 d = pc - pcProj;
|
||||
|
||||
|
||||
float length_d = float(length(d));
|
||||
double lengthPcProj = length(pcProj);
|
||||
|
||||
|
||||
float r_p_pi = float(shadowInfoArray[0].rc * (lengthPcProj + shadowInfoArray[0].xp) / shadowInfoArray[0].xp);
|
||||
float r_u_pi = float(shadowInfoArray[0].rc * (shadowInfoArray[0].xu - lengthPcProj) / shadowInfoArray[0].xu);
|
||||
|
||||
|
||||
if (length_d < r_u_pi) {
|
||||
// umbra
|
||||
if (hardShadows) {
|
||||
@@ -240,7 +240,7 @@ bool atmosphereIntersection(Ray ray, double atmRadius, out double offset,
|
||||
offset = 0.0;
|
||||
maxLength = s + q;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -257,7 +257,7 @@ Ray calculateRayRenderableGlobe(vec2 st) {
|
||||
// Clip to Object Coords
|
||||
dvec4 objectCoords = projectionToModelTransformMatrix * clipCoords;
|
||||
objectCoords.xyz /= objectCoords.w;
|
||||
|
||||
|
||||
// Building Ray
|
||||
// Ray in object space (in KM)
|
||||
Ray ray;
|
||||
@@ -266,7 +266,7 @@ Ray calculateRayRenderableGlobe(vec2 st) {
|
||||
return ray;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Calculates the light scattering in the view direction comming from other light rays
|
||||
* scattered in the atmosphere.
|
||||
* Following the paper: S[L]|x - T(x,xs) * S[L]|xs
|
||||
@@ -274,7 +274,7 @@ Ray calculateRayRenderableGlobe(vec2 st) {
|
||||
* position and zenith cosine angle as in the paper.
|
||||
* Arguments:
|
||||
* x := camera position
|
||||
* t := ray displacement variable after calculating the intersection with the
|
||||
* t := ray displacement variable after calculating the intersection with the
|
||||
* atmosphere. It is the distance from the camera to the last intersection with the
|
||||
* atmosphere. If the ray hits the ground, t is updated to the correct value
|
||||
* v := view direction (ray's direction) (normalized)
|
||||
@@ -292,7 +292,7 @@ vec3 inscatterRadiance(vec3 x, inout float t, inout float irradianceFactor, vec3
|
||||
const float INTERPOLATION_EPS = 0.004; // precision const from Brunetton
|
||||
|
||||
vec3 radiance;
|
||||
|
||||
|
||||
mu = dot(x, v) / r;
|
||||
|
||||
float r2 = r * r;
|
||||
@@ -300,7 +300,7 @@ vec3 inscatterRadiance(vec3 x, inout float t, inout float irradianceFactor, vec3
|
||||
float muSun = dot(x, s) / r;
|
||||
float rayleighPhase = rayleighPhaseFunction(nu);
|
||||
float miePhase = miePhaseFunction(nu, mieG);
|
||||
|
||||
|
||||
// S[L](x,s,v)
|
||||
// I.e. the next line has the scattering light for the "infinite" ray passing through
|
||||
// the atmosphere. If this ray hits something inside the atmosphere, we will subtract
|
||||
@@ -310,7 +310,7 @@ vec3 inscatterRadiance(vec3 x, inout float t, inout float irradianceFactor, vec3
|
||||
SAMPLES_MU_S, SAMPLES_NU),
|
||||
0.0
|
||||
);
|
||||
|
||||
|
||||
// After removing the initial path from camera pos to top of atmosphere (for an
|
||||
// observer in the space) we test if the light ray is hitting the atmosphere
|
||||
float r0 = length(fragPosObj);
|
||||
@@ -319,18 +319,18 @@ vec3 inscatterRadiance(vec3 x, inout float t, inout float irradianceFactor, vec3
|
||||
float mu0 = dot(fragPosObj, v) * invr0;
|
||||
|
||||
if ((pixelDepth > INTERPOLATION_EPS) && (pixelDepth < maxLength)) {
|
||||
t = float(pixelDepth);
|
||||
t = float(pixelDepth);
|
||||
groundHit = true;
|
||||
|
||||
|
||||
// Transmittance from point r, direction mu, distance t
|
||||
// By Analytical calculation
|
||||
// attenuation = analyticTransmittance(r, mu, t);
|
||||
// JCC: change from analytical to LUT transmittance to avoid
|
||||
// acme on planet surface when looking from far away. (11/02/2017)
|
||||
attenuation = transmittance(transmittanceTexture, r, mu, t, Rg, Rt);
|
||||
|
||||
attenuation = transmittance(transmittanceTexture, r, mu, t, Rg, Rt);
|
||||
|
||||
// Here we use the idea of S[L](a->b) = S[L](b->a), and get the S[L](x0, v, s)
|
||||
// Then we calculate S[L] = S[L]|x - T(x, x0)*S[L]|x0
|
||||
// Then we calculate S[L] = S[L]|x - T(x, x0)*S[L]|x0
|
||||
// The "infinite" ray hist something inside the atmosphere, so we need to remove
|
||||
// the unsused contribution to the final radiance.
|
||||
vec4 inscatterFromSurface = texture4D(inscatterTexture, r0, mu0, muSun0, nu, Rg,
|
||||
@@ -367,13 +367,13 @@ vec3 inscatterRadiance(vec3 x, inout float t, inout float irradianceFactor, vec3
|
||||
float halfCosineLaw1 = r2 + (t * t);
|
||||
float halfCosineLaw2 = 2.0 * r * t;
|
||||
r0 = sqrt(halfCosineLaw1 + halfCosineLaw2 * mu);
|
||||
|
||||
|
||||
// From the dot product: cos(theta0) = (x0 dot v)/(||ro||*||v||)
|
||||
// mu0 = ((x + t) dot v) / r0
|
||||
// mu0 = (x dot v + t dot v) / r0
|
||||
// mu0 = (r*mu + t) / r0
|
||||
mu0 = (r * mu + t) * (1.0 / r0);
|
||||
|
||||
|
||||
vec4 inScatterAboveX = texture4D(inscatterTexture, r, mu, muSun, nu, Rg,
|
||||
SAMPLES_MU, Rt, SAMPLES_R, SAMPLES_MU_S, SAMPLES_NU);
|
||||
vec4 inScatterAboveXs = texture4D(inscatterTexture, r0, mu0, muSun0, nu, Rg,
|
||||
@@ -385,9 +385,9 @@ vec3 inscatterRadiance(vec3 x, inout float t, inout float irradianceFactor, vec3
|
||||
mu = muHorizon + INTERPOLATION_EPS;
|
||||
//r0 = sqrt(r2 + t2 + 2.0 * r * t * mu);
|
||||
r0 = sqrt(halfCosineLaw1 + halfCosineLaw2 * mu);
|
||||
|
||||
|
||||
mu0 = (r * mu + t) * (1.0 / r0);
|
||||
|
||||
|
||||
vec4 inScatterBelowX = texture4D(inscatterTexture, r, mu, muSun, nu, Rg,
|
||||
SAMPLES_MU, Rt, SAMPLES_R, SAMPLES_MU_S, SAMPLES_NU);
|
||||
vec4 inScatterBelowXs = texture4D(inscatterTexture, r0, mu0, muSun0, nu, Rg,
|
||||
@@ -397,12 +397,12 @@ vec3 inscatterRadiance(vec3 x, inout float t, inout float irradianceFactor, vec3
|
||||
|
||||
// Interpolate between above and below inScattering radiance
|
||||
inscatterRadiance = mix(inScatterAbove, inScatterBelow, interpolationValue);
|
||||
}
|
||||
}
|
||||
|
||||
// The w component of inscatterRadiance has stored the Cm,r value (Cm = Sm[L0])
|
||||
// So, we must reintroduce the Mie inscatter by the proximity rule as described in the
|
||||
// paper by Bruneton and Neyret in "Angular precision" paragraph:
|
||||
|
||||
|
||||
// Hermite interpolation between two values
|
||||
// This step is done because imprecision problems happen when the Sun is slightly
|
||||
// below the horizon. When this happens, we avoid the Mie scattering contribution
|
||||
@@ -410,19 +410,19 @@ vec3 inscatterRadiance(vec3 x, inout float t, inout float irradianceFactor, vec3
|
||||
vec3 inscatterMie =
|
||||
inscatterRadiance.rgb * inscatterRadiance.a / max(inscatterRadiance.r, 1e-4) *
|
||||
(betaRayleigh.r / betaRayleigh);
|
||||
|
||||
radiance = max(inscatterRadiance.rgb * rayleighPhase + inscatterMie * miePhase, 0.0);
|
||||
|
||||
|
||||
radiance = max(inscatterRadiance.rgb * rayleighPhase + inscatterMie * miePhase, 0.0);
|
||||
|
||||
// Finally we add the Lsun (all calculations are done with no Lsun so we can change it
|
||||
// on the fly with no precomputations)
|
||||
vec3 finalScatteringRadiance = radiance * sunIntensity;
|
||||
return groundHit ? finalScatteringRadiance : spaceColor + finalScatteringRadiance;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Calculates the light reflected in the view direction comming from other light rays
|
||||
* integrated over the hemispehre plus the direct light (L0) from Sun.
|
||||
* Following the paper: R[L]= R[L0]+R[L*]
|
||||
* Following the paper: R[L]= R[L0]+R[L*]
|
||||
* The ray is x + tv, v the view direction, s is the sun direction, r and mu the position
|
||||
* and zenith cosine angle as in the paper.
|
||||
* As for all calculations in the atmosphere, the center of the coordinate system is the
|
||||
@@ -430,7 +430,7 @@ vec3 inscatterRadiance(vec3 x, inout float t, inout float irradianceFactor, vec3
|
||||
* Arguments:
|
||||
* x := camera position
|
||||
* t := ray displacement variable. Here, differently from the inScatter light calculation,
|
||||
* the position of the camera is already offset (on top of atmosphere) or inside
|
||||
* the position of the camera is already offset (on top of atmosphere) or inside
|
||||
* the atmosphere
|
||||
* v := view direction (ray's direction) (normalized)
|
||||
* s := Sun direction (normalized)
|
||||
@@ -465,7 +465,7 @@ vec3 groundColor(vec3 x, float t, vec3 v, vec3 s, vec3 attenuationXtoX0, vec3 gr
|
||||
groundReflectance * mix(30.0, 1.0, smoothstep(-1.0, 0.05, dotNS)) * RLStar :
|
||||
groundReflectance * RLStar;
|
||||
|
||||
// Specular reflection from sun on oceans and rivers
|
||||
// Specular reflection from sun on oceans and rivers
|
||||
if ((waterReflectance > 0.1) && (muSun > 0.0)) {
|
||||
vec3 h = normalize(s - v);
|
||||
// Fresnell Schlick's approximation
|
||||
@@ -478,11 +478,11 @@ vec3 groundColor(vec3 x, float t, vec3 v, vec3 s, vec3 attenuationXtoX0, vec3 gr
|
||||
}
|
||||
|
||||
// Finally, we attenuate the surface Radiance from the point x0 to the camera location
|
||||
vec3 reflectedRadiance = attenuationXtoX0 * groundRadiance;
|
||||
return reflectedRadiance;
|
||||
vec3 reflectedRadiance = attenuationXtoX0 * groundRadiance;
|
||||
return reflectedRadiance;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Calculates the Sun color. The ray is x + tv, v the view direction, s is the sun
|
||||
* direction, r and mu the position and zenith cosine angle as in the paper. As for all
|
||||
* calculations in the atmosphere, the center of the coordinate system is the planet's
|
||||
@@ -535,7 +535,7 @@ void main() {
|
||||
|
||||
// Get the ray from camera to atm in object space
|
||||
Ray ray = calculateRayRenderableGlobe(texCoord);
|
||||
|
||||
|
||||
double offset = 0.0; // in KM
|
||||
double maxLength = 0.0; // in KM
|
||||
bool intersect = atmosphereIntersection(ray, Rt - (ATM_EPSILON * 0.001), offset, maxLength);
|
||||
@@ -561,7 +561,7 @@ void main() {
|
||||
// Data in the mainPositionTexture are written in view space (view plus camera rig)
|
||||
vec4 position = texture(mainPositionTexture, st);
|
||||
|
||||
// OS Eye to World coords
|
||||
// OS Eye to World coords
|
||||
dvec4 positionWorldCoords = viewToWorldMatrix * position;
|
||||
|
||||
// World to Object (Normal and Position in meters)
|
||||
@@ -571,7 +571,7 @@ void main() {
|
||||
// JCC (12/12/2017): AMD distance function is buggy.
|
||||
//double pixelDepth = distance(cameraPositionInObject.xyz, positionObjectsCoords.xyz);
|
||||
double pixelDepth = length(camPosObj - positionObjectsCoords);
|
||||
|
||||
|
||||
// JCC (12/13/2017): Trick to remove floating error in texture.
|
||||
// We see a squared noise on planet's surface when seeing the planet from far away
|
||||
// @TODO (abock, 2021-07-01) I don't think this does anything. Remove?
|
||||
@@ -581,12 +581,12 @@ void main() {
|
||||
pixelDepth += 1000.0;
|
||||
const float alpha = 1000.0;
|
||||
const float beta = 1000000.0;
|
||||
const float x2 = 1e9;
|
||||
const float x2 = 1e9;
|
||||
const float diffGreek = beta - alpha;
|
||||
const float diffDist = x2 - x1;
|
||||
const float varA = diffGreek / diffDist;
|
||||
const float varB = (alpha - varA * x1);
|
||||
pixelDepth += double(varA * dC + varB);
|
||||
pixelDepth += double(varA * dC + varB);
|
||||
}
|
||||
|
||||
// All calculations are done in KM:
|
||||
@@ -599,8 +599,8 @@ void main() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Following paper nomenclature
|
||||
double t = offset;
|
||||
// Following paper nomenclature
|
||||
double t = offset;
|
||||
|
||||
// Moving observer from camera location to top atmosphere. If the observer is already
|
||||
// inside the atm, offset = 0.0 and no changes at all
|
||||
@@ -615,16 +615,16 @@ void main() {
|
||||
// adjust the pixelDepth for tdCalculateRayRenderableGlobe' offset so the next
|
||||
// comparison with the planet's ground make sense:
|
||||
pixelDepth -= offset;
|
||||
|
||||
|
||||
dvec3 onATMPos = (modelTransformMatrix * dvec4(x * 1000.0, 1.0)).xyz;
|
||||
float eclipseShadowATM = calcShadow(shadowDataArray, onATMPos, false);
|
||||
float eclipseShadowATM = calcShadow(shadowDataArray, onATMPos, false);
|
||||
float sunIntensityInscatter = sunRadiance * eclipseShadowATM;
|
||||
|
||||
float irradianceFactor = 0.0;
|
||||
|
||||
bool groundHit = false;
|
||||
vec3 attenuation;
|
||||
|
||||
vec3 attenuation;
|
||||
|
||||
vec3 inscatterColor = inscatterRadiance(x, tF, irradianceFactor, v, s, r,
|
||||
vec3(positionObjectsCoords), maxLength, pixelDepth, color, sunIntensityInscatter, mu,
|
||||
attenuation, groundHit);
|
||||
@@ -639,8 +639,8 @@ void main() {
|
||||
// In order to get better performance, we are not tracing multiple rays per pixel
|
||||
// when the ray doesn't intersect the ground
|
||||
atmColor = sunColor(v, s, r, mu, irradianceFactor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Final Color of ATM plus terrain:
|
||||
renderTarget = vec4(inscatterColor + atmColor, 1.0);;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout (triangles) in;
|
||||
|
||||
@@ -27,6 +27,6 @@
|
||||
out vec4 renderTableColor;
|
||||
|
||||
|
||||
void main() {
|
||||
void main() {
|
||||
renderTableColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
@@ -100,7 +100,7 @@ vec3 inscatter(float r, float mu, float muSun, float nu) {
|
||||
|
||||
// Now we get vec(v) and vec(s) from mu, muSun and nu:
|
||||
// Assuming:
|
||||
// z |theta
|
||||
// z |theta
|
||||
// |\ vec(v) ||vec(v)|| = 1
|
||||
// | \
|
||||
// |__\_____x
|
||||
@@ -121,7 +121,7 @@ vec3 inscatter(float r, float mu, float muSun, float nu) {
|
||||
// 1 = sqrt(s.x*s.x + s.y*s.y + s.z*s.z)
|
||||
// s.y = sqrt(1 - s.x*s.x - s.z*s.z) = sqrt(1 - s.x*s.x - muSun*muSun)
|
||||
vec3 s = vec3(sx, sqrt(max(0.0, 1.0 - sx * sx - muSun2)), muSun);
|
||||
|
||||
|
||||
// In order to integrate over 4PI, we scan the sphere using the spherical coordinates
|
||||
// previously defined
|
||||
vec3 radianceJAcc = vec3(0.0);
|
||||
@@ -132,7 +132,7 @@ vec3 inscatter(float r, float mu, float muSun, float nu) {
|
||||
float distanceToGround = 0.0;
|
||||
float groundReflectance = 0.0;
|
||||
vec3 groundTransmittance = vec3(0.0);
|
||||
|
||||
|
||||
// If the ray w can see the ground we must compute the transmittance
|
||||
// effect from the starting point x to the ground point in direction -vec(v):
|
||||
if (cosineTheta < cosHorizon) { // ray hits ground
|
||||
@@ -146,7 +146,7 @@ vec3 inscatter(float r, float mu, float muSun, float nu) {
|
||||
// |\ distGround
|
||||
// r | \ alpha
|
||||
// | \/
|
||||
// | /
|
||||
// | /
|
||||
// | / Rg
|
||||
// |/
|
||||
// So cos(alpha) = ((vec(x)+vec(dg)) dot -vec(distG))/(||(vec(x)+vec(distG))|| * ||vec(distG)||)
|
||||
@@ -178,7 +178,7 @@ vec3 inscatter(float r, float mu, float muSun, float nu) {
|
||||
float nuWV = dot(v, w);
|
||||
float phaseRayleighWV = rayleighPhaseFunction(nuWV);
|
||||
float phaseMieWV = miePhaseFunction(nuWV, mieG);
|
||||
|
||||
|
||||
vec3 groundNormal = (vec3(0.0, 0.0, r) + distanceToGround * w) / Rg;
|
||||
vec3 groundIrradiance = irradianceLUT(deltaETexture, dot(groundNormal, s), Rg);
|
||||
|
||||
@@ -194,7 +194,7 @@ vec3 inscatter(float r, float mu, float muSun, float nu) {
|
||||
// light. We stored these values in the deltaS textures (Ray and Mie), and in order
|
||||
// to avoid problems with the high angle dependency in the phase functions, we don't
|
||||
// include the phase functions on those tables (that's why we calculate them now).
|
||||
if (firstIteration == 1) {
|
||||
if (firstIteration == 1) {
|
||||
float phaseRaySW = rayleighPhaseFunction(nuSW);
|
||||
float phaseMieSW = miePhaseFunction(nuSW, mieG);
|
||||
// We can now access the values for the single InScattering in the textures deltaS textures.
|
||||
@@ -204,7 +204,7 @@ vec3 inscatter(float r, float mu, float muSun, float nu) {
|
||||
Rt, SAMPLES_R, SAMPLES_MU_S, SAMPLES_NU).rgb;
|
||||
|
||||
// Initial InScattering including the phase functions
|
||||
radianceJ1 += singleRay * phaseRaySW + singleMie * phaseMieSW;
|
||||
radianceJ1 += singleRay * phaseRaySW + singleMie * phaseMieSW;
|
||||
}
|
||||
else {
|
||||
// On line 9 of the algorithm, the texture table deltaSR is updated, so when we
|
||||
@@ -219,7 +219,7 @@ vec3 inscatter(float r, float mu, float muSun, float nu) {
|
||||
// Finally, we add the atmospheric scale height (See: Radiation Transfer on the
|
||||
// Atmosphere and Ocean from Thomas and Stamnes, pg 9-10.
|
||||
radianceJAcc += radianceJ1 * (betaRayleigh * exp(-(r - Rg) / HR) * phaseRayleighWV +
|
||||
betaMieScattering * exp(-(r - Rg) / HM) * phaseMieWV) * dw;
|
||||
betaMieScattering * exp(-(r - Rg) / HM) * phaseMieWV) * dw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,11 +41,11 @@ void main() {
|
||||
// First we convert the window's fragment coordinate to texel coordinates
|
||||
vec3 rst = vec3(gl_FragCoord.xy, float(layer) + 0.5) /
|
||||
vec3(ivec3(SAMPLES_MU_S * SAMPLES_NU, SAMPLES_MU, SAMPLES_R));
|
||||
|
||||
|
||||
vec3 rayleighInscattering = texture(deltaSRTexture, rst).rgb;
|
||||
float mieInscattering = texture(deltaSMTexture, rst).r;
|
||||
|
||||
|
||||
// We are using only the red component of the Mie scattering. See the Precomputed
|
||||
// Atmosphere Scattering paper for details about the angular precision
|
||||
renderTarget = vec4(rayleighInscattering, mieInscattering);
|
||||
renderTarget = vec4(rayleighInscattering, mieInscattering);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
@@ -45,7 +45,7 @@ uniform float r;
|
||||
uniform vec4 dhdH;
|
||||
|
||||
|
||||
void integrand(float r, float mu, float muSun, float nu, float y, out vec3 S_R,
|
||||
void integrand(float r, float mu, float muSun, float nu, float y, out vec3 S_R,
|
||||
out vec3 S_M)
|
||||
{
|
||||
// The integral's integrand is the single inscattering radiance:
|
||||
@@ -59,10 +59,10 @@ void integrand(float r, float mu, float muSun, float nu, float y, out vec3 S_R,
|
||||
// angular precision
|
||||
S_R = vec3(0.0);
|
||||
S_M = vec3(0.0);
|
||||
|
||||
|
||||
// cosine law
|
||||
float ri = max(sqrt(r * r + y * y + 2.0 * r * mu * y), Rg);
|
||||
|
||||
|
||||
// Considering the Sun as a parallel light source, thew vector s_i = s.
|
||||
// So muSun_i = (vec(y_i) dot vec(s))/r_i = ((vec(x) + vec(yi-x)) dot vec(s))/r_i
|
||||
// muSun_i = (vec(x) dot vec(s) + vec(yi-x) dot vec(s))/r_i = (r*muSun + yi*nu)/r_i
|
||||
@@ -123,7 +123,7 @@ void main() {
|
||||
// parameters (uv), we unmapping mu, muSun and nu.
|
||||
float mu, muSun, nu;
|
||||
unmappingMuMuSunNu(r, dhdH, SAMPLES_MU, Rg, Rt, SAMPLES_MU_S, SAMPLES_NU, mu, muSun, nu);
|
||||
|
||||
|
||||
// Here we calculate the single inScattered light. Because this is a single
|
||||
// inscattering, the light that arrives at a point y in the path from the eye to the
|
||||
// infinity (top of atmosphere or planet's ground), comes only from the light source,
|
||||
@@ -135,7 +135,7 @@ void main() {
|
||||
// S[L0] = P_R*S_R[L0] + P_M*S_M[L0]
|
||||
// In order to save memory, we just store the red component of S_M[L0], and later we use
|
||||
// the proportionality rule to calcule the other components.
|
||||
vec3 S_R; // First Order Rayleigh InScattering
|
||||
vec3 S_R; // First Order Rayleigh InScattering
|
||||
vec3 S_M; // First Order Mie InScattering
|
||||
inscatter(r, mu, muSun, nu, S_R, S_M);
|
||||
renderTarget1 = vec4(S_R, 1.0);
|
||||
|
||||
@@ -64,7 +64,7 @@ vec3 inscatter(float r, float mu, float muSun, float nu) {
|
||||
vec3 inScatteringRadiance = vec3(0.0);
|
||||
float dy = rayDistance(r, mu, Rt, Rg) / float(INSCATTER_INTEGRAL_SAMPLES);
|
||||
vec3 inScatteringRadiance_i = integrand(r, mu, muSun, nu, 0.0);
|
||||
|
||||
|
||||
// In order to solve the integral from equation (11) we use the trapezoidal rule:
|
||||
// Integral(f(y)dy)(from a to b) = ((b-a)/2n_steps)*(Sum(f(y_i+1)+f(y_i)))
|
||||
// where y_i+1 = y_j
|
||||
@@ -84,7 +84,7 @@ void main() {
|
||||
float nu = 0.0;
|
||||
// Unmapping the variables from texture texels coordinates to mapped coordinates
|
||||
unmappingMuMuSunNu(r, dhdH, SAMPLES_MU, Rg, Rt, SAMPLES_MU_S, SAMPLES_NU, mu, muSun, nu);
|
||||
|
||||
// Write to texture deltaSR
|
||||
|
||||
// Write to texture deltaSR
|
||||
renderTarget = vec4(inscatter(r, mu, muSun, nu), 1.0);
|
||||
}
|
||||
|
||||
@@ -30,9 +30,9 @@ uniform ivec2 OTHER_TEXTURES;
|
||||
uniform sampler2D deltaETexture;
|
||||
|
||||
|
||||
void main() {
|
||||
void main() {
|
||||
vec2 uv = gl_FragCoord.xy / vec2(OTHER_TEXTURES);
|
||||
|
||||
// Update texture E with E plus deltaE textures.
|
||||
renderTableColor = texture(deltaETexture, uv);
|
||||
renderTableColor = texture(deltaETexture, uv);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
@@ -98,5 +98,5 @@ void main() {
|
||||
}
|
||||
|
||||
// Write the higher order irradiance to texture deltaE
|
||||
renderTableColor = vec4(irradianceE, 0.0);
|
||||
renderTableColor = vec4(irradianceE, 0.0);
|
||||
}
|
||||
|
||||
@@ -47,14 +47,14 @@ const int TRANSMITTANCE_STEPS = 500;
|
||||
// r := height of starting point vect(x)
|
||||
// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r
|
||||
// H := Thickness of atmosphere if its density were uniform (used for Rayleigh and Mie)
|
||||
float opticalDepth(float r, float mu, float H) {
|
||||
float opticalDepth(float r, float mu, float H) {
|
||||
float r2 = r * r;
|
||||
// Is ray below horizon? The transmittance table will have only the values for
|
||||
// transmittance starting at r (x) until the light ray touches the atmosphere or the
|
||||
// ground and only for view angles v between 0 and pi/2 + eps. That's because we can
|
||||
// calculate the transmittance for angles bigger than pi/2 just inverting the ray
|
||||
// direction and starting and ending points.
|
||||
|
||||
|
||||
// cosine law for triangles: y_i^2 = a^2 + b^2 - 2abcos(alpha)
|
||||
float cosZenithHorizon = -sqrt(1.0 - ((Rg * Rg) / r2));
|
||||
if (mu < cosZenithHorizon) {
|
||||
@@ -67,7 +67,7 @@ float opticalDepth(float r, float mu, float H) {
|
||||
float deltaStep = b_a / float(TRANSMITTANCE_STEPS);
|
||||
// cosine law
|
||||
float y_i = exp(-(r - Rg) / H);
|
||||
|
||||
|
||||
float accumulation = 0.0;
|
||||
for (int i = 1; i <= TRANSMITTANCE_STEPS; ++i) {
|
||||
float x_i = float(i) * deltaStep;
|
||||
@@ -84,11 +84,11 @@ float opticalDepth(float r, float mu, float H) {
|
||||
void main() {
|
||||
float u_mu = gl_FragCoord.x / float(TRANSMITTANCE.x);
|
||||
float u_r = gl_FragCoord.y / float(TRANSMITTANCE.y);
|
||||
|
||||
|
||||
// In the paper u_r^2 = (r^2-Rg^2)/(Rt^2-Rg^2)
|
||||
// So, extracting r from u_r in the above equation:
|
||||
float r = Rg + (u_r * u_r) * (Rt - Rg);
|
||||
|
||||
|
||||
// In the paper the Bruneton suggest mu = dot(v,x)/||x|| with ||v|| = 1.0
|
||||
// Later he proposes u_mu = (1-exp(-3mu-0.6))/(1-exp(-3.6))
|
||||
// But the below one is better. See Collienne.
|
||||
@@ -99,9 +99,9 @@ void main() {
|
||||
if (ozoneLayerEnabled) {
|
||||
ozoneContribution = betaOzoneExtinction * 0.0000006 * opticalDepth(r, muSun, HO);
|
||||
}
|
||||
vec3 opDepth = ozoneContribution +
|
||||
vec3 opDepth = ozoneContribution +
|
||||
betaMieExtinction * opticalDepth(r, muSun, HM) +
|
||||
betaRayleigh * opticalDepth(r, muSun, HR);
|
||||
|
||||
|
||||
renderTableColor = vec4(exp(-opDepth), 0.0);
|
||||
}
|
||||
|
||||
@@ -54,14 +54,7 @@ namespace {
|
||||
"This value species the size of each dimensions of the box"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo DrawLabelInfo = {
|
||||
"DrawLabels",
|
||||
"Draw Labels",
|
||||
"Determines whether labels should be drawn or hidden"
|
||||
};
|
||||
|
||||
static const openspace::properties::PropertyOwner::PropertyOwnerInfo LabelsInfo =
|
||||
{
|
||||
static const openspace::properties::PropertyOwner::PropertyOwnerInfo LabelsInfo = {
|
||||
"Labels",
|
||||
"Labels",
|
||||
"The labels for the grid"
|
||||
@@ -77,9 +70,6 @@ namespace {
|
||||
// [[codegen::verbatim(SizeInfo.description)]]
|
||||
std::optional<glm::vec3> size;
|
||||
|
||||
// [[codegen::verbatim(DrawLabelInfo.description)]]
|
||||
std::optional<bool> drawLabels;
|
||||
|
||||
// [[codegen::verbatim(LabelsInfo.description)]]
|
||||
std::optional<ghoul::Dictionary> labels
|
||||
[[codegen::reference("space_labelscomponent")]];
|
||||
@@ -98,12 +88,10 @@ RenderableBoxGrid::RenderableBoxGrid(const ghoul::Dictionary& dictionary)
|
||||
, _color(ColorInfo, glm::vec3(0.5f), glm::vec3(0.f), glm::vec3(1.f))
|
||||
, _lineWidth(LineWidthInfo, 0.5f, 1.f, 20.f)
|
||||
, _size(SizeInfo, glm::vec3(1.f), glm::vec3(1.f), glm::vec3(100.f))
|
||||
, _drawLabels(DrawLabelInfo, false)
|
||||
{
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
addProperty(_opacity);
|
||||
registerUpdateRenderBinFromOpacity();
|
||||
addProperty(Fadeable::_opacity);
|
||||
|
||||
_color = p.color.value_or(_color);
|
||||
_color.setViewOption(properties::Property::ViewOptions::Color);
|
||||
@@ -113,16 +101,15 @@ RenderableBoxGrid::RenderableBoxGrid(const ghoul::Dictionary& dictionary)
|
||||
addProperty(_lineWidth);
|
||||
|
||||
_size = p.size.value_or(_size);
|
||||
_size.onChange([&]() { _gridIsDirty = true; });
|
||||
_size.onChange([this]() { _gridIsDirty = true; });
|
||||
addProperty(_size);
|
||||
|
||||
if (p.labels.has_value()) {
|
||||
_drawLabels = p.drawLabels.value_or(_drawLabels);
|
||||
addProperty(_drawLabels);
|
||||
|
||||
_labels = std::make_unique<LabelsComponent>(*p.labels);
|
||||
_hasLabels = true;
|
||||
addPropertySubOwner(_labels.get());
|
||||
// Fading of the labels should also depend on the fading of the renderable
|
||||
_labels->setParentFadeable(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,7 +202,7 @@ void RenderableBoxGrid::render(const RenderData& data, RendererTasks&){
|
||||
global::renderEngine->openglStateCache().resetDepthState();
|
||||
|
||||
// Draw labels
|
||||
if (_drawLabels && _hasLabels) {
|
||||
if (_hasLabels && _labels->enabled()) {
|
||||
const glm::vec3 lookup = data.camera.lookUpVectorWorldSpace();
|
||||
const glm::vec3 viewDirection = data.camera.viewDirectionWorldSpace();
|
||||
glm::vec3 right = glm::cross(viewDirection, lookup);
|
||||
|
||||
@@ -76,7 +76,6 @@ protected:
|
||||
|
||||
// Labels
|
||||
bool _hasLabels = false;
|
||||
properties::BoolProperty _drawLabels;
|
||||
std::unique_ptr<LabelsComponent> _labels;
|
||||
};
|
||||
|
||||
|
||||
@@ -81,14 +81,7 @@ namespace {
|
||||
"This value species the size of each dimensions of the grid"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo DrawLabelInfo = {
|
||||
"DrawLabels",
|
||||
"Draw Labels",
|
||||
"Determines whether labels should be drawn or hidden"
|
||||
};
|
||||
|
||||
static const openspace::properties::PropertyOwner::PropertyOwnerInfo LabelsInfo =
|
||||
{
|
||||
static const openspace::properties::PropertyOwner::PropertyOwnerInfo LabelsInfo = {
|
||||
"Labels",
|
||||
"Labels",
|
||||
"The labels for the grid"
|
||||
@@ -116,9 +109,6 @@ namespace {
|
||||
// [[codegen::verbatim(SizeInfo.description)]]
|
||||
std::optional<glm::vec2> size;
|
||||
|
||||
// [[codegen::verbatim(DrawLabelInfo.description)]]
|
||||
std::optional<bool> drawLabels;
|
||||
|
||||
// [[codegen::verbatim(LabelsInfo.description)]]
|
||||
std::optional<ghoul::Dictionary> labels
|
||||
[[codegen::reference("space_labelscomponent")]];
|
||||
@@ -141,12 +131,10 @@ RenderableGrid::RenderableGrid(const ghoul::Dictionary& dictionary)
|
||||
, _lineWidth(LineWidthInfo, 0.5f, 1.f, 20.f)
|
||||
, _highlightLineWidth(HighlightLineWidthInfo, 0.5f, 1.f, 20.f)
|
||||
, _size(SizeInfo, glm::vec2(1.f), glm::vec2(1.f), glm::vec2(1e11f))
|
||||
, _drawLabels(DrawLabelInfo, false)
|
||||
{
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
addProperty(_opacity);
|
||||
registerUpdateRenderBinFromOpacity();
|
||||
addProperty(Fadeable::_opacity);
|
||||
|
||||
_color = p.color.value_or(_color);
|
||||
_color.setViewOption(properties::Property::ViewOptions::Color);
|
||||
@@ -158,11 +146,11 @@ RenderableGrid::RenderableGrid(const ghoul::Dictionary& dictionary)
|
||||
addProperty(_highlightColor);
|
||||
|
||||
_segments = p.segments.value_or(_segments);
|
||||
_segments.onChange([&]() { _gridIsDirty = true; });
|
||||
_segments.onChange([this]() { _gridIsDirty = true; });
|
||||
addProperty(_segments);
|
||||
|
||||
_highlightRate = p.highlightRate.value_or(_highlightRate);
|
||||
_highlightRate.onChange([&]() { _gridIsDirty = true; });
|
||||
_highlightRate.onChange([this]() { _gridIsDirty = true; });
|
||||
addProperty(_highlightRate);
|
||||
|
||||
_lineWidth = p.lineWidth.value_or(_lineWidth);
|
||||
@@ -174,16 +162,15 @@ RenderableGrid::RenderableGrid(const ghoul::Dictionary& dictionary)
|
||||
|
||||
_size.setExponent(10.f);
|
||||
_size = p.size.value_or(_size);
|
||||
_size.onChange([&]() { _gridIsDirty = true; });
|
||||
_size.onChange([this]() { _gridIsDirty = true; });
|
||||
addProperty(_size);
|
||||
|
||||
if (p.labels.has_value()) {
|
||||
_drawLabels = p.drawLabels.value_or(_drawLabels);
|
||||
addProperty(_drawLabels);
|
||||
|
||||
_labels = std::make_unique<LabelsComponent>(*p.labels);
|
||||
_hasLabels = true;
|
||||
addPropertySubOwner(_labels.get());
|
||||
// Fading of the labels should also depend on the fading of the renderable
|
||||
_labels->setParentFadeable(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,11 +301,11 @@ void RenderableGrid::render(const RenderData& data, RendererTasks&){
|
||||
global::renderEngine->openglStateCache().resetDepthState();
|
||||
|
||||
// Draw labels
|
||||
if (_drawLabels && _hasLabels) {
|
||||
if (_hasLabels && _labels->enabled()) {
|
||||
const glm::vec3 orthoUp = glm::normalize(
|
||||
glm::vec3(worldToModelTransform * glm::dvec4(up, 0.0))
|
||||
);
|
||||
_labels->render(data, modelViewProjectionMatrix, orthoRight, orthoUp);
|
||||
_labels->render(data, modelViewProjectionMatrix, orthoRight, orthoUp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,7 +85,6 @@ protected:
|
||||
|
||||
// Labels
|
||||
bool _hasLabels = false;
|
||||
properties::BoolProperty _drawLabels;
|
||||
std::unique_ptr<LabelsComponent> _labels;
|
||||
};
|
||||
|
||||
|
||||
@@ -71,14 +71,7 @@ namespace {
|
||||
"ring"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo DrawLabelInfo = {
|
||||
"DrawLabels",
|
||||
"Draw Labels",
|
||||
"Determines whether labels should be drawn or hidden"
|
||||
};
|
||||
|
||||
static const openspace::properties::PropertyOwner::PropertyOwnerInfo LabelsInfo =
|
||||
{
|
||||
static const openspace::properties::PropertyOwner::PropertyOwnerInfo LabelsInfo = {
|
||||
"Labels",
|
||||
"Labels",
|
||||
"The labels for the grid"
|
||||
@@ -100,9 +93,6 @@ namespace {
|
||||
// [[codegen::verbatim(RadiiInfo.description)]]
|
||||
std::optional<glm::vec2> radii;
|
||||
|
||||
// [[codegen::verbatim(DrawLabelInfo.description)]]
|
||||
std::optional<bool> drawLabels;
|
||||
|
||||
// [[codegen::verbatim(LabelsInfo.description)]]
|
||||
std::optional<ghoul::Dictionary> labels
|
||||
[[codegen::reference("space_labelscomponent")]];
|
||||
@@ -123,23 +113,21 @@ RenderableRadialGrid::RenderableRadialGrid(const ghoul::Dictionary& dictionary)
|
||||
, _circleSegments(CircleSegmentsInfo, 36, 4, 200)
|
||||
, _lineWidth(LineWidthInfo, 0.5f, 1.f, 20.f)
|
||||
, _radii(RadiiInfo, glm::vec2(0.f, 1.f), glm::vec2(0.f), glm::vec2(20.f))
|
||||
, _drawLabels(DrawLabelInfo, false)
|
||||
{
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
addProperty(_opacity);
|
||||
registerUpdateRenderBinFromOpacity();
|
||||
addProperty(Fadeable::_opacity);
|
||||
|
||||
_color = p.color.value_or(_color);
|
||||
_color.setViewOption(properties::Property::ViewOptions::Color);
|
||||
addProperty(_color);
|
||||
|
||||
_gridSegments = p.gridSegments.value_or(_gridSegments);
|
||||
_gridSegments.onChange([&]() { _gridIsDirty = true; });
|
||||
_gridSegments.onChange([this]() { _gridIsDirty = true; });
|
||||
addProperty(_gridSegments);
|
||||
|
||||
_circleSegments = p.circleSegments.value_or(_circleSegments);
|
||||
_circleSegments.onChange([&]() {
|
||||
_circleSegments.onChange([this]() {
|
||||
if (_circleSegments.value() % 2 == 1) {
|
||||
_circleSegments = _circleSegments - 1;
|
||||
}
|
||||
@@ -152,17 +140,16 @@ RenderableRadialGrid::RenderableRadialGrid(const ghoul::Dictionary& dictionary)
|
||||
|
||||
_radii = p.radii.value_or(_radii);
|
||||
_radii.setViewOption(properties::Property::ViewOptions::MinMaxRange);
|
||||
_radii.onChange([&]() { _gridIsDirty = true; });
|
||||
_radii.onChange([this]() { _gridIsDirty = true; });
|
||||
|
||||
addProperty(_radii);
|
||||
|
||||
if (p.labels.has_value()) {
|
||||
_drawLabels = p.drawLabels.value_or(_drawLabels);
|
||||
addProperty(_drawLabels);
|
||||
|
||||
_labels = std::make_unique<LabelsComponent>(*p.labels);
|
||||
_hasLabels = true;
|
||||
addPropertySubOwner(_labels.get());
|
||||
// Fading of the labels should also depend on the fading of the renderable
|
||||
_labels->setParentFadeable(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,7 +231,7 @@ void RenderableRadialGrid::render(const RenderData& data, RendererTasks&) {
|
||||
global::renderEngine->openglStateCache().resetDepthState();
|
||||
|
||||
// Draw labels
|
||||
if (_drawLabels && _hasLabels) {
|
||||
if (_hasLabels && _labels->enabled()) {
|
||||
const glm::vec3 lookup = data.camera.lookUpVectorWorldSpace();
|
||||
const glm::vec3 viewDirection = data.camera.viewDirectionWorldSpace();
|
||||
glm::vec3 right = glm::cross(viewDirection, lookup);
|
||||
|
||||
@@ -90,7 +90,6 @@ protected:
|
||||
|
||||
// Labels
|
||||
bool _hasLabels = false;
|
||||
properties::BoolProperty _drawLabels;
|
||||
std::unique_ptr<LabelsComponent> _labels;
|
||||
};
|
||||
|
||||
|
||||
@@ -55,14 +55,7 @@ namespace {
|
||||
"This value specifies the line width of the spherical grid"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo DrawLabelInfo = {
|
||||
"DrawLabels",
|
||||
"Draw Labels",
|
||||
"Determines whether labels should be drawn or hidden"
|
||||
};
|
||||
|
||||
static const openspace::properties::PropertyOwner::PropertyOwnerInfo LabelsInfo =
|
||||
{
|
||||
static const openspace::properties::PropertyOwner::PropertyOwnerInfo LabelsInfo = {
|
||||
"Labels",
|
||||
"Labels",
|
||||
"The labels for the grid"
|
||||
@@ -78,9 +71,6 @@ namespace {
|
||||
// [[codegen::verbatim(LineWidthInfo.description)]]
|
||||
std::optional<float> lineWidth;
|
||||
|
||||
// [[codegen::verbatim(DrawLabelInfo.description)]]
|
||||
std::optional<bool> drawLabels;
|
||||
|
||||
// [[codegen::verbatim(LabelsInfo.description)]]
|
||||
std::optional<ghoul::Dictionary> labels
|
||||
[[codegen::reference("space_labelscomponent")]];
|
||||
@@ -100,19 +90,17 @@ RenderableSphericalGrid::RenderableSphericalGrid(const ghoul::Dictionary& dictio
|
||||
, _color(ColorInfo, glm::vec3(0.5f), glm::vec3(0.f), glm::vec3(1.f))
|
||||
, _segments(SegmentsInfo, 36, 4, 200)
|
||||
, _lineWidth(LineWidthInfo, 0.5f, 1.f, 20.f)
|
||||
, _drawLabels(DrawLabelInfo, false)
|
||||
{
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
addProperty(_opacity);
|
||||
registerUpdateRenderBinFromOpacity();
|
||||
addProperty(Fadeable::_opacity);
|
||||
|
||||
_color = p.color.value_or(_color);
|
||||
_color.setViewOption(properties::Property::ViewOptions::Color);
|
||||
addProperty(_color);
|
||||
|
||||
_segments = p.segments.value_or(_segments);
|
||||
_segments.onChange([&]() {
|
||||
_segments.onChange([this]() {
|
||||
if (_segments.value() % 2 == 1) {
|
||||
_segments = _segments - 1;
|
||||
}
|
||||
@@ -127,12 +115,11 @@ RenderableSphericalGrid::RenderableSphericalGrid(const ghoul::Dictionary& dictio
|
||||
setBoundingSphere(1.0);
|
||||
|
||||
if (p.labels.has_value()) {
|
||||
_drawLabels = p.drawLabels.value_or(_drawLabels);
|
||||
addProperty(_drawLabels);
|
||||
|
||||
_labels = std::make_unique<LabelsComponent>(*p.labels);
|
||||
_hasLabels = true;
|
||||
addPropertySubOwner(_labels.get());
|
||||
// Fading of the labels should also depend on the fading of the renderable
|
||||
_labels->setParentFadeable(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,7 +219,7 @@ void RenderableSphericalGrid::render(const RenderData& data, RendererTasks&){
|
||||
global::renderEngine->openglStateCache().resetDepthState();
|
||||
|
||||
// Draw labels
|
||||
if (_drawLabels && _hasLabels) {
|
||||
if (_hasLabels && _labels->enabled()) {
|
||||
const glm::vec3 lookup = data.camera.lookUpVectorWorldSpace();
|
||||
const glm::vec3 viewDirection = data.camera.viewDirectionWorldSpace();
|
||||
glm::vec3 right = glm::cross(viewDirection, lookup);
|
||||
|
||||
@@ -80,7 +80,6 @@ protected:
|
||||
|
||||
// Labels
|
||||
bool _hasLabels = false;
|
||||
properties::BoolProperty _drawLabels;
|
||||
std::unique_ptr<LabelsComponent> _labels;
|
||||
};
|
||||
|
||||
|
||||
@@ -92,19 +92,19 @@ RenderableDisc::RenderableDisc(const ghoul::Dictionary& dictionary)
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
_texturePath = p.texture.string();
|
||||
_texturePath.onChange([&]() { _texture->loadFromFile(_texturePath.value()); });
|
||||
_texturePath.onChange([this]() { _texture->loadFromFile(_texturePath.value()); });
|
||||
addProperty(_texturePath);
|
||||
|
||||
_size.setExponent(13.f);
|
||||
_size = p.size.value_or(_size);
|
||||
setBoundingSphere(_size);
|
||||
_size.onChange([&]() { _planeIsDirty = true; });
|
||||
_size.onChange([this]() { _planeIsDirty = true; });
|
||||
addProperty(_size);
|
||||
|
||||
_width = p.width.value_or(_width);
|
||||
addProperty(_width);
|
||||
|
||||
addProperty(_opacity);
|
||||
addProperty(Fadeable::_opacity);
|
||||
|
||||
setRenderBin(Renderable::RenderBin::PostDeferredTransparent);
|
||||
}
|
||||
|
||||
@@ -238,7 +238,7 @@ documentation::Documentation RenderableLabel::Documentation() {
|
||||
}
|
||||
|
||||
RenderableLabel::RenderableLabel(const ghoul::Dictionary& dictionary)
|
||||
: Renderable(dictionary)
|
||||
: Renderable(dictionary, { .automaticallyUpdateRenderBin = false })
|
||||
, _blendMode(BlendModeInfo, properties::OptionProperty::DisplayType::Dropdown)
|
||||
, _color(ColorInfo, glm::vec3(1.f), glm::vec3(0.f), glm::vec3(1.f))
|
||||
, _fontSize(FontSizeInfo, 50.f, 1.f, 100.f)
|
||||
@@ -259,14 +259,13 @@ RenderableLabel::RenderableLabel(const ghoul::Dictionary& dictionary)
|
||||
{
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
addProperty(_opacity);
|
||||
registerUpdateRenderBinFromOpacity();
|
||||
addProperty(Fadeable::_opacity);
|
||||
|
||||
_blendMode.addOptions({
|
||||
{ BlendMode::Normal, "Normal" },
|
||||
{ BlendMode::Additive, "Additive"}
|
||||
{ BlendMode::Additive, "Additive" }
|
||||
});
|
||||
_blendMode.onChange([&]() {
|
||||
_blendMode.onChange([this]() {
|
||||
switch (_blendMode) {
|
||||
case BlendMode::Normal:
|
||||
setRenderBinFromOpacity();
|
||||
@@ -302,7 +301,7 @@ RenderableLabel::RenderableLabel(const ghoul::Dictionary& dictionary)
|
||||
addProperty(_color);
|
||||
|
||||
_fontSize = p.fontSize.value_or(_fontSize);
|
||||
_fontSize.onChange([&]() {
|
||||
_fontSize.onChange([this]() {
|
||||
_font = global::fontManager->font(
|
||||
"Mono",
|
||||
_fontSize,
|
||||
|
||||
@@ -292,8 +292,7 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
|
||||
{
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
addProperty(_opacity);
|
||||
registerUpdateRenderBinFromOpacity();
|
||||
addProperty(Fadeable::_opacity);
|
||||
|
||||
if (p.forceRenderInvisible.has_value()) {
|
||||
_forceRenderInvisible = *p.forceRenderInvisible;
|
||||
@@ -518,7 +517,7 @@ void RenderableModel::initializeGL() {
|
||||
}
|
||||
_program = BaseModule::ProgramObjectManager.request(
|
||||
program,
|
||||
[&]() -> std::unique_ptr<ghoul::opengl::ProgramObject> {
|
||||
[this, program]() -> std::unique_ptr<ghoul::opengl::ProgramObject> {
|
||||
std::filesystem::path vs =
|
||||
_vertexShaderPath.empty() ?
|
||||
absPath("${MODULE_BASE}/shaders/model_vs.glsl") :
|
||||
@@ -690,7 +689,7 @@ void RenderableModel::update(const UpdateData& data) {
|
||||
glm::compMax(data.modelTransform.scale)
|
||||
);
|
||||
// Set Interaction sphere size to be 10% of the bounding sphere
|
||||
setInteractionSphere(_boundingSphere * 0.1);
|
||||
setInteractionSphere(boundingSphere() * 0.1);
|
||||
|
||||
if (_geometry->hasAnimation() && !_animationStart.empty()) {
|
||||
double relativeTime;
|
||||
|
||||
@@ -153,7 +153,7 @@ RenderableNodeLine::RenderableNodeLine(const ghoul::Dictionary& dictionary)
|
||||
{
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
addProperty(_opacity);
|
||||
addProperty(Fadeable::_opacity);
|
||||
|
||||
_lineColor = p.color.value_or(_lineColor);
|
||||
_lineColor.setViewOption(properties::Property::ViewOptions::Color);
|
||||
@@ -181,7 +181,7 @@ RenderableNodeLine::RenderableNodeLine(const ghoul::Dictionary& dictionary)
|
||||
"Trying to use relative offsets for start node '{}' that has no "
|
||||
"bounding sphere. This will result in no offset. Use direct "
|
||||
"values by setting UseRelativeOffsets to false",
|
||||
_parent->identifier(), _start
|
||||
parent()->identifier(), _start
|
||||
));
|
||||
}
|
||||
});
|
||||
@@ -199,20 +199,20 @@ RenderableNodeLine::RenderableNodeLine(const ghoul::Dictionary& dictionary)
|
||||
"Trying to use relative offsets for end node '{}' that has no "
|
||||
"bounding sphere. This will result in no offset. Use direct "
|
||||
"values by setting UseRelativeOffsets to false",
|
||||
_parent->identifier(), _end
|
||||
parent()->identifier(), _end
|
||||
));
|
||||
}
|
||||
});
|
||||
|
||||
addProperty(_useRelativeOffsets);
|
||||
_useRelativeOffsets.onChange([&]() {
|
||||
_useRelativeOffsets.onChange([this]() {
|
||||
SceneGraphNode* startNode = global::renderEngine->scene()->sceneGraphNode(_start);
|
||||
SceneGraphNode* endNode = global::renderEngine->scene()->sceneGraphNode(_end);
|
||||
|
||||
if (!startNode) {
|
||||
LERROR(fmt::format(
|
||||
"Error when recomputing node line offsets for scene graph node '{}'. "
|
||||
"Could not find start node '{}'", _parent->identifier(), _start.value()
|
||||
"Could not find start node '{}'", parent()->identifier(), _start.value()
|
||||
));
|
||||
return;
|
||||
}
|
||||
@@ -220,7 +220,7 @@ RenderableNodeLine::RenderableNodeLine(const ghoul::Dictionary& dictionary)
|
||||
if (!endNode) {
|
||||
LERROR(fmt::format(
|
||||
"Error when recomputing node line offsets for scene graph node '{}'. "
|
||||
"Could not find end node '{}'", _parent->identifier(), _end.value()
|
||||
"Could not find end node '{}'", parent()->identifier(), _end.value()
|
||||
));
|
||||
return;
|
||||
}
|
||||
@@ -229,8 +229,10 @@ RenderableNodeLine::RenderableNodeLine(const ghoul::Dictionary& dictionary)
|
||||
// Recompute previous offsets to relative values
|
||||
double startBs = startNode->boundingSphere();
|
||||
double endBs = endNode->boundingSphere();
|
||||
_startOffset = startBs > 0.0 ? _startOffset / startBs : 0.0;
|
||||
_endOffset = endBs > 0.0 ? _endOffset / startBs : 0.0;
|
||||
_startOffset =
|
||||
static_cast<float>(startBs > 0.0 ? _startOffset / startBs : 0.0);
|
||||
_endOffset =
|
||||
static_cast<float>(endBs > 0.0 ? _endOffset / startBs : 0.0);
|
||||
}
|
||||
else {
|
||||
// Recompute relative values to meters
|
||||
|
||||
@@ -113,7 +113,7 @@ documentation::Documentation RenderablePlane::Documentation() {
|
||||
}
|
||||
|
||||
RenderablePlane::RenderablePlane(const ghoul::Dictionary& dictionary)
|
||||
: Renderable(dictionary)
|
||||
: Renderable(dictionary, { .automaticallyUpdateRenderBin = false })
|
||||
, _blendMode(BlendModeInfo, properties::OptionProperty::DisplayType::Dropdown)
|
||||
, _billboard(BillboardInfo, false)
|
||||
, _mirrorBackside(MirrorBacksideInfo, false)
|
||||
@@ -122,8 +122,7 @@ RenderablePlane::RenderablePlane(const ghoul::Dictionary& dictionary)
|
||||
{
|
||||
Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
addProperty(_opacity);
|
||||
registerUpdateRenderBinFromOpacity();
|
||||
addProperty(Fadeable::_opacity);
|
||||
|
||||
_size = p.size;
|
||||
_billboard = p.billboard.value_or(_billboard);
|
||||
@@ -133,7 +132,7 @@ RenderablePlane::RenderablePlane(const ghoul::Dictionary& dictionary)
|
||||
{ static_cast<int>(BlendMode::Normal), "Normal" },
|
||||
{ static_cast<int>(BlendMode::Additive), "Additive"}
|
||||
});
|
||||
_blendMode.onChange([&]() {
|
||||
_blendMode.onChange([this]() {
|
||||
switch (_blendMode) {
|
||||
case static_cast<int>(BlendMode::Normal):
|
||||
setRenderBinFromOpacity();
|
||||
@@ -146,7 +145,7 @@ RenderablePlane::RenderablePlane(const ghoul::Dictionary& dictionary)
|
||||
}
|
||||
});
|
||||
|
||||
_opacity.onChange([&]() {
|
||||
_opacity.onChange([this]() {
|
||||
if (_blendMode == static_cast<int>(BlendMode::Normal)) {
|
||||
setRenderBinFromOpacity();
|
||||
}
|
||||
|
||||
@@ -141,21 +141,21 @@ RenderablePrism::RenderablePrism(const ghoul::Dictionary& dictionary)
|
||||
{
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
_nShapeSegments.onChange([&]() { _prismIsDirty = true; });
|
||||
_nShapeSegments.onChange([this]() { _prismIsDirty = true; });
|
||||
_nShapeSegments = p.segments;
|
||||
addProperty(_nShapeSegments);
|
||||
|
||||
_nLines.onChange([&]() { _prismIsDirty = true; });
|
||||
_nLines.onChange([this]() { _prismIsDirty = true; });
|
||||
_nLines = p.lines.value_or(_nShapeSegments);
|
||||
addProperty(_nLines);
|
||||
|
||||
_radius.setExponent(12.f);
|
||||
_radius.onChange([&]() { _prismIsDirty = true; });
|
||||
_radius.onChange([this]() { _prismIsDirty = true; });
|
||||
_radius = p.radius.value_or(_radius);
|
||||
addProperty(_radius);
|
||||
|
||||
_baseRadius.setExponent(12.f);
|
||||
_baseRadius.onChange([&]() { _prismIsDirty = true; });
|
||||
_baseRadius.onChange([this]() { _prismIsDirty = true; });
|
||||
// Use the "regular" radius as default if no value was provided
|
||||
_baseRadius = p.baseRadius.value_or(_radius);
|
||||
addProperty(_baseRadius);
|
||||
@@ -168,11 +168,11 @@ RenderablePrism::RenderablePrism(const ghoul::Dictionary& dictionary)
|
||||
addProperty(_lineColor);
|
||||
|
||||
_length.setExponent(12.f);
|
||||
_length.onChange([&]() { _prismIsDirty = true; });
|
||||
_length.onChange([this]() { _prismIsDirty = true; });
|
||||
_length = p.length.value_or(_length);
|
||||
addProperty(_length);
|
||||
|
||||
addProperty(_opacity);
|
||||
addProperty(Fadeable::_opacity);
|
||||
}
|
||||
|
||||
bool RenderablePrism::isReady() const {
|
||||
|
||||
@@ -161,8 +161,7 @@ RenderableSphere::RenderableSphere(const ghoul::Dictionary& dictionary)
|
||||
{
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
addProperty(_opacity);
|
||||
registerUpdateRenderBinFromOpacity();
|
||||
addProperty(Fadeable::_opacity);
|
||||
|
||||
_size = p.size;
|
||||
_segments = p.segments;
|
||||
@@ -208,7 +207,6 @@ RenderableSphere::RenderableSphere(const ghoul::Dictionary& dictionary)
|
||||
addProperty(_disableFadeInDistance);
|
||||
|
||||
setBoundingSphere(_size);
|
||||
setRenderBinFromOpacity();
|
||||
}
|
||||
|
||||
bool RenderableSphere::isReady() const {
|
||||
|
||||
@@ -163,8 +163,7 @@ RenderableTimeVaryingSphere::RenderableTimeVaryingSphere(
|
||||
{
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
addProperty(_opacity);
|
||||
registerUpdateRenderBinFromOpacity();
|
||||
addProperty(Fadeable::_opacity);
|
||||
|
||||
_size = p.size;
|
||||
_segments = p.segments;
|
||||
@@ -208,7 +207,6 @@ RenderableTimeVaryingSphere::RenderableTimeVaryingSphere(
|
||||
}
|
||||
|
||||
setBoundingSphere(_size);
|
||||
setRenderBinFromOpacity();
|
||||
}
|
||||
|
||||
bool RenderableTimeVaryingSphere::isReady() const {
|
||||
|
||||
@@ -191,7 +191,7 @@ RenderableTrail::RenderableTrail(const ghoul::Dictionary& dictionary)
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
setRenderBin(RenderBin::Overlay);
|
||||
addProperty(_opacity);
|
||||
addProperty(Fadeable::_opacity);
|
||||
|
||||
_translation = Translation::createFromDictionary(
|
||||
dictionary.value<ghoul::Dictionary>("Translation")
|
||||
@@ -433,7 +433,7 @@ void RenderableTrail::render(const RenderData& data, RendererTasks&) {
|
||||
);
|
||||
const double distance = glm::distance(trailPosWorld, data.camera.eyePositionVec3());
|
||||
|
||||
if (distance > _boundingSphere * DISTANCE_CULLING_RADII) {
|
||||
if (distance > boundingSphere() * DISTANCE_CULLING_RADII) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -208,23 +208,23 @@ void RenderableTrailTrajectory::update(const UpdateData& data) {
|
||||
_totalSampleInterval = _sampleInterval / _timeStampSubsamplingFactor;
|
||||
|
||||
// Cap _numberOfVertices in order to prevent overflow and extreme performance
|
||||
// degredation/RAM usage
|
||||
// degredation/RAM usage
|
||||
_numberOfVertices = std::min(
|
||||
static_cast<unsigned int>(timespan / _totalSampleInterval),
|
||||
maxNumberOfVertices
|
||||
);
|
||||
|
||||
// We need to recalcuate the _totalSampleInterval if _numberOfVertices eqals
|
||||
// maxNumberOfVertices. If we don't do this the position for each vertex
|
||||
// maxNumberOfVertices. If we don't do this the position for each vertex
|
||||
// will not be correct for the number of vertices we are doing along the trail.
|
||||
_totalSampleInterval = (_numberOfVertices == maxNumberOfVertices) ?
|
||||
_totalSampleInterval = (_numberOfVertices == maxNumberOfVertices) ?
|
||||
(timespan / _numberOfVertices) : _totalSampleInterval;
|
||||
|
||||
// Make space for the vertices
|
||||
_vertexArray.clear();
|
||||
_vertexArray.resize(_numberOfVertices);
|
||||
}
|
||||
|
||||
|
||||
// Calculate sweeping range for this iteration
|
||||
unsigned int startIndex = _sweepIteration * _sweepChunkSize;
|
||||
unsigned int nextIndex = (_sweepIteration + 1) * _sweepChunkSize;
|
||||
@@ -249,12 +249,12 @@ void RenderableTrailTrajectory::update(const UpdateData& data) {
|
||||
_sweepIteration = 0;
|
||||
setBoundingSphere(glm::distance(_maxVertex, _minVertex) / 2.f);
|
||||
}
|
||||
else {
|
||||
// Early return as we don't need to render if we are still
|
||||
else {
|
||||
// Early return as we don't need to render if we are still
|
||||
// doing full sweep calculations
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Upload vertices to the GPU
|
||||
glBindVertexArray(_primaryRenderInformation._vaoID);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _primaryRenderInformation._vBufferID);
|
||||
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
private:
|
||||
|
||||
|
||||
/// Reset some variables to default state
|
||||
void reset();
|
||||
|
||||
@@ -95,7 +95,7 @@ private:
|
||||
/// Tracks sweep iteration, is used to calculate which vertices to work on per frame
|
||||
int _sweepIteration = 0;
|
||||
|
||||
/// How many points do we need to compute given the distance between the
|
||||
/// How many points do we need to compute given the distance between the
|
||||
/// start and end date and the desired sample interval
|
||||
unsigned int _numberOfVertices = 0;
|
||||
|
||||
|
||||
@@ -328,7 +328,9 @@ FixedRotation::FixedRotation(const ghoul::Dictionary& dictionary)
|
||||
{ Axis::Type::CoordinateSystemCompletion, "Coordinate System Completion" }
|
||||
});
|
||||
_xAxis.type.setGroupIdentifier("xAxis");
|
||||
_xAxis.type.onChange([&]() { setPropertyVisibility(_xAxis); });
|
||||
_xAxis.type.onChange(
|
||||
[this, setPropertyVisibility]() { setPropertyVisibility(_xAxis); }
|
||||
);
|
||||
addProperty(_xAxis.type);
|
||||
|
||||
_xAxis.object.setGroupIdentifier("xAxis");
|
||||
@@ -351,7 +353,9 @@ FixedRotation::FixedRotation(const ghoul::Dictionary& dictionary)
|
||||
{ Axis::Type::CoordinateSystemCompletion, "Coordinate System Completion" }
|
||||
});
|
||||
_yAxis.type.setGroupIdentifier("yAxis");
|
||||
_yAxis.type.onChange([&]() { setPropertyVisibility(_yAxis); });
|
||||
_yAxis.type.onChange(
|
||||
[this, setPropertyVisibility]() { setPropertyVisibility(_yAxis); }
|
||||
);
|
||||
addProperty(_yAxis.type);
|
||||
|
||||
_yAxis.object.setGroupIdentifier("yAxis");
|
||||
@@ -371,7 +375,9 @@ FixedRotation::FixedRotation(const ghoul::Dictionary& dictionary)
|
||||
{ Axis::Type::CoordinateSystemCompletion, "Coordinate System Completion" }
|
||||
});
|
||||
_zAxis.type.setGroupIdentifier("zAxis");
|
||||
_zAxis.type.onChange([&]() { setPropertyVisibility(_zAxis); });
|
||||
_zAxis.type.onChange(
|
||||
[this, setPropertyVisibility]() { setPropertyVisibility(_zAxis); }
|
||||
);
|
||||
addProperty(_zAxis.type);
|
||||
|
||||
_zAxis.object.setGroupIdentifier("zAxis");
|
||||
|
||||
@@ -65,7 +65,7 @@ LuaRotation::LuaRotation()
|
||||
{
|
||||
addProperty(_luaScriptFile);
|
||||
|
||||
_luaScriptFile.onChange([&]() {
|
||||
_luaScriptFile.onChange([this]() {
|
||||
requireUpdate();
|
||||
_fileHandle = std::make_unique<ghoul::filesystem::File>(_luaScriptFile.value());
|
||||
_fileHandle->setCallback([this]() { requireUpdate(); });
|
||||
|
||||
@@ -64,7 +64,7 @@ LuaScale::LuaScale()
|
||||
{
|
||||
addProperty(_luaScriptFile);
|
||||
|
||||
_luaScriptFile.onChange([&]() {
|
||||
_luaScriptFile.onChange([this]() {
|
||||
requireUpdate();
|
||||
_fileHandle = std::make_unique<ghoul::filesystem::File>(_luaScriptFile.value());
|
||||
_fileHandle->setCallback([this]() { requireUpdate(); });
|
||||
|
||||
@@ -103,7 +103,7 @@ Fragment getFragment() {
|
||||
// Some of these values could be passed in as uniforms
|
||||
const vec3 lightColorAmbient = vec3(1.0);
|
||||
const vec3 lightColor = vec3(1.0);
|
||||
|
||||
|
||||
vec3 n;
|
||||
if (has_texture_normal) {
|
||||
vec3 normalAlbedo = texture(texture_normal, vs_st).rgb;
|
||||
|
||||
@@ -52,7 +52,7 @@ void main() {
|
||||
gl_Position = positionScreenSpace;
|
||||
vs_st = in_st;
|
||||
vs_screenSpaceDepth = positionScreenSpace.w;
|
||||
|
||||
|
||||
vs_normalViewSpace = normalize(mat3(normalTransform) * (mat3(meshNormalTransform) * in_normal));
|
||||
|
||||
// TBN matrix for normal mapping
|
||||
|
||||
@@ -32,7 +32,7 @@ uniform vec3 color;
|
||||
uniform int renderPhase;
|
||||
uniform float opacity = 1.0;
|
||||
|
||||
// Fragile! Keep in sync with RenderableTrail::render::RenderPhase
|
||||
// Fragile! Keep in sync with RenderableTrail::render::RenderPhase
|
||||
#define RenderPhaseLines 0
|
||||
#define RenderPhasePoints 1
|
||||
|
||||
@@ -49,7 +49,7 @@ Fragment getFragment() {
|
||||
// Use the length of the vector (dot(circCoord, circCoord)) as factor in the
|
||||
// smoothstep to gradually decrease the alpha on the edges of the point
|
||||
vec2 circCoord = 2.0 * gl_PointCoord - 1.0;
|
||||
//float circleClipping = 1.0 - smoothstep(1.0 - Delta, 1.0, dot(circCoord, circCoord));
|
||||
//float circleClipping = 1.0 - smoothstep(1.0 - Delta, 1.0, dot(circCoord, circCoord));
|
||||
float circleClipping = smoothstep(1.0, 1.0 - Delta, dot(circCoord, circCoord));
|
||||
float transparencyCorrection = frag.color.a * circleClipping;
|
||||
if (transparencyCorrection < 0.9) {
|
||||
|
||||
@@ -67,7 +67,7 @@ void main() {
|
||||
id = 1.0 - id;
|
||||
}
|
||||
|
||||
fade = clamp(id * lineFade, 0.0, 1.0);
|
||||
fade = clamp(id * lineFade, 0.0, 1.0);
|
||||
}
|
||||
else {
|
||||
fade = 1.0;
|
||||
@@ -76,8 +76,8 @@ void main() {
|
||||
vs_gPosition = vec4(modelViewTransform * dvec4(in_point_position, 1));
|
||||
vec4 vs_positionClipSpace = projectionTransform * vs_gPosition;
|
||||
vs_positionDepth = vs_positionClipSpace.w;
|
||||
|
||||
gl_PointSize = (stride == 1 || int(modId) % stride == 0) ?
|
||||
|
||||
gl_PointSize = (stride == 1 || int(modId) % stride == 0) ?
|
||||
float(pointSize) : float(pointSize) / 2;
|
||||
gl_Position = z_normalization(vs_positionClipSpace);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ uniform float opacity = 1.0;
|
||||
uniform float lineWidth;
|
||||
uniform vec4 viewport;
|
||||
|
||||
// Fragile! Keep in sync with RenderableTrail::render::RenderPhase
|
||||
// Fragile! Keep in sync with RenderableTrail::render::RenderPhase
|
||||
const int RenderPhaseLines = 0;
|
||||
const int RenderPhasePoints = 1;
|
||||
|
||||
@@ -52,7 +52,7 @@ Fragment getFragment() {
|
||||
// Use the length of the vector (dot(circCoord, circCoord)) as factor in the
|
||||
// smoothstep to gradually decrease the alpha on the edges of the point
|
||||
vec2 circCoord = 2.0 * gl_PointCoord - 1.0;
|
||||
//float circleClipping = 1.0 - smoothstep(1.0 - Delta, 1.0, dot(circCoord, circCoord));
|
||||
//float circleClipping = 1.0 - smoothstep(1.0 - Delta, 1.0, dot(circCoord, circCoord));
|
||||
float circleClipping = smoothstep(1.0, 1.0 - Delta, dot(circCoord, circCoord));
|
||||
float transparencyCorrection = frag.color.a * circleClipping;
|
||||
if (transparencyCorrection < 0.9) {
|
||||
@@ -71,7 +71,7 @@ Fragment getFragment() {
|
||||
double distanceCenter = length(mathLine - xy);
|
||||
double dLW = double(lineWidth);
|
||||
const float blendFactor = 20.0;
|
||||
|
||||
|
||||
if (distanceCenter > dLW) {
|
||||
frag.color.a = 0.0;
|
||||
}
|
||||
@@ -80,7 +80,7 @@ Fragment getFragment() {
|
||||
}
|
||||
|
||||
frag.gPosition = vs_gPosition;
|
||||
|
||||
|
||||
// There is no normal here
|
||||
frag.gNormal = vec4(0.0, 0.0, -1.0, 1.0);
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ void main() {
|
||||
id = 1.0 - id;
|
||||
}
|
||||
|
||||
fade = clamp(id * lineFade, 0.0, 1.0);
|
||||
fade = clamp(id * lineFade, 0.0, 1.0);
|
||||
}
|
||||
else {
|
||||
fade = 1.0;
|
||||
@@ -78,8 +78,8 @@ void main() {
|
||||
vec4 vs_positionClipSpace = projectionTransform * vs_gPosition;
|
||||
vec4 vs_positionNDC = vs_positionClipSpace / vs_positionClipSpace.w;
|
||||
vs_positionDepth = vs_positionClipSpace.w;
|
||||
|
||||
gl_PointSize = (stride == 1 || int(modId) % stride == 0) ?
|
||||
|
||||
gl_PointSize = (stride == 1 || int(modId) % stride == 0) ?
|
||||
float(pointSize) : float(pointSize) / 2;
|
||||
gl_Position = z_normalization(vs_positionClipSpace);
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ LuaTranslation::LuaTranslation()
|
||||
{
|
||||
addProperty(_luaScriptFile);
|
||||
|
||||
_luaScriptFile.onChange([&]() {
|
||||
_luaScriptFile.onChange([this]() {
|
||||
requireUpdate();
|
||||
_fileHandle = std::make_unique<ghoul::filesystem::File>(_luaScriptFile.value());
|
||||
_fileHandle->setCallback([this]() {
|
||||
|
||||
@@ -32,7 +32,7 @@ GUIKeyboardHandler::GUIKeyboardHandler() {
|
||||
_keyConsumed = false;
|
||||
|
||||
global::callback::keyboard->emplace_back(
|
||||
[&](Key, KeyModifier, KeyAction, IsGuiWindow isGuiWindow) -> bool {
|
||||
[this](Key, KeyModifier, KeyAction, IsGuiWindow isGuiWindow) -> bool {
|
||||
const bool previous = _keyConsumed;
|
||||
_keyConsumed = false;
|
||||
return isGuiWindow ? previous : false;
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/scene/scene.h>
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr const char RenderedPathIdentifier[] = "CurrentCameraPath";
|
||||
@@ -31,17 +33,6 @@ constexpr const char DebuggingGuiPath[] = "/Debugging";
|
||||
constexpr glm::vec3 PathColor = glm::vec3(1.0, 1.0, 0.0);
|
||||
constexpr glm::vec3 OrientationLineColor = glm::vec3(0.0, 1.0, 1.0);
|
||||
|
||||
// Conver the input string to a format that is valid as an identifier
|
||||
std::string makeIdentifier(std::string s) {
|
||||
std::replace(s.begin(), s.end(), ' ', '_');
|
||||
std::replace(s.begin(), s.end(), '.', '-');
|
||||
// Remove quotes and apostrophe, since they cause problems
|
||||
// when a string is translated to a script call
|
||||
s.erase(remove(s.begin(), s.end(), '\"'), s.end());
|
||||
s.erase(remove(s.begin(), s.end(), '\''), s.end());
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the current camera path from the path navigation system. The first optional
|
||||
* argument is the number of samples to take along the path (defaults to 100). If a second
|
||||
@@ -190,7 +181,7 @@ std::string makeIdentifier(std::string s) {
|
||||
// previously rendered ones
|
||||
std::string addParentScript = fmt::format(
|
||||
"if openspace.hasSceneGraphNode('{0}') then "
|
||||
"openspace.removeSceneGraphNode('{0}') "
|
||||
"openspace.removeSceneGraphNode('{0}') "
|
||||
"end "
|
||||
"openspace.addSceneGraphNode({{ Identifier = '{0}' }})",
|
||||
RenderedPointsIdentifier
|
||||
@@ -215,23 +206,23 @@ std::string makeIdentifier(std::string s) {
|
||||
"Identifier = 'ControlPoint_" + std::to_string(i) + "',"
|
||||
"Parent = '" + RenderedPointsIdentifier + "',"
|
||||
"Transform = { "
|
||||
"Translation = {"
|
||||
"Type = 'StaticTranslation',"
|
||||
"Position = " + ghoul::to_string(points[i]) + ""
|
||||
"},"
|
||||
"Translation = {"
|
||||
"Type = 'StaticTranslation',"
|
||||
"Position = " + ghoul::to_string(points[i]) + ""
|
||||
"},"
|
||||
"},"
|
||||
"Renderable = {"
|
||||
"Type = 'RenderableSphere',"
|
||||
"Enabled = true,"
|
||||
"Segments = 30,"
|
||||
"Size = " + std::to_string(radius) + ","
|
||||
"Texture = " + colorTexturePath + ""
|
||||
"Type = 'RenderableSphere',"
|
||||
"Enabled = true,"
|
||||
"Segments = 30,"
|
||||
"Size = " + std::to_string(radius) + ","
|
||||
"Texture = " + colorTexturePath + ""
|
||||
"},"
|
||||
"GUI = {"
|
||||
"Name = 'Control Point " + std::to_string(i) + "',"
|
||||
"Path = '" + guiPath + "'"
|
||||
"Name = 'Control Point " + std::to_string(i) + "',"
|
||||
"Path = '" + guiPath + "'"
|
||||
"}"
|
||||
"}";
|
||||
"}";
|
||||
|
||||
global::scriptEngine->queueScript(
|
||||
fmt::format("openspace.addSceneGraphNode({})", node),
|
||||
@@ -280,21 +271,21 @@ std::string makeIdentifier(std::string s) {
|
||||
"Identifier = '" + identifier + "',"
|
||||
"Parent = '" + nodeIdentifier + "',"
|
||||
"Transform = { "
|
||||
"Scale = {"
|
||||
"Type = 'StaticScale',"
|
||||
"Scale = " + std::to_string(*scale) + ""
|
||||
"}"
|
||||
"Scale = {"
|
||||
"Type = 'StaticScale',"
|
||||
"Scale = " + std::to_string(*scale) + ""
|
||||
"}"
|
||||
"},"
|
||||
"Renderable = {"
|
||||
"Type = 'RenderableCartesianAxes',"
|
||||
"Enabled = true,"
|
||||
"XColor = { 1.0, 0.0, 0.0 },"
|
||||
"YColor = { 0.0, 1.0, 0.0 },"
|
||||
"ZColor = { 0.0, 0.0, 1.0 }"
|
||||
"Type = 'RenderableCartesianAxes',"
|
||||
"Enabled = true,"
|
||||
"XColor = { 1.0, 0.0, 0.0 },"
|
||||
"YColor = { 0.0, 1.0, 0.0 },"
|
||||
"ZColor = { 0.0, 0.0, 1.0 }"
|
||||
"},"
|
||||
"GUI = {"
|
||||
"Name = '" + identifier + "',"
|
||||
"Path = '" + DebuggingGuiPath + "/Coordiante Systems'"
|
||||
"Name = '" + identifier + "',"
|
||||
"Path = '" + DebuggingGuiPath + "/Coordiante Systems'"
|
||||
"}"
|
||||
"}";
|
||||
|
||||
|
||||
@@ -106,14 +106,7 @@ namespace {
|
||||
"Enables/Disables the drawing of the astronomical objects"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo DrawLabelInfo = {
|
||||
"DrawLabels",
|
||||
"Draw Labels",
|
||||
"Determines whether labels should be drawn or hidden"
|
||||
};
|
||||
|
||||
static const openspace::properties::PropertyOwner::PropertyOwnerInfo LabelsInfo =
|
||||
{
|
||||
static const openspace::properties::PropertyOwner::PropertyOwnerInfo LabelsInfo = {
|
||||
"Labels",
|
||||
"Labels",
|
||||
"The labels for the astronomical objects"
|
||||
@@ -251,9 +244,6 @@ namespace {
|
||||
// The number of sides for the polygon used to represent the astronomical object
|
||||
std::optional<int> polygonSides;
|
||||
|
||||
// [[codegen::verbatim(DrawLabelInfo.description)]]
|
||||
std::optional<bool> drawLabels;
|
||||
|
||||
// [[codegen::verbatim(LabelsInfo.description)]]
|
||||
std::optional<ghoul::Dictionary> labels
|
||||
[[codegen::reference("space_labelscomponent")]];
|
||||
@@ -308,7 +298,6 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di
|
||||
, _pointColor(ColorInfo, glm::vec3(1.f), glm::vec3(0.f), glm::vec3(1.f))
|
||||
, _spriteTexturePath(SpriteTextureInfo)
|
||||
, _drawElements(DrawElementsInfo, true)
|
||||
, _drawLabels(DrawLabelInfo, false)
|
||||
, _pixelSizeControl(PixelSizeControlInfo, false)
|
||||
, _colorOption(ColorOptionInfo, properties::OptionProperty::DisplayType::Dropdown)
|
||||
, _optionColorRangeData(OptionColorRangeInfo, glm::vec2(0.f))
|
||||
@@ -345,7 +334,7 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di
|
||||
_useColorMap = p.useColorMap.value_or(_useColorMap);
|
||||
|
||||
_drawElements = p.drawElements.value_or(_drawElements);
|
||||
_drawElements.onChange([&]() { _hasSpeckFile = !_hasSpeckFile; });
|
||||
_drawElements.onChange([this]() { _hasSpeckFile = !_hasSpeckFile; });
|
||||
addProperty(_drawElements);
|
||||
|
||||
_renderOption.addOption(RenderOption::ViewDirection, "Camera View Direction");
|
||||
@@ -368,7 +357,7 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di
|
||||
|
||||
if (p.texture.has_value()) {
|
||||
_spriteTexturePath = absPath(*p.texture).string();
|
||||
_spriteTexturePath.onChange([&]() { _spriteTextureIsDirty = true; });
|
||||
_spriteTexturePath.onChange([this]() { _spriteTextureIsDirty = true; });
|
||||
|
||||
// @TODO (abock, 2021-01-31) I don't know why we only add this property if the
|
||||
// texture is given, but I think it's a bug
|
||||
@@ -389,7 +378,7 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di
|
||||
_colorOptionString = opts[i];
|
||||
}
|
||||
}
|
||||
_colorOption.onChange([&]() {
|
||||
_colorOption.onChange([this]() {
|
||||
_dataIsDirty = true;
|
||||
const glm::vec2 colorRange = _colorRangeData[_colorOption.value()];
|
||||
_optionColorRangeData = colorRange;
|
||||
@@ -401,7 +390,7 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di
|
||||
if (!_colorRangeData.empty()) {
|
||||
_optionColorRangeData = _colorRangeData[_colorRangeData.size() - 1];
|
||||
}
|
||||
_optionColorRangeData.onChange([&]() {
|
||||
_optionColorRangeData.onChange([this]() {
|
||||
const glm::vec2 colorRange = _optionColorRangeData;
|
||||
_colorRangeData[_colorOption.value()] = colorRange;
|
||||
_dataIsDirty = true;
|
||||
@@ -415,7 +404,7 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di
|
||||
_pointColor.setViewOption(properties::Property::ViewOptions::Color);
|
||||
addProperty(_pointColor);
|
||||
|
||||
addProperty(_opacity);
|
||||
addProperty(Fadeable::_opacity);
|
||||
|
||||
_scaleFactor = p.scaleFactor.value_or(_scaleFactor);
|
||||
addProperty(_scaleFactor);
|
||||
@@ -428,7 +417,7 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di
|
||||
_datavarSizeOptionString = opts[i];
|
||||
}
|
||||
|
||||
_datavarSizeOption.onChange([&]() {
|
||||
_datavarSizeOption.onChange([this]() {
|
||||
_dataIsDirty = true;
|
||||
_datavarSizeOptionString = _optionConversionSizeMap[_datavarSizeOption];
|
||||
});
|
||||
@@ -441,12 +430,11 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di
|
||||
_hasPolygon = p.polygonSides.has_value();
|
||||
|
||||
if (p.labels.has_value()) {
|
||||
_drawLabels = p.drawLabels.value_or(_drawLabels);
|
||||
addProperty(_drawLabels);
|
||||
|
||||
_labels = std::make_unique<LabelsComponent>(*p.labels);
|
||||
_hasLabels = true;
|
||||
addPropertySubOwner(_labels.get());
|
||||
// Fading of the labels should also depend on the fading of the renderable
|
||||
_labels->setParentFadeable(this);
|
||||
}
|
||||
|
||||
_transformationMatrix = p.transformationMatrix.value_or(_transformationMatrix);
|
||||
@@ -496,7 +484,7 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di
|
||||
addProperty(_useColorMap);
|
||||
|
||||
_useLinearFiltering = p.useLinearFiltering.value_or(_useLinearFiltering);
|
||||
_useLinearFiltering.onChange([&]() { _dataIsDirty = true; });
|
||||
_useLinearFiltering.onChange([this]() { _dataIsDirty = true; });
|
||||
addProperty(_useLinearFiltering);
|
||||
}
|
||||
|
||||
@@ -624,9 +612,7 @@ void RenderableBillboardsCloud::renderBillboards(const RenderData& data,
|
||||
_program->setUniform(_uniformCache.modelMatrix, modelMatrix);
|
||||
_program->setUniform(
|
||||
_uniformCache.cameraViewProjectionMatrix,
|
||||
glm::mat4(
|
||||
glm::dmat4(data.camera.projectionMatrix()) * data.camera.combinedViewMatrix()
|
||||
)
|
||||
glm::dmat4(data.camera.projectionMatrix()) * data.camera.combinedViewMatrix()
|
||||
);
|
||||
|
||||
const float minBillboardSize = _billboardMinMaxSize.value().x; // in pixels
|
||||
@@ -698,9 +684,9 @@ void RenderableBillboardsCloud::render(const RenderData& data, RendererTasks&) {
|
||||
glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale));
|
||||
|
||||
glm::dmat4 modelViewMatrix = data.camera.combinedViewMatrix() * modelMatrix;
|
||||
glm::mat4 projectionMatrix = data.camera.projectionMatrix();
|
||||
glm::dmat4 projectionMatrix = glm::dmat4(data.camera.projectionMatrix());
|
||||
|
||||
glm::dmat4 modelViewProjectionMatrix = glm::dmat4(projectionMatrix) * modelViewMatrix;
|
||||
glm::dmat4 modelViewProjectionMatrix = projectionMatrix * modelViewMatrix;
|
||||
|
||||
glm::dvec3 cameraViewDirectionWorld = -data.camera.viewDirectionWorldSpace();
|
||||
glm::dvec3 cameraUpDirectionWorld = data.camera.lookUpVectorWorldSpace();
|
||||
@@ -721,7 +707,7 @@ void RenderableBillboardsCloud::render(const RenderData& data, RendererTasks&) {
|
||||
renderBillboards(data, modelMatrix, orthoRight, orthoUp, fadeInVar);
|
||||
}
|
||||
|
||||
if (_drawLabels && _hasLabels) {
|
||||
if (_hasLabels) {
|
||||
_labels->render(data, modelViewProjectionMatrix, orthoRight, orthoUp, fadeInVar);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +98,6 @@ private:
|
||||
properties::Vec3Property _pointColor;
|
||||
properties::StringProperty _spriteTexturePath;
|
||||
properties::BoolProperty _drawElements;
|
||||
properties::BoolProperty _drawLabels;
|
||||
properties::BoolProperty _pixelSizeControl;
|
||||
properties::OptionProperty _colorOption;
|
||||
properties::Vec2Property _optionColorRangeData;
|
||||
|
||||
@@ -188,12 +188,11 @@ RenderableDUMeshes::RenderableDUMeshes(const ghoul::Dictionary& dictionary)
|
||||
{
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
addProperty(_opacity);
|
||||
registerUpdateRenderBinFromOpacity();
|
||||
addProperty(Fadeable::_opacity);
|
||||
|
||||
_speckFile = absPath(p.file).string();
|
||||
_hasSpeckFile = true;
|
||||
_drawElements.onChange([&]() { _hasSpeckFile = !_hasSpeckFile; });
|
||||
_drawElements.onChange([this]() { _hasSpeckFile = !_hasSpeckFile; });
|
||||
addProperty(_drawElements);
|
||||
|
||||
_renderOption.addOption(RenderOptionViewDirection, "Camera View Direction");
|
||||
@@ -229,7 +228,7 @@ RenderableDUMeshes::RenderableDUMeshes(const ghoul::Dictionary& dictionary)
|
||||
_hasLabel = p.textColor.has_value();
|
||||
_textColor.setViewOption(properties::Property::ViewOptions::Color);
|
||||
addProperty(_textColor);
|
||||
_textColor.onChange([&]() { _textColorIsDirty = true; });
|
||||
_textColor.onChange([this]() { _textColorIsDirty = true; });
|
||||
|
||||
_textOpacity = p.textOpacity.value_or(_textOpacity);
|
||||
addProperty(_textOpacity);
|
||||
|
||||
@@ -211,12 +211,12 @@ RenderablePlanesCloud::RenderablePlanesCloud(const ghoul::Dictionary& dictionary
|
||||
{
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
addProperty(_opacity);
|
||||
addProperty(Fadeable::_opacity);
|
||||
|
||||
if (p.file.has_value()) {
|
||||
_speckFile = absPath(*p.file);
|
||||
_hasSpeckFile = true;
|
||||
_drawElements.onChange([&]() { _hasSpeckFile = !_hasSpeckFile; });
|
||||
_drawElements.onChange([this]() { _hasSpeckFile = !_hasSpeckFile; });
|
||||
addProperty(_drawElements);
|
||||
}
|
||||
|
||||
@@ -236,12 +236,14 @@ RenderablePlanesCloud::RenderablePlanesCloud(const ghoul::Dictionary& dictionary
|
||||
|
||||
_scaleFactor = p.scaleFactor.value_or(_scaleFactor);
|
||||
addProperty(_scaleFactor);
|
||||
_scaleFactor.onChange([&]() { _dataIsDirty = true; });
|
||||
_scaleFactor.onChange([this]() { _dataIsDirty = true; });
|
||||
|
||||
if (p.labels.has_value()) {
|
||||
_labels = std::make_unique<LabelsComponent>(*p.labels);
|
||||
_hasLabels = true;
|
||||
addPropertySubOwner(_labels.get());
|
||||
// Fading of the labels should also depend on the fading of the renderable
|
||||
_labels->setParentFadeable(this);
|
||||
}
|
||||
|
||||
_transformationMatrix = p.transformationMatrix.value_or(_transformationMatrix);
|
||||
@@ -250,7 +252,7 @@ RenderablePlanesCloud::RenderablePlanesCloud(const ghoul::Dictionary& dictionary
|
||||
{ BlendModeNormal, "Normal" },
|
||||
{ BlendModeAdditive, "Additive" }
|
||||
});
|
||||
_blendMode.onChange([&]() {
|
||||
_blendMode.onChange([this]() {
|
||||
switch (_blendMode) {
|
||||
case BlendModeNormal:
|
||||
setRenderBin(Renderable::RenderBin::Opaque);
|
||||
|
||||
@@ -129,8 +129,7 @@ RenderablePoints::RenderablePoints(const ghoul::Dictionary& dictionary)
|
||||
{
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
addProperty(_opacity);
|
||||
registerUpdateRenderBinFromOpacity();
|
||||
addProperty(Fadeable::_opacity);
|
||||
|
||||
_speckFile = absPath(p.file);
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ Fragment getFragment() {
|
||||
}
|
||||
|
||||
vec4 fullColor = textureColor;
|
||||
|
||||
|
||||
if (hasColorMap && useColorMap) {
|
||||
fullColor *= gs_colorMap;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ out float ta;
|
||||
// General settings
|
||||
uniform float scaleFactor;
|
||||
uniform int renderOption;
|
||||
uniform mat4 cameraViewProjectionMatrix;
|
||||
uniform dmat4 cameraViewProjectionMatrix;
|
||||
uniform dmat4 modelMatrix;
|
||||
uniform bool enabledRectSizeControl;
|
||||
uniform bool hasDvarScaling;
|
||||
@@ -63,7 +63,7 @@ const double PARSEC = 0.308567756e17LF;
|
||||
|
||||
const vec2 corners[4] = vec2[4](
|
||||
vec2(0.0, 0.0),
|
||||
vec2(1.0, 0.0),
|
||||
vec2(1.0, 0.0),
|
||||
vec2(1.0, 1.0),
|
||||
vec2(0.0, 1.0)
|
||||
);
|
||||
@@ -76,7 +76,7 @@ void main() {
|
||||
ta = 1.0;
|
||||
vec4 pos = gl_in[0].gl_Position;
|
||||
gs_colorMap = colorMap[0];
|
||||
|
||||
|
||||
double unit = PARSEC;
|
||||
|
||||
// Must be the same as the enum in RenderableBillboardsCloud.h
|
||||
@@ -96,10 +96,10 @@ void main() {
|
||||
if (hasDvarScaling) {
|
||||
scaleMultiply *= dvarScaling[0];
|
||||
}
|
||||
|
||||
|
||||
vec3 scaledRight = vec3(0.0);
|
||||
vec3 scaledUp = vec3(0.0);
|
||||
|
||||
|
||||
if (renderOption == RenderOptionCameraViewDirection) {
|
||||
scaledRight = scaleMultiply * right * 0.5;
|
||||
scaledUp = scaleMultiply * up * 0.5;
|
||||
@@ -119,27 +119,27 @@ void main() {
|
||||
scaledRight = scaleMultiply * newRight * 0.5;
|
||||
scaledUp = scaleMultiply * newUp * 0.5;
|
||||
}
|
||||
|
||||
|
||||
if (enabledRectSizeControl) {
|
||||
vec4 initialPosition = z_normalization(cameraViewProjectionMatrix *
|
||||
vec4(vec3(dpos.xyz) - scaledRight - scaledUp, dpos.w));
|
||||
|
||||
vec4 initialPosition = z_normalization(vec4(cameraViewProjectionMatrix *
|
||||
dvec4(dpos.xyz - dvec3(scaledRight - scaledUp), dpos.w)));
|
||||
|
||||
vs_screenSpaceDepth = initialPosition.w;
|
||||
|
||||
vec4 crossCorner = z_normalization(cameraViewProjectionMatrix *
|
||||
vec4(vec3(dpos.xyz) + scaledUp + scaledRight, dpos.w));
|
||||
|
||||
|
||||
vec4 crossCorner = z_normalization(vec4(cameraViewProjectionMatrix *
|
||||
dvec4(dpos.xyz + dvec3(scaledRight + scaledUp), dpos.w)));
|
||||
|
||||
// Testing size for rectangular viewport:
|
||||
vec2 halfViewSize = screenSize * 0.5;
|
||||
vec2 topRight = crossCorner.xy / crossCorner.w;
|
||||
vec2 bottomLeft = initialPosition.xy / initialPosition.w;
|
||||
|
||||
|
||||
// width and height
|
||||
vec2 sizes = abs(halfViewSize * (topRight - bottomLeft));
|
||||
|
||||
|
||||
if (enabledRectSizeControl && (length(sizes) > maxBillboardSize)) {
|
||||
float correctionScale = maxBillboardSize / length(sizes);
|
||||
|
||||
|
||||
scaledRight *= correctionScale;
|
||||
scaledUp *= correctionScale;
|
||||
}
|
||||
@@ -158,9 +158,9 @@ void main() {
|
||||
}
|
||||
|
||||
// Saving one matrix multiplication:
|
||||
vec4 dposClip = cameraViewProjectionMatrix * vec4(dpos);
|
||||
vec4 scaledRightClip = cameraViewProjectionMatrix * vec4(scaledRight, 0.0);
|
||||
vec4 scaledUpClip = cameraViewProjectionMatrix * vec4(scaledUp, 0.0);
|
||||
vec4 dposClip = vec4(cameraViewProjectionMatrix * dpos);
|
||||
vec4 scaledRightClip = vec4(cameraViewProjectionMatrix * dvec4(scaledRight, 0.0));
|
||||
vec4 scaledUpClip = vec4(cameraViewProjectionMatrix * dvec4(scaledUp, 0.0));
|
||||
|
||||
vec4 initialPosition = z_normalization(dposClip - scaledRightClip - scaledUpClip);
|
||||
vs_screenSpaceDepth = initialPosition.w;
|
||||
@@ -172,7 +172,7 @@ void main() {
|
||||
texCoord = corners[0];
|
||||
gl_Position = initialPosition;
|
||||
EmitVertex();
|
||||
|
||||
|
||||
texCoord = corners[1];
|
||||
gl_Position = secondPosition;
|
||||
EmitVertex();
|
||||
@@ -180,10 +180,10 @@ void main() {
|
||||
texCoord = corners[3];
|
||||
gl_Position = thirdPosition;
|
||||
EmitVertex();
|
||||
|
||||
|
||||
texCoord = corners[2];
|
||||
gl_Position = crossCorner;
|
||||
EmitVertex();
|
||||
|
||||
|
||||
EndPrimitive();
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ const float PI = 3.1415926;
|
||||
|
||||
void main() {
|
||||
vec4 v0 = gl_in[0].gl_Position;
|
||||
|
||||
|
||||
for (int i = sides; i > 0; --i) {
|
||||
// Angle between each side in radians
|
||||
float ang = 2.0 * PI / float(sides) * i;
|
||||
|
||||
@@ -44,6 +44,6 @@ Fragment getFragment() {
|
||||
// JCC: Need to change the position to camera space
|
||||
frag.gPosition = vs_positionViewSpace;
|
||||
frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
@@ -154,13 +154,6 @@ glm::dmat3 computeSystemRotation(glm::dvec3 starPosition) {
|
||||
);
|
||||
}
|
||||
|
||||
std::string createIdentifier(std::string name) {
|
||||
std::replace(name.begin(), name.end(), ' ', '_');
|
||||
std::replace(name.begin(), name.end(), '.', '-');
|
||||
sanitizeNameString(name);
|
||||
return name;
|
||||
}
|
||||
|
||||
void sanitizeNameString(std::string& s) {
|
||||
// We want to avoid quotes and apostrophes in names, since they cause problems
|
||||
// when a string is translated to a script call
|
||||
|
||||
@@ -108,9 +108,6 @@ glm::dmat4 computeOrbitPlaneRotationMatrix(float i, float bigom = 180.f,
|
||||
// so that x is pointing from star to the sun.
|
||||
glm::dmat3 computeSystemRotation(glm::dvec3 starPosition);
|
||||
|
||||
// Create an identifier without whitespaces
|
||||
std::string createIdentifier(std::string name);
|
||||
|
||||
void sanitizeNameString(std::string& s);
|
||||
|
||||
} // namespace openspace::exoplanets
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#include <openspace/query/query.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <openspace/util/distanceconstants.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
@@ -123,7 +124,7 @@ void createExoplanetSystem(const std::string& starName) {
|
||||
using namespace openspace;
|
||||
using namespace exoplanets;
|
||||
|
||||
const std::string starIdentifier = createIdentifier(starName);
|
||||
const std::string starIdentifier = makeIdentifier(starName);
|
||||
|
||||
std::string sanitizedStarName = starName;
|
||||
sanitizeNameString(sanitizedStarName);
|
||||
@@ -286,7 +287,7 @@ void createExoplanetSystem(const std::string& starName) {
|
||||
double semiMajorAxisInMeter = planet.a * distanceconstants::AstronomicalUnit;
|
||||
double semiMajorAxisInKm = semiMajorAxisInMeter * 0.001;
|
||||
|
||||
const std::string planetIdentifier = createIdentifier(planetName);
|
||||
const std::string planetIdentifier = makeIdentifier(planetName);
|
||||
|
||||
const std::string planetKeplerTranslation = "{"
|
||||
"Type = 'KeplerTranslation',"
|
||||
@@ -631,7 +632,7 @@ std::vector<std::string> hostStarsWithSufficientData() {
|
||||
[[codegen::luawrap]] void removeExoplanetSystem(std::string starName) {
|
||||
using namespace openspace;
|
||||
using namespace exoplanets;
|
||||
const std::string starIdentifier = createIdentifier(std::move(starName));
|
||||
const std::string starIdentifier = makeIdentifier(std::move(starName));
|
||||
global::scriptEngine->queueScript(
|
||||
"openspace.removeSceneGraphNode('" + starIdentifier + "');",
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
|
||||
@@ -117,17 +117,17 @@ RenderableOrbitDisc::RenderableOrbitDisc(const ghoul::Dictionary& dictionary)
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
_offset = p.offset.value_or(_offset);
|
||||
_offset.onChange([&]() { _planeIsDirty = true; });
|
||||
_offset.onChange([this]() { _planeIsDirty = true; });
|
||||
addProperty(_offset);
|
||||
|
||||
_size = p.size;
|
||||
_size.onChange([&]() { _planeIsDirty = true; });
|
||||
_size.onChange([this]() { _planeIsDirty = true; });
|
||||
addProperty(_size);
|
||||
|
||||
setBoundingSphere(_size + _offset.value().y * _size);
|
||||
|
||||
_texturePath = p.texture.string();
|
||||
_texturePath.onChange([&]() { _texture->loadFromFile(_texturePath.value()); });
|
||||
_texturePath.onChange([this]() { _texture->loadFromFile(_texturePath.value()); });
|
||||
addProperty(_texturePath);
|
||||
|
||||
_multiplyColor = p.multiplyColor.value_or(_multiplyColor);
|
||||
@@ -135,10 +135,10 @@ RenderableOrbitDisc::RenderableOrbitDisc(const ghoul::Dictionary& dictionary)
|
||||
addProperty(_multiplyColor);
|
||||
|
||||
_eccentricity = p.eccentricity;
|
||||
_eccentricity.onChange([&]() { _planeIsDirty = true; });
|
||||
_eccentricity.onChange([this]() { _planeIsDirty = true; });
|
||||
addProperty(_eccentricity);
|
||||
|
||||
addProperty(_opacity);
|
||||
addProperty(Fadeable::_opacity);
|
||||
}
|
||||
|
||||
bool RenderableOrbitDisc::isReady() const {
|
||||
|
||||
@@ -45,7 +45,7 @@ Fragment getFragment() {
|
||||
}
|
||||
|
||||
frag.depth = pscDepth(gs_position);
|
||||
|
||||
|
||||
// G-Buffer
|
||||
frag.gPosition = vec4(0.0);//vs_gPosition;
|
||||
// There is no normal here
|
||||
|
||||
@@ -577,7 +577,7 @@ bool RenderableFieldlinesSequence::prepareForOsflsStreaming() {
|
||||
_states.push_back(newState);
|
||||
_nStates = _startTimes.size();
|
||||
if (_nStates == 1) {
|
||||
// loading dynamicaly is not nessesary if only having one set in the sequence
|
||||
// loading dynamicaly is not nessesary if only having one set in the sequence
|
||||
_loadingStatesDynamically = false;
|
||||
}
|
||||
_activeStateIndex = 0;
|
||||
@@ -1046,7 +1046,7 @@ void RenderableFieldlinesSequence::update(const UpdateData& data) {
|
||||
const double currentTime = data.time.j2000Seconds();
|
||||
const bool isInInterval = (currentTime >= _startTimes[0]) &&
|
||||
(currentTime < _sequenceEndTime);
|
||||
|
||||
|
||||
// Check if current time in OpenSpace is within sequence interval
|
||||
if (isInInterval) {
|
||||
const size_t nextIdx = _activeTriggerTimeIndex + 1;
|
||||
|
||||
@@ -108,7 +108,7 @@ private:
|
||||
// line segments
|
||||
bool _shouldUpdateMaskingBuffer = false;
|
||||
// note Elon: rework the case of only one state
|
||||
// hasBeenUpdated only gets sets once, first iteration of update function, to
|
||||
// hasBeenUpdated only gets sets once, first iteration of update function, to
|
||||
// guarantee the vertext position buffer to be initialized.
|
||||
bool _hasBeenUpdated = false;
|
||||
|
||||
|
||||
@@ -487,7 +487,7 @@ RenderableGaiaStars::RenderableGaiaStars(const ghoul::Dictionary& dictionary)
|
||||
if (p.renderMode.has_value()) {
|
||||
_renderMode = codegen::map<gaia::RenderMode>(*p.renderMode);
|
||||
}
|
||||
_renderMode.onChange([&]() { _buffersAreDirty = true; });
|
||||
_renderMode.onChange([this]() { _buffersAreDirty = true; });
|
||||
addProperty(_renderMode);
|
||||
|
||||
_shaderOption.addOptions({
|
||||
@@ -511,7 +511,7 @@ RenderableGaiaStars::RenderableGaiaStars(const ghoul::Dictionary& dictionary)
|
||||
}
|
||||
#endif // __APPLE__
|
||||
}
|
||||
_shaderOption.onChange([&]() {
|
||||
_shaderOption.onChange([this]() {
|
||||
_buffersAreDirty = true;
|
||||
_shadersAreDirty = true;
|
||||
});
|
||||
@@ -547,7 +547,7 @@ RenderableGaiaStars::RenderableGaiaStars(const ghoul::Dictionary& dictionary)
|
||||
_lodPixelThreshold = p.lodPixelThreshold.value_or(_lodPixelThreshold);
|
||||
|
||||
_maxGpuMemoryPercent = p.maxGpuMemoryPercent.value_or(_maxGpuMemoryPercent);
|
||||
_maxGpuMemoryPercent.onChange([&]() {
|
||||
_maxGpuMemoryPercent.onChange([this]() {
|
||||
if (_ssboData != 0) {
|
||||
glDeleteBuffers(1, &_ssboData);
|
||||
glGenBuffers(1, &_ssboData);
|
||||
@@ -594,11 +594,11 @@ RenderableGaiaStars::RenderableGaiaStars(const ghoul::Dictionary& dictionary)
|
||||
// Only add properties correlated to fits files if we're reading from a fits file.
|
||||
if (_fileReaderOption == gaia::FileReaderOption::Fits) {
|
||||
_firstRow = p.firstRow.value_or(_firstRow);
|
||||
_firstRow.onChange([&]() { _dataIsDirty = true; });
|
||||
_firstRow.onChange([this]() { _dataIsDirty = true; });
|
||||
addProperty(_firstRow);
|
||||
|
||||
_lastRow = p.lastRow.value_or(_lastRow);
|
||||
_lastRow.onChange([&]() { _dataIsDirty = true; });
|
||||
_lastRow.onChange([this]() { _dataIsDirty = true; });
|
||||
addProperty(_lastRow);
|
||||
|
||||
if (p.columnNames.has_value()) {
|
||||
|
||||
@@ -79,7 +79,7 @@ openspace.gaia.addClippingSphere = function (name, radius)
|
||||
Transform = {
|
||||
Scale = {
|
||||
Type = "StaticScale",
|
||||
Scale = radius * kilo_parsec_in_meter
|
||||
Scale = radius * kilo_parsec_in_meter
|
||||
}
|
||||
},
|
||||
Renderable = {
|
||||
|
||||
@@ -44,7 +44,7 @@ uniform int renderOption;
|
||||
// Keep in sync with gaiaoptions.h:RenderOption enum
|
||||
const int RENDEROPTION_STATIC = 0;
|
||||
const int RENDEROPTION_COLOR = 1;
|
||||
const int RENDEROPTION_MOTION = 2;
|
||||
const int RENDEROPTION_MOTION = 2;
|
||||
const float ONE_PARSEC = 3.08567758e16; // 1 Parsec
|
||||
const float FLT_MAX = 3.402823466e38; // Max float constant in GLSL
|
||||
const float LUM_LOWER_CAP = 0.01;
|
||||
|
||||
@@ -34,7 +34,7 @@ in float vs_cameraDistFromSun[];
|
||||
|
||||
layout(triangle_strip, max_vertices = 4) out;
|
||||
out vec2 ge_brightness;
|
||||
out vec4 ge_gPosition;
|
||||
out vec4 ge_gPosition;
|
||||
out vec2 texCoord;
|
||||
out float ge_starDistFromSun;
|
||||
out float ge_cameraDistFromSun;
|
||||
@@ -54,15 +54,15 @@ uniform float magnitudeBoost;
|
||||
// Keep in sync with gaiaoptions.h:RenderOption enum
|
||||
const int RENDEROPTION_STATIC = 0;
|
||||
const int RENDEROPTION_COLOR = 1;
|
||||
const int RENDEROPTION_MOTION = 2;
|
||||
const int RENDEROPTION_MOTION = 2;
|
||||
const float EPS = 1e-5;
|
||||
|
||||
|
||||
const vec2 corners[4] = vec2[4](
|
||||
vec2(0.0, 1.0),
|
||||
vec2(0.0, 0.0),
|
||||
vec2(1.0, 1.0),
|
||||
vec2(1.0, 0.0)
|
||||
vec2(0.0, 1.0),
|
||||
vec2(0.0, 0.0),
|
||||
vec2(1.0, 1.0),
|
||||
vec2(1.0, 0.0)
|
||||
);
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ void main() {
|
||||
// Big positive magnitude => Dwarfs
|
||||
float absoluteMagnitude = vs_brightness[0].x;
|
||||
float normalizedMagnitude = (absoluteMagnitude - 20) / -1; // (-15 - 20);
|
||||
|
||||
|
||||
// TODO: A linear scale is prabably not the best!
|
||||
initStarSize += normalizedMagnitude * (magnitudeBoost / 50);
|
||||
}
|
||||
@@ -102,9 +102,9 @@ void main() {
|
||||
if (length(position) < EPS || distThreshold <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
vec4 centerWorldPos = vs_gPosition[0];
|
||||
|
||||
|
||||
dvec3 cameraNormal = normalize(cameraPos - dvec3(centerWorldPos.xyz));
|
||||
dvec3 newRight = normalize(cross(cameraLookUp, cameraNormal));
|
||||
dvec3 newUp = cross(cameraNormal, newRight);
|
||||
@@ -122,7 +122,7 @@ void main() {
|
||||
gl_Position.z = 0.0;
|
||||
texCoord = corners[i];
|
||||
ge_gPosition = viewPosition;
|
||||
|
||||
|
||||
EmitVertex();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
|
||||
#include "fragment.glsl"
|
||||
#include "floatoperations.glsl"
|
||||
|
||||
@@ -41,7 +41,7 @@ uniform int renderOption;
|
||||
// Keep in sync with gaiaoptions.h:RenderOption enum
|
||||
const int RENDEROPTION_STATIC = 0;
|
||||
const int RENDEROPTION_COLOR = 1;
|
||||
const int RENDEROPTION_MOTION = 2;
|
||||
const int RENDEROPTION_MOTION = 2;
|
||||
const float ONE_PARSEC = 3.08567758e16; // 1 Parsec
|
||||
const float DEFAULT_DEPTH = 3.08567758e19; // 1000 Pc
|
||||
const float LUM_LOWER_CAP = 0.01;
|
||||
@@ -114,7 +114,7 @@ Fragment getFragment() {
|
||||
|
||||
Fragment frag;
|
||||
frag.color = vec4(color, textureColor.a);;
|
||||
// Place stars at back to begin with.
|
||||
// Place stars at back to begin with.
|
||||
frag.depth = DEFAULT_DEPTH;
|
||||
frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
frag.blend = BLEND_MODE_NORMAL;
|
||||
|
||||
@@ -42,7 +42,7 @@ uniform float viewScaling;
|
||||
// Keep in sync with gaiaoptions.h:RenderOption enum
|
||||
const int RENDEROPTION_STATIC = 0;
|
||||
const int RENDEROPTION_COLOR = 1;
|
||||
const int RENDEROPTION_MOTION = 2;
|
||||
const int RENDEROPTION_MOTION = 2;
|
||||
const float ONE_PARSEC = 3.08567758e16; // 1 Parsec
|
||||
const float LUM_LOWER_CAP = 0.01;
|
||||
|
||||
|
||||
@@ -26,11 +26,11 @@
|
||||
|
||||
#include "floatoperations.glsl"
|
||||
|
||||
layout (std430) buffer ssbo_idx_data {
|
||||
layout (std430) buffer ssbo_idx_data {
|
||||
int starsPerChunk[];
|
||||
};
|
||||
|
||||
layout (std430) buffer ssbo_comb_data {
|
||||
layout (std430) buffer ssbo_comb_data {
|
||||
float allData[];
|
||||
};
|
||||
|
||||
@@ -42,7 +42,7 @@ out float vs_cameraDistFromSun;
|
||||
uniform dmat4 model;
|
||||
uniform dmat4 view;
|
||||
uniform dmat4 projection;
|
||||
uniform float time;
|
||||
uniform float time;
|
||||
uniform int renderOption;
|
||||
uniform int maxStarsPerNode;
|
||||
uniform int valuesPerStar;
|
||||
@@ -57,7 +57,7 @@ uniform vec2 distThreshold;
|
||||
// Keep in sync with gaiaoptions.h:RenderOption enum
|
||||
const int RENDEROPTION_STATIC = 0;
|
||||
const int RENDEROPTION_COLOR = 1;
|
||||
const int RENDEROPTION_MOTION = 2;
|
||||
const int RENDEROPTION_MOTION = 2;
|
||||
const float EPS = 1e-5;
|
||||
const float Parsec = 3.0856776e16;
|
||||
|
||||
@@ -88,7 +88,7 @@ void main() {
|
||||
int chunkId = findChunkId(0, nChunksToRender - 1, gl_VertexID);
|
||||
// Fail safe - this should never happen!
|
||||
if (chunkId == -1) {
|
||||
vs_gPosition = vec4(0.0);
|
||||
vs_gPosition = vec4(0.0);
|
||||
gl_Position = vec4(0.0);
|
||||
return;
|
||||
}
|
||||
@@ -97,28 +97,28 @@ void main() {
|
||||
int nStarsInChunk = starsPerChunk[chunkId + 1] - starsPerChunk[chunkId]; // Stars in current chunk.
|
||||
// Remove possible duplicates
|
||||
if (nStarsInChunk <= 0) {
|
||||
vs_gPosition = vec4(0.0);
|
||||
vs_gPosition = vec4(0.0);
|
||||
gl_Position = vec4(0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int startOfPos = firstStarInChunk + placeInChunk * 3;
|
||||
vec3 in_position = vec3(allData[startOfPos], allData[startOfPos + 1], allData[startOfPos + 2]);
|
||||
vec2 in_brightness = vec2(0.0);
|
||||
vec3 in_velocity = vec3(0.0);
|
||||
|
||||
// Check if we should filter this star by position
|
||||
if ((abs(posXThreshold.x) > EPS && in_position.x < posXThreshold.x) ||
|
||||
(abs(posXThreshold.y) > EPS && in_position.x > posXThreshold.y) ||
|
||||
(abs(posYThreshold.x) > EPS && in_position.y < posYThreshold.x) ||
|
||||
(abs(posYThreshold.y) > EPS && in_position.y > posYThreshold.y) ||
|
||||
(abs(posZThreshold.x) > EPS && in_position.z < posZThreshold.x) ||
|
||||
(abs(posZThreshold.y) > EPS && in_position.z > posZThreshold.y) ||
|
||||
(abs(distThreshold.x - distThreshold.y) < EPS
|
||||
if ((abs(posXThreshold.x) > EPS && in_position.x < posXThreshold.x) ||
|
||||
(abs(posXThreshold.y) > EPS && in_position.x > posXThreshold.y) ||
|
||||
(abs(posYThreshold.x) > EPS && in_position.y < posYThreshold.x) ||
|
||||
(abs(posYThreshold.y) > EPS && in_position.y > posYThreshold.y) ||
|
||||
(abs(posZThreshold.x) > EPS && in_position.z < posZThreshold.x) ||
|
||||
(abs(posZThreshold.y) > EPS && in_position.z > posZThreshold.y) ||
|
||||
(abs(distThreshold.x - distThreshold.y) < EPS
|
||||
&& abs(length(in_position) - distThreshold.y) < EPS))
|
||||
{
|
||||
// Discard star in geometry shader
|
||||
vs_gPosition = vec4(0.0);
|
||||
vs_gPosition = vec4(0.0);
|
||||
gl_Position = vec4(0.0);
|
||||
return;
|
||||
}
|
||||
@@ -130,14 +130,14 @@ void main() {
|
||||
|
||||
// Check if we should filter this star by magnitude or color
|
||||
if ((abs(gMagThreshold.x - gMagThreshold.y) < EPS && abs(gMagThreshold.x - in_brightness.x) < EPS) ||
|
||||
(abs(gMagThreshold.x - 20.0f) > EPS && in_brightness.x < gMagThreshold.x) ||
|
||||
(abs(gMagThreshold.x - 20.0f) > EPS && in_brightness.x < gMagThreshold.x) ||
|
||||
(abs(gMagThreshold.y - 20.0f) > EPS && in_brightness.x > gMagThreshold.y) ||
|
||||
(abs(bpRpThreshold.x - bpRpThreshold.y) < EPS && abs(bpRpThreshold.x - in_brightness.y) < EPS) ||
|
||||
(abs(bpRpThreshold.x) > EPS && in_brightness.y < bpRpThreshold.x) ||
|
||||
(abs(bpRpThreshold.x) > EPS && in_brightness.y < bpRpThreshold.x) ||
|
||||
(abs(bpRpThreshold.y) > EPS && in_brightness.y > bpRpThreshold.y))
|
||||
{
|
||||
// Discard star in geometry shader
|
||||
vs_gPosition = vec4(0.0);
|
||||
vs_gPosition = vec4(0.0);
|
||||
gl_Position = vec4(0.0);
|
||||
return;
|
||||
}
|
||||
@@ -145,7 +145,7 @@ void main() {
|
||||
if (renderOption == RENDEROPTION_MOTION) {
|
||||
int startOfVel = firstStarInChunk + nStarsInChunk * 5 + placeInChunk * 3;
|
||||
in_velocity = vec3(allData[startOfVel], allData[startOfVel + 1], allData[startOfVel + 2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
vs_brightness = in_brightness;
|
||||
|
||||
@@ -157,12 +157,12 @@ void main() {
|
||||
|
||||
// Thres moving stars by their new position
|
||||
float distPosition = length(objectPosition.xyz / (1000.0 * Parsec));
|
||||
if ((abs(distThreshold.x - distThreshold.y) > EPS &&
|
||||
((abs(distThreshold.x) > EPS && distPosition < distThreshold.x) ||
|
||||
if ((abs(distThreshold.x - distThreshold.y) > EPS &&
|
||||
((abs(distThreshold.x) > EPS && distPosition < distThreshold.x) ||
|
||||
(abs(distThreshold.y) > EPS && distPosition > distThreshold.y))))
|
||||
{
|
||||
// Discard star in geometry shader
|
||||
vs_gPosition = vec4(0.0);
|
||||
vs_gPosition = vec4(0.0);
|
||||
gl_Position = vec4(0.0);
|
||||
return;
|
||||
}
|
||||
@@ -177,11 +177,11 @@ void main() {
|
||||
// Remove stars without position, happens when VBO chunk is stuffed with zeros.
|
||||
// Has to be done in Geometry shader because Vertices cannot be discarded here.
|
||||
if (length(in_position) > EPS){
|
||||
vs_gPosition = vec4(model * objectPosition);
|
||||
vs_gPosition = vec4(model * objectPosition);
|
||||
gl_Position = vec4(projection * viewPosition);
|
||||
}
|
||||
else {
|
||||
vs_gPosition = vec4(0.0);
|
||||
vs_gPosition = vec4(0.0);
|
||||
gl_Position = vec4(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,9 +33,9 @@ const float DEFAULT_DEPTH = 3.08567758e19; // 1000 Pc
|
||||
|
||||
Fragment getFragment() {
|
||||
vec4 color = vec4(0.0);
|
||||
|
||||
|
||||
// BILLBOARDS
|
||||
// Sample color. Tonemapping done in first shader pass.
|
||||
// Sample color. Tonemapping done in first shader pass.
|
||||
vec4 textureColor = texture(renderedTexture, uv);
|
||||
|
||||
// Use the following to check for any intensity at all.
|
||||
@@ -43,7 +43,7 @@ Fragment getFragment() {
|
||||
|
||||
Fragment frag;
|
||||
frag.color = textureColor;
|
||||
// Place stars at back to begin with.
|
||||
// Place stars at back to begin with.
|
||||
frag.depth = DEFAULT_DEPTH;
|
||||
frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
frag.blend = BLEND_MODE_NORMAL;
|
||||
|
||||
@@ -39,7 +39,7 @@ const float DEFAULT_DEPTH = 3.08567758e19; // 1000 Pc
|
||||
|
||||
Fragment getFragment() {
|
||||
vec4 color = vec4(0.0);
|
||||
|
||||
|
||||
// GL_POINTS
|
||||
|
||||
// Use frustum params to be able to compensate for a skewed frustum (in a dome).
|
||||
@@ -55,21 +55,21 @@ Fragment getFragment() {
|
||||
float planeAspect = yFactor / xFactor; // Equals: (right - left) / (top - bottom)
|
||||
float screenAspect = screenSize.x / screenSize.y;
|
||||
float fullAspect = planeAspect / screenAspect;
|
||||
|
||||
// Find screenPos in skewed frustum. uv is [0, 1]
|
||||
vec2 screenPos = uv * vec2(right - left, top - bottom) + vec2(left, bottom);
|
||||
|
||||
// Find our elliptic scale factors by trigonometric approximation.
|
||||
// Find screenPos in skewed frustum. uv is [0, 1]
|
||||
vec2 screenPos = uv * vec2(right - left, top - bottom) + vec2(left, bottom);
|
||||
|
||||
// Find our elliptic scale factors by trigonometric approximation.
|
||||
float beta = atan(length(screenPos) / near);
|
||||
vec2 sigmaScaleFactor = vec2(1.0 / cos(beta), 1.0 / pow(cos(beta), 2.0));
|
||||
vec2 sigmaScaleFactor = vec2(1.0 / cos(beta), 1.0 / pow(cos(beta), 2.0));
|
||||
|
||||
float defaultScreen = 1200.0;
|
||||
float scaling = screenSize.y / defaultScreen * yFactor;
|
||||
|
||||
// Scale filter size depending on screen pos.
|
||||
vec2 filterScaleFactor = vec2(
|
||||
pow(screenPos.x / near, 2.0) * fullAspect,
|
||||
pow(screenPos.y / near, 2.0)
|
||||
pow(screenPos.x / near, 2.0) * fullAspect,
|
||||
pow(screenPos.y / near, 2.0)
|
||||
);
|
||||
|
||||
// Use to ignore scaling.
|
||||
@@ -91,8 +91,8 @@ Fragment getFragment() {
|
||||
// Uncomment to compare to original filterSize (assumes origo in center of screen).
|
||||
//screenPos = (uv - 0.5) * 2.0; // [-1, 1]
|
||||
//filterScaleFactor = vec2(
|
||||
// pow(screenPos.x, 2.0),
|
||||
// pow(screenPos.y, 2.0)
|
||||
// pow(screenPos.x, 2.0),
|
||||
// pow(screenPos.y, 2.0)
|
||||
//);
|
||||
|
||||
// Make use of the following flag this to toggle betweeen circular and elliptic distribution.
|
||||
@@ -131,20 +131,20 @@ Fragment getFragment() {
|
||||
|
||||
// Calculate the contribution of this pixel (elliptic gaussian distribution).
|
||||
float pixelWeight = exp(-(
|
||||
a * pow(x * fullAspect, 2.0) + 2 * b * x * y * fullAspect + c * pow(y, 2.0)
|
||||
a * pow(x * fullAspect, 2.0) + 2 * b * x * y * fullAspect + c * pow(y, 2.0)
|
||||
));
|
||||
|
||||
|
||||
// Only sample inside FBO texture and if the pixel will contribute to final color.
|
||||
if (all(greaterThan(sPoint, vec2(0.0))) && all(lessThan(sPoint, vec2(1.0))) &&
|
||||
pixelWeight > pixelWeightThreshold)
|
||||
{
|
||||
vec4 sIntensity = texture(renderedTexture, sPoint);
|
||||
|
||||
// Use normal distribution function for halo/bloom effect.
|
||||
// Use normal distribution function for halo/bloom effect.
|
||||
if (useCircleDist) {
|
||||
float circleDist = sqrt(pow(x / (1 + length(filterScaleFactor)), 2.0) +
|
||||
pow(y / (1 + length(filterScaleFactor)), 2.0));
|
||||
intensity += sIntensity.rgb * (1.0 / (sigma * sqrt(2.0 * M_PI))) *
|
||||
intensity += sIntensity.rgb * (1.0 / (sigma * sqrt(2.0 * M_PI))) *
|
||||
exp(-(pow(circleDist, 2.0) / (2.0 * pow(sigma, 2.0)))) / filterSize;
|
||||
}
|
||||
else {
|
||||
@@ -169,7 +169,7 @@ Fragment getFragment() {
|
||||
|
||||
Fragment frag;
|
||||
frag.color = color;
|
||||
// Place stars at back to begin with.
|
||||
// Place stars at back to begin with.
|
||||
frag.depth = DEFAULT_DEPTH;
|
||||
frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
frag.blend = BLEND_MODE_NORMAL;
|
||||
|
||||
@@ -38,7 +38,7 @@ out float vs_cameraDistFromSun;
|
||||
uniform dmat4 model;
|
||||
uniform dmat4 view;
|
||||
uniform dmat4 projection;
|
||||
uniform float time;
|
||||
uniform float time;
|
||||
uniform int renderOption;
|
||||
uniform vec2 posXThreshold;
|
||||
uniform vec2 posYThreshold;
|
||||
@@ -50,7 +50,7 @@ uniform vec2 distThreshold;
|
||||
// Keep in sync with gaiaoptions.h:RenderOption enum
|
||||
const int RENDEROPTION_STATIC = 0;
|
||||
const int RENDEROPTION_COLOR = 1;
|
||||
const int RENDEROPTION_MOTION = 2;
|
||||
const int RENDEROPTION_MOTION = 2;
|
||||
const float EPS = 1e-5;
|
||||
const float Parsec = 3.0856776e16;
|
||||
|
||||
@@ -59,24 +59,24 @@ void main() {
|
||||
vs_brightness = in_brightness;
|
||||
|
||||
// Check if we should filter this star by position. Thres depending on original values.
|
||||
if ((abs(posXThreshold.x) > EPS && in_position.x < posXThreshold.x) ||
|
||||
(abs(posXThreshold.y) > EPS && in_position.x > posXThreshold.y) ||
|
||||
(abs(posYThreshold.x) > EPS && in_position.y < posYThreshold.x) ||
|
||||
(abs(posYThreshold.y) > EPS && in_position.y > posYThreshold.y) ||
|
||||
(abs(posZThreshold.x) > EPS && in_position.z < posZThreshold.x) ||
|
||||
(abs(posZThreshold.y) > EPS && in_position.z > posZThreshold.y) ||
|
||||
(abs(distThreshold.x - distThreshold.y) < EPS
|
||||
if ((abs(posXThreshold.x) > EPS && in_position.x < posXThreshold.x) ||
|
||||
(abs(posXThreshold.y) > EPS && in_position.x > posXThreshold.y) ||
|
||||
(abs(posYThreshold.x) > EPS && in_position.y < posYThreshold.x) ||
|
||||
(abs(posYThreshold.y) > EPS && in_position.y > posYThreshold.y) ||
|
||||
(abs(posZThreshold.x) > EPS && in_position.z < posZThreshold.x) ||
|
||||
(abs(posZThreshold.y) > EPS && in_position.z > posZThreshold.y) ||
|
||||
(abs(distThreshold.x - distThreshold.y) < EPS
|
||||
&& abs(length(in_position) - distThreshold.y) < EPS) ||
|
||||
(renderOption != RENDEROPTION_STATIC && (
|
||||
(abs(gMagThreshold.x - gMagThreshold.y) < EPS && abs(gMagThreshold.x - in_brightness.x) < EPS) ||
|
||||
(abs(gMagThreshold.x - 20.0f) > EPS && in_brightness.x < gMagThreshold.x) ||
|
||||
(abs(gMagThreshold.x - 20.0f) > EPS && in_brightness.x < gMagThreshold.x) ||
|
||||
(abs(gMagThreshold.y - 20.0f) > EPS && in_brightness.x > gMagThreshold.y) ||
|
||||
(abs(bpRpThreshold.x - bpRpThreshold.y) < EPS && abs(bpRpThreshold.x - in_brightness.y) < EPS) ||
|
||||
(abs(bpRpThreshold.x) > EPS && in_brightness.y < bpRpThreshold.x) ||
|
||||
(abs(bpRpThreshold.x) > EPS && in_brightness.y < bpRpThreshold.x) ||
|
||||
(abs(bpRpThreshold.y) > EPS && in_brightness.y > bpRpThreshold.y))))
|
||||
{
|
||||
// Discard star in geometry shader.
|
||||
vs_gPosition = vec4(0.0);
|
||||
vs_gPosition = vec4(0.0);
|
||||
gl_Position = vec4(0.0);
|
||||
return;
|
||||
}
|
||||
@@ -92,12 +92,12 @@ void main() {
|
||||
|
||||
// Thres moving stars by their new position.
|
||||
float distPosition = length(objectPosition.xyz / (1000.0 * Parsec));
|
||||
if ((abs(distThreshold.x - distThreshold.y) > EPS &&
|
||||
((abs(distThreshold.x) > EPS && distPosition< distThreshold.x) ||
|
||||
if ((abs(distThreshold.x - distThreshold.y) > EPS &&
|
||||
((abs(distThreshold.x) > EPS && distPosition< distThreshold.x) ||
|
||||
(abs(distThreshold.y) > EPS && distPosition > distThreshold.y))))
|
||||
{
|
||||
// Discard star in geometry shader.
|
||||
vs_gPosition = vec4(0.0);
|
||||
vs_gPosition = vec4(0.0);
|
||||
gl_Position = vec4(0.0);
|
||||
return;
|
||||
}
|
||||
@@ -112,11 +112,11 @@ void main() {
|
||||
// Remove stars without position, happens when VBO chunk is stuffed with zeros.
|
||||
// Has to be done in Geometry shader because Vertices cannot be discarded here.
|
||||
if (length(in_position) > EPS) {
|
||||
vs_gPosition = vec4(model * objectPosition);
|
||||
vs_gPosition = vec4(model * objectPosition);
|
||||
gl_Position = vec4(projection * viewPosition);
|
||||
}
|
||||
else {
|
||||
vs_gPosition = vec4(0.0);
|
||||
vs_gPosition = vec4(0.0);
|
||||
gl_Position = vec4(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,7 +297,7 @@ RenderableGalaxy::RenderableGalaxy(const ghoul::Dictionary& dictionary)
|
||||
_pointSpreadFunctionTexturePath
|
||||
);
|
||||
|
||||
auto onChange = [&](bool enabled) {
|
||||
auto onChange = [this](bool enabled) {
|
||||
if (enabled) {
|
||||
global::raycasterManager->attachRaycaster(*_raycaster);
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ void MilkywayConversionTask::perform(const Task::ProgressCallback& onProgress) {
|
||||
resolutionRatio
|
||||
);
|
||||
std::function<glm::tvec4<GLfloat>(glm::ivec3)> sampleFunction =
|
||||
[&](glm::ivec3 outCoord) {
|
||||
[this, resolutionRatio, sampler](glm::ivec3 outCoord) {
|
||||
const glm::vec3 inCoord = ((glm::vec3(outCoord) + glm::vec3(0.5f)) *
|
||||
resolutionRatio) - glm::vec3(0.5f);
|
||||
const glm::tvec4<GLfloat> value = sampler.sample(inCoord);
|
||||
|
||||
@@ -58,6 +58,7 @@ set(HEADER_FILES
|
||||
src/tileindex.h
|
||||
src/tileloadjob.h
|
||||
src/tiletextureinitdata.h
|
||||
src/tilecacheproperties.h
|
||||
src/timequantizer.h
|
||||
src/tileprovider/defaulttileprovider.h
|
||||
src/tileprovider/imagesequencetileprovider.h
|
||||
|
||||
@@ -369,9 +369,9 @@ namespace cpl
|
||||
/** Use cpl::down_cast<Derived*>(pointer_to_base) as equivalent of
|
||||
* static_cast<Derived*>(pointer_to_base) with safe checking in debug
|
||||
* mode.
|
||||
*
|
||||
*
|
||||
* Only works if no virtual inheritance is involved.
|
||||
*
|
||||
*
|
||||
* @param f pointer to a base class
|
||||
* @return pointer to a derived class
|
||||
*/
|
||||
|
||||
@@ -148,7 +148,7 @@ bool CPLIsMachinePotentiallyGCEInstance();
|
||||
bool CPLIsMachineForSureGCEInstance();
|
||||
|
||||
/** Manager of Google OAuth2 authentication.
|
||||
*
|
||||
*
|
||||
* This class handles different authentication methods and handles renewal
|
||||
* of access token.
|
||||
*
|
||||
|
||||
@@ -91,43 +91,24 @@
|
||||
namespace {
|
||||
constexpr std::string_view _loggerCat = "GlobeBrowsingModule";
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo WMSCacheEnabledInfo = {
|
||||
"WMSCacheEnabled",
|
||||
"WMS Cache Enabled",
|
||||
"Determines whether automatic caching of WMS servers is enabled. Changing the "
|
||||
"value of this property will not affect already created WMS datasets"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo OfflineModeInfo = {
|
||||
"OfflineMode",
|
||||
"Offline Mode",
|
||||
"Determines whether loaded WMS servers should be used in offline mode, that is "
|
||||
"not even try to retrieve images through an internet connection. Please note "
|
||||
"that this setting is only reasonable, if the caching is enabled and there is "
|
||||
"available cached data. Changing the value of this property will not affect "
|
||||
"already created WMS datasets"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo WMSCacheLocationInfo = {
|
||||
"WMSCacheLocation",
|
||||
"WMS Cache Location",
|
||||
"The location of the cache folder for WMS servers. Changing the value of this "
|
||||
"property will not affect already created WMS datasets"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo WMSCacheSizeInfo = {
|
||||
"WMSCacheSize",
|
||||
"WMS Cache Size",
|
||||
"The maximum size of the cache for each WMS server. Changing the value of this "
|
||||
"property will not affect already created WMS datasets"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo TileCacheSizeInfo = {
|
||||
"TileCacheSize",
|
||||
"Tile Cache Size",
|
||||
"The maximum size of the MemoryAwareTileCache, on the CPU and GPU"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo MRFCacheEnabledInfo = {
|
||||
"MRFCacheEnabled",
|
||||
"MRF Cache Enabled",
|
||||
"Determines whether automatic caching of globe browsing data is enabled."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo MRFCacheLocationInfo = {
|
||||
"MRFCacheLocation",
|
||||
"MRF Cache Location",
|
||||
"The location of the root folder for the MRF cache of globe browsing data."
|
||||
};
|
||||
|
||||
openspace::GlobeBrowsingModule::Capabilities
|
||||
parseSubDatasets(char** subDatasets, int nSubdatasets)
|
||||
{
|
||||
@@ -185,25 +166,15 @@ namespace {
|
||||
}
|
||||
|
||||
struct [[codegen::Dictionary(GlobeBrowsingModule)]] Parameters {
|
||||
// [[codegen::verbatim(WMSCacheEnabledInfo.description)]]
|
||||
std::optional<bool> cacheEnabled [[codegen::key("WMSCacheEnabled")]];
|
||||
|
||||
// [[codegen::verbatim(OfflineModeInfo.description)]]
|
||||
std::optional<bool> offlineMode;
|
||||
|
||||
// [[codegen::verbatim(WMSCacheLocationInfo.description)]]
|
||||
std::optional<std::string> cacheLocation [[codegen::key("WMSCacheLocation")]];
|
||||
|
||||
// [[codegen::verbatim(WMSCacheSizeInfo.description)]]
|
||||
std::optional<int> wmsCacheSize [[codegen::key("WMSCacheSize")]];
|
||||
|
||||
// [[codegen::verbatim(TileCacheSizeInfo.description)]]
|
||||
std::optional<int> tileCacheSize;
|
||||
|
||||
// If you know what you are doing and you have WMS caching *disabled* but offline
|
||||
// mode *enabled*, you can set this value to 'true' to silence a warning that you
|
||||
// would otherwise get at startup
|
||||
std::optional<bool> noWarning;
|
||||
// [[codegen::verbatim(MRFCacheEnabledInfo.description)]]
|
||||
std::optional<bool> mrfCacheEnabled [[codegen::key("MRFCacheEnabled")]];
|
||||
|
||||
// [[codegen::verbatim(MRFCacheLocationInfo.description)]]
|
||||
std::optional<std::string> mrfCacheLocation [[codegen::key("MRFCacheLocation")]];
|
||||
};
|
||||
#include "globebrowsingmodule_codegen.cpp"
|
||||
} // namespace
|
||||
@@ -212,43 +183,25 @@ namespace openspace {
|
||||
|
||||
GlobeBrowsingModule::GlobeBrowsingModule()
|
||||
: OpenSpaceModule(Name)
|
||||
, _wmsCacheEnabled(WMSCacheEnabledInfo, false)
|
||||
, _offlineMode(OfflineModeInfo, false)
|
||||
, _wmsCacheLocation(WMSCacheLocationInfo, "${BASE}/cache_gdal")
|
||||
, _wmsCacheSizeMB(WMSCacheSizeInfo, 1024)
|
||||
, _tileCacheSizeMB(TileCacheSizeInfo, 1024)
|
||||
, _mrfCacheEnabled(MRFCacheEnabledInfo, false)
|
||||
, _mrfCacheLocation(MRFCacheLocationInfo, "${BASE}/cache_mrf")
|
||||
{
|
||||
addProperty(_wmsCacheEnabled);
|
||||
addProperty(_offlineMode);
|
||||
addProperty(_wmsCacheLocation);
|
||||
addProperty(_wmsCacheSizeMB);
|
||||
addProperty(_tileCacheSizeMB);
|
||||
addProperty(_mrfCacheEnabled);
|
||||
addProperty(_mrfCacheLocation);
|
||||
}
|
||||
|
||||
void GlobeBrowsingModule::internalInitialize(const ghoul::Dictionary& dict) {
|
||||
using namespace globebrowsing;
|
||||
|
||||
const Parameters p = codegen::bake<Parameters>(dict);
|
||||
_wmsCacheEnabled = p.cacheEnabled.value_or(_wmsCacheEnabled);
|
||||
_offlineMode = p.offlineMode.value_or(_offlineMode);
|
||||
_wmsCacheLocation = p.cacheLocation.value_or(_wmsCacheLocation);
|
||||
_wmsCacheSizeMB = p.wmsCacheSize.value_or(_wmsCacheSizeMB);
|
||||
_tileCacheSizeMB = p.tileCacheSize.value_or(_tileCacheSizeMB);
|
||||
const bool noWarning = p.noWarning.value_or(false);
|
||||
|
||||
if (!_wmsCacheEnabled && _offlineMode && !noWarning) {
|
||||
LWARNINGC(
|
||||
"GlobeBrowsingModule",
|
||||
"WMS caching is disabled, but offline mode is enabled. Unless you know "
|
||||
"what you are doing, this will probably cause many servers to stop working. "
|
||||
"If you want to silence this warning, set the 'NoWarning' parameter to "
|
||||
"'true'"
|
||||
);
|
||||
}
|
||||
|
||||
_mrfCacheEnabled = p.mrfCacheEnabled.value_or(_mrfCacheEnabled);
|
||||
_mrfCacheLocation = p.mrfCacheLocation.value_or(_mrfCacheLocation);
|
||||
|
||||
// Initialize
|
||||
global::callback::initializeGL->emplace_back([&]() {
|
||||
global::callback::initializeGL->emplace_back([this]() {
|
||||
ZoneScopedN("GlobeBrowsingModule");
|
||||
|
||||
_tileCache = std::make_unique<cache::MemoryAwareTileCache>(_tileCacheSizeMB);
|
||||
@@ -271,14 +224,14 @@ void GlobeBrowsingModule::internalInitialize(const ghoul::Dictionary& dict) {
|
||||
});
|
||||
|
||||
// Render
|
||||
global::callback::render->emplace_back([&]() {
|
||||
global::callback::render->emplace_back([this]() {
|
||||
ZoneScopedN("GlobeBrowsingModule");
|
||||
|
||||
_tileCache->update();
|
||||
});
|
||||
|
||||
// Deinitialize
|
||||
global::callback::deinitialize->emplace_back([&]() {
|
||||
global::callback::deinitialize->emplace_back([]() {
|
||||
ZoneScopedN("GlobeBrowsingModule");
|
||||
|
||||
GdalWrapper::destroy();
|
||||
@@ -670,21 +623,12 @@ bool GlobeBrowsingModule::hasUrlInfo(const std::string& globe) const {
|
||||
return _urlList.find(globe) != _urlList.end();
|
||||
}
|
||||
|
||||
bool GlobeBrowsingModule::isWMSCachingEnabled() const {
|
||||
return _wmsCacheEnabled;
|
||||
bool GlobeBrowsingModule::isMRFCachingEnabled() const {
|
||||
return _mrfCacheEnabled;
|
||||
}
|
||||
|
||||
bool GlobeBrowsingModule::isInOfflineMode() const {
|
||||
return _offlineMode;
|
||||
}
|
||||
|
||||
std::string GlobeBrowsingModule::wmsCacheLocation() const {
|
||||
return _wmsCacheLocation;
|
||||
}
|
||||
|
||||
uint64_t GlobeBrowsingModule::wmsCacheSize() const {
|
||||
uint64_t size = _wmsCacheSizeMB;
|
||||
return size * 1024 * 1024;
|
||||
const std::string GlobeBrowsingModule::mrfCacheLocation() const {
|
||||
return _mrfCacheLocation;
|
||||
}
|
||||
|
||||
scripting::LuaLibrary GlobeBrowsingModule::luaLibrary() const {
|
||||
|
||||
@@ -92,10 +92,8 @@ public:
|
||||
|
||||
void removeWMSServer(const std::string& name);
|
||||
|
||||
bool isWMSCachingEnabled() const;
|
||||
bool isInOfflineMode() const;
|
||||
std::string wmsCacheLocation() const;
|
||||
uint64_t wmsCacheSize() const; // bytes
|
||||
bool isMRFCachingEnabled() const;
|
||||
const std::string mrfCacheLocation() const;
|
||||
|
||||
protected:
|
||||
void internalInitialize(const ghoul::Dictionary&) override;
|
||||
@@ -113,12 +111,11 @@ private:
|
||||
glm::dquat lookDownCameraRotation(const globebrowsing::RenderableGlobe& globe,
|
||||
glm::dvec3 cameraPositionModelSpace, globebrowsing::Geodetic2 geo2);
|
||||
|
||||
properties::BoolProperty _wmsCacheEnabled;
|
||||
properties::BoolProperty _offlineMode;
|
||||
properties::StringProperty _wmsCacheLocation;
|
||||
properties::UIntProperty _wmsCacheSizeMB;
|
||||
properties::UIntProperty _tileCacheSizeMB;
|
||||
|
||||
properties::BoolProperty _mrfCacheEnabled;
|
||||
properties::StringProperty _mrfCacheLocation;
|
||||
|
||||
std::unique_ptr<globebrowsing::cache::MemoryAwareTileCache> _tileCache;
|
||||
|
||||
// name -> capabilities
|
||||
|
||||
@@ -56,6 +56,9 @@ namespace {
|
||||
throw ghoul::lua::LuaError("Unknown layer group: " + layerGroupName);
|
||||
}
|
||||
|
||||
// Add the name of the enclosing globe to layer dict, it is used to identify a cache
|
||||
layer.setValue("GlobeName", globeName);
|
||||
|
||||
// Get the dictionary defining the layer
|
||||
Layer* l = globe->layerManager().addLayer(groupID, layer);
|
||||
if (l) {
|
||||
@@ -182,7 +185,7 @@ namespace {
|
||||
if (group == layers::Group::ID::Unknown) {
|
||||
throw ghoul::lua::LuaError(fmt::format("Unknown layer group: {}", layerGroup));
|
||||
}
|
||||
|
||||
|
||||
LayerGroup& lg = globe->layerManager().layerGroup(group);
|
||||
if (std::holds_alternative<int>(source) && std::holds_alternative<int>(destination)) {
|
||||
// Short circut here, no need to get the layers
|
||||
|
||||
@@ -45,6 +45,7 @@ uniform vec3 sunPositionObj;
|
||||
uniform vec3 camPositionObj;
|
||||
uniform float nightFactor;
|
||||
uniform float zFightingPercentage;
|
||||
uniform float opacity;
|
||||
|
||||
|
||||
Fragment getFragment() {
|
||||
@@ -123,6 +124,7 @@ Fragment getFragment() {
|
||||
Fragment frag;
|
||||
|
||||
frag.color = diffuse * shadow;
|
||||
frag.color.a *= opacity;
|
||||
frag.depth = vs_screenSpaceDepth;
|
||||
frag.gPosition = vec4(1e30, 1e30, 1e30, 1.0);
|
||||
frag.gNormal = vec4(normal, 1.0);
|
||||
|
||||
@@ -39,6 +39,7 @@ uniform float colorFilterValue;
|
||||
uniform vec3 sunPosition;
|
||||
uniform float nightFactor;
|
||||
uniform float zFightingPercentage;
|
||||
uniform float opacity;
|
||||
|
||||
|
||||
Fragment getFragment() {
|
||||
@@ -111,6 +112,7 @@ Fragment getFragment() {
|
||||
Fragment frag;
|
||||
|
||||
frag.color = diffuse * shadow;
|
||||
frag.color.a *= opacity;
|
||||
frag.depth = vs_screenSpaceDepth;
|
||||
frag.gPosition = vec4(1e30, 1e30, 1e30, 1.0);
|
||||
frag.gNormal = vec4(normal, 1.0);
|
||||
|
||||
@@ -185,7 +185,7 @@ vec4 getSample#{layerGroup}#{i}(vec2 uv, vec3 levelWeights,
|
||||
|
||||
vec4 blend#{layerGroup}#{i}(vec4 currentColor, vec4 newColor, float blendFactor) {
|
||||
#if (#{#{layerGroup}#{i}BlendMode} == BlendModeDefault)
|
||||
return blendNormal(currentColor, vec4(newColor.rgb, newColor.a * blendFactor));
|
||||
return blendNormal(currentColor, vec4(newColor.rgb, newColor.a * blendFactor));
|
||||
#elif (#{#{layerGroup}#{i}BlendMode} == BlendModeMultiply)
|
||||
return blendMultiply(currentColor, newColor * blendFactor);
|
||||
#elif (#{#{layerGroup}#{i}BlendMode} == BlendModeAdd)
|
||||
|
||||
@@ -97,12 +97,6 @@ namespace {
|
||||
"The text color of the labels"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo OpacityInfo = {
|
||||
"Opacity",
|
||||
"Opacity",
|
||||
"The opacity of the labels"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo FadeDistancesInfo = {
|
||||
"FadeDistances",
|
||||
"Fade-In Distances",
|
||||
@@ -165,7 +159,7 @@ namespace {
|
||||
// [[codegen::verbatim(ColorInfo.description)]]
|
||||
std::optional<glm::vec3> color [[codegen::color()]];
|
||||
|
||||
// [[codegen::verbatim(OpacityInfo.description)]]
|
||||
// The opacity of the labels
|
||||
std::optional<float> opacity [[codegen::inrange(0.f, 1.f)]];
|
||||
|
||||
// [[codegen::verbatim(FadeDistancesInfo.description)]]
|
||||
@@ -207,7 +201,6 @@ GlobeLabelsComponent::GlobeLabelsComponent()
|
||||
, _minMaxSize(MinMaxSizeInfo, glm::ivec2(1, 1000), glm::ivec2(1), glm::ivec2(1000))
|
||||
, _heightOffset(HeightOffsetInfo, 100.f, 0.f, 10000.f)
|
||||
, _color(ColorInfo, glm::vec3(1.f, 1.f, 0.f), glm::vec3(0.f), glm::vec3(1.f))
|
||||
, _opacity(OpacityInfo, 1.f, 0.f, 1.f)
|
||||
, _fadeDistances(
|
||||
FadeDistancesInfo,
|
||||
glm::vec2(1e4f, 1e6f),
|
||||
@@ -224,19 +217,21 @@ GlobeLabelsComponent::GlobeLabelsComponent()
|
||||
)
|
||||
{
|
||||
addProperty(_enabled);
|
||||
addProperty(_color);
|
||||
_color.setViewOption(properties::Property::ViewOptions::Color);
|
||||
addProperty(Fadeable::_opacity);
|
||||
addProperty(Fadeable::_fade);
|
||||
|
||||
addProperty(_fontSize);
|
||||
addProperty(_size);
|
||||
_minMaxSize.setViewOption(properties::Property::ViewOptions::MinMaxRange);
|
||||
addProperty(_minMaxSize);
|
||||
addProperty(_color);
|
||||
addProperty(_opacity);
|
||||
_fadeDistances.setViewOption(properties::Property::ViewOptions::MinMaxRange);
|
||||
_fadeDistances.setExponent(3.f);
|
||||
addProperty(_fadeDistances);
|
||||
addProperty(_fadeInEnabled);
|
||||
addProperty(_fadeOutEnabled);
|
||||
addProperty(_heightOffset);
|
||||
_color.setViewOption(properties::Property::ViewOptions::Color);
|
||||
addProperty(_disableCulling);
|
||||
addProperty(_distanceEPS);
|
||||
|
||||
@@ -533,7 +528,7 @@ void GlobeLabelsComponent::renderLabels(const RenderData& data,
|
||||
) {
|
||||
glm::vec4 textColor = glm::vec4(
|
||||
glm::vec3(_color),
|
||||
_opacity * fadeInVariable
|
||||
opacity() * fadeInVariable
|
||||
);
|
||||
|
||||
glm::dmat4 VP = glm::dmat4(data.camera.sgctInternal.projectionMatrix()) *
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___GLOBELABELSCOMPONENT___H__
|
||||
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
#include <openspace/rendering/fadeable.h>
|
||||
|
||||
#include <openspace/properties/optionproperty.h>
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
@@ -47,7 +48,7 @@ struct RenderData;
|
||||
namespace documentation { struct Documentation; }
|
||||
namespace globebrowsing { class RenderableGlobe; }
|
||||
|
||||
class GlobeLabelsComponent : public properties::PropertyOwner {
|
||||
class GlobeLabelsComponent : public properties::PropertyOwner, public Fadeable {
|
||||
public:
|
||||
GlobeLabelsComponent();
|
||||
~GlobeLabelsComponent() override = default;
|
||||
@@ -85,14 +86,11 @@ private:
|
||||
};
|
||||
|
||||
properties::BoolProperty _enabled;
|
||||
properties::Vec3Property _color;
|
||||
properties::FloatProperty _fontSize;
|
||||
properties::FloatProperty _size;
|
||||
properties::IVec2Property _minMaxSize;
|
||||
properties::FloatProperty _heightOffset;
|
||||
|
||||
properties::Vec3Property _color;
|
||||
properties::FloatProperty _opacity;
|
||||
|
||||
properties::Vec2Property _fadeDistances;
|
||||
properties::BoolProperty _fadeInEnabled;
|
||||
properties::BoolProperty _fadeOutEnabled;
|
||||
|
||||
@@ -48,7 +48,7 @@ void GPULayerGroup::setValue(ghoul::opengl::ProgramObject& program,
|
||||
auto& galuc = gal.uniformCache;
|
||||
const Layer& al = *activeLayers[i];
|
||||
|
||||
program.setUniform(galuc.opacity, al.renderSettings().opacity);
|
||||
program.setUniform(galuc.opacity, al.opacity());
|
||||
program.setUniform(galuc.gamma, al.renderSettings().gamma);
|
||||
program.setUniform(galuc.multiplier, al.renderSettings().multiplier);
|
||||
program.setUniform(galuc.offset, al.renderSettings().offset);
|
||||
|
||||
@@ -125,10 +125,10 @@ namespace {
|
||||
// borders
|
||||
std::optional<bool> padTiles;
|
||||
|
||||
struct Settings {
|
||||
// The opacity value of the layer
|
||||
std::optional<float> opacity [[codegen::inrange(0.0, 1.0)]];
|
||||
// The opacity value of the layer
|
||||
std::optional<float> opacity [[codegen::inrange(0.0, 1.0)]];
|
||||
|
||||
struct Settings {
|
||||
// The gamma value that is applied to each pixel of the layer
|
||||
std::optional<float> gamma;
|
||||
|
||||
@@ -228,8 +228,11 @@ Layer::Layer(layers::Group::ID id, const ghoul::Dictionary& layerDict, LayerGrou
|
||||
_padTilePixelStartOffset = initData.tilePixelStartOffset;
|
||||
_padTilePixelSizeDifference = initData.tilePixelSizeDifference;
|
||||
|
||||
_opacity = p.opacity.value_or(_opacity);
|
||||
addProperty(Fadeable::_opacity);
|
||||
addProperty(Fadeable::_fade);
|
||||
|
||||
if (p.settings.has_value()) {
|
||||
_renderSettings.opacity = p.settings->opacity.value_or(_renderSettings.opacity);
|
||||
_renderSettings.gamma = p.settings->gamma.value_or(_renderSettings.gamma);
|
||||
_renderSettings.multiplier =
|
||||
p.settings->multiplier.value_or(_renderSettings.multiplier);
|
||||
@@ -277,26 +280,26 @@ Layer::Layer(layers::Group::ID id, const ghoul::Dictionary& layerDict, LayerGrou
|
||||
}
|
||||
|
||||
// On change callbacks definitions
|
||||
_enabled.onChange([&]() {
|
||||
_enabled.onChange([this]() {
|
||||
if (_onChangeCallback) {
|
||||
_onChangeCallback(this);
|
||||
}
|
||||
});
|
||||
|
||||
_reset.onChange([&]() {
|
||||
_reset.onChange([this]() {
|
||||
if (_tileProvider) {
|
||||
_tileProvider->reset();
|
||||
}
|
||||
});
|
||||
|
||||
_remove.onChange([&]() {
|
||||
_remove.onChange([this]() {
|
||||
if (_tileProvider) {
|
||||
_tileProvider->reset();
|
||||
_parent.deleteLayer(identifier());
|
||||
}
|
||||
});
|
||||
|
||||
_renderSettings.onChange([&]() {
|
||||
_renderSettings.onChange([this]() {
|
||||
// Only if we are a height layer will anyone care about these settings changing as
|
||||
// that will change the overall bounding box of the layer and thus require culling
|
||||
if (_parent.isHeightLayer() && _onChangeCallback) {
|
||||
@@ -304,7 +307,7 @@ Layer::Layer(layers::Group::ID id, const ghoul::Dictionary& layerDict, LayerGrou
|
||||
}
|
||||
});
|
||||
|
||||
_typeOption.onChange([&]() {
|
||||
_typeOption.onChange([this]() {
|
||||
switch (type()) {
|
||||
// Intentional fall through. Same for all tile layers
|
||||
case layers::Layer::ID::DefaultTileLayer:
|
||||
@@ -335,13 +338,13 @@ Layer::Layer(layers::Group::ID id, const ghoul::Dictionary& layerDict, LayerGrou
|
||||
}
|
||||
});
|
||||
|
||||
_blendModeOption.onChange([&]() {
|
||||
_blendModeOption.onChange([this]() {
|
||||
if (_onChangeCallback) {
|
||||
_onChangeCallback(this);
|
||||
}
|
||||
});
|
||||
|
||||
_layerAdjustment.onChange([&]() {
|
||||
_layerAdjustment.onChange([this]() {
|
||||
if (_onChangeCallback) {
|
||||
_onChangeCallback(this);
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___LAYER___H__
|
||||
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
#include <openspace/rendering/fadeable.h>
|
||||
|
||||
#include <modules/globebrowsing/src/basictypes.h>
|
||||
#include <modules/globebrowsing/src/layeradjustment.h>
|
||||
@@ -42,7 +43,7 @@ struct LayerGroup;
|
||||
struct TileIndex;
|
||||
struct TileProvider;
|
||||
|
||||
class Layer : public properties::PropertyOwner {
|
||||
class Layer : public properties::PropertyOwner, public Fadeable {
|
||||
public:
|
||||
Layer(layers::Group::ID id, const ghoul::Dictionary& layerDict, LayerGroup& parent);
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ LayerAdjustment::LayerAdjustment()
|
||||
_typeOption.setValue(static_cast<int>(layers::Adjustment::ID::None));
|
||||
_type = static_cast<layers::Adjustment::ID>(_typeOption.value());
|
||||
|
||||
_typeOption.onChange([&]() {
|
||||
_typeOption.onChange([this]() {
|
||||
switch (type()) {
|
||||
case layers::Adjustment::ID::None:
|
||||
break;
|
||||
|
||||
@@ -32,14 +32,6 @@ namespace {
|
||||
"values"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo OpacityInfo = {
|
||||
"Opacity",
|
||||
"Opacity",
|
||||
"This value sets the transparency of this layer. If this value is equal to '1', "
|
||||
"the layer is completely opaque. If this value is equal to '0', the layer is "
|
||||
"completely transparent"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo GammaInfo = {
|
||||
"Gamma",
|
||||
"Gamma",
|
||||
@@ -65,20 +57,17 @@ namespace openspace::globebrowsing {
|
||||
|
||||
LayerRenderSettings::LayerRenderSettings()
|
||||
: properties::PropertyOwner({ "Settings" })
|
||||
, opacity(OpacityInfo, 1.f, 0.f, 1.f)
|
||||
, gamma(GammaInfo, 1.f, 0.f, 5.f)
|
||||
, multiplier(MultiplierInfo, 1.f, 0.f, 20.f)
|
||||
, offset(OffsetInfo, 0.f, -10000.f, 10000.f)
|
||||
, setDefault(SetDefaultInfo)
|
||||
{
|
||||
addProperty(opacity);
|
||||
addProperty(gamma);
|
||||
addProperty(multiplier);
|
||||
addProperty(offset);
|
||||
addProperty(setDefault);
|
||||
|
||||
setDefault.onChange([this](){
|
||||
opacity = 1.f;
|
||||
gamma = 1.f;
|
||||
multiplier = 1.f;
|
||||
offset = 0.f;
|
||||
@@ -86,7 +75,6 @@ LayerRenderSettings::LayerRenderSettings()
|
||||
}
|
||||
|
||||
void LayerRenderSettings::onChange(std::function<void()> callback) {
|
||||
opacity.onChange(callback);
|
||||
gamma.onChange(callback);
|
||||
multiplier.onChange(callback);
|
||||
multiplier.onChange(callback);
|
||||
@@ -95,7 +83,7 @@ void LayerRenderSettings::onChange(std::function<void()> callback) {
|
||||
|
||||
float LayerRenderSettings::performLayerSettings(float v) const {
|
||||
return
|
||||
((glm::sign(v) * glm::pow(glm::abs(v), gamma) * multiplier) + offset) * opacity;
|
||||
((glm::sign(v) * glm::pow(glm::abs(v), gamma) * multiplier) + offset);
|
||||
}
|
||||
|
||||
glm::vec4 LayerRenderSettings::performLayerSettings(const glm::vec4& currentValue) const {
|
||||
|
||||
@@ -35,7 +35,6 @@ namespace openspace::globebrowsing {
|
||||
struct LayerRenderSettings : public properties::PropertyOwner {
|
||||
LayerRenderSettings();
|
||||
|
||||
properties::FloatProperty opacity;
|
||||
properties::FloatProperty gamma;
|
||||
properties::FloatProperty multiplier;
|
||||
properties::FloatProperty offset;
|
||||
|
||||
@@ -272,10 +272,10 @@ MemoryAwareTileCache::MemoryAwareTileCache(int tileCacheSize)
|
||||
|
||||
createDefaultTextureContainers();
|
||||
|
||||
_clearTileCache.onChange([&]() { clear(); });
|
||||
_clearTileCache.onChange([this]() { clear(); });
|
||||
addProperty(_clearTileCache);
|
||||
|
||||
_applyTileCacheSize.onChange([&](){
|
||||
_applyTileCacheSize.onChange([this](){
|
||||
setSizeEstimated(uint64_t(_tileCacheSize) * 1024ul * 1024ul);
|
||||
});
|
||||
addProperty(_applyTileCacheSize);
|
||||
@@ -381,8 +381,8 @@ bool MemoryAwareTileCache::exist(const ProviderTileKey& key) const {
|
||||
const TextureContainerMap::const_iterator result = std::find_if(
|
||||
_textureContainerMap.cbegin(),
|
||||
_textureContainerMap.cend(),
|
||||
[&](const std::pair<const TileTextureInitData::HashKey,
|
||||
TextureContainerTileCache>& p)
|
||||
[&key](const std::pair<const TileTextureInitData::HashKey,
|
||||
TextureContainerTileCache>& p)
|
||||
{
|
||||
return p.second.second->exist(key);
|
||||
}
|
||||
@@ -396,8 +396,8 @@ Tile MemoryAwareTileCache::get(const ProviderTileKey& key) {
|
||||
const TextureContainerMap::const_iterator it = std::find_if(
|
||||
_textureContainerMap.cbegin(),
|
||||
_textureContainerMap.cend(),
|
||||
[&](const std::pair<const TileTextureInitData::HashKey,
|
||||
TextureContainerTileCache>& p)
|
||||
[&key](const std::pair<const TileTextureInitData::HashKey,
|
||||
TextureContainerTileCache>& p)
|
||||
{
|
||||
return p.second.second->exist(key);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/exception.h>
|
||||
#include <ghoul/misc/profiling.h>
|
||||
#include <filesystem>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (push)
|
||||
@@ -54,11 +53,13 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
#include <system_error>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr std::string_view _loggerCat = "RawTileDataReader";
|
||||
// These are some locations in memory taken from ESRI's No Data Available tile so that we
|
||||
// can spotcheck these tiles and not present them
|
||||
// The pair is <byte index, expected value>
|
||||
@@ -421,9 +422,11 @@ RawTile::ReadError postProcessErrorCheck(const RawTile& rawTile,
|
||||
|
||||
RawTileDataReader::RawTileDataReader(std::string filePath,
|
||||
TileTextureInitData initData,
|
||||
TileCacheProperties cacheProperties,
|
||||
PerformPreprocessing preprocess)
|
||||
: _datasetFilePath(std::move(filePath))
|
||||
, _initData(std::move(initData))
|
||||
, _cacheProperties(std::move(cacheProperties))
|
||||
, _preprocess(preprocess)
|
||||
{
|
||||
ZoneScoped;
|
||||
@@ -439,83 +442,115 @@ RawTileDataReader::~RawTileDataReader() {
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<std::string> RawTileDataReader::mrfCache() {
|
||||
// We don't support these formats as they will typically lack
|
||||
// crucial imformation such as GeoTags. It also makes little sense to
|
||||
// cache them as they are already local files.
|
||||
// If it is crucial to cache a dataset of this type, convert it to geotiff.
|
||||
constexpr std::array<std::string_view, 11> Unsupported = {
|
||||
"jpeg", "jpg",
|
||||
"png",
|
||||
"bmp",
|
||||
"psd",
|
||||
"tga",
|
||||
"gif",
|
||||
"hdr",
|
||||
"pic",
|
||||
"ppm", "pgm"
|
||||
};
|
||||
|
||||
for (std::string_view fmt : Unsupported) {
|
||||
if (_datasetFilePath.ends_with(fmt)) {
|
||||
LWARNING(fmt::format(
|
||||
"Unsupported file format for MRF caching: {}, Dataset: {}",
|
||||
fmt, _datasetFilePath
|
||||
));
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
GlobeBrowsingModule& module = *global::moduleEngine->module<GlobeBrowsingModule>();
|
||||
|
||||
std::string datasetIdentifier =
|
||||
std::to_string(std::hash<std::string>{}(_datasetFilePath));
|
||||
std::string path = fmt::format("{}/{}/{}/",
|
||||
module.mrfCacheLocation(), _cacheProperties.path, datasetIdentifier);
|
||||
std::string root = absPath(path).string();
|
||||
std::string mrf = root + datasetIdentifier + ".mrf";
|
||||
std::string cache = root + datasetIdentifier + ".mrfcache";
|
||||
|
||||
if (!std::filesystem::exists(mrf)) {
|
||||
std::error_code ec;
|
||||
if (!std::filesystem::create_directories(root, ec)) {
|
||||
// Already existing directories causes a 'failure' but no error
|
||||
if (ec) {
|
||||
LWARNING(fmt::format(
|
||||
"Failed to create directories for cache at: {}. Error Code: {}, message: {}",
|
||||
root, std::to_string(ec.value()), ec.message()
|
||||
));
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
GDALDriver* driver = GetGDALDriverManager()->GetDriverByName("MRF");
|
||||
if (driver != nullptr) {
|
||||
GDALDataset* src = static_cast<GDALDataset*>(GDALOpen(_datasetFilePath.c_str(), GA_ReadOnly));
|
||||
if (!src) {
|
||||
LWARNING(fmt::format(
|
||||
"Failed to load dataset: {}. GDAL Error: {}",
|
||||
_datasetFilePath, CPLGetLastErrorMsg()
|
||||
));
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
defer{ GDALClose(src); };
|
||||
|
||||
char** createOpts = nullptr;
|
||||
createOpts = CSLSetNameValue(createOpts, "CACHEDSOURCE", _datasetFilePath.c_str());
|
||||
createOpts = CSLSetNameValue(createOpts, "NOCOPY", "true");
|
||||
createOpts = CSLSetNameValue(createOpts, "uniform_scale", "2");
|
||||
createOpts = CSLSetNameValue(createOpts, "compress", _cacheProperties.compression.c_str());
|
||||
createOpts = CSLSetNameValue(createOpts, "quality", std::to_string(_cacheProperties.quality).c_str());
|
||||
createOpts = CSLSetNameValue(createOpts, "blocksize", std::to_string(_cacheProperties.blockSize).c_str());
|
||||
createOpts = CSLSetNameValue(createOpts, "indexname", cache.c_str());
|
||||
createOpts = CSLSetNameValue(createOpts, "DATANAME", cache.c_str());
|
||||
|
||||
GDALDataset* dst = static_cast<GDALDataset*>(driver->CreateCopy(mrf.c_str(), src, false, createOpts, nullptr, nullptr));
|
||||
if (!dst) {
|
||||
LWARNING(fmt::format(
|
||||
"Failed to create MRF Caching dataset dataset: {}. GDAL Error: {}",
|
||||
mrf, CPLGetLastErrorMsg()
|
||||
));
|
||||
return std::nullopt;
|
||||
}
|
||||
GDALClose(dst);
|
||||
|
||||
return mrf;
|
||||
}
|
||||
else {
|
||||
LWARNING("Failed to create MRF driver");
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return mrf;
|
||||
}
|
||||
}
|
||||
|
||||
void RawTileDataReader::initialize() {
|
||||
ZoneScoped;
|
||||
|
||||
if (_datasetFilePath.empty()) {
|
||||
throw ghoul::RuntimeError("File path must not be empty");
|
||||
}
|
||||
|
||||
GlobeBrowsingModule& module = *global::moduleEngine->module<GlobeBrowsingModule>();
|
||||
|
||||
std::string content = _datasetFilePath;
|
||||
if (module.isWMSCachingEnabled()) {
|
||||
ZoneScopedN("WMS Caching");
|
||||
std::string c;
|
||||
if (std::filesystem::is_regular_file(_datasetFilePath)) {
|
||||
// Only replace the 'content' if the dataset is an XML file and we want to do
|
||||
// caching
|
||||
std::ifstream t(_datasetFilePath);
|
||||
c.append(
|
||||
(std::istreambuf_iterator<char>(t)),
|
||||
std::istreambuf_iterator<char>()
|
||||
);
|
||||
}
|
||||
else {
|
||||
//GDAL input case for configuration string (e.g. temporal data)
|
||||
c = _datasetFilePath;
|
||||
}
|
||||
|
||||
if (c.size() > 10 && c.substr(0, 10) == "<GDAL_WMS>") {
|
||||
// We know that _datasetFilePath is an XML file, so now we add a Cache line
|
||||
// into it iff there isn't already one in the XML and if the configuration
|
||||
// says we should
|
||||
if (_cacheProperties.enabled) {
|
||||
ZoneScopedN("MRF Caching");
|
||||
|
||||
// 1. Parse XML
|
||||
// 2. Inject Cache tag if it isn't already there
|
||||
// 3. Serialize XML to pass into GDAL
|
||||
|
||||
LDEBUGC(_datasetFilePath, "Inserting caching tag");
|
||||
|
||||
bool shouldSerializeXml = false;
|
||||
|
||||
CPLXMLNode* root = CPLParseXMLString(c.c_str());
|
||||
CPLXMLNode* cache = CPLSearchXMLNode(root, "Cache");
|
||||
if (!cache) {
|
||||
// If there already is a cache, we don't want to modify it
|
||||
cache = CPLCreateXMLNode(root, CXT_Element, "Cache");
|
||||
|
||||
CPLCreateXMLElementAndValue(
|
||||
cache,
|
||||
"Path",
|
||||
absPath(module.wmsCacheLocation()).string().c_str()
|
||||
);
|
||||
CPLCreateXMLElementAndValue(cache, "Depth", "4");
|
||||
CPLCreateXMLElementAndValue(cache, "Expires", "315576000"); // 10 years
|
||||
CPLCreateXMLElementAndValue(
|
||||
cache,
|
||||
"MaxSize",
|
||||
std::to_string(module.wmsCacheSize()).c_str()
|
||||
);
|
||||
|
||||
// The serialization only needs to be one if the cache didn't exist
|
||||
// already
|
||||
shouldSerializeXml = true;
|
||||
}
|
||||
|
||||
if (module.isInOfflineMode()) {
|
||||
CPLXMLNode* offlineMode = CPLSearchXMLNode(root, "OfflineMode");
|
||||
if (!offlineMode) {
|
||||
CPLCreateXMLElementAndValue(root, "OfflineMode", "true");
|
||||
shouldSerializeXml = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (shouldSerializeXml) {
|
||||
content = std::string(CPLSerializeXMLTree(root));
|
||||
//CPLSerializeXMLTreeToFile(root, (_datasetFilePath + ".xml").c_str());
|
||||
}
|
||||
std::optional<std::string> cache = mrfCache();
|
||||
if (cache.has_value()) {
|
||||
content = cache.value();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <modules/globebrowsing/src/basictypes.h>
|
||||
#include <modules/globebrowsing/src/rawtile.h>
|
||||
#include <modules/globebrowsing/src/tiletextureinitdata.h>
|
||||
#include <modules/globebrowsing/src/tilecacheproperties.h>
|
||||
#include <ghoul/misc/boolean.h>
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
@@ -53,6 +54,7 @@ public:
|
||||
* \param baseDirectory, the base directory to use in future loading operations
|
||||
*/
|
||||
RawTileDataReader(std::string filePath, TileTextureInitData initData,
|
||||
TileCacheProperties cacheProperties,
|
||||
PerformPreprocessing preprocess = PerformPreprocessing::No);
|
||||
~RawTileDataReader();
|
||||
|
||||
@@ -65,6 +67,8 @@ public:
|
||||
glm::ivec2 fullPixelSize() const;
|
||||
|
||||
private:
|
||||
std::optional<std::string> mrfCache();
|
||||
|
||||
void initialize();
|
||||
|
||||
RawTile::ReadError rasterRead(int rasterBand, const IODescription& io,
|
||||
@@ -97,6 +101,7 @@ private:
|
||||
int _maxChunkLevel = -1;
|
||||
|
||||
const TileTextureInitData _initData;
|
||||
const TileCacheProperties _cacheProperties;
|
||||
const PerformPreprocessing _preprocess;
|
||||
TileDepthTransform _depthTransform = { .scale = 0.f, .offset = 0.f };
|
||||
|
||||
|
||||
@@ -579,7 +579,7 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
ghoul::Dictionary layersDictionary = dictionary.value<ghoul::Dictionary>("Layers");
|
||||
_layerManager.initialize(layersDictionary);
|
||||
|
||||
addProperty(_opacity);
|
||||
addProperty(Fadeable::_opacity);
|
||||
addProperty(_generalProperties.performShading);
|
||||
addProperty(_generalProperties.useAccurateNormals);
|
||||
addProperty(_generalProperties.renderAtDistance);
|
||||
@@ -603,7 +603,7 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
_shadowMappingPropertyOwner.addProperty(_generalProperties.shadowMapping);
|
||||
_shadowMappingPropertyOwner.addProperty(_generalProperties.zFightingPercentage);
|
||||
_shadowMappingPropertyOwner.addProperty(_generalProperties.nShadowSamples);
|
||||
_generalProperties.nShadowSamples.onChange([&]() {
|
||||
_generalProperties.nShadowSamples.onChange([this]() {
|
||||
_shadersNeedRecompilation = true;
|
||||
});
|
||||
addPropertySubOwner(_shadowMappingPropertyOwner);
|
||||
@@ -626,7 +626,7 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
_debugPropertyOwner.addProperty(_debugProperties.modelSpaceRenderingCutoffLevel);
|
||||
_debugPropertyOwner.addProperty(_debugProperties.dynamicLodIterationCount);
|
||||
|
||||
auto notifyShaderRecompilation = [&]() {
|
||||
auto notifyShaderRecompilation = [this]() {
|
||||
_shadersNeedRecompilation = true;
|
||||
};
|
||||
_generalProperties.useAccurateNormals.onChange(notifyShaderRecompilation);
|
||||
@@ -635,7 +635,7 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
_generalProperties.performShading.onChange(notifyShaderRecompilation);
|
||||
_debugProperties.showChunkEdges.onChange(notifyShaderRecompilation);
|
||||
|
||||
_layerManager.onChange([&](Layer* l) {
|
||||
_layerManager.onChange([this](Layer* l) {
|
||||
_shadersNeedRecompilation = true;
|
||||
_chunkCornersDirty = true;
|
||||
_nLayersIsDirty = true;
|
||||
@@ -655,6 +655,7 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
// Components
|
||||
_hasRings = p.rings.has_value();
|
||||
if (_hasRings) {
|
||||
_ringsComponent.setParentFadeable(this);
|
||||
_ringsComponent.initialize();
|
||||
addPropertySubOwner(_ringsComponent);
|
||||
}
|
||||
@@ -676,6 +677,9 @@ void RenderableGlobe::initializeGL() {
|
||||
if (!_labelsDictionary.isEmpty()) {
|
||||
_globeLabelsComponent.initialize(_labelsDictionary, this);
|
||||
addPropertySubOwner(_globeLabelsComponent);
|
||||
|
||||
// Fading of the labels should also depend on the fading of the globe
|
||||
_globeLabelsComponent.setParentFadeable(this);
|
||||
}
|
||||
|
||||
_layerManager.update();
|
||||
@@ -749,7 +753,9 @@ void RenderableGlobe::render(const RenderData& data, RendererTasks& rendererTask
|
||||
|
||||
// Render from light source point of view
|
||||
renderChunks(lightRenderData, rendererTask, {}, true);
|
||||
if (_hasRings && _ringsComponent.isEnabled()) {
|
||||
if (_hasRings && _ringsComponent.isEnabled() &&
|
||||
_ringsComponent.isVisible())
|
||||
{
|
||||
_ringsComponent.draw(
|
||||
lightRenderData,
|
||||
RingsComponent::RenderPass::GeometryOnly
|
||||
@@ -762,7 +768,9 @@ void RenderableGlobe::render(const RenderData& data, RendererTasks& rendererTask
|
||||
|
||||
// Render again from original point of view
|
||||
renderChunks(data, rendererTask, _shadowComponent.shadowMapData());
|
||||
if (_hasRings && _ringsComponent.isEnabled()) {
|
||||
if (_hasRings && _ringsComponent.isEnabled() &&
|
||||
_ringsComponent.isVisible())
|
||||
{
|
||||
_ringsComponent.draw(
|
||||
data,
|
||||
RingsComponent::RenderPass::GeometryAndShading,
|
||||
@@ -772,7 +780,9 @@ void RenderableGlobe::render(const RenderData& data, RendererTasks& rendererTask
|
||||
}
|
||||
else {
|
||||
renderChunks(data, rendererTask);
|
||||
if (_hasRings && _ringsComponent.isEnabled()) {
|
||||
if (_hasRings && _ringsComponent.isEnabled() &&
|
||||
_ringsComponent.isVisible())
|
||||
{
|
||||
_ringsComponent.draw(
|
||||
data,
|
||||
RingsComponent::RenderPass::GeometryAndShading
|
||||
|
||||
@@ -53,18 +53,18 @@
|
||||
namespace {
|
||||
constexpr std::string_view _loggerCat = "RingsComponent";
|
||||
|
||||
constexpr std::array<const char*, 9> UniformNames = {
|
||||
constexpr std::array<const char*, 10> UniformNames = {
|
||||
"modelViewProjectionMatrix", "textureOffset", "colorFilterValue", "nightFactor",
|
||||
"sunPosition", "ringTexture", "shadowMatrix", "shadowMapTexture",
|
||||
"zFightingPercentage"
|
||||
"zFightingPercentage", "opacity"
|
||||
};
|
||||
|
||||
constexpr std::array<const char*, 15> UniformNamesAdvancedRings = {
|
||||
constexpr std::array<const char*, 16> UniformNamesAdvancedRings = {
|
||||
"modelViewProjectionMatrix", "textureOffset", "colorFilterValue", "nightFactor",
|
||||
"sunPosition", "sunPositionObj", "camPositionObj", "ringTextureFwrd",
|
||||
"ringTextureBckwrd", "ringTextureUnlit", "ringTextureColor",
|
||||
"ringTextureTransparency", "shadowMatrix", "shadowMapTexture",
|
||||
"zFightingPercentage"
|
||||
"zFightingPercentage", "opacity"
|
||||
};
|
||||
|
||||
constexpr std::array<const char*, 3> GeomUniformNames = {
|
||||
@@ -248,10 +248,12 @@ void RingsComponent::initialize() {
|
||||
const Parameters p = codegen::bake<Parameters>(_ringsDictionary);
|
||||
|
||||
addProperty(_enabled);
|
||||
addProperty(Fadeable::_opacity);
|
||||
addProperty(Fadeable::_fade);
|
||||
|
||||
_size.setExponent(15.f);
|
||||
_size = p.size.value_or(_size);
|
||||
_size.onChange([&]() { _planeIsDirty = true; });
|
||||
_size.onChange([this]() { _planeIsDirty = true; });
|
||||
addProperty(_size);
|
||||
|
||||
if (p.texture.has_value()) {
|
||||
@@ -473,6 +475,7 @@ void RingsComponent::draw(const RenderData& data, RenderPass renderPass,
|
||||
_uniformCacheAdvancedRings.ringTextureTransparency,
|
||||
ringTextureTransparencyUnit
|
||||
);
|
||||
_shader->setUniform(_uniformCacheAdvancedRings.opacityValue, opacity());
|
||||
|
||||
// Adding the model transformation to the final shadow matrix so we have a
|
||||
// complete transformation from the model coordinates to the clip space of
|
||||
@@ -507,7 +510,6 @@ void RingsComponent::draw(const RenderData& data, RenderPass renderPass,
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnablei(GL_BLEND, 0);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
}
|
||||
else {
|
||||
_shader->setUniform(
|
||||
@@ -523,6 +525,7 @@ void RingsComponent::draw(const RenderData& data, RenderPass renderPass,
|
||||
_uniformCache.modelViewProjectionMatrix,
|
||||
modelViewProjectionTransform
|
||||
);
|
||||
_shader->setUniform(_uniformCache.opacityValue, opacity());
|
||||
|
||||
ringTextureUnit.activate();
|
||||
_texture->bind();
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___RINGSCOMPONENT___H__
|
||||
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
#include <openspace/rendering/fadeable.h>
|
||||
|
||||
#include <modules/globebrowsing/src/shadowcomponent.h>
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
@@ -48,7 +49,7 @@ namespace openspace {
|
||||
|
||||
namespace documentation { struct Documentation; }
|
||||
|
||||
class RingsComponent : public properties::PropertyOwner {
|
||||
class RingsComponent : public properties::PropertyOwner, public Fadeable {
|
||||
public:
|
||||
enum class RenderPass {
|
||||
GeometryOnly,
|
||||
@@ -95,12 +96,13 @@ private:
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _shader;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _geometryOnlyShader;
|
||||
UniformCache(modelViewProjectionMatrix, textureOffset, colorFilterValue, nightFactor,
|
||||
sunPosition, ringTexture, shadowMatrix, shadowMapTexture, zFightingPercentage
|
||||
sunPosition, ringTexture, shadowMatrix, shadowMapTexture, zFightingPercentage,
|
||||
opacityValue
|
||||
) _uniformCache;
|
||||
UniformCache(modelViewProjectionMatrix, textureOffset, colorFilterValue, nightFactor,
|
||||
sunPosition, sunPositionObj, camPositionObj, ringTextureFwrd, ringTextureBckwrd,
|
||||
ringTextureUnlit, ringTextureColor, ringTextureTransparency, shadowMatrix,
|
||||
shadowMapTexture, zFightingPercentage
|
||||
shadowMapTexture, zFightingPercentage, opacityValue
|
||||
) _uniformCacheAdvancedRings;
|
||||
UniformCache(modelViewProjectionMatrix, textureOffset, ringTexture
|
||||
) _geomUniformCache;
|
||||
|
||||
@@ -178,7 +178,7 @@ ShadowComponent::ShadowComponent(const ghoul::Dictionary& dictionary)
|
||||
_distanceFraction = p.distanceFraction.value_or(_distanceFraction);
|
||||
addProperty(_distanceFraction);
|
||||
|
||||
_saveDepthTexture.onChange([&]() { _executeDepthTextureSave = true; });
|
||||
_saveDepthTexture.onChange([this]() { _executeDepthTextureSave = true; });
|
||||
|
||||
if (p.depthMapSize.has_value()) {
|
||||
_shadowDepthTextureWidth = p.depthMapSize->x;
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2023 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILE_CACHE_PROPERTIES___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILE_CACHE_PROPERTIES___H__
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
struct TileCacheProperties {
|
||||
bool enabled = false;
|
||||
std::string compression;
|
||||
std::string path;
|
||||
int quality;
|
||||
int blockSize;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILE_CACHE_PROPERTIES___H__
|
||||
@@ -48,10 +48,25 @@ namespace {
|
||||
"complete image if a single image is used"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo CompressionInfo = {
|
||||
"Compression",
|
||||
"Compression Algorithm",
|
||||
"The compression algorithm to use for MRF cached tiles"
|
||||
};
|
||||
|
||||
enum class [[codegen::stringify()]] Compression {
|
||||
PNG = 0,
|
||||
JPEG,
|
||||
LERC
|
||||
};
|
||||
|
||||
struct [[codegen::Dictionary(DefaultTileProvider)]] Parameters {
|
||||
// User-facing name of this tile provider
|
||||
std::optional<std::string> name;
|
||||
|
||||
// Identifier of the enclosing layer to which tiles are provided
|
||||
std::optional<std::string> identifier;
|
||||
|
||||
// The path to the file that is loaded by GDAL to produce tiles. Since GDAL
|
||||
// supports it, this can also be the textual representation of the contents of a
|
||||
// loading file
|
||||
@@ -70,6 +85,32 @@ namespace {
|
||||
// Determines if the tiles should be preprocessed before uploading to the GPU
|
||||
std::optional<bool> performPreProcessing;
|
||||
|
||||
struct CacheSettings {
|
||||
// Specifies whether to use caching or not
|
||||
std::optional<bool> enabled;
|
||||
|
||||
// [[codegen::verbatim(CompressionInfo.description)]]
|
||||
enum class [[codegen::map(Compression)]] Compression {
|
||||
PNG = 0,
|
||||
JPEG,
|
||||
LERC
|
||||
};
|
||||
|
||||
// The compression algorithm to use for cached tiles
|
||||
std::optional<Compression> compression;
|
||||
|
||||
// The quality setting of the compression alogrithm, only valid for JPEG
|
||||
std::optional<int> quality [[codegen::inrange(0, 100)]];
|
||||
|
||||
// The block-size of the MRF cache
|
||||
std::optional<int> blockSize [[codegen::greater(0)]];
|
||||
};
|
||||
// Specifies the cache settings that should be applied to this layer
|
||||
std::optional<CacheSettings> cacheSettings;
|
||||
|
||||
// The name of the enclosing globe
|
||||
std::optional<std::string> globeName;
|
||||
|
||||
};
|
||||
#include "defaulttileprovider_codegen.cpp"
|
||||
} // namespace
|
||||
@@ -105,17 +146,53 @@ DefaultTileProvider::DefaultTileProvider(const ghoul::Dictionary& dictionary)
|
||||
_performPreProcessing = _layerGroupID == layers::Group::ID::HeightLayers;
|
||||
_performPreProcessing = p.performPreProcessing.value_or(_performPreProcessing);
|
||||
|
||||
// Get the name of the layergroup to which this layer belongs
|
||||
auto it = std::find_if(
|
||||
layers::Groups.begin(),
|
||||
layers::Groups.end(),
|
||||
[id = _layerGroupID](const layers::Group& gi) {
|
||||
return gi.id == id;
|
||||
}
|
||||
);
|
||||
auto layerGroup = it != layers::Groups.end() ? it->name : std::to_string(static_cast<int>(_layerGroupID));
|
||||
|
||||
std::string identifier = p.identifier.value_or("unspecified");
|
||||
std::string enclosing = p.globeName.value_or("unspecified");
|
||||
|
||||
std::string path = fmt::format("{}/{}/{}/", enclosing, layerGroup, identifier);
|
||||
|
||||
GlobeBrowsingModule& module = *global::moduleEngine->module<GlobeBrowsingModule>();
|
||||
bool enabled = module.isMRFCachingEnabled();
|
||||
Compression compression =
|
||||
_layerGroupID == layers::Group::ID::HeightLayers ? Compression::LERC : Compression::JPEG;
|
||||
int quality = 75;
|
||||
int blockSize = 1024;
|
||||
if (p.cacheSettings.has_value()) {
|
||||
enabled = p.cacheSettings->enabled.value_or(enabled);
|
||||
if (p.cacheSettings->compression.has_value()) {
|
||||
compression = codegen::map<Compression>(*p.cacheSettings->compression);
|
||||
}
|
||||
quality = p.cacheSettings->quality.value_or(quality);
|
||||
blockSize = p.cacheSettings->blockSize.value_or(blockSize);
|
||||
}
|
||||
|
||||
_cacheProperties.enabled = enabled;
|
||||
_cacheProperties.path = path;
|
||||
_cacheProperties.quality = quality;
|
||||
_cacheProperties.blockSize = blockSize;
|
||||
_cacheProperties.compression = codegen::toString(compression);
|
||||
|
||||
TileTextureInitData initData(
|
||||
tileTextureInitData(_layerGroupID, _padTiles, pixelSize)
|
||||
);
|
||||
_tilePixelSize = initData.dimensions.x;
|
||||
initAsyncTileDataReader(initData);
|
||||
initAsyncTileDataReader(initData, _cacheProperties);
|
||||
|
||||
addProperty(_filePath);
|
||||
addProperty(_tilePixelSize);
|
||||
}
|
||||
|
||||
void DefaultTileProvider::initAsyncTileDataReader(TileTextureInitData initData) {
|
||||
void DefaultTileProvider::initAsyncTileDataReader(TileTextureInitData initData, TileCacheProperties cacheProperties) {
|
||||
ZoneScoped;
|
||||
|
||||
_asyncTextureDataProvider = std::make_unique<AsyncTileDataProvider>(
|
||||
@@ -123,6 +200,7 @@ void DefaultTileProvider::initAsyncTileDataReader(TileTextureInitData initData)
|
||||
std::make_unique<RawTileDataReader>(
|
||||
_filePath,
|
||||
initData,
|
||||
cacheProperties,
|
||||
RawTileDataReader::PerformPreprocessing(_performPreProcessing)
|
||||
)
|
||||
);
|
||||
@@ -189,7 +267,8 @@ void DefaultTileProvider::update() {
|
||||
|
||||
if (_asyncTextureDataProvider->shouldBeDeleted()) {
|
||||
initAsyncTileDataReader(
|
||||
tileTextureInitData(_layerGroupID, _padTiles, _tilePixelSize)
|
||||
tileTextureInitData(_layerGroupID, _padTiles, _tilePixelSize),
|
||||
_cacheProperties
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user