Beispiel #1
0
SceneGraphNode* SceneGraphNode::getLeftSibling(SceneGraphNode *root, SceneGraphNode *target)
{
    if (root == NULL || target == NULL) return NULL;

    SceneGraphNode *previous = NULL;

    std::queue<SceneGraphNode *> queue;
    queue.push(root);
    root->_marked = true;

    while (!queue.empty()) {
        SceneGraphNode *t = queue.front(); queue.pop();
        if (t->isEqual(target)) {
            break;
        } else {
            previous = t;
        }

        std::vector<SceneGraphNode *>::iterator itr;
        for (itr = t->children.begin(); itr != t->children.end(); ++itr) {
            if (!(*itr)->_marked) {
                (*itr)->_marked = true;
                queue.push(*itr);
            }
        }
    }

    _clearMarked(root);
    return previous;
}
Beispiel #2
0
SceneGraphNode* SceneGraphNode::getRightSibling(SceneGraphNode *root, SceneGraphNode *target)
{
    if (root == NULL || target == NULL) return NULL;
    
    SceneGraphNode *result = NULL;
    bool foundSelf = false;
    
    std::queue<SceneGraphNode *> queue;
    queue.push(root);
    root->_marked = true;
    
    while (!queue.empty()) {
        SceneGraphNode *t = queue.front(); queue.pop();
        if (foundSelf) {
            result = t;
            break;
        }
        
        if (t->isEqual(target)) {
            foundSelf = true;
        }
        
        std::vector<SceneGraphNode *>::iterator itr;
        for (itr = t->children.begin(); itr != t->children.end(); ++itr) {
            if (!(*itr)->_marked) {
                (*itr)->_marked = true;
                queue.push(*itr);
            }
        }
    }
    
    _clearMarked(root);
    return result;
}
Beispiel #3
0
void SceneGraphEditor::updateNode(SceneGraphNode* pnode, int uid, int xpos, int ypos)
{
    feather::status e;
    unsigned int nid = feather::qml::command::get_node_id(uid,e);

    // if the node is already in the draw list, don't add a new one
    SceneGraphNode *node = getNode(uid);
    if(!node){
        std::cout << "ADDING NODE TO SG EDITOR\n";
        node = new SceneGraphNode(uid,nid,this);
        m_nodes.push_back(node);
        // setup the node qt connections
        connect(node,SIGNAL(ConnClicked(Qt::MouseButton,SceneGraphConnection::Connection,int,int)),this,SLOT(ConnOption(Qt::MouseButton,SceneGraphConnection::Connection,int,int)));
        connect(node,SIGNAL(nodePressed(Qt::MouseButton,int,int)),this,SLOT(nodePressed(Qt::MouseButton,int,int)));

        // place the node in the scenegraph
        node->setX(xpos);
        node->setY(ypos);

        // get the connected nodes
        std::vector<int> cuids;
        feather::qml::command::get_node_connected_uids(uid,cuids);

        // add a link for each connection between the two nodes
        int ystep=0;
        for(auto c : cuids) {
            // add the child node to draw list and get it's links
            updateNode(node, c, xpos+200, ypos+ystep);
            ystep+=node->height()+40;
        } 

    }
Beispiel #4
0
void annihilate(SceneGraphNode* root, bool deleteMeshes)
{
    vector<SceneGraphNode*> victims;
    stack<SceneGraphNode*> nodeStack;
    stack<int> counterStack;
    victims.clear();
    nodeStack.push(root);
    counterStack.push(-1);
    enlist(root, victims, deleteMeshes);
    while (nodeStack.size()>0)
    {
        SceneGraphNode * node = nodeStack.top();
        int childIndex = counterStack.top();
        vector<SceneGraphNode*>* children = node->getChildren();
        int childCount = children->size();
        if (childIndex < (childCount - 1))
        {
            childIndex++;
            //counterStack.set(counterStack.size() - 1, childIndex);
            counterStack.pop();
            counterStack.push(childIndex);
            SceneGraphNode * child = node->getChildren()->at(childIndex);
            nodeStack.push(child);
            counterStack.push(-1);
            enlist(child, victims, deleteMeshes);
        }
        else
        {
            nodeStack.pop();
            counterStack.pop();
        }
    }
    for (int i=0; i<victims.size(); i++)
    {
        SceneGraphNode* victim = victims.at(i);
        //Why do we need this? Because Objective-/C/C++ was not designed properly, that's why!
        if (typeid(*victim)==typeid(TransformNode))
        {
            delete (TransformNode*) victim;
        } 
        else if (typeid(*victim)==typeid(LightNode))  
        {
            delete (LightNode*) victim;
        }
        else if (typeid(*victim)==typeid(MeshNode))  
        {
            delete (MeshNode*) victim;
        }
        else
        {
            delete victim;
        }
    }
}
Beispiel #5
0
/// After we loaded our mesh, we need to add submeshes as children nodes
void Mesh::postLoad(SceneGraphNode& sgn) {
    static const U32 normalMask = to_base(ComponentType::NAVIGATION) |
                                  to_base(ComponentType::TRANSFORM) |
                                  to_base(ComponentType::BOUNDS) |
                                  to_base(ComponentType::RENDERING) |
                                  to_base(ComponentType::NAVIGATION);

    static const U32 skinnedMask = normalMask | 
                                   to_base(ComponentType::ANIMATION) |
                                   to_base(ComponentType::INVERSE_KINEMATICS) |
                                   to_base(ComponentType::RAGDOLL);

    SceneGraphNodeDescriptor subMeshDescriptor;
    subMeshDescriptor._usageContext = sgn.usageContext();
    subMeshDescriptor._instanceCount = sgn.instanceCount();

    for (const SubMesh_ptr& submesh : _subMeshList) {
        subMeshDescriptor._node = submesh;
        subMeshDescriptor._componentMask = submesh->getObjectFlag(ObjectFlag::OBJECT_FLAG_SKINNED) ? skinnedMask : normalMask;
        if (sgn.get<RigidBodyComponent>() != nullptr) {
            subMeshDescriptor._componentMask |= to_base(ComponentType::RIGID_BODY);
        }
        subMeshDescriptor._name = Util::StringFormat("%s_%d", sgn.name().c_str(), submesh->getID());
        SceneGraphNode* subSGN = sgn.addNode(subMeshDescriptor);

        if (BitCompare(subMeshDescriptor._componentMask, ComponentType::RIGID_BODY)) {
            subSGN->get<RigidBodyComponent>()->physicsGroup(sgn.get<RigidBodyComponent>()->physicsGroup());
        }

        RenderingComponent* rComp = sgn.get<RenderingComponent>();
        if (rComp != nullptr) {
            RenderingComponent* subRComp = subSGN->get<RenderingComponent>();
            for (auto it : rComp->getShaderBuffers()) {
                subRComp->addShaderBuffer(it);
            }
        }
        
    }

    sgn.get<BoundsComponent>()->ignoreTransform(true);

    Object3D::postLoad(sgn);
}
Beispiel #6
0
/// Called from SceneGraph "sceneUpdate"
void Mesh::sceneUpdate(const U64 deltaTimeUS, SceneGraphNode& sgn, SceneState& sceneState) {
    if (getObjectFlag(ObjectFlag::OBJECT_FLAG_SKINNED)) {
        sgn.forEachChild([deltaTimeUS](const SceneGraphNode& child) {
            AnimationComponent* animComp = child.get<AnimationComponent>();
            // Not all submeshes are necessarily animated. (e.g. flag on the back of a character)
            if (animComp) {
                animComp->incParentTimeStamp(deltaTimeUS);
            }
        });
    }

    Object3D::sceneUpdate(deltaTimeUS, sgn, sceneState);
}
Beispiel #7
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;
    }
}
Beispiel #8
0
void SubMesh::buildDrawCommands(SceneGraphNode& sgn,
                                RenderStagePass renderStagePass,
                                RenderPackage& pkgInOut) {

    GenericDrawCommand cmd = {};
    cmd._primitiveType = PrimitiveType::TRIANGLES,
    cmd._cmd.firstIndex = getGeometryVB()->getPartitionOffset(_geometryPartitionID);
    cmd._cmd.indexCount = getGeometryVB()->getPartitionIndexCount(_geometryPartitionID);
    cmd._cmd.primCount = sgn.instanceCount();
    cmd._sourceBuffer = _parentMesh->getGeometryVB();
    cmd._bufferIndex = renderStagePass.index();
    enableOption(cmd, CmdRenderOptions::RENDER_INDIRECT);

    GFX::DrawCommand drawCommand;
    drawCommand._drawCommands.push_back(cmd);
    pkgInOut.addDrawCommand(drawCommand);

    Object3D::buildDrawCommands(sgn, renderStagePass, pkgInOut);
}
void RenderablePlaneProjection::updatePlane(const Image img, double currentTime) {
	
	std::string frame;
	std::vector<glm::dvec3> bounds;
	glm::dvec3 boresight;
	
	std::string target = _defaultTarget;
	// Turned on if the plane should be attached to the closest target, 
	// rather than the target specified in img 
	//if (!_moving) {
	//	target = findClosestTarget(currentTime);
	//}
	if (img.path != "")
	target = img.target;

	setTarget(target);

    try {
        SpiceManager::FieldOfViewResult res = SpiceManager::ref().fieldOfView(_instrument);

        frame = std::move(res.frameName);
        bounds = std::move(res.bounds);
        boresight = std::move(res.boresightVector);
    } catch (const SpiceManager::SpiceException& e) {
        LERROR(e.what());
    }

	double lt;
	psc projection[4];

    glm::dvec3 vecToTarget = SpiceManager::ref().targetPosition(
        _target.body,
        _spacecraft,
        GalacticFrame,
        { SpiceManager::AberrationCorrection::Type::ConvergedNewtonianStellar, SpiceManager::AberrationCorrection::Direction::Reception },
        currentTime,
        lt
    );
	// The apparent position, CN+S, makes image align best with target

	for (int j = 0; j < bounds.size(); ++j) {
        bounds[j] = SpiceManager::ref().frameTransformationMatrix(frame, GalacticFrame, currentTime) * bounds[j];
        glm::dvec3 cornerPosition = glm::proj(vecToTarget, bounds[j]);
		
		if (!_moving) {
			cornerPosition -= vecToTarget;
		}
        cornerPosition = SpiceManager::ref().frameTransformationMatrix(GalacticFrame, _target.frame, currentTime) * cornerPosition;
				
		projection[j] = PowerScaledCoordinate::CreatePowerScaledCoordinate(cornerPosition[0], cornerPosition[1], cornerPosition[2]);
		projection[j][3] += 3;
	}

	if (!_moving) {
		SceneGraphNode* thisNode = OsEng.renderEngine().scene()->sceneGraphNode(_name);
		SceneGraphNode* newParent = OsEng.renderEngine().scene()->sceneGraphNode(_target.node);
		if (thisNode != nullptr && newParent != nullptr)
			thisNode->setParent(newParent);
	}
	
	const GLfloat vertex_data[] = { // square of two triangles drawn within fov in target coordinates
		//	  x      y     z     w     s     t
		projection[1][0], projection[1][1], projection[1][2], projection[1][3], 0, 1, // Lower left 1
		projection[3][0], projection[3][1], projection[3][2], projection[3][3], 1, 0, // Upper right 2
		projection[2][0], projection[2][1], projection[2][2], projection[2][3], 0, 0, // Upper left 3
		projection[1][0], projection[1][1], projection[1][2], projection[1][3], 0, 1, // Lower left 4 = 1
		projection[0][0], projection[0][1], projection[0][2], projection[0][3], 1, 1, // Lower right 5
		projection[3][0], projection[3][1], projection[3][2], projection[3][3], 1, 0, // Upper left 6 = 2
	};

	glBindVertexArray(_quad); // bind array
	glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer); // bind buffer
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast<void*>(0));
	glEnableVertexAttribArray(1);
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast<void*>(sizeof(GLfloat) * 4));

	if (!_moving && img.path != "") {
		_texturePath = img.path;
		loadTexture();
	}
}
Beispiel #10
0
    void PropertyWindow::drawInternal() {
        bool hasSelections = !selections().empty();

        Camera* selectedCamera = Attorney::EditorPropertyWindow::getSelectedCamera(_parent);
        if (selectedCamera != nullptr) {
            if (ImGui::CollapsingHeader(selectedCamera->resourceName().c_str())) {
                vec3<F32> eye = selectedCamera->getEye();
                if (ImGui::InputFloat3("Eye", eye._v)) {
                    selectedCamera->setEye(eye);
                }
                vec3<F32> euler = selectedCamera->getEuler();
                if (ImGui::InputFloat3("Euler", euler._v)) {
                    selectedCamera->setEuler(euler);
                }

                F32 aspect = selectedCamera->getAspectRatio();
                if (ImGui::InputFloat("Aspect", &aspect)) {
                    selectedCamera->setAspectRatio(aspect);
                }

                F32 horizontalFoV = selectedCamera->getHorizontalFoV();
                if (ImGui::InputFloat("FoV (horizontal)", &horizontalFoV)) {
                    selectedCamera->setHorizontalFoV(horizontalFoV);
                }

                vec2<F32> zPlanes = selectedCamera->getZPlanes();
                if (ImGui::InputFloat2("zPlanes", zPlanes._v)) {
                    if (selectedCamera->isOrthoProjected()) {
                        selectedCamera->setProjection(selectedCamera->orthoRect(), zPlanes);
                    } else {
                        selectedCamera->setProjection(selectedCamera->getAspectRatio(), selectedCamera->getVerticalFoV(), zPlanes);
                    }
                }

                if (selectedCamera->isOrthoProjected()) {
                    vec4<F32> orthoRect = selectedCamera->orthoRect();
                    if (ImGui::InputFloat4("Ortho", orthoRect._v)) {
                        selectedCamera->setProjection(orthoRect, selectedCamera->getZPlanes());
                    }
                }
                ImGui::Text("View Matrix");
                ImGui::Spacing();
                mat4<F32> viewMatrix = selectedCamera->getViewMatrix();
                EditorComponentField worldMatrixField = {
                    GFX::PushConstantType::MAT4,
                    EditorComponentFieldType::PUSH_TYPE,
                    true,
                    "View Matrix",
                    &viewMatrix
                };
                processBasicField(worldMatrixField);

                ImGui::Text("Projection Matrix");
                ImGui::Spacing();
                mat4<F32> projMatrix = selectedCamera->getProjectionMatrix();
                EditorComponentField projMatrixField = {
                    GFX::PushConstantType::MAT4,
                    EditorComponentFieldType::PUSH_TYPE,
                    true,
                    "Projection Matrix",
                    &projMatrix
                };
                processBasicField(projMatrixField);
            }
        } else if (hasSelections) {
            const F32 smallButtonWidth = 60.0f;
            F32 xOffset = ImGui::GetWindowSize().x * 0.5f - smallButtonWidth;
            const vector<I64>& crtSelections = selections();

            static bool closed = false;
            for (I64 nodeGUID : crtSelections) {
                SceneGraphNode* sgnNode = node(nodeGUID);
                if (sgnNode != nullptr) {
                    bool enabled = sgnNode->isActive();
                    if (ImGui::Checkbox(sgnNode->name().c_str(), &enabled)) {
                        sgnNode->setActive(enabled);
                    }
                    ImGui::Separator();

                    vectorFast<EditorComponent*>& editorComp = Attorney::SceneGraphNodeEditor::editorComponents(*sgnNode);
                    for (EditorComponent* comp : editorComp) {
                        if (ImGui::CollapsingHeader(comp->name().c_str(), ImGuiTreeNodeFlags_OpenOnArrow)) {
                            //const I32 RV = ImGui::AppendTreeNodeHeaderButtons(comp->name().c_str(), ImGui::GetCursorPosX(), 1, &closed, "Remove", NULL, 0);
                            ImGui::NewLine();
                            ImGui::SameLine(xOffset);
                            if (ImGui::Button("INSPECT", ImVec2(smallButtonWidth, 20))) {
                                Attorney::EditorGeneralWidget::inspectMemory(_context.editor(), std::make_pair(comp, sizeof(EditorComponent)));
                            }
                            ImGui::SameLine();
                            if (ImGui::Button("REMOVE", ImVec2(smallButtonWidth, 20))) {
                                Attorney::EditorGeneralWidget::inspectMemory(_context.editor(), std::make_pair(nullptr, 0));
                            }
                            ImGui::Separator();

                            vector<EditorComponentField>& fields = Attorney::EditorComponentEditor::fields(*comp);
                            for (EditorComponentField& field : fields) {
                                ImGui::Text(field._name.c_str());
                                ImGui::Spacing();
                                if (processField(field) && !field._readOnly) {
                                    Attorney::EditorComponentEditor::onChanged(*comp, field);
                                }
                            }
                        }
                    }
                }
            }
        }

        if (hasSelections) {
            const F32 buttonWidth = 80.0f;
            F32 xOffset = ImGui::GetWindowSize().x - buttonWidth - 20.0f;
            ImGui::NewLine();
            ImGui::Separator();
            ImGui::NewLine();
            ImGui::SameLine(xOffset);
            if (ImGui::Button("ADD NEW", ImVec2(buttonWidth, 15))) {
                ImGui::OpenPopup("COMP_SELECTION_GROUP");
            }

            static ComponentType selectedType = ComponentType::COUNT;

            if (ImGui::BeginPopup("COMP_SELECTION_GROUP")) {
                for (ComponentType type : ComponentType::_values()) {
                    if (type._to_integral() == ComponentType::COUNT) {
                        continue;
                    }

                    if (ImGui::Selectable(type._to_string())) {
                        selectedType = type;
                    }
                }
                ImGui::EndPopup();
            }
            if (selectedType._to_integral() != ComponentType::COUNT) {
                ImGui::OpenPopup("Add new component");
            }

            if (ImGui::BeginPopupModal("Add new component", NULL, ImGuiWindowFlags_AlwaysAutoResize)) {
                ImGui::Text("Add new %s component?", selectedType._to_string());
                ImGui::Separator();

                if (ImGui::Button("OK", ImVec2(120, 0))) {
                    selectedType = ComponentType::COUNT;
                    ImGui::CloseCurrentPopup();
                }

                ImGui::SetItemDefaultFocus();
                ImGui::SameLine();
                if (ImGui::Button("Cancel", ImVec2(120, 0))) {
                    selectedType = ComponentType::COUNT;
                    ImGui::CloseCurrentPopup();
                }
                ImGui::EndPopup();
            }
            
        }
    }
