Merge branch 'feature/dataplane' of github.com:OpenSpace/OpenSpace-Development into feature/dataplane

This commit is contained in:
Michael Nilsson
2016-03-28 11:26:56 -04:00
12 changed files with 192 additions and 40 deletions

1
.gitignore vendored
View File

@@ -115,3 +115,4 @@ data/spice/MAR063.BSP
data/spice/de430_1850-2150.bsp
data/spice/jup260.bsp
data/BATSRUS.cdf
data/ENLIL.cdf

View File

@@ -1,16 +1,18 @@
return {
{
Name = "DataSurfaces",
Parent = "Root",
Parent = "SolarSystem",
Renderable = {
Type = "DataSurfaceContainer"
Type = "DataSurfaceContainer",
Frame = "GALACTIC"
},
Ephemeris = {
Type = "Spice",
Body = "Earth",
Observer = "Sun",
Body = "Sun",
Observer = "Earth",
Kernels = {
"${SPICE}/GSM.ti"
"${SPICE}/GSM.ti",
"${SPICE}/GSE.ti"
}
}
}

31
data/spice/GSE.ti Normal file
View File

@@ -0,0 +1,31 @@
Geocentric Solar Ecliptic (GSE) frame:
+X is parallel to the geometric earth-sun position vector.
+Y axis is the normalized component of the geometric earth-sun velocity
vector orthogonal to the GSE +X axis.
+Z axis is parallel to the cross product of the GSE +X axis
and the GSE +Y axis.
\begindata
FRAME_GSE = 2
FRAME_2_NAME = 'GSE'
FRAME_2_CLASS = 5
FRAME_2_CLASS_ID = 2
FRAME_2_CENTER = 399
FRAME_2_RELATIVE = 'J2000'
FRAME_2_DEF_STYLE = 'PARAMETERIZED'
FRAME_2_FAMILY = 'TWO-VECTOR'
FRAME_2_PRI_AXIS = 'X'
FRAME_2_PRI_VECTOR_DEF = 'OBSERVER_TARGET_POSITION'
FRAME_2_PRI_OBSERVER = 'EARTH'
FRAME_2_PRI_TARGET = 'SUN'
FRAME_2_PRI_ABCORR = 'NONE'
FRAME_2_SEC_AXIS = 'Y'
FRAME_2_SEC_VECTOR_DEF = 'OBSERVER_TARGET_VELOCITY'
FRAME_2_SEC_OBSERVER = 'EARTH'
FRAME_2_SEC_TARGET = 'SUN'
FRAME_2_SEC_ABCORR = 'NONE'
FRAME_2_SEC_FRAME = 'J2000'

View File

@@ -14,7 +14,7 @@ Geocentric Solar Magnetospheric (GSM) frame:
FRAME_1_CLASS = 5
FRAME_1_CLASS_ID = 1
FRAME_1_CENTER = 399
FRAME_1_RELATIVE = 'J2000'
FRAME_1_RELATIVE = 'GALACTIC'
FRAME_1_DEF_STYLE = 'PARAMETERIZED'
FRAME_1_FAMILY = 'TWO-VECTOR'
FRAME_1_PRI_AXIS = 'X'
@@ -24,7 +24,7 @@ Geocentric Solar Magnetospheric (GSM) frame:
FRAME_1_PRI_ABCORR = 'NONE'
FRAME_1_SEC_AXIS = 'Z'
FRAME_1_SEC_VECTOR_DEF = 'CONSTANT'
FRAME_1_SEC_FRAME = 'IAU_EARTH'
FRAME_1_SEC_FRAME = 'ECLIPJ2000'
FRAME_1_SEC_SPEC = 'LATITUDINAL'
FRAME_1_SEC_UNITS = 'DEGREES'
FRAME_1_SEC_LONGITUDE = 288.43

View File

@@ -46,7 +46,15 @@ DataPlane::DataPlane(std::shared_ptr<KameleonWrapper> kw, std::string path)
, _texture(nullptr)
, _quad(0)
, _vertexPositionBuffer(0)
{}
{
KameleonWrapper::Model model = _kw->model();
if( model == KameleonWrapper::Model::BATSRUS){
_var = "p";
}else{
_var = "rho";
}
}
DataPlane::~DataPlane(){}
@@ -58,10 +66,13 @@ bool DataPlane::initialize(){
_modelScale = _kw->getModelScaleScaled();
_pscOffset = _kw->getModelBarycenterOffsetScaled();
std::cout << _modelScale.x << ", " << _modelScale.y << ", " << _modelScale.z << ", " << _modelScale.w << std::endl;
std::cout << _pscOffset.x << ", " << _pscOffset.y << ", " << _pscOffset.z << ", " << _pscOffset.w << std::endl;
_dimensions = glm::size3_t(500,500,1);
float zSlice = 0.5f;
_dataSlice = _kw->getUniformSliceValues(std::string("p"), _dimensions, zSlice);
_dataSlice = _kw->getUniformSliceValues(std::string(_var), _dimensions, zSlice);
glGenVertexArrays(1, &_quad); // generate array
glGenBuffers(1, &_vertexPositionBuffer); // generate buffer
@@ -118,22 +129,40 @@ void DataPlane::render(){
glm::mat4 transform = glm::mat4(1.0);
glm::mat4 rotx = glm::rotate(transform, static_cast<float>(M_PI_2), glm::vec3(1, 0, 0));
glm::mat4 roty = glm::rotate(transform, static_cast<float>(M_PI_2), glm::vec3(0, 1, 0));
glm::mat4 roty = glm::rotate(transform, static_cast<float>(M_PI_2), glm::vec3(0, -1, 0));
glm::mat4 rotz = glm::rotate(transform, static_cast<float>(M_PI_2), glm::vec3(0, 0, 1));
// glm::mat4 rot = glm::mat4(1.0);
glm::mat4 rot = glm::mat4(1.0);
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++){
transform[i][j] = static_cast<float>(_stateMatrix[i][j]);
}
}
transform = transform * roty * rotx;
position += transform*glm::vec4(-_pscOffset.x, _pscOffset.z, _pscOffset.y, _pscOffset.w);
transform = transform * rotz * roty; //BATSRUS
// transform = transform * roty;
// transform = glm::rotate(transform, _roatation.value()[0], glm::vec3(1,0,0));
// transform = glm::rotate(transform, _roatation.value()[1], glm::vec3(0,1,0));
// transform = glm::rotate(transform, _roatation.value()[2], glm::vec3(0,0,1));
glm::vec4 vec(1,0,0,1);
vec = transform*vec;
double lt;
glm::vec3 sun_vec =
SpiceManager::ref().targetPosition("SUN", "Earth", "GALACTIC", {}, _time, lt);
sun_vec = glm::normalize(sun_vec);
float angle = acos(glm::dot(sun_vec, glm::vec3(vec))/(glm::length(sun_vec)*glm::length(glm::vec3(vec))));
glm::vec3 v = glm::cross(sun_vec, glm::vec3(vec));
transform = glm::rotate(transform, -angle, v);
position += transform*glm::vec4(_pscOffset.x, _pscOffset.z, _pscOffset.y, _pscOffset.w);
// std::cout << sun_vec.x << ", " << sun_vec.y << ", " << sun_vec.z << std::endl;
// std::cout << vec.x << ", " << vec.y << ", " << vec.z << std::endl;
// std::cout << angle << std::endl << std::endl;
// Activate shader
_shader->activate();
glEnable(GL_ALPHA_TEST);
@@ -157,10 +186,34 @@ void DataPlane::render(){
}
void DataPlane::update(){
_stateMatrix = SpiceManager::ref().positionTransformMatrix("GALACTIC", "GSM", Time::ref().currentTime());
_time = Time::ref().currentTime();
_stateMatrix = SpiceManager::ref().positionTransformMatrix("GALACTIC", _frame, _time);
}
void DataPlane::setParent(){
KameleonWrapper::Model model = _kw->model();
if( model == KameleonWrapper::Model::BATSRUS ||
model == KameleonWrapper::Model::OpenGGCM ||
model == KameleonWrapper::Model::LFM)
{
_parent = OsEng.renderEngine().scene()->sceneGraphNode("Earth");
_frame = "GSM";
}else if(
model == KameleonWrapper::Model::ENLIL ||
model == KameleonWrapper::Model::MAS ||
model == KameleonWrapper::Model::Adapt3D ||
model == KameleonWrapper::Model::SWMF)
{
_parent = OsEng.renderEngine().scene()->sceneGraphNode("SolarSystem");
_frame = "GALACTIC";
}else{
//Warning!
}
}
void DataPlane::loadTexture() {
//std::unique_ptr<ghoul::opengl::Texture> texture = ghoul::io::TextureReader::ref().loadTexture(absPath(_texturePath));
@@ -187,16 +240,16 @@ void DataPlane::createPlane() {
// GEOMETRY (quad)
// ============================
const GLfloat x = _modelScale.x/2.0;
const GLfloat y = _modelScale.y/2.0;
const GLfloat y = _modelScale.z/2.0;
const GLfloat w = _modelScale.w;
const GLfloat vertex_data[] = { // square of two triangles (sigh)
// x y z w s t
-x, -y, 0.0f, w, 0, 1,
x, y, 0.0f, w, 1, 0,
-x, y, 0.0f, w, 0, 0,
-x, -y, 0.0f, w, 0, 1,
x, -y, 0.0f, w, 1, 1,
x, y, 0.0f, w, 1, 0,
-x, -y, 0, w, 0, 1,
x, y, 0, w, 1, 0,
-x, y, 0, w, 0, 0,
-x, -y, 0, w, 0, 1,
x, -y, 0, w, 1, 1,
x, y, 0, w, 1, 0,
};
glBindVertexArray(_quad); // bind array

View File

@@ -49,7 +49,7 @@
virtual void update();
private:
virtual void setParent() override;
void loadTexture();
void createPlane();
@@ -68,7 +68,9 @@
GLuint _quad;
GLuint _vertexPositionBuffer;
glm::dmat3 _stateMatrix;
glm::dmat3 _stateMatrix;
std::string _frame;
std::string _var;
// bool _planeIsDirty;
};

View File

@@ -36,8 +36,7 @@ DataSurface::DataSurface(std::string path)
DataSurface::~DataSurface(){}
bool DataSurface::initialize(){
_parent = OsEng.renderEngine().scene()->sceneGraphNode("Earth");
setParent();
return true;
}

View File

@@ -44,11 +44,13 @@ public:
protected:
void setPscUniforms(ghoul::opengl::ProgramObject* program, const Camera* camera, const PowerScaledCoordinate& position);
virtual void setParent() = 0;
properties::StringProperty _path;
std::unique_ptr<ghoul::opengl::ProgramObject> _shader;
SceneGraphNode* _parent;
double _time;
};
}//namespace openspace

