Table of Contents

Formato EasyAR Mega Annotation 0.5

Este documento define la especificación del formato EMA 0.5.

Antes de empezar

En este documento, "productor" se refiere al programa que genera datos EMA, y "consumidor" al programa que lee datos EMA.

Convenciones del formato

  • Los archivos EMA usan codificación UTF-8 y siguen la sintaxis JSON definida por RFC 8259.
  • Los nombres de campo dentro del mismo objeto no deben repetirse.
  • Los nombres de campo distinguen mayúsculas y minúsculas. Los definidos en este documento deben usar las formas de las tablas y ejemplos.
  • Los campos obligatorios deben existir y usar los tipos definidos en las tablas. Los opcionales pueden omitirse si no tienen valor.
  • Los UUID se escriben como cadenas con guiones, por ejemplo 123e4567-e89b-12d3-a456-426614174000.
  • Las marcas de tiempo usan cadenas de fecha y hora UTC con el formato YYYY-MM-DDThh:mm:ssZ, con precisión de segundos. Por ejemplo, 2026-08-12T00:00:00Z. Este formato sigue la representación UTC definida por W3C Date and Time Formats.
  • Las transformaciones de coordenadas usan un sistema OpenGL de mano derecha: +X hacia la derecha, +Y hacia arriba y +Z hacia atrás.

Estructura del documento

El objeto raíz de un documento EMA contiene la versión del formato, el generador, las declaraciones de extensiones, la lista de Mega Block y la lista de anotaciones.

Ejemplo de estructura del objeto raíz EMA:

{
  "version": "0.5.0",
  "generatedBy": "EasyAR Mega Support 2.14.0",
  "blocks": [],
  "annotations": [],
  "extensions": []
}
Campo Tipo Obligatorio Descripción
version string Versión del formato EMA. Un documento 0.5 se escribe como 0.5.0.
generatedBy string Información sobre la herramienta o entidad que generó el documento, normalmente con nombre de producto y versión.
blocks array<Block> Mega Blocks referenciados por el documento. Puede ser un arreglo vacío.
annotations array<Annotation> Objetos de anotación. Puede ser un arreglo vacío.
extensions array<string> No Declaraciones de extensión usadas por el documento. Consulte Extensiones.

Block

Block representa un Mega Block referenciado por un documento EMA y su información de coordenadas.

Campo Tipo Obligatorio Descripción
id UUID string Identificador único del Mega Block. Debe usarse el valor devuelto por el servicio EasyAR Mega.
timestamp date-time string Hora de última modificación del Mega Block. Debe usarse el valor devuelto por el servicio EasyAR Mega. Consulte Convenciones del formato.
location Location No Ubicación geográfica WGS 84 del origen del Mega Block.
transform Transform Transformación del Mega Block relativa al sistema de coordenadas raíz de la escena EMA.
keepTransform boolean Indica si se conserva y aplica el transform registrado en el documento. true significa conservar la transformación ajustada manualmente.

Ejemplo de Mega Block:

{
  "id": "37f11da4-84c0-4fd1-839f-0d86a43cce21",
  "timestamp": "2026-08-12T00:00:00Z",
  "location": {
    "latitude": 31.2304,
    "longitude": 121.4737,
    "altitude": 5.5
  },
  "transform": {
    "position": { "x": 0.0, "y": 0.0, "z": 0.0 },
    "rotation": { "x": 0.0, "y": 0.0, "z": 0.0, "w": 1.0 },
    "scale": { "x": 1.0, "y": 1.0, "z": 1.0 }
  },
  "keepTransform": true
}

Annotation

Annotation representa una anotación en un documento EMA.

Campo Tipo Obligatorio Descripción
type string Tipo de anotación. El valor es node o relationship.
id UUID string Identificador único de la anotación. Los ID de annotations deben ser únicos.
timestamp date-time string Hora de última modificación de la anotación. Consulte Convenciones del formato.
featureType string No Tipo de función al que pertenece la anotación.
properties object No Propiedades de la anotación y datos de extensión.

Node

Node representa una anotación con posición espacial.

Campo Tipo Obligatorio Descripción
type string Fijo en node.
geometry string Tipo de geometría. El valor es point o cube.
parent Parent Sistema de coordenadas de referencia de la anotación node. Puede referenciar un Mega Block o una ubicación geográfica WGS 84; para el soporte del producto en este último caso, consulte WorldParent.
transform Transform Transformación de la anotación node relativa al sistema de coordenadas de referencia. Los campos incluidos los determina geometry.

