Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AsciiDoc conversion experiments #682

Merged
merged 110 commits into from
Jun 6, 2022
Merged
Show file tree
Hide file tree
Changes from 96 commits
Commits
Show all changes
110 commits
Select commit Hold shift + click to select a range
8e2c32a
Remove certain HTML elements from markdown
javagl Apr 7, 2022
b3b66f2
Added auto-generated AsciiDoc specification
javagl Apr 7, 2022
8253270
Clean up AsciiDoc for Asciidoctor
javagl Apr 7, 2022
ac729d4
Add basic instructions for building from AsciiDoc
javagl Apr 7, 2022
1794fa5
First pass of auto-generated README.adoc files
javagl Apr 13, 2022
3d49714
Removed local TOCs. Basic structure for AsciiDoc.
javagl Apr 13, 2022
dcea6ce
Set AsciiDoc syntax highlighter
javagl Apr 13, 2022
8efe6af
Consistent source blocks
javagl Apr 14, 2022
7950df9
Fixed image paths and minor formatting
javagl Apr 16, 2022
158e15e
An attempt to insert auto-generated section IDs
javagl Apr 16, 2022
603d23d
First pass of pointing internal links to anchors
javagl Apr 16, 2022
e86ab9b
Removed HTML formatting in Semantics
javagl Apr 16, 2022
eab3975
Define proper image paths with imagesdir
javagl Apr 16, 2022
41a4cf4
Fixed image links for implicit tiling
javagl Apr 16, 2022
6c79b04
Consistent implementation notes
javagl Apr 16, 2022
e0f3cab
A few internal link fixes
javagl Apr 16, 2022
35ad563
A first pass of link fixes
javagl Apr 16, 2022
01001ec
Consistent examples/implementation notes
javagl Apr 16, 2022
63e1577
Minor update of build instructions
javagl Apr 16, 2022
4170a72
Removed GitHub-specific icons
javagl Apr 16, 2022
812731e
Restructured appendix
javagl Apr 16, 2022
01e8633
Fixed copy-and-paste typo
javagl Apr 19, 2022
d835958
Moved Styling into appendix
javagl Apr 19, 2022
4a429b8
Moved Styling into own section
javagl Apr 20, 2022
7fab1ef
Removed inlined property references
javagl Apr 20, 2022
0025bfb
Merge remote-tracking branch 'upstream/draft-1.1' into asciidoc-conve…
javagl Apr 20, 2022
f2dce43
Attempts for fixing links
javagl Apr 25, 2022
9e1d32a
Using a relative link
javagl Apr 25, 2022
aee5772
Re-inserted metadata semantics as appendix
javagl Apr 25, 2022
a3028b5
Common links to schema files
javagl Apr 25, 2022
e672e17
An attempt to handle relative links
javagl Apr 25, 2022
710225b
An attempt to make cross-file links work
javagl Apr 25, 2022
b5f1aaa
Fixed link to main specification
javagl Apr 25, 2022
16ee39f
Fixed link to main specification again
javagl Apr 25, 2022
b7fa89b
Fixed link to availability appendix
javagl Apr 25, 2022
916aed2
Fixed link to availability indexing
javagl Apr 25, 2022
211ddf4
Give images in tables a sensible size
javagl Apr 27, 2022
c42b3f3
Further linking experiments
javagl Apr 27, 2022
dc0d9eb
Fixed formatting typo
javagl Apr 27, 2022
984a8d6
Trial and error for link fixes
javagl Apr 27, 2022
8c64cb2
Trial and error for links
javagl Apr 27, 2022
625f312
Linking experiments
javagl Apr 27, 2022
de13ac4
Linking experiments
javagl Apr 27, 2022
abd8d26
Linking experiments
javagl Apr 27, 2022
e336739
Linking experiments
javagl Apr 27, 2022
0d90d1a
Linking experiments
javagl Apr 27, 2022
5026838
Basic tests for linking
javagl Apr 27, 2022
ba1483c
Workaround for linking
javagl Apr 27, 2022
3898281
Link fixes for PropertyTable
javagl Apr 27, 2022
69ded14
Proper relative link
javagl Apr 27, 2022
b11fd1d
Proper relative link now
javagl Apr 27, 2022
3f9b353
Minor building instructions update
javagl Apr 27, 2022
50d8f07
Links for Semantics
javagl Apr 27, 2022
49419c4
Link fix for Semantics
javagl Apr 27, 2022
fb3e2fd
Link fix for Semantics
javagl Apr 27, 2022
a19d9e1
Link fixes for Schema and PropertyTable
javagl Apr 27, 2022
edefa6e
Link fixes for PropertyTable
javagl Apr 27, 2022
cc1fdd9
Link fixes for Metadata
javagl Apr 27, 2022
d662349
Link fix for Metadata
javagl Apr 27, 2022
7905bae
Link fixes for ReferenceImplementation
javagl Apr 27, 2022
14755a1
Link fixes for ReferenceImplementation
javagl Apr 27, 2022
891f2b7
Fix typo in anchor
javagl Apr 27, 2022
7b2d303
Link fixes for Styling
javagl Apr 27, 2022
24f3702
Link fix for Styling
javagl Apr 27, 2022
8399d27
Link fix for ImplicitTiling
javagl Apr 27, 2022
a0fbf78
Link fix for Styling
javagl Apr 27, 2022
bf4c914
Fix links for TileFormats
javagl Apr 27, 2022
dd41bf7
Extract migration guide as appendix
javagl Apr 27, 2022
ff2c367
Link fix in TileFormats
javagl Apr 27, 2022
6f86692
Link fix for TileFormats
javagl Apr 27, 2022
9e1aff4
Link fixes for tile formats
javagl Apr 28, 2022
63086b9
Link fix for migration guide
javagl Apr 28, 2022
8e1107e
Update for building info
javagl Apr 28, 2022
67a5b44
Update building instructions
javagl Apr 28, 2022
f9796c6
Minor fix in building instructions
javagl May 3, 2022
226a5bf
Experiments for property references
javagl May 3, 2022
9493378
Additional experimental property references
javagl May 12, 2022
88da5b6
Link fixes for migration guide
javagl May 17, 2022
43ad9c0
Link fixes for schema
javagl May 17, 2022
c07bd38
Formatting for tables
javagl May 17, 2022
ef5902c
Add image captions
javagl May 17, 2022
7280fd1
Proper image captions
javagl May 17, 2022
72a452e
Link fixes
javagl May 17, 2022
c7106b0
Restore text that was lost in translation
javagl May 17, 2022
e99b12d
Updated build instructions
javagl May 17, 2022
8c36b3a
Link fixes for main README
javagl May 17, 2022
b572106
Proper base directory for main README
javagl May 17, 2022
492be69
External tileset class clarification
javagl May 17, 2022
3a13438
Using single ADOC files for property reference
javagl May 22, 2022
36bd2bb
Merge branch 'asciidoc-conversion-experiments' into asciidoc-conversion
javagl May 25, 2022
ffe8e9a
Merge remote-tracking branch 'upstream/draft-1.1' into asciidoc-conve…
javagl May 25, 2022
df202db
Improved formatting from wetzel output
javagl May 25, 2022
7e74d6e
Update with latest wetzel output
javagl May 25, 2022
2a18cb1
Updated build instructions
javagl May 26, 2022
188f7e5
Moved build instructions to specification directory
javagl May 26, 2022
a816eb0
Use logo in specification subdirectory
javagl May 26, 2022
d63fbbd
Show logo and introduction in spec README on GitHub
javagl May 28, 2022
a6dc753
Convert logo from inline to block image
javagl May 28, 2022
a24864c
Updated compression infos to build instructions
javagl May 28, 2022
71fd3a5
Fix typo
lilleyse May 31, 2022
b2eefff
Update TileFormats README.adoc
javagl May 31, 2022
09e6f56
Updated properties reference with latest output
javagl May 31, 2022
06f5732
Updated build instructions for properties reference
javagl May 31, 2022
e1acec0
Merge branch 'draft-1.1' into asciidoc-conversion
javagl May 31, 2022
6f6bde1
Merge remote-tracking branch 'upstream/draft-1.1' into asciidoc-conve…
javagl May 31, 2022
23552d2
Removed Markdown files that now are AsciiDoc
javagl Jun 6, 2022
78c2a65
Updated links to point to AsciiDoc instead of Markdown
javagl Jun 6, 2022
6c2c5da
Update wetzel link to CesiumGS branch
lilleyse Jun 6, 2022
35f93d5
Updated properties reference with latest state
javagl Jun 6, 2022
a2712b3
Merge branch 'asciidoc-conversion' of https://github.com/javagl/3d-ti…
javagl Jun 6, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions specification/ACKNOWLEDGEMENTS.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
= Acknowledgements
lilleyse marked this conversation as resolved.
Show resolved Hide resolved

