Add conversion of PMD range to cartesian coordinates to simulation library.
[camsim.git] / libcamsim / simulator.hpp
1 /*
2  * Copyright (C) 2012, 2013, 2014, 2016, 2017, 2018
3  * Computer Graphics Group, University of Siegen
4  * Written by Martin Lambers <martin.lambers@uni-siegen.de>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24
25 #ifndef CAMSIM_SIMULATOR_HPP
26 #define CAMSIM_SIMULATOR_HPP
27
28 #include <random>
29
30 #include <QList>
31 #include <QVector>
32 #include <QSize>
33 #include <QVector2D>
34 #include <QOpenGLShaderProgram>
35
36 #include "scene.hpp"
37 #include "animation.hpp"
38 #include "texdata.hpp"
39
40
41 namespace CamSim {
42
43 /*! \brief Speed of light in m/s */
44 constexpr double speedOfLight = 299792458;
45 /*! \brief Elementary charge in Attocoulomb (1e-18 C). */
46 constexpr double elementaryCharge = 0.1602176565;
47
48 /**
49  * \brief Defines chip timings and therefore frames-per-second
50  *
51  * In physically-based simulations, the exposure time is important
52  * since it determines how much energy a chip pixel receives.
53  *
54  * For simple RGB simulation, physical quantities are irrelevant
55  * and you can simply set the exposure time to zero and the readout
56  * time to the duration of one frame.
57  */
58 class ChipTiming
59 {
60 public:
61     /*! \brief Constructor */
62     ChipTiming();
63
64     /*! \brief Exposure time for each subframe in seconds */
65     double exposureTime;
66     /*! \brief Readout time for each subframe in seconds */
67     double readoutTime;
68     /*! \brief Pause time after all subframes, before the start of a new frame */
69     double pauseTime;
70
71     /*! \brief Return the duration of one subframe resulting from these timings */
72     double subFrameDuration() const { return exposureTime + readoutTime; }
73
74     /*! \brief Return the subframes-per-second rate resulting from these timings */
75     double subFramesPerSecond() const { return 1.0 / subFrameDuration(); }
76
77     /*! Generate chip timings from subframes-per-second. This ignores exposure
78      * time, so this is not suitable for physically-based simulations such
79      * as PMD simulation. */
80     static ChipTiming fromSubFramesPerSecond(float sfps);
81 };
82
83 /**
84  * \brief Defines a PMD chip
85  */
86 class PMD
87 {
88 public:
89     /*! \brief Constructor */
90     PMD();
91
92     /*! \brief Pixel size in micrometers¬≤ (also known as pixel pitch) */
93     double pixelSize;
94     /*! \brief Pixel achievable contrast in [0,1] */
95     double pixelContrast;
96     /*! \brief Modulation Frequency in Hz */
97     double modulationFrequency;
98     /* \brief wavelength of light pulse in nm */
99     float wavelength;
100     /* \brief quantum efficiency of camera */
101     float quantumEfficiency;
102     /* \brief maximum number of electrons per pixel */
103     int maxElectrons;
104 };
105
106 /**
107  * \brief Defines the camera projection onto the image plane
108  *
109  * For OpenGL, this means viewport and projection matrix information.
110  * For OpenCV, this means image size and intrinsic parameter information.
111  */
112 class Projection
113 {
114 private:
115     int _w, _h;
116     float _l, _r, _b, _t; // frustum for near=1
117     float _k1, _k2, _p1, _p2; // lens distortion parameters, compatible to OpenCV
118
119 public:
120     /*! \brief Constructor */
121     Projection();
122
123     /*! \brief Get the image size */
124     QSize imageSize() const;
125
126     /*! \brief For OpenGL: Get the projection matrix for the given near and far plane values \a n and \a f */
127     QMatrix4x4 projectionMatrix(float n, float f) const;
128
129     /*! \brief For OpenCV: get the center pixel coordinates */
130     QVector2D centerPixel() const;
131     /*! \brief For OpenCV: get the focal lengths in x and y direction, in millimeters */
132     QVector2D focalLengths() const;
133
134     /*! \brief Create a camera transformation from image size and frustum information (relative to a near plane value of 1) */
135     static Projection fromFrustum(int imageWidth, int imageHeight,
136             float l, float r, float b, float t);
137     /*! \brief Create a camera transformation from image size and vertical opening angle (in degrees) */
138     static Projection fromOpeningAngle(int imageWidth, int imageHeight, float fovy);
139     /*! \brief Create a camera transformation from image size and camera intrinsic parameters as used by OpenCV */
140     static Projection fromIntrinsics(int imageWidth, int imageHeight,
141             float centerX, float centerY, float focalLengthX, float focalLengthY);
142
143     /*! \brief Set lens distortion parameters, compatible to OpenCV.
144      * Set everything to zero to disable lens distortion. */
145     void setDistortion(float k1, float k2, float p1, float p2);
146     /*! \brief Get lens distortion parameters, compatible to OpenCV. */
147     void distortion(float* k1, float* k2, float* p1, float* p2);
148 };
149
150 /**
151  * \brief Defines the rendering pipeline
152  */
153 class Pipeline
154 {
155 public:
156     /*! \brief Constructor */
157     Pipeline();
158
159     /**
160      * \name Basic parameters
161      */
162     /*@{*/
163
164     /*! \brief Near clipping plane value */
165     float nearClippingPlane;
166     /*! \brief Far clipping plane value */
167     float farClippingPlane;
168
169     /*@}*/
170
171     /**
172      * \name Simple feature switches
173      */
174     /*@{*/
175
176     /*! \brief Flag: enable mipmapping? */
177     bool mipmapping;
178     /*! \brief Flag: enable anisotropic filtering? */
179     bool anisotropicFiltering;
180     /*! \brief Flag: enable transparency (discard fragments with opacity < 0.5)? */
181     bool transparency;
182     /*! \brief Flag: enable normal mapping via bump map or normal map? */
183     bool normalMapping;
184     /*! \brief Flag: use ambient light and colors? (should be off, but may be needed for imported scenes) */
185     bool ambientLight;
186     /*! \brief Flag: enable thin lens vignetting based on lens aperture diameter (see \a Projection)? */
187     bool thinLensVignetting;
188     /*! \brief Thin lens aperture diameter in millimeter. Only used if \a thinLensVignetting is true. */
189     float thinLensApertureDiameter;
190     /*! \brief Thin lens focal length in millimeter. Only used if \a thinLensVignetting is true. */
191     float thinLensFocalLength;
192     /*! \brief Flag: enable shot noise (also known as poisson noise) for PMD output? */
193     bool shotNoise;
194     /*! \brief Flag: enable Gaussian white noise for RGB output? */
195     bool gaussianWhiteNoise;
196     /*! \brief Gaussian noise mean; should be zero in almost all cases. Only used if \a gaussianWhiteNoise is true. */
197     float gaussianWhiteNoiseMean;
198     /*! \brief Gaussian noise standard deviation in (0,1]; typically in [0.01, 0.1]. For RGB simulation, this applies
199      * to the color values in [0,1]. For PMD simulation, this is first stretched to the maximum per-pixel energy estimated for
200      * the current simulation parameters, so that in effect you can assume the PMD energy values to also be in [0,1].
201      * Only used if \a gaussianWhiteNoise is true. */
202     float gaussianWhiteNoiseStddev;
203
204     /*@}*/
205
206     /**
207      * \name Other features
208      */
209     /*@{*/
210
211     /*! \brief Lens distortion computation in the vertex shader. Please read the documentation!
212      * See also \a postprocLensDistortion. */
213     bool preprocLensDistortion;
214     /*! \brief Extra margin for early clipping for \a preprocLensDistortion. Zero by default.
215      * A greater margin means that more triangles outside of the cube are rendered.
216      * This decreases the amount of discarded otherwise visible triangles but increases
217      * the chance of broken geometry from lens distortion. */
218     float preprocLensDistortionMargin;
219     /*! \brief Lens distortion computation in the fragment shader. Please read the documentation!
220      * See also \a preprocLensDistortion. */
221     bool postprocLensDistortion;
222
223     /*@}*/
224
225     /**
226      * \name Shadows and light maps
227      */
228     /*@{*/
229
230     /*! \brief Flag: enable shadow maps? */
231     bool shadowMaps;
232     /*! \brief Flag: enable filtering of shadow maps? */
233     bool shadowMapFiltering;
234     /*! \brief Flag: enable reflective shadow maps? */
235     bool reflectiveShadowMaps;
236     /*! \brief Flag: enable light source power factor maps? */
237     bool lightPowerFactorMaps;
238
239     /*@}*/
240
241     /**
242      * \name Oversampling
243      */
244     /*@{*/
245
246     /*! \brief Flag: should subframes be simulated at different points in time, according to \a ChipTiming?
247      * This should always be true; if it is disabled, all subframes are simulated for the timestamp
248      * of the first subframe. */
249     bool subFrameTemporalSampling;
250     /*! \brief Samples per fragment for spatial oversampling (1x1 means no oversampling).
251      * The number of samples in both horizontal and vertical direction must be odd! */
252     QSize spatialSamples;
253     /*! \brief Weights for spatial oversampling. If not given (vector is empty), then
254      * default weights will be used (1 / number_of_samples for each sample).
255      * Otherwise the vector size must match the number of samples. */
256     QVector<float> spatialSampleWeights;
257     /*! \brief Number of temporal samples (1 means no oversampling) */
258     int temporalSamples;
259
260     /*@}*/
261 };
262
263 /**
264  * \brief Defines the simulator output
265  */
266 class Output
267 {
268 public:
269     /*! Constructor */
270     Output();
271
272     /**
273      * \name Light-based simulation output
274      */
275     /*@{*/
276
277     /*! \brief Flag: enable output of linear RGB colors? */
278     bool rgb;
279     /*! \brief Flag: enable output of sRGB colors (only if \a rgb is also true)? */
280     bool srgb;
281     /*! \brief Flag: enable output of PMD results (subframes/phase images and final result)? */
282     bool pmd;
283     /*! \brief Flag: enable output of PMD cartesian coordinates (only if \a pmd is also true)? */
284     bool pmdCoordinates;
285
286     /*@}*/
287
288     /**
289      * \name Geometry-related simulation output
290      */
291     /*@{*/
292
293     /*! \brief Flag: enable output of eye space positions? */
294     bool eyeSpacePositions;
295     /*! \brief Flag: enable output of custom space positions (see \a Simulator::setCustomTransformation)? */
296     bool customSpacePositions;
297     /*! \brief Flag: enable output of eye space normals? */
298     bool eyeSpaceNormals;
299     /*! \brief Flag: enable output of custom space normals (see \a Simulator::setCustomTransformation)? */
300     bool customSpaceNormals;
301     /*! \brief Flag: enable output of eye space depth and range? */
302     bool depthAndRange;
303     /*! \brief Flag: enable output of indices (object, shape-in-object, triangle-in-shape, material)? */
304     bool indices;
305
306     /*@}*/
307
308     /**
309      * \name Temporal flow-related simulation output
310      */
311     /*@{*/
312
313     /*! \brief Flag: enable output of forward 3D flow (offset from current to next 3D position)? */
314     bool forwardFlow3D;
315     /*! \brief Flag: enable output of forward 2D flow (offset from current to next 2D pixel position)? */
316     bool forwardFlow2D;
317     /*! \brief Flag: enable output of backward 3D flow (offset from current to last 3D position)? */
318     bool backwardFlow3D;
319     /*! \brief Flag: enable output of backward 2D flow (offset from current to last 2D pixel position)? */
320     bool backwardFlow2D;
321
322     /*@}*/
323 };
324
325 /**
326  * \brief Simulates a camera frame
327  */
328 class Simulator {
329 private:
330     // Our random number generator (e.g. for noise generation)
331     std::mt19937 _randomGenerator;
332
333     // The configuration: animated camera and scene
334     Animation _cameraAnimation;
335     Transformation _cameraTransformation;
336     Scene _scene;
337
338     // The configuration: chip and optics
339     ChipTiming _chipTiming;
340     PMD _pmd;
341     Projection _projection;
342
343     // The configuration: rendering pipeline and output
344     Pipeline _pipeline;
345     Output _output;
346     Transformation _customTransformation;
347
348     // Timestamp management
349     bool _recreateTimestamps;
350     long long _startTimestamp;
351     long long _endTimestamp;
352     bool _haveLastFrameTimestamp;
353     long long _lastFrameTimestamp;
354
355     // Shader pipeline management
356     bool _recreateShaders;
357     QOpenGLShaderProgram _shadowMapPrg;          // create shadow map for a single light source
358     QOpenGLShaderProgram _reflectiveShadowMapPrg;// create reflective shadow map for a single light source
359     QOpenGLShaderProgram _depthPrg;              // pre-render the depth buf only
360     QOpenGLShaderProgram _lightPrg;              // simulate rgb and pmd phase for current time stamp
361     QOpenGLShaderProgram _lightOversampledPrg;   // reduce spatially oversampled rgb and pmd phase
362     QOpenGLShaderProgram _pmdDigNumPrg;          // convert energies to PMD digital numbers, possibly with shot noise
363     QOpenGLShaderProgram _gaussianWhiteNoisePrg; // add gaussian white noise
364     QOpenGLShaderProgram _zeroPrg;               // produce all-zero output
365     QOpenGLShaderProgram _rgbResultPrg;          // combine rgb subframes to final result
366     QOpenGLShaderProgram _pmdResultPrg;          // combine pmd phase subframes to final result
367     QOpenGLShaderProgram _pmdCoordinatesPrg;     // compute cartesian coordinates from pmd range
368     QOpenGLShaderProgram _geomPrg;               // simulate geometry (pos, normals, depth, range, indices) information
369     QOpenGLShaderProgram _flowPrg;               // simulate 2D/3D flow information
370     QOpenGLShaderProgram _convertToSRGBPrg;      // convert linear RGB to sRGB
371     QOpenGLShaderProgram _postprocLensDistortionPrg; // postprocessing: apply lens distortion
372
373     // Simulation output management
374     bool _recreateOutput;
375     QVector<long long> _timestamps;                              // subFrames
376     QVector<Transformation> _cameraTransformations;              // subFrames
377     QVector<QVector<Transformation>> _lightTransformations;      // subFrames; each contained vector stores one transf for each light source in the scene
378     QVector<QVector<Transformation>> _objectTransformations;     // subFrames; each contained vector stores one transf for each object in the scene
379     QVector<QVector<unsigned int>> _shadowMapDepthBufs;          // subFrames; each contained vector stores one cube depth buffer for each light source
380     QVector<QVector<unsigned int>> _reflectiveShadowMapDepthBufs;// subFrames; each contained vector stores one cube depth buffer for each light source
381     QVector<QVector<unsigned int>> _reflectiveShadowMapTexs;     // subFrames; each contained vector stores one cube array tex with 5 layers for each light source
382     unsigned int _pbo;
383     unsigned int _depthBufferOversampled;
384     unsigned int _rgbTexOversampled;
385     unsigned int _pmdEnergyTexOversampled;
386     unsigned int _pmdEnergyTex;
387     unsigned int _pmdCoordinatesTex;
388     unsigned int _gaussianNoiseTex;               // for shot noise generation, dynamically generated
389     QVector<float> _gaussianWhiteNoiseBuf;        // reused vector to generate gaussian white noise
390     QVector<unsigned int> _gaussianWhiteNoiseTexs;// subFrames
391     QVector<unsigned int> _depthBuffers;          // subFrames+1
392     QVector<unsigned int> _rgbTexs;               // subFrames+1
393     QVector<unsigned int> _srgbTexs;              // subFrames+1
394     QVector<unsigned int> _pmdDigNumTexs;         // subFrames+1
395     QVector<unsigned int> _eyeSpacePosTexs;       // subFrames
396     QVector<unsigned int> _customSpacePosTexs;    // subFrames
397     QVector<unsigned int> _eyeSpaceNormalTexs;    // subFrames
398     QVector<unsigned int> _customSpaceNormalTexs; // subFrames
399     QVector<unsigned int> _depthAndRangeTexs;     // subFrames
400     QVector<unsigned int> _indicesTexs;           // subFrames
401     QVector<unsigned int> _forwardFlow3DTexs;     // subFrames+1
402     QVector<unsigned int> _forwardFlow2DTexs;     // subFrames+1
403     QVector<unsigned int> _backwardFlow3DTexs;    // subFrames+1
404     QVector<unsigned int> _backwardFlow2DTexs;    // subFrames+1
405     QVector<QList<unsigned int>> _lightSimOutputTexs;
406     QVector<QList<unsigned int>> _geomSimOutputTexs;
407     QVector<QList<unsigned int>> _flowSimOutputTexs;
408     QList<unsigned int> _oversampledLightSimOutputTexs;
409     unsigned int _postProcessingTex; // temporary texture for post-processing, e.g. lens distortion
410
411     // Our FBO
412     unsigned int _fbo; // managed by prepareFBO()
413     unsigned int _fullScreenQuadVao; // managed by prepareFBO()
414
415 private:
416     bool spatialOversampling() const;
417     QSize spatialOversamplingSize() const;
418     bool temporalOversampling() const;
419     bool powerTexs() const;
420
421     void recreateTimestampsIfNecessary();
422     void recreateShadersIfNecessary();
423     void prepareDepthBuffers(QSize size, const QVector<unsigned int>& depthBufs);
424     void prepareOutputTexs(QSize size, const QVector<unsigned int>& outputTexs, int internalFormat, bool interpolation);
425     void recreateOutputIfNecessary();
426
427     float lightIntensity(int lightSourceIndex) const;
428
429     void simulateTimestamps(long long t);
430     void simulateSampleTimestamp(long long t,
431             Transformation& cameraTransformation,
432             QVector<Transformation>& lightTransformations,
433             QVector<Transformation>& objectTransformations);
434     void prepareFBO(QSize size, unsigned int depthBuf, bool reuseDepthBufData,
435             const QList<unsigned int>& colorAttachments, int cubeMapSide = -1, int arrayTextureLayers = 0,
436             bool enableBlending = false, bool clearBlendingColorBuffer = true);
437
438     void drawScene(QOpenGLShaderProgram& prg,
439             const QMatrix4x4& projectionMatrix,
440             const QMatrix4x4& viewMatrix,
441             const QMatrix4x4& lastViewMatrix,
442             const QMatrix4x4& nextViewMatrix,
443             const QVector<Transformation>& objectTransformations,
444             const QVector<Transformation>& lastObjectTransformations,
445             const QVector<Transformation>& nextObjectTransformations);
446     void simulate(QOpenGLShaderProgram& prg,
447             int subFrame, long long t, long long lastT, long long nextT, unsigned int lastDepthBuf,
448             const Transformation& cameraTransformation,
449             const QVector<Transformation>& lightTransformations,
450             const QVector<Transformation>& objectTransformations);
451     void simulateShadowMap(bool reflective,
452             int subFrame, int lightIndex,
453             const Transformation& cameraTransformation,
454             const QVector<Transformation>& lightTransformations,
455             const QVector<Transformation>& objectTransformations);
456     void simulateShadowMaps(int subFrame,
457             const Transformation& cameraTransformation,
458             const QVector<Transformation>& lightTransformations,
459             const QVector<Transformation>& objectTransformations);
460     void simulateDepth(int subFrame, long long t,
461             const Transformation& cameraTransformation,
462             const QVector<Transformation>& lightTransformations,
463             const QVector<Transformation>& objectTransformations);
464     void simulateLight(int subFrame, long long t,
465             const Transformation& cameraTransformation,
466             const QVector<Transformation>& lightTransformations,
467             const QVector<Transformation>& objectTransformations);
468     void simulateOversampledLight();
469     void simulatePMDDigNums();
470     void simulateGaussianWhiteNoise(int subFrame);
471     void simulateRGBResult();
472     void simulatePMDResult();
473     void simulatePMDCoordinates();
474     void simulateGeometry(int subFrame);
475     void simulateFlow(int subFrame, long long lastT, long long nextT, unsigned int lastDepthBuf);
476     void simulatePostprocLensDistortion(const QList<unsigned int>& textures);
477
478     void convertToSRGB(int texIndex);
479
480     bool haveValidOutput(int i) const;
481     bool haveShadowMap(int lightIndex) const;
482     bool haveReflectiveShadowMap(int lightIndex) const;
483
484 public:
485     /*! \brief Constructor */
486     Simulator();
487
488     /**
489      * \name Configuration: animation and scene
490      */
491     /*@{*/
492
493     /*! \brief Get camera animation */
494     const Animation& cameraAnimation() const { return _cameraAnimation; }
495     /*! \brief Set camera animation */
496     void setCameraAnimation(const Animation& animation);
497
498     /*! \brief Get camera transformation (relative to the camera animation) */
499     const Transformation& cameraTransformation() const { return _cameraTransformation; }
500     /*! \brief Set camera transformation (relative to the camera animation) */
501     void setCameraTransformation(const Transformation& transformation);
502
503     /*! \brief Get scene */
504     const Scene& scene() const { return _scene; }
505     /*! \brief Set scene */
506     void setScene(const Scene& scene);
507
508     /*@}*/
509
510     /**
511      * \name Configuration: chip and optics
512      */
513     /*@{*/
514
515     /*! \brief Get chip timing parameters */
516     const ChipTiming& chipTiming() const { return _chipTiming; }
517     /*! \brief Set chip timing parameters */
518     void setChipTiming(const ChipTiming& chipTiming);
519
520     /*! \brief Get PMD chip parameters */
521     const PMD& pmd() const { return _pmd; }
522     /*! \brief Set PMD chip parameters */
523     void setPMD(const PMD& pmd);
524
525     /*! \brief Get projection parameters */
526     const Projection& projection() const { return _projection; }
527     /*! \brief Set projection parameters */
528     void setProjection(const Projection& projection);
529
530     /*@}*/
531
532     /**
533      * \name Configuration: rendering pipeline and output
534      */
535     /*@{*/
536
537     /*! \brief Get pipeline parameters */
538     const Pipeline& pipeline() const { return _pipeline; }
539     /*! \brief Set pipeline parameters */
540     void setPipeline(const Pipeline& pipeline);
541
542     /*! \brief Get output parameters */
543     const Output& output() const { return _output; }
544     /*! \brief Set output parameters */
545     void setOutput(const Output& output);
546
547     /*! \brief Set custom transformation, for output of custom space position and normals
548      * (see \a Output::customSpacePositions, \a Output::customSpaceNormals).
549      * By default, the custom transformation does nothing, and the custom space is
550      * equivalent to world space. */
551     void setCustomTransformation(const Transformation& transformation);
552
553     /*@}*/
554
555     /**
556      * \name Simulation
557      */
558     /*@{*/
559
560     /*! \brief Get the number of subframes simulated for the current configuration.
561      * This is usually 4 if PMD simulation is active (see \a output), and 1 otherwise. */
562     int subFrames() const;
563
564     /*! \brief Get the start time in microseconds (earliest starting point of all involved animations) */
565     long long startTimestamp();
566     /*! \brief Get the end time in microseconds (latest end point of all involved animations) */
567     long long endTimestamp();
568     /*! \brief Get subframe duration in microseconds (depends on chip timings) */
569     long long subFrameDuration();
570     /*! \brief Get frame duration in microseconds (depends on chip timings and number of subframes) */
571     long long frameDuration();
572     /*! \brief Get frames per second rate (depends on chip timings and number of subframes) */
573     float framesPerSecond();
574     /*! \brief Get the next time stamp in microseconds for simulation via \a simulate(). If you did not call
575      * \a simulate() yet with the current configuration, this will be the same as
576      * \a startTimestamp. Otherwise, it will be the last time stamp passed to \a simulate()
577      * plus the \a frameDuration(). You should stop to call \a simulate() once the returned
578      * time stamp is later than \a endTimestamp(). */
579     long long nextFrameTimestamp();
580
581     /*! \brief Simulate a camera frame at the time given by \a frameTimestamp.
582      *
583      * This function simulates a camera viewing the scene using the current
584      * configuration at the given point in time.
585      *
586      * It uses its own internal framebuffer object and manages its own textures
587      * for simulation results. You can get these textures individually.
588      *
589      * If the simulation requires the simulation of subframes, then all subframes
590      * and the final result frame are simulated in one step, but the results
591      * from every subframe remain accessible. For example, if PMD simulation is
592      * activated (see \a output), then the four phase images as well as the final
593      * result are simulated in one step.
594      */
595     void simulate(long long frameTimestamp);
596
597     /*@}*/
598
599     /**
600      * \name Retrieving simulation results
601      *
602      * Many of these function return texture handles. See the \a TexData class
603      * on how to access the data within the texture conveniently, and the \a Exporter class
604      * on how to write the data to various file formats.
605      */
606     /*@{*/
607
608     /*! \brief Get the time stamp associated with the given subframe \a i or the final
609      * result (if \a i is -1; however, this is always the same as for subframe 0). */
610     long long getTimestamp(int i = -1) const;
611
612     /*! \brief Get the texture containing the shadow map cube
613      * for the light source with index \a lightIndex in the scene
614      * for the given subframe \a i or the final result (if \a i is -1).
615      * Shadow maps for the final result are always the same as those for the first subframe. */
616     unsigned int getShadowMapCubeTex(int lightIndex, int i = -1) const;
617
618     /*! \brief Convenience wrapper for \a getShadowMapTex().
619      * You need to specify the cube side (0 = pos-x, 1 = neg-x, 2 = pos-y, 3 = neg-y, 4 = pos-z, 5 = neg-z). */
620     TexData getShadowMap(int lightIndex, int cubeSide, int i = -1) const
621     { return TexData(getShadowMapCubeTex(lightIndex, i), cubeSide, -1, GL_R32F, { "gldepth" }, _pbo); }
622
623     /*! \brief Get the cube array texture containing the reflective shadow map information
624      * for the light source with index \a lightIndex in the scene,
625      * for the given subframe \a i or the final result (if \a i is -1).
626      * Shadow maps for the final result are always the same as those for the first subframe.
627      * The cube array texture contains the following layers:
628      * - 0: Positions in camera space (not light space and not world space)
629      * - 1: Normals in camera space
630      * - 2: Radiances for r, g, b, and power
631      * - 3: BRDF diffuse parameters kd_r, kd_g, kd_b
632      * - 4: BRDF specular parameters ks_r, ks_g, ks_b, shininess
633      */
634     unsigned int getReflectiveShadowMapCubeArrayTex(int lightIndex, int i = -1) const;
635
636     /*! \brief Convenience wrapper for \a getReflectiveShadowMapTex()
637      * that gets the position data.
638      * You need to specify the cube side (0 = pos-x, 1 = neg-x, 2 = pos-y, 3 = neg-y, 4 = pos-z, 5 = neg-z). */
639     TexData getReflectiveShadowMapPositions(int lightIndex, int cubeSide, int i = -1) const
640     { return TexData(getReflectiveShadowMapCubeArrayTex(lightIndex, i), cubeSide, 0, GL_RGB32F, { "x", "y", "z" }, _pbo); }
641
642     /*! \brief Convenience wrapper for \a getReflectiveShadowMapTex()
643      * that gets the normal data. */
644     TexData getReflectiveShadowMapNormals(int lightIndex, int cubeSide, int i = -1) const
645     { return TexData(getReflectiveShadowMapCubeArrayTex(lightIndex, i), cubeSide, 1, GL_RGB32F, { "nx", "ny", "nz" }, _pbo); }
646
647     /*! \brief Convenience wrapper for \a getReflectiveShadowMapTex()
648      * that gets the radiance data. */
649     TexData getReflectiveShadowMapRadiances(int lightIndex, int cubeSide, int i = -1) const
650     { return TexData(getReflectiveShadowMapCubeArrayTex(lightIndex, i), cubeSide, 2, GL_RGBA32F, { "r", "g", "b", "radiances" }, _pbo); }
651
652     /*! \brief Convenience wrapper for \a getReflectiveShadowMapTex()
653      * that gets the BRDF diffuse parameter data. */
654     TexData getReflectiveShadowMapBRDFDiffuseParameters(int lightIndex, int cubeSide, int i = -1) const
655     { return TexData(getReflectiveShadowMapCubeArrayTex(lightIndex, i), cubeSide, 3, GL_RGB32F, { "kdr", "kdg", "kdb" }, _pbo); }
656
657     /*! \brief Convenience wrapper for \a getReflectiveShadowMapTex()
658      * that gets the BRDF specular parameter data. */
659     TexData getReflectiveShadowMapBRDFSpecularParameters(int lightIndex, int cubeSide, int i = -1) const
660     { return TexData(getReflectiveShadowMapCubeArrayTex(lightIndex, i), cubeSide, 4, GL_RGBA32F, { "ksr", "ksg", "ksb", "shininess" }, _pbo); }
661
662     /*! \brief Get the texture containing gaussian white noise applied to RGB simulation
663      * results. This is floating point texture where three components contain independent noise values.
664      * The texture returned is for the given subframe \a i or the final result (if \a i is -1). */
665     unsigned int getGaussianWhiteNoiseTex(int i = -1) const;
666
667     /*! \brief Convenience wrapper for \a getGaussianWhiteNoiseTex() */
668     TexData getGaussianWhiteNoise(int i = -1) const
669     { return TexData(getGaussianWhiteNoiseTex(i), -1, -1, GL_RGB32F, { "noise_a", "noise_b", "noise_c" }, _pbo); }
670
671     /*! \brief Get the output texture containing OpenGL depth buffer data
672      * for the given subframe \a i or the final result (if \a i is -1)
673      * Depths of the final result are always the same as those for the first subframe.
674      * Note that depth buffer data is only available if (1) any output other than rgb or pmd is active
675      * or (2) neither spatial nor temporal oversampling is active. */
676     unsigned int getDepthTex(int i = -1) const;
677
678     /*! \brief Convenience wrapper for \a getDepthTex() */
679     TexData getDepth(int i = -1) const
680     { return TexData(getDepthTex(i), -1, -1, GL_R32F, { "gldepth" }, _pbo); }
681
682     /*! \brief Get the output texture containing linear RGB colors
683      * for the given subframe \a i or the final result (if \a i is -1) */
684     unsigned int getRGBTex(int i = -1) const;
685
686     /*! \brief Convenience wrapper for \a getRGBTex() */
687     TexData getRGB(int i = -1) const
688     { return TexData(getRGBTex(i), -1, -1, GL_RGB32F, { "r", "g", "b" }, _pbo); }
689
690     /*! \brief Get the output texture containing sRGB colors
691      * for the given subframe \a i or the final result (if \a i is -1) */
692     unsigned int getSRGBTex(int i = -1) const;
693
694     /*! \brief Convenience wrapper for \a getSRGBTex() */
695     TexData getSRGB(int i = -1) const
696     { return TexData(getSRGBTex(i), -1, -1, GL_RGB8, { "r", "g", "b" }, _pbo); }
697
698     /*! \brief Get the output texture containing PMD simulation
699      * for the given subframe \a i or the final result (if \a i is -1).
700      * The subframe texture will contain a phase image in digital numbers with the
701      * three channels (A-B, A+B, A, B);
702      * the final result will contain simulated range, amplitude, and intensity. */
703     unsigned int getPMDTex(int i = -1) const;
704
705     /*! \brief Convenience wrapper for \a getPMDTex() */
706     TexData getPMD(int i = -1) const
707     {
708         if (i == -1)
709             return TexData(getPMDTex(i), -1, -1, GL_RGB32F, { "range", "amplitude", "intensity" }, _pbo);
710         else
711             return TexData(getPMDTex(i), -1, -1, GL_RGBA32F, { "a_minus_b", "a_plus_b", "a", "b" }, _pbo);
712     }
713
714     /*! \brief Get the output texture containing PMD simulated cartesian
715      * coordinates. These are computed from the simulated PMD range value, taking the camera intrinsic parameters into
716      * account (image size, center pixel and focal lengths). Note that lens distortion is currently ignored. */
717     unsigned int getPMDCoordinatesTex() const;
718
719     /*! \brief Convenience wrapper for \a getPMDCoordinatesTex() */
720     TexData getPMDCoordinates() const
721     {
722         return TexData(getPMDCoordinatesTex(), -1, -1, GL_RGB32F, { "x", "y", "z" }, _pbo);
723     }
724
725     /*! \brief Get the output texture containing eye space positions
726      * for the given subframe \a i or the final result (if \a i is -1).
727      * Positions of the final result are always the same as those for the first subframe. */
728     unsigned int getEyeSpacePositionsTex(int i = -1) const;
729
730     /*! \brief Convenience wrapper for \a getEyeSpacePositionsTex() */
731     TexData getEyeSpacePositions(int i = -1) const
732     { return TexData(getEyeSpacePositionsTex(i), -1, -1, GL_RGB32F, { "x", "y", "z" }, _pbo); }
733
734     /*! \brief Get the output texture containing custom space positions
735      * for the given subframe \a i or the final result (if \a i is -1).
736      * Positions of the final result are always the same as those for the first subframe. */
737     unsigned int getCustomSpacePositionsTex(int i = -1) const;
738
739     /*! \brief Convenience wrapper for \a getCustomSpacePositionsTex() */
740     TexData getCustomSpacePositions(int i = -1) const
741     { return TexData(getCustomSpacePositionsTex(i),-1,  -1, GL_RGB32F, { "x", "y", "z" }, _pbo); }
742
743     /*! \brief Get the output texture containing eye space normals
744      * for the given subframe \a i or the final result (if \a i is -1)
745      * Normals of the final result are always the same as those for the first subframe. */
746     unsigned int getEyeSpaceNormalsTex(int i = -1) const;
747
748     /*! \brief Convenience wrapper for \a getEyeSpaceNormalsTex() */
749     TexData getEyeSpaceNormals(int i = -1) const
750     { return TexData(getEyeSpaceNormalsTex(i), -1, -1, GL_RGB32F, { "nx", "ny", "nz" }, _pbo); }
751
752     /*! \brief Get the output texture containing custom space normals
753      * for the given subframe \a i or the final result (if \a i is -1)
754      * Normals of the final result are always the same as those for the first subframe. */
755     unsigned int getCustomSpaceNormalsTex(int i = -1) const;
756
757     /*! \brief Convenience wrapper for \a getCustomSpaceNormalsTex() */
758     TexData getCustomSpaceNormals(int i = -1) const
759     { return TexData(getCustomSpaceNormalsTex(i), -1, -1, GL_RGB32F, { "nx", "ny", "nz" }, _pbo); }
760
761     /*! \brief Get the output texture containing depth and range
762      * for the given subframe \a i or the final result (if \a i is -1)
763      * Depth and range of the final result are always the same as those for the first subframe. */
764     unsigned int getDepthAndRangeTex(int i = -1) const;
765
766     /*! \brief Convenience wrapper for \a getDepthAndRangeTex() */
767     TexData getDepthAndRange(int i = -1) const
768     { return TexData(getDepthAndRangeTex(i), -1, -1, GL_RG32F, { "depth", "range" }, _pbo); }
769
770     /*! \brief Get the output texture containing indices
771      * for the given subframe \a i or the final result (if \a i is -1)
772      * Indices of the final result are always the same as those for the first subframe.
773      * Note that all indices are incremented by one, so that unrendered areas in the
774      * resulting texture can be identified by checking for index zero (which never corresponds
775      * to a rendered object). */
776     unsigned int getIndicesTex(int i = -1) const;
777
778     /*! \brief Convenience wrapper for \a getIndicesTex() */
779     TexData getIndices(int i = -1) const
780     { return TexData(getIndicesTex(i), -1, -1, GL_RGBA32UI, { "object_index", "shape_index", "triangle_index", "material_index" }, _pbo); }
781
782     /*! \brief Get the output texture containing forward 3D flow
783      * for the given subframe \a i or the final result (if \a i is -1) */
784     unsigned int getForwardFlow3DTex(int i = -1) const;
785
786     /*! \brief Convenience wrapper for \a getForwardFlow3DTex() */
787     TexData getForwardFlow3D(int i = -1) const
788     { return TexData(getForwardFlow3DTex(i), -1, -1, GL_RGB32F, { "flow3d_x", "flow3d_y", "flow3d_z" }, _pbo); }
789
790     /*! \brief Get the output texture containing forward 2D flow
791      * for the given subframe \a i or the final result (if \a i is -1) */
792     unsigned int getForwardFlow2DTex(int i = -1) const;
793
794     /*! \brief Convenience wrapper for \a getForwardFlow2DTex() */
795     TexData getForwardFlow2D(int i = -1) const
796     { return TexData(getForwardFlow2DTex(i), -1, -1, GL_RG32F, { "flow2d_x", "flow2d_y" }, _pbo); }
797
798     /*! \brief Get the output texture containing backward 3D flow
799      * for the given subframe \a i or the final result (if \a i is -1) */
800     unsigned int getBackwardFlow3DTex(int i = -1) const;
801
802     /*! \brief Convenience wrapper for \a getBackwardFlow3DTex() */
803     TexData getBackwardFlow3D(int i = -1) const
804     { return TexData(getBackwardFlow3DTex(i), -1, -1, GL_RGB32F, { "flow3d_x", "flow3d_y", "flow3d_z" }, _pbo); }
805
806     /*! \brief Get the output texture containing backward 2D flow
807      * for the given subframe \a i or the final result (if \a i is -1) */
808     unsigned int getBackwardFlow2DTex(int i = -1) const;
809
810     /*! \brief Convenience wrapper for \a getBackwardFlow2DTex() */
811     TexData getBackwardFlow2D(int i = -1) const
812     { return TexData(getBackwardFlow2DTex(i), -1, -1, GL_RG32F, { "flow2d_x", "flow2d_y" }, _pbo); }
813
814     /*! \brief Get the camera transformation
815      * for the given subframe \a i or the final result (if \a i is -1)
816      * Transformations of the final result are always the same as those for the first subframe. */
817     const Transformation& getCameraTransformation(int i = -1) const;
818
819     /*! \brief Get the transformation for the light source with index \a lightIndex in the scene
820      * for the given subframe \a i or the final result (if \a i is -1)
821      * Transformations of the final result are always the same as those for the first subframe. */
822     const Transformation& getLightTransformation(int lightIndex, int i) const;
823
824     /*! \brief Get the transformation for the object with index \a objectIndex in the scene
825      * for the given subframe \a i or the final result (if \a i is -1)
826      * Transformations of the final result are always the same as those for the first subframe. */
827     const Transformation& getObjectTransformation(int objectIndex, int i) const;
828
829     /*@}*/
830 };
831
832 }
833
834 #endif