View File

@@ -42,6 +42,7 @@ namespace openspace{
std::cout << "Initialized datasurface container" << std::endl;
addDataSurface("${OPENSPACE_DATA}/BATSRUS.cdf");
// addDataSurface("${OPENSPACE_DATA}/ENLIL.cdf");
//addTextureSurface("${OPENSPACE_DATA}/test.png");
}
bool DataSurfaceContainer::deinitialize(){}

View File

@@ -161,6 +161,10 @@ void TexturePlane::update(){
}
}
void TexturePlane::setParent(){
_parent = OsEng.renderEngine().scene()->sceneGraphNode("Earth");
}
void TexturePlane::updateTexture(){
int imageSize = 1024;
DownloadManager::FileFuture* future;

View File

@@ -50,6 +50,7 @@
virtual void update();
private:
virtual void setParent() override;
void loadTexture();
void createPlane();

View File

@@ -368,6 +368,11 @@ float* KameleonWrapper::getUniformSliceValues(
_model->loadVariable(var);
auto vars = _model->getLoadedVariables();
for(v :vars){
std::cout << v << std::endl;
}
double varMin = _model->getVariableAttribute(var, "actual_min").getAttributeFloat();
double varMax = _model->getVariableAttribute(var, "actual_max").getAttributeFloat();
@@ -384,31 +389,80 @@ float* KameleonWrapper::getUniformSliceValues(
for (int x = 0; x < outDimensions.x; ++x) {
for (int y = 0; y < outDimensions.y; ++y) {
double value = 0;
unsigned int index = static_cast<unsigned int>(x + y*outDimensions.x);
if(_gridType == GridType::Spherical) {
// int z = zSlice;
// Put r in the [0..sqrt(3)] range
double rNorm = sqrt(3.0)*(double)x/(double)(outDimensions.x-1);
// Put theta in the [0..PI] range
double thetaNorm = M_PI*(double)zSlice; ///(double)(outDimensions.y-1);
// Put phi in the [0..2PI] range
double phiNorm = 2.0*M_PI*(double)y/(double)(outDimensions.y-1);
// Go to physical coordinates before sampling
double rPh = _xMin + rNorm*(_xMax-_xMin);
double thetaPh = thetaNorm;
// phi range needs to be mapped to the slightly different model
// range to avoid gaps in the data Subtract a small term to
// avoid rounding errors when comparing to phiMax.
double phiPh = _zMin + phiNorm/(2.0*M_PI)*(_zMax-_zMin-0.000001);
// See if sample point is inside domain
if (rPh < _xMin || rPh > _xMax || thetaPh < _yMin ||
thetaPh > _yMax || phiPh < _zMin || phiPh > _zMax) {
if (phiPh > _zMax) {
std::cout << "Warning: There might be a gap in the data\n";
}
// Leave values at zero if outside domain
} else { // if inside
// ENLIL CDF specific hacks!
// Convert from meters to AU for interpolator
rPh /= ccmc::constants::AU_in_meters;
// Convert from colatitude [0, pi] rad to latitude [-90, 90] degrees
thetaPh = -thetaPh*180.f/M_PI+90.f;
// Convert from [0, 2pi] rad to [0, 360] degrees
phiPh = phiPh*180.f/M_PI;
// Sample
value = _interpolator->interpolate(
var,
static_cast<float>(rPh),
static_cast<float>(phiPh),
static_cast<float>(thetaPh));
// value = _interpolator->interpolate(var, rPh, phiPh, thetaPh);
}
}else{
double xPos = _xMax - stepX*x;
double yPos = _yMin + stepY*y;
double zPos = (_zMin + (_zMax-_zMin)*zSlice);
double xPos = _xMin + stepX*x;
double yPos = _yMin + stepY*y;
double zPos = (_zMin + (_zMax-_zMin)*zSlice);
// Should y and z be flipped?
double value = _interpolator->interpolate(
var,
static_cast<float>(xPos),
static_cast<float>(yPos),
static_cast<float>(zPos));
// Should y and z be flipped?
value = _interpolator->interpolate(
var,
static_cast<float>(xPos),
static_cast<float>(zPos),
static_cast<float>(yPos));
}
if(value != missingValue){
doubleData[index] = value;
if(value > maxValue){
doubleData[index] = value;
if(value > maxValue){
maxValue = value;
}
if(value < minValue){
minValue = value;
}
}else{
std::cout << "value missing" << std::endl;
// std::cout << "value missing" << std::endl;
doubleData[index] = 0;
}
}
@@ -416,6 +470,8 @@ float* KameleonWrapper::getUniformSliceValues(
for(size_t i = 0; i < size; ++i) {
double normalizedVal = (doubleData[i]-minValue)/(maxValue-minValue);
data[i] = glm::clamp(normalizedVal, 0.0, 1.0);
// data[i] = 1;
// std::cout << minValue << ", " << maxValue << ", " << doubleData[i] << ", " << normalizedVal << ", " << data[i] << std::endl;
}
std::cout << std::endl << std::endl;
@@ -653,7 +709,7 @@ glm::vec4 KameleonWrapper::getModelScaleScaled(){
}
else if (std::get<0>(gridUnits) == "m" && std::get<1>(gridUnits) == "radian" && std::get<2>(gridUnits) == "radian") {
// For spherical coordinate systems the radius is in meter
scale.w = -log10(1.0f/getGridMax().x);
scale.w = -log10(1.0f/_xMax);
}
return scale;