Editors:

* Patrick Cozzi, https://twitter.com/pjcozzi[@pjcozzi], link:mailto:[email protected][[email protected]]
* Sean Lilley, https://twitter.com/lilleyse[@lilleyse], link:mailto:[email protected][[email protected]]
* Gabby Getz, https://twitter.com/gabbygetz[@gabbygetz], link:mailto:[email protected][[email protected]]

Acknowledgements:

* Matt Amato, https://twitter.com/matt_amato[@matt_amato]
* Erik Andersson, https://github.com/e-andersson[@e-andersson]
* Dan Bagnell, https://github.com/bagnell[@bagnell]
* Ray Bentley
* Jannes Bolling, https://github.com/jbo023[@jbo023]
* Dylan Brown, http://www.github.com/Dylan-Brown[@Dylan-Brown]
* Sarah Chow, https://cesium.com/team/SarahChow/[cesium.com/team/SarahChow]
* Paul Connelly
* Volker Coors
* Tom Fili, https://twitter.com/CesiumFili[@CesiumFili]
* Leesa Fini, http://www.github.com/LeesaFini[@LeesaFini]
* Ralf Gutbell
* Frederic Houbie
* Christopher Mitchell, Ph.D., https://github.com/KermMartian[@KermMartian]
* Claus Nagel
* Jean-Philippe Pons
* Carl Reed
* Kevin Ring, http://www.kotachrome.com/kevin/[www.kotachrome.com/kevin]
* Scott Simmons
* Rob Taglang, https://github.com/lasalvavida[@lasalvavida]
* Stan Tillman
* Piero Toffanin, https://github.com/pierotofy[@pierotofy]
* Pano Voudouris
* Dave Wesloh
49 changes: 49 additions & 0 deletions specification/APPENDIX.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@

