Example #1
0
        // find links in a "context"
        void EntityLinkDecorator::gatherLinks(Vec4f::List& vListLocal, Vec4f::List& vListContext, RenderContext& context, Model::Entity& curEnt, Model::EntitySet& visitedEntities) {
            Model::EntitySet::iterator vIt = visitedEntities.lower_bound(&curEnt);

            if (*vIt == &curEnt)
                return;

            visitedEntities.insert(vIt, &curEnt);

            if (!context.filter().entityVisible(curEnt))
                return;

            Model::EntityList::const_iterator it, end;
            const Model::EntityList& targetList = curEnt.linkTargets();

            for (it = targetList.begin(), end = targetList.end(); it != end; ++it) {
                Model::Entity& targetEnt = **it;

                if (!context.filter().entityVisible(targetEnt))
                    continue;

                if (curEnt.selected() || targetEnt.selected())
                    addArrowVerts(vListLocal, curEnt.center(), targetEnt.center());
                else
                    addArrowVerts(vListContext, curEnt.center(), targetEnt.center());

                gatherLinks(vListLocal, vListContext, context, targetEnt, visitedEntities);
            }

            const Model::EntityList& sourceList = curEnt.linkSources();

            for (it = sourceList.begin(), end = sourceList.end(); it != end; ++it) {
                Model::Entity& sourceEnt = **it;

                if (!context.filter().entityVisible(sourceEnt))
                    continue;

                gatherLinks(vListLocal, vListContext, context, sourceEnt, visitedEntities);
            }
        }
Example #2
0
        void EntityLinkDecorator::render(Vbo& vbo, RenderContext& context) {
            if (context.viewOptions().linkDisplayMode() == View::ViewOptions::LinkDisplayNone)
                return;

            const Model::EntityList& entities = map().entities();
            if (entities.empty())
                return;

            SetVboState activateVbo(vbo, Vbo::VboActive);
            
            if (m_doRebuild) {
                delete m_vertexArray;
                m_vertexArray = NULL;
                m_doRebuild = false;

                // for keeping track of which entities have already been visited by the link-gathering algorithm - should this be part of each entity instead ?
                Model::EntitySet visitedEntities;

                Vec4f::List vertsLocal; // links directly connected to a selected entity
                Vec4f::List vertsContext; // links not directly connected, but in the same context
                Vec4f::List vertsUnrelated; // links not related to the current selection

                Model::EntityList::const_iterator it, end;

                // first pass, outputs local or local+context links
                for (it = entities.begin(), end = entities.end(); it != end; ++it) {
                    Model::Entity& entity = **it;

                    if (entity.selected()) {
                        if (context.viewOptions().linkDisplayMode() == View::ViewOptions::LinkDisplayLocal) {
                            gatherLinksLocal(vertsLocal, context, entity);
                        } else {
                            gatherLinks(vertsLocal, vertsContext, context, entity, visitedEntities);
                        }
                    }
                }

                // second pass, only used in "display all" mode, outputs target links of entities the first pass didn't visit
                if (context.viewOptions().linkDisplayMode() == View::ViewOptions::LinkDisplayAll) {
                    Model::EntitySet::const_iterator vIt;
                    for (it = entities.begin(), end = entities.end(); it != end; ++it) {
                        Model::Entity& entity = **it;
                        vIt = visitedEntities.lower_bound( &entity );

                        if( *vIt != &entity )
                            gatherLinksUnrelated(vertsUnrelated, context, entity);
                    }
                }

                unsigned int vertexCount = static_cast<unsigned int>(vertsLocal.size() + vertsContext.size() + vertsUnrelated.size());
                if (vertexCount == 0)
                    return;
                
                //FIXME : doesn't need to be a color4f at the moment
                m_vertexArray = new VertexArray(vbo, GL_LINES, vertexCount, Attribute::position3f(), Attribute::color4f(), 0);
                
                SetVboState mapVbo(vbo, Vbo::VboMapped);

                // draw order : unrelated -> context -> local
                // vertData.y sets the type of link for the shader ( 0 = unrelated, 0.5 = context, 1.0 = local )
                Vec4f vertData(1.0f);

                vertData.y = 0.0f;
                for (int i = 0; i != vertsUnrelated.size(); ++i ) {
                    vertData.x = vertsUnrelated[i].w;
                    m_vertexArray->addAttribute(Vec3f(vertsUnrelated[i].x, vertsUnrelated[i].y, vertsUnrelated[i].z));
                    m_vertexArray->addAttribute(vertData);
                }
                vertData.y = 0.5f;
                for (int i = 0; i != vertsContext.size(); ++i) {
                    vertData.x = vertsContext[i].w;
                    m_vertexArray->addAttribute(Vec3f(vertsContext[i].x, vertsContext[i].y, vertsContext[i].z));
                    m_vertexArray->addAttribute(vertData);
                }
                vertData.y = 1.0f;
                for (int i = 0; i != vertsLocal.size(); ++i) {
                    vertData.x = vertsLocal[i].w;
                    m_vertexArray->addAttribute(Vec3f(vertsLocal[i].x, vertsLocal[i].y, vertsLocal[i].z));
                    m_vertexArray->addAttribute(vertData);
                }

                m_valid = true;
            }

            if (!m_valid || m_vertexArray == NULL)
                return;

            ActivateShader shader(context.shaderManager(), Shaders::EntityLinkShader );
            shader.currentShader().setUniformVariable("CameraPosition", context.camera().position());
            //shader.currentShader().setUniformVariable("Color", m_color); // unused at the moment, make color view-prefs for the different types of links ?
            shader.currentShader().setUniformVariable("Occluded", 1.0f);

            // render the "occluded" portion without depth-test
            glLineWidth(2.0f);
            glDepthMask(GL_FALSE);
            glDisable(GL_DEPTH_TEST);

            m_vertexArray->render();

            shader.currentShader().setUniformVariable("Occluded", 0.0f);
            glEnable(GL_DEPTH_TEST);

            m_vertexArray->render();

            glDepthMask(GL_TRUE);
            glLineWidth(1.0f);
        }