Merlict simulates light. It finds the intersections of a ray and a complex 3D geometry with special emphasis on surface-normals. Merlict can propagate photons based on geometric optics according to Fresnel. Merlict comes with its own interactive viewer for the terminal. Merlict is a library written in c89
.
Merlict reads your scenery from text-files which describe your objects, the geometric relations between them, their materials, and their sourrounding media. Merlict can read a subset of the popular object-wavefront format .obj
.
You define photons with a creation-position, direction, and wavelength.
For each photon, merlict gives you the list of physical interactions up to its absorbtion.
Merlict would not exist without the author's past and present affiliations:
-
Max-Planck-Institute for Nuclear Physics, Saupfercheckweg 1, 69117 Heidelberg, Germany
-
Institute for Particle Physics and Astrophysics, ETH-Zurich, Otto-Stern-Weg 5, 8093 Zurich, Switzerland
-
Experimental Physics Vb, Astroparticle Physics, TU-Dortmund, Otto-Hahn-Str. 4a, 44227 Dortmund, Germany
Merlict is organized in 'The Pitchfork Layout'.
It uses the 'merged Header Placement' because it has no private headers and it uses the 'merged Tests Placement'.
This hopefully gives you a reasonable chance to wrap your build system around it.
Merlict is split in what the pitch fork layout calls 'submodules'.
The submodules are mli
, mli_viewer
, mli_corsika
, and mli_testing
.
The mli
is mandatory. It is the core of merlict. But the other submodules are optional and you might not want all of them.
merlict_c89
|
|-> libs
|
|-> mli
| |
| |-> src
| |-> mliVec.h
| |-> mliVec.c
| ...
|
|-> mli_viewer
...
The core of merlict. It contains the geometry, the linear algebra, and all the basic infrastucture.
An interactive viewer for merlict that runs on the command line.
Tools to read the photon output creadted by the CORSIKA simulation.
Only needed for merlict's own unit tests.
A Makefile
will build the interactive viewer in build/bin/viewer
.
Take a look here for what a makefile based build system might look like.
make
Merlict has tool/almagamate.py
which can combine the headers and sources into a single file.
This is a poor man's build system which is primarily used to almagamate the sources for a python
(cython
) build. It makes the cython
side of things very easy.
Also it builds very fast. It builds much faster than individual objects .o
which are linked together later. You can use the almagamated sources for your build system as well.
This way you only have to:
#include "mli.h"
in your headers, and
#include "mli.c"
in your sources. Thats it. 🏁
With the --test
flag the tool/almagamate.py
further creates the main()
for unit testing.
See ./compile_and_test.sh
for a minimal example.
The test's main does not use the almagamated sources but includes the source files directly.
This is done to ease debugging so that filenames and linenumberr match the original sources.
Merlict's viewer runs in the terminal and reads three formats:
- a standalone object-wavefront
.obj
- merlict's own
scenery.tar
- merlict's own
scenery.bin
Control your viewing direction and position via the keyboard. You can inspect the scenery and render high resolution images.
The viewer prints into the terminal using ASCII-art. When your terminal supports ANSI-escape-code
you can switch to 24-bit true color. The viewer is especially useful when you run merlict on a remote computer via ssh
without an X
-server.
Merlict's viewer will try to set your terminal's stdin
to a non canonical mode so that you do not have to press [Enter] after each keypress.
When using tools/almagamate.py
:
First run almagamate:
python ./tools/almagamate.py \
build/almagamate \
libs/mli \
libs/mli_viewer \
--header_path build/almagamate/mli-mli_viewer.h \
--source_path build/almagamate/mli-mli_viewer.c
Second build the viewer:
gcc \
-include build/almagamate/mli-mli_viewer.h \
-include build/almagamate/mli-mli_viewer.c \
libs/mli_viewer/apps/viewer.main.c \
-o build/viewer \
-lm
See also libs/mli_viewer/apps/viewer.main.c
.
build/viewer libs/mli/tests/resources/sceneries/001.tar
ASCII-art | ANSI-escape-codes |
---|---|
A tree with cartesian frames as nodes and object-references as leafs. The tree defines the relative position and orientation of your object-references.
A mesh of triangular faces
which are defined by their vertices
, and vertex-normals
.
To approximate complex surfaces, especially complex surface-normals, you can control the vertex-normals
of each face
. The surface-normal in an intersection will be the barycentric interpolation of the vertex-normals
.
A reference to an object. It bundles the object and the pysical properties of its surfaces and media.
You describe a medium by its transmissivity and its refractive index.
You define surfaces by their specular, and diffuse (lambertian) reflections approximating physical surfaces using the Phong-model.
Photons are defined by their creation-position, their direction, their wavelength. During propagation, merlict writes the history of the photon bouncing around in the scenery until it is absorbed.
Merlict supports a subset of the obj
format in ASCII-text. An object-wavefront defines a mesh of triangle-faces in a 3D space with special emphasis on the meshe's surface-normal. Each face f
references its three vertices v
. The surface-normal of a face f
will be interpolated between the face's three vertex-normals vn
using the barycentrig weight of the intersection-position w.r.t the face.
#
comment-line. Any text in this line.v
vertex-line. Three real numbers define one vertex in the mesh.vn
vertex-normal-line. Three reel numbers define one surface-normal in the mesh.f
face-line. Exactly three integer references to vertices define a face. And three integer references to vertex-normals define the surface-normals on this face. References must be positive, backwards referencing with negative integers is not supported.usemtl
material-reference. All following faces are assigned the same material. There must be at least oneusemtl
before the first face.
Other features of obj
such as e.g. vertex-texture-coordinates vt
will be ignored. Blank lines are accepted but ignored.
A simple cube where each of the six sides references a different material:
# vertices
v 1.0 0.0 0.0
v 1.0 1.0 0.0
v 0.0 1.0 0.0
v 0.0 0.0 0.0
v 1.0 0.0 1.0
v 1.0 1.0 1.0
v 0.0 1.0 1.0
v 0.0 0.0 1.0
# vertex normals
vn 1.0 0.0 0.0
vn 0.0 1.0 0.0
vn 0.0 0.0 1.0
vn -1.0 0.0 0.0
vn 0.0 -1.0 0.0
vn 0.0 0.0 -1.0
# faces
usemtl px
f 1//1 2//1 6//1
f 6//1 5//1 1//1
usemtl py
f 2//2 3//2 6//2
f 6//2 3//2 7//2
usemtl pz
f 5//3 6//3 7//3
f 7//3 8//3 5//3
usemtl mx
f 3//4 7//4 4//4
f 7//4 8//4 4//4
usemtl my
f 1//5 4//5 8//5
f 8//5 5//5 1//5
usemtl mz
f 1//6 2//6 3//6
f 3//6 4//6 1//6
Merlict has a bash
script
./compile_and_test.sh
to prepare, build, and run the unit-tests. Run this script to check whether merlict builds and runs fine on your platform.
The unit-tests and their resources are located in the ./tests/
directory.
The script
- prepares the resources as it
tar
s the sceneries into tape-archives, - builds with both
gcc
andclang
, in bothc
, andc++
mode, - and runs the tests.
Open an issue and describe your problem or wish.
Then its the core developer's job to:
- Write unit-tests.
- Credit and acknowledge original authors.
- Obey
std=c89
standard. - Keep the header's namespace clean. No
typedef
s! Merlict usesmli
prefix. - Avoid all Warnings in
gcc
andclang
in bothc
andc++
mode. - Format
c
according to./tools/.clang-format
.
But of course the author will happily recive pull-requests that meet such expectations 😉.
Merlict tries to migrate towards a physical layout according to the 'The Pitchfork Layout' in 'merged Header Placement'. The merged headers are prefered as there are only public headers anyhow.
-
Blender to inspect and manipulate objects. It is especially useful to visualize surface-normals.
-
OpenScad to create meshes in a parametric way. Unfortunately it does not have a concept of vertex-normals.
-
refractive-index-database a database of refractive indices of various materials.
Finding intersections of triangles and cubes
- Voorhies, Douglas; Triangle-Cube Intersection; Graphics Gems III, p. 236-239, code: p. 521-526
Finding ray and triangle intersection
- Thomas, Moeller and Ben, Trumbore; 'Fast, Minimum Storage Ray-Triangle Intersection', Journal of Graphics Tools 2: 21-28 and Wikipedia
Mirroring direction-vectors on a surface-normal
- J.H., Bruge; University of Arizona; OPTI 421/521 – 'Introductory Optomechanical Engineering'
Traversing an octree with a ray
- Revelles, Jorge and Urena, Carlos and Lastra, Miguel; 'An efficient parametric algorithm for octree traversal'; Vaclav Skala-UNION Agency
- Jeroen, Baert; additional comments
Pseudo random number generator
- Makoto, Matsumoto and Takuji, Nishimura and wikipedia; Mersenne Twister
- Melissa E. O'Neill; Harvey Mudd College; pcg-random.org; Permuted Congruential Generator (PCG)
Parsing JSON-strings
- Serge, Zaitsev; JSMN
Awesome debug MACROS
- Zed, Shawn; 'Learn C the hard way'
Sampling from random distributions
- Volker, Blobel; 'Statistical and numerical methods'
Homogenous Transformations
- Bruno, Siciliano and Lorenzo, Sciavicco and Luigi, Villani and Guiseppe, Oriolo; 'Robotics -- Modelling, Planning and Control'
Writing and reading tape-archives (.tar
)
- rxi; microtar
Controlling stdin buffer using termios
- Edwin, Buck;
A fast voxel traversal algorithm for ray tracing
- John Amanatides and Andrew Woo, Dept. of Computer Science University of Toronto, Toronto, Ontario, Canada M5S 1A4