Cuando geometry es point, representa un punto de posición. Cuando es cube, representa un área con forma de caja centrada en el origen. Consulte Transform para los requisitos de transform según la geometría.

Ejemplo de anotación de punto:

{
  "type": "node",
  "id": "b62fd4b5-66aa-4418-a603-69ae6faedbe6",
  "timestamp": "2026-08-12T00:00:01Z",
  "geometry": "point",
  "parent": {
    "type": "block",
    "id": "37f11da4-84c0-4fd1-839f-0d86a43cce21",
    "timestamp": "2026-08-12T00:00:00Z"
  },
  "transform": {
    "position": { "x": 1.0, "y": 2.0, "z": 3.0 }
  },
  "properties": {
    "name": "Entrance"
  }
}

Ejemplo de anotación de área en caja:

{
  "type": "node",
  "id": "76c0e24a-a01a-4a50-9246-e7d827c96b38",
  "timestamp": "2026-08-12T00:00:02Z",
  "geometry": "cube",
  "parent": {
    "type": "block",
    "id": "37f11da4-84c0-4fd1-839f-0d86a43cce21",
    "timestamp": "2026-08-12T00:00:00Z"
  },
  "transform": {
    "position": { "x": 0.0, "y": 0.0, "z": 0.0 },
    "rotation": { "x": 0.0, "y": 0.0, "z": 0.0, "w": 1.0 },
    "scale": { "x": 0.5, "y": 1.75, "z": 0.5 }
  }
}

Relationship

Relationship representa una relación entre anotaciones y también puede usarse para organizar varias anotaciones en una colección.

Campo Tipo Obligatorio Descripción
type string Fijo en relationship.
members array<UUID string> Registra en orden los ID de las anotaciones miembro. Los miembros pueden referenciar anotaciones node o relationship.

Ejemplo de anotación de relación:

{
  "type": "relationship",
  "id": "b7cf28e4-041e-460e-81cf-a0591c09faee",
  "timestamp": "2026-08-12T00:00:03Z",
  "members": [
    "b62fd4b5-66aa-4418-a603-69ae6faedbe6",
    "76c0e24a-a01a-4a50-9246-e7d827c96b38"
  ],
  "properties": {
    "name": "Annotation Group",
    "isDirected": false
  }
}

Parent

Parent representa el sistema de coordenadas de referencia al que se adjunta un Node y determina la base de interpretación de su transformación espacial.

BlockParent

BlockParent representa un sistema de coordenadas de referencia basado en un Mega Block.

Campo Tipo Obligatorio Descripción
type string Fijo en block.
id UUID string ID del Mega Block referenciado. Este ID debe existir en blocks del objeto raíz.
timestamp date-time string Hora de modificación del Mega Block referenciado cuando se creó o actualizó la anotación. Consulte Convenciones del formato.

WorldParent

WorldParent representa un sistema mundial de coordenadas de referencia cuyo origen es una ubicación WGS 84.

Campo Tipo Obligatorio Descripción
type string Fijo en world.
location Location Ubicación geográfica WGS 84 del origen del sistema de coordenadas de referencia de la anotación node.
Advertencia

EMA 0.5 define la estructura donde parent.type es world, pero EasyAR Mega Studio 2.13 y las versiones posteriores a EasyAR Sense Unity Plugin 4003 eliminaron las funciones relacionadas. La definición del formato no significa que esas versiones del producto admitan el uso de WorldParent.

Coordenadas y tipos básicos

Location

Location representa una ubicación geográfica WGS 84.

Campo Tipo Obligatorio Descripción
latitude number Latitud, número de coma flotante de 64 bits expresado en grados decimales.
longitude number Longitud, número de coma flotante de 64 bits expresado en grados decimales.
altitude number Altitud, número de coma flotante de 64 bits en metros.

Transform

Transform representa la transformación espacial de un objeto relativa a un sistema de coordenadas de referencia.

Campo Tipo Obligatorio Descripción
position Vector3F Posición relativa al sistema de coordenadas de referencia.
rotation Vector4F Condicional Rotación relativa al sistema de coordenadas de referencia.
scale Vector3F Condicional Escala relativa al sistema de coordenadas de referencia.

Los requisitos de cada campo en los distintos casos de uso son los siguientes:

Caso de uso position rotation scale
Mega Block Obligatorio Obligatorio Obligatorio
Anotación cuyo geometry es point Obligatorio Omitido Omitido
Anotación cuyo geometry es cube Obligatorio Obligatorio Obligatorio

Vector3F

Vector3F representa un vector tridimensional usado para registrar posición y escala.