Beispiel #11
0
Renderable* renderable(const std::string& name) {
    SceneGraphNode* node = sceneGraphNode(name);
    return node->renderable();
}
Beispiel #12
0
SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& dictionary){
    openspace::documentation::testSpecificationAndThrow(
        SceneGraphNode::Documentation(),
        dictionary,
        "SceneGraphNode"
    );

    SceneGraphNode* result = new SceneGraphNode;

    if (!dictionary.hasValue<std::string>(KeyName)) {
        LERROR("SceneGraphNode did not contain a '" << KeyName << "' key");
        delete result;
        return nullptr;
    }
    std::string name;
    dictionary.getValue(KeyName, name);
    result->setName(name);

    if (dictionary.hasValue<ghoul::Dictionary>(KeyRenderable)) {
        ghoul::Dictionary renderableDictionary;
        dictionary.getValue(KeyRenderable, renderableDictionary);

        renderableDictionary.setValue(KeyName, name);

        result->_renderable = Renderable::createFromDictionary(renderableDictionary);
        if (result->_renderable == nullptr) {
            LERROR("Failed to create renderable for SceneGraphNode '"
                   << result->name() << "'");
            delete result;
            return nullptr;
        }
        result->addPropertySubOwner(result->_renderable);
        LDEBUG("Successfully created renderable for '" << result->name() << "'");
    }

    if (dictionary.hasKey(keyTransformTranslation)) {
        ghoul::Dictionary translationDictionary;
        dictionary.getValue(keyTransformTranslation, translationDictionary);
        result->_ephemeris = 
            (Ephemeris::createFromDictionary(translationDictionary));
        if (result->_ephemeris == nullptr) {
            LERROR("Failed to create ephemeris for SceneGraphNode '"
                << result->name() << "'");
            delete result;
            return nullptr;
        }
        LDEBUG("Successfully created ephemeris for '" << result->name() << "'");
    }

    if (dictionary.hasKey(keyTransformRotation)) {
        ghoul::Dictionary rotationDictionary;
        dictionary.getValue(keyTransformRotation, rotationDictionary);
        result->_rotation = 
            (Rotation::createFromDictionary(rotationDictionary));
        if (result->_rotation == nullptr) {
            LERROR("Failed to create rotation for SceneGraphNode '"
                << result->name() << "'");
            delete result;
            return nullptr;
        }
        LDEBUG("Successfully created rotation for '" << result->name() << "'");
    }

    if (dictionary.hasKey(keyTransformScale)) {
        ghoul::Dictionary scaleDictionary;
        dictionary.getValue(keyTransformScale, scaleDictionary);
        result->_scale = 
            (Scale::createFromDictionary(scaleDictionary));
        if (result->_scale == nullptr) {
            LERROR("Failed to create scale for SceneGraphNode '"
                << result->name() << "'");
            delete result;
            return nullptr;
        }
        LDEBUG("Successfully created scale for '" << result->name() << "'");
    }

    //std::string parentName;
    //if (!dictionary.getValue(KeyParentName, parentName)) {
    //    LWARNING("Could not find '" << KeyParentName << "' key, using 'Root'.");
    //    parentName = "Root";
    //}

    //SceneGraphNode* parentNode = sceneGraphNode(parentName);
    //if (parentNode == nullptr) {
    //    LFATAL("Could not find parent named '"
    //           << parentName << "' for '" << result->name() << "'."
    //           << " Check module definition order. Skipping module.");
    //}

    //parentNode->addNode(result);

    LDEBUG("Successfully created SceneGraphNode '"
                   << result->name() << "'");
    return result;
}