1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /**
18  * The Scene class implements a simple physical simulation of a scene, using the
19  * CIE 1931 colorspace to represent light in physical units (lux).
20  *
21  * It's fairly approximate, but does provide a scene with realistic widely
22  * variable illumination levels and colors over time.
23  *
24  */
25 
26 #ifndef HW_EMULATOR_CAMERA2_SCENE_H
27 #define HW_EMULATOR_CAMERA2_SCENE_H
28 
29 #include "utils/Timers.h"
30 
31 namespace android {
32 
33 class Scene {
34  public:
35   Scene(int sensorWidthPx, int sensorHeightPx, float sensorSensitivity);
36   ~Scene();
37 
38   // Set the filter coefficients for the red, green, and blue filters on the
39   // sensor. Used as an optimization to pre-calculate various illuminance
40   // values. Two different green filters can be provided, to account for
41   // possible cross-talk on a Bayer sensor. Must be called before
42   // calculateScene.
43   void setColorFilterXYZ(float rX, float rY, float rZ, float grX, float grY,
44                          float grZ, float gbX, float gbY, float gbZ, float bX,
45                          float bY, float bZ);
46 
47   // Set time of day (24-hour clock). This controls the general light levels
48   // in the scene. Must be called before calculateScene
49   void setHour(int hour);
50   // Get current hour
51   int getHour();
52 
53   // Set the duration of exposure for determining luminous exposure.
54   // Must be called before calculateScene
55   void setExposureDuration(float seconds);
56 
57   // Calculate scene information for current hour and the time offset since
58   // the hour. Must be called at least once before calling getLuminousExposure.
59   // Resets pixel readout location to 0,0
60   void calculateScene(nsecs_t time);
61 
62   // Set sensor pixel readout location.
63   void setReadoutPixel(int x, int y);
64 
65   // Get sensor response in physical units (electrons) for light hitting the
66   // current readout pixel, after passing through color filters. The readout
67   // pixel will be auto-incremented. The returned array can be indexed with
68   // ColorChannels.
69   const uint32_t* getPixelElectrons();
70 
71   enum ColorChannels { R = 0, Gr, Gb, B, Y, Cb, Cr, NUM_CHANNELS };
72 
73  private:
74   // Sensor color filtering coefficients in XYZ
75   float mFilterR[3];
76   float mFilterGr[3];
77   float mFilterGb[3];
78   float mFilterB[3];
79 
80   int mOffsetX, mOffsetY;
81   int mMapDiv;
82 
83   int mHandshakeX, mHandshakeY;
84 
85   int mSensorWidth;
86   int mSensorHeight;
87   int mCurrentX;
88   int mCurrentY;
89   int mSubX;
90   int mSubY;
91   int mSceneX;
92   int mSceneY;
93   int mSceneIdx;
94   uint32_t* mCurrentSceneMaterial;
95 
96   int mHour;
97   float mExposureDuration;
98   float mSensorSensitivity;
99 
100   enum Materials {
101     GRASS = 0,
102     GRASS_SHADOW,
103     HILL,
104     WALL,
105     ROOF,
106     DOOR,
107     CHIMNEY,
108     WINDOW,
109     SUN,
110     SKY,
111     MOON,
112     NUM_MATERIALS
113   };
114 
115   uint32_t mCurrentColors[NUM_MATERIALS * NUM_CHANNELS];
116 
117   /**
118    * Constants for scene definition. These are various degrees of approximate.
119    */
120 
121   // Fake handshake parameters. Two shake frequencies per axis, plus magnitude
122   // as a fraction of a scene tile, and relative magnitudes for the frequencies
123   static const float kHorizShakeFreq1;
124   static const float kHorizShakeFreq2;
125   static const float kVertShakeFreq1;
126   static const float kVertShakeFreq2;
127   static const float kFreq1Magnitude;
128   static const float kFreq2Magnitude;
129 
130   static const float kShakeFraction;
131 
132   // RGB->YUV conversion
133   static const float kRgb2Yuv[12];
134 
135   // Aperture of imaging lens
136   static const float kAperture;
137 
138   // Sun, moon illuminance levels in 2-hour increments. These don't match any
139   // real day anywhere.
140   static const uint32_t kTimeStep = 2;
141   static const float kSunlight[];
142   static const float kMoonlight[];
143   static const int kSunOverhead;
144   static const int kMoonOverhead;
145 
146   // Illumination levels for various conditions, in lux
147   static const float kDirectSunIllum;
148   static const float kDaylightShadeIllum;
149   static const float kSunsetIllum;
150   static const float kTwilightIllum;
151   static const float kFullMoonIllum;
152   static const float kClearNightIllum;
153   static const float kStarIllum;
154   static const float kLivingRoomIllum;
155 
156   // Chromaticity of various illumination sources
157   static const float kIncandescentXY[2];
158   static const float kDirectSunlightXY[2];
159   static const float kDaylightXY[2];
160   static const float kNoonSkyXY[2];
161   static const float kMoonlightXY[2];
162   static const float kSunsetXY[2];
163 
164   static const uint8_t kSelfLit;
165   static const uint8_t kShadowed;
166   static const uint8_t kSky;
167 
168   static const float kMaterials_xyY[NUM_MATERIALS][3];
169   static const uint8_t kMaterialsFlags[NUM_MATERIALS];
170 
171   static const int kSceneWidth;
172   static const int kSceneHeight;
173   static const uint8_t kScene[];
174 };
175 
176 }  // namespace android
177 
178 #endif  // HW_EMULATOR_CAMERA2_SCENE_H
179