:leveloffset: +1

[appendix]
= Properties Reference
:leveloffset: +1
include::PropertiesReference_3dtiles.adoc[]
:leveloffset: -1

[appendix]
= JSON Schema reference
:leveloffset: +1
include::PropertiesReference_3dtiles_schema.adoc[]
:leveloffset: -1

[appendix]
:imagesdir: TileFormats/glTF
include::TileFormats/glTF/MIGRATION.adoc[]

[appendix]
:imagesdir: ImplicitTiling
include::ImplicitTiling/AVAILABILITY.adoc[]

[appendix]
:imagesdir: Metadata/ReferenceImplementation
include::Metadata/ReferenceImplementation/README.adoc[]

:leveloffset: +1

:imagesdir: Metadata/ReferenceImplementation/PropertyTable
include::Metadata/ReferenceImplementation/PropertyTable/README.adoc[]

:imagesdir: Metadata/ReferenceImplementation/Schema
include::Metadata/ReferenceImplementation/Schema/README.adoc[]

:leveloffset: -1

[appendix]
:imagesdir: Metadata/Semantics
include::Metadata/Semantics/README.adoc[]

[appendix]
include::ACKNOWLEDGEMENTS.adoc[]

[appendix]
include::LICENSE.adoc[]


:leveloffset: -1
110 changes: 110 additions & 0 deletions specification/BUILDING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<!-- omit in toc -->
javagl marked this conversation as resolved.
Show resolved Hide resolved
javagl marked this conversation as resolved.
Show resolved Hide resolved
# Build instructions

