Exemplo n.º 1
0
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));
}
Exemplo n.º 2
0
InteractionHandler::InteractionHandler()
    : properties::PropertyOwner()
    , _camera(nullptr)
    , _focusNode(nullptr)
    , _deltaTime(0.0)
    //, _validKeyLua(false)
    , _controllerSensitivity(1.f)
    , _invertRoll(true)
    , _invertRotation(false)
    , _keyboardController(nullptr)
    , _mouseController(nullptr)
    , _origin("origin", "Origin", "")
    , _coordinateSystem("coordinateSystem", "Coordinate System", "")
    , _currentKeyframeTime(-1.0)
{
    setName("Interaction");
    
    _origin.onChange([this](){
        SceneGraphNode* node = sceneGraphNode(_origin.value());
        if (!node) {
            LWARNING("Could not find a node in scenegraph called '" << _origin.value() <<"'");
            return;
        }
        setFocusNode(node);
    });
    addProperty(_origin);
    
    _coordinateSystem.onChange([this](){
        OsEng.renderEngine().changeViewPoint(_coordinateSystem.value());
    });
    addProperty(_coordinateSystem);
}
Exemplo n.º 3
0
properties::Property* property(const std::string& uri) {
    properties::Property* globalProp = OsEng.globalPropertyOwner().property(uri);
    if (globalProp) {
        return globalProp;
    }
    else {
        // The URI consists of the following form at this stage:
        // <node name>.{<property owner>.}^(0..n)<property id>
        const size_t nameSeparator = uri.find(properties::PropertyOwner::URISeparator);
        if (nameSeparator == std::string::npos) {
            LERROR("Malformed URI '" << uri << "': At least one '" << nameSeparator
                   << "' separator must be present.");
            return nullptr;
        }
        const std::string nameUri = uri.substr(0, nameSeparator);
        const std::string remainingUri = uri.substr(nameSeparator + 1);

        SceneGraphNode* node = sceneGraphNode(nameUri);
        if (node) {
            properties::Property* property = node->property(remainingUri);
            return property;
        }

        std::shared_ptr<ScreenSpaceRenderable> ssr = OsEng.renderEngine().screenSpaceRenderable(nameUri);
        if(ssr){
            properties::Property* property = ssr->property(remainingUri);
            return property;
        }
#ifdef OPENSPACE_MODULE_ISWA_ENABLED
        std::shared_ptr<IswaBaseGroup> group = IswaManager::ref().iswaGroup(nameUri);
        if(group){
            properties::Property* property = group->property(remainingUri);
            return property;
        }
#endif
        LERROR("Node or ScreenSpaceRenderable' " << nameUri << "' did not exist");
        return nullptr;
    }
}
Exemplo n.º 4
0
bool SceneGraph::loadFromFile(const std::string& sceneDescription) {
    clear(); // Move this to a later stage to retain a proper scenegraph when the loading fails ---abock

    std::string absSceneFile = absPath(sceneDescription);

    // See if scene file exists
    if (!FileSys.fileExists(absSceneFile, true)) {
        LERROR("Could not load scene file '" << absSceneFile << "'. " <<
            "File not found");
        return false;
    }
    LINFO("Loading SceneGraph from file '" << absSceneFile << "'");

    // Load dictionary
    ghoul::Dictionary sceneDictionary;
    try {
        ghoul::lua::loadDictionaryFromFile(absSceneFile, sceneDictionary);
    }
    catch (...) {
        return false;
    }

    std::string sceneDescriptionDirectory =
    ghoul::filesystem::File(absSceneFile, true).directoryName();
    std::string sceneDirectory(".");
    sceneDictionary.getValue(KeyPathScene, sceneDirectory);

    // The scene path could either be an absolute or relative path to the description
    // paths directory
    std::string relativeCandidate = sceneDescriptionDirectory +
        ghoul::filesystem::FileSystem::PathSeparator + sceneDirectory;
    std::string absoluteCandidate = absPath(sceneDirectory);

    if (FileSys.directoryExists(relativeCandidate))
        sceneDirectory = relativeCandidate;
    else if (FileSys.directoryExists(absoluteCandidate))
        sceneDirectory = absoluteCandidate;
    else {
        LERROR("The '" << KeyPathScene << "' pointed to a "
            "path '" << sceneDirectory << "' that did not exist");
        return false;
    }

    ghoul::Dictionary moduleDictionary;
    bool success = sceneDictionary.getValue(KeyModules, moduleDictionary);
    if (!success)
        // There are no modules that are loaded
        return true;

    lua_State* state = ghoul::lua::createNewLuaState();
    OsEng.scriptEngine().initializeLuaState(state);

    // Get the common directory
    bool commonFolderSpecified = sceneDictionary.hasKey(KeyCommonFolder);
    bool commonFolderCorrectType = sceneDictionary.hasKeyAndValue<std::string>(KeyCommonFolder);

    if (commonFolderSpecified) {
        if (commonFolderCorrectType) {
            std::string commonFolder = sceneDictionary.value<std::string>(KeyCommonFolder);
            std::string fullCommonFolder = FileSys.pathByAppendingComponent(
                sceneDirectory,
                commonFolder
            );
            if (!FileSys.directoryExists(fullCommonFolder))
                LERROR("Specified common folder '" << fullCommonFolder << "' did not exist");
            else {
                if (!commonFolder.empty()) {
                    FileSys.registerPathToken(_commonModuleToken, commonFolder);
                    size_t nKeys = moduleDictionary.size();
                    moduleDictionary.setValue(std::to_string(nKeys + 1), commonFolder);
                }
            }
        }
        else
            LERROR("Specification for 'common' folder has invalid type");
    }

    std::vector<std::string> keys = moduleDictionary.keys();

    std::map<std::string, std::vector<std::string>> dependencies;
    std::map<std::string, std::string> parents;

    _rootNode = new SceneGraphNode;
    _rootNode->setName(SceneGraphNode::RootNodeName);
    SceneGraphNodeInternal* internalRoot = new SceneGraphNodeInternal;
    internalRoot->node = _rootNode;
    _nodes.push_back(internalRoot);

    std::sort(keys.begin(), keys.end());
    ghoul::filesystem::Directory oldDirectory = FileSys.currentDirectory();
    for (const std::string& key : keys) {
        std::string moduleName = moduleDictionary.value<std::string>(key);
        std::string modulePath = FileSys.pathByAppendingComponent(sceneDirectory, moduleName);

        if (!FileSys.directoryExists(modulePath)) {
            LERROR("Could not load module '" << moduleName << "'. Directory did not exist");
            continue;
        }

        std::string moduleFile = FileSys.pathByAppendingComponent(
            modulePath,
            moduleName + _moduleExtension
        );

        if (!FileSys.fileExists(moduleFile)) {
            LERROR("Could not load module file '" << moduleFile << "'. File did not exist");
            continue;
        }

        ghoul::Dictionary moduleDictionary;
        try {
            ghoul::lua::loadDictionaryFromFile(moduleFile, moduleDictionary, state);
        }
        catch (...) {
            continue;
        }

        std::vector<std::string> keys = moduleDictionary.keys();
        for (const std::string& key : keys) {
            if (!moduleDictionary.hasValue<ghoul::Dictionary>(key)) {
                LERROR("SceneGraphNode '" << key << "' is not a table in module '"
                                             << moduleFile << "'");
                continue;
            }

            ghoul::Dictionary element;
            std::string nodeName;
            std::string parentName;

            moduleDictionary.getValue(key, element);
            element.setValue(KeyPathModule, modulePath);

            element.getValue(SceneGraphNode::KeyName, nodeName);
            element.getValue(SceneGraphNode::KeyParentName, parentName);

            FileSys.setCurrentDirectory(modulePath);
            SceneGraphNode* node = SceneGraphNode::createFromDictionary(element);
            if (node == nullptr) {
                LERROR("Error loading SceneGraphNode '" << nodeName << "' in module '" << moduleName << "'");
                continue;
                //clear();
                //return false;
            }

            dependencies[nodeName].push_back(parentName);
            parents[nodeName] = parentName;
            // Also include loaded dependencies

            if (element.hasKey(SceneGraphNode::KeyDependencies)) {
                if (element.hasValue<ghoul::Dictionary>(SceneGraphNode::KeyDependencies)) {
                    ghoul::Dictionary nodeDependencies;
                    element.getValue(SceneGraphNode::KeyDependencies, nodeDependencies);

                    std::vector<std::string> keys = nodeDependencies.keys();
                    for (const std::string& key : keys) {
                        std::string value = nodeDependencies.value<std::string>(key);
                        dependencies[nodeName].push_back(value);
                    }
                }
                else {
                    LERROR("Dependencies did not have the corrent type");
                }
            }


            SceneGraphNodeInternal* internalNode = new SceneGraphNodeInternal;
            internalNode->node = node;
            _nodes.push_back(internalNode);
        }
    }
    ghoul::lua::destroyLuaState(state);
    FileSys.setCurrentDirectory(oldDirectory);

    for (SceneGraphNodeInternal* node : _nodes) {
        if (node->node == _rootNode)
            continue;
        std::string parent = parents[node->node->name()];
        SceneGraphNode* parentNode = sceneGraphNode(parent);
        if (parentNode == nullptr) {
            LERROR("Could not find parent '" << parent << "' for '" << node->node->name() << "'");
        }

        node->node->setParent(parentNode);
    }

    // Setup dependencies
    for (SceneGraphNodeInternal* node : _nodes) {
        std::vector<std::string> nodeDependencies = dependencies[node->node->name()];

        for (const std::string& dep : nodeDependencies) {
            SceneGraphNodeInternal* n = nodeByName(dep);
            if (n == nullptr) {
                LERROR("Dependent node '" << dep << "' was not loaded for '" <<node->node->name() << "'");
                continue;
            }
            node->outgoingEdges.push_back(n);
            n->incomingEdges.push_back(node);
        }
    }

    std::vector<SceneGraphNodeInternal*> nodesToDelete;
    for (SceneGraphNodeInternal* node : _nodes) {
        if (!nodeIsDependentOnRoot(node)) {
            LERROR("Node '" << node->node->name() << "' has no direct connection to Root.");
            nodesToDelete.push_back(node);
        }
    }

    for (SceneGraphNodeInternal* node : nodesToDelete) {
        _nodes.erase(std::find(_nodes.begin(), _nodes.end(), node));
        delete node;
    }

    bool s = sortTopologically();
    if (!s) {
        LERROR("Topological sort failed");
        return false;
    }
    
    return true;
}
Exemplo n.º 5
0
Renderable* renderable(const std::string& name) {
    SceneGraphNode* node = sceneGraphNode(name);
    return node->renderable();
}
Exemplo n.º 6
0
// InteractionHandler
InteractionHandler::InteractionHandler()
    : _origin("origin", "Origin", "")
    , _coordinateSystem("coordinateSystem", "Coordinate System", "")
    , _rotationalFriction("rotationalFriction", "Rotational Friction", true)
    , _horizontalFriction("horizontalFriction", "Horizontal Friction", true)
    , _verticalFriction("verticalFriction", "Vertical Friction", true)
    , _sensitivity("sensitivity", "Sensitivity", 0.002, 0.0001, 0.02)
    , _rapidness("rapidness", "Rapidness", 1, 0.1, 60)
{
    setName("Interaction");

    _origin.onChange([this]() {
        SceneGraphNode* node = sceneGraphNode(_origin.value());
        if (!node) {
            LWARNING("Could not find a node in scenegraph called '" << _origin.value() << "'");
            return;
        }
        setFocusNode(node);
        resetCameraDirection();
    });

    _coordinateSystem.onChange([this]() {
        OsEng.renderEngine().changeViewPoint(_coordinateSystem.value());
    });

    // Create the interactionModes
    _inputState = std::make_unique<InputState>();
    // Inject the same mouse states to both orbital and global interaction mode
    _mouseStates = std::make_unique<OrbitalInteractionMode::MouseStates>(0.002, 1);
    _interactionModes.insert(
        std::pair<std::string, std::shared_ptr<InteractionMode>>(
            "Orbital",
            std::make_shared<OrbitalInteractionMode>(_mouseStates)
            ));
    _interactionModes.insert(
        std::pair<std::string, std::shared_ptr<InteractionMode>>(
            "GlobeBrowsing",
            std::make_shared<GlobeBrowsingInteractionMode>(_mouseStates)
            ));

    // Set the interactionMode
    _currentInteractionMode = _interactionModes["Orbital"];

    // Define lambda functions for changed properties
    _rotationalFriction.onChange([&]() {
        _mouseStates->setRotationalFriction(_rotationalFriction);
    });
    _horizontalFriction.onChange([&]() {
        _mouseStates->setHorizontalFriction(_horizontalFriction);
    });
    _verticalFriction.onChange([&]() {
        _mouseStates->setVerticalFriction(_verticalFriction);
    });
    _sensitivity.onChange([&]() {
        _mouseStates->setSensitivity(_sensitivity);
    });
    _rapidness.onChange([&]() {
        _mouseStates->setVelocityScaleFactor(_rapidness);
    });

    // Add the properties
    addProperty(_origin);
    addProperty(_coordinateSystem);

    addProperty(_rotationalFriction);
    addProperty(_horizontalFriction);
    addProperty(_verticalFriction);
    addProperty(_sensitivity);
    addProperty(_rapidness);
}