← Documentation

Étendre UFO@home avec des modules

Il n'y a pas de compte : un module est un fichier à une adresse qui est la vôtre. L'éditeur le charge, les enregistrements qui en ont besoin le nomment.

Ce qu'un module apporte#

Des sources de données (imagerie aérienne, relief du sol, météo, trafic aérien…) et des modèles 3D, chacun avec le crédit que sa licence demande. Ils s'ajoutent à ceux d'UFO@home : dans les sélecteurs de l'éditeur, après eux, et dans la scène partout où un enregistrement nomme l'un de ses modèles.

Le manifeste#

Un fichier JSON, ufoathome-module.json par convention, lisible depuis d'autres sites (CORS). Ses adresses relatives se lisent depuis la sienne.

Le manifeste ci-dessous est en lecture seule et connaît son format : placez le curseur dans un objet et faites Ctrl+Espace (⌥+I sur Mac) pour lister toutes les clés qui pourraient y figurer, avec ce que chacune veut dire.

{
  "format": 1,
  "id": "acme",
  "name": "ACME surveys",
  "credit": "© ACME",
  "creditUrl": "https://acme.example",
  "contributes": {
    "imagery": [
      {
        "id": "acme-ortho",
        "name": "ACME ortho",
        "credit": "© ACME",
        "creditUrl": "https://acme.example/licence",
        "tiles": "https://tiles.acme.example/ortho/{z}/{x}/{y}.jpg"
      }
    ],
    "elevation": [
      {
        "id": "acme-relief",
        "name": "ACME relief",
        "credit": "© ACME",
        "creditUrl": "https://acme.example/licence",
        "tiles": "relief/{z}/{x}/{y}.png"
      }
    ],
    "models": [
      {
        "id": "acme-weather-balloon",
        "kind": "entity",
        "name": "Weather balloon",
        "file": "models/balloon.glb",
        "sizeM": {
          "widthM": 2,
          "lengthM": 2,
          "heightM": 2
        },
        "credit": {
          "title": "Weather balloon",
          "author": "ACME",
          "license": "CC BY 4.0",
          "sourceUrl": "https://acme.example/models"
        }
      }
    ]
  },
  "script": "module.js"
}
  • imagery : des tuiles d'images ordinaires, {z}, {x} et {y} dans l'adresse dans l'ordre que le service leur donne.
  • elevation : des tuiles de relief encodées en PNG Terrarium (hauteur = R × 256 + G + B / 256 − 32768 m).
  • models : des fichiers glTF ou GLB, chacun avec son type (vehicle, aircraft, building, entity…), sa taille et son crédit, comme dans le catalogue d'UFO@home.
  • Un id qu'un autre module ou UFO@home donne déjà au même endroit est refusé, pour tout le module : donnez aux vôtres un préfixe à vous.

Quand il faut du code#

Un service dont les réponses ont une forme à lui demande du code : script nomme un module ES dont l'export par défaut renvoie des implémentations des interfaces de src/modules.

// module.js: its default export returns more implementations, at any point.
export default ({ manifestUrl }) => ({
  weather: [{
    id: "acme-weather", name: "ACME weather", credit: "© ACME", creditUrl: "https://acme.example",
    create: () => ({ /* the methods of WeatherProvider */ })
  }]
})

Les endroits où un module peut ajouter : weather, place, timeZone, narrative, assessment, lightPollution, aircraft, upperAir, elevation, imagery, surroundings, decorModels, skyEvents, interpretations, perception.

Un script s'exécute avec tous les droits de la page. Il n'est exécuté que pour un module que la personne a ajouté elle-même, jamais pour un module qu'un enregistrement nomme.

Simuler un type d'événement du ciel#

Un type d'événement du ciel (un éclair, une fusée, une fusée éclairante…) est ce qu'un enregistrement énonce sous skyEvents.<clé>, dessiné dans la scène et édité dans une partie à lui du groupe Ciel. Sa simulation donne à la scène un objet three.js et le place à chaque image, d'après l'instant et le cadre où la scène se trouve (où est l'œil, l'air, le sol, le vent) ; elle ne dessine jamais elle-même. Le cadre dit aussi où le témoin se tient vraiment, l'instant réel, la magnitude la plus faible vue, ce que les nuages et l'air laissent passer, et lui permet d'éclairer le sol (lightFrom) et d'éblouir l'œil (glareFrom). Construisez-la avec le three que reçoit le script, jamais une copie à vous. Les lancements, les faisceaux et les bolides d'UFO@home sont écrits ainsi, dans src/modules/sky-events.

// A kind of event of the sky: stated in recordings under skyEvents.ballLightning.
export default ({ three }) => ({
  skyEvents: [{
    id: "ballLightning", name: "Ball lightning", credit: "© ACME", creditUrl: "https://acme.example",
    create: () => ({
      key: "ballLightning",
      title: { en: "Ball lightning", fr: "Foudre en boule" },
      simulation: async () => () => {
        const object = new three.Group()
        return {
          object,
          drawnCount: 0,
          // Places and lights the events at t (ms), from frame.eye; draws nothing itself.
          update(events, t, frame) { /* … */ },
          dispose() { object.removeFromParent() }
        }
      },
      // Optional: the part of the Sky group that edits them.
      editor: async () => (container, host, language) => ({ sync() {}, refresh() {}, setTime(t) {}, async setLanguage(l) {} })
    })
  }]
})

Un type d'interprétation#

Une lecture d'un compte rendu qu'énoncent quelques paramètres, calculée en corps quand elle est montrée (des lanternes célestes lâchées d'un jardin, des leurres pyrotechniques largués par un avion) : énoncée sous interpretation.<clé>, donnée à interpretations avec une key, un title, bodiesOf(item) qui renvoie les corps qu'elle est, et un editor facultatif. Pas un fait du ciel : ce que quelqu'un affirme que le compte rendu a vu.

En ajouter un dans l'éditeur#

Dans le groupe Fichiers, l'élément Modules : saisissez l'adresse du manifeste et appuyez sur Ajouter. Vos modules sont gardés dans ce navigateur, peuvent être désactivés ou retirés, et enregistrés dans un fichier (Enregistrer mes modules) qui les charge ailleurs (Charger des modules).

Un enregistrement qui en a besoin#

Un enregistrement qui dessine un modèle d'un module le nomme, pour que qui l'ouvre voie la même chose : l'éditeur écrit son adresse dans le fichier dès qu'un de ses modèles est utilisé, relative à l'enregistrement quand les deux sont sur le même site, et Nommé par cet enregistrement le décoche. Un lecteur qui n'a pas ajouté le module en reçoit ce que son manifeste énonce, sans son script.

{
  "modules": ["https://acme.example/ufo/ufoathome-module.json"]
}

Dans UFO@home lui-même#

Une implémentation peut aussi rejoindre UFO@home : chaque type a son dossier sous src/modules, dont le README dit quoi écrire et où l'inscrire. Une pull request est la bienvenue.