c283f537a11c44aaaa3421c1ab5196898b97bbf5
[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 phase image (energy, A tap, B tap)? */
282     bool pmd;
283
284     /*@}*/
285
286     /**
287      * \name Geometry-related simulation output
288      */
289     /*@{*/
290
291     /*! \brief Flag: enable output of eye space positions? */
292     bool eyeSpacePositions;
293     /*! \brief Flag: enable output of custom space positions (see \a Simulator::setCustomTransformation)? */
294     bool customSpacePositions;
295     /*! \brief Flag: enable output of eye space normals? */
296     bool eyeSpaceNormals;
297     /*! \brief Flag: enable output of custom space normals (see \a Simulator::setCustomTransformation)? */
298     bool customSpaceNormals;
299     /*! \brief Flag: enable output of eye space depth and range? */
300     bool depthAndRange;
301     /*! \brief Flag: enable output of indices (object, shape-in-object, triangle-in-shape, material)? */
302     bool indices;
303
304     /*@}*/
305
306     /**
307      * \name Temporal flow-related simulation output
308      */
309     /*@{*/
310
311     /*! \brief Flag: enable output of forward 3D flow (offset from current to next 3D position)? */
312     bool forwardFlow3D;
313     /*! \brief Flag: enable output of forward 2D flow (offset from current to next 2D pixel position)? */
314     bool forwardFlow2D;
315     /*! \brief Flag: enable output of backward 3D flow (offset from current to last 3D position)? */
316     bool backwardFlow3D;
317     /*! \brief Flag: enable output of backward 2D flow (offset from current to last 2D pixel position)? */
318     bool backwardFlow2D;
319
320     /*@}*/
321 };
322
323 /**
324  * \brief Simulates a camera frame
325  */
326 class Simulator {
327 private:
328     // Our random number generator (e.g. for noise generation)
329     std::mt19937 _randomGenerator;
330
331     // The configuration: animated camera and scene
332     Animation _cameraAnimation;
333     Transformation _cameraTransformation;
334     Scene _scene;
335
336     // The configuration: chip and optics
337     ChipTiming _chipTiming;
338     PMD _pmd;
339     Projection _projection;
340
341     // The configuration: rendering pipeline and output
342     Pipeline _pipeline;
343     Output _output;
344     Transformation _customTransformation;
345
346     // Timestamp management
347     bool _recreateTimestamps;
348     long long _startTimestamp;
349     long long _endTimestamp;
350     bool _haveLastFrameTimestamp;
351     long long _lastFrameTimestamp;
352
353     // Shader pipeline management
354     bool _recreateShaders;
355     QOpenGLShaderProgram _shadowMapPrg;          // create shadow map for a single light source
356     QOpenGLShaderProgram _reflectiveShadowMapPrg;// create reflective shadow map for a single light source
357     QOpenGLShaderProgram _depthPrg;              // pre-render the depth buf only
358     QOpenGLShaderProgram _lightPrg;              // simulate rgb and pmd phase for current time stamp
359     QOpenGLShaderProgram _lightOversampledPrg;   // reduce spatially oversampled rgb and pmd phase
360     QOpenGLShaderProgram _pmdDigNumPrg;          // convert energies to PMD digital numbers, possibly with shot noise
361     QOpenGLShaderProgram _gaussianWhiteNoisePrg; // add gaussian white noise
362     QOpenGLShaderProgram _zeroPrg;               // produce all-zero output
363     QOpenGLShaderProgram _rgbResultPrg;          // combine rgb subframes to final result
364     QOpenGLShaderProgram _pmdResultPrg;          // combine pmd phase subframes to final result
365     QOpenGLShaderProgram _geomPrg;               // simulate geometry (pos, normals, depth, range, indices) information
366     QOpenGLShaderProgram _flowPrg;               // simulate 2D/3D flow information
367     QOpenGLShaderProgram _convertToSRGBPrg;      // convert linear RGB to sRGB
368     QOpenGLShaderProgram _postprocLensDistortionPrg; // postprocessing: apply lens distortion
369
370     // Simulation output management
371     bool _recreateOutput;
372     QVector<long long> _timestamps;                              // subFrames
373     QVector<Transformation> _cameraTransformations;              // subFrames
374     QVector<QVector<Transformation>> _lightTransformations;      // subFrames; each contained vector stores one transf for each light source in the scene
375     QVector<QVector<Transformation>> _objectTransformations;     // subFrames; each contained vector stores one transf for each object in the scene
376     QVector<QVector<unsigned int>> _shadowMapDepthBufs;          // subFrames; each contained vector stores one cube depth buffer for each light source
377     QVector<QVector<unsigned int>> _reflectiveShadowMapDepthBufs;// subFrames; each contained vector stores one cube depth buffer for each light source
378     QVector<QVector<unsigned int>> _reflectiveShadowMapTexs;     // subFrames; each contained vector stores one cube array tex with 5 layers for each light source
379     unsigned int _pbo;
380     unsigned int _depthBufferOversampled;
381     unsigned int _rgbTexOversampled;
382     unsigned int _pmdEnergyTexOversampled;
383     unsigned int _pmdEnergyTex;
384     unsigned int _gaussianNoiseTex;               // for shot noise generation, dynamically generated
385     QVector<float> _gaussianWhiteNoiseBuf;        // reused vector to generate gaussian white noise
386     QVector<unsigned int> _gaussianWhiteNoiseTexs;// subFrames
387     QVector<unsigned int> _depthBuffers;          // subFrames+1
388     QVector<unsigned int> _rgbTexs;               // subFrames+1
389     QVector<unsigned int> _srgbTexs;              // subFrames+1
390     QVector<unsigned int> _pmdDigNumTexs;         // subFrames+1
391     QVector<unsigned int> _eyeSpacePosTexs;       // subFrames
392     QVector<unsigned int> _customSpacePosTexs;    // subFrames
393     QVector<unsigned int> _eyeSpaceNormalTexs;    // subFrames
394     QVector<unsigned int> _customSpaceNormalTexs; // subFrames
395     QVector<unsigned int> _depthAndRangeTexs;     // subFrames
396     QVector<unsigned int> _indicesTexs;           // subFrames
397     QVector<unsigned int> _forwardFlow3DTexs;     // subFrames+1
398     QVector<unsigned int> _forwardFlow2DTexs;     // subFrames+1
399     QVector<unsigned int> _backwardFlow3DTexs;    // subFrames+1
400     QVector<unsigned int> _backwardFlow2DTexs;    // subFrames+1
401     QVector<QList<unsigned int>> _lightSimOutputTexs;
402     QVector<QList<unsigned int>> _geomSimOutputTexs;
403     QVector<QList<unsigned int>> _flowSimOutputTexs;
404     QList<unsigned int> _oversampledLightSimOutputTexs;
405     unsigned int _postProcessingTex; // temporary texture for post-processing, e.g. lens distortion
406
407     // Our FBO
408     unsigned int _fbo; // managed by prepareFBO()
409     unsigned int _fullScreenQuadVao; // managed by prepareFBO()
410
411 private:
412     bool spatialOversampling() const;
413     QSize spatialOversamplingSize() const;
414     bool temporalOversampling() const;
415     bool powerTexs() const;
416
417     void recreateTimestampsIfNecessary();
418     void recreateShadersIfNecessary();
419     void prepareDepthBuffers(QSize size, const QVector<unsigned int>& depthBufs);
420     void prepareOutputTexs(QSize size, const QVector<unsigned int>& outputTexs, int internalFormat, bool interpolation);
421     void recreateOutputIfNecessary();
422
423     float lightIntensity(int lightSourceIndex) const;
424
425     void simulateTimestamps(long long t);
426     void simulateSampleTimestamp(long long t,
427             Transformation& cameraTransformation,
428             QVector<Transformation>& lightTransformations,
429             QVector<Transformation>& objectTransformations);
430     void prepareFBO(QSize size, unsigned int depthBuf, bool reuseDepthBufData,
431             const QList<unsigned int>& colorAttachments, int cubeMapSide = -1, int arrayTextureLayers = 0,
432             bool enableBlending = false, bool clearBlendingColorBuffer = true);
433
434     void drawScene(QOpenGLShaderProgram& prg,
435             const QMatrix4x4& projectionMatrix,
436             const QMatrix4x4& viewMatrix,
437             const QMatrix4x4& lastViewMatrix,
438             const QMatrix4x4& nextViewMatrix,
439             const QVector<Transformation>& objectTransformations,
440             const QVector<Transformation>& lastObjectTransformations,
441             const QVector<Transformation>& nextObjectTransformations);
442     void simulate(QOpenGLShaderProgram& prg,
443             int subFrame, long long t, long long lastT, long long nextT, unsigned int lastDepthBuf,
444             const Transformation& cameraTransformation,
445             const QVector<Transformation>& lightTransformations,
446             const QVector<Transformation>& objectTransformations);
447     void simulateShadowMap(bool reflective,
448             int subFrame, int lightIndex,
449             const Transformation& cameraTransformation,
450             const QVector<Transformation>& lightTransformations,
451             const QVector<Transformation>& objectTransformations);
452     void simulateShadowMaps(int subFrame,
453             const Transformation& cameraTransformation,
454             const QVector<Transformation>& lightTransformations,
455             const QVector<Transformation>& objectTransformations);
456     void simulateDepth(int subFrame, long long t,
457             const Transformation& cameraTransformation,
458             const QVector<Transformation>& lightTransformations,
459             const QVector<Transformation>& objectTransformations);
460     void simulateLight(int subFrame, long long t,
461             const Transformation& cameraTransformation,
462             const QVector<Transformation>& lightTransformations,
463             const QVector<Transformation>& objectTransformations);
464     void simulateOversampledLight();
465     void simulatePMDDigNums();
466     void simulateGaussianWhiteNoise(int subFrame);
467     void simulateRGBResult();
468     void simulatePMDResult();
469     void simulateGeometry(int subFrame);
470     void simulateFlow(int subFrame, long long lastT, long long nextT, unsigned int lastDepthBuf);
471     void simulatePostprocLensDistortion(const QList<unsigned int>& textures);
472
473     void convertToSRGB(int texIndex);
474
475     bool haveValidOutput(int i) const;
476     bool haveShadowMap(int lightIndex) const;
477     bool haveReflectiveShadowMap(int lightIndex) const;
478
479 public:
480     /*! \brief Constructor */
481     Simulator();
482
483     /**
484      * \name Configuration: animation and scene
485      */
486     /*@{*/
487
488     /*! \brief Get camera animation */
489     const Animation& cameraAnimation() const { return _cameraAnimation; }
490     /*! \brief Set camera animation */
491     void setCameraAnimation(const Animation& animation);
492
493     /*! \brief Get camera transformation (relative to the camera animation) */
494     const Transformation& cameraTransformation() const { return _cameraTransformation; }
495     /*! \brief Set camera transformation (relative to the camera animation) */
496     void setCameraTransformation(const Transformation& transformation);
497
498     /*! \brief Get scene */
499     const Scene& scene() const { return _scene; }
500     /*! \brief Set scene */
501     void setScene(const Scene& scene);
502
503     /*@}*/
504
505     /**
506      * \name Configuration: chip and optics
507      */
508     /*@{*/
509
510     /*! \brief Get chip timing parameters */
511     const ChipTiming& chipTiming() const { return _chipTiming; }
512     /*! \brief Set chip timing parameters */
513     void setChipTiming(const ChipTiming& chipTiming);
514
515     /*! \brief Get PMD chip parameters */
516     const PMD& pmd() const { return _pmd; }
517     /*! \brief Set PMD chip parameters */
518     void setPMD(const PMD& pmd);
519
520     /*! \brief Get projection parameters */
521     const Projection& projection() const { return _projection; }
522     /*! \brief Set projection parameters */
523     void setProjection(const Projection& projection);
524
525     /*@}*/
526
527     /**
528      * \name Configuration: rendering pipeline and output
529      */
530     /*@{*/
531
532     /*! \brief Get pipeline parameters */
533     const Pipeline& pipeline() const { return _pipeline; }
534     /*! \brief Set pipeline parameters */
535     void setPipeline(const Pipeline& pipeline);
536
537     /*! \brief Get output parameters */
538     const Output& output() const { return _output; }
539     /*! \brief Set output parameters */
540     void setOutput(const Output& output);
541
542     /*! \brief Set custom transformation, for output of custom space position and normals
543      * (see \a Output::customSpacePositions, \a Output::customSpaceNormals).
544      * By default, the custom transformation does nothing, and the custom space is
545      * equivalent to world space. */
546     void setCustomTransformation(const Transformation& transformation);
547
548     /*@}*/
549
550     /**
551      * \name Simulation
552      */
553     /*@{*/
554
555     /*! \brief Get the number of subframes simulated for the current configuration.
556      * This is usually 4 if PMD simulation is active (see \a output), and 1 otherwise. */
557     int subFrames() const;
558
559     /*! \brief Get the start time in microseconds (earliest starting point of all involved animations) */
560     long long startTimestamp();
561     /*! \brief Get the end time in microseconds (latest end point of all involved animations) */
562     long long endTimestamp();
563     /*! \brief Get subframe duration in microseconds (depends on chip timings) */
564     long long subFrameDuration();
565     /*! \brief Get frame duration in microseconds (depends on chip timings and number of subframes) */
566     long long frameDuration();
567     /*! \brief Get frames per second rate (depends on chip timings and number of subframes) */
568     float framesPerSecond();
569     /*! \brief Get the next time stamp in microseconds for simulation via \a simulate(). If you did not call
570      * \a simulate() yet with the current configuration, this will be the same as
571      * \a startTimestamp. Otherwise, it will be the last time stamp passed to \a simulate()
572      * plus the \a frameDuration(). You should stop to call \a simulate() once the returned
573      * time stamp is later than \a endTimestamp(). */
574     long long nextFrameTimestamp();
575
576     /*! \brief Simulate a camera frame at the time given by \a frameTimestamp.
577      *
578      * This function simulates a camera viewing the scene using the current
579      * configuration at the given point in time.
580      *
581      * It uses its own internal framebuffer object and manages its own textures
582      * for simulation results. You can get these textures individually.
583      *
584      * If the simulation requires the simulation of subframes, then all subframes
585      * and the final result frame are simulated in one step, but the results
586      * from every subframe remain accessible. For example, if PMD simulation is
587      * activated (see \a output), then the four phase images as well as the final
588      * result are simulated in one step.
589      */
590     void simulate(long long frameTimestamp);
591
592     /*@}*/
593
594     /**
595      * \name Retrieving simulation results
596      *
597      * Many of these function return texture handles. See the \a TexData class
598      * on how to access the data within the texture conveniently, and the \a Exporter class
599      * on how to write the data to various file formats.
600      */
601     /*@{*/
602
603     /*! \brief Get the time stamp associated with the given subframe \a i or the final
604      * result (if \a i is -1; however, this is always the same as for subframe 0). */
605     long long getTimestamp(int i = -1) const;
606
607     /*! \brief Get the texture containing the shadow map cube
608      * for the light source with index \a lightIndex in the scene
609      * for the given subframe \a i or the final result (if \a i is -1).
610      * Shadow maps for the final result are always the same as those for the first subframe. */
611     unsigned int getShadowMapCubeTex(int lightIndex, int i = -1) const;
612
613     /*! \brief Convenience wrapper for \a getShadowMapTex().
614      * 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). */
615     TexData getShadowMap(int lightIndex, int cubeSide, int i = -1) const
616     { return TexData(getShadowMapCubeTex(lightIndex, i), cubeSide, -1, GL_R32F, { "gldepth" }, _pbo); }
617
618     /*! \brief Get the cube array texture containing the reflective shadow map information
619      * for the light source with index \a lightIndex in the scene,
620      * for the given subframe \a i or the final result (if \a i is -1).
621      * Shadow maps for the final result are always the same as those for the first subframe.
622      * The cube array texture contains the following layers:
623      * - 0: Positions in camera space (not light space and not world space)
624      * - 1: Normals in camera space
625      * - 2: Radiances for r, g, b, and power
626      * - 3: BRDF diffuse parameters kd_r, kd_g, kd_b
627      * - 4: BRDF specular parameters ks_r, ks_g, ks_b, shininess
628      */
629     unsigned int getReflectiveShadowMapCubeArrayTex(int lightIndex, int i = -1) const;
630
631     /*! \brief Convenience wrapper for \a getReflectiveShadowMapTex()
632      * that gets the position data.
633      * 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). */
634     TexData getReflectiveShadowMapPositions(int lightIndex, int cubeSide, int i = -1) const
635     { return TexData(getReflectiveShadowMapCubeArrayTex(lightIndex, i), cubeSide, 0, GL_RGB32F, { "x", "y", "z" }, _pbo); }
636
637     /*! \brief Convenience wrapper for \a getReflectiveShadowMapTex()
638      * that gets the normal data. */
639     TexData getReflectiveShadowMapNormals(int lightIndex, int cubeSide, int i = -1) const
640     { return TexData(getReflectiveShadowMapCubeArrayTex(lightIndex, i), cubeSide, 1, GL_RGB32F, { "nx", "ny", "nz" }, _pbo); }
641
642     /*! \brief Convenience wrapper for \a getReflectiveShadowMapTex()
643      * that gets the radiance data. */
644     TexData getReflectiveShadowMapRadiances(int lightIndex, int cubeSide, int i = -1) const
645     { return TexData(getReflectiveShadowMapCubeArrayTex(lightIndex, i), cubeSide, 2, GL_RGBA32F, { "r", "g", "b", "radiances" }, _pbo); }
646
647     /*! \brief Convenience wrapper for \a getReflectiveShadowMapTex()
648      * that gets the BRDF diffuse parameter data. */
649     TexData getReflectiveShadowMapBRDFDiffuseParameters(int lightIndex, int cubeSide, int i = -1) const
650     { return TexData(getReflectiveShadowMapCubeArrayTex(lightIndex, i), cubeSide, 3, GL_RGB32F, { "kdr", "kdg", "kdb" }, _pbo); }
651
652     /*! \brief Convenience wrapper for \a getReflectiveShadowMapTex()
653      * that gets the BRDF specular parameter data. */
654     TexData getReflectiveShadowMapBRDFSpecularParameters(int lightIndex, int cubeSide, int i = -1) const
655     { return TexData(getReflectiveShadowMapCubeArrayTex(lightIndex, i), cubeSide, 4, GL_RGBA32F, { "ksr", "ksg", "ksb", "shininess" }, _pbo); }
656
657     /*! \brief Get the texture containing gaussian white noise applied to RGB simulation
658      * results. This is floating point texture where three components contain independent noise values.
659      * The texture returned is for the given subframe \a i or the final result (if \a i is -1). */
660     unsigned int getGaussianWhiteNoiseTex(int i = -1) const;
661
662     /*! \brief Convenience wrapper for \a getGaussianWhiteNoiseTex() */
663     TexData getGaussianWhiteNoise(int i = -1) const
664     { return TexData(getGaussianWhiteNoiseTex(i), -1, -1, GL_RGB32F, { "noise_a", "noise_b", "noise_c" }, _pbo); }
665
666     /*! \brief Get the output texture containing OpenGL depth buffer data
667      * for the given subframe \a i or the final result (if \a i is -1)
668      * Depths of the final result are always the same as those for the first subframe.
669      * Note that depth buffer data is only available if (1) any output other than rgb or pmd is active
670      * or (2) neither spatial nor temporal oversampling is active. */
671     unsigned int getDepthTex(int i = -1) const;
672
673     /*! \brief Convenience wrapper for \a getDepthTex() */
674     TexData getDepth(int i = -1) const
675     { return TexData(getDepthTex(i), -1, -1, GL_R32F, { "gldepth" }, _pbo); }
676
677     /*! \brief Get the output texture containing linear RGB colors
678      * for the given subframe \a i or the final result (if \a i is -1) */
679     unsigned int getRGBTex(int i = -1) const;
680
681     /*! \brief Convenience wrapper for \a getRGBTex() */
682     TexData getRGB(int i = -1) const
683     { return TexData(getRGBTex(i), -1, -1, GL_RGB32F, { "r", "g", "b" }, _pbo); }
684
685     /*! \brief Get the output texture containing sRGB colors
686      * for the given subframe \a i or the final result (if \a i is -1) */
687     unsigned int getSRGBTex(int i = -1) const;
688
689     /*! \brief Convenience wrapper for \a getSRGBTex() */
690     TexData getSRGB(int i = -1) const
691     { return TexData(getSRGBTex(i), -1, -1, GL_RGB8, { "r", "g", "b" }, _pbo); }
692
693     /*! \brief Get the output texture containing PMD simulation
694      * for the given subframe \a i or the final result (if \a i is -1).
695      * The subframe texture will contain a phase image in digital numbers with the
696      * three channels (A-B, A+B, A, B);
697      * the final result will contain simulated range, amplitude, and intensity. */
698     unsigned int getPMDTex(int i = -1) const;
699
700     /*! \brief Convenience wrapper for \a getPMDTex() */
701     TexData getPMD(int i = -1) const
702     {
703         if (i == -1)
704             return TexData(getPMDTex(i), -1, -1, GL_RGB32F, { "range", "amplitude", "intensity" }, _pbo);
705         else
706             return TexData(getPMDTex(i), -1, -1, GL_RGBA32F, { "a_minus_b", "a_plus_b", "a", "b" }, _pbo);
707     }
708
709     /*! \brief Get the output texture containing eye space positions
710      * for the given subframe \a i or the final result (if \a i is -1).
711      * Positions of the final result are always the same as those for the first subframe. */
712     unsigned int getEyeSpacePositionsTex(int i = -1) const;
713
714     /*! \brief Convenience wrapper for \a getEyeSpacePositionsTex() */
715     TexData getEyeSpacePositions(int i = -1) const
716     { return TexData(getEyeSpacePositionsTex(i), -1, -1, GL_RGB32F, { "x", "y", "z" }, _pbo); }
717
718     /*! \brief Get the output texture containing custom space positions
719      * for the given subframe \a i or the final result (if \a i is -1).
720      * Positions of the final result are always the same as those for the first subframe. */
721     unsigned int getCustomSpacePositionsTex(int i = -1) const;
722
723     /*! \brief Convenience wrapper for \a getCustomSpacePositionsTex() */
724     TexData getCustomSpacePositions(int i = -1) const
725     { return TexData(getCustomSpacePositionsTex(i),-1,  -1, GL_RGB32F, { "x", "y", "z" }, _pbo); }
726
727     /*! \brief Get the output texture containing eye space normals
728      * for the given subframe \a i or the final result (if \a i is -1)
729      * Normals of the final result are always the same as those for the first subframe. */
730     unsigned int getEyeSpaceNormalsTex(int i = -1) const;
731
732     /*! \brief Convenience wrapper for \a getEyeSpaceNormalsTex() */
733     TexData getEyeSpaceNormals(int i = -1) const
734     { return TexData(getEyeSpaceNormalsTex(i), -1, -1, GL_RGB32F, { "nx", "ny", "nz" }, _pbo); }
735
736     /*! \brief Get the output texture containing custom space normals
737      * for the given subframe \a i or the final result (if \a i is -1)
738      * Normals of the final result are always the same as those for the first subframe. */
739     unsigned int getCustomSpaceNormalsTex(int i = -1) const;
740
741     /*! \brief Convenience wrapper for \a getCustomSpaceNormalsTex() */
742     TexData getCustomSpaceNormals(int i = -1) const
743     { return TexData(getCustomSpaceNormalsTex(i), -1, -1, GL_RGB32F, { "nx", "ny", "nz" }, _pbo); }
744
745     /*! \brief Get the output texture containing depth and range
746      * for the given subframe \a i or the final result (if \a i is -1)
747      * Depth and range of the final result are always the same as those for the first subframe. */
748     unsigned int getDepthAndRangeTex(int i = -1) const;
749
750     /*! \brief Convenience wrapper for \a getDepthAndRangeTex() */
751     TexData getDepthAndRange(int i = -1) const
752     { return TexData(getDepthAndRangeTex(i), -1, -1, GL_RG32F, { "depth", "range" }, _pbo); }
753
754     /*! \brief Get the output texture containing indices
755      * for the given subframe \a i or the final result (if \a i is -1)
756      * Indices of the final result are always the same as those for the first subframe.
757      * Note that all indices are incremented by one, so that unrendered areas in the
758      * resulting texture can be identified by checking for index zero (which never corresponds
759      * to a rendered object). */
760     unsigned int getIndicesTex(int i = -1) const;
761
762     /*! \brief Convenience wrapper for \a getIndicesTex() */
763     TexData getIndices(int i = -1) const
764     { return TexData(getIndicesTex(i), -1, -1, GL_RGBA32UI, { "object_index", "shape_index", "triangle_index", "material_index" }, _pbo); }
765
766     /*! \brief Get the output texture containing forward 3D flow
767      * for the given subframe \a i or the final result (if \a i is -1) */
768     unsigned int getForwardFlow3DTex(int i = -1) const;
769
770     /*! \brief Convenience wrapper for \a getForwardFlow3DTex() */
771     TexData getForwardFlow3D(int i = -1) const
772     { return TexData(getForwardFlow3DTex(i), -1, -1, GL_RGB32F, { "flow3d_x", "flow3d_y", "flow3d_z" }, _pbo); }
773
774     /*! \brief Get the output texture containing forward 2D flow
775      * for the given subframe \a i or the final result (if \a i is -1) */
776     unsigned int getForwardFlow2DTex(int i = -1) const;
777
778     /*! \brief Convenience wrapper for \a getForwardFlow2DTex() */
779     TexData getForwardFlow2D(int i = -1) const
780     { return TexData(getForwardFlow2DTex(i), -1, -1, GL_RG32F, { "flow2d_x", "flow2d_y" }, _pbo); }
781
782     /*! \brief Get the output texture containing backward 3D flow
783      * for the given subframe \a i or the final result (if \a i is -1) */
784     unsigned int getBackwardFlow3DTex(int i = -1) const;
785
786     /*! \brief Convenience wrapper for \a getBackwardFlow3DTex() */
787     TexData getBackwardFlow3D(int i = -1) const
788     { return TexData(getBackwardFlow3DTex(i), -1, -1, GL_RGB32F, { "flow3d_x", "flow3d_y", "flow3d_z" }, _pbo); }
789
790     /*! \brief Get the output texture containing backward 2D flow
791      * for the given subframe \a i or the final result (if \a i is -1) */
792     unsigned int getBackwardFlow2DTex(int i = -1) const;
793
794     /*! \brief Convenience wrapper for \a getBackwardFlow2DTex() */
795     TexData getBackwardFlow2D(int i = -1) const
796     { return TexData(getBackwardFlow2DTex(i), -1, -1, GL_RG32F, { "flow2d_x", "flow2d_y" }, _pbo); }
797
798     /*! \brief Get the camera transformation
799      * for the given subframe \a i or the final result (if \a i is -1)
800      * Transformations of the final result are always the same as those for the first subframe. */
801     const Transformation& getCameraTransformation(int i = -1) const;
802
803     /*! \brief Get the transformation for the light source with index \a lightIndex in the scene
804      * for the given subframe \a i or the final result (if \a i is -1)
805      * Transformations of the final result are always the same as those for the first subframe. */
806     const Transformation& getLightTransformation(int lightIndex, int i) const;
807
808     /*! \brief Get the transformation for the object with index \a objectIndex in the scene
809      * for the given subframe \a i or the final result (if \a i is -1)
810      * Transformations of the final result are always the same as those for the first subframe. */
811     const Transformation& getObjectTransformation(int objectIndex, int i) const;
812
813     /*@}*/
814 };
815
816 }
817
818 #endif