ScreenSpaceImage::ScreenSpaceImage(const ghoul::Dictionary& dictionary) : ScreenSpaceRenderable(dictionary) , _texturePath("texturePath", "Texture path", "") , _downloadImage(false) { std::string name; if (dictionary.getValue(KeyName, name)) { setName(name); } else { static int id = 0; setName("ScreenSpaceImage " + std::to_string(id)); ++id; } addProperty(_texturePath); std::string texturePath; if (dictionary.getValue(KeyTexturePath, texturePath)) { _texturePath = texturePath; _texturePath.onChange([this](){ loadTexture(); }); } if (dictionary.getValue(KeyUrl, _url)) { _downloadImage = true; } }
void InteractionHandler::setCameraStateFromDictionary(const ghoul::Dictionary& cameraDict) { bool readSuccessful = true; std::string focus; glm::dvec3 cameraPosition; glm::dvec4 cameraRotation; // Need to read the quaternion as a vector first. readSuccessful &= cameraDict.getValue(KeyFocus, focus); readSuccessful &= cameraDict.getValue(KeyPosition, cameraPosition); readSuccessful &= cameraDict.getValue(KeyRotation, cameraRotation); if (!readSuccessful) { throw ghoul::RuntimeError( "Position, Rotation and Focus need to be defined for camera dictionary."); } SceneGraphNode* node = sceneGraphNode(focus); if (!node) { throw ghoul::RuntimeError( "Could not find a node in scenegraph called '" + focus + "'"); } // Set state setFocusNode(node); _camera->setPositionVec3(cameraPosition); _camera->setRotation(glm::dquat( cameraRotation.x, cameraRotation.y, cameraRotation.z, cameraRotation.w)); }
InstrumentDecoder::InstrumentDecoder(const ghoul::Dictionary& dictionary) { bool success = dictionary.getValue(keyDetector, _type); ghoul_assert(success, "Instrument has not provided detector type"); for_each(_type.begin(), _type.end(), [](char& in){ in = ::toupper(in); }); if (!dictionary.hasKeyAndValue<std::string>(keyStopCommand) && _type == "SCANNER"){ LWARNING("Scanner must provide stop command, please check mod file."); }else{ dictionary.getValue(keyStopCommand, _stopCommand); } std::vector<std::string> spice; ghoul::Dictionary spiceDictionary; success = dictionary.getValue(keySpice, spiceDictionary); ghoul_assert(success, "Instrument did not provide spice ids"); _spiceIDs.resize(spiceDictionary.size()); for (int i = 0; i < _spiceIDs.size(); ++i) { std::string id; spiceDictionary.getValue(std::to_string(i + 1), id); _spiceIDs[i] = id; } }
ModelGeometry::ModelGeometry(const ghoul::Dictionary& dictionary) : _parent(nullptr) , _magnification("magnification", "Magnification", 1.f, 0.f, 10.f) , _mode(GL_TRIANGLES) { setName("ModelGeometry"); std::string name; bool success = dictionary.getValue(keyName, name); ghoul_assert(success, "Name tag was not present"); if (dictionary.hasKeyAndValue<double>(keySize)) _magnification = static_cast<float>(dictionary.value<double>(keySize)); success = dictionary.getValue(keyGeomModelFile, _file); if (!success) { LERROR("Geometric Model file of '" << name << "' did not provide a key '" << keyGeomModelFile << "'"); } _file = FileSys.absolutePath(_file); if (!FileSys.fileExists(_file, ghoul::filesystem::FileSystem::RawPath::Yes)) LERROR("Could not load the geometric model file '" << _file << "': File not found"); addProperty(_magnification); }
RenderablePlaneProjection::RenderablePlaneProjection(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _texturePath("") , _planeIsDirty(false) , _shader(nullptr) , _textureIsDirty(false) , _texture(nullptr) , _quad(0) , _vertexPositionBuffer(0) , _name("ImagePlane") , _previousTime(0) , _moving(false) , _hasImage(false) { dictionary.getValue(KeySpacecraft, _spacecraft); dictionary.getValue(KeyInstrument, _instrument); dictionary.getValue(KeyMoving, _moving); dictionary.getValue(KeyName, _name); dictionary.getValue(KeyTarget, _defaultTarget); std::string texturePath = ""; bool success = dictionary.getValue(KeyTexture, _texturePath); if (success) { _texturePath = absPath(_texturePath); _textureFile = new ghoul::filesystem::File(_texturePath); } loadTexture(); }
MissionPhase::MissionPhase(const ghoul::Dictionary& dict) { _name = dict.value<std::string>(KeyName); dict.getValue(KeyDescription, _description); ghoul::Dictionary childDicts; if (dict.getValue(KeyPhases, childDicts)) { // This is a nested mission phase _subphases.reserve(childDicts.size()); for (size_t i = 0; i < childDicts.size(); ++i) { std::string key = std::to_string(i + 1); _subphases.emplace_back(childDicts.value<ghoul::Dictionary>(key)); } // Ensure subphases are sorted std::stable_sort( _subphases.begin(), _subphases.end(), [](const MissionPhase& a, const MissionPhase& b) { return a.timeRange().start < b.timeRange().start; } ); // Calculate the total time range of all subphases TimeRange timeRangeSubPhases; timeRangeSubPhases.start = _subphases[0].timeRange().start; timeRangeSubPhases.end = _subphases.back().timeRange().end; // user may specify an overall time range. In that case expand this timerange. ghoul::Dictionary timeRangeDict; if (dict.getValue(KeyTimeRange, timeRangeDict)) { TimeRange overallTimeRange(timeRangeDict); if (!overallTimeRange.includes(timeRangeSubPhases)) { throw ghoul::RuntimeError( "User specified time range must at least include its subphases'", "Mission (" + _name + ")" ); } _timeRange.include(overallTimeRange); } else { // Its OK to not specify an overall time range, the time range for the // subphases will simply be used. _timeRange.include(timeRangeSubPhases); } } else { ghoul::Dictionary timeRangeDict; if (dict.getValue(KeyTimeRange, timeRangeDict)) { _timeRange = TimeRange(timeRangeDict); // throws exception if unable to parse } else { throw ghoul::RuntimeError( "If there are no subphases specified, the time range has to be specified", "Mission (" + _name + ")" ); } } }
TargetDecoder::TargetDecoder(const ghoul::Dictionary& dictionary) :_type("TARGET") { _names.resize(dictionary.size()); for (int i = 0; i < _names.size(); ++i) { std::string readMe; dictionary.getValue(std::to_string(i + 1), readMe); _names[i] = readMe; } }
RenderablePath::RenderablePath(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _lineWidth("lineWidth", "Line Width", 2.f, 1.f, 20.f) , _drawLine("drawline", "Draw Line", false) , _programObject(nullptr) , _successfullDictionaryFetch(true) , _vaoID(0) , _vBufferID(0) , _needsSweep(true) , _start(0.0) , _stop(0.0) { _successfullDictionaryFetch &= dictionary.getValue(keyBody, _target); _successfullDictionaryFetch &= dictionary.getValue(keyObserver, _observer); _successfullDictionaryFetch &= dictionary.getValue(keyFrame, _frame); _successfullDictionaryFetch &= dictionary.getValue(keyTimeSteps, _increment); float fPointSteps; // Dictionary can not pick out ints... if (!dictionary.getValue(keyPointSteps, fPointSteps)) fPointSteps = 4; _pointSteps = fPointSteps; glm::vec3 color(0.f); if (dictionary.hasKeyAndValue<glm::vec3>(keyColor)) dictionary.getValue(keyColor, color); _lineColor = color; bool drawLine = false; if (dictionary.hasKeyAndValue<bool>(keyDrawLine)) dictionary.getValue(keyDrawLine, drawLine); _drawLine = drawLine; addProperty(_drawLine); addProperty(_lineWidth); _distanceFade = 1.0; }
RenderableCrawlingLine::RenderableCrawlingLine(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _program(nullptr) , _imageSequenceTime(-1.f) , _vao(0) , _vbo(0) { dictionary.getValue(KeySource, _source); dictionary.getValue(KeyTarget, _target); dictionary.getValue(KeyInstrument, _instrumentName); dictionary.getValue(KeyReferenceFrame, _referenceFrame); if (dictionary.hasKeyAndValue<glm::vec3>(keyColor)) dictionary.getValue(keyColor, _lineColor); else _lineColor = glm::vec3(1); }
SimpleSphereGeometry::SimpleSphereGeometry(const ghoul::Dictionary& dictionary) : PlanetGeometry() , _realRadius("radius", "Radius", glm::vec4(1.f, 1.f, 1.f, 0.f), glm::vec4(-10.f, -10.f, -10.f, -20.f), glm::vec4(10.f, 10.f, 10.f, 20.f)) , _segments("segments", "Segments", 20, 1, 5000) , _sphere(nullptr) { using constants::simplespheregeometry::keyRadius; using constants::simplespheregeometry::keySegments; // The name is passed down from the SceneGraphNode bool success = dictionary.getValue(SceneGraphNode::KeyName, _name); assert(success); glm::vec4 radius; success = dictionary.getValue(keyRadius, _modRadius); if (!success) { LERROR("SimpleSphereGeometry of '" << _name << "' did not provide a key '" << keyRadius << "'"); } else { radius[0] = _modRadius[0]; radius[1] = _modRadius[0]; radius[2] = _modRadius[0]; radius[3] = _modRadius[1]; _realRadius = radius; // In case the kernels does not supply a real } double segments; success = dictionary.getValue(keySegments, segments); if (!success) { LERROR("SimpleSphereGeometry of '" << _name << "' did not provide a key '" << keySegments << "'"); } else _segments = static_cast<int>(segments); // The shader need the radii values but they are not changeable runtime // TODO: Possibly add a scaling property @AA addProperty(_realRadius); // Changing the radius/scaling should affect the shader but not the geometry? @AA //_radius.onChange(std::bind(&SimpleSphereGeometry::createSphere, this)); addProperty(_segments); _segments.onChange(std::bind(&SimpleSphereGeometry::createSphere, this)); }
DynamicEphemeris::DynamicEphemeris(const ghoul::Dictionary& dictionary) : _position(0.f, 0.f, 0.f, 0.f) { const bool hasPosition = dictionary.hasKeyAndValue<glm::vec4>(KeyPosition); if (hasPosition) { glm::vec4 tmp; dictionary.getValue(KeyPosition, tmp); _position = tmp; } }
StaticRotation::StaticRotation(const ghoul::Dictionary& dictionary) : _rotationMatrix(1.0) { const bool hasEulerAngles = dictionary.hasKeyAndValue<glm::dvec3>(KeyEulerAngles); if (hasEulerAngles) { glm::dvec3 tmp; dictionary.getValue(KeyEulerAngles, tmp); _rotationMatrix = glm::mat3_cast(glm::dquat(tmp)); } }
void ScriptScheduler::loadScripts(const ghoul::Dictionary& dictionary) { // Check if all of the scheduled scripts are formed correctly documentation::testSpecificationAndThrow( Documentation(), dictionary, "ScriptScheduler" ); // Create all the scheduled script first std::vector<ScheduledScript> scheduledScripts; for (size_t i = 1; i <= dictionary.size(); ++i) { const ghoul::Dictionary& timedScriptDict = dictionary.value<ghoul::Dictionary>( std::to_string(i) ); scheduledScripts.emplace_back(timedScriptDict); } // Sort scripts by time; use a stable_sort as the user might have had an intention // specifying multiple scripts for the same time in a specific order std::stable_sort( scheduledScripts.begin(), scheduledScripts.end(), [](const ScheduledScript& lhs, const ScheduledScript& rhs) { return lhs.time < rhs.time; } ); // Move the scheduled scripts into their SOA alignment // For the forward scripts, this is the forwards direction // For the backward scripts, we insert them in the opposite order so that we can still // return forward iterators to them in the progressTo method for (ScheduledScript& script : scheduledScripts) { _timings.push_back(script.time); _forwardScripts.push_back(std::move(script.forwardScript)); _backwardScripts.insert( _backwardScripts.begin(), std::move(script.backwardScript) ); } // Ensure _currentIndex and _currentTime is accurate after new scripts was added double lastTime = _currentTime; rewind(); progressTo(lastTime); ghoul_assert( (_timings.size() == _forwardScripts.size()) && (_timings.size() == _backwardScripts.size()), "The SOA data structure has been mistreated and has different number of values" ); }
SizeReferenceTileProvider::SizeReferenceTileProvider(const ghoul::Dictionary& dictionary) { _fontSize = 50; ghoul::fontrendering::FontManager& fm = OsEng.fontManager(); _font = fm.font("Mono", _fontSize); glm::dvec3 radii(1,1,1); if (!dictionary.getValue(KeyRadii, radii)) { throw std::runtime_error("Must define key '" + KeyRadii + "'"); } _ellipsoid = Ellipsoid(radii); _backgroundTile.status = Tile::Status::Unavailable; std::string backgroundImagePath; if (dictionary.getValue(KeyBackgroundImagePath, backgroundImagePath)) { using namespace ghoul::io; std::string imgAbsPath = absPath(backgroundImagePath); _backgroundTile.texture = TextureReader::ref().loadTexture(imgAbsPath); _backgroundTile.texture->uploadTexture(); _backgroundTile.texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); _backgroundTile.status = Tile::Status::OK; } }
TileProviderManager::TileProviderManager( const ghoul::Dictionary& textureCategoriesDictionary, const ghoul::Dictionary& textureInitDictionary){ // Create all the categories of tile providers for (size_t i = 0; i < textureCategoriesDictionary.size(); i++) { ghoul::Dictionary texturesDict = textureCategoriesDictionary.value<ghoul::Dictionary>( LayeredTextures::TEXTURE_CATEGORY_NAMES[i]); ghoul_assert(texturesDict.size() <= LayeredTextures::MAX_NUM_TEXTURES_PER_CATEGORY, "Too many textures! Number of textures per category must be less than or equal to " << LayeredTextures::MAX_NUM_TEXTURES_PER_CATEGORY); TileProviderInitData initData; if (i == LayeredTextures::ColorTextures || i == LayeredTextures::NightTextures || i == LayeredTextures::WaterMasks || i == LayeredTextures::GrayScaleOverlays) { initData.minimumPixelSize = textureInitDictionary.value<double>("ColorTextureMinimumSize"); } else if (i == LayeredTextures::Overlays) { initData.minimumPixelSize = textureInitDictionary.value<double>("OverlayMinimumSize"); } else if (i == LayeredTextures::HeightMaps) { initData.minimumPixelSize = textureInitDictionary.value<double>("HeightMapMinimumSize"); } else { initData.minimumPixelSize = 512; } initData.threads = 1; initData.cacheSize = 5000; initData.framesUntilRequestQueueFlush = 60; // Only preprocess height maps. initData.preprocessTiles = i == LayeredTextures::HeightMaps; initTexures( _layerCategories[i].tileProviders, texturesDict, initData); // init level blending to be true _layerCategories[i].levelBlendingEnabled = true; } }
void TileProviderManager::initTexures(std::vector<NamedTileProvider>& dest, const ghoul::Dictionary& texturesDict, const TileProviderInitData& initData) { // Create TileProviders for all textures within this category for (size_t i = 0; i < texturesDict.size(); i++) { std::string name, path; std::string dictKey = std::to_string(i + 1); ghoul::Dictionary texDict = texturesDict.value<ghoul::Dictionary>(dictKey); texDict.getValue("Name", name); texDict.getValue("FilePath", path); std::string type = "LRUCaching"; // if type is unspecified texDict.getValue("Type", type); TileProvider* tileProvider; auto tileProviderFactory = FactoryManager::ref().factory<TileProvider>(); try { tileProvider = tileProviderFactory->create(type, texDict); } catch (const ghoul::RuntimeError& e) { LERROR(e.what()); continue; } // Something else went wrong and no exception was thrown if (tileProvider == nullptr) { LERROR("Unable to create TileProvider '" << name << "' of type '" << type << "'"); continue; } bool enabled = false; // defaults to false if unspecified texDict.getValue("Enabled", enabled); dest.push_back({ name, std::shared_ptr<TileProvider>(tileProvider), enabled }); } }
ScriptScheduler::ScheduledScript::ScheduledScript(const ghoul::Dictionary& dictionary) : time(-std::numeric_limits<double>::max()) { std::string timeStr = dictionary.value<std::string>(KeyTime); time = Time::ref().convertTime(timeStr); // If a universal script is specified, retrieve it and add a ; as a separator so that // it can be added to the other scripts std::string universal; dictionary.getValue(KeyUniversalScript, universal); if (!universal.empty()) { universal += ";"; } if (dictionary.hasKeyAndValue<std::string>(KeyForwardScript)) { forwardScript = universal + dictionary.value<std::string>(KeyForwardScript); } if (dictionary.hasKeyAndValue<std::string>(KeyBackwardScript)) { backwardScript = universal + dictionary.value<std::string>(KeyBackwardScript); } }
RenderableGalaxy::RenderableGalaxy(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _stepSize("stepSize", "Step Size", 0.012, 0.0005, 0.05) , _pointStepSize("pointStepSize", "Point Step Size", 0.01, 0.01, 0.1) , _translation("translation", "Translation", glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0), glm::vec3(10.0)) , _rotation("rotation", "Euler rotation", glm::vec3(0.0, 0.0, 0.0), glm::vec3(0), glm::vec3(6.28)) , _enabledPointsRatio("nEnabledPointsRatio", "Enabled points", 0.2, 0, 1) { float stepSize; glm::vec3 scaling, translation, rotation; glm::vec4 color; ghoul::Dictionary volumeDictionary, pointsDictionary; if (dictionary.getValue("Translation", translation)) { _translation = translation; } if (dictionary.getValue("Rotation", rotation)) { _rotation = rotation; } if (dictionary.getValue("StepSize", stepSize)) { _stepSize = stepSize; } if (dictionary.getValue("Volume", volumeDictionary)) { std::string volumeFilename; if (volumeDictionary.getValue("Filename", volumeFilename)) { _volumeFilename = absPath(volumeFilename); } else { LERROR("No volume filename specified."); } glm::vec3 volumeDimensions; if (volumeDictionary.getValue("Dimensions", volumeDimensions)) { _volumeDimensions = static_cast<glm::ivec3>(volumeDimensions); } else { LERROR("No volume dimensions specified."); } glm::vec3 volumeSize; if (volumeDictionary.getValue("Size", volumeSize)) { _volumeSize = static_cast<glm::vec3>(volumeSize); } else { LERROR("No volume dimensions specified."); } } else { LERROR("No volume dictionary specified."); } if (dictionary.getValue("Points", pointsDictionary)) { std::string pointsFilename; if (pointsDictionary.getValue("Filename", pointsFilename)) { _pointsFilename = absPath(pointsFilename); } else { LERROR("No points filename specified."); } glm::vec3 pointsScaling; if (pointsDictionary.getValue("Scaling", pointsScaling)) { _pointScaling = static_cast<glm::vec3>(pointsScaling); } else { LERROR("No volume dimensions specified."); } } else { LERROR("No points dictionary specified."); } }
RenderableDebugPlane::RenderableDebugPlane(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _texture("texture", "Texture", -1, -1, 255) , _billboard("billboard", "Billboard", false) , _size("size", "Size", glm::vec2(1,1), glm::vec2(0.f), glm::vec2(1.f, 25.f)) , _origin(Origin::Center) , _shader(nullptr) , _quad(0) , _vertexPositionBuffer(0) { glm::vec2 size; dictionary.getValue("Size", size); _size = size; if (dictionary.hasKey("Name")){ dictionary.getValue("Name", _nodeName); } if (dictionary.hasKey("Texture")) { int t; dictionary.getValue("Texture", t); _texture = t; } std::string origin; if (dictionary.getValue("Origin", origin)) { if (origin == "LowerLeft") { _origin = Origin::LowerLeft; } else if (origin == "LowerRight") { _origin = Origin::LowerRight; } else if (origin == "UpperLeft") { _origin = Origin::UpperLeft; } else if (origin == "UpperRight") { _origin = Origin::UpperRight; } else if (origin == "Center") { _origin = Origin::Center; } } // Attempt to get the billboard value bool billboard = false; if (dictionary.getValue("Billboard", billboard)) { _billboard = billboard; } int texture; if (dictionary.getValue("Texture", texture)) _texture = texture; addProperty(_texture); addProperty(_billboard); addProperty(_size); _size.onChange([this](){ _planeIsDirty = true; }); setBoundingSphere(_size.value()); }
RenderableTrailNew::RenderableTrailNew(const ghoul::Dictionary& dictionary) : Renderable(dictionary) // Properties , _lineColor("lineColor", "Line Color", DEFAULT_COLOR, glm::vec3(0), glm::vec3(1)) , _pointColor("pointColor", "Point Color", DEFAULT_COLOR, glm::vec3(0), glm::vec3(1)) , _lineFade("lineFade", "Line Fade", DEFAULT_LINE_FADE, 0, 1) , _lineWidth("lineWidth", "Line Width", DEFAULT_LINE_WIDTH, 1, 10) , _renderPart("renderPart", "Render Part", DEFAULT_RENDER_PART, 0, DEFAULT_RENDER_PART) , _showTimeStamps("showTimeStamps", "Show TimeStamps", DEFAULT_SHOW_TIME_STAMPS) , _renderFullTrail("renderFullTrail", "Render Full Trail", DEFAULT_RENDER_FULL_TRAIL) // OpenGL , _vaoGlobalID(0) , _vBufferGlobalID(0) , _vaoLocalID(0) , _vBufferLocalID(0) // Other , _programObject(nullptr) , _successfullDictionaryFetch(true) , _currentTimeClamped(0) , _subSamples(0) { ghoul::Dictionary timeRangeDict; // Values that needs to be set _successfullDictionaryFetch &= dictionary.getValue(keyBody, _body); _successfullDictionaryFetch &= dictionary.getValue(keyObserver, _observer); _successfullDictionaryFetch &= dictionary.getValue(keyFrame, _frame); _successfullDictionaryFetch &= dictionary.getValue(keySampleDeltaTime, _sampleDeltaTime); _successfullDictionaryFetch &= dictionary.getValue(keyTimeRange, timeRangeDict); _successfullDictionaryFetch &= TimeRange::initializeFromDictionary( timeRangeDict, _timeRange); // Validate _successfullDictionaryFetch &= _sampleDeltaTime > 0; // Initialize optional values glm::vec3 lineColor = glm::vec3(DEFAULT_COLOR); glm::vec3 pointColor = glm::vec3(DEFAULT_COLOR); float lineFade = DEFAULT_LINE_FADE; float lineWidth = DEFAULT_LINE_WIDTH; float pointSteps = DEFAULT_POINT_STEPS; double renderPart = DEFAULT_RENDER_PART; bool showTimeStamps = DEFAULT_SHOW_TIME_STAMPS; bool renderFullTrail = DEFAULT_RENDER_FULL_TRAIL; // Fetch from dictionary dictionary.getValue(keyLineColor, lineColor); dictionary.getValue(keyPointColor, pointColor); dictionary.getValue(keyLineFade, lineFade); dictionary.getValue(keyLineWidth, lineWidth); dictionary.getValue(keyRenderPart, renderPart); dictionary.getValue(keyShowTimeStamps, showTimeStamps); dictionary.getValue(keyRenderFullTrail, renderFullTrail); float fSubSamples; // ghoul can not read ints from dictionaries... if (dictionary.getValue(keySubSamples, fSubSamples)) _subSamples = fSubSamples; // Set property values _lineColor = lineColor; _pointColor = pointColor; _lineFade = lineFade; _lineWidth = lineWidth; _renderPart = renderPart; _showTimeStamps = showTimeStamps; _renderFullTrail = renderFullTrail; // Add all properties and set view options addProperty(_lineColor); addProperty(_pointColor); addProperty(_lineFade); addProperty(_lineWidth); addProperty(_renderPart); addProperty(_showTimeStamps); addProperty(_renderFullTrail); _lineColor.setViewOption(properties::Property::ViewOptions::Color); _pointColor.setViewOption(properties::Property::ViewOptions::Color); }
RenderableSphericalGrid::RenderableSphericalGrid(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _gridProgram(nullptr) , _vaoID(0) , _vBufferID(0) , _iBufferID(0) , _mode(GL_LINES) { _gridMatrix = glm::mat4(1); dictionary.getValue(KeyGridType, _gridType); dictionary.getValue(KeyGridColor, _gridColor); staticGrid = dictionary.getValue(KeyGridMatrix, _gridMatrix); if (!staticGrid){ staticGrid = dictionary.getValue(KeyGridParentsRotation, _parentsRotation); } dictionary.getValue(KeyGridSegments, _segments); /*glm::vec2 radius; dictionary.getValue(constants::renderablesphericalgrid::gridRadius, radius); */ _isize = int(6 * _segments * _segments); _vsize = int((_segments + 1) * (_segments + 1)); _varray = new Vertex[_vsize]; _iarray = new int[_isize]; static_assert(sizeof(Vertex) == 64, "The size of the Vertex needs to be 64 for performance"); int nr = 0; const float fsegments = static_cast<float>(_segments); const float r = static_cast<float>(radius[0]); //int nr2 = 0; for (int i = 0; i <= _segments; i++) { // define an extra vertex around the y-axis due to texture mapping for (int j = 0; j <= _segments; j++) { const float fi = static_cast<float>(i); const float fj = static_cast<float>(j); // inclination angle (north to south) const float theta = fi * float(M_PI) / fsegments*2.f; // 0 -> PI // azimuth angle (east to west) const float phi = fj * float(M_PI) * 2.0f / fsegments; // 0 -> 2*PI const float x = r * sin(phi) * sin(theta); // const float y = r * cos(theta); // up const float z = r * cos(phi) * sin(theta); // glm::vec3 normal = glm::vec3(x, y, z); if (!(x == 0.f && y == 0.f && z == 0.f)) normal = glm::normalize(normal); //const float t1 = fj / fsegments; const float t2 = fi / fsegments; // tex coord. not used, use to manip color if (round(y) == 0.0f) _varray[nr].tex[0] = -2; _varray[nr].tex[1] = t2; glm::vec4 tmp(x, y, z, 1); glm::mat4 rot = glm::rotate(glm::mat4(1), static_cast<float>(M_PI_2), glm::vec3(1, 0, 0)); tmp = _gridMatrix*rot*tmp; for (int i = 0; i < 3; i++){ _varray[nr].location[i] = tmp[i]; _varray[nr].normal[i] = normal[i]; } _varray[nr].location[3] = static_cast<GLfloat>(radius[1]); ++nr; } } nr = 0; // define indices for all triangles for (int i = 1; i <= _segments; ++i) { for (int j = 0; j < _segments; ++j) { const int t = _segments + 1; _iarray[nr] = t * (i - 1) + j + 0; ++nr; _iarray[nr] = t * (i + 0) + j + 0; ++nr; _iarray[nr] = t * (i + 0) + j + 1; ++nr; _iarray[nr] = t * (i - 1) + j + 1; ++nr; _iarray[nr] = t * (i - 1) + j + 0; ++nr; } } }