%% Part of Stellarium User Guide 0.15+
%% History:
%% 2016-04-12 adapted from Scenery3D plugin documentation. Just reformatted.
%% Doc should be edited in here from now on. 
%% 2017-12-09 update about performance after playing with big models. Added section about temporally changing material.
%% 2019-10-11 added current references
%% !!!!!!!!!! Please ask GZ before editing this file. !!!!!!!!!!!!!!!

\chapter{Scenery3d -- 3D Landscapes}
\label{ch:scenery3d}
\chapterauthor*{Georg Zotti and Florian Schaukowitsch}


\section{Introduction}
\label{sec:scenery3d:Introduction}


Have you ever wished to be able to walk through Stonehenge or other
ancient building structures described as being constructed with
astronomical orientation in mind, and experience such orientation in a
3D virtual environment that also provides a good sky simulation?

The Stellarium Scenery3d plugin allows you to see architectural 3D models
embedded in a landscape combined with the excellent representation of the sky
provided by Stellarium. You can walk around, check for (or
demonstrate) possible astronomical alignments of ancient architecture, see
sundials and other shadow casters in action, etc.

\section{Usage}
\label{sec:scenery3d:Usage}


You activate the plugin with the \emph{circular enclosure} button \guibutton{0.6}{bt_scenery3d_off.png} at screen
bottom or by pressing \key{\ctrl+W}. A right-click on that button \newFeature{0.21.2} (or \key{\ctrl+\shift+W})
opens the settings dialog. Once loaded and
displaying, you can walk around pressing \key{\ctrl} plus cursor keys. Change eye
height with \key{\ctrl+Page\,\arrowkeyup\,}/\key{\ctrl + Page\,\arrowkeydown\,} keys. Adding \key{\shift} key increases speed by 10,
adding \key{\Alt} multiplies by 5 (pressing both keys multiplies by 50!). If you release \key{\ctrl} before
the cursor key, animation will continue. (Press \key{\ctrl}+any cursor key to stop
moving.)
%\footnote{I (GZ) had to change keyboard handling in the main program, somewhat breaking the plugin concept.}

Further key bindings exist which can be configured using the Stellarium default
key-binding interface. Some options are also available in the Scenery3d dialog.
For example, coordinate display can be enabled with \key{\ctrl+R}+\key{T}. If your models are georeferenced
in a true geographical coordinate grid, e.g.\ UTM or Gauss-Krueger, you will
especially like this, and this makes the plugin usable for scientific purposes.
Display shows grid name, Easting, Northing, Altitude of ground, and eye height
above ground.

Other features include a virtual ``torchlight'', which can be enabled with \key{\ctrl+R}+\key{L} to give
additional local illumination around the viewer to help to see in the dark.
Interesting points of view can be saved and restored later by the user,
including a description of the view. Scene authors can also distribute
predefined viewpoints in their scene.

The plugin also simulates the shadows of the scene's objects cast by
the Sun, Moon and even Venus (only 1 shadow caster used at a time, you
will never see shadows cast by Venus in moonlight), so you could use
it for examining sundials, or analyze and simulate light-and-shadow
interactions in archaeological structures.

Sometimes, \newFeature{23.2} light patches cast through small holes are important, e.g., 
in churches with \emph{meridiana} ``sundial/calendar'' lines. If these patches 
appear too dim, you can increase the power of the directional light using the 
\menu{Directional light enhancement} switch. (Use value 1.0 to revert to normal.) 

\section{Hardware Requirements \& Performance}
\label{sec:scenery3d:HardwareRequirements}

In order to work with the non-linear projection models in Stellarium,
this plugin uses a trick to create the foreground renderings: it
renders the scene into the six planes of a so-called cubemap, which is
then correctly reprojected onto the sides of a cube, depending on the
current projection settings. Your graphics card must be able to do
this, i.e. it must support the OpenGL extension called
\texttt{EXT\_framebuffer\_object}. Typical modern 3D cards (by Nvidia
or ATI/AMD) support this extension. In case your graphics hardware
does not support it, the plugin will still work, but you are limited
to perspective projection.

You can influence rendering quality, but also speed, using the plugin's 
GUI, which provides some options such as enabling the use
of shadows, bumpmapping (provides more realistic surface lighting) or 
configuring the sizes of the textures used
for the cubemap or shadowmaps. Larger values there improve the quality,
but require faster hardware and more video memory for smooth results.

Because the ``cubemap trick'' requires quite a large amount of performance (in
essence, the scene has to be rendered 6 times), there are some options available
that try to reduce this burden. The first option is to change the type of the
``cubemap''. The most compatible setting is \emph{6 textures}, which seems to
work best on older integrated Intel GPUs. The recommended default is the second
setting, \emph{Cubemap}, which uses a more modern OpenGL feature and generally
works a bit faster than \emph{6 textures} on more modern graphics cards. Finally,
the \emph{Geometry shader} option tries to render all 6 cube faces at once. This
requires a more recent GPU + drivers (at least OpenGL 3.2 must be supported),
the setting is disabled otherwise. Depending on your hardware and the scene's
complexity, this method may give a speedup or may be slower, you must find this out yourself.

