blob: df02691354d16bb2f1f2abb0126a7ee6db7a2689 [file] [log] [blame]
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* The Scene class implements a simple physical simulation of a scene, using the
* CIE 1931 colorspace to represent light in physical units (lux).
*
* It's fairly approximate, but does provide a scene with realistic widely
* variable illumination levels and colors over time.
*
*/
#ifndef HW_EMULATOR_CAMERA2_SCENE_H
#define HW_EMULATOR_CAMERA2_SCENE_H
#include "utils/Timers.h"
namespace android {
class Scene {
public:
Scene(int sensorWidthPx,
int sensorHeightPx,
float sensorSensitivity);
~Scene();
// Set the filter coefficients for the red, green, and blue filters on the
// sensor. Used as an optimization to pre-calculate various illuminance
// values. Two different green filters can be provided, to account for
// possible cross-talk on a Bayer sensor. Must be called before
// calculateScene.
void setColorFilterXYZ(
float rX, float rY, float rZ,
float grX, float grY, float grZ,
float gbX, float gbY, float gbZ,
float bX, float bY, float bZ);
// Set time of day (24-hour clock). This controls the general light levels
// in the scene. Must be called before calculateScene
void setHour(int hour);
// Get current hour
int getHour();
// Set the duration of exposure for determining luminous exposure.
// Must be called before calculateScene
void setExposureDuration(float seconds);
// Calculate scene information for current hour and the time offset since
// the hour. Must be called at least once before calling getLuminousExposure.
// Resets pixel readout location to 0,0
void calculateScene(nsecs_t time);
// Set sensor pixel readout location.
inline void setReadoutPixel(int x, int y) {
mCurrentX = x;
mCurrentY = y;
mSubX = (x + mOffsetX + mHandshakeX) % mMapDiv;
mSubY = (y + mOffsetY + mHandshakeY) % mMapDiv;
mSceneX = (x + mOffsetX + mHandshakeX) / mMapDiv;
mSceneY = (y + mOffsetY + mHandshakeY) / mMapDiv;
mSceneIdx = mSceneY * kSceneWidth + mSceneX;
mCurrentSceneMaterial = &(mCurrentColors[kScene[mSceneIdx]]);
}
// Get sensor response in physical units (electrons) for light hitting the
// current readout pixel, after passing through color filters. The readout
// pixel will be auto-incremented. The returned array can be indexed with
// ColorChannels.
inline const uint32_t* getPixelElectrons() {
const uint32_t *pixel = mCurrentSceneMaterial;
mCurrentX++;
mSubX++;
if (mCurrentX >= mSensorWidth) {
mCurrentX = 0;
mCurrentY++;
if (mCurrentY >= mSensorHeight) mCurrentY = 0;
setReadoutPixel(mCurrentX, mCurrentY);
} else if (mSubX > mMapDiv) {
mSceneIdx++;
mSceneX++;
mCurrentSceneMaterial = &(mCurrentColors[kScene[mSceneIdx]]);
mSubX = 0;
}
return pixel;
}
enum ColorChannels {
R = 0,
Gr,
Gb,
B,
Y,
Cb,
Cr,
NUM_CHANNELS
};
private:
// Sensor color filtering coefficients in XYZ
float mFilterR[3];
float mFilterGr[3];
float mFilterGb[3];
float mFilterB[3];
int mOffsetX, mOffsetY;
int mMapDiv;
int mHandshakeX, mHandshakeY;
int mSensorWidth;
int mSensorHeight;
int mCurrentX;
int mCurrentY;
int mSubX;
int mSubY;
int mSceneX;
int mSceneY;
int mSceneIdx;
uint32_t *mCurrentSceneMaterial;
int mHour;
float mExposureDuration;
//float mSensorSensitivity;
enum Materials {
GRASS = 0,
GRASS_SHADOW,
HILL,
WALL,
ROOF,
DOOR,
CHIMNEY,
WINDOW,
SUN,
SKY,
MOON,
NUM_MATERIALS
};
uint32_t mCurrentColors[NUM_MATERIALS*NUM_CHANNELS];
/**
* Constants for scene definition. These are various degrees of approximate.
*/
// Fake handshake parameters. Two shake frequencies per axis, plus magnitude
// as a fraction of a scene tile, and relative magnitudes for the frequencies
static const float kHorizShakeFreq1;
static const float kHorizShakeFreq2;
static const float kVertShakeFreq1;
static const float kVertShakeFreq2;
static const float kFreq1Magnitude;
static const float kFreq2Magnitude;
static const float kShakeFraction;
// RGB->YUV conversion
static const float kRgb2Yuv[12];
// Aperture of imaging lens
static const float kAperture;
// Sun, moon illuminance levels in 2-hour increments. These don't match any
// real day anywhere.
static const uint32_t kTimeStep = 2;
static const float kSunlight[];
static const float kMoonlight[];
static const int kSunOverhead;
static const int kMoonOverhead;
// Illumination levels for various conditions, in lux
static const float kDirectSunIllum;
static const float kDaylightShadeIllum;
static const float kSunsetIllum;
static const float kTwilightIllum;
static const float kFullMoonIllum;
static const float kClearNightIllum;
static const float kStarIllum;
static const float kLivingRoomIllum;
// Chromaticity of various illumination sources
static const float kIncandescentXY[2];
static const float kDirectSunlightXY[2];
static const float kDaylightXY[2];
static const float kNoonSkyXY[2];
static const float kMoonlightXY[2];
static const float kSunsetXY[2];
static const uint8_t kSelfLit;
static const uint8_t kShadowed;
static const uint8_t kSky;
static const float kMaterials_xyY[NUM_MATERIALS][3];
static const uint8_t kMaterialsFlags[NUM_MATERIALS];
static const int kSceneWidth;
static const int kSceneHeight;
static const uint8_t kScene[];
};
}
#endif // HW_EMULATOR_CAMERA2_SCENE_H