├── .gitignore ├── API ├── C.hh ├── Graph.hh ├── Javascript.hh └── Python.hh ├── Assets ├── Backgrounds │ ├── 20130928195742-155b1e302766320da055794365087956.jpg │ ├── Wallpaper_Black_White_Red_by_Too_Fast.png │ ├── backgroundGradient.png │ └── futuristic-abstract-background-m.jpg ├── Countries │ ├── ad.png │ ├── ae.png │ ├── af.png │ ├── ag.png │ ├── ai.png │ ├── al.png │ ├── am.png │ ├── an.png │ ├── ao.png │ ├── ar.png │ ├── as.png │ ├── at.png │ ├── au.png │ ├── aw.png │ ├── ax.png │ ├── ba.png │ ├── bb.png │ ├── bd.png │ ├── be.png │ ├── bf.png │ ├── bg.png │ ├── bh.png │ ├── bi.png │ ├── bj.png │ ├── bm.png │ ├── bn.png │ ├── bo.png │ ├── br.png │ ├── bs.png │ ├── bt.png │ ├── bw.png │ ├── by.png │ ├── bz.png │ ├── ca.png │ ├── cd.png │ ├── cf.png │ ├── cg.png │ ├── ch.png │ ├── ci.png │ ├── ck.png │ ├── cl.png │ ├── cm.png │ ├── cn.png │ ├── co.png │ ├── cr.png │ ├── cu.png │ ├── cv.png │ ├── cx.png │ ├── cy.png │ ├── cz.png │ ├── de.png │ ├── dj.png │ ├── dk.png │ ├── dm.png │ ├── do.png │ ├── dz.png │ ├── ec.png │ ├── ee.png │ ├── eg.png │ ├── er.png │ ├── es.png │ ├── et.png │ ├── eu.png │ ├── fi.png │ ├── fj.png │ ├── fk.png │ ├── fm.png │ ├── fo.png │ ├── fr.png │ ├── ga.png │ ├── gd.png │ ├── ge.png │ ├── gg.png │ ├── gh.png │ ├── gi.png │ ├── gl.png │ ├── gm.png │ ├── gn.png │ ├── gq.png │ ├── gr-cy.png │ ├── gr.png │ ├── gs.png │ ├── gt.png │ ├── gu.png │ ├── gw.png │ ├── gy.png │ ├── hk.png │ ├── hn.png │ ├── hr.png │ ├── ht.png │ ├── hu.png │ ├── id.png │ ├── ie.png │ ├── il.png │ ├── im.png │ ├── in.png │ ├── io.png │ ├── iq.png │ ├── ir.png │ ├── is.png │ ├── it.png │ ├── je.png │ ├── jm.png │ ├── jo.png │ ├── jp.png │ ├── ke.png │ ├── kg.png │ ├── kh.png │ ├── ki.png │ ├── km.png │ ├── kn.png │ ├── kp.png │ ├── kr.png │ ├── kw.png │ ├── ky.png │ ├── kz.png │ ├── la.png │ ├── lb.png │ ├── lc.png │ ├── li.png │ ├── lk.png │ ├── lr.png │ ├── ls.png │ ├── lt.png │ ├── lu.png │ ├── lv.png │ ├── ly.png │ ├── ma.png │ ├── mc.png │ ├── md.png │ ├── me.png │ ├── mg.png │ ├── mh.png │ ├── ml.png │ ├── mn.png │ ├── mo.png │ ├── mp.png │ ├── mq.png │ ├── mr.png │ ├── ms.png │ ├── mt.png │ ├── mu.png │ ├── mv.png │ ├── mw.png │ ├── mx.png │ ├── my.png │ ├── mz.png │ ├── na.png │ ├── ne.png │ ├── nf.png │ ├── ng.png │ ├── ni.png │ ├── nl.png │ ├── nm.png │ ├── no.png │ ├── np.png │ ├── nr.png │ ├── nu.png │ ├── nz.png │ ├── om.png │ ├── pa.png │ ├── pf.png │ ├── pg.png │ ├── ph.png │ ├── pk.png │ ├── pl.png │ ├── pm.png │ ├── pn.png │ ├── pr.png │ ├── pt.png │ ├── pw.png │ ├── py.png │ ├── qa.png │ ├── ro.png │ ├── rs.png │ ├── ru.png │ ├── rw.png │ ├── sa.png │ ├── sb.png │ ├── sc.png │ ├── sd.png │ ├── se.png │ ├── sg.png │ ├── sh.png │ ├── si.png │ ├── sk.png │ ├── sl.png │ ├── sm.png │ ├── sn.png │ ├── so.png │ ├── sr.png │ ├── st.png │ ├── sv.png │ ├── sy.png │ ├── sz.png │ ├── tc.png │ ├── td.png │ ├── tg.png │ ├── th.png │ ├── tj.png │ ├── tl.png │ ├── tm.png │ ├── tn.png │ ├── to.png │ ├── tr.png │ ├── tt.png │ ├── tv.png │ ├── tw.png │ ├── tz.png │ ├── ua.png │ ├── ug.png │ ├── uk.png │ ├── us.png │ ├── uy.png │ ├── uz.png │ ├── vc.png │ ├── ve.png │ ├── vg.png │ ├── vh.png │ ├── vi.png │ ├── vn.png │ ├── vu.png │ ├── wf.png │ ├── ws.png │ ├── ye.png │ ├── yt.png │ ├── yu.png │ ├── za.png │ ├── zm.png │ └── zw.png ├── Earth │ ├── black-and-blue.jpg │ ├── clouds.jpg │ ├── globe.frag │ ├── globe.png │ ├── globe.vert │ ├── miller-2048x1502-bw.jpg │ ├── miller-2048x1502.jpg │ ├── miller-bw-cropped.png │ ├── normal.jpg │ ├── world-1024x512.jpg │ ├── world-2048x1024.jpg │ ├── world-4000x2000.jpg │ └── world-map-icon.png ├── Globe │ ├── node.frag │ ├── node.geom │ └── node.vert ├── Hud │ ├── bug.png │ ├── expand.png │ ├── eye.png │ ├── flag.png │ ├── graph.png │ ├── label.png │ ├── loupe.png │ ├── marker.png │ ├── movie.png │ ├── node.png │ ├── pause.png │ ├── play.png │ ├── pointer.png │ ├── spheres.png │ ├── text.png │ └── white-disk.png ├── NetworkView │ ├── edge_solid.png │ ├── edges.frag │ ├── edges.geom │ ├── edges.vert │ ├── node_disk.png │ ├── nodes.frag │ ├── nodes.geom │ ├── nodes.vert │ └── physics.cl ├── Particle │ ├── ball.png │ ├── flame.png │ ├── metaball.png │ ├── metaball2.png │ ├── smoke.png │ ├── spark1.png │ ├── spark10.png │ ├── spark2.png │ ├── spark3.png │ ├── spark4.png │ ├── spark5.png │ ├── spark6.png │ ├── spark7.png │ ├── spark8.png │ └── spark9.png ├── ParticleView │ ├── node.frag │ ├── node.vert │ └── physics.cl ├── SpaceView │ ├── EdgeStyles │ │ ├── circles.png │ │ ├── cross.png │ │ ├── dashed.png │ │ ├── dots.png │ │ ├── solid.png │ │ ├── squares.png │ │ ├── triangles.png │ │ └── zigzag.png │ └── node-activity.png ├── Spheres │ ├── earth_ice.jpg │ ├── perlin.jpg │ ├── sky.jpg │ ├── starfield-keep.png │ ├── starfield.png │ └── starfield_8192x4096.png ├── TimeSeries │ ├── timevector.frag │ ├── timevector.geom │ └── timevector.vert ├── WorldMap │ ├── node.frag │ ├── node.geom │ └── node.vert ├── WorldView │ ├── geoline.frag │ └── geoline.vert ├── background-2.jpg ├── background.png ├── circle-new.png ├── circle.png ├── cube.frag ├── cube.vert ├── curve.frag ├── curve.vert ├── disk-white.png ├── graph.frag ├── graph.vert ├── monkey.frag ├── monkey.h ├── monkey.vert ├── og-logo.png ├── quad.frag ├── quad.vert ├── ray.frag ├── ray.vert ├── sphere.frag ├── sphere.png ├── sphere.vert ├── square-white.png ├── target.png ├── umbrella-logo.png ├── world.frag └── world.vert ├── Builds └── VS2013 │ ├── Dataviz.sln │ └── Graphiti.vcxproj ├── CMakeLists.txt ├── Core ├── Console.hh ├── Logo.hh ├── Shell.hh └── Window.hh ├── Documents ├── Globe.hh ├── TimeSeries.hh └── WorldMap.hh ├── Entities ├── Graph │ ├── GraphCommands.hh │ ├── GraphEntity.hh │ ├── GraphMessages.hh │ └── GraphModel.hh ├── MVC.hh ├── Root.hh └── TimeSeries │ ├── TimeSeriesCommands.hh │ ├── TimeSeriesEntity.hh │ └── TimeSeriesModel.hh ├── Graphiti.hh ├── Javascript ├── example.js └── main.js ├── LICENSE ├── Lib ├── GeoLiteCity.dat ├── networkx-1.8.1.zip ├── pySVG-0.2.1.zip ├── pygeoip-0.2.7.tar.gz ├── pyzmq-14.0.1.tar.gz └── siphash-0.0.1.tar.gz ├── Main.cc ├── README.md ├── Scripts ├── __init__.py ├── console │ ├── __init__.py │ ├── cheat_sheet.txt │ ├── console.py │ ├── edition.py │ ├── graph.py │ ├── help.py │ ├── layout.py │ ├── opendns.py │ ├── player.py │ ├── query.py │ ├── script.py │ └── test.py ├── dashboard.py ├── demo.py ├── diff.py ├── leap.py ├── network.py ├── standard.py ├── start.py └── world.py ├── Visualizers ├── Cloud │ ├── CloudController.hh │ ├── CloudView.hh │ ├── CloudVisualizer.hh │ └── CloudWidgets.hh ├── Network │ ├── GPUGraph.hh │ ├── NetworkController.hh │ ├── NetworkView.hh │ └── NetworkVisualizer.hh ├── Space │ ├── SpaceController.hh │ ├── SpaceEdge.hh │ ├── SpaceForces.hh │ ├── SpaceNode.hh │ ├── SpaceResources.hh │ ├── SpaceSphere.hh │ ├── SpaceView.hh │ ├── SpaceVisualizer.hh │ └── SpaceWidgets.hh ├── Stream │ ├── StreamController.hh │ ├── StreamView.hh │ └── StreamVisualizer.hh └── World │ ├── Earth.hh │ ├── WorldController.hh │ ├── WorldMap.hh │ ├── WorldResources.hh │ ├── WorldView.hh │ ├── WorldVisualizer.hh │ └── WorldWidgets.hh ├── clean.sh ├── cmake ├── FindLibPython.py ├── FindOpenCL.cmake └── FindPythonLibs.cmake └── pack.sh /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | graphiti 3 | *.pyc 4 | Pack 5 | 6 | -------------------------------------------------------------------------------- /API/C.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | Graphiti* g_Graphiti = NULL; 7 | 8 | namespace API { 9 | extern "C" { 10 | 11 | void create(int argc, char** argv) 12 | { 13 | LOG("[API] create(%d, %p)\n", argc, argv); 14 | g_Graphiti = new Graphiti(argc, argv); 15 | } 16 | 17 | void initialize() 18 | { 19 | LOG("[API] initialize()\n"); 20 | g_Graphiti->initialize(); 21 | } 22 | 23 | void createWindow(const char* title, int width, int height) 24 | { 25 | LOG("[API] createWindow('%s', %i, %i);\n", title, width, height); 26 | g_Graphiti->createWindow(title, width, height); 27 | } 28 | 29 | void createVisualizer(const char* visualizer) 30 | { 31 | LOG("[API] createVisualizer('%s')\n", visualizer); 32 | g_Graphiti->createVisualizer(visualizer); 33 | } 34 | 35 | void start() 36 | { 37 | LOG("[API] start()\n"); 38 | g_Graphiti->start(); 39 | } 40 | 41 | void stop() 42 | { 43 | LOG("[API] stop()\n"); 44 | g_Graphiti->stop(); 45 | } 46 | 47 | void destroy() 48 | { 49 | LOG("[API] destroy()\n"); 50 | SAFE_DELETE(g_Graphiti); 51 | } 52 | 53 | void screenshot(const char* filename, float factor) 54 | { 55 | LOG("[API] screenshot(%s, %f)\n", filename, factor); 56 | g_Graphiti->screenshot(filename, factor); 57 | } 58 | 59 | void console(const Variables& input, Variables& output) 60 | { 61 | g_Graphiti->console()->send(input, output); 62 | } 63 | 64 | void request(EntityManager::ID id, const Variables& input, Variables& output) 65 | { 66 | //LOG("[API] request(%lu, %p, %p)\n", id, &input, &output); 67 | g_Graphiti->request(id, input, output); 68 | } 69 | 70 | // ----- Entities ----- 71 | 72 | EntityManager::ID createEntity(const char* type) 73 | { 74 | LOG("[API] createEntity('%s')\n", type); 75 | return g_Graphiti->createEntity(type); 76 | } 77 | 78 | void bindEntity(EntityManager::ID id) 79 | { 80 | // LOG("[API] bindEntitiy(%lu)\n", id); 81 | g_Graphiti->entities().bind(id); 82 | } 83 | 84 | void destroyEntity(EntityManager::ID id) 85 | { 86 | LOG("[API] destroyEntity('%lu')\n", id); 87 | return g_Graphiti->entities().destroy(id); 88 | } 89 | 90 | // ----- Attributes ----- 91 | 92 | void setAttribute(const char* name, const char* type, const char* value) 93 | { 94 | // LOG("[API] setAttribute('%s', '%s', '%s')\n", name, type, value); 95 | return g_Graphiti->entities().active()->setAttribute(name, type, value); 96 | } 97 | 98 | IVariable* getAttribute(const char* name) 99 | { 100 | // LOG("[API] getAttribute('%s')\n", name); 101 | return g_Graphiti->entities().active()->getAttribute(name); 102 | } 103 | 104 | // ----- Scripts ----- 105 | 106 | void registerScript(const char* name, const char* source) 107 | { 108 | // LOG("[API] registerScript('%s', '%s')\n", name, source); 109 | g_Graphiti->registerScript(name, source); 110 | } 111 | 112 | void unregisterScript(const char* name) 113 | { 114 | // LOG("[API] unregisterScript('%s')\n", name); 115 | g_Graphiti->unregisterScript(name); 116 | } 117 | 118 | Job::ID addJob(const char* name, float period) 119 | { 120 | IScript* script = g_Graphiti->console()->getScript(name); 121 | if (script == NULL) 122 | { 123 | LOG("[API] Can't create job, script <%s> not found!\n", name); 124 | return 0; 125 | } 126 | 127 | return g_Graphiti->console()->addJob(script, period); 128 | } 129 | 130 | void removeJob(Job::ID id) 131 | { 132 | g_Graphiti->console()->removeJob(id); 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /API/Javascript.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | using namespace emscripten; 9 | 10 | namespace Javascript 11 | { 12 | // NOTE : Emscripten can't bind char* prototypes, we need to use std::string ones instead. 13 | 14 | void createWindow(const std::string& title, int width, int height) { API::createWindow(title.c_str(), width, height); } 15 | 16 | void createEntity(const std::string& type) { API::createEntity(type.c_str()); } 17 | 18 | void createVisualizer(const std::string& visualizer) { API::createVisualizer(visualizer.c_str()); } 19 | 20 | void setAttribute(const std::string& name, const std::string& type, const std::string& value) { API::setAttribute(name.c_str(), type.c_str(), value.c_str()); } 21 | 22 | void registerScript(const std::string& name, const std::string& source) { API::registerScript(name.c_str(), source.c_str()); } 23 | 24 | void unregisterScript(const std::string& name) { API::unregisterScript(name.c_str()); } 25 | 26 | Job::ID addJob(const std::string& name, float period) { return API::addJob(name.c_str(), period); } 27 | 28 | namespace Graph 29 | { 30 | Node::ID addNode(const std::string& label) { return API::Graph::addNode(label.c_str()); } 31 | 32 | void setNodeAttribute(Node::ID id, const std::string& name, const std::string& type, const std::string& value) { API::Graph::setNodeAttribute(id, name.c_str(), type.c_str(), value.c_str()); } 33 | 34 | void setEdgeAttribute(Edge::ID id, const std::string& name, const std::string& type, const std::string& value) { API::Graph::setEdgeAttribute(id, name.c_str(), type.c_str(), value.c_str()); } 35 | 36 | std::pair addNeighbor(const std::string& label, Node::ID neighbor) { return API::Graph::addNeighbor(label.c_str(), neighbor); } 37 | } 38 | } 39 | 40 | EMSCRIPTEN_BINDINGS(my_module) 41 | { 42 | function("create", &API::create); 43 | function("initialize", &API::initialize); 44 | function("createWindow", &Javascript::createWindow, allow_raw_pointers()); 45 | function("createVisualizer", &Javascript::createVisualizer, allow_raw_pointers()); 46 | function("start", &API::start); 47 | function("destroy", &API::destroy); 48 | // function("screenshot", &API::screenshot); 49 | 50 | // ----- Entities ----- 51 | 52 | function("createEntity", &Javascript::createEntity, allow_raw_pointers()); 53 | function("bindEntity", &API::bindEntity); 54 | // function("send"); 55 | function("destroyEntity", &API::destroyEntity); 56 | 57 | // ----- Attributes ----- 58 | 59 | function("setAttribute", &Javascript::setAttribute, allow_raw_pointers()); 60 | // TODO : function("getAttribute"); 61 | 62 | // ----- Scripts ----- 63 | 64 | function("registerScript", &Javascript::registerScript, allow_raw_pointers()); 65 | function("unregisterScript", &Javascript::unregisterScript, allow_raw_pointers()); 66 | function("addJob", &Javascript::addJob, allow_raw_pointers()); 67 | function("removeJob", &API::removeJob); 68 | 69 | // ----- Commands ----- 70 | 71 | // TODO : function("sendCommand"); 72 | 73 | // ----- Graph Entity ----- 74 | 75 | function("addNode", &Javascript::Graph::addNode, allow_raw_pointers()); 76 | function("removeNode", &API::Graph::removeNode); 77 | function("countNodes", &API::Graph::countNodes); 78 | function("getNodeID", &API::Graph::getNodeID); 79 | function("getNodeIDs", &API::Graph::getNodeIDs); 80 | function("setNodeAttribute", &Javascript::Graph::setNodeAttribute, allow_raw_pointers()); 81 | // TODO : function("getNodeAttribute") 82 | function("countSelectedNodes", &API::Graph::countSelectedNodes); 83 | function("getSelectedNode", &API::Graph::getSelectedNode); 84 | 85 | function("addEdge", &API::Graph::addEdge); 86 | function("removeEdge", &API::Graph::removeEdge); 87 | function("countEdges", &API::Graph::countEdges); 88 | function("getEdgeID", &API::Graph::getEdgeID); 89 | function("getEdgeIDs", &API::Graph::getEdgeIDs); 90 | function("getEdgeNode1", &API::Graph::getEdgeNode1); 91 | function("getEdgeNode2", &API::Graph::getEdgeNode2); 92 | function("setEdgeAttribute", &Javascript::Graph::setEdgeAttribute, allow_raw_pointers()); 93 | // TODO : function("getEdgeAttribute") 94 | } 95 | -------------------------------------------------------------------------------- /Assets/Backgrounds/20130928195742-155b1e302766320da055794365087956.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Backgrounds/20130928195742-155b1e302766320da055794365087956.jpg -------------------------------------------------------------------------------- /Assets/Backgrounds/Wallpaper_Black_White_Red_by_Too_Fast.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Backgrounds/Wallpaper_Black_White_Red_by_Too_Fast.png -------------------------------------------------------------------------------- /Assets/Backgrounds/backgroundGradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Backgrounds/backgroundGradient.png -------------------------------------------------------------------------------- /Assets/Backgrounds/futuristic-abstract-background-m.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Backgrounds/futuristic-abstract-background-m.jpg -------------------------------------------------------------------------------- /Assets/Countries/ad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ad.png -------------------------------------------------------------------------------- /Assets/Countries/ae.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ae.png -------------------------------------------------------------------------------- /Assets/Countries/af.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/af.png -------------------------------------------------------------------------------- /Assets/Countries/ag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ag.png -------------------------------------------------------------------------------- /Assets/Countries/ai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ai.png -------------------------------------------------------------------------------- /Assets/Countries/al.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/al.png -------------------------------------------------------------------------------- /Assets/Countries/am.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/am.png -------------------------------------------------------------------------------- /Assets/Countries/an.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/an.png -------------------------------------------------------------------------------- /Assets/Countries/ao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ao.png -------------------------------------------------------------------------------- /Assets/Countries/ar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ar.png -------------------------------------------------------------------------------- /Assets/Countries/as.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/as.png -------------------------------------------------------------------------------- /Assets/Countries/at.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/at.png -------------------------------------------------------------------------------- /Assets/Countries/au.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/au.png -------------------------------------------------------------------------------- /Assets/Countries/aw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/aw.png -------------------------------------------------------------------------------- /Assets/Countries/ax.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ax.png -------------------------------------------------------------------------------- /Assets/Countries/ba.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ba.png -------------------------------------------------------------------------------- /Assets/Countries/bb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/bb.png -------------------------------------------------------------------------------- /Assets/Countries/bd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/bd.png -------------------------------------------------------------------------------- /Assets/Countries/be.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/be.png -------------------------------------------------------------------------------- /Assets/Countries/bf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/bf.png -------------------------------------------------------------------------------- /Assets/Countries/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/bg.png -------------------------------------------------------------------------------- /Assets/Countries/bh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/bh.png -------------------------------------------------------------------------------- /Assets/Countries/bi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/bi.png -------------------------------------------------------------------------------- /Assets/Countries/bj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/bj.png -------------------------------------------------------------------------------- /Assets/Countries/bm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/bm.png -------------------------------------------------------------------------------- /Assets/Countries/bn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/bn.png -------------------------------------------------------------------------------- /Assets/Countries/bo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/bo.png -------------------------------------------------------------------------------- /Assets/Countries/br.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/br.png -------------------------------------------------------------------------------- /Assets/Countries/bs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/bs.png -------------------------------------------------------------------------------- /Assets/Countries/bt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/bt.png -------------------------------------------------------------------------------- /Assets/Countries/bw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/bw.png -------------------------------------------------------------------------------- /Assets/Countries/by.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/by.png -------------------------------------------------------------------------------- /Assets/Countries/bz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/bz.png -------------------------------------------------------------------------------- /Assets/Countries/ca.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ca.png -------------------------------------------------------------------------------- /Assets/Countries/cd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/cd.png -------------------------------------------------------------------------------- /Assets/Countries/cf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/cf.png -------------------------------------------------------------------------------- /Assets/Countries/cg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/cg.png -------------------------------------------------------------------------------- /Assets/Countries/ch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ch.png -------------------------------------------------------------------------------- /Assets/Countries/ci.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ci.png -------------------------------------------------------------------------------- /Assets/Countries/ck.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ck.png -------------------------------------------------------------------------------- /Assets/Countries/cl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/cl.png -------------------------------------------------------------------------------- /Assets/Countries/cm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/cm.png -------------------------------------------------------------------------------- /Assets/Countries/cn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/cn.png -------------------------------------------------------------------------------- /Assets/Countries/co.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/co.png -------------------------------------------------------------------------------- /Assets/Countries/cr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/cr.png -------------------------------------------------------------------------------- /Assets/Countries/cu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/cu.png -------------------------------------------------------------------------------- /Assets/Countries/cv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/cv.png -------------------------------------------------------------------------------- /Assets/Countries/cx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/cx.png -------------------------------------------------------------------------------- /Assets/Countries/cy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/cy.png -------------------------------------------------------------------------------- /Assets/Countries/cz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/cz.png -------------------------------------------------------------------------------- /Assets/Countries/de.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/de.png -------------------------------------------------------------------------------- /Assets/Countries/dj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/dj.png -------------------------------------------------------------------------------- /Assets/Countries/dk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/dk.png -------------------------------------------------------------------------------- /Assets/Countries/dm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/dm.png -------------------------------------------------------------------------------- /Assets/Countries/do.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/do.png -------------------------------------------------------------------------------- /Assets/Countries/dz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/dz.png -------------------------------------------------------------------------------- /Assets/Countries/ec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ec.png -------------------------------------------------------------------------------- /Assets/Countries/ee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ee.png -------------------------------------------------------------------------------- /Assets/Countries/eg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/eg.png -------------------------------------------------------------------------------- /Assets/Countries/er.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/er.png -------------------------------------------------------------------------------- /Assets/Countries/es.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/es.png -------------------------------------------------------------------------------- /Assets/Countries/et.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/et.png -------------------------------------------------------------------------------- /Assets/Countries/eu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/eu.png -------------------------------------------------------------------------------- /Assets/Countries/fi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/fi.png -------------------------------------------------------------------------------- /Assets/Countries/fj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/fj.png -------------------------------------------------------------------------------- /Assets/Countries/fk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/fk.png -------------------------------------------------------------------------------- /Assets/Countries/fm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/fm.png -------------------------------------------------------------------------------- /Assets/Countries/fo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/fo.png -------------------------------------------------------------------------------- /Assets/Countries/fr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/fr.png -------------------------------------------------------------------------------- /Assets/Countries/ga.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ga.png -------------------------------------------------------------------------------- /Assets/Countries/gd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/gd.png -------------------------------------------------------------------------------- /Assets/Countries/ge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ge.png -------------------------------------------------------------------------------- /Assets/Countries/gg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/gg.png -------------------------------------------------------------------------------- /Assets/Countries/gh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/gh.png -------------------------------------------------------------------------------- /Assets/Countries/gi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/gi.png -------------------------------------------------------------------------------- /Assets/Countries/gl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/gl.png -------------------------------------------------------------------------------- /Assets/Countries/gm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/gm.png -------------------------------------------------------------------------------- /Assets/Countries/gn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/gn.png -------------------------------------------------------------------------------- /Assets/Countries/gq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/gq.png -------------------------------------------------------------------------------- /Assets/Countries/gr-cy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/gr-cy.png -------------------------------------------------------------------------------- /Assets/Countries/gr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/gr.png -------------------------------------------------------------------------------- /Assets/Countries/gs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/gs.png -------------------------------------------------------------------------------- /Assets/Countries/gt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/gt.png -------------------------------------------------------------------------------- /Assets/Countries/gu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/gu.png -------------------------------------------------------------------------------- /Assets/Countries/gw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/gw.png -------------------------------------------------------------------------------- /Assets/Countries/gy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/gy.png -------------------------------------------------------------------------------- /Assets/Countries/hk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/hk.png -------------------------------------------------------------------------------- /Assets/Countries/hn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/hn.png -------------------------------------------------------------------------------- /Assets/Countries/hr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/hr.png -------------------------------------------------------------------------------- /Assets/Countries/ht.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ht.png -------------------------------------------------------------------------------- /Assets/Countries/hu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/hu.png -------------------------------------------------------------------------------- /Assets/Countries/id.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/id.png -------------------------------------------------------------------------------- /Assets/Countries/ie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ie.png -------------------------------------------------------------------------------- /Assets/Countries/il.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/il.png -------------------------------------------------------------------------------- /Assets/Countries/im.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/im.png -------------------------------------------------------------------------------- /Assets/Countries/in.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/in.png -------------------------------------------------------------------------------- /Assets/Countries/io.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/io.png -------------------------------------------------------------------------------- /Assets/Countries/iq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/iq.png -------------------------------------------------------------------------------- /Assets/Countries/ir.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ir.png -------------------------------------------------------------------------------- /Assets/Countries/is.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/is.png -------------------------------------------------------------------------------- /Assets/Countries/it.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/it.png -------------------------------------------------------------------------------- /Assets/Countries/je.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/je.png -------------------------------------------------------------------------------- /Assets/Countries/jm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/jm.png -------------------------------------------------------------------------------- /Assets/Countries/jo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/jo.png -------------------------------------------------------------------------------- /Assets/Countries/jp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/jp.png -------------------------------------------------------------------------------- /Assets/Countries/ke.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ke.png -------------------------------------------------------------------------------- /Assets/Countries/kg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/kg.png -------------------------------------------------------------------------------- /Assets/Countries/kh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/kh.png -------------------------------------------------------------------------------- /Assets/Countries/ki.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ki.png -------------------------------------------------------------------------------- /Assets/Countries/km.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/km.png -------------------------------------------------------------------------------- /Assets/Countries/kn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/kn.png -------------------------------------------------------------------------------- /Assets/Countries/kp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/kp.png -------------------------------------------------------------------------------- /Assets/Countries/kr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/kr.png -------------------------------------------------------------------------------- /Assets/Countries/kw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/kw.png -------------------------------------------------------------------------------- /Assets/Countries/ky.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ky.png -------------------------------------------------------------------------------- /Assets/Countries/kz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/kz.png -------------------------------------------------------------------------------- /Assets/Countries/la.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/la.png -------------------------------------------------------------------------------- /Assets/Countries/lb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/lb.png -------------------------------------------------------------------------------- /Assets/Countries/lc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/lc.png -------------------------------------------------------------------------------- /Assets/Countries/li.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/li.png -------------------------------------------------------------------------------- /Assets/Countries/lk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/lk.png -------------------------------------------------------------------------------- /Assets/Countries/lr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/lr.png -------------------------------------------------------------------------------- /Assets/Countries/ls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ls.png -------------------------------------------------------------------------------- /Assets/Countries/lt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/lt.png -------------------------------------------------------------------------------- /Assets/Countries/lu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/lu.png -------------------------------------------------------------------------------- /Assets/Countries/lv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/lv.png -------------------------------------------------------------------------------- /Assets/Countries/ly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ly.png -------------------------------------------------------------------------------- /Assets/Countries/ma.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ma.png -------------------------------------------------------------------------------- /Assets/Countries/mc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/mc.png -------------------------------------------------------------------------------- /Assets/Countries/md.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/md.png -------------------------------------------------------------------------------- /Assets/Countries/me.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/me.png -------------------------------------------------------------------------------- /Assets/Countries/mg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/mg.png -------------------------------------------------------------------------------- /Assets/Countries/mh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/mh.png -------------------------------------------------------------------------------- /Assets/Countries/ml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ml.png -------------------------------------------------------------------------------- /Assets/Countries/mn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/mn.png -------------------------------------------------------------------------------- /Assets/Countries/mo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/mo.png -------------------------------------------------------------------------------- /Assets/Countries/mp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/mp.png -------------------------------------------------------------------------------- /Assets/Countries/mq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/mq.png -------------------------------------------------------------------------------- /Assets/Countries/mr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/mr.png -------------------------------------------------------------------------------- /Assets/Countries/ms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ms.png -------------------------------------------------------------------------------- /Assets/Countries/mt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/mt.png -------------------------------------------------------------------------------- /Assets/Countries/mu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/mu.png -------------------------------------------------------------------------------- /Assets/Countries/mv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/mv.png -------------------------------------------------------------------------------- /Assets/Countries/mw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/mw.png -------------------------------------------------------------------------------- /Assets/Countries/mx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/mx.png -------------------------------------------------------------------------------- /Assets/Countries/my.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/my.png -------------------------------------------------------------------------------- /Assets/Countries/mz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/mz.png -------------------------------------------------------------------------------- /Assets/Countries/na.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/na.png -------------------------------------------------------------------------------- /Assets/Countries/ne.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ne.png -------------------------------------------------------------------------------- /Assets/Countries/nf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/nf.png -------------------------------------------------------------------------------- /Assets/Countries/ng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ng.png -------------------------------------------------------------------------------- /Assets/Countries/ni.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ni.png -------------------------------------------------------------------------------- /Assets/Countries/nl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/nl.png -------------------------------------------------------------------------------- /Assets/Countries/nm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/nm.png -------------------------------------------------------------------------------- /Assets/Countries/no.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/no.png -------------------------------------------------------------------------------- /Assets/Countries/np.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/np.png -------------------------------------------------------------------------------- /Assets/Countries/nr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/nr.png -------------------------------------------------------------------------------- /Assets/Countries/nu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/nu.png -------------------------------------------------------------------------------- /Assets/Countries/nz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/nz.png -------------------------------------------------------------------------------- /Assets/Countries/om.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/om.png -------------------------------------------------------------------------------- /Assets/Countries/pa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/pa.png -------------------------------------------------------------------------------- /Assets/Countries/pf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/pf.png -------------------------------------------------------------------------------- /Assets/Countries/pg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/pg.png -------------------------------------------------------------------------------- /Assets/Countries/ph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ph.png -------------------------------------------------------------------------------- /Assets/Countries/pk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/pk.png -------------------------------------------------------------------------------- /Assets/Countries/pl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/pl.png -------------------------------------------------------------------------------- /Assets/Countries/pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/pm.png -------------------------------------------------------------------------------- /Assets/Countries/pn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/pn.png -------------------------------------------------------------------------------- /Assets/Countries/pr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/pr.png -------------------------------------------------------------------------------- /Assets/Countries/pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/pt.png -------------------------------------------------------------------------------- /Assets/Countries/pw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/pw.png -------------------------------------------------------------------------------- /Assets/Countries/py.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/py.png -------------------------------------------------------------------------------- /Assets/Countries/qa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/qa.png -------------------------------------------------------------------------------- /Assets/Countries/ro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ro.png -------------------------------------------------------------------------------- /Assets/Countries/rs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/rs.png -------------------------------------------------------------------------------- /Assets/Countries/ru.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ru.png -------------------------------------------------------------------------------- /Assets/Countries/rw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/rw.png -------------------------------------------------------------------------------- /Assets/Countries/sa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/sa.png -------------------------------------------------------------------------------- /Assets/Countries/sb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/sb.png -------------------------------------------------------------------------------- /Assets/Countries/sc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/sc.png -------------------------------------------------------------------------------- /Assets/Countries/sd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/sd.png -------------------------------------------------------------------------------- /Assets/Countries/se.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/se.png -------------------------------------------------------------------------------- /Assets/Countries/sg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/sg.png -------------------------------------------------------------------------------- /Assets/Countries/sh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/sh.png -------------------------------------------------------------------------------- /Assets/Countries/si.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/si.png -------------------------------------------------------------------------------- /Assets/Countries/sk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/sk.png -------------------------------------------------------------------------------- /Assets/Countries/sl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/sl.png -------------------------------------------------------------------------------- /Assets/Countries/sm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/sm.png -------------------------------------------------------------------------------- /Assets/Countries/sn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/sn.png -------------------------------------------------------------------------------- /Assets/Countries/so.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/so.png -------------------------------------------------------------------------------- /Assets/Countries/sr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/sr.png -------------------------------------------------------------------------------- /Assets/Countries/st.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/st.png -------------------------------------------------------------------------------- /Assets/Countries/sv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/sv.png -------------------------------------------------------------------------------- /Assets/Countries/sy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/sy.png -------------------------------------------------------------------------------- /Assets/Countries/sz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/sz.png -------------------------------------------------------------------------------- /Assets/Countries/tc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/tc.png -------------------------------------------------------------------------------- /Assets/Countries/td.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/td.png -------------------------------------------------------------------------------- /Assets/Countries/tg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/tg.png -------------------------------------------------------------------------------- /Assets/Countries/th.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/th.png -------------------------------------------------------------------------------- /Assets/Countries/tj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/tj.png -------------------------------------------------------------------------------- /Assets/Countries/tl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/tl.png -------------------------------------------------------------------------------- /Assets/Countries/tm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/tm.png -------------------------------------------------------------------------------- /Assets/Countries/tn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/tn.png -------------------------------------------------------------------------------- /Assets/Countries/to.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/to.png -------------------------------------------------------------------------------- /Assets/Countries/tr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/tr.png -------------------------------------------------------------------------------- /Assets/Countries/tt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/tt.png -------------------------------------------------------------------------------- /Assets/Countries/tv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/tv.png -------------------------------------------------------------------------------- /Assets/Countries/tw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/tw.png -------------------------------------------------------------------------------- /Assets/Countries/tz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/tz.png -------------------------------------------------------------------------------- /Assets/Countries/ua.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ua.png -------------------------------------------------------------------------------- /Assets/Countries/ug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ug.png -------------------------------------------------------------------------------- /Assets/Countries/uk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/uk.png -------------------------------------------------------------------------------- /Assets/Countries/us.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/us.png -------------------------------------------------------------------------------- /Assets/Countries/uy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/uy.png -------------------------------------------------------------------------------- /Assets/Countries/uz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/uz.png -------------------------------------------------------------------------------- /Assets/Countries/vc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/vc.png -------------------------------------------------------------------------------- /Assets/Countries/ve.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ve.png -------------------------------------------------------------------------------- /Assets/Countries/vg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/vg.png -------------------------------------------------------------------------------- /Assets/Countries/vh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/vh.png -------------------------------------------------------------------------------- /Assets/Countries/vi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/vi.png -------------------------------------------------------------------------------- /Assets/Countries/vn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/vn.png -------------------------------------------------------------------------------- /Assets/Countries/vu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/vu.png -------------------------------------------------------------------------------- /Assets/Countries/wf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/wf.png -------------------------------------------------------------------------------- /Assets/Countries/ws.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ws.png -------------------------------------------------------------------------------- /Assets/Countries/ye.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/ye.png -------------------------------------------------------------------------------- /Assets/Countries/yt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/yt.png -------------------------------------------------------------------------------- /Assets/Countries/yu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/yu.png -------------------------------------------------------------------------------- /Assets/Countries/za.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/za.png -------------------------------------------------------------------------------- /Assets/Countries/zm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/zm.png -------------------------------------------------------------------------------- /Assets/Countries/zw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Countries/zw.png -------------------------------------------------------------------------------- /Assets/Earth/black-and-blue.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Earth/black-and-blue.jpg -------------------------------------------------------------------------------- /Assets/Earth/clouds.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Earth/clouds.jpg -------------------------------------------------------------------------------- /Assets/Earth/globe.frag: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | #ifdef GL_ES 4 | precision mediump float; 5 | #endif 6 | 7 | uniform sampler2D u_Texture; 8 | 9 | in vec2 vs_Texcoord; 10 | in vec3 vs_Normal; 11 | in vec4 vs_Color; 12 | 13 | out vec4 FragColor; 14 | 15 | void main(void) 16 | { 17 | vec4 texcolor = texture(u_Texture, vs_Texcoord).rgba; 18 | 19 | //float gray = (texcolor.r + texcolor.g + texcolor.b) / 2.5; 20 | //float c = sin(pow(gray, 4.0)); 21 | 22 | //texcolor.r = c; 23 | //texcolor.g = c; 24 | //texcolor.b = c; 25 | 26 | FragColor = texcolor * vs_Color; 27 | } 28 | -------------------------------------------------------------------------------- /Assets/Earth/globe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Earth/globe.png -------------------------------------------------------------------------------- /Assets/Earth/globe.vert: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | struct Light 4 | { 5 | int Type; 6 | vec3 Position; 7 | vec3 Direction; 8 | vec3 Color; 9 | }; 10 | 11 | struct Material 12 | { 13 | vec3 Ambient; 14 | vec4 Diffuse; 15 | vec3 Specular; 16 | float Shininess; 17 | }; 18 | 19 | layout(location = 0) in vec3 a_Position; 20 | layout(location = 1) in vec3 a_Normal; 21 | layout(location = 2) in vec2 a_Texcoord; 22 | 23 | uniform mat4 u_ModelMatrix; 24 | uniform mat4 u_ViewMatrix; 25 | uniform mat4 u_ProjectionMatrix; 26 | uniform mat3 u_NormalMatrix; 27 | 28 | uniform Light u_Light; 29 | uniform Material u_Material; 30 | 31 | out vec3 vs_Position; 32 | out vec2 vs_Texcoord; 33 | out vec3 vs_Normal; 34 | out vec4 vs_Color; 35 | 36 | void main(void) 37 | { 38 | vs_Position = vec3(u_ViewMatrix * u_ModelMatrix * vec4(a_Position, 1.0)); 39 | vs_Normal = normalize(u_NormalMatrix * a_Normal); 40 | vs_Texcoord = a_Texcoord; 41 | 42 | vs_Color = vec4(u_Material.Ambient, 0.0); 43 | 44 | vec3 lightPositionViewSpace = vec3(u_ViewMatrix * vec4(u_Light.Position, 0.0)); 45 | vec3 lightDirection = normalize(lightPositionViewSpace - vs_Position); 46 | float lambert = dot(vs_Normal, lightDirection); 47 | 48 | if (lambert > 0.0) 49 | { 50 | vs_Color += vec4(u_Light.Color, 1.0) * u_Material.Diffuse * lambert; 51 | 52 | vec3 eyeDirection = normalize(-vs_Position); 53 | vec3 r = reflect(-lightDirection, vs_Normal); 54 | 55 | float specular = pow(max(dot(r, eyeDirection), 0.0), u_Material.Shininess); 56 | 57 | vs_Color += vec4(u_Material.Specular * specular, 0.0); 58 | } 59 | 60 | gl_Position = u_ProjectionMatrix * vec4(vs_Position, 1.0); 61 | } -------------------------------------------------------------------------------- /Assets/Earth/miller-2048x1502-bw.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Earth/miller-2048x1502-bw.jpg -------------------------------------------------------------------------------- /Assets/Earth/miller-2048x1502.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Earth/miller-2048x1502.jpg -------------------------------------------------------------------------------- /Assets/Earth/miller-bw-cropped.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Earth/miller-bw-cropped.png -------------------------------------------------------------------------------- /Assets/Earth/normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Earth/normal.jpg -------------------------------------------------------------------------------- /Assets/Earth/world-1024x512.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Earth/world-1024x512.jpg -------------------------------------------------------------------------------- /Assets/Earth/world-2048x1024.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Earth/world-2048x1024.jpg -------------------------------------------------------------------------------- /Assets/Earth/world-4000x2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Earth/world-4000x2000.jpg -------------------------------------------------------------------------------- /Assets/Earth/world-map-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Earth/world-map-icon.png -------------------------------------------------------------------------------- /Assets/Globe/node.frag: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | #ifdef GL_ES 4 | precision mediump float; 5 | #endif 6 | 7 | in vec4 gs_Color; 8 | 9 | out vec4 FragColor; 10 | 11 | void main(void) 12 | { 13 | FragColor = gs_Color; 14 | } 15 | -------------------------------------------------------------------------------- /Assets/Globe/node.geom: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | uniform mat4 u_ProjectionMatrix; 4 | uniform mat4 u_ViewMatrix; 5 | 6 | layout(points) in; 7 | layout(line_strip, max_vertices = 2) out; 8 | 9 | in vec4 vs_Color[]; 10 | in float vs_Size[]; 11 | 12 | out vec4 gs_Color; 13 | 14 | void main() 15 | { 16 | vec4 p = gl_in[0].gl_Position; 17 | 18 | vec3 n = normalize(p.xyz); 19 | 20 | gl_Position = u_ProjectionMatrix * u_ViewMatrix * p; 21 | gs_Color = vs_Color[0]; 22 | EmitVertex(); 23 | 24 | gl_Position = u_ProjectionMatrix * u_ViewMatrix * vec4(p.xyz + vs_Size[0] * n, 1.0); 25 | gs_Color = vs_Color[0]; 26 | EmitVertex(); 27 | 28 | EndPrimitive(); 29 | } -------------------------------------------------------------------------------- /Assets/Globe/node.vert: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | #define M_PI 3.1415926535897932384626433832795 4 | 5 | layout(location = 0) in vec2 a_Location; 6 | layout(location = 1) in vec4 a_Color; 7 | layout(location = 2) in float a_Size; 8 | 9 | uniform float u_Radius; 10 | 11 | out float vs_Size; 12 | out vec4 vs_Color; 13 | 14 | void main() 15 | { 16 | vs_Size = a_Size; 17 | vs_Color = a_Color; 18 | 19 | float radLatitude = (a_Location.x - 90) * M_PI / 180.0; 20 | float radLongitude = (180 - a_Location.y) * M_PI / 180.0; 21 | 22 | vec3 pos = vec3( 23 | u_Radius * cos(radLongitude) * sin(radLatitude), 24 | u_Radius * cos(radLatitude), 25 | u_Radius * sin(radLongitude) * sin(radLatitude) 26 | ); 27 | 28 | gl_Position = vec4(pos, 1.0); 29 | } -------------------------------------------------------------------------------- /Assets/Hud/bug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Hud/bug.png -------------------------------------------------------------------------------- /Assets/Hud/expand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Hud/expand.png -------------------------------------------------------------------------------- /Assets/Hud/eye.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Hud/eye.png -------------------------------------------------------------------------------- /Assets/Hud/flag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Hud/flag.png -------------------------------------------------------------------------------- /Assets/Hud/graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Hud/graph.png -------------------------------------------------------------------------------- /Assets/Hud/label.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Hud/label.png -------------------------------------------------------------------------------- /Assets/Hud/loupe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Hud/loupe.png -------------------------------------------------------------------------------- /Assets/Hud/marker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Hud/marker.png -------------------------------------------------------------------------------- /Assets/Hud/movie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Hud/movie.png -------------------------------------------------------------------------------- /Assets/Hud/node.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Hud/node.png -------------------------------------------------------------------------------- /Assets/Hud/pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Hud/pause.png -------------------------------------------------------------------------------- /Assets/Hud/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Hud/play.png -------------------------------------------------------------------------------- /Assets/Hud/pointer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Hud/pointer.png -------------------------------------------------------------------------------- /Assets/Hud/spheres.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Hud/spheres.png -------------------------------------------------------------------------------- /Assets/Hud/text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Hud/text.png -------------------------------------------------------------------------------- /Assets/Hud/white-disk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Hud/white-disk.png -------------------------------------------------------------------------------- /Assets/NetworkView/edge_solid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/NetworkView/edge_solid.png -------------------------------------------------------------------------------- /Assets/NetworkView/edges.frag: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | #ifdef GL_ES 4 | precision mediump float; 5 | #endif 6 | 7 | uniform sampler2D u_Texture; 8 | 9 | in vec4 gs_Color; 10 | in vec2 gs_UV; 11 | 12 | out vec4 FragColor; 13 | 14 | void main(void) 15 | { 16 | FragColor = gs_Color * texture(u_Texture, gs_UV); 17 | } 18 | -------------------------------------------------------------------------------- /Assets/NetworkView/edges.geom: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | uniform mat4 u_ModelViewMatrix; 4 | uniform mat4 u_ProjectionMatrix; 5 | 6 | layout(points) in; 7 | layout(triangle_strip, max_vertices = 4) out; 8 | //layout(line_strip, max_vertices = 2) out; 9 | 10 | in vec3 vs_SourcePosition[]; 11 | in vec4 vs_SourceColor[]; 12 | 13 | in vec3 vs_TargetPosition[]; 14 | in vec4 vs_TargetColor[]; 15 | 16 | in float vs_Width[]; 17 | 18 | out vec4 gs_Color; 19 | out vec2 gs_UV; 20 | 21 | /* Simple Lines 22 | void main() 23 | { 24 | vec4 origin = gl_in[0].gl_Position; 25 | 26 | vec4 source = u_ProjectionMatrix * u_ModelViewMatrix * vec4(origin.xyz + vs_SourcePosition[0], 1.0); 27 | vec4 target = u_ProjectionMatrix * u_ModelViewMatrix * vec4(origin.xyz + vs_TargetPosition[0], 1.0); 28 | 29 | gl_Position = source; 30 | gs_Color = vs_SourceColor[0]; 31 | EmitVertex(); 32 | 33 | gl_Position = target; 34 | gs_Color = vs_TargetColor[0]; 35 | EmitVertex(); 36 | 37 | EndPrimitive(); 38 | } 39 | */ 40 | 41 | void main() 42 | { 43 | vec4 origin = gl_in[0].gl_Position; 44 | 45 | vec4 source = u_ModelViewMatrix * vec4(origin.xyz + vs_SourcePosition[0], 1.0); 46 | vec4 target = u_ModelViewMatrix * vec4(origin.xyz + vs_TargetPosition[0], 1.0); 47 | 48 | vec3 p0 = source.xyz / source.w; 49 | vec3 p1 = target.xyz / target.w; 50 | 51 | vec3 direction = normalize(p1 - p0); 52 | vec3 extrusion = 0.5 * vs_Width[0] * cross(direction, vec3(0, 0, 1)); 53 | 54 | //vec3 extrusion = 0.5 * vs_Width[0] * vec3(-direction.y, direction.x, 0); 55 | 56 | float uv_x = length(target.xyz - source.xyz) / (2.0 * length(extrusion)); 57 | 58 | gl_Position = u_ProjectionMatrix * vec4(p0 + extrusion, 1.0); 59 | gs_Color = vs_SourceColor[0]; 60 | gs_UV = vec2(0, 0); 61 | EmitVertex(); 62 | 63 | gl_Position = u_ProjectionMatrix * vec4(p1 + extrusion, 1.0); 64 | gs_Color = vs_TargetColor[0]; 65 | gs_UV = vec2(uv_x, 0); 66 | EmitVertex(); 67 | 68 | gl_Position = u_ProjectionMatrix * vec4(p0 - extrusion, 1.0); 69 | gs_Color = vs_SourceColor[0]; 70 | gs_UV = vec2(0, 1); 71 | EmitVertex(); 72 | 73 | gl_Position = u_ProjectionMatrix * vec4(p1 - extrusion, 1.0); 74 | gs_Color = vs_TargetColor[0]; 75 | gs_UV = vec2(uv_x, 1); 76 | EmitVertex(); 77 | 78 | EndPrimitive(); 79 | } 80 | -------------------------------------------------------------------------------- /Assets/NetworkView/edges.vert: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | layout(location = 0) in vec4 a_Origin; 4 | 5 | layout(location = 2) in vec4 a_SourcePosition; 6 | layout(location = 3) in vec4 a_SourceColor; 7 | 8 | layout(location = 4) in vec4 a_TargetPosition; 9 | layout(location = 5) in vec4 a_TargetColor; 10 | 11 | layout(location = 6) in float a_Width; 12 | 13 | out vec3 vs_SourcePosition; 14 | out vec4 vs_SourceColor; 15 | 16 | out vec3 vs_TargetPosition; 17 | out vec4 vs_TargetColor; 18 | 19 | out float vs_Width; 20 | 21 | void main(void) 22 | { 23 | gl_Position = a_Origin; 24 | 25 | vs_SourcePosition = a_SourcePosition.xyz; 26 | vs_SourceColor = a_SourceColor; 27 | 28 | vs_TargetPosition = a_TargetPosition.xyz; 29 | vs_TargetColor = a_TargetColor; 30 | 31 | vs_Width = a_Width / 2.0; 32 | } 33 | -------------------------------------------------------------------------------- /Assets/NetworkView/node_disk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/NetworkView/node_disk.png -------------------------------------------------------------------------------- /Assets/NetworkView/nodes.frag: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | #ifdef GL_ES 4 | precision mediump float; 5 | #endif 6 | 7 | uniform sampler2D u_Texture; 8 | 9 | in vec4 gs_Color; 10 | in vec2 gs_UV; 11 | 12 | out vec4 FragColor; 13 | 14 | void main(void) 15 | { 16 | FragColor = gs_Color * texture(u_Texture, gs_UV); 17 | } 18 | -------------------------------------------------------------------------------- /Assets/NetworkView/nodes.geom: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | uniform mat4 u_ProjectionMatrix; 4 | 5 | layout(points) in; 6 | layout(triangle_strip, max_vertices = 4) out; 7 | 8 | in vec4 vs_Color[]; 9 | in float vs_Size[]; 10 | 11 | out vec4 gs_Color; 12 | out vec2 gs_UV; 13 | 14 | void main() 15 | { 16 | vec2 pos[4] = vec2[]( 17 | vec2(-0.5, -0.5), 18 | vec2( 0.5, -0.5), 19 | vec2(-0.5, 0.5), 20 | vec2( 0.5, 0.5) 21 | ); 22 | 23 | vec2 uv[4] = vec2[]( 24 | vec2(0.0, 0.0), 25 | vec2(1.0, 0.0), 26 | vec2(0.0, 1.0), 27 | vec2(1.0, 1.0) 28 | ); 29 | 30 | vec4 p = gl_in[0].gl_Position; 31 | 32 | for(int i = 0; i < 4; i++) 33 | { 34 | vec2 v = p.xy + pos[i] * vs_Size[0]; 35 | 36 | gl_Position = u_ProjectionMatrix * vec4(v, p.zw); 37 | gs_Color = vs_Color[0]; 38 | gs_UV = uv[i]; 39 | EmitVertex(); 40 | } 41 | 42 | EndPrimitive(); 43 | } -------------------------------------------------------------------------------- /Assets/NetworkView/nodes.vert: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | uniform mat4 u_ModelViewMatrix; 4 | 5 | layout(location = 0) in vec4 a_Origin; 6 | 7 | layout(location = 1) in vec4 a_Position; 8 | layout(location = 2) in vec4 a_Color; 9 | layout(location = 3) in float a_Size; 10 | 11 | out vec4 vs_Color; 12 | out float vs_Size; 13 | 14 | void main(void) 15 | { 16 | vec4 pos = a_Origin + a_Position; 17 | 18 | gl_Position = u_ModelViewMatrix * vec4(pos.xyz, 1.0); 19 | 20 | vs_Color = a_Color; 21 | vs_Size = a_Size; 22 | } 23 | -------------------------------------------------------------------------------- /Assets/NetworkView/physics.cl: -------------------------------------------------------------------------------- 1 | typedef struct 2 | { 3 | float4 Direction; 4 | } ParticleForce; 5 | 6 | typedef struct 7 | { 8 | float4 Position; 9 | float4 Color; 10 | float Size; 11 | 12 | ParticleForce Force; 13 | 14 | // float3 __Unused; // NOTE: Padding 15 | } NodeInstance; 16 | 17 | typedef struct 18 | { 19 | float4 SourcePosition; 20 | float4 SourceColor; 21 | float4 TargetPosition; 22 | float4 TargetColor; 23 | float Width; 24 | 25 | unsigned int SourceID; 26 | unsigned int TargetID; 27 | 28 | // float __Unused; 29 | } EdgeInstance; 30 | 31 | 32 | __kernel void repulsion(__global NodeInstance* node_instances, const float k) 33 | { 34 | unsigned long node_count = get_global_size(0); 35 | unsigned long i = get_global_id(0); 36 | 37 | for (unsigned long j = i + 1; j < node_count; j++) 38 | { 39 | float4 direction = node_instances[i].Position - node_instances[j].Position; 40 | float magnitude = length(direction.xyz); // NOTE: Make sure we ignore W component 41 | if (magnitude > 0.0) 42 | { 43 | float4 f = (direction / magnitude) * (k * k / magnitude); 44 | node_instances[i].Force.Direction += f; 45 | node_instances[j].Force.Direction -= f; 46 | } 47 | } 48 | } 49 | 50 | __kernel void attraction(__global NodeInstance* node_instances, 51 | __global EdgeInstance* edge_instances, 52 | const float k) 53 | { 54 | unsigned int i = get_global_id(0); 55 | 56 | unsigned int src = edge_instances[i].SourceID; 57 | unsigned int dst = edge_instances[i].TargetID; 58 | 59 | float4 direction = node_instances[src].Position - node_instances[dst].Position; 60 | float magnitude = length(direction.xyz); // NOTE: Make sure we ignore W component 61 | 62 | node_instances[src].Force.Direction -= direction * magnitude / k; 63 | node_instances[dst].Force.Direction += direction * magnitude / k; 64 | } 65 | 66 | __kernel void node_animation(__global NodeInstance* instances, const float temperature) 67 | { 68 | unsigned long i = get_global_id(0); 69 | 70 | float magnitude = length(instances[i].Force.Direction.xyz); // NOTE: Make sure we ignore W component 71 | if (magnitude > 0.0) 72 | { 73 | float4 new_pos = temperature * instances[i].Force.Direction / magnitude; 74 | 75 | if (length(new_pos.xyz) < 100000) // NOTE: Sphere Radius 76 | { 77 | instances[i].Position += new_pos; 78 | } 79 | } 80 | 81 | // instances[i].Position.z = 0; 82 | 83 | instances[i].Force.Direction = (float4)(0.0); 84 | } 85 | 86 | __kernel void edge_animation(__global NodeInstance* node_instances, 87 | __global EdgeInstance* edge_instances) 88 | { 89 | unsigned long i = get_global_id(0); 90 | 91 | unsigned int src = edge_instances[i].SourceID; 92 | unsigned int dst = edge_instances[i].TargetID; 93 | 94 | edge_instances[i].SourcePosition = node_instances[src].Position; 95 | edge_instances[i].TargetPosition = node_instances[dst].Position; 96 | } 97 | -------------------------------------------------------------------------------- /Assets/Particle/ball.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Particle/ball.png -------------------------------------------------------------------------------- /Assets/Particle/flame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Particle/flame.png -------------------------------------------------------------------------------- /Assets/Particle/metaball.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Particle/metaball.png -------------------------------------------------------------------------------- /Assets/Particle/metaball2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Particle/metaball2.png -------------------------------------------------------------------------------- /Assets/Particle/smoke.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Particle/smoke.png -------------------------------------------------------------------------------- /Assets/Particle/spark1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Particle/spark1.png -------------------------------------------------------------------------------- /Assets/Particle/spark10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Particle/spark10.png -------------------------------------------------------------------------------- /Assets/Particle/spark2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Particle/spark2.png -------------------------------------------------------------------------------- /Assets/Particle/spark3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Particle/spark3.png -------------------------------------------------------------------------------- /Assets/Particle/spark4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Particle/spark4.png -------------------------------------------------------------------------------- /Assets/Particle/spark5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Particle/spark5.png -------------------------------------------------------------------------------- /Assets/Particle/spark6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Particle/spark6.png -------------------------------------------------------------------------------- /Assets/Particle/spark7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Particle/spark7.png -------------------------------------------------------------------------------- /Assets/Particle/spark8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Particle/spark8.png -------------------------------------------------------------------------------- /Assets/Particle/spark9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Particle/spark9.png -------------------------------------------------------------------------------- /Assets/ParticleView/node.frag: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | #ifdef GL_ES 4 | precision mediump float; 5 | #endif 6 | 7 | in vec4 vs_Color; 8 | 9 | out vec4 FragColor; 10 | 11 | void main(void) 12 | { 13 | FragColor = vs_Color; 14 | } 15 | -------------------------------------------------------------------------------- /Assets/ParticleView/node.vert: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | layout(location = 0) in vec3 a_Position; 4 | layout(location = 1) in vec3 a_Normal; 5 | 6 | uniform mat4 u_ModelViewProjectionMatrix; 7 | 8 | out vec4 vs_Color; 9 | 10 | void main(void) 11 | { 12 | vs_Color = vec4(0.5 * vec3(1.0, 1.0, 1.0) + 0.5 * a_Normal, 1.0); 13 | gl_Position = u_ModelViewProjectionMatrix * vec4(a_Position, 1.0); 14 | } 15 | -------------------------------------------------------------------------------- /Assets/ParticleView/physics.cl: -------------------------------------------------------------------------------- 1 | __kernel void repulsion(__global float4* inNodes, 2 | __global float4* outDirections, 3 | const unsigned long count, 4 | const float k) 5 | { 6 | unsigned int i = get_global_id(0); 7 | float4 f = (float4)(0.0); 8 | for(unsigned long j = 0; j < count; j++) 9 | { 10 | if (i != j) 11 | { 12 | float4 direction = inNodes[i] - inNodes[j]; 13 | float magnitude = length(direction); 14 | if (magnitude > 0.0) 15 | f += (direction / magnitude) * (k * k / magnitude); 16 | } 17 | } 18 | outDirections[i] = f; 19 | } 20 | 21 | __kernel void attraction(__global float4* inNodes, 22 | __global ulong2* inEdges, 23 | __global float4* outDirections, 24 | const unsigned long count, 25 | const float k) 26 | { 27 | unsigned int i = get_global_id(0); 28 | unsigned long src = inEdges[i].x; 29 | unsigned long dst = inEdges[i].y; 30 | float4 pos1 = inNodes[src]; 31 | float4 pos2 = inNodes[dst]; 32 | float4 direction = pos1 - pos2; 33 | float magnitude = length(direction); 34 | if (magnitude > 100.0) 35 | { 36 | outDirections[src] -= direction * magnitude / k; 37 | outDirections[dst] += direction * magnitude / k; 38 | } 39 | } 40 | 41 | __kernel void movement(__global float4* inNodes, 42 | __global float4* inForces, 43 | __global float4* outNodes, 44 | const float temperature) 45 | { 46 | unsigned int i = get_global_id(0); 47 | if (length(inNodes[i]) < 100000) 48 | { 49 | float magnitude = length(inForces[i]); 50 | if (magnitude > 0.0) 51 | outNodes[i] = inNodes[i] + temperature * inForces[i] / magnitude; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Assets/SpaceView/EdgeStyles/circles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/SpaceView/EdgeStyles/circles.png -------------------------------------------------------------------------------- /Assets/SpaceView/EdgeStyles/cross.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/SpaceView/EdgeStyles/cross.png -------------------------------------------------------------------------------- /Assets/SpaceView/EdgeStyles/dashed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/SpaceView/EdgeStyles/dashed.png -------------------------------------------------------------------------------- /Assets/SpaceView/EdgeStyles/dots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/SpaceView/EdgeStyles/dots.png -------------------------------------------------------------------------------- /Assets/SpaceView/EdgeStyles/solid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/SpaceView/EdgeStyles/solid.png -------------------------------------------------------------------------------- /Assets/SpaceView/EdgeStyles/squares.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/SpaceView/EdgeStyles/squares.png -------------------------------------------------------------------------------- /Assets/SpaceView/EdgeStyles/triangles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/SpaceView/EdgeStyles/triangles.png -------------------------------------------------------------------------------- /Assets/SpaceView/EdgeStyles/zigzag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/SpaceView/EdgeStyles/zigzag.png -------------------------------------------------------------------------------- /Assets/SpaceView/node-activity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/SpaceView/node-activity.png -------------------------------------------------------------------------------- /Assets/Spheres/earth_ice.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Spheres/earth_ice.jpg -------------------------------------------------------------------------------- /Assets/Spheres/perlin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Spheres/perlin.jpg -------------------------------------------------------------------------------- /Assets/Spheres/sky.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Spheres/sky.jpg -------------------------------------------------------------------------------- /Assets/Spheres/starfield-keep.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Spheres/starfield-keep.png -------------------------------------------------------------------------------- /Assets/Spheres/starfield.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Spheres/starfield.png -------------------------------------------------------------------------------- /Assets/Spheres/starfield_8192x4096.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/Spheres/starfield_8192x4096.png -------------------------------------------------------------------------------- /Assets/TimeSeries/timevector.frag: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | #ifdef GL_ES 4 | precision mediump float; 5 | #endif 6 | 7 | uniform vec4 u_Color; 8 | 9 | out vec4 FragColor; 10 | 11 | void main(void) 12 | { 13 | FragColor = u_Color; 14 | } 15 | -------------------------------------------------------------------------------- /Assets/TimeSeries/timevector.geom: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | uniform mat4 u_ModelViewProjectionMatrix; 4 | 5 | layout(lines) in; 6 | layout(triangle_strip, max_vertices = 4) out; 7 | 8 | out float gs_Y; 9 | 10 | void main() 11 | { 12 | vec4 p0 = gl_in[0].gl_Position; 13 | vec4 p1 = gl_in[1].gl_Position; 14 | 15 | gl_Position = u_ModelViewProjectionMatrix * p0; 16 | gs_Y = p0.y; 17 | EmitVertex(); 18 | 19 | gl_Position = u_ModelViewProjectionMatrix * vec4(p0.x, 0, p0.z, 1.0); 20 | gs_Y = 0; 21 | EmitVertex(); 22 | 23 | gl_Position = u_ModelViewProjectionMatrix * vec4(p1.x, p0.y, p1.z, 1.0); 24 | gs_Y = p1.y; 25 | EmitVertex(); 26 | 27 | gl_Position = u_ModelViewProjectionMatrix * vec4(p1.x, 0, p1.z, 1.0); 28 | gs_Y = 0; 29 | EmitVertex(); 30 | 31 | EndPrimitive(); 32 | } 33 | -------------------------------------------------------------------------------- /Assets/TimeSeries/timevector.vert: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | layout(location = 0) in float a_Time; 4 | layout(location = 1) in float a_Value; 5 | 6 | void main(void) 7 | { 8 | gl_Position = vec4(a_Time, a_Value, 0.0, 1.0); 9 | } 10 | 11 | -------------------------------------------------------------------------------- /Assets/WorldMap/node.frag: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | #ifdef GL_ES 4 | precision mediump float; 5 | #endif 6 | 7 | uniform sampler2D u_Texture; 8 | 9 | in vec4 gs_Color; 10 | //in vec2 gs_UV; 11 | 12 | out vec4 FragColor; 13 | 14 | void main(void) 15 | { 16 | FragColor = gs_Color;// * texture(u_Texture, gs_UV); 17 | } 18 | -------------------------------------------------------------------------------- /Assets/WorldMap/node.geom: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | uniform mat4 u_ProjectionMatrix; 4 | 5 | layout(points) in; 6 | layout(triangle_strip, max_vertices = 4) out; 7 | 8 | in vec4 vs_Color[]; 9 | in float vs_Size[]; 10 | 11 | out vec4 gs_Color; 12 | //out vec2 gs_UV; 13 | 14 | void main() 15 | { 16 | vec2 pos[4] = vec2[]( 17 | vec2(-0.5, -0.5), 18 | vec2( 0.5, -0.5), 19 | vec2(-0.5, 0.5), 20 | vec2( 0.5, 0.5) 21 | ); 22 | 23 | /* 24 | vec2 uv[4] = vec2[]( 25 | vec2(0.0, 0.0), 26 | vec2(1.0, 0.0), 27 | vec2(0.0, 1.0), 28 | vec2(1.0, 1.0) 29 | ); 30 | */ 31 | 32 | vec4 p = gl_in[0].gl_Position; 33 | 34 | for(int i = 0; i < 4; i++) 35 | { 36 | vec2 v = p.xy + pos[i] * vs_Size[0]; 37 | 38 | gl_Position = u_ProjectionMatrix * vec4(v, p.zw); 39 | gs_Color = vs_Color[0]; 40 | //gs_UV = uv[i]; 41 | EmitVertex(); 42 | } 43 | 44 | EndPrimitive(); 45 | } -------------------------------------------------------------------------------- /Assets/WorldMap/node.vert: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | #define M_PI 3.1415926535897932384626433832795 4 | 5 | layout(location = 0) in vec2 a_Location; 6 | layout(location = 1) in vec4 a_Color; 7 | layout(location = 2) in float a_Size; 8 | 9 | uniform vec2 u_Dimension; 10 | 11 | out float vs_Size; 12 | out vec4 vs_Color; 13 | 14 | void main() 15 | { 16 | vs_Size = a_Size; 17 | vs_Color = a_Color; 18 | 19 | float radLatitude = a_Location.x * M_PI / 180.0; 20 | float radLongitude = a_Location.y * M_PI / 180.0; 21 | 22 | // NOTE : http://en.wikipedia.org/wiki/Miller_projection 23 | vec2 miller = vec2 24 | ( 25 | radLongitude, 26 | (5.0f / 4.0f) * log(tan(M_PI / 4.0f + 2.0f * radLatitude / 5.0f)) 27 | ); 28 | 29 | float range = (5.0f / 4.0f) * log(tan(9.0f * M_PI / 20.0f)); 30 | 31 | // NOTE : Scale to screen 32 | vec2 pos = vec2 33 | ( 34 | u_Dimension.x / 2 + u_Dimension.x * miller.x / (2 * M_PI), 35 | u_Dimension.y / 2 + u_Dimension.y * miller.y / (2 * range) 36 | ); 37 | 38 | gl_Position = vec4(pos, 0.0, 1.0); 39 | } -------------------------------------------------------------------------------- /Assets/WorldView/geoline.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | void main(void) 6 | { 7 | gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /Assets/WorldView/geoline.vert: -------------------------------------------------------------------------------- 1 | uniform mat4 u_ModelViewProjection; 2 | 3 | attribute vec3 a_Position; 4 | 5 | void main(void) 6 | { 7 | gl_Position = u_ModelViewProjection * vec4(a_Position, 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /Assets/background-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/background-2.jpg -------------------------------------------------------------------------------- /Assets/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/background.png -------------------------------------------------------------------------------- /Assets/circle-new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/circle-new.png -------------------------------------------------------------------------------- /Assets/circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/circle.png -------------------------------------------------------------------------------- /Assets/cube.frag: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | #ifdef GL_ES 4 | precision mediump float; 5 | #endif 6 | 7 | in vec4 vs_Color; 8 | 9 | out vec4 FragColor; 10 | 11 | void main(void) 12 | { 13 | FragColor = vs_Color; 14 | } 15 | -------------------------------------------------------------------------------- /Assets/cube.vert: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | struct Light 4 | { 5 | int Type; 6 | vec3 Position; 7 | vec3 Direction; 8 | vec3 Color; 9 | }; 10 | 11 | struct Material 12 | { 13 | vec3 Ambient; 14 | vec4 Diffuse; 15 | vec3 Specular; 16 | float Shininess; 17 | }; 18 | 19 | layout(location = 0) in vec3 a_Position; 20 | layout(location = 1) in vec3 a_Normal; 21 | 22 | uniform mat4 u_ModelMatrix; 23 | uniform mat4 u_ViewMatrix; 24 | uniform mat4 u_ProjectionMatrix; 25 | uniform mat3 u_NormalMatrix; 26 | 27 | uniform Light u_Light; 28 | uniform Material u_Material; 29 | 30 | out vec3 vs_Position; 31 | out vec3 vs_Normal; 32 | out vec4 vs_Color; 33 | 34 | void main(void) 35 | { 36 | vs_Position = vec3(u_ViewMatrix * u_ModelMatrix * vec4(a_Position, 1.0)); 37 | vs_Normal = normalize(u_NormalMatrix * a_Normal); 38 | 39 | vs_Color = vec4(u_Material.Ambient, 0.0); 40 | 41 | vec3 lightPositionViewSpace = vec3(u_ViewMatrix * vec4(u_Light.Position, 0.0)); 42 | vec3 lightDirection = normalize(lightPositionViewSpace - vs_Position); 43 | float lambert = dot(vs_Normal, lightDirection); 44 | 45 | if (lambert > 0.0) 46 | { 47 | vs_Color += vec4(u_Light.Color, 1.0) * u_Material.Diffuse * lambert; 48 | 49 | vec3 eyeDirection = normalize(-vs_Position); 50 | vec3 r = reflect(-lightDirection, vs_Normal); 51 | 52 | float specular = pow(max(dot(r, eyeDirection), 0.0), u_Material.Shininess); 53 | 54 | vs_Color += vec4(u_Material.Specular * specular, 0.0); 55 | } 56 | 57 | vs_Color.a = u_Material.Diffuse.a; 58 | 59 | gl_Position = u_ProjectionMatrix * vec4(vs_Position, 1.0); 60 | } 61 | 62 | -------------------------------------------------------------------------------- /Assets/curve.frag: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | #ifdef GL_ES 4 | precision mediump float; 5 | #endif 6 | 7 | in vec4 vs_Color; 8 | 9 | out vec4 FragColor; 10 | 11 | void main(void) 12 | { 13 | FragColor = vs_Color; 14 | } 15 | -------------------------------------------------------------------------------- /Assets/curve.vert: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | layout(location = 0) in vec3 a_Position; 4 | layout(location = 1) in vec4 a_Color; 5 | 6 | uniform mat4 u_ModelViewProjection; 7 | uniform vec4 u_Tint; 8 | 9 | out vec4 vs_Color; 10 | 11 | void main(void) 12 | { 13 | vs_Color = a_Color * u_Tint; 14 | gl_Position = u_ModelViewProjection * vec4(a_Position, 1.0); 15 | } 16 | -------------------------------------------------------------------------------- /Assets/disk-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/disk-white.png -------------------------------------------------------------------------------- /Assets/graph.frag: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | #ifdef GL_ES 4 | precision mediump float; 5 | #endif 6 | 7 | varying vec4 v_Color; 8 | 9 | out vec4 FragColor; 10 | 11 | void main(void) 12 | { 13 | FragColor = v_Color; 14 | } 15 | -------------------------------------------------------------------------------- /Assets/graph.vert: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | layout(location = 0) in vec3 a_Position; 4 | layout(location = 1) in vec4 a_Color; 5 | 6 | uniform mat4 u_ModelViewProjection; 7 | uniform vec4 u_Tint; 8 | 9 | out vec4 v_Color; 10 | 11 | void main(void) 12 | { 13 | v_Color = a_Color * u_Tint; 14 | gl_Position = u_ModelViewProjection * vec4(a_Position, 1.0); 15 | } 16 | -------------------------------------------------------------------------------- /Assets/monkey.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | varying vec4 v_Color; 6 | 7 | void main(void) 8 | { 9 | gl_FragColor = v_Color; 10 | } 11 | -------------------------------------------------------------------------------- /Assets/monkey.vert: -------------------------------------------------------------------------------- 1 | uniform mat4 u_Model; 2 | uniform mat4 u_View; 3 | uniform mat4 u_Projection; 4 | 5 | attribute vec3 a_Position; 6 | attribute vec3 a_Normal; 7 | 8 | struct Light 9 | { 10 | vec3 position; 11 | }; 12 | 13 | uniform Light u_Light; 14 | 15 | varying vec4 v_Color; 16 | 17 | void main(void) 18 | { 19 | mat4 mvp = u_Projection * u_View * u_Model; 20 | 21 | vec3 v = (u_Model * vec4(a_Position, 1.0)).xyz; 22 | vec3 n = (u_Model * vec4(a_Normal, 1.0)).xyz; 23 | n = normalize(n); 24 | 25 | vec3 lightDir = u_Light.position - vec3(v.x, v.y, v.z); 26 | lightDir = normalize(lightDir); 27 | 28 | float lambert = dot(lightDir, n); 29 | v_Color = lambert * vec4(1.0, 1.0, 1.0, 1.0); 30 | 31 | gl_Position = u_Projection * u_View * vec4(v, 1.0); 32 | } 33 | -------------------------------------------------------------------------------- /Assets/og-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/og-logo.png -------------------------------------------------------------------------------- /Assets/quad.frag: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | #ifdef GL_ES 4 | precision mediump float; 5 | #endif 6 | 7 | uniform sampler2D u_Texture; 8 | 9 | in vec3 vs_Normal; 10 | in vec2 vs_Texcoord; 11 | 12 | out vec4 FragColor; 13 | 14 | void main(void) 15 | { 16 | FragColor = texture(u_Texture, vs_Texcoord) + 0.1 * vec4(vs_Normal, 1.0); 17 | } 18 | 19 | -------------------------------------------------------------------------------- /Assets/quad.vert: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | layout (location = 0) in vec3 a_Position; 4 | layout (location = 1) in vec3 a_Normal; 5 | layout (location = 2) in vec2 a_Texcoord; 6 | 7 | uniform mat4 u_ModelViewProjectionMatrix; 8 | 9 | out vec3 vs_Normal; 10 | out vec2 vs_Texcoord; 11 | 12 | void main(void) 13 | { 14 | vs_Normal = a_Normal; 15 | vs_Texcoord = a_Texcoord; 16 | gl_Position = u_ModelViewProjectionMatrix * vec4(a_Position, 1.0); 17 | } 18 | 19 | -------------------------------------------------------------------------------- /Assets/ray.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | varying vec4 v_Color; 6 | 7 | void main(void) 8 | { 9 | gl_FragColor = v_Color; 10 | } 11 | -------------------------------------------------------------------------------- /Assets/ray.vert: -------------------------------------------------------------------------------- 1 | 2 | attribute vec3 a_Position; 3 | attribute vec3 a_Color; 4 | 5 | uniform mat4 u_ModelViewProjection; 6 | 7 | varying vec4 v_Color; 8 | 9 | void main(void) 10 | { 11 | v_Color = vec4(a_Color, 1.0); 12 | gl_Position = u_ModelViewProjection * vec4(a_Position, 1.0); 13 | } 14 | 15 | -------------------------------------------------------------------------------- /Assets/sphere.frag: -------------------------------------------------------------------------------- 1 | 2 | #ifdef GL_ES 3 | precision mediump float; 4 | #endif 5 | 6 | uniform sampler2D u_Texture; 7 | 8 | varying vec2 v_Texcoord; 9 | 10 | void main(void) 11 | { 12 | vec4 texcolor = texture2D(u_Texture, v_Texcoord); 13 | float gray = (texcolor.r + texcolor.g + texcolor.b) / 3.0; 14 | 15 | float c = sin(pow(gray, 3.0)); 16 | 17 | texcolor.r = c; 18 | texcolor.g = c; 19 | texcolor.b = c; 20 | 21 | gl_FragColor = texcolor; 22 | } 23 | -------------------------------------------------------------------------------- /Assets/sphere.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/sphere.png -------------------------------------------------------------------------------- /Assets/sphere.vert: -------------------------------------------------------------------------------- 1 | 2 | attribute vec3 a_Position; 3 | // attribute vec3 a_Normal; 4 | attribute vec2 a_Texcoord; 5 | 6 | uniform mat4 u_ModelViewProjection; 7 | 8 | varying vec2 v_Texcoord; 9 | 10 | void main(void) 11 | { 12 | v_Texcoord = a_Texcoord; 13 | gl_Position = u_ModelViewProjection * vec4(a_Position, 1.0); 14 | } 15 | 16 | -------------------------------------------------------------------------------- /Assets/square-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/square-white.png -------------------------------------------------------------------------------- /Assets/target.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/target.png -------------------------------------------------------------------------------- /Assets/umbrella-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Assets/umbrella-logo.png -------------------------------------------------------------------------------- /Assets/world.frag: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | #ifdef GL_ES 4 | precision mediump float; 5 | #endif 6 | 7 | uniform sampler2D u_Texture; 8 | 9 | in vec2 vs_Texcoord; 10 | 11 | out vec4 FragColor; 12 | 13 | void main(void) 14 | { 15 | FragColor = texture(u_Texture, vs_Texcoord).rgba; 16 | } 17 | 18 | -------------------------------------------------------------------------------- /Assets/world.vert: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | layout(location = 0) in vec3 a_Position; 4 | layout(location = 1) in vec2 a_Texcoord; 5 | 6 | uniform mat4 u_ModelViewProjection; 7 | 8 | out vec2 vs_Texcoord; 9 | 10 | void main(void) 11 | { 12 | vs_Texcoord = a_Texcoord; 13 | gl_Position = u_ModelViewProjection * vec4(a_Position, 1.0); 14 | } 15 | 16 | -------------------------------------------------------------------------------- /Builds/VS2013/Dataviz.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.21005.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "graphiti", "Graphiti.vcxproj", "{762C5CE7-35EF-40E6-87F6-60C6A3DFE1CB}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Release|Win32 = Release|Win32 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {762C5CE7-35EF-40E6-87F6-60C6A3DFE1CB}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {762C5CE7-35EF-40E6-87F6-60C6A3DFE1CB}.Debug|Win32.Build.0 = Debug|Win32 16 | {762C5CE7-35EF-40E6-87F6-60C6A3DFE1CB}.Release|Win32.ActiveCfg = Release|Win32 17 | {762C5CE7-35EF-40E6-87F6-60C6A3DFE1CB}.Release|Win32.Build.0 = Release|Win32 18 | {762C5CE7-35EF-40E6-87F6-60C6A3DFE1CB}.Release|Win32.Deploy.0 = Release|Win32 19 | EndGlobalSection 20 | GlobalSection(SolutionProperties) = preSolution 21 | HideSolutionNode = FALSE 22 | EndGlobalSection 23 | EndGlobal 24 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ### ----- Project Configuration ----- 2 | 3 | cmake_minimum_required(VERSION 2.8) 4 | project(OpenGraphiti) 5 | 6 | set (OpenGraphiti_VERSION_MAJOR 1) 7 | set (OpenGraphiti_VERSION_MINOR 0) 8 | 9 | ### ----- Packing Resources 10 | 11 | set_source_files_properties(Pack.hh PROPERTIES GENERATED true) 12 | add_custom_command(OUTPUT Pack.hh 13 | COMMAND . pack.sh 14 | WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} ) 15 | 16 | add_executable(graphiti Main.cc Pack.hh) 17 | 18 | ### ----- Compiler Configuration ----- 19 | 20 | include(CheckCXXCompilerFlag) 21 | 22 | CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) 23 | CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) 24 | 25 | if(COMPILER_SUPPORTS_CXX11) 26 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 27 | elseif(COMPILER_SUPPORTS_CXX0X) 28 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") 29 | else() 30 | message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.") 31 | endif() 32 | 33 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -W -Wall -Wno-missing-field-initializers -O3 -Wno-deprecated") 34 | 35 | ### ----- Includes / Libraries / Packages ----- 36 | 37 | list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") 38 | 39 | include_directories(${PROJECT_SOURCE_DIR}/../) 40 | 41 | list(APPEND CMAKE_PREFIX_PATH ${PROJECT_SOURCE_DIR}/../raindance/Lib/glm-0.9.5.4) 42 | 43 | find_package(PkgConfig REQUIRED) 44 | pkg_search_module(GLFW REQUIRED glfw3) 45 | 46 | find_package(OpenGL REQUIRED) 47 | find_package(OpenCL REQUIRED) 48 | find_package(GLEW REQUIRED) 49 | find_package(PythonLibs REQUIRED) 50 | 51 | include_directories(${OPENGL_INCLUDE_DIRS}) 52 | include_directories(${OPENCL_INCLUDE_DIRS}) 53 | include_directories(${GLFW_INCLUDE_DIRS}) 54 | include_directories(${GLEW_INCLUDE_DIRS}) 55 | include_directories(${GLM_INCLUDE_DIRS}) 56 | #include_directories(${PYTHON_INCLUDE_DIRS}) 57 | include_directories(${PYTHON_INCLUDE_PATH}) 58 | 59 | if (DEFINED OG_OCULUS_RIFT) 60 | add_definitions(-DRD_OCULUS_RIFT=true) 61 | include_directories(${PROJECT_SOURCE_DIR}/../OculusSDK/LibOVR/Include) 62 | include_directories(${PROJECT_SOURCE_DIR}/../OculusSDK/LibOVRKernel/Src/) 63 | 64 | add_library(libovr STATIC IMPORTED) 65 | set_target_properties(libovr PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/../OculusSDK/output/libovr.a) 66 | endif() 67 | 68 | ### ----- Linking ----- 69 | 70 | target_link_libraries(graphiti ${OPENGL_LIBRARIES}) 71 | target_link_libraries(graphiti ${OPENCL_LIBRARIES}) 72 | target_link_libraries(graphiti ${GLFW_STATIC_LIBRARIES}) 73 | target_link_libraries(graphiti ${GLEW_LIBRARIES}) 74 | target_link_libraries(graphiti ${PYTHON_LIBRARIES}) 75 | 76 | if(DEFINED OG_OCULUS_RIFT) 77 | target_link_libraries(graphiti libovr) 78 | endif() -------------------------------------------------------------------------------- /Core/Console.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #if EMSCRIPTEN 7 | # include 8 | # include 9 | #else 10 | # include 11 | # include 12 | #endif 13 | 14 | #include 15 | 16 | class GraphitiConsoleBase : public Entity 17 | { 18 | public: 19 | GraphitiConsoleBase() : Entity(Entity::CONSOLE) {} 20 | 21 | virtual void send(const Variables& input, Variables& output) 22 | { 23 | (void) output; 24 | 25 | std::string logtext; 26 | if (input.get("log", logtext)) 27 | notifyListeners(new ConsoleMessage(logtext)); 28 | } 29 | 30 | virtual EntityContext* context() { return NULL; } 31 | virtual EntityModel* model() { return NULL; } 32 | }; 33 | 34 | #ifdef EMSCRIPTEN 35 | 36 | class GraphitiConsole : public GraphitiConsoleBase, public JavascriptConsole 37 | { 38 | public: 39 | GraphitiConsole(int argc, char** argv) : JavascriptConsole(argc, argv) {} 40 | }; 41 | 42 | #else 43 | # ifndef NO_PYTHON 44 | 45 | class GraphitiConsole : public GraphitiConsoleBase, public PythonConsole 46 | { 47 | public: 48 | GraphitiConsole(int argc, char** argv) : PythonConsole(argc, argv) {} 49 | }; 50 | 51 | # else 52 | 53 | class GraphitiConsole : public GraphitiConsoleBase 54 | { 55 | public: 56 | GraphitiConsole(int argc, char** argv) { (void) argc; (void) argv; } 57 | 58 | void initialize() {} 59 | 60 | bool execute(IScript* script) 61 | { 62 | LOG("[CONSOLE] Couldn't execute script \"%s\" !\n", script->name().c_str()); 63 | return false; 64 | } 65 | }; 66 | 67 | # endif 68 | #endif 69 | -------------------------------------------------------------------------------- /Core/Logo.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | class Logo : public Document::Node 9 | { 10 | public: 11 | Logo(Document::Node* parent = NULL) 12 | : Document::Node(parent) 13 | { 14 | background().loadImage("og-logo.png", FS::BinaryFile("Assets/og-logo.png")); 15 | } 16 | 17 | void onScreenshot(bool enter) override 18 | { 19 | style().Visible = !enter; 20 | } 21 | }; -------------------------------------------------------------------------------- /Core/Shell.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | class GraphitiStdout : public TextArea 10 | { 11 | public: 12 | GraphitiStdout(Document::Node* parent = NULL) 13 | : TextArea(parent) 14 | { 15 | } 16 | 17 | void onScreenshot(bool enter) override 18 | { 19 | style().Visible = !enter; 20 | } 21 | }; 22 | 23 | class GraphitiShell : public Shell, public EntityListener 24 | { 25 | public: 26 | GraphitiShell(Document::Node* parent = NULL) 27 | : Shell(parent), EntityListener() 28 | { 29 | m_Console = NULL; 30 | } 31 | 32 | virtual ~GraphitiShell() 33 | { 34 | } 35 | 36 | void onScreenshot(bool enter) override 37 | { 38 | style().Visible = !enter; 39 | } 40 | 41 | void bind(GraphitiConsole* console) 42 | { 43 | m_Console = console; 44 | m_Console->listeners().push_back(this); 45 | } 46 | 47 | virtual void notify(IMessage* message) 48 | { 49 | if (message->type() != IMessage::CONSOLE) 50 | return; 51 | 52 | auto msg = static_cast(message); 53 | this->print(msg->Message); 54 | } 55 | 56 | void execute(const std::string& command) override 57 | { 58 | if (m_Console == NULL) 59 | print(command); 60 | else 61 | m_Console->execute(command); 62 | } 63 | 64 | private: 65 | GraphitiConsole* m_Console; 66 | }; 67 | -------------------------------------------------------------------------------- /Core/Window.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | class GLWindow : public rd::Window 9 | { 10 | public: 11 | struct Settings : rd::Window::Settings 12 | { 13 | // TODO: Insert GLWindow specific members here 14 | }; 15 | 16 | GLWindow(Settings* settings, Root* parent = NULL) 17 | : rd::Window(settings) 18 | { 19 | m_ActiveVisualizer = 0; 20 | m_Parent = parent; 21 | } 22 | 23 | virtual ~GLWindow() 24 | { 25 | } 26 | 27 | virtual void draw(Context* context) 28 | { 29 | glClearColor(0.3, 0.3, 0.35, 1.0); 30 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 31 | 32 | body().draw(context); 33 | } 34 | 35 | virtual void idle(Context* context) 36 | { 37 | body().idle(context); 38 | } 39 | 40 | // ----- Window Events ----- 41 | 42 | void onKey(int key, int scancode, int action, int mods) override 43 | { 44 | if (key == GLFW_KEY_S && action == GLFW_PRESS && mods == GLFW_MOD_ALT) 45 | { 46 | Geometry::getMetrics().dump(); 47 | Geometry::getMetrics().reset(); 48 | ResourceManager::getInstance().dump(); 49 | } 50 | else 51 | { 52 | body().onKey(key, scancode, action, mods); 53 | } 54 | } 55 | 56 | void onChar(unsigned codepoint) override 57 | { 58 | body().onChar(codepoint); 59 | } 60 | 61 | void onScroll(double xoffset, double yoffset) override 62 | { 63 | body().onScroll(xoffset, yoffset); 64 | } 65 | 66 | inline Root* getParent() { return m_Parent; } 67 | 68 | private: 69 | Root* m_Parent; 70 | std::vector m_Visualizers; 71 | int m_ActiveVisualizer; 72 | }; 73 | -------------------------------------------------------------------------------- /Documents/WorldMap.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class WorldMap : public Document::Node 10 | { 11 | public: 12 | 13 | struct Node 14 | { 15 | glm::vec2 Location; 16 | glm::vec4 Color; 17 | float Size; 18 | }; 19 | 20 | WorldMap(Document::Node* parent = NULL) 21 | : Document::Node(parent) 22 | { 23 | background().loadImage("WorldMap/miller", FS::BinaryFile("Assets/Earth/miller-bw-cropped.png")); 24 | 25 | FS::TextFile vert("Assets/WorldMap/node.vert"); 26 | FS::TextFile geom("Assets/WorldMap/node.geom"); 27 | FS::TextFile frag("Assets/WorldMap/node.frag"); 28 | m_Shader = ResourceManager::getInstance().loadShader("WorldMap/node", 29 | vert.content(), 30 | frag.content(), 31 | geom.content()); 32 | m_Shader->dump(); 33 | 34 | Node node; 35 | node.Size = 5.0; 36 | 37 | node.Color = glm::vec4(LOVE_RED, 0.75); 38 | node.Location = glm::vec2(48.8567, 2.3508); 39 | m_VertexBuffer.push(&node, sizeof(Node)); 40 | 41 | node.Color = glm::vec4(SKY_BLUE, 0.75); 42 | node.Location = glm::vec2(37.783333, -122.416667); 43 | m_VertexBuffer.push(&node, sizeof(Node)); 44 | 45 | m_VertexBuffer.describe("a_Location", GL_FLOAT, 2); 46 | m_VertexBuffer.describe("a_Color", GL_FLOAT, 4); 47 | m_VertexBuffer.describe("a_Size", GL_FLOAT, 1); 48 | m_VertexBuffer.generate(Buffer::DYNAMIC); 49 | 50 | auto drawcall = new DrawArrays(); 51 | drawcall->shader(m_Shader); 52 | drawcall->add(&m_VertexBuffer); 53 | 54 | m_Batch.add(drawcall); 55 | } 56 | 57 | virtual ~WorldMap() 58 | { 59 | } 60 | 61 | void draw(Context* context) override 62 | { 63 | glEnable(GL_BLEND); 64 | glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA); 65 | 66 | m_Camera.setOrthographicProjection(0.0, this->content().getWidth(), 0.0, this->content().getHeight(), -10, 10); 67 | 68 | m_Shader->use(); 69 | m_Shader->uniform("u_ProjectionMatrix").set(m_Camera.getProjectionMatrix()); 70 | m_Shader->uniform("u_Dimension").set(glm::vec2(this->content().getWidth(), this->content().getHeight())); 71 | m_Batch.execute(context); 72 | } 73 | 74 | void idle(Context* context) override 75 | { 76 | (void) context; 77 | } 78 | 79 | void request(const Variables& input, Variables& output) override 80 | { 81 | //LOG("[WORLDMAP] Request received!\n"); 82 | //input.dump(); 83 | 84 | std::string function; 85 | if (!input.get("function", function)) 86 | return; 87 | 88 | bool error = false; 89 | 90 | if (function == "add") 91 | { 92 | float latitude = 0; 93 | float longitude = 0; 94 | float size = 5.0; 95 | glm::vec4 color = glm::vec4(WHITE, 0.75); 96 | 97 | error &= input.get("latitude", &latitude); 98 | error &= input.get("longitude", &longitude); 99 | error &= input.get("color.r", &color.r); 100 | error &= input.get("color.g", &color.g); 101 | error &= input.get("color.b", &color.b); 102 | error &= input.get("color.a", &color.a); 103 | error &= input.get("size", &size); 104 | 105 | Node node; 106 | node.Size = size; 107 | node.Color = color; 108 | node.Location = glm::vec2(latitude, longitude); 109 | m_VertexBuffer.push(&node, sizeof(Node)); 110 | m_VertexBuffer.update(); 111 | } 112 | 113 | auto var = new IntVariable(); 114 | var->set(error ? -1 : 1); 115 | output.set("error", var); 116 | } 117 | 118 | private: 119 | Batch m_Batch; 120 | Camera m_Camera; 121 | Shader::Program* m_Shader; 122 | Buffer m_VertexBuffer; 123 | }; -------------------------------------------------------------------------------- /Entities/Graph/GraphMessages.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | enum GraphMessage 7 | { 8 | // Graph 9 | NODE_FIRST = IMessage::CUSTOM + 1, 10 | 11 | NODE_SELECTED, 12 | NODE_UNSELECTED, 13 | 14 | // Navigation 15 | TARGET_NODE, 16 | }; 17 | 18 | struct GraphNodeSelectedMessage : public IMessage 19 | { 20 | GraphNodeSelectedMessage(unsigned long id) : ID(id) {} 21 | unsigned int type() { return NODE_SELECTED; } 22 | unsigned long ID; 23 | }; 24 | struct GraphNodeUnselectedMessage : public IMessage 25 | { 26 | GraphNodeUnselectedMessage(unsigned long id) : ID(id) {} 27 | unsigned int type() { return NODE_UNSELECTED; } 28 | unsigned long ID; 29 | }; 30 | 31 | struct GraphTargetNodeMessage : public IMessage 32 | { 33 | GraphTargetNodeMessage(unsigned long id) : ID(id) {} 34 | unsigned int type() { return TARGET_NODE; } 35 | unsigned long ID; 36 | }; 37 | 38 | -------------------------------------------------------------------------------- /Entities/Root.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | class Root 7 | { 8 | public: 9 | virtual Context* context() = 0; 10 | virtual GraphitiConsole* console() = 0; 11 | virtual EntityManager& entities() = 0; 12 | virtual EntityVisualizerManager& visualizers() = 0; 13 | }; 14 | -------------------------------------------------------------------------------- /Entities/TimeSeries/TimeSeriesCommands.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | class TimeSeriesCommand : public Sequence 8 | { 9 | public: 10 | TimeSeriesCommand(TimeSeriesEntity* entity, const char* name) 11 | : Sequence(name) 12 | { 13 | m_TimeSeries = entity; 14 | } 15 | 16 | virtual ~TimeSeriesCommand() {} 17 | 18 | virtual void start(Timecode timecode) 19 | { 20 | (void) timecode; 21 | } 22 | 23 | virtual void stop(Timecode timecode) 24 | { 25 | (void) timecode; 26 | } 27 | 28 | protected: 29 | TimeSeriesEntity* m_TimeSeries; 30 | }; 31 | 32 | class TimeSeriesCommand_SetAttribute : public TimeSeriesCommand 33 | { 34 | public: 35 | TimeSeriesCommand_SetAttribute(TimeSeriesEntity* entity, const char* name, const char* type, const char* value) 36 | : TimeSeriesCommand(entity, "SetAttribute") 37 | { 38 | m_Input.Name = std::string(name); 39 | m_Input.Type = std::string(type); 40 | m_Input.Value = std::string(value); 41 | } 42 | 43 | virtual Sequence::Status play(Timecode timecode) 44 | { 45 | (void) timecode; 46 | m_TimeSeries->setAttribute(m_Input.Name.c_str(), m_Input.Type.c_str(), m_Input.Value.c_str()); 47 | LOG("[COMMAND] SetAttribute{ Input : (%s, %s, %s) }\n", m_Input.Name.c_str(), m_Input.Type.c_str(), m_Input.Value.c_str()); 48 | return KILL; 49 | } 50 | 51 | struct Input 52 | { 53 | std::string Name; 54 | std::string Type; 55 | std::string Value; 56 | } m_Input; 57 | }; 58 | -------------------------------------------------------------------------------- /Entities/TimeSeries/TimeSeriesEntity.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class TimeSeriesContext : public EntityContext 6 | { 7 | }; 8 | 9 | class TimeSeriesListener : public EntityListener 10 | { 11 | }; 12 | 13 | class TimeSeriesView : public EntityView, public TimeSeriesListener 14 | { 15 | }; 16 | 17 | class TimeSeriesController : public EntityController, public TimeSeriesListener 18 | { 19 | }; 20 | 21 | class TimeSeriesEntity : public Entity 22 | { 23 | public: 24 | TimeSeriesEntity() 25 | : Entity(TIME_SERIES) 26 | { 27 | m_TimeSeriesContext = new TimeSeriesContext(); 28 | m_TimeSeriesModel = new TimeSeriesModel(); 29 | } 30 | 31 | virtual ~TimeSeriesEntity() 32 | { 33 | SAFE_DELETE(m_TimeSeriesModel); 34 | SAFE_DELETE(m_TimeSeriesContext); 35 | } 36 | 37 | virtual void send(const Variables& input, Variables& output) 38 | { 39 | (void) output; 40 | LOG("[TIMESERIES] Message :\n"); 41 | input.dump(); 42 | } 43 | 44 | virtual EntityModel* model() { return m_TimeSeriesModel; } 45 | virtual EntityContext* context() { return m_TimeSeriesContext; } 46 | private: 47 | TimeSeriesContext* m_TimeSeriesContext; 48 | TimeSeriesModel* m_TimeSeriesModel; 49 | }; 50 | -------------------------------------------------------------------------------- /Entities/TimeSeries/TimeSeriesModel.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class TimeSeriesModel : public EntityModel 6 | { 7 | public: 8 | 9 | TimeSeriesModel() 10 | { 11 | } 12 | 13 | virtual ~TimeSeriesModel() 14 | { 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /Javascript/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * NOTE : In order to run this script when OpenGraphiti starts, you need to add some code at the end of your graphiti.html. 3 | * Add : 4 | * 5 | */ 6 | 7 | var example = function() 8 | { 9 | console.log("Running example script ..."); 10 | 11 | n1 = Module.addNode("A"); 12 | n2 = Module.addNode("B"); 13 | n3 = Module.addNode("C"); 14 | 15 | e1 = Module.addEdge(n1, n2); // A -> B 16 | e2 = Module.addEdge(n2, n3); // B -> C 17 | e3 = Module.addEdge(n3, n1); // C -> A 18 | 19 | Module.setNodeAttribute(n1, "og:space:color", "vec4", "1.0 0.0 0.0 1.0"); // RED 20 | Module.setNodeAttribute(n2, "og:space:color", "vec4", "0.0 1.0 0.0 1.0"); // GREEN 21 | Module.setNodeAttribute(n3, "og:space:color", "vec4", "0.0 0.0 1.0 1.0"); // BLUE 22 | 23 | Module.setEdgeAttribute(e1, "og:space:activity", "float", "1.0"); 24 | Module.setEdgeAttribute(e2, "og:space:activity", "float", "2.0"); 25 | Module.setEdgeAttribute(e3, "og:space:activity", "float", "3.0"); 26 | } 27 | 28 | var hideEmscriptenUI = function() 29 | { 30 | for (i = 0; i < 5; i++) 31 | { 32 | document.body.children[i].style.display = 'None'; 33 | } 34 | 35 | document.getElementById('output').style.display ='None'; 36 | document.getElementById('canvas').style.display ='block'; 37 | } 38 | 39 | var main = function() 40 | { 41 | hideEmscriptenUI(); 42 | 43 | Module.create(); 44 | Module.initialize(); 45 | Module.createWindow('OpenGraphiti : Data Visualization Engine', window.innerWidth - 10, window.innerHeight - 10); 46 | Module.createEntity('graph'); 47 | Module.createVisualizer('space'); 48 | 49 | Module.registerScript('#started', 'alert("Welcome in OpenGraphiti !");'); 50 | Module.registerScript('Example', 'example();') 51 | 52 | Module.start(); 53 | Module.destroy(); 54 | } 55 | 56 | Module.postRun = [main]; -------------------------------------------------------------------------------- /Javascript/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * NOTE : In order to run this script when OpenGraphiti starts, you need to add some code at the end of your graphiti.html. 3 | * Add : 4 | * 5 | */ 6 | 7 | var loadJSON = function(file, jdata) 8 | { 9 | var nodes = {}; 10 | var edges = {}; 11 | 12 | var node_attributes = 13 | { 14 | "og:space:position" : "vec3", 15 | "og:space:color" : "vec4", 16 | "og:space:locked" : "bool", 17 | "og:space:lod": "float", 18 | "og:space:activity" : "float", 19 | "og:space:mark" : "int", 20 | "og:space:size" : "float" 21 | }; 22 | 23 | var edge_attributes = 24 | { 25 | "og:space:activity" : "float", 26 | "og:space:color1" : "vec4", 27 | "og:space:color2" : "vec4", 28 | "og:space:width" : "float", 29 | "og:space:lod" : "float" 30 | }; 31 | 32 | Module.setAttribute("og:space:title", "string", file.name); 33 | 34 | if (jdata[""]) 35 | 36 | for (id in jdata["nodes"]) 37 | { 38 | var node = jdata["nodes"][id]; 39 | var nid = Module.addNode(node["label"]); 40 | 41 | for (attribute in node) 42 | if (attribute in node_attributes) 43 | { 44 | var name = attribute; 45 | var type = node_attributes[name]; 46 | var value = type.indexOf("vec") == 0 ? node[name].join(" ") : node[attribute].toString(); 47 | // console.log(name, type, value); 48 | Module.setNodeAttribute(nid, attribute, type, value); 49 | } 50 | nodes[node["id"]] = nid; 51 | } 52 | 53 | for (id in jdata["edges"]) 54 | { 55 | var edge = jdata["edges"][id] 56 | var src = nodes[edge["src"]]; 57 | var dst = nodes[edge["dst"]]; 58 | var eid = Module.addEdge(src, dst); 59 | 60 | for (attribute in edge) 61 | if (attribute in edge_attributes) 62 | { 63 | var name = attribute; 64 | var type = edge_attributes[name]; 65 | var value = type.indexOf("vec") == 0 ? edge[name].join(" ") : edge[attribute].toString(); 66 | // console.log(name, type, value); 67 | Module.setEdgeAttribute(eid, attribute, type, value); 68 | } 69 | 70 | edges[edge["id"]] = eid; 71 | } 72 | } 73 | 74 | var hideEmscriptenUI = function() 75 | { 76 | for (i = 0; i < 5; i++) 77 | { 78 | document.body.children[i].style.display = 'None'; 79 | } 80 | 81 | document.getElementById('output').style.display ='None'; 82 | document.getElementById('canvas').style.display ='block'; 83 | } 84 | 85 | var setupDragAndDrop = function() 86 | { 87 | var holder = document.getElementById('canvas'); 88 | var state = document.getElementById('status'); 89 | 90 | if (typeof window.FileReader === 'undefined') 91 | { 92 | state.className = 'fail'; 93 | } 94 | else 95 | { 96 | state.className = 'success'; 97 | state.innerHTML = 'File API & FileReader available'; 98 | } 99 | 100 | holder.ondragover = function () 101 | { 102 | holder.style.opacity = 0.5; 103 | return false; 104 | }; 105 | holder.ondragend = function () 106 | { 107 | holder.style.opacity = 1.0; 108 | console.log("dragend"); 109 | return false; 110 | }; 111 | holder.ondrop = function (e) 112 | { 113 | holder.style.opacity = 1.0; 114 | holder.style.border = "none"; 115 | e.preventDefault(); 116 | 117 | var file = e.dataTransfer.files[0]; 118 | console.log(file); 119 | var reader = new FileReader(); 120 | reader.onload = function (event) 121 | { 122 | console.log(event.target); 123 | 124 | var jdata = JSON.parse(event.target.result); 125 | loadJSON(file, jdata); 126 | }; 127 | 128 | reader.readAsText(file); 129 | 130 | return false; 131 | }; 132 | } 133 | 134 | var main = function() 135 | { 136 | hideEmscriptenUI(); 137 | 138 | setupDragAndDrop(); 139 | 140 | Module.create(); 141 | Module.initialize(); 142 | Module.createWindow('OpenGraphiti : Data Visualization Engine', window.innerWidth - 10, window.innerHeight - 10); 143 | 144 | Module.createEntity('graph'); 145 | Module.createVisualizer('space'); 146 | Module.registerScript('Start Animation', 'Module.setAttribute("og:space:animation", "bool", "true");'); 147 | Module.registerScript('Stop Animation', 'Module.setAttribute("og:space:animation", "bool", "false");'); 148 | 149 | Module.start(); 150 | Module.destroy(); 151 | } 152 | 153 | Module.postRun = [main]; -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Thibault Reuille 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | -------------------------------------------------------------------------------- /Lib/GeoLiteCity.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Lib/GeoLiteCity.dat -------------------------------------------------------------------------------- /Lib/networkx-1.8.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Lib/networkx-1.8.1.zip -------------------------------------------------------------------------------- /Lib/pySVG-0.2.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Lib/pySVG-0.2.1.zip -------------------------------------------------------------------------------- /Lib/pygeoip-0.2.7.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Lib/pygeoip-0.2.7.tar.gz -------------------------------------------------------------------------------- /Lib/pyzmq-14.0.1.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Lib/pyzmq-14.0.1.tar.gz -------------------------------------------------------------------------------- /Lib/siphash-0.0.1.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThibaultReuille/graphiti/56d85e5262b76dc6ce4f213a4d80486e015de1b7/Lib/siphash-0.0.1.tar.gz -------------------------------------------------------------------------------- /Main.cc: -------------------------------------------------------------------------------- 1 | #define GRAPHITI_VERSION "Alpha" 2 | 3 | #ifndef EMSCRIPTEN 4 | 5 | #include "Graphiti.hh" 6 | #include "API/Python.hh" 7 | 8 | int main(int argc, char** argv) 9 | { 10 | LOG("--- Welcome in OpenGraphiti (" GRAPHITI_VERSION ") ---\n"); 11 | 12 | // Create context 13 | API::create(argc, argv); 14 | 15 | // Initialize python bindings 16 | API::Python::initialize(); 17 | 18 | // Launch starting script 19 | API::initialize(); 20 | 21 | // Destroy everything 22 | API::destroy(); 23 | 24 | return 0; 25 | } 26 | 27 | #else 28 | 29 | #include "Graphiti.hh" 30 | #include "API/Javascript.hh" 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | OpenDNS Data Visualization Framework 2 | ==================================== 3 | 4 | Official documentation at [www.opengraphiti.com](http://www.opengraphiti.com/) 5 | 6 | Cheat sheet of the console commands available [here](https://github.com/ThibaultReuille/graphiti/blob/master/Scripts/console/cheat_sheet.txt) 7 | 8 | 9 | -------------------------------------------------------------------------------- /Scripts/__init__.py: -------------------------------------------------------------------------------- 1 | print("[__INIT__]") 2 | 3 | import sys 4 | 5 | import math as math 6 | import random as random 7 | import networkx as nx 8 | 9 | import graphiti as graphiti 10 | import standard as std 11 | import console as console 12 | 13 | import demo 14 | import network 15 | import diff 16 | #import leap 17 | import world 18 | import dashboard 19 | -------------------------------------------------------------------------------- /Scripts/console/__init__.py: -------------------------------------------------------------------------------- 1 | print("[__CONSOLE__]") 2 | import console 3 | -------------------------------------------------------------------------------- /Scripts/console/cheat_sheet.txt: -------------------------------------------------------------------------------- 1 | Cheat Sheet: 2 | ================== 3 | 4 | # Basic Controls 5 | 6 | Click + Move mouse to change camera orientation 7 | 8 | Click on a node to select it 9 | 10 | Double click on a node to zoom in and lock the camera on that node 11 | 12 | Click anywhere else to unlock the camera from that node 13 | 14 | ALT + M : Hide left panel 15 | 16 | ALT + SPACE : Play/Pause event timeline 17 | 18 | # Basic Commands 19 | 20 | help 21 | $ help 22 | 23 | info 24 | $ info 25 | 26 | load 27 | $ load my_dataset.json 28 | save 29 | $ save my_graph.json 30 | 31 | screenshot 32 | $ screenshot example.tga <--- Take a screenshot and save it in example.tga 33 | $ screenshot example.tga 2 <--- Take a screenshot with the resolution of your window multiplied by 2 34 | 35 | set 36 | $ set my_attribute my_value 37 | $ set float og:space:size 2.0 38 | $ set vec4 og:space:color 1.0 0.0 0.0 0.5 <--- RGBA components 39 | 40 | get 41 | $ get my_attribute 42 | $ get og:space:size 43 | 44 | remove 45 | $ remove 46 | 47 | map 48 | $ map float og:space:size to float og:space:activity 49 | 50 | clear 51 | $ clear graph 52 | $ clear colors 53 | $ clear icons 54 | $ clear activity 55 | $ clear lod 56 | 57 | color 58 | $ color orange 59 | $ color by type 60 | $ color by my_attribute 61 | $ color set rgb 0.7 62 | $ color set rgb 1 .46 0 1 63 | $ color mul alpha 0.8 64 | $ color add rgba .2 65 | 66 | # Queries 67 | 68 | select 69 | $ select blah <--- Select Node named blah 70 | $ select *blah* <--- Select nodes matching "*blah*" 71 | $ select blah plop <--- Select edge between blah and plop 72 | $ select blah * <--- Select all edges connected to node named blah 73 | 74 | filter 75 | $ filter type 2 <--- Select all nodes with type "2" 76 | $ filter my_attribute value_pattern <--- Select all nodes with my_attribute matches value_pattern 77 | $ filter cc US <--- Select all nodes where "cc" attribute (Country code) is US 78 | 79 | $ filter type 2 3 <--- Select all edges connecting a node with type 2 and a node with type 3 80 | 81 | query 82 | - Undocumented for now, working on real query language. 83 | 84 | # Layout / Animation 85 | 86 | layout 87 | $ layout point 88 | $ layout sphere 89 | $ layout sphere 50 90 | $ layout cube 91 | $ layout cone 92 | # layout seeds <--- Place nodes with depth 0 on a circle 93 | # layout globe <--- If nodes have geocoordinates, place them on a globe sphere. 94 | 95 | play 96 | $ play camera 97 | $ play physics 98 | 99 | stop 100 | $ stop camera 101 | $ stop physics 102 | 103 | # Graph Commands 104 | 105 | topo 106 | $ topo neighbors 107 | $ topo cc <-- Connected Components 108 | $ topo directions 109 | $ topo connections <-- Color nodes depending on their in/out degree (Internal, Sink, Source, Leaf) 110 | $ topo degrees <-- Highlight nodes with high degrees 111 | $ topo degrees high 112 | $ topo degrees low <-- Highlight nodes with low degrees 113 | $ topo spn <-- Apply SPN model (See research presentations) 114 | 115 | # Test 116 | 117 | test 118 | $ test debug <--- Activate debug mode 119 | $ test graph <--- Generate a random graph with 1k nodes, 1k edges. 120 | $ test graph 500 <--- Generate a random graph with 500 nodes, 500 edges. 121 | $ test graph 100 200 <--- Generate a random graph with 100 nodes, 200 edges. 122 | $ test randomize activity <--- Randomize the graph activity attribute 123 | $ test randomize icons 124 | $ test randomize lod 125 | $ test randomize node size 126 | $ test randomize edge width 127 | $ test randomize timeline 128 | $ test neighbor plop <--- Add a neighbor "plop" to selected node. 129 | 130 | # Custom Commands 131 | 132 | opendns 133 | $ opendns infected <--- Show infected score (Whitelisted/Blocked) 134 | $ opendns dga <--- Show DGA score on red gradient (Red: DGA, White: Benign) 135 | 136 | -------------------------------------------------------------------------------- /Scripts/console/help.py: -------------------------------------------------------------------------------- 1 | import script 2 | from script import * 3 | 4 | class Help(script.Script): 5 | def __init__(self, console): 6 | super(Help, self).__init__(console) 7 | 8 | def run(self, args): 9 | print("Not implemented") -------------------------------------------------------------------------------- /Scripts/console/layout.py: -------------------------------------------------------------------------------- 1 | import script 2 | from script import * 3 | 4 | class Layout(script.Script): 5 | 6 | def point(self): 7 | ids = og.get_node_ids() 8 | for nid in ids: 9 | og.set_node_attribute(nid, "og:space:position", "vec3", "0.0 0.0 0.0") 10 | 11 | def sphere(self, args): 12 | radius = 20 13 | if len(args) == 2: 14 | radius = float(args[1]) 15 | 16 | ids = og.get_node_ids() 17 | for nid in ids: 18 | r1 = random.random() * 2 * math.pi 19 | r2 = random.random() * 2 * math.pi 20 | r3 = 0.9 + 0.1 * random.random() 21 | pos = [ 22 | radius * r3 * math.sin(r1) * math.cos(r2), 23 | radius * r3 * math.cos(r1), 24 | radius * r3 * math.sin(r1) * math.sin(r2) 25 | ] 26 | og.set_node_attribute(nid, "og:space:position", "vec3", std.vec3_to_str(pos)) 27 | 28 | def cube(self): 29 | ids = og.get_node_ids() 30 | size = int(len(ids) ** (1.0 / 3.0)) 31 | count = 0 32 | for nid in ids: 33 | pos = [ 34 | count % size, 35 | count / (size * size), 36 | (count % (size * size)) / size 37 | ] 38 | 39 | for i in range(len(pos)): 40 | pos[i] = 5 * (pos[i] - size / 2) 41 | 42 | og.set_node_attribute(nid, "og:space:position", "vec3", std.vec3_to_str(pos)) 43 | count += 1 44 | 45 | def cone(self): 46 | graph = std.load_nx_graph() 47 | 48 | og.set_attribute("og:space:edgemode", "string", "node_color") 49 | 50 | sorted_degrees = sorted(nx.degree(graph).values()) 51 | max_degree = sorted_degrees[-1] 52 | 53 | degree_nodes = {} 54 | for n in graph.nodes(data = True): 55 | degree = nx.degree(graph, n[0]) 56 | if degree in degree_nodes: 57 | degree_nodes[degree].append(n[0]) 58 | else: 59 | degree_nodes[degree] = [n[0]] 60 | 61 | max_radius = 30.0 62 | max_height = 20 63 | for n in graph.nodes(data = True): 64 | degree = nx.degree(graph, n[0]) 65 | 66 | nodes = degree_nodes[degree] 67 | 68 | radius = 1.0 + max_radius * float(1.0 - float(degree) / float(max_degree)) 69 | alpha = 2.0 * math.pi * random.random() #float(nodes.index(n[0])) / float(len(nodes)) 70 | # 3D 71 | # beta = 2.0 * math.pi * random.random() #float(nodes.index(n[0])) / float(len(nodes)) 72 | 73 | x = radius * math.cos(alpha) 74 | y = max_height * float(degree) / float(max_degree) 75 | z = radius * math.sin(alpha) 76 | # 3D 77 | # x = radius * math.sin(alpha) * math.cos(beta) 78 | # y = radius * math.sin(alpha) * math.sin(beta) 79 | # z = radius * math.cos(alpha) 80 | 81 | og.set_node_attribute(n[0], "og:space:position", "vec3", str(x) + " " + str(y) + " " + str(z)) 82 | 83 | 84 | def globe_coordinates(latitude, longitude, delta = 0.0): 85 | globe_radius = 50 86 | radLatitude = latitude * math.pi / 180.0; 87 | radLongitude = longitude * math.pi / 180.0; 88 | 89 | return [ 90 | (globe_radius + delta) * math.cos(radLatitude) * math.cos(radLongitude), 91 | (globe_radius + delta) * math.sin(radLatitude), 92 | - (globe_radius + delta) * math.cos(radLatitude) * math.sin(radLongitude) 93 | ] 94 | 95 | def globe(self): 96 | ids = og.get_node_ids() 97 | for id in ids: 98 | geo = og.get_node_attribute(id, "og:world:geolocation") 99 | if geo is not None: 100 | pos = self.globe_coordinates(geo[0], geo[1]) 101 | og.set_node_attribute(id, "og:space:position", "vec3", std.vec3_to_str(pos)) 102 | og.set_node_attribute(id, "og:space:locked", "bool", "true") 103 | 104 | 105 | def seeds(self): 106 | radius = 100.0 107 | 108 | ids = og.get_node_ids() 109 | zeros = [] 110 | for id in ids: 111 | attribute = og.get_node_attribute(id, "depth") 112 | if attribute == None: 113 | continue 114 | else: 115 | if attribute == 0: 116 | zeros.append(id) 117 | 118 | count = 0 119 | if len(zeros) == 1: 120 | radius = 0.0 121 | for id in zeros: 122 | angle = 2.0 * math.pi * float(count) / float(len(zeros)) 123 | 124 | x = radius * math.cos(angle) 125 | y = 0.0 126 | z = radius * math.sin(angle) 127 | 128 | og.set_node_attribute(id, "og:space:position", "vec3", str(x) + " " + str(y) + " " + str(z)) 129 | og.set_node_attribute(id, "og:space:locked", "bool", "True") 130 | og.set_node_attribute(id, "og:space:activity", "float", "2.0") 131 | og.set_node_attribute(id, "og:space:mark", "int", "2") 132 | count += 1 133 | 134 | def usage(self, args): 135 | self.console.log("Usage: {0} [point|cube|sphere|cone|globe|seeds]".format(args[0])) 136 | 137 | def run(self, args): 138 | if len(args) == 2 and args[1] == "point": 139 | self.point() 140 | elif len(args) == 2 and args[1] == "cube": 141 | self.cube() 142 | elif len(args) >= 2 and args[1] == "sphere": 143 | self.sphere(args[1:]) 144 | elif len(args) == 2 and args[1] == "cone": 145 | self.cone() 146 | elif len(args) == 2 and args[1] == "globe": 147 | self.globe() 148 | elif len(args) == 2 and args[1] == "seeds": 149 | self.seeds() 150 | else: 151 | self.usage(args) 152 | -------------------------------------------------------------------------------- /Scripts/console/opendns.py: -------------------------------------------------------------------------------- 1 | import script 2 | from script import * 3 | 4 | class OpenDNS(script.Script): 5 | 6 | def score(self): 7 | 8 | og.set_attribute("graphiti:space:edgemode", "string", "node_color") 9 | 10 | ids = og.get_node_ids() 11 | for id in ids: 12 | score = og.get_node_attribute(id, "sgraph:score") 13 | if score is None: 14 | og.set_node_attribute(id, "og:space:color", "vec4", "0.5 0.5 0.5 0.5") 15 | elif score < -50: 16 | og.set_node_attribute(id, "og:space:color", "vec3", "1.0 0.0 0.0") 17 | elif score > 50: 18 | og.set_node_attribute(id, "og:space:color", "vec3", "0.0 1.0 0.0") 19 | else: 20 | og.set_node_attribute(id, "og:space:color", "vec3", "1.0 1.0 1.0") 21 | 22 | def infected(self): 23 | 24 | og.set_attribute("graphiti:space:edgemode", "string", "node_color") 25 | 26 | ids = og.get_node_ids() 27 | for id in ids: 28 | score = og.get_node_attribute(id, "sgraph:infected") 29 | if score is None: 30 | og.set_node_attribute(id, "og:space:color", "vec4", "0.5 0.5 0.5 0.5") 31 | elif score < 0: 32 | og.set_node_attribute(id, "og:space:color", "vec3", "1.0 0.0 0.0") 33 | elif score > 0: 34 | og.set_node_attribute(id, "og:space:color", "vec3", "0.0 1.0 0.0") 35 | else: 36 | og.set_node_attribute(id, "og:space:color", "vec3", "1.0 1.0 1.0") 37 | 38 | def dga(self): 39 | 40 | og.set_attribute("graphiti:space:edgemode", "string", "node_color") 41 | 42 | ids = og.get_node_ids() 43 | for id in ids: 44 | score = og.get_node_attribute(id, "sgraph:dga:score") 45 | if score is None: 46 | og.set_node_attribute(id, "og:space:color", "vec4", "0.5 0.5 0.5 0.5") 47 | continue 48 | else: 49 | # DGA score is between [0 : not DGA, 100 : DGA] 50 | sub = score / 100; 51 | rgb = [1.0, 1.0 - sub, 1.0 - sub, 1.0] 52 | og.set_node_attribute(id, "og:space:color", "vec4", std.vec4_to_str(rgb)) 53 | 54 | def run(self, args): 55 | if len(args) == 2 and args[1] == "score": 56 | self.score() 57 | elif len(args) == 2 and args[1] == "infected": 58 | self.infected() 59 | elif len(args) == 2 and args[1] == "dga": 60 | self.dga() -------------------------------------------------------------------------------- /Scripts/console/player.py: -------------------------------------------------------------------------------- 1 | import script 2 | from script import * 3 | 4 | class Play(script.Script): 5 | 6 | def run(self, args): 7 | if len(args) == 2: 8 | if args[1] == "camera": 9 | og.set_attribute('og:space:animation', 'bool', 'True') 10 | elif args[1] == "physics": 11 | og.set_attribute('og:space:physics', 'bool', 'True') 12 | 13 | class Stop(script.Script): 14 | 15 | def run(self, args): 16 | if len(args) == 2: 17 | if args[1] == "camera": 18 | og.set_attribute('og:space:animation', 'bool', 'False') 19 | elif args[1] == "physics": 20 | og.set_attribute('og:space:physics', 'bool', 'False') 21 | -------------------------------------------------------------------------------- /Scripts/console/query.py: -------------------------------------------------------------------------------- 1 | import script 2 | from script import * 3 | 4 | class Query(script.Script): 5 | def __init__(self, console): 6 | super(Query, self).__init__(console) 7 | 8 | 9 | def flip(self, entity_type): 10 | list1 = list() 11 | list2 = list() 12 | 13 | if entity_type in self.console.query: 14 | list1 = self.console.query[entity_type] 15 | 16 | if entity_type == "nodes": 17 | list2 = og.get_node_ids() 18 | elif entity_type == "edges": 19 | list2 = og.get_edge_ids() 20 | 21 | flipped = list() 22 | for oid in list2: 23 | if oid not in list1: 24 | flipped.append(oid) 25 | return flipped 26 | 27 | def run(self, args): 28 | 29 | if len(args) >= 2 and args[1] == "clear": 30 | self.console.query = dict() 31 | 32 | elif len(args) >= 2 and args[1] == "flip": 33 | 34 | if len(args) == 2 or (len(args) == 3 and args[2] == "all"): 35 | self.console.query = { 36 | 'nodes' : self.flip("nodes"), 37 | 'edges' : self.flip("edges") 38 | } 39 | elif len(args) == 3 and args[2] in ["nodes", "edges"]: 40 | flipped = self.flip(args[2]) 41 | self.console.query = dict() 42 | self.console.query[args[2]] = flipped 43 | 44 | elif len(args) > 2 and args[1] == "run": 45 | 46 | s = " ".join(args[2:]).strip() 47 | if s == "nodes": 48 | self.console.query = { "nodes" : og.get_node_ids() } 49 | elif s == "edges": 50 | self.console.query = { "edges" : og.get_edge_ids() } 51 | elif s == "all": 52 | self.console.query = { 53 | "nodes" : og.get_node_ids(), 54 | "edges" : og.get_edge_ids() 55 | } 56 | else: 57 | self.console.log("Error: Invalid query!") 58 | return 59 | else: 60 | self.console.log("Usage: {0} [clear|flip|run]".format(args[0])) 61 | return 62 | 63 | self.console.print_query() 64 | 65 | class Select(script.Script): 66 | def __init__(self, console): 67 | super(Select, self).__init__(console) 68 | 69 | def run(self, args): 70 | if len(args) <= 1 or len(args) > 3: 71 | self.console.log("Usage: {0} [pattern2]".format(args[0])) 72 | return 73 | 74 | found = list() 75 | 76 | if len(args) == 2: 77 | 78 | for nid in og.get_node_ids(): 79 | label = og.get_node_label(nid) 80 | if label is None: 81 | continue 82 | if fnmatch.fnmatch(label, args[1]): 83 | found.append(nid) 84 | self.console.query = { 'nodes' : found } 85 | 86 | elif len(args) == 3: 87 | 88 | for eid in og.get_edge_ids(): 89 | label1 = og.get_node_label(og.get_edge_node1(eid)) 90 | label2 = og.get_node_label(og.get_edge_node2(eid)) 91 | 92 | if label1 is None or label2 is None: 93 | continue 94 | 95 | if ( 96 | fnmatch.fnmatch(label1, args[1]) and fnmatch.fnmatch(label2, args[2]) 97 | ) or ( 98 | fnmatch.fnmatch(label2, args[1]) and fnmatch.fnmatch(label1, args[2]) 99 | ): 100 | found.append(eid) 101 | self.console.query = { 'edges' : found } 102 | 103 | self.console.print_query() 104 | 105 | class Filter(script.Script): 106 | def __init__(self, console): 107 | super(Filter, self).__init__(console) 108 | self.attribute_cache = dict() 109 | 110 | def get_node_attribute(self, nid, attribute): 111 | if nid in self.attribute_cache: 112 | return self.attribute_cache[nid] 113 | 114 | if attribute == "label": 115 | return og.get_node_label(nid) 116 | else: 117 | return og.get_node_attribute(nid, attribute) 118 | 119 | def run(self, args): 120 | if len(args) <= 1 or len(args) > 4: 121 | self.console.log("Usage: {0} [pattern2]".format(args[0])) 122 | return 123 | 124 | found = list() 125 | 126 | attribute = args[1] 127 | pattern1 = args[2] 128 | 129 | if len(args) == 3: 130 | 131 | self.attribute_cache = dict() # Clearing cache 132 | 133 | for nid in og.get_node_ids(): 134 | value = self.get_node_attribute(nid, attribute) 135 | if value is None: 136 | continue 137 | if fnmatch.fnmatch(value, pattern1): 138 | found.append(nid) 139 | self.console.query = { 'nodes' : found } 140 | 141 | elif len(args) == 4: 142 | 143 | pattern2 = args[3] 144 | self.attribute_cache = dict() # Clearing cache 145 | 146 | for eid in og.get_edge_ids(): 147 | value1 = self.get_node_attribute(og.get_edge_node1(eid), attribute) 148 | value2 = self.get_node_attribute(og.get_edge_node2(eid), attribute) 149 | 150 | if value1 is None or value2 is None: 151 | continue 152 | 153 | if ( 154 | fnmatch.fnmatch(value1, pattern1) and fnmatch.fnmatch(value2, pattern2) 155 | ) or ( 156 | fnmatch.fnmatch(value2, pattern1) and fnmatch.fnmatch(value1, pattern2) 157 | ): 158 | found.append(eid) 159 | self.console.query = { 'edges' : found } 160 | 161 | self.console.print_query() 162 | 163 | 164 | -------------------------------------------------------------------------------- /Scripts/console/script.py: -------------------------------------------------------------------------------- 1 | from Scripts import graphiti as og 2 | from Scripts import std 3 | 4 | from Scripts import nx 5 | 6 | import sys 7 | import argparse 8 | 9 | import os.path 10 | import glob 11 | import fnmatch 12 | 13 | import itertools 14 | 15 | import random 16 | import math 17 | 18 | import json 19 | 20 | class Script(object): 21 | def __init__(self, console): 22 | self.console = console 23 | 24 | def run(self, args): 25 | self.console.log("Error: run() method not implemented!") -------------------------------------------------------------------------------- /Scripts/console/test.py: -------------------------------------------------------------------------------- 1 | import script 2 | from script import * 3 | 4 | class Test(script.Script): 5 | 6 | def randomize_timeline(self): 7 | ids = og.get_node_ids() 8 | time = 0 9 | for nid in ids: 10 | time += 500 11 | og.send_command(time, "graph:set_node_attribute", 12 | { 13 | "id" : int(random.choice(ids)), 14 | "type" : "vec4", 15 | "name" : "graphiti:space:color", 16 | "value" : "1.0 0.0 0.0 1.0" 17 | }) 18 | 19 | def randomize_activity(self): 20 | for id in og.get_node_ids(): 21 | if random.uniform(0.0, 1.0) > 0.10: 22 | continue 23 | activity = random.uniform(0.0, 5.0) 24 | og.set_node_attribute(id, "og:space:activity", "float", str(activity)) 25 | for id in og.get_edge_ids(): 26 | activity = random.uniform(0.0, 2.0) 27 | og.set_edge_attribute(id, "og:space:activity", "float", str(activity)) 28 | 29 | def randomize_icons(self): 30 | icons = glob.glob("./Assets/Countries/*.png") 31 | for id in og.get_node_ids(): 32 | icon = "countries/" + random.choice(icons).split("/")[-1][:2].lower() 33 | og.set_node_attribute(id, "og:space:icon", "string", icon) 34 | 35 | icons = glob.glob("./Assets/SpaceView/EdgeStyles/*.png") 36 | for id in og.get_edge_ids(): 37 | icon = "styles/" + random.choice(icons).split("/")[-1][:-4].lower() 38 | og.set_edge_attribute(id, "og:space:icon", "string", icon) 39 | 40 | def randomize_lod(self): 41 | for id in og.get_node_ids(): 42 | og.set_node_attribute(id, "og:space:lod", "float", str(random.random())) 43 | for id in og.get_edge_ids(): 44 | og.set_edge_attribute(id, "og:space:lod", "float", str(random.random())) 45 | 46 | def randomize_node_size(self): 47 | for id in og.get_node_ids(): 48 | activity = random.uniform(0.0, 5.0) 49 | og.set_node_attribute(id, "og:space:size", "float", str(activity)) 50 | 51 | def randomize_edge_width(self): 52 | for id in og.get_edge_ids(): 53 | width = random.uniform(0.0, 5.0) 54 | og.set_edge_attribute(id, "og:space:width", "float", str(width)) 55 | 56 | 57 | def randomize_spheres(self): 58 | node_ids = og.get_node_ids() 59 | for s in range(0, og.count_nodes() / 100): 60 | sphere = og.add_sphere(str(s)) 61 | for i in range(0, 1): 62 | og.tag_node(random.choice(node_ids), sphere) 63 | 64 | 65 | def randomize(self, args): 66 | if len(args) == 2 and args[1] == "activity": 67 | self.randomize_activity() 68 | elif len(args) == 2 and args[1] == "timeline": 69 | self.randomize_timeline() 70 | elif len(args) == 2 and args[1] == "lod": 71 | self.randomize_lod() 72 | elif len(args) == 2 and args[1] == "icons": 73 | self.randomize_icons() 74 | elif len(args) == 2 and args[1] == "spheres": 75 | self.randomize_spheres() 76 | elif len(args) == 3 and args[1] == "node" and args[2] == "size": 77 | self.randomize_node_size() 78 | elif len(args) == 3 and args[1] == "edge" and args[2] == "width": 79 | self.randomize_edge_width() 80 | else: 81 | self.console.log("Error: {0}: Wrong arguments!".format(args[0])) 82 | 83 | def debug(self, args): 84 | flag = og.get_attribute("og:space:debug") 85 | og.set_attribute("og:space:debug", "bool", str(not flag)) 86 | 87 | def random_graph(self, args): 88 | node_count = 1000 89 | edge_count = 1000 90 | 91 | if len(args) >= 3: 92 | node_count = int(args[2]) 93 | edge_count = node_count 94 | if len(args) >= 4: 95 | edge_count = int(args[3]) 96 | 97 | nodes = list() 98 | for i in range(node_count): 99 | id = og.add_node(str(i)) 100 | og.set_node_attribute(id, "type", "string", str(i % 3)) 101 | size = 1 + abs(math.sin(float(i))) 102 | og.set_node_attribute(id, "og:space:size", "float", str(size)) 103 | nodes.append(id) 104 | 105 | for j in range(edge_count): 106 | loop = True 107 | while loop: 108 | src = random.choice(nodes) 109 | dst = random.choice(nodes) 110 | if src != dst: 111 | loop = False 112 | id = og.add_edge(src, dst) 113 | og.set_edge_attribute(id, "type", "string", str(j % 3)) 114 | 115 | def add_neighbor(self, args): 116 | if og.count_selected_nodes() == 0: 117 | self.console.log("Please select a node !") 118 | return 119 | sid = og.get_selected_node(0) 120 | 121 | if len(args) >= 2: 122 | label = args[1] 123 | nid = og.add_node(label) 124 | og.add_edge(sid, nid) 125 | 126 | if len(args) >= 3: 127 | og.set_node_attribute(nid, "type", "string", args[2]) 128 | else: 129 | self.console.log("Error: {0}: Wrong arguments!".format(args[0])) 130 | 131 | def run(self, args): 132 | if len(args) > 2 and args[1] == "randomize": 133 | self.randomize(args[1:]) 134 | elif len(args) >= 2 and args[1] == "debug": 135 | self.debug(args[1:]) 136 | elif len(args) >= 2 and args[1] == "graph": 137 | self.random_graph(args) 138 | elif len(args) >= 3 and args[1] == "neighbor": 139 | self.add_neighbor(args[1:]) 140 | else: 141 | self.console.log("Error: {0}: Wrong arguments!".format(args[0])) -------------------------------------------------------------------------------- /Scripts/demo.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from Scripts import graphiti as og 4 | from Scripts import console 5 | 6 | shell = console.console.Console() 7 | 8 | def start(): 9 | 10 | # ----- Initialization ----- 11 | 12 | og.create_window("OpenGraphiti : Data Visualization Engine", 1024, 728) 13 | og.create_entity("graph") 14 | og.create_visualizer("space") 15 | og.create_visualizer("shell") 16 | og.create_visualizer("logo") 17 | 18 | # ----- Console Callback ------ 19 | 20 | og.register_script("#console", 'demo.shell.execute') 21 | 22 | # ----- Start ----- 23 | 24 | if len(sys.argv) == 3: 25 | if sys.argv[2].endswith(".json"): 26 | og.register_script('#started', 'load ' + sys.argv[2]) 27 | else: 28 | print("Unrecognized format <'" + sys.argv[2] + "'> !") 29 | 30 | og.start() 31 | -------------------------------------------------------------------------------- /Scripts/diff.py: -------------------------------------------------------------------------------- 1 | from Scripts import graphiti 2 | from Scripts import nx 3 | from Scripts import std 4 | from Scripts import demo 5 | 6 | import sys 7 | 8 | colors = { 9 | "removed": "1.0 0.4 0.4", 10 | "added": "0.7 1.0 0.4", 11 | "modified": "1.0 1.0 0.4", 12 | "same": "1.0 1.0 1.0" 13 | } 14 | 15 | def color_diff(): 16 | global colors 17 | for n in graphiti.get_node_ids(): 18 | s = graphiti.get_node_attribute(n, 'diffstatus') 19 | graphiti.set_node_attribute(n, "graphiti:space:color", "vec3", colors[s]) 20 | for e in graphiti.get_edge_ids(): 21 | s = graphiti.get_edge_attribute(e, 'diffstatus') 22 | try: 23 | graphiti.set_edge_attribute(e, "graphiti:space:color", "vec3", colors[s]) 24 | except KeyError: 25 | print("edge: {}".format(e)) 26 | print("diffstatus: {}".format(s)) 27 | sys.exit(-1) 28 | 29 | def search_by_attribute(node_flag, edge_flag): 30 | pattern = raw_input("Expression : ") 31 | attribute = raw_input("Attribute : ") 32 | 33 | def f(t, id, match): 34 | if not match: 35 | if t == "node": 36 | graphiti.set_node_attribute(id, "graphiti:space:lod", "float", "0.0") 37 | elif t == "edge": 38 | graphiti.set_edge_attribute(id, "graphiti:space:lod", "float", "0.0") 39 | 40 | std.regex_map(pattern, attribute, node_flag, edge_flag, f, False) 41 | 42 | def start(): 43 | Scripts = [ 44 | ["Edition", [ 45 | ["Info", "std.info()"], 46 | ["Color Diff", 'diff.color_diff()'], 47 | 48 | ["-", "pass"], 49 | 50 | ["Clear Graph", "demo.clear_graph()"], 51 | ["Clear Colors", "demo.clear_colors()"], 52 | ["Clear Icons", "demo.clear_icons()"], 53 | ["Clear LOD", "demo.clear_lod()"], 54 | ["Node Type", "demo.color_nodes_by_type()"], 55 | ["Edge Type", "demo.color_edges_by_type()"], 56 | ["Country Icons", "demo.countries_to_icons()"], 57 | ["Depth to LOD", "demo.attribute_to_lod('depth', lambda a: a)"], 58 | ["Search by Node Attribute", "diff.search_by_attribute(True, False)"], 59 | ["Search by Edge Attribute", "diff.search_by_attribute(False, True)"], 60 | ]], 61 | ["Colors", [ 62 | ["Dim Nodes", "demo.multiply_colors([0.7, 0.7, 0.7, 1.0], True, False)"], 63 | ["Dim Edges", "demo.multiply_colors([0.7, 0.7, 0.7, 1.0], False, True)"], 64 | ["Brighten Nodes", "demo.multiply_colors([1.3, 1.3, 1.3, 1.0], True, False)"], 65 | ["Brighten Edges", "demo.multiply_colors([1.3, 1.3, 1.3, 1.0], False, True)"], 66 | ["Dim Nodes Alpha", "demo.multiply_colors([1.0, 1.0, 1.0, 0.7], True, False)"], 67 | ["Dim Edges Alpha", "demo.multiply_colors([1.0, 1.0, 1.0, 0.7], False, True)"], 68 | ["Brighten Nodes Alpha", "demo.multiply_colors([1.0, 1.0, 1.0, 1.3], True, False)"], 69 | ["Brighten Edges Alpha", "demo.multiply_colors([1.0, 1.0, 1.0, 1.3], False, True)"], 70 | ]], 71 | ["Arrangement", [ 72 | ["Lock / Unlock", "demo.lock_unlock()"], 73 | ["Point Layout", "demo.sphere_layout(0)"], 74 | ["Sphere Layout", "demo.sphere_layout(20)"], 75 | ["Cube Layout", "demo.cube_layout()"], 76 | ["Conic Layout", "demo.conic_layout()"], 77 | ["Depth Circle Layout", "demo.depth_circle_layout()"], 78 | ["Globe Layout", "demo.globe_layout()"], 79 | ]], 80 | ["Topology", [ 81 | ["Neighbors", "demo.color_neighbors()"], 82 | ["Connected Components", "demo.show_connected_components()"], 83 | ["High Degrees", "demo.show_high_degrees()"], 84 | ["Low Degrees", "demo.show_low_degrees()"], 85 | ["Node Connections", "demo.color_by_node_degree()"], 86 | ["Detect SPN", "demo.detect_spn()"] 87 | ]], 88 | ["Animation", [ 89 | ["Start", "graphiti.set_attribute('graphiti:space:animation', 'bool', 'True')"], 90 | ["Stop", "graphiti.set_attribute('graphiti:space:animation', 'bool', 'False')"] 91 | ]] 92 | ] 93 | 94 | unreg_command = "" 95 | for script in Scripts: 96 | for s in script[1]: 97 | unreg_command += 'graphiti.unregister_script("' + s[0] + '")\n' 98 | 99 | for script in Scripts: 100 | reg_command = "" 101 | for s in script[1]: 102 | reg_command += 'graphiti.register_script("' + s[0] + '", "' + s[1] + '")\n' 103 | 104 | graphiti.register_script(script[0], unreg_command + "\n" + reg_command) 105 | 106 | graphiti.register_script("==========", "pass") 107 | 108 | if len(sys.argv) == 3: 109 | if sys.argv[2].endswith(".json"): 110 | graphiti.register_script('#started', 'std.load_json("' + sys.argv[2] + '"); diff.color_diff()') 111 | else: 112 | print("Unrecognized format <'" + sys.argv[2] + "'> !") 113 | 114 | graphiti.create_window("OpenGraphiti : Data Visualization Engine", 0, 0) 115 | graphiti.create_entity("graph") 116 | graphiti.create_visualizer("space") 117 | graphiti.start() 118 | -------------------------------------------------------------------------------- /Scripts/network.py: -------------------------------------------------------------------------------- 1 | from Scripts import graphiti as og 2 | from Scripts import std 3 | from Scripts import console 4 | 5 | import sys 6 | import os.path 7 | 8 | shell = console.console.Console() 9 | 10 | def start(): 11 | 12 | # ----- Initialization ----- 13 | 14 | og.create_window("OpenGraphiti : Data Visualization Engine", 0, 0) 15 | og.create_entity("graph") 16 | og.create_visualizer("network") 17 | og.create_visualizer("logo") 18 | og.create_visualizer("shell") 19 | 20 | # ----- Console Callback ------ 21 | 22 | og.register_script("#console", 'network.shell.execute') 23 | 24 | # ----- Load JSON dataset if defined ----- 25 | 26 | if len(sys.argv) == 3: 27 | if sys.argv[2].endswith(".json"): 28 | og.register_script('#started', 'load ' + sys.argv[2]) 29 | else: 30 | print("Unrecognized format <'" + sys.argv[2] + "'> !") 31 | 32 | # ----- Start ----- 33 | 34 | og.start() 35 | -------------------------------------------------------------------------------- /Scripts/start.py: -------------------------------------------------------------------------------- 1 | import sys 2 | sys.path.insert(0, "./") 3 | import os 4 | 5 | from Scripts import * 6 | 7 | def usage(): 8 | exclude = ['__init__.py', 'start.py', 'standard.py'] 9 | print("") 10 | print("Usage: " + sys.argv[0] + " ") 11 | print(" Available views : {}".format( 12 | " ".join([file.split('.')[0] for file in os.listdir('Scripts') 13 | if file.split('.')[-1] == "py" 14 | and file not in exclude]))) 15 | print("") 16 | 17 | if __name__ == "__main__": 18 | 19 | if len(sys.argv) <= 1: 20 | usage() 21 | else: 22 | module = "Scripts." + sys.argv[1] 23 | if module in sys.modules: 24 | sys.modules[module].start() 25 | else: 26 | print("No module named {}".format("Scripts." + sys.argv[1])) 27 | usage() 28 | -------------------------------------------------------------------------------- /Scripts/world.py: -------------------------------------------------------------------------------- 1 | from Scripts import math 2 | from Scripts import random 3 | 4 | import sys 5 | import datetime 6 | import thread 7 | import time 8 | import fnmatch 9 | import re 10 | import os 11 | import glob 12 | 13 | from Scripts import graphiti 14 | from Scripts import nx 15 | from Scripts import std 16 | 17 | cities = [ 18 | { 19 | "name" : "Paris", 20 | "geolocation": [48.8742, 2.3470], 21 | "color" : [1.0, 1.0, 0.0, 1.0], 22 | "size" : 1.0 23 | }, 24 | { 25 | "name" : "San Francisco", 26 | "geolocation" : [37.7750, -122.4183], 27 | "color" : [1.0, 0.0, 0.0, 1.0], 28 | "size" : 2.0 29 | }, 30 | ] 31 | 32 | def on_started(): 33 | global cities 34 | 35 | dico = {} 36 | 37 | for city in cities: 38 | nid = graphiti.add_node(city["name"]) 39 | graphiti.set_node_attribute(nid, "og:world:geolocation", "vec2", std.vec2_to_str(city["geolocation"])) 40 | graphiti.set_node_attribute(nid, "og:world:color", "vec4", std.vec4_to_str(city["color"])) 41 | graphiti.set_node_attribute(nid, "og:world:size", "float", str(city["size"])) 42 | dico[city['name']] = nid 43 | 44 | eid = graphiti.add_edge(dico['Paris'], dico['San Francisco']) 45 | graphiti.set_edge_attribute(eid, "og:world:color", "vec4", "0.0 1.0 0.0 1.0") 46 | 47 | def start(): 48 | 49 | if len(sys.argv) == 3: 50 | if sys.argv[2].endswith(".json"): 51 | graphiti.register_script('#started', 'std.load_json("' + sys.argv[2] + '")') 52 | else: 53 | print("Unrecognized format <'" + sys.argv[2] + "'> !") 54 | 55 | # graphiti.register_script("#started", "world.on_started()") 56 | 57 | graphiti.create_window("OpenGraphiti : Data Visualization Engine", 0, 0) 58 | graphiti.create_entity("graph") 59 | graphiti.create_visualizer("world") 60 | graphiti.start() 61 | -------------------------------------------------------------------------------- /Visualizers/Cloud/CloudVisualizer.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class CloudVisualizer : public EntityVisualizer 8 | { 9 | public: 10 | 11 | CloudVisualizer() 12 | { 13 | } 14 | 15 | virtual bool bind(const Viewport& viewport, Entity* entity) 16 | { 17 | if (entity->type() != Entity::GRAPH) 18 | { 19 | LOG("[CLOUD] Couldn't bind entity to view : Wrong entity type!\n"); 20 | return false; 21 | } 22 | 23 | auto ts = static_cast(entity); 24 | 25 | auto view = new CloudView(); 26 | view->setViewport(viewport); 27 | view->bind(ts); 28 | 29 | entity->context()->messages().addListener(view); 30 | 31 | auto controller = new CloudController(); 32 | controller->bind(static_cast(ts->context()), view); 33 | 34 | entity->controllers().push_back(controller); 35 | entity->context()->messages().addListener(controller); 36 | 37 | set(view); 38 | set(controller); 39 | 40 | return true; 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /Visualizers/Cloud/CloudWidgets.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class ViewWidget : public IWidget 6 | { 7 | public: 8 | ViewWidget(IWidget* parent, glm::vec3 pos, glm::vec2 dimension) 9 | : IWidget("view", parent, pos, dimension) 10 | { 11 | m_Icon = new Icon(glm::vec2(1.0, 1.0), glm::vec2(0.5, -0.5)); 12 | m_Icon->load("eye", Assets_Hud_eye_png, sizeof(Assets_Hud_eye_png)); 13 | m_State = 0; 14 | } 15 | 16 | virtual ~ViewWidget() 17 | { 18 | delete m_Icon; 19 | } 20 | 21 | virtual void draw(Context* context, glm::mat4 model, glm::mat4 view, glm::mat4 projection) 22 | { 23 | m_Icon->draw(context, projection * view * glm::scale(model, glm::vec3(m_Dimension, 1.0)), glm::vec4(1.0, 1.0, 1.0, 1.0), 0); 24 | } 25 | 26 | void onMouseClick(MessageQueue& messages, const glm::vec2& pos) override 27 | { 28 | (void) pos; 29 | m_State = (m_State + 1) % 7; 30 | switch(m_State) 31 | { 32 | case 0: 33 | messages.push(static_cast(new WidgetMessage(m_Name.c_str(), "perspective"))); 34 | break; 35 | case 1: 36 | messages.push(static_cast(new WidgetMessage(m_Name.c_str(), "front"))); 37 | break; 38 | case 2: 39 | messages.push(static_cast(new WidgetMessage(m_Name.c_str(), "top"))); 40 | break; 41 | case 3: 42 | messages.push(static_cast(new WidgetMessage(m_Name.c_str(), "left"))); 43 | break; 44 | case 4: 45 | messages.push(static_cast(new WidgetMessage(m_Name.c_str(), "back"))); 46 | break; 47 | case 5: 48 | messages.push(static_cast(new WidgetMessage(m_Name.c_str(), "bottom"))); 49 | break; 50 | case 6: 51 | messages.push(static_cast(new WidgetMessage(m_Name.c_str(), "right"))); 52 | break; 53 | default: 54 | break; 55 | } 56 | } 57 | private: 58 | unsigned int m_State; 59 | }; 60 | -------------------------------------------------------------------------------- /Visualizers/Network/NetworkController.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | class NetworkController : public GraphController 10 | { 11 | public: 12 | NetworkController() 13 | { 14 | m_Font = new rd::Font(); 15 | m_HasPick = false; 16 | } 17 | 18 | virtual ~NetworkController() 19 | { 20 | } 21 | 22 | void bind(Context* context, NetworkView* view) 23 | { 24 | m_Context = context; 25 | m_NetworkView = view; 26 | 27 | m_CameraController.bind(context, view->cameras()); 28 | #ifdef RD_OCULUS_RIFT 29 | m_CameraController.select(CameraController::OCULUS_RIFT); 30 | #else 31 | m_CameraController.select(CameraController::FIRST_PERSON); 32 | #endif 33 | } 34 | 35 | void onResize(const Viewport& viewport) override 36 | { 37 | m_Viewport = viewport; 38 | m_CameraController.onResize(viewport); 39 | } 40 | 41 | void idle(Context* context) override 42 | { 43 | (void) context; 44 | 45 | m_CameraController.update(); 46 | } 47 | 48 | glm::vec2 convertToWindowCoords(const glm::vec2& pos) 49 | { 50 | // NOTE: Convert viewport to window coordinates 51 | // Eventually, Controllers will be documents and 52 | // everything will use viewport coordinates, 53 | // This is temporary hack. Remove when possible. 54 | 55 | auto framebuffer = m_Viewport.getFramebuffer(); 56 | 57 | auto ratio = glm::vec2( 58 | m_Viewport.getDimension().x / framebuffer.Width, 59 | m_Viewport.getDimension().y / framebuffer.Height 60 | ); 61 | 62 | return glm::vec2(pos.x * ratio.x, (framebuffer.Height - pos.y) * ratio.y); 63 | } 64 | 65 | void onKey(int key, int scancode, int action, int mods) override 66 | { 67 | m_CameraController.onKey(key, scancode, action, mods); 68 | } 69 | 70 | void onMouseDown(const glm::vec2& viewport_pos) override 71 | { 72 | auto pos = convertToWindowCoords(viewport_pos); // TODO: Hack! Remove when possible. 73 | 74 | m_CameraController.onMouseDown(pos); 75 | } 76 | 77 | void onMouseClick(const glm::vec2& viewport_pos) override 78 | { 79 | auto pos = convertToWindowCoords(viewport_pos); // TODO: Hack! Remove when possible. 80 | 81 | m_CameraController.onMouseClick(pos); 82 | 83 | m_SelectedNodes.clear(); 84 | 85 | GPUGraph::NodeInstance::ID nid; 86 | m_HasPick = m_NetworkView->pick(pos, &nid); 87 | if (m_HasPick) 88 | { 89 | m_SelectedNodes.push_back(nid); 90 | } 91 | /* 92 | else 93 | { 94 | #ifdef RD_OCULUS_RIFT 95 | m_CameraController.select(CameraController::OCULUS_RIFT); 96 | #else 97 | m_CameraController.select(CameraController::FIRST_PERSON); 98 | #endif 99 | } 100 | */ 101 | } 102 | 103 | void onMouseDoubleClick(const glm::vec2& viewport_pos) override 104 | { 105 | auto pos = convertToWindowCoords(viewport_pos); // TODO: Hack! Remove when possible. 106 | 107 | /* 108 | if (m_HasPick) 109 | { 110 | m_CameraController.zoom(m_SelectNodes[0]) 111 | 112 | #ifdef RD_OCULUS_RIFT 113 | m_CameraController.select(CameraController::OCULUS_RIFT); 114 | #else 115 | m_CameraController.select(CameraController::SPHERICAL); 116 | #endif 117 | } 118 | */ 119 | 120 | m_CameraController.onMouseDoubleClick(pos); 121 | } 122 | 123 | void onMouseTripleClick(const glm::vec2& viewport_pos) override 124 | { 125 | auto pos = convertToWindowCoords(viewport_pos); // TODO: Hack! Remove when possible. 126 | 127 | m_CameraController.onMouseTripleClick(pos); 128 | } 129 | 130 | void onMouseMove(const glm::vec2& viewport_pos, const glm::vec2& viewport_dpos) override 131 | { 132 | auto pos = convertToWindowCoords(viewport_pos); // TODO: Hack! Remove when possible. 133 | auto dpos = convertToWindowCoords(viewport_dpos); // TODO: Hack! Remove when possible. 134 | 135 | m_CameraController.onMouseMove(pos, dpos); 136 | } 137 | 138 | void onScroll(double xoffset, double yoffset) override 139 | { 140 | m_CameraController.onScroll(xoffset, yoffset); 141 | } 142 | 143 | void notify(IMessage* message) 144 | { 145 | (void) message; 146 | } 147 | 148 | private: 149 | Context* m_Context; 150 | NetworkView* m_NetworkView; 151 | Viewport m_Viewport; 152 | 153 | CameraController m_CameraController; 154 | 155 | rd::Font* m_Font; 156 | 157 | bool m_HasPick; 158 | std::vector m_SelectedNodes; 159 | }; 160 | 161 | -------------------------------------------------------------------------------- /Visualizers/Network/NetworkVisualizer.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class NetworkVisualizer : public EntityVisualizer 8 | { 9 | public: 10 | 11 | NetworkVisualizer() 12 | { 13 | } 14 | 15 | virtual bool bind(const Viewport& viewport, Entity* entity) 16 | { 17 | if (entity->type() != Entity::GRAPH) 18 | { 19 | LOG("[MESH] Couldn't bind entity to view : Wrong entity type!\n"); 20 | return false; 21 | } 22 | 23 | auto ts = static_cast(entity); 24 | 25 | auto view = new NetworkView(); 26 | view->setViewport(viewport); 27 | view->bind(ts); 28 | 29 | entity->context()->messages().addListener(view); 30 | 31 | auto controller = new NetworkController(); 32 | controller->bind(ts->context(), view); 33 | 34 | entity->controllers().push_back(controller); 35 | entity->context()->messages().addListener(controller); 36 | 37 | set(view); 38 | set(controller); 39 | 40 | return true; 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /Visualizers/Space/SpaceNode.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | class SpaceNode : public Scene::Node 9 | { 10 | public: 11 | typedef unsigned long ID; 12 | 13 | SpaceNode(const char* label) 14 | : Scene::Node() 15 | { 16 | m_ID = 0; 17 | m_TextureID = 0; 18 | m_Color = glm::vec4(1.0, 1.0, 1.0, 1.0); 19 | m_Mark = 0; 20 | m_Size = 1.0f; 21 | m_Label.set(label, g_SpaceResources->NodeFont); 22 | m_Activity = 0.0; 23 | } 24 | 25 | virtual ~SpaceNode() 26 | { 27 | } 28 | 29 | void draw(Context* context, const glm::mat4& projection, const glm::mat4& view, const glm::mat4& model) 30 | { 31 | if (g_SpaceResources->ShowNodeShapes == SpaceResources::NONE && !g_SpaceResources->ShowNodeLabels) 32 | return; 33 | 34 | glm::vec4 color = m_Color; 35 | 36 | if (!g_SpaceResources->isNodeVisible(getLOD())) 37 | return; 38 | 39 | float nodeSize = getScreenSize(); 40 | glm::mat4 billboard = Geometry::billboard(view * model * getModelMatrix()); 41 | 42 | if (g_SpaceResources->ShowNodeShapes == SpaceResources::ALL || g_SpaceResources->ShowNodeShapes == SpaceResources::COLORS) 43 | { 44 | g_SpaceResources->NodeIcon->draw(context, projection * glm::scale(billboard, glm::vec3(nodeSize, nodeSize, nodeSize)), color, m_TextureID); 45 | } 46 | 47 | if ((g_SpaceResources->ShowNodeShapes == SpaceResources::ALL || g_SpaceResources->ShowNodeShapes == SpaceResources::MARKS) && m_Mark > 0) 48 | { 49 | glPolygonOffset(-1, -1); 50 | glEnable(GL_POLYGON_OFFSET_FILL); 51 | glm::vec4 markerColor = MarkerWidget::color(m_Mark); 52 | markerColor.a = color.a; 53 | g_SpaceResources->NodeMarkIcon->draw(context, projection * glm::scale(billboard, glm::vec3(nodeSize, nodeSize, nodeSize)), markerColor, 0); 54 | glDisable(GL_POLYGON_OFFSET_FILL); 55 | } 56 | 57 | if (g_SpaceResources->ShowNodeLabels) 58 | { 59 | float labelRatio = 0.66; 60 | 61 | float fontSize = m_Label.getFont()->getSize(); 62 | float textSize = labelRatio * nodeSize / (fontSize * m_Label.getFont()->getHeight()); 63 | 64 | Transformation transformation; 65 | transformation.set(billboard); 66 | transformation.translate(glm::vec3(nodeSize / 2 + 0.1, -nodeSize * (1 - labelRatio) / 2, 0.0)); 67 | transformation.scale(glm::vec3(textSize, textSize, 1.0)); 68 | 69 | m_Label.setColor(color); 70 | m_Label.draw(context, projection * transformation.state()); 71 | } 72 | 73 | if (g_SpaceResources->ShowNodeActivity && m_Activity > 0.0f) 74 | { 75 | float maxScale = 5.0; 76 | float t = 1.0 + fmod(context->clock().seconds() * m_Activity, maxScale); 77 | float alpha = 1.0 - (t - 1.0) / maxScale; 78 | float activitySize = nodeSize * t; 79 | glm::vec4 activityColor = glm::vec4(color.r, color.g, color.b, alpha); 80 | 81 | g_SpaceResources->NodeActivityIcon->draw(context, projection * glm::scale(billboard, glm::vec3(activitySize, activitySize, activitySize)), activityColor, 0); 82 | } 83 | } 84 | 85 | bool isOverlap (const glm::vec3& min, const glm::vec3& max) const 86 | { 87 | return Intersection::PointBox(getPosition(), min, max); 88 | } 89 | 90 | inline void setColor(const glm::vec3& color) { m_Color = glm::vec4(color, 1.0); } 91 | inline void setColor(const glm::vec4& color) { m_Color = color; } 92 | inline const glm::vec4& getColor() const { return m_Color; } 93 | 94 | inline void setLabel(const char* label) { m_Label.set(label, g_SpaceResources->NodeFont); } 95 | 96 | inline void setMark(int mark) { m_Mark = mark; } 97 | inline int getMark() { return m_Mark; } 98 | 99 | inline void setSize(float size) { m_Size = size; } 100 | inline float getSize() { return m_Size; } 101 | inline float getScreenSize() { return g_SpaceResources->NodeIconSize * m_Size; } 102 | 103 | inline void setActivity(float activity) { m_Activity = activity; } 104 | inline float getActivity() { return m_Activity; } 105 | 106 | void setIcon(const std::string& name) 107 | { 108 | unsigned long id; 109 | if (!g_SpaceResources->NodeIcon->getTexture(name.c_str(), &id)) 110 | { 111 | LOG("[SPACE] Icon '%s' not found!\n", name.c_str()); 112 | return; 113 | } 114 | 115 | m_TextureID = static_cast(id); 116 | } 117 | 118 | inline void setID(ID id) { m_ID = id; } 119 | inline ID getID() { return m_ID; } 120 | 121 | private: 122 | ID m_ID; 123 | unsigned int m_TextureID; 124 | glm::vec4 m_Color; 125 | int m_Mark; 126 | float m_Size; 127 | Text m_Label; 128 | float m_Activity; 129 | }; 130 | -------------------------------------------------------------------------------- /Visualizers/Space/SpaceSphere.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | class SpaceSphere : public Scene::Node 7 | { 8 | public: 9 | typedef unsigned long ID; 10 | 11 | SpaceSphere() 12 | { 13 | m_Radius = 0.5; 14 | m_Color = glm::vec4(1.0, 1.0, 1.0, 1.0); 15 | m_LOD = 0.0f; 16 | } 17 | ~SpaceSphere() 18 | { 19 | } 20 | 21 | inline void setRadius(float radius) { m_Radius = radius; } 22 | inline void setColor(const glm::vec3& color) { m_Color = glm::vec4(color, 1.0); } 23 | inline void setColor(const glm::vec4& color) { m_Color = color; } 24 | 25 | void draw(Context* context, const glm::mat4& projection, const glm::mat4& view, const glm::mat4& model) 26 | { 27 | float radius = 4 * (m_Radius + 0.5f); 28 | g_SpaceResources->SphereIcon->draw 29 | ( 30 | context, 31 | projection * glm::scale(Geometry::billboard(view * model * getModelMatrix()), glm::vec3(radius, radius, radius)), 32 | m_Color, 33 | 0 34 | ); 35 | } 36 | 37 | bool isOverlap (const glm::vec3& min, const glm::vec3& max) const 38 | { 39 | (void) min; 40 | (void) max; 41 | 42 | // TODO : SpaceSphere::isOverlap 43 | return false; 44 | } 45 | 46 | inline void setLOD(float lod) { m_LOD = lod; } 47 | 48 | private: 49 | float m_Radius; 50 | glm::vec4 m_Color; 51 | float m_LOD; 52 | }; 53 | -------------------------------------------------------------------------------- /Visualizers/Space/SpaceVisualizer.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | class SpaceVisualizer : public EntityVisualizer 9 | { 10 | public: 11 | 12 | SpaceVisualizer() 13 | { 14 | } 15 | 16 | virtual bool bind(const Viewport& viewport, Entity* entity) 17 | { 18 | if (entity->type() != Entity::GRAPH) 19 | { 20 | LOG("[SPACE] Couldn't bind entity to visualizer : Wrong entity type!\n"); 21 | return false; 22 | } 23 | 24 | auto graph = static_cast(entity); 25 | 26 | auto view = new SpaceView(); 27 | view->setViewport(viewport); 28 | view->bind(graph); 29 | 30 | entity->context()->messages().addListener(view); 31 | 32 | auto controller = new SpaceController(); 33 | controller->bind(static_cast(graph->context()), graph->model(), view); 34 | 35 | entity->controllers().push_back(controller); 36 | entity->listeners().push_back(controller); 37 | entity->context()->messages().addListener(controller); 38 | 39 | set(view); 40 | set(controller); 41 | 42 | return true; 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /Visualizers/Stream/StreamController.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | class StreamController : public TimeSeriesController 10 | { 11 | public: 12 | StreamController() 13 | { 14 | m_Font = new rd::Font(); 15 | 16 | m_WidgetGroup = new WidgetGroup("Stream/Controller/Widgets"); 17 | m_WidgetSpacing = 10; 18 | m_WidgetDimension = glm::vec2(16, 16); 19 | } 20 | 21 | virtual ~StreamController() 22 | { 23 | SAFE_DELETE(m_WidgetGroup); 24 | } 25 | 26 | void bind(Context* context, TimeSeriesView* view) 27 | { 28 | m_Camera.setOrthographicProjection(0.0f, view->getViewport().getDimension()[0], 0.0f, view->getViewport().getDimension()[1], 0.001f, 100.f); 29 | m_Camera.lookAt(glm::vec3(0, 0, 1), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0)); 30 | 31 | m_Context = context; 32 | m_TimeSeriesView = view; 33 | } 34 | 35 | void onWindowSize(int width, int height) override 36 | { 37 | m_Camera.resize(width, height); 38 | m_Camera.lookAt(glm::vec3(0, 0, 1), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0)); 39 | 40 | m_WidgetGroup->resize(width, height); 41 | } 42 | 43 | void draw(Context* context) override 44 | { 45 | m_WidgetGroup->draw(context, glm::mat4(), m_Camera.getViewMatrix(), m_Camera.getProjectionMatrix()); 46 | } 47 | 48 | void onMouseClick(const glm::vec2& pos) override 49 | { 50 | IWidget* pickWidget = m_WidgetGroup->pickWidget(pos); 51 | if (pickWidget != NULL) 52 | pickWidget->onMouseClick(m_Context->messages(), pos); 53 | } 54 | 55 | void notify(IMessage* message) 56 | { 57 | (void) message; 58 | } 59 | 60 | private: 61 | Context* m_Context; 62 | TimeSeriesView* m_TimeSeriesView; 63 | 64 | Camera m_Camera; 65 | 66 | rd::Font* m_Font; 67 | 68 | glm::vec2 m_WidgetDimension; 69 | float m_WidgetSpacing; 70 | WidgetGroup* m_WidgetGroup; 71 | }; 72 | 73 | -------------------------------------------------------------------------------- /Visualizers/Stream/StreamView.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | class StreamView : public TimeSeriesView 13 | { 14 | public: 15 | StreamView() 16 | { 17 | LOG("[TIMESERIES] Creating view ...\n"); 18 | 19 | m_TimeSeriesEntity = NULL; 20 | m_Font = new rd::Font(); 21 | } 22 | 23 | virtual ~StreamView() 24 | { 25 | SAFE_DELETE(m_Font); 26 | } 27 | 28 | virtual const char* name() const { return "mesh"; } 29 | 30 | virtual bool bind(TimeSeriesEntity* entity) 31 | { 32 | m_Camera2D.setOrthographicProjection(0.0f, getViewport().getDimension()[0], 0.0f, getViewport().getDimension()[1], 0.001f, 100.f); 33 | m_Camera2D.lookAt(glm::vec3(0, 0, 10), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0)); 34 | 35 | m_TimeSeriesEntity = entity; 36 | m_TimeSeriesEntity->views().push_back(this); 37 | m_TimeSeriesEntity->listeners().push_back(this); 38 | 39 | return true; 40 | } 41 | 42 | IVariable* getAttribute(const std::string& name) override 43 | { 44 | (void) name; 45 | return NULL; 46 | } 47 | 48 | void draw(Context* context) override 49 | { 50 | (void) context; 51 | 52 | glClearColor(0.7, 0.2, 0.2, 1.0); 53 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 54 | } 55 | 56 | void notify(IMessage* message) 57 | { 58 | (void) message; 59 | } 60 | 61 | inline TimeSeriesContext* context() { return static_cast(m_TimeSeriesEntity->context()); } 62 | inline TimeSeriesModel* model() { return static_cast(m_TimeSeriesEntity->model()); } 63 | 64 | private: 65 | TimeSeriesEntity* m_TimeSeriesEntity; 66 | 67 | Camera m_Camera2D; 68 | 69 | rd::Font* m_Font; 70 | }; 71 | 72 | -------------------------------------------------------------------------------- /Visualizers/Stream/StreamVisualizer.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class StreamVisualizer : public EntityVisualizer 8 | { 9 | public: 10 | 11 | StreamVisualizer() 12 | { 13 | } 14 | 15 | virtual bool bind(const Viewport& viewport, Entity* entity) 16 | { 17 | if (entity->type() != Entity::TIME_SERIES) 18 | { 19 | LOG("[TIMESERIES] Couldn't bind entity to view : Wrong entity type!\n"); 20 | return false; 21 | } 22 | 23 | auto ts = static_cast(entity); 24 | 25 | auto view = new StreamView(); 26 | view->setViewport(viewport); 27 | view->bind(ts); 28 | 29 | entity->context()->messages().addListener(view); 30 | 31 | auto controller = new StreamController(); 32 | controller->bind(static_cast(ts->context()), view); 33 | 34 | entity->controllers().push_back(controller); 35 | entity->context()->messages().addListener(controller); 36 | 37 | set(view); 38 | set(controller); 39 | 40 | return true; 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /Visualizers/World/WorldController.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | class WorldController : public GraphController 12 | { 13 | public: 14 | WorldController() 15 | { 16 | m_WidgetDimension = glm::vec2(32, 32); 17 | m_WidgetSpacing = 10; 18 | 19 | // glm::vec3 center = glm::vec3(m_WidgetSpacing + m_WidgetDimension.x / 2, - m_WidgetSpacing - m_WidgetDimension.y / 2, 0); 20 | m_WidgetGroup = new WidgetGroup("world controller group"); 21 | // m_WidgetGroup->add(m_EarthWidget = new EarthWidget (NULL, center, m_WidgetDimension)); center.y -= m_WidgetSpacing + m_WidgetDimension.y; 22 | // m_WidgetGroup->add(m_WorldMapWidget = new WorldMapWidget (NULL, center, m_WidgetDimension)); 23 | } 24 | 25 | virtual ~WorldController() 26 | { 27 | delete m_WidgetGroup; 28 | } 29 | 30 | void bind(Context* context, WorldView* view) 31 | { 32 | m_Context = context; 33 | m_WorldView = view; 34 | 35 | m_Camera.setOrthographicProjection(0.0f, view->getViewport().getDimension()[0], 0.0f, view->getViewport().getDimension()[1], 0.001f, 100.f); 36 | m_Camera.lookAt(glm::vec3(0, 0, 1), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0)); 37 | 38 | m_SphericalCameraController.bind(context, view->getCamera3D()); 39 | m_SphericalCameraController.update(); 40 | } 41 | 42 | void idle(Context* context) override 43 | { 44 | (void) context; 45 | 46 | m_SphericalCameraController.update(); 47 | } 48 | 49 | virtual void draw(Context* context) 50 | { 51 | m_WidgetGroup->draw(context, glm::mat4(), m_Camera.getViewMatrix(), m_Camera.getProjectionMatrix()); 52 | } 53 | 54 | void onWindowSize(int width, int height) override 55 | { 56 | m_Camera.resize(width, height); 57 | m_Camera.setOrthographicProjection(0.0f, (float)width, 0.0f, (float)height, 0.001f, 100.f); 58 | m_Camera.lookAt(glm::vec3(0, 0, 1), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0)); 59 | 60 | m_WidgetGroup->resize(width, height); 61 | 62 | m_SphericalCameraController.onWindowSize(width, height); 63 | } 64 | 65 | void onKey(int key, int scancode, int action, int mods) override 66 | { 67 | m_SphericalCameraController.onKey(key, scancode, action, mods); 68 | } 69 | 70 | void onScroll(double xoffset, double yoffset) override 71 | { 72 | m_SphericalCameraController.onScroll(xoffset, yoffset); 73 | } 74 | 75 | void onMouseDown(const glm::vec2& pos) override 76 | { 77 | m_SphericalCameraController.onMouseDown(pos); 78 | } 79 | 80 | void onMouseClick(const glm::vec2& pos) override 81 | { 82 | IWidget* pickWidget = m_WidgetGroup->pickWidget(pos); 83 | if (pickWidget != NULL) 84 | pickWidget->onMouseClick(m_Context->messages(), pos); 85 | else 86 | m_SphericalCameraController.onMouseClick(pos); 87 | } 88 | 89 | void onMouseDoubleClick(const glm::vec2& pos) override 90 | { 91 | m_SphericalCameraController.onMouseDoubleClick(pos); 92 | } 93 | 94 | void onMouseTripleClick(const glm::vec2& pos) override 95 | { 96 | m_SphericalCameraController.onMouseTripleClick(pos); 97 | } 98 | 99 | void onMouseMove(const glm::vec2& pos, const glm::vec2& dpos) override 100 | { 101 | m_SphericalCameraController.onMouseMove(pos, dpos); 102 | } 103 | 104 | void notify(IMessage* message) 105 | { 106 | (void) message; 107 | } 108 | 109 | private: 110 | Context* m_Context; 111 | WorldView* m_WorldView; 112 | 113 | Camera m_Camera; 114 | 115 | glm::vec2 m_WidgetDimension; 116 | float m_WidgetSpacing; 117 | WidgetGroup* m_WidgetGroup; 118 | 119 | // EarthWidget* m_EarthWidget; 120 | // WorldMapWidget* m_WorldMapWidget; 121 | 122 | SphericalCameraController m_SphericalCameraController; 123 | }; 124 | 125 | -------------------------------------------------------------------------------- /Visualizers/World/WorldResources.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class WorldResources 4 | { 5 | public: 6 | WorldResources() 7 | { 8 | EarthGeoPointShader = ResourceManager::getInstance().loadShader("cube", Assets_cube_vert, sizeof(Assets_cube_vert), Assets_cube_frag, sizeof(Assets_cube_frag)); 9 | EarthGeoCube = new Cube(glm::vec3(0.0, 0.5, 0.0)); 10 | 11 | StarfieldTexture = ResourceManager::getInstance().loadTexture("starfield", Assets_Spheres_starfield_png, sizeof(Assets_Spheres_starfield_png)); 12 | Starfield = new EnvironmentSphere(); 13 | Starfield->setTexture(StarfieldTexture); 14 | 15 | WorldMapNodeIcon = new Icon(); 16 | WorldMapNodeIcon->load("ball", Assets_Particle_ball_png, sizeof(Assets_Particle_ball_png)); 17 | WorldMapNodeIconSize = 10.0; 18 | 19 | EarthRadius = 20.0f; 20 | EarthNodeSize = 0.25; 21 | EarthGeoEdgeShader = ResourceManager::getInstance().loadShader("curve", Assets_curve_vert, sizeof(Assets_curve_vert), Assets_curve_frag, sizeof(Assets_curve_frag)); 22 | } 23 | 24 | ~WorldResources() 25 | { 26 | delete WorldMapNodeIcon; 27 | delete Starfield; 28 | ResourceManager::getInstance().unload(StarfieldTexture); 29 | 30 | delete EarthGeoCube; 31 | ResourceManager::getInstance().unload(EarthGeoPointShader); 32 | ResourceManager::getInstance().unload(EarthGeoEdgeShader); 33 | } 34 | 35 | GraphModel* Model; 36 | 37 | Light Sun; 38 | Material EarthGeoPointMaterial; 39 | Shader::Program* EarthGeoPointShader; 40 | Shader::Program* EarthGeoEdgeShader; 41 | float EarthRadius; 42 | Cube* EarthGeoCube; 43 | float EarthNodeSize; 44 | 45 | Texture* StarfieldTexture; 46 | EnvironmentSphere* Starfield; 47 | 48 | Icon* WorldMapNodeIcon; 49 | float WorldMapNodeIconSize; 50 | 51 | }; 52 | 53 | WorldResources* g_WorldResources = NULL; 54 | 55 | -------------------------------------------------------------------------------- /Visualizers/World/WorldVisualizer.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | class WorldVisualizer : public EntityVisualizer 9 | { 10 | public: 11 | 12 | WorldVisualizer() 13 | { 14 | } 15 | 16 | virtual bool bind(const Viewport& viewport, Entity* entity) 17 | { 18 | if (entity->type() != Entity::GRAPH) 19 | { 20 | LOG("[SPACE] Couldn't bind entity to visualizer : Wrong entity type!\n"); 21 | return false; 22 | } 23 | 24 | auto graph = static_cast(entity); 25 | 26 | auto view = new WorldView(); 27 | view->setViewport(viewport); 28 | if (!view->bind(graph)) 29 | { 30 | SAFE_DELETE(view); 31 | return false; 32 | } 33 | 34 | entity->context()->messages().addListener(view); 35 | 36 | auto controller = new WorldController(); 37 | controller->bind(static_cast(graph->context()), view); 38 | 39 | entity->controllers().push_back(controller); 40 | entity->context()->messages().addListener(controller); 41 | 42 | set(view); 43 | set(controller); 44 | 45 | return true; 46 | } 47 | 48 | private: 49 | }; 50 | -------------------------------------------------------------------------------- /Visualizers/World/WorldWidgets.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class EarthWidget : public IWidget 6 | { 7 | public: 8 | EarthWidget(IWidget* parent, glm::vec3 pos, glm::vec2 dimension) 9 | : IWidget("earth", parent, pos, dimension) 10 | { 11 | m_Icon = new Icon(); 12 | m_Icon->load("globe", Assets_Earth_globe_png, sizeof(Assets_Earth_globe_png)); 13 | m_State = true; 14 | } 15 | virtual ~EarthWidget() 16 | { 17 | delete m_Icon; 18 | } 19 | virtual void draw(Context* context, glm::mat4 model, glm::mat4 view, glm::mat4 projection) 20 | { 21 | m_Icon->draw(context, projection * view * model, m_State ? glm::vec4(1.0, 1.0, 1.0, 1.0) : glm::vec4(0.5, 0.5, 0.5, 1.0), 0); 22 | } 23 | void onMouseClick(MessageQueue& messages, const glm::vec2& pos) override 24 | { 25 | (void) pos; 26 | m_State = !m_State; 27 | messages.push(static_cast(new WidgetMessage(m_State ? "show earth" : "hide earth"))); 28 | } 29 | private: 30 | bool m_State; 31 | }; 32 | 33 | class WorldMapWidget : public IWidget 34 | { 35 | public: 36 | WorldMapWidget(IWidget* parent, glm::vec3 pos, glm::vec2 dimension) 37 | : IWidget("world map", parent, pos, dimension) 38 | { 39 | m_Icon = new Icon(); 40 | m_Icon->load("worldmap", Assets_Earth_world_map_icon_png, sizeof(Assets_Earth_world_map_icon_png)); 41 | m_State = true; 42 | } 43 | virtual ~WorldMapWidget() 44 | { 45 | delete m_Icon; 46 | } 47 | virtual void draw(Context* context, glm::mat4 model, glm::mat4 view, glm::mat4 projection) 48 | { 49 | m_Icon->draw(context, projection * view * model, m_State ? glm::vec4(1.0, 1.0, 1.0, 1.0) : glm::vec4(0.5, 0.5, 0.5, 1.0), 0); 50 | } 51 | void onMouseClick(MessageQueue& messages, const glm::vec2& pos) override 52 | { 53 | (void) pos; 54 | m_State = !m_State; 55 | messages.push(static_cast(new WidgetMessage(m_State ? "show worldmap" : "hide worldmap"))); 56 | } 57 | private: 58 | bool m_State; 59 | }; 60 | -------------------------------------------------------------------------------- /clean.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | rm -rf Makefile CMakeFiles/ CMakeCache.txt cmake_install.cmake Pack.hh 4 | 5 | -------------------------------------------------------------------------------- /cmake/FindLibPython.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright (c) 2007, Simon Edwards 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are met: 8 | # * Redistributions of source code must retain the above copyright 9 | # notice, this list of conditions and the following disclaimer. 10 | # * Redistributions in binary form must reproduce the above copyright 11 | # notice, this list of conditions and the following disclaimer in the 12 | # documentation and/or other materials provided with the distribution. 13 | # * Neither the name of the Simon Edwards nor the 14 | # names of its contributors may be used to endorse or promote products 15 | # derived from this software without specific prior written permission. 16 | # 17 | # THIS SOFTWARE IS PROVIDED BY Simon Edwards ''AS IS'' AND ANY 18 | # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | # DISCLAIMED. IN NO EVENT SHALL Simon Edwards BE LIABLE FOR ANY 21 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | # 28 | # FindLibPython.py 29 | # Copyright (c) 2007, Simon Edwards 30 | # Redistribution and use is allowed according to the terms of the BSD license. 31 | # For details see the accompanying COPYING-CMAKE-SCRIPTS file. 32 | 33 | import sys 34 | import distutils.sysconfig 35 | 36 | print("exec_prefix:%s" % sys.exec_prefix) 37 | print("short_version:%s" % sys.version[:3]) 38 | print("long_version:%s" % sys.version.split()[0]) 39 | print("py_inc_dir:%s" % distutils.sysconfig.get_python_inc()) 40 | print("site_packages_dir:%s" % distutils.sysconfig.get_python_lib(plat_specific=1)) 41 | --------------------------------------------------------------------------------