Skip to content

Latest commit

 

History

History
293 lines (220 loc) · 11.7 KB

README.md

File metadata and controls

293 lines (220 loc) · 11.7 KB

merlict c89 logo

Build Status License: GPL v3

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

Build 🔨

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
        ...

Submodules

mli

The core of merlict. It contains the geometry, the linear algebra, and all the basic infrastucture.

mli_viewer

An interactive viewer for merlict that runs on the command line.

mli_corsika

Tools to read the photon output creadted by the CORSIKA simulation.

mli_testing

Only needed for merlict's own unit tests.

Makefile

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

Almagamate into a single header and a single source

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.

Viewer 👀

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.

Build 🔨

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.

Run

build/viewer libs/mli/tests/resources/sceneries/001.tar
ASCII-art ANSI-escape-codes
viewer-ascii-art viewer-ansi-escape

viewer-rendering-ppm

Interface

Scenery

Tree

A tree with cartesian frames as nodes and object-references as leafs. The tree defines the relative position and orientation of your object-references.

Object

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.

Object-Reference

A reference to an object. It bundles the object and the pysical properties of its surfaces and media.

Materials

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

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.

Object-Wavefront Format .obj

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 one usemtl 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

Unit-Tests

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 tars the sceneries into tape-archives,
  • builds with both gcc and clang, in both c, and c++ mode,
  • and runs the tests.

Development

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 typedefs! Merlict uses mli prefix.
  • Avoid all Warnings ingcc and clang in both c and c++ 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.

Suggested Tools

  • 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.

Acknowledgement

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)

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