Campo Tipo Obligatorio Descripción
x number Componente del eje x, número de coma flotante de 32 bits.
y number Componente del eje y, número de coma flotante de 32 bits.
z number Componente del eje z, número de coma flotante de 32 bits.

Vector4F

Vector4F representa un cuaternión usado para registrar rotación.

Campo Tipo Obligatorio Descripción
x number Componente x del cuaternión, número de coma flotante de 32 bits.
y number Componente y del cuaternión, número de coma flotante de 32 bits.
z number Componente z del cuaternión, número de coma flotante de 32 bits.
w number Componente w del cuaternión, número de coma flotante de 32 bits.

Propiedades

properties almacena propiedades comunes, propiedades de función y datos de extensión de las anotaciones. Este campo es un objeto clave-valor, y el valor puede ser cualquier valor JSON.

EMA 0.5 define las siguientes propiedades comunes:

Propiedad Objeto aplicable Tipo Obligatorio Descripción
name node, relationship string No Nombre visible de la anotación.
isDirected relationship boolean No Indica si la relación es dirigida. Si no se especifica, es true.
category relationship string No Categoría de relación.

Tipos de función

featureType especifica el tipo de función en el que participa la anotación. Cada tipo define la estructura, la relación y las propiedades dedicadas de las anotaciones relacionadas.

Grafo de puntos de navegación

Un grafo de puntos de navegación representa puntos de navegación en el espacio, rutas que los conectan y la red formada por ellos. Puede expresar rutas y relaciones de conectividad. Todas las anotaciones que forman el grafo establecen featureType en navPointGraph.

El grafo de puntos de navegación consta de tres tipos de anotaciones:

Objeto Requisito de estructura
Punto de navegación type es node y geometry es point.
Ruta type es relationship y members referencia dos puntos de navegación en orden.
Red type es relationship y members referencia puntos de navegación y rutas incluidos en la red.

Las anotaciones de relación en un grafo de puntos de navegación usan las siguientes propiedades de properties:

Propiedad Objeto aplicable Tipo Obligatorio Descripción
category Ruta, red string Distingue tipos de relación: la ruta es route y la red es network.
isDirected Ruta boolean No true significa desde el primer punto de navegación en members hacia el segundo; false significa no dirigido.
weight Ruta number No Peso de la ruta, número de coma flotante de 32 bits. El significado específico lo define la aplicación que usa el grafo de puntos de navegación.

Ejemplo de anotación de grafo de puntos de navegación:

[
  {
    "type": "node",
    "id": "25634f2e-c42d-4163-84c4-86757e8f6e8f",
    "timestamp": "2026-08-12T00:00:00Z",
    "featureType": "navPointGraph",
    "geometry": "point",
    "parent": {
      "type": "block",
      "id": "37f11da4-84c0-4fd1-839f-0d86a43cce21",
      "timestamp": "2026-08-12T00:00:00Z"
    },
    "transform": {
      "position": { "x": 0.0, "y": 0.0, "z": 0.0 }
    }
  },
  {
    "type": "node",
    "id": "fa144e57-c388-4673-a940-9a3f904247c5",
    "timestamp": "2026-08-12T00:00:01Z",
    "featureType": "navPointGraph",
    "geometry": "point",
    "parent": {
      "type": "block",
      "id": "37f11da4-84c0-4fd1-839f-0d86a43cce21",
      "timestamp": "2026-08-12T00:00:00Z"
    },
    "transform": {
      "position": { "x": 0.0, "y": 0.0, "z": 0.0 }
    }
  },
  {
    "type": "relationship",
    "id": "455427a3-b68d-4237-a78f-22213de89dc8",
    "timestamp": "2026-08-12T00:00:02Z",
    "featureType": "navPointGraph",
    "members": [
      "25634f2e-c42d-4163-84c4-86757e8f6e8f",
      "fa144e57-c388-4673-a940-9a3f904247c5"
    ],
    "properties": {
      "category": "route",
      "isDirected": true,
      "weight": 1.0
    }
  },
  {
    "type": "relationship",
    "id": "b579c5fe-e574-410b-853f-77c985966d0f",
    "timestamp": "2026-08-12T00:00:03Z",
    "featureType": "navPointGraph",
    "members": [
      "25634f2e-c42d-4163-84c4-86757e8f6e8f",
      "fa144e57-c388-4673-a940-9a3f904247c5",
      "455427a3-b68d-4237-a78f-22213de89dc8"
    ],
    "properties": {
      "category": "network"
    }
  }
]

Extensiones

Las extensiones agregan datos personalizados a las anotaciones sin cambiar la estructura central de EMA 0.5.