- [Building the specification](#building-the-specification)
- [Asciidoctor setup](#asciidoctor-setup)
- [Generating HTML and PDF with AsciiDoc](#generating-html-and-pdf-with-asciidoc)
- [Compressing the PDF](#compressing-the-pdf)
- [A note about section IDs](#a-note-about-section-ids)
- [Cross-linking between files](#cross-linking-between-files)

## Building the specification

The following is a short summary of the basic process for generating a single HTML- or PDF file containing the whole specification.

> Note: This process might be extended in the future, with details about how [wetzel](https://github.com/CesiumGS/wetzel) is used to generate the property reference. Depending on the exact process, the required toolchain might be summarized in a Docker container, similar to [Vulkan](https://github.com/KhronosGroup/Vulkan-Docs/blob/15d807ce4839d8feb523ca5c133a42a2aa448ade/BUILD.adoc), and controlled via a Makefile.

### Asciidoctor setup

- Install the Ruby interpreter, 2.3 or later, from http://www.ruby-lang.org/
- Install Asciidoctor: `gem install asciidoctor`
- In order to be able to generate PDF output: `gem install asciidoctor-pdf`
- Install some rogue software: `gem install rouge` - no worries, that's the syntax highlighter...

- A VSCode plugin for AsciiDoc syntax highlighting and preview: https://marketplace.visualstudio.com/items?itemName=asciidoctor.asciidoctor-vscode

### Generating HTML and PDF with AsciiDoc

- Generating HTML:
- `asciidoctor --verbose Specification.adoc --out-file Specification-1.1.0.html`
- Generating PDF:
- `asciidoctor-pdf --verbose --trace --attribute scripts=cjk --attribute pdf-theme=default-with-fallback-font Specification.adoc --out-file Specification-1.1.0.pdf`

> Note: The last call is derived from https://asciidoctor.org/docs/asciidoctor-pdf/#support-for-non-latin-languages and handles Japanese characters. Without them, the call could just be `asciidoctor -r asciidoctor-pdf -b pdf Specification.adoc -o Specification-1.1.0.pdf`

<sup>If the call does not appear to do anything, neither generate a PDF nor print an error message, make sure you typed `asciidoctor` and not just `asciidoc`</sup>


### Compressing the PDF

By default, the PDF file is large, due to the large image files being inserted uncompressed. There are tools for compressing the PDF, including a dedicated `asciidoctor-pdf-optimize` tool, but they have caveats.
javagl marked this conversation as resolved.
Show resolved Hide resolved

The process that worked for me:

- Download GhostScript **not later than 9.20** from https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/tag/gs920
- This is the latest version that did not contain the so-called ""bugfix"" from https://bugs.ghostscript.com/show_bug.cgi?id=699830 that apparently caused more harm than good.

- Run the following command:
```
"C:\Program Files\gs\gs9.20\bin\gswin64.exe" ^
-dPrinted=false ^
-sDEVICE=pdfwrite ^
-dCompatibilityLevel=1.4 ^
-dPDFSETTINGS=/screen ^
-dNOPAUSE ^
-dBATCH ^
-dDetectDuplicateImages ^
-sOutputFile=Specification-1.1.0-compressed.pdf ^
Specification-1.1.0.pdf
```
(This is a Windows .BAT file. On Linux, replace the `^` with `\`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My notes on the build process on Linux:

  • I had to build Ghostscript from source since I couldn't find precompiled Linux binaries. I downloaded ghostscript-9.20-linux-x86_64.tgz, ran ./configure, then make, and that created bin/gs.
  • Have you seen this warning? I'm not sure which character it's refering to.
~/Code/3d-tiles/specification$ asciidoctor-pdf --verbose --trace --attribute scripts=cjk --attribute pdf-theme=default-with-fallback-font Specification.adoc --out-file Specification-1.1.0.pdf
asciidoctor: WARNING: Could not locate the character `⁣' (\u2063) in the following fonts: Noto Serif, M+ 1p Fallback, Noto Emoji

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw that warning, and tried to figure out where it came from, but my friggin Windows console just displayed this as "�" and did not include the info that it was \u2063, so I couldn't properly search for this. I'll take a note for that as well, the Unicode code may be helpful to figure out what this actually is... "Invisible Separator" for now, but I'll have a look...


The main tweaking takes place via the `screen` setting, which can alternatively be `ebook`, `printer`, or `prepress` for higher resolutions.


## A note about section IDs

The automatic naming for `#anchors` based on section titles is different for Markdown and AsciiDoc. While the latter _can_ be configured to some extent, this would still cause problems when generating a single HTML document. While an anchor may be something like `#overview` _locally_ (in the single `.adoc` file viewn on GitHub), the name may be `#overview_7` when creating a single HTML document. Therefore, unique identifiers for the sections have been inserted. These identifiers follow the pattern

_`<directoryName>`_ `-` _`<markdownAnchor>`_

where `directoryName` is the full directory name in lowercase (with subdirectories separated by `-`), and `markdownAnchor` is the section title as a markdown anchor. For example, the section

`./Metadata/ReferenceImplementation/README.md -> == Overview`

received the ID

`[#metadata-referenceimplementation-overview]`


## Cross-linking between files

Two `adoc` files that are contained in sibling directories cannot trivially link to each other. When there are two files

\ImplicitTiling\README.adoc
\Matadata\README.adoc

and they should link to each other, then it is not possible to write

See xref:../Metadata/README.adoc#anchor[Metadata]

in the first one. (See https://github.com/asciidoctor/asciidoctor/issues/650, https://github.com/asciidoctor/asciidoctor/issues/844, https://github.com/asciidoctor/asciidoctor/issues/3136, https://github.com/asciidoctor/asciidoctor/issues/3276 ...)

In order to create links between documents that work in GitHub **and** in the single HTML/PDF file, the following workaround can be used:

1. At the top of the `ImplicitTiling/README.adoc`, insert this:

```
ifdef::env-github[]
:url-specification-metadata: ../Metadata/
endif::[]
ifndef::env-github[]
:url-specification-metadata:
endif::[]
```

2. Then, use the following pattern for links:

`See xref:{url-specification-metadata}README.adoc#anchor[An example]`

This will cause the _relative_ link to be used when the file is viewn on GitHub, and the "unqualified" link to be used inside the single HTML/PDF document.
158 changes: 158 additions & 0 deletions specification/ImplicitTiling/AVAILABILITY.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
[#implicittiling-availability-indexing]
= Availability Indexing

[#implicittiling-converting-from-tile-coordinates-to-morton-index]
[discrete]
== Converting from Tile Coordinates to Morton Index

A https://en.wikipedia.org/wiki/Z-order_curve[Morton index] is computed by interleaving the bits of the `(x, y)` or `(x, y, z)` coordinates of a tile. Specifically:

----
quadtreeMortonIndex = interleaveBits(x, y)
octreeMortonIndex = interleaveBits(x, y, z)
----

For example:

----
// Quadtree
interleaveBits(0b11, 0b00) = 0b0101
interleaveBits(0b1010, 0b0011) = 0b01001110
interleaveBits(0b0110, 0b0101) = 0b00110110

// Octree
interleaveBits(0b001, 0b010, 0b100) = 0b100010001
interleaveBits(0b111, 0b000, 0b111) = 0b101101101
----

.An example for the computation of the Morton index based on the tile coordinates on three levels of a quadtree
image::figures/morton-indexing.png[Morton Order]



[#implicittiling-availability-bitstream-lengths]
[discrete]
== Availability Bitstream Lengths

[cols="~,~,30%"]
|===
| Availability Type | Length (bits) | Description

| Tile availability
| `+(N^subtreeLevels - 1)/(N - 1)+`
| Total number of nodes in the subtree

| Content availability
| `+(N^subtreeLevels - 1)/(N - 1)+`
| Since there is at most one content per tile, this is the same length as tile availability

| Child subtree availability
| `+N^subtreeLevels+`
| Number of nodes one level deeper than the deepest level of the subtree
|===

Where `N` is 4 for quadtrees and 8 for octrees.

These lengths are in number of bits in a bitstream. To compute the length of the bitstream in bytes, the following formula is used:

----
lengthBytes = ceil(lengthBits / 8)
----



[#implicittiling-accessing-availability-bits]
[discrete]
== Accessing Availability Bits

For tile availability and content availability, the Morton index only determines the ordering within a single level of the subtree. Since the availability bitstream stores bits for every level of the subtree, a level offset must be computed.

Given the `(level, mortonIndex)` of a tile relative to the subtree root, the index of the corresponding bit can be computed with the following formulas:

[cols="~,~,30%"]
|===
| Quantity | Formula | Description

| `levelOffset`
| `+(N^level - 1) / (N - 1)+`
| This is the number of nodes at levels `+1, 2, ... (level - 1)+`

| `tileAvailabilityIndex`
| `levelOffset + mortonIndex`
| The index into the buffer view is the offset for the tile's level plus the morton index for the tile
|===

Where `N` is 4 for quadtrees and 8 for octrees.

Since child subtree availability stores bits for a single level, no levelOffset is needed, i.e. `childSubtreeAvailabilityIndex = mortonIndex`, where the `mortonIndex` is the Morton
index of the desired child subtree relative to the root of the current subtree.



[#implicittiling-global-and-local-tile-coordinates]
[discrete]
== Global and Local Tile Coordinates

When working with tile coordinates, it is important to consider which tile the coordinates are relative to. There are two main types used in implicit tiling:

* *global coordinates* - coordinates relative to the implicit root tile.
* *local coordinates* - coordinates relative to the root of a specific subtree.

Global coordinates are used for locating any tile in the entire implicit tileset. For example, template URIs use global coordinates to locate content files and subtrees. Meanwhile, local coordinates are used for locating data within a single subtree file.

In binary, a tile's global Morton index is the complete path from the implicit root tile to the tile. This is the concatenation of the path from the implicit root tile to the subtree root tile, followed by the path from the subtree root tile to the tile. This can be expressed with the following equation:

----
tile.globalMortonIndex = concatBits(subtreeRoot.globalMortonIndex, tile.localMortonIndex)
----

.Illustration of how to compute the global Morton index of a tile, from the global Morton index of the root of the containing subtree, and the local Morton index of the tile in this subtree
image::figures/global-to-local-morton.png[,500]

Similarly, the global level of a tile is the length of the path from the implicit root tile to the tile. This is the sum of the subtree root tile's global level and the tile's local level relative to the subtree root tile:

----
tile.globalLevel = subtreeRoot.globalLevel + tile.localLevel
----

.Illustration of how to compute the global level of a tile, from the glonal level of the root of the containing subtree, and the local level of the tile in this subtree
image::figures/global-to-local-levels.png[,500]

`(x, y, z)` coordinates follow the same pattern as Morton indices. The only difference is that the concatenation of bits happens component-wise. That is:

----
tile.globalX = concatBits(subtreeRoot.globalX, tile.localX)
tile.globalY = concatBits(subtreeRoot.globalY, tile.localY)

// Octrees only
tile.globalZ = concatBits(subtreeRoot.globalZ, tile.localZ)
----

.Illustration of the computation of the global tile coordinates, from the global coordinates of the containing subtree, and the local coordinates of the tile in this subtree.
image::figures/global-to-local-xy.png[Global to local XY coordinates]



[#implicittiling-finding-parent-and-child-tiles]
[discrete]
== Finding Parent and Child Tiles

The coordinates of a parent or child tile can also be computed with bitwise operations on the Morton index. The following formulas apply for both local and global coordinates.

----
childTile.level = parentTile.level + 1
childTile.mortonIndex = concatBits(parentTile.mortonIndex, childIndex)
childTile.x = concatBits(parentTile.x, childX)
childTile.y = concatBits(parentTile.y, childY)

// Octrees only
childTile.z = concatBits(parentTile.z, childZ)
----

Where:

* `childIndex` is an integer in the range `[0, N)` that is the index of the child tile relative to the parent.
* `childX`, `childY`, and `childZ` are single bits that represent which half of the parent's bounding volume the child is in in each direction.

.Illustration of the computation of the coordinates of parent- and child tiles
image::figures/parent-and-child-coordinates.png[Parent and child coordinates]
Loading