Merge branch 'master' into feature/min-max-distance

This commit is contained in:
Malin E
2023-04-13 12:43:35 +02:00
966 changed files with 3974 additions and 2717 deletions
+3 -3
View File
@@ -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)
+1 -1
View File
@@ -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;
};
+3 -3
View File
@@ -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);
}
+5 -6
View File
@@ -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,
+3 -4
View File
@@ -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;
+10 -8
View File
@@ -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
+4 -5
View File
@@ -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();
}
+6 -6
View File
@@ -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 {
+1 -3
View File
@@ -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 {
+2 -2
View File
@@ -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;
+9 -3
View File
@@ -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");
+1 -1
View File
@@ -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(); });
+1 -1
View File
@@ -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(); });
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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);
}
+4 -4
View File
@@ -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);
+3 -3
View File
@@ -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);
+1 -1
View File
@@ -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]() {
+1 -1
View File
@@ -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;
+26 -35
View File
@@ -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;
}
-7
View File
@@ -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
-3
View File
@@ -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
-1
View File
@@ -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>
+4 -3
View File
@@ -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 {
+1 -1
View File
@@ -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()) {
+1 -1
View File
@@ -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 = {
+1 -1
View File
@@ -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;
+10 -10
View File
@@ -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;
+1 -1
View File
@@ -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;
+24 -24
View File
@@ -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;
+17 -17
View File
@@ -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);
+1
View File
@@ -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.
*
+30 -86
View File
@@ -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 {
+5 -8
View File
@@ -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;
+1 -1
View File
@@ -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);
+14 -11
View File
@@ -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);
}
+2 -1
View File
@@ -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);
}
+105 -70
View File
@@ -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 };
+17 -7
View File
@@ -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
+9 -6
View File
@@ -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();
+5 -3
View File
@@ -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