El array extensions del objeto raíz declara las extensiones usadas por el documento. Cada elemento usa el siguiente formato:

PROVIDER:NAME#MAJOR.MINOR.PATCH
  • PROVIDER es el nombre del proveedor de la extensión.
  • NAME es el nombre de la extensión.
  • La versión consta de tres enteros no negativos.
  • PROVIDER y NAME no deben contener : ni #.
  • El mismo PROVIDER:NAME se declara solo una vez en extensions.

Los datos de extensión se almacenan en properties de la anotación, con el nombre de propiedad PROVIDER:NAME y sin el número de versión. El valor de la extensión puede ser cualquier valor JSON. Se recomienda un objeto JSON para poder agregar campos más adelante.

Ejemplo de declaración y datos de extensión:

{
  "version": "0.5.0",
  "generatedBy": "Sample Producer 1.0.0",
  "extensions": [
    "SampleCompany:SampleExtension#1.0.0"
  ],
  "blocks": [],
  "annotations": [
    {
      "type": "relationship",
      "id": "15da6815-174a-4963-ac27-6dc97f324474",
      "timestamp": "2026-08-12T00:00:04Z",
      "members": [],
      "properties": {
        "SampleCompany:SampleExtension": {
          "label": "sample",
          "priority": 10
        }
      }
    }
  ]
}

Requisitos de coherencia

Los productores deben asegurarse de que:

  • Los ID de Mega Block y de anotación son únicos en sus colecciones respectivas.
  • Cuando parent.type es block, parent.id referencia un Mega Block existente en blocks.
  • Cuando type es relationship, los ID de members referencian anotaciones existentes en annotations.
  • Las propiedades de extensión usadas en properties tienen declaraciones correspondientes en extensions.

Los consumidores pueden ignorar campos ordinarios no reconocidos. type, parent.type o geometry desconocidos deben tratarse como datos no compatibles.

Ejemplo completo

Ejemplo de documento EMA completo con datos de extensión:

{
  "version": "0.5.0",
  "generatedBy": "EasyAR Mega Support 2.14.0",
  "extensions": [
    "SampleCompany:SampleExtension#1.0.0"
  ],
  "blocks": [
    {
      "id": "37f11da4-84c0-4fd1-839f-0d86a43cce21",
      "timestamp": "2026-08-12T00:00:00Z",
      "location": {
        "latitude": 31.2304,
        "longitude": 121.4737,
        "altitude": 5.5
      },
      "transform": {
        "position": { "x": 0.0, "y": 0.0, "z": 0.0 },
        "rotation": { "x": 0.0, "y": 0.0, "z": 0.0, "w": 1.0 },
        "scale": { "x": 1.0, "y": 1.0, "z": 1.0 }
      },
      "keepTransform": true
    }
  ],
  "annotations": [
    {
      "type": "node",
      "id": "b62fd4b5-66aa-4418-a603-69ae6faedbe6",
      "timestamp": "2026-08-12T00:00:01Z",
      "geometry": "point",
      "parent": {
        "type": "block",
        "id": "37f11da4-84c0-4fd1-839f-0d86a43cce21",
        "timestamp": "2026-08-12T00:00:00Z"
      },
      "transform": {
        "position": { "x": 1.0, "y": 2.0, "z": 3.0 }
      },
      "properties": {
        "name": "Entrance",
        "SampleCompany:SampleExtension": {
          "label": "sample",
          "priority": 10
        }
      }
    },
    {
      "type": "node",
      "id": "76c0e24a-a01a-4a50-9246-e7d827c96b38",
      "timestamp": "2026-08-12T00:00:02Z",
      "geometry": "cube",
      "parent": {
        "type": "block",
        "id": "37f11da4-84c0-4fd1-839f-0d86a43cce21",
        "timestamp": "2026-08-12T00:00:00Z"
      },
      "transform": {
        "position": { "x": 0.0, "y": 0.0, "z": 0.0 },
        "rotation": { "x": 0.0, "y": 0.0, "z": 0.0, "w": 1.0 },
        "scale": { "x": 0.5, "y": 1.75, "z": 0.5 }
      },
      "properties": {
        "name": "Display Area"
      }
    },
    {
      "type": "relationship",
      "id": "b7cf28e4-041e-460e-81cf-a0591c09faee",
      "timestamp": "2026-08-12T00:00:03Z",
      "members": [
        "b62fd4b5-66aa-4418-a603-69ae6faedbe6",
        "76c0e24a-a01a-4a50-9246-e7d827c96b38"
      ],
      "properties": {
        "name": "Tour Area",
        "isDirected": false
      }
    }
  ]
}