Another option prevents re-rendering of the cubemap if nothing relevant has
changed. You can define the interval (in Stellarium's simulation time) in which
nothing is updated in the GUI. You can still rotate the camera without causing a
re-draw, giving a subjective performance that is close to Stellarium's
performance without Scenery3d. When moving, the cubemap will be updated. You can
enable another option that only causes 1 or 2 sides of the cubemap to be updated
while you move, giving a speedup but causing some parts of the image to be
outdated and discontinuous. The cubemap will be completed again when you stop
moving.

Shadow rendering may also cause quite a performance impact. The \emph{Simple
shadows} option can speed this up a lot, at the cost of shadow quality
especially in larger scenes. Another performance/quality factor is shadow
filtering. The sharpest (and fastest) possible shadows are achieved with
filtering \emph{Off}, but depending on shadowmap resolution and scene size the
shadows may look quite ``blocky''. \emph{Hardware} shadow filtering is usually
very fast, but may not improve appearance a lot. Therefore, there are additional
filter options available, the \emph{High} filter option is relatively expensive.
Finally, the \emph{PCSS} option allows to approximate the increase of solar and lunar shadow
penumbras relative to the distance from their shadow casters, i.e. shadows are
sharp near contact points, and more blurred further away. This again requires
quite a bit of performance, and only works if the shadow filter option is set to
\emph{Low} or \emph{High} (without \emph{Hardware}).

The configuration GUI shows tooltips for most of its settings, which can explain
what a setting does. All settings are saved automatically, and restored when you
reopen Stellarium.


\subsection{Performance notes}
\label{sec:scenery3d:Performance}

This plugin clearly runs better with proper 3D graphics cards. 
On reasonably good hardware 
%2012: (tested on a notebook PC with Nvidia M9800 GTS), 
% models up to 100.000 triangles are fluent, up to 250.000 are still ``interactive''.  
% we have 2015, and a much faster implementation!
%%(tested on a notebook PC with Nvidia M580 GTS), models with about 850.000 triangles 
%% Latest benchmark...
(tested on a notebook PC with Nvidia M960), models with over 10.000.000 triangles 
%%
are working nicely with shadows and bumpmaps, although your mileage may vary.  On very small
hardware like single-board computers with native OpenGL ES2, models
may be limited to 64k vertices (points).  If display is too slow,
switch to perspective projection: all other projections require almost
sixfold effort!  Or try the ``lazy'' cubemap mode and lazy updates of tiles, 
where the scene is only rendered in specific timesteps or
when movement happens.  


\section{Model Configuration}
\label{sec:scenery3d:ModelConfiguration}

The model format supported in Scenery3d is Wavefront .OBJ, which is
pretty common for 3D models.  You can use several modeling programs to
build your models. Software such as \program{Blender}, \program{Maya}, \program{3D Studio
Max} etc.\ can export OBJ. 

\subsection{Exporting OBJ from Sketchup}
\label{sec:scenery3d:sketchup}

A simple to use and cost-free modeling program is \program{Sketchup}, commonly
used to create the 3D buildings seen in \program{Google Earth}. It can be used
to create georeferenced models.  OBJ is not a native export format for
the standard version of \program{Sketchup}. If you are not willing to
afford \program{Sketchup Pro}, you have to find another way to export a textured
OBJ model.


\begin{table}[t]
  \centering
\begin{tabular}{rl}\toprule
Geometry&Yes\\Lights&Yes\\Clay&No\\Photomatched&Yes\\DefaultUVs&No\\Instanced&No\\\bottomrule
\end{tabular}
\caption{Kerkythea Export Settings}
  \label{fig:scenery3d:KerkytheaExportSettings}
\end{table}

One good exporter is available in the \program{Kerkythea} renderer project\footnote{
Available at \url{http://www.kerkythea.net/cms/}}.  You need
\program{SU2KT~3.17}
or better, and \program{KT2OBJ~1.1.0} or better.  Deselect any selection, then
export your model to the \program{Kerkythea} XML format with settings shown in
\ref{fig:scenery3d:KerkytheaExportSettings}.
(Or, with selection enabled, make sure settings are No-Yes-Yes-No-Yes-No-No.)  
You do not have to launch \program{Kerkythea} unless you want to create nice renderings of
your model. 
Then, use the \program{KT2OBJ} converter to create an OBJ.  You can delete the
XML after the conversion.  Note that some texture coordinates may not be
exported correctly. The setting \texttt{Photomatched:Yes} seems now to have
corrected this issue, esp. with distorted/manu\-ally shifted textures.

Another free OBJ exporter has been made available by 
TIG: \file{OBJexporter.rb}\footnote{Available from
\url{http://forums.sketchucation.com/viewtopic.php?f=323&t=33448}}. 
This is the only OBJ exporter tested so far capable of handling large TIN landscapes
($>450.000$ triangles). 
As of version 2.6 it seems to be the best OBJ exporter available for \program{Sketchup}. 

%As of version 1.6 it appears to have valid texture coordinates, but I have
%experienced problems with black faces which need more
%investigation. Maybe you can combine two OBJ files with another 3D
%editor after creating individual OBJs if this is a problem. 

This exporter swaps Y/Z coordinates, but you can add a key to the config file to
correct swapped axes, see below. Other exporters may also provide coordinates in
any order of X, Y, Z -- all those can be properly configured.

Another quirk has to be fixed manually though: in the material description file (MTL), TIG's exporter writes both \texttt{d} and \texttt{Tr} lines with the same value.
Actually, $\mathtt{Tr}=1.0-\mathtt{d}$ according to OBJ/MTL documentation, so you should edit away one line, or else the later line overwrites the value given earlier. 
Moreover, given that \texttt{Tr=1} should actually specify fully transparent objects, such a line will make your object entirely invisible!

Another (almost) working alternative: \file{ObjExporter.rb} by author
Honing.  Here, export with settings \texttt{0xxx00}. This will not create a
\file{TX...} folder but dump all textures in the same directory as the OBJ
and MTL files. Unfortunately, currently some material assignments seem to be
bad.

%Yet another exporter, \file{su2objmtl}, does also not provide good texture
%coordinates and cannot be recommended at this time.

\subsection{Notes on OBJ file format limitations}
\label{sec:scenery3d:OBJlimitations}

The OBJ format supported is only a subset of the full OBJ format: Only
(optionally textured) triangle meshes are supported, i.e., only lines containing
statements: \parameter{mtllib}, \parameter{usemtl}, \parameter{v}, \parameter{vn}, \parameter{vt}, \parameter{f}
(with three elements only!), \parameter{g}. Negative vertex numbers (i.e., a
specification of relative positions) are not supported.

A further recommendation for correct illumination is that all vertices should
have vertex normals. \program{Sketchup} models exported with the \program{Kerkythea} or TIG plugins
should have correct normals. If your model does not provide them, default
normals can be reconstructed from the triangle edges, resulting in a faceted
look.

If possible, the model should also be triangulated, but the current loader may
also work with non-triangle geometry. 
%% TODO: GZ: Does that mean Quads, or higher-level polygons? 
The correct use of objects (\parameter{o}) and groups (\parameter{g})
will improve performance: it is best if you pre-combine all objects
that use the same material into a single one. The loader will try to
optimize it anyways if this is not the case, but can do this only
partly (to combine 2 objects with the same material into 1, it
requires them to follow directly after each other in the OBJ). A
simple guide to use
\program{Blender}\footnote{\url{https://www.blender.org}} for this task
follows:

\begin{enumerate}
\item \menu{File>Import>Wavefront .obj} - you may need to change the forward/up axes for correct orientation, try ``-Y forward'' and ``Z up''
\item Select an object which has a shared material
\item Press \key{\shift+L} and select 'By Material'
\item Select 'Join' in the left (main) tool window
\item Repeat for other objects that have shared materials
\item Export the .obj, making sure to select the same forward/up axes as in the import, also make sure ``Write Normals'', ``Write Materials'' and ``Include UVs'' are checked
\end{enumerate}

\noindent For transparent objects (with a \parameter{d} or \parameter{Tr} value, alpha testing does
NOT need this), this recommendation does NOT hold: for optimal
results, each separate transparent object should be exported as a
separate ``OBJ object''. This is because they need to be sorted during
rendering to achieve correct transparency. If the objects are combined
already, you can separate them using \program{Blender}:

\begin{enumerate}
\item Import .obj (see above)
\item Select the combined transparent object
\item Enter ``Edit'' mode with \key{\tab} and make sure everything is selected (press \key{A} if not)
\item Press \key{P} and select ``By loose parts'', this should separate the object into its unconnected regions
\item Export .obj (see above), also check ``Objects as OBJ Objects''
\end{enumerate}

\begin{table}[tb]
\footnotesize
\begin{tabular}{llll}
\toprule
\emph{Parameter}  &\emph{Default} &\emph{Range}    & \emph{Meaning}\\
\midrule
\parameter{Ka}            &set to \parameter{Kd} values & $0\dots1$ each& R/G/B Ambient color\\
\parameter{Kd}            &0.8 0.8 0.8  & $0\dots1$ each & R/G/B Diffuse color\\
\parameter{Ke}            &0.0 0.0 0.0  & $0\dots1$ each & R/G/B Emissive color\\
\parameter{Ks}            &0.0 0.0 0.0  & $0\dots1$ each & R/G/B Specular color\\
\parameter{Ns}            &8.0          & $0\dots\infty$ & shinyness \\
\parameter{d} or \parameter{Tr} &1.0          & $0\dots1$      & opacity \\
\parameter{bAlphatest}    &0            & 0 or 1         & perform alpha test \\
\parameter{bBackface}     &0            & 0 or 1         & render backface \\
\parameter{map\_Kd}       & (none)      & filename       & texture map to be mixed with Ka, Kd \\
\parameter{map\_Ke}       & (none)      & filename       & texture map to be mixed with Ke \\
\parameter{map\_bump}     & (none)      & filename       & normal map for surface roughness\\  
\parameter{illum}         & 2           & integer        & illumination mode in the standard MTL format. \\
\parameter{vis\_fadeIn}   & (none)      & double         & see \ref{sec:scenery3d:Beyond3D}\\
\parameter{vis\_fadeOut}  & (none)      & double         & see \ref{sec:scenery3d:Beyond3D}\\
\bottomrule
\end{tabular}
\caption{MTL parameters evaluated}
\label{tab:scenery3d:MTL}
\end{table}

\noindent The MTL file specified by \parameter{mtllib} contains the material parameters. The
minimum that should be specified is either \parameter{map\_Kd} or a \parameter{Kd} line
specifying color values used for the respective faces. But there are other
options in MTL files, and the supported parameters and defaults are listed in
Table~\ref{tab:scenery3d:MTL}.

If no ambient color is specified, the diffuse color values are taken for the
ambient color. An optional emissive term \parameter{Ke} can be added, which is
modulated to only be visible during nighttime. This also requires the
landscape's self-illumination layer to be enabled. It allows to model
self-illuminating objects such as street lights, windows etc. It can optionally
also be modulated by the emissive texture \parameter{map\_Ke}.

If a value for \parameter{Ks} is specified, specularity is evaluated
using the Phong reflection
model\footnote{\url{https://en.wikipedia.org/wiki/Phong_reflection_model}}
with \parameter{Ns} as the exponential shininess constant. Larger
shininess means smaller specular highlights (more metal-like
appearance). Specularity is not modulated by the texture
maps. Unfortunately, some 3D editors export unusable default value
combinations for \parameter{Ks} and \parameter{Ns}. \program{Blender}
may create lines with \parameter{Ks}=1/1/1 and \parameter{Ns}=0. This
creates a look of ``partial overexposed snow fields''. While the
values are allowed in the specification, in most cases the result
looks ugly. \emph{Make sure to set \parameter{Ns} to 1 or higher, or
  disable those two lines.}

If a value for \parameter{d} or \parameter{Tr} exists, alpha blending is enabled for this
material. This simulates transparency effects. Transparency can be further
controlled using the alpha channel of the \parameter{map\_Kd} texture.

A simpler and usually more performant way to achieve simple ``cutout''
transparency effects is alpha-testing, by setting \parameter{bAlphatest} to 1. This
simply discards all pixels of the model where the alpha value of the
\parameter{map\_Kd} is below the \parameter{transparency\_threshold} value from
\file{scenery3d.ini}, making ``holes'' in the model. This also produces
better shadows for such objects. If required, alpha testing can be combined with
``real'' blending-based transparency.

Sometimes, exported objects only have a single side (``paper wall''), and are only visible
from one side when looked at in Scenery3d. This is caused by an optimization
called \emph{back-face culling}\footnote{\url{https://en.wikipedia.org/wiki/Back-face_culling}},
which skips drawing the back sides of objects because they are usually
not visible anyway. If possible, avoid such ``thin'' geometry, this will also
produce better shadows on the object. As a workaround, you can also set
\parameter{bBackface} to 1 to disable back-face culling for this material.

The optional \parameter{map\_bump} enables the use of a tangent-space
normal
maps\footnote{\url{https://en.wikipedia.org/wiki/Normal_mapping}},
which provides a dramatic improvement in surface detail under
illumination.

\subsection{Configuring OBJ for Scenery3d}
\label{sec:scenery3d:Configuring}

The walkaround in your scene can use a ground level (piece of terrain)
on which the observer can walk. The observer eye will always stay ``eye
height'' above ground. Currently, there is no collision detection with
walls implemented, so you can easily walk through walls, or jump on
high towers, if their platform or roof is exported in the ground
layer. If your model has no explicit ground layer, walk will be on the
highest surface of the scenery layer.  If you use the special name
\parameter{NULL} as ground layer, walk will be above \parameter{zero\_ground\_height} level.

Technically, if your model has cavities or doors, you should export
your model twice. Once, just the ground plane, i.e. where you will
walk. Of course, for a temple or other building, this includes its
socket above soil, and any steps, but pillars should not be included.  
This plane is required to compute
eye position above ground. Note that it is not possible to walk in
several floors of a building, or in a multi-plane staircase. You may
have to export several ``ground'' planes and configure several scenery
directories for those rare cases. For optimal performance, the ground 
model should consist of as few triangles as you can tolerate.

The second export includes all visible model parts, and will be used for
rendering. Of course, this requires the ground plane again, but also
all building elements, walls, roofs, etc. 

If you have not done so by yourself, it is recommended to separate
ground and buildings into Sketchup layers 
(or similar concepts in whichever editor you are using) 
in order to easily switch the model to the right state prior to exporting.

Filename recommendations: 

\noindent%
\begin{tabularx}{\textwidth}{lX} 
\file{<Temple>.skp}         &Name of a Sketchup Model file. 
                             (The \file{<>} brackets signal ``use your own name here!'')
                             The SKP file is not used by Scenery3d, but you may want
                             to leave it in the folder for later improvements.\\
\file{<Temple>.obj}         &Model in OBJ format. \\
\file{<Temple>\_ground.obj} &Ground layer, if different from Model file. 
\end{tabularx}

\noindent OBJ export may also create folders \file{TX\_<Temple>} and
\file{TX\_<Temple>\_ground}. You can delete the \file{TX\_<Temple>\_ground} folder, 
\file{<Temple>\_ground.obj} is just used to compute vertical height.

%Stellarium uses a directory to store additional data per-user. On Windows, this
%defaults to \verb|C:\Documents and Settings\<username>\Application Data\Stellarium|, 
%but you can use another directory by using the command-line
%argument \parameter{--user-dir <USERDATA>}.  We will refer to this directory. 

Put the
OBJ, MTL and TX directories into a subdirectory of your user directory (see section~\ref{sec:Directories}), e.g.\ 
\file{<USERDATA>/Stellarium/scenery3d/<Temple>}, and add a text file into it 
called \file{scenery3d.ini} (This name is mandatory!) with content described as
follows.

% A Sketchup plugin "Write scenery3d.ini for Stellarium" will write this
% file. Locate the directory where the .obj file(s) reside(s), and store
% scenery3d.ini there. If you have other modelers and models, or if your
% model is not georeferenced in Sketchup, write the file yourself and
% use the following format.
%
% TBD GZ: Release this Sketchup export plugin?

\noindent%
\begin{tabularx}{\textwidth}{lX} 
\texttt{[model]}&\\
\texttt{name=<Temple>}&      Unique ID within all models in scenery3d directory.
                             Recommendation: use directory name.\\
\texttt{landscape=<landscapename>}& Name of an available Stellarium landscape.
\end{tabularx}

\noindent This is required if the landscape file includes geographical
coordinates and your model does not: First, the location coordinates
of the \file{landscape.ini} file are used, then location coordinates given here.
The landscape also provides the background image of your scenery. If
you want a zero-height (mathematical) horizon, use the provided
landscape called \file{Zero Horizon}.

\noindent%
\begin{tabularx}{\textwidth}{lX} 
\texttt{scenery=<Temple>.obj}         &The complete model, including visible ground.\\
\texttt{ground=<Temple>\_ground.obj}  &Optional: separate ground plane. (NULL for zero altitude.)\\
\texttt{description=<Description>}    &A basic scene description (including HTML tags)
\end{tabularx}

\noindent The \file{scenery3d.ini} may contain a simple scene description, but it is
recommended to use the \emph{localizable} description format: in the scene's
directory (which contains \file{scenery3d.ini}) create files in the format
\file{description.<lang>.utf8} which can contain arbitrary
UTF-8--encoded HTML content. \parameter{<lang>} stands for the ISO~639
language code.

\noindent%
\begin{longtable}{lp{92mm}} 
\multicolumn{2}{l}{\texttt{author=<Your Name yourname@yourplace.com>}}\\
\multicolumn{2}{l}{\texttt{copyright=<Copyright Info>}}\\
\texttt{obj\_order=XYZ}      & Use this if you have used an exporter which swaps Y/Z coordinates. 
                               Defaults to \texttt{XYZ}, other options: \texttt{XZY}, \texttt{YZX}, \texttt{YXZ}, \texttt{ZXY}, \texttt{ZYX}\\
\texttt{camNearZ=0.3}        & This defines the distance of the camera near plane, default 0.3.
                               Everything closer than this value to the camera can not be 
                               displayed. Must be larger than zero. It may seem tempting 
                               to set this very small, but this will lead to accuracy issues. 
                               Recommendation is not to go under 0.1\\
\texttt{camFarZ=10000}       & Defines the maximal viewing distance, default 10000.\\
\texttt{shadowDistance=<val>}& The maximal distance shadows are displayed. If left out, the
                               value from \texttt{camFarZ} is used here. If this is set to a smaller
                               value, this may increase the quality of the shadows that are
                               still visible.\\
\texttt{shadowSplitWeight=0..1}& Decimal value for further shadow tweaking. If you require
                                 better shadows up close, try setting this to higher values.
                                 The default is calculated using a heuristic that incorporates
                                 scene size.\\
\texttt{[general]}&\\
\end{longtable}

\noindent The general section defines some further import/rendering options.
% GZ TBD: Why do we need ground normals? 


\noindent%
\begin{tabularx}{\textwidth}{lX} 
\texttt{transparency\_threshold=0.5}  &Defines the alpha threshold for alpha-testing, as described in section~\ref{sec:scenery3d:OBJlimitations}. Default \texttt{0.5}\\
\texttt{scenery\_generate\_normals=0} &Boolean, if true normals are recalculated by the plugin, instead of imported. Default \texttt{false}\\
\texttt{ground\_generate\_normals=0}  &Boolean, same as above, for ground model. Default \texttt{false}.\\
\texttt{[location]}                   &
\end{tabularx}

\noindent Optional section to specify geographic longitude $\lambda$, latitude $\varphi$,
and altitude. The section is required if \verb:coord/convergence_angle={from_grid|from_utm}:, else
location is inherited from landscape.

\noindent%
\begin{tabularx}{\textwidth}{lX} 
\multicolumn{2}{l}{\texttt{planet = Earth}}\\
\texttt{latitude = +48d31'30.4"}      & Required if \texttt{coord/convergence\_angle=from\_\{grid|utm\}}\\
\texttt{longitude = +16d12'25.5"}     & "--"\\
\texttt{altitude =from\_model|<int>}   &  altitude (for astronomical computations) can be computed from the model:  if
                                           \texttt{from\_model}, it is computed as $(z_{min}+z_{max})/2+\mathtt{orig\_H}$, 
                                            i.e.\ from the model bounding box centre height.\\
\multicolumn{2}{l}{\texttt{display\_fog = 0}}\\
\multicolumn{2}{l}{\texttt{atmospheric\_extinction\_coefficient = 0.2}}\\
\multicolumn{2}{l}{\texttt{atmospheric\_temperature = 10.0}}\\
\multicolumn{2}{l}{\texttt{atmospheric\_pressure = -1}}\\
\multicolumn{2}{l}{\texttt{light\_pollution = 1}}\\
\multicolumn{2}{l}{\texttt{[coord]}}\\
\end{tabularx}

\noindent Entries in the \verb|[coord]| section are again optional,
default to zero when not specified, but are required if you want to
display meaningful eye coordinates in your survey (world) coordinate
system, like UTM or Gauss-Kr\"uger.

\begin{longtable}{lp{84mm}} 
\texttt{grid\_name=<string> }& Name of grid coordinates, e.g. \texttt{"UTM 33 U (WGS 84)"},
                               \texttt{"Gauss-Kr\"uger M34"} or \texttt{"Relative to <Center>"} This name is
                              only displayed, there is no evaluation of its contents.\\
\texttt{orig\_E=<double> | (Easting)}  &East-West-distance to zone central meridian\\
\texttt{orig\_N=<double> | (Northing)} &North distance from Equator\\
\texttt{orig\_H=<double> | (Height)}   &Altitude above Mean Sea Level of model origin\\
\end{longtable}

\noindent These entries describe the offset, in metres, of the model coordinates relative
to coordinates in a geographic grid, like Gauss-Kr\"uger or UTM. If you have your model
vertices specified in grid coordinates, do not specify \verb|orig_...| data, but
please definitely add \verb|start_...| data, below.

Note that using grid coordinates without offset for the vertices is
usually a bad idea for real-world applications like surveyed sites in
UTM coordinates. Coordinate values are often very large numbers
(ranging into millions of meters from equator and many thousands from
the zone meridian). If you want to assign millimetre values to model
vertices, you will hit numerical problems with the usual
single-precision floating point arithmetic. Therefore we can specify
this offset which is only necessary for coordinate display.

Typically, digital elevation models and building structures built on
those are survey-grid aligned, so true geographical north for a place
with geographical longitude $\lambda$ and latitude $\varphi$ will in
general not coincide with grid north, the difference is known as
\indexterm{meridian convergence}\footnote{%
  \url{https://en.wikipedia.org/wiki/Transverse_Mercator_projection}} 
and, on a spherical globe, amounts to:
\begin{equation}
\gamma(\lambda, \varphi)=\arctan(\tan(\lambda-\lambda_0)\sin\varphi)
\end{equation}
This amount can be given in \verb|convergence_angle| (degrees), so
that your model will be rotated clockwise by this amount around the
vertical axis to be aligned with True North\footnote{Note that
  Sketchup's \emph{georeferencing dictionary} provides a NorthAngle
  entry, which is $360-\mathtt{convergence\_angle}$.}.

\begin{configfile}
convergence_angle=from_grid|from_utm|<double> 
grid_meridian=<double>|+<int>d<int>'<float>"      
\end{configfile}

\noindent \texttt{grid\_meridian} is the central meridian $\lambda_0$ of the grid
zone, e.g.\ for Gauss-Kr\"uger, and is only required to compute
convergence angle if \texttt{convergence\_angle=from\_grid}. 
If your model coordinates is based on UTM, you can use 
\texttt{coord/convergence\_angle=from\_utm} for a more accurate computation.


\begin{configfile}
zero_ground_height=<double> 
\end{configfile}
height of terrain outside \file{<Temple>\_ground.OBJ}, or if \verb|ground=NULL|.
Allows smooth approach from outside.  This value is relative to the model
origin, or typically close to zero, i.e.,  use a Z value in model coordinates,
not world coordinates! (If you want the terrain height surrounding your model to
be \texttt{orig\_H}, use 0, not the correct mean height above sea level!)  Defaults
to minimum of height of ground level (or model, resp.) bounding box.

\begin{tabularx}{\textwidth}{lX} 
\multicolumn{2}{l}{\texttt{start\_E=<double>}}\\ 
\multicolumn{2}{l}{\texttt{start\_N=<double>}} \\
\texttt{start\_H=<double>}     &only meaningful if \texttt{ground==NULL}, else \texttt{H} is derived from ground \\
\texttt{start\_Eye=<double>}   &default: \texttt{1.65m} \\
\multicolumn{2}{l}{\texttt{start\_az\_alt\_fov=<az\_deg>,<alt\_deg>,<fov\_deg>}}\\
\                                &initial view direction and field of view.\\
\end{tabularx}

\noindent \texttt{start\_...} defines the view position to be set after loading the scenery.
Defaults to center of model boundingbox.

It is advisable to use the grid coordinates of the location of the panoramic
photo (landscape) as \texttt{start\_...} coordinates, or the correct coordinates
and some carefully selected \texttt{start\_az\_alt\_fov} in case you want to highlight 
a certain view corridor (temple axis, \ldots).

In some setups like digital full-dome planetaria \newFeature{23.2}
it is advisable to disable the use of the \texttt{start\_az\_alt\_fov}. 
You can do that in the Scenery3D configuration dialog or by the entry \texttt{ignore\_start\_az\_alt\_fov} in \file{config.ini}.

\subsection{Concatenating OBJ files}
\label{sec:scenery3d:concatenating}

Some automated workflows may involve tiled landscape areas, e.g. to
overcome texture limitations or triangle count limits in simpler tools
like \program{Sketchup}. In this case you can create separate meshes
in the same coordinate system, but you need to concatenate them. One
powerful program to assemble your parts is again \program{Blender}.

In \program{Blender}, import the OBJ files \menu{File>Import>Wavefront
  .obj}. If your OBJ coordinates have Z as vertical axis (common for
terrestrial models), use ``Z up'', ``-Y Forward'' as import settings
for the coordinate axes. The model will appear south-up.

Blender may not show anything except the default cube because of
aggressive camera far plane clipping.  Press \keys{N} and in the
\menu{View} set at least the far clipping plane as required to see the full
extent of your terrain model. Then press \menu{View>View All} (or \keys{Home}).



The landscape may look white now. Switch on textured view if required
(\keys{\Alt+Z}). If the scene looks almost black now, reconfigure the
light to be sunlight: Select the lamp in the outliner graph, press the
lamp icon and in the \menu{Lamp} select ``Sun''. Now the scene should
be in full color, and the Y axis should point towards grid-south.

After importing the first model, you may consider locking it in place
to avoid errors. Select the model in the outliner, select the cube
button below, then open \menu{Transform Locks} and lock all. The other
model parts may have to be transformed, and numerical transformation
can be added in the \menu{Transform} settings in this menu.

If you have created a VRML (WRL) of some structures in \program{ArcScene},
export that without shifting to center, and import the WRL file in
\program{Blender} with default orientation ``Y up'', ``Z
forward''. Models from other sources may still be different.

In the end, all parts should fit neatly together. \program{Blender} is
a very powerful program, you can enhance your model as you wish.

When the model configuration is complete, select all relevant parts
which you want to have visible in Stellarium (click on the lines in
the outline view containing the object names to light them up gray,
then Rightclick-Select, so that the triangle (mesh) icon has a colored
background circle) and press \key{\ctrl+J} to optionally join them,
then export to a single OBJ \menu{File>Export>Wavefront .obj}. In the
export options, apply ``Selection Only'', and ``-Y Forward'' and ``Z
Up''%
\footnote{https://blender.stackexchange.com/questions/3352/merging-multiple-obj-files}.

Verify the new model loads correctly, e.g.\ in \program{Meshlab}\footnote{\url{https://www.meshlab.net/}}!

\subsection{Beyond 3D: Temporally evolving Models}
\label{sec:scenery3d:Beyond3D}

Stellarium \newFeature{0.16.1} working as ``time machine'' can display the sky for any calendar date in its range of valid dates. 
Also landscapes and human-built structures evolve. Temples are being rebuilt, changed, re-dedicated or repurposed, 
new windows are cut, old windows closed. 
To show landscape and buildings in the right shape for the time in question, we can make material transparent, 
so that parts of the model are not displayed.  To allow for archaeological uncertainties in dating 
construction and destruction, we can gradually fade in and fade out the model parts in question \citep{Zotti:SEAC2017}.

To enable this magic, you must combine all your models into one (see section~\ref{sec:scenery3d:concatenating}), 
export as one OBJ/MTL as usual, and manually edit the MTL file. It is wise to give the material 
for the parts in question a reasonable name that you can later identify in the MTL file.
Then you simply add one or both of the new keywords \texttt{vis\_fadeIn} or \texttt{vis\_fadeOut} 
to the material description,  with 2 arguments which are the Julian days of begin and end of a phase transition. 
For sharp transitions, just use the same JD dates.

\begin{configfile}
# Some structure has been put up around -3100/-3000
vis_fadeIn  588783.5 625308.5
# Fade away between 500AD/700AD
vis_fadeOut 1903682.5 1976732.5
\end{configfile}
 

\subsection{Working with non-georeferenced OBJ files}
\label{sec:scenery3d:NonGeoreferenced}


There exists modeling software which produces nice models, but without
concept of georeference. One spectacular example is \program{AutoDesk PhotoFly},
a cloud application which delivers 3D models from a bunch of photos
uploaded via its program interface. This ``technological preview'' is
in version 2 and free of cost as of mid-2011.

The problem with these models is that you cannot assign surveyed
coordinates to points in the model, so either you can georeference the
models in other applications, or you must find the correct
transformation matrix.  Importing the OBJ in \program{Sketchup} may take a long
time for detailed photo-generated models, and the texturing may
suffer, so you can cut the model down to the minimum necessary e.g.\ in
\program{Meshlab}, and import just a stub required to georeference the model in
\program{Sketchup}. 

Now, how would you find the proper orientation? The easiest chance
would be with a structure visible in the photo layer of \program{Google
Earth}. So, start a new model and immediately \menu{add location} from the
\program{Google Earth} interface. Then you can import the OBJ with TIG's importer
plugin.  If the imported model looks perfect, you may just place the
model into the \program{Sketchup} landscape and export a complete landscape just
like above. If not, or if you had to cut/simplify the OBJ to be able
to import it, you can rotate/scale the OBJ (it must be grouped!). If
you see a shadow in the photos, you may want to set the date/time of
the original photos in the scene and verify that the shadows created by
\program{Sketchup} illuminating the model match those in the model's photo
texture. When you are satisfied with placement/orientation, you create
a \file{scenery3d.ini} like above with the command
\menu{Plugins>ASTROSIM/Stellarium scenery3d helpers>Create scenery3d.ini}.

Then, you select the OBJ group, open the \menu{Windows>Ruby Console} and readout data by calling
\menu{Plugins>ASTROSIM/Stellarium scenery3d helpers>Export transformation
of selected group}.

On the Ruby console, you will find a line of numbers (the $4\times4$
transformation matrix) which you copy/paste (all in one line!) into the
\file{[model]} section in \file{scenery3d.ini}.
\begin{configfile}
obj2grid_trafo=<a11>,<a12>,<a13>,<a14>,<a21>,<a22>,<a23>,<a24>,
               <a31>,<a32>,<a33>,<a34>,<a41>,<a42>,<a43>,<a44>
\end{configfile}
You edit the \file{scenery3d.ini} to use your full (unmodified)
\program{PhotoFly} model and, if you don't have a panorama, take \parameter{Zero Horizon}
landscape as (no-)background. It depends on the model if you want to
be able to step on it, or to declare \texttt{ground=NULL} for a
constant-height ground. Run Stellarum once and adjust the
\texttt{start\_N}, \texttt{start\_E} and \texttt{zero\_ground\_height}.

\subsection{Rotating OBJs with recognized survey points}
\label{sec:scenery3d:RotatingOBJ}

If you have survey points measured in a survey grid plus an image-based model
with those points visible, you can use Meshlab to find the model
vertex coordinates in the photo model, and some other program like
\program{CoordTrans} in the \program{JavaGraticule3D} suite to find either the matrix
values to enter in \file{scenery3d.ini} or even rotate the OBJ
points. However, this involves more math than can be described here;
if you came that far, you likely know the required steps.  Here it
really helps if you know how to operate automatic text processors like
\program{AWK}.

\section{Predefined views}
You can also configure and distribute some predefined views with optional date of interest with your
model in a \file{viewpoints.ini} file. The viewpoints can be loaded
and stored with the viewpoint dialog which you can call with the
\guibutton{0.6}{bt_scenery3d_eyepoint_off.png} button. See the provided
``Sterngarten'' scene for an example. These entries are not editable
by the user through the interface. The user can always save his own
views, they will be saved into the file \file{userviews.ini} in the
user's Stellarium user directory, and are editable.

\begin{configfileScr}
[StoredViews]
size=<int>              Defines how many entries are in this file. 
                        Prefix each entry with its index!
1/label=<string>        The name of this entry
1/description=<string>  A description of this entry (can include HTML)
1/position=<x,y,z,h>    The x,y,z grid coordinates 
                        (like orig_* or start_* in scenery3d.ini) 
                        + the current eye height h
1/view_fov=<az_deg,alt_deg,fov_deg>  The view direction + FOV
                                     (like start_az_alt_fov in scenery3d.ini)
; an example for a second entry (note the 2 at the beginning of each line!)
2/label       = Signs
2/description = Two signs that describe the Sterngarten
2/position    = 593155.2421,5333348.6304,325.7295809038,0.8805
2/view_fov    = 84.315399,-8.187078,83.000000
2/JD          = 2451545.5 [optional]
\end{configfileScr}

\section{Example}
\label{sec:scenery3d:example}
Let us add a quick example here. A recent paper~\citep{Pollard:2017:UffingtonHorse} claims that the Uffington White Horse, 
a geoglyph carved into a hillsite in England during the Bronze Age,  may depict the mythical ``Sun Horse'', a common conception of that period.

Unfortunately, as of 2017, the official UK Lidar repository does not include the Uffington area, 
so a detailed GIS-based model is not available. We could use EUdem25 data with aerial imagery, 
or for a quick look, we just use \program{Sketchup}.
Yet another unfortunate development: Trimble declared that after the 5-year transition 
period from Google to Trimble is over in May 2017, terrain modelling will be limited to \program{Sketchup Pro}. 
But note that a fresh installation comes with a 30-day Pro trial time, this should be enough for this example.

First, locate the site in \program{Google Earth} at $\lambda=-1.56718, \varphi=51.582843$. (Or just search for ``Uffington''.)
Try to identify which parts of the landscape may be visible from your site, so you can estimate which parts of terrain should be included in the model.
Open \program{Sketchup}, select the meter-based ``Landscape Architecture'' template, add \menu{View>Toolbars\ldots}: Locations. 
Click on the ``Add Location'' button of that toolbar. Enter ``Uffington'' into the location search dialog. 
This brings you close to our site of interest. Clip a part of terrain to import it to Sketchup. Optionally, add more terrain. 

If installed, TIG's OBJ exporter is available from the \menu{File} menu, or you can use \program{Sketchup Pro}'s built-in OBJ export. 
Export \file{UffingtonHorse.obj} to a subdirectory  \file{scenery3d/Uffington} in your Stellarium user data directory.
The geolocation is stored in an ``AttributeDictionary''. To read this, press \menu{Window>Ruby Console} to open the Ruby Console. 
Then write a few lines of Ruby to get access to the \texttt{Georeference} dictionary and other data:
\begin{commands}
model=Sketchup.active_model
attrdicts=model.attribute_dictionaries
attrdicts.each {|d|
  puts "AttributeDictionary: %s" % d.name
  d.each_pair { |k, v| puts "  %s=%s" % [k, v] }
}
model.shadow_info.each{|k,v| puts " #{k} #{v}"}
utm=model.point_to_utm Geom::Point3d.new(0,0,0) 
puts("grid_name=UTM %i %s (%s)" % 
    [ utm.zone_number, utm.zone_letter, model.get_datum])
\end{commands}						
						

Note the \texttt{ModelTranslation} values. Those are inches (of all units!) in the UTM reference frame 
and define the model coordinate origin in world coordinates. (Actually, it uses the negative values.) 
Multiplication by 2.54 gives cm, and by 0.0254, meters in the UTM coordinate system. 
We will use the negatives of these values as \texttt{orig\_E}, \texttt{orig\_N}, \texttt{orig\_H}. 
Additionally, we have found information about meridian convergence correction (\program{Sketchup}'s \texttt{NorthAngle}), 
UTM zone number etc. All this goes into our configuration file. 
Create this file \file{scenery3d.ini} with the content seen in fig.~\ref{fig:scenery3d:UffingtonIni}
\begin{figure}[p]
\begin{configfile}
[model]
name=UffingtonHorse
;Either a fitting landscape or just 'Zero Horizon':
landscape=Zero Horizon
scenery=UffingtonHorse.obj
;activate the next line if you have a separate ground layer 
;ground=UffingtonHorse_ground.obj
;If model Y-axis points up, activate the next line
;obj_order=XZY
author=Georg Zotti
copyright=(c) 2017 Georg Zotti
description=Uffington Horse may represent the Sun Horse. \
        See Joshua Pollard in Antiquity 91 356(2017): 406-20.
[location]
name=UffingtonHorse
country=UK
planetName=Earth
;Set the following to a fitting landscape
landscapeKey=Zero Horizon
longitude=-1.56718254089355
latitude=51.5828432749823
altitude=137
[coord]
grid_name=UTM 30 U (WGS 84)
gridType=UTM
orig_E=599273.02119578
orig_N=5715615.15079106
orig_H=136.295297626736
convergence_angle=1.12284363771988
;Height used outside the terrain, to not "fall off" the rim.
zero_ground_height=137
;You may want to reset these coordinates. 
;Observer is set to those on loading the scenery.
start_E=599273.02119578
start_N=5715615.15079106
start_az_alt_fov=50,10,83
\end{configfile}
\caption{\file{scenery3d.ini} for the Uffington example.}
\label{fig:scenery3d:UffingtonIni}
\end{figure}

\section{Limitations}
\label{sec:scenery3d:Limitations}

Models with up to 14 million triangles have been used successfully on
a mid-range notebook PC from 2016. However, take some restrictions
into account:

\begin{itemize}
\item The model is rendered in Cartesian coordinates. Earth's surface
  is curved. If your model extends by tens of kilometres, the visible
  horizon formed by faraway mountains may appear too high. You can
  \newFeature{0.20.2} display a landscape polygon defined in the
  currently displayed Landscape on top of your 3D scene by activating
  \menu{Draw horizon polyline in foreground} in the plugin's
  settings dialog.
\item
  The OBJ format is static. Simulation of interaction with 3D objects
  is not possible with this plugin.
\end{itemize}

\section*{Authors and Acknowledgements}
\label{sec:scenery3d:Acknowledgments}


Scenery3d was conceived by Georg Zotti for the
ASTROSIM\footnote{\url{https://astrosim.univie.ac.at}} project. A first
prototype was implemented in 2010/2011 by Simon Parzer and
Peter Neubauer as student work supervised by Michael Wimmer (TU Wien).
Models for accuracy tests (Sterngarten, Testscene), and later
improvements in integration, user interaction, \file{.ini} option handling,
OBJ/MTL loader bugfixes and georeference testing by Georg Zotti.

Andrei Borza in 2011/12 further improved rendering quality (shadow
mapping, normal mapping) and
speed~\citep{Zotti-Neubauer:VSMM2012,Zotti-Neubauer:EuroMed2012,Zotti:2012:SpringerAA}.

In 2014--17,
Florian Schaukowitsch adapted the code to work with Qt~5 and the 
Stellarium~0.13 codebase, replaced the renderer with a more efficient, fully
shader-based system, implemented various performance, quality and usability
enhancements, and did some code cleanup. Both Andrei and Florian were again
supervised by Michael Wimmer~\citep{Zotti:CHNT2015,Zotti:SEAC2015,Zotti:SEAC2017}.

This work has been originally created during the ASTROSIM project supported 2008-2012 by
the Austrian Science Fund (FWF) under grant number P~21208-G19. Further development has
partially been supported by the Ludwig Boltzmann Institute for Archaeological Prospection and Virtual Archaeology in Vienna, Austria\footnote{%
  \url{https://archpro.lbg.ac.at}}.

If you are using this plugin in scientific work, please cite: \citep{Zotti:CHNT2015,Zotti:SEAC2015,Zotti:SEAC2017,Zotti-etal:SIA2016,Zotti:TAG2016,Zotti-etal:JSA2020.6.2}.


%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "guide"
%%% End: 

