18a94683196406b83b14218d1beef66067f126a16keunyoung/*
28a94683196406b83b14218d1beef66067f126a16keunyoung * Copyright (C) 2012 The Android Open Source Project
38a94683196406b83b14218d1beef66067f126a16keunyoung *
48a94683196406b83b14218d1beef66067f126a16keunyoung * Licensed under the Apache License, Version 2.0 (the "License");
58a94683196406b83b14218d1beef66067f126a16keunyoung * you may not use this file except in compliance with the License.
68a94683196406b83b14218d1beef66067f126a16keunyoung * You may obtain a copy of the License at
78a94683196406b83b14218d1beef66067f126a16keunyoung *
88a94683196406b83b14218d1beef66067f126a16keunyoung *      http://www.apache.org/licenses/LICENSE-2.0
98a94683196406b83b14218d1beef66067f126a16keunyoung *
108a94683196406b83b14218d1beef66067f126a16keunyoung * Unless required by applicable law or agreed to in writing, software
118a94683196406b83b14218d1beef66067f126a16keunyoung * distributed under the License is distributed on an "AS IS" BASIS,
128a94683196406b83b14218d1beef66067f126a16keunyoung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138a94683196406b83b14218d1beef66067f126a16keunyoung * See the License for the specific language governing permissions and
148a94683196406b83b14218d1beef66067f126a16keunyoung * limitations under the License.
158a94683196406b83b14218d1beef66067f126a16keunyoung */
168a94683196406b83b14218d1beef66067f126a16keunyoung
178a94683196406b83b14218d1beef66067f126a16keunyoung//#define LOG_NDEBUG 0
188a94683196406b83b14218d1beef66067f126a16keunyoung#define LOG_TAG "EmulatedCamera_Scene"
198a94683196406b83b14218d1beef66067f126a16keunyoung#include <utils/Log.h>
208a94683196406b83b14218d1beef66067f126a16keunyoung#include <stdlib.h>
215e936df9ce247b8bd0964dabb4369ea45875c825Eino-Ville Talvala#include <cmath>
228a94683196406b83b14218d1beef66067f126a16keunyoung#include "Scene.h"
238a94683196406b83b14218d1beef66067f126a16keunyoung
248a94683196406b83b14218d1beef66067f126a16keunyoung// TODO: This should probably be done host-side in OpenGL for speed and better
258a94683196406b83b14218d1beef66067f126a16keunyoung// quality
268a94683196406b83b14218d1beef66067f126a16keunyoung
278a94683196406b83b14218d1beef66067f126a16keunyoungnamespace android {
288a94683196406b83b14218d1beef66067f126a16keunyoung
298a94683196406b83b14218d1beef66067f126a16keunyoung// Define single-letter shortcuts for scene definition, for directly indexing
308a94683196406b83b14218d1beef66067f126a16keunyoung// mCurrentColors
318a94683196406b83b14218d1beef66067f126a16keunyoung#define G (Scene::GRASS * Scene::NUM_CHANNELS)
328a94683196406b83b14218d1beef66067f126a16keunyoung#define S (Scene::GRASS_SHADOW * Scene::NUM_CHANNELS)
338a94683196406b83b14218d1beef66067f126a16keunyoung#define H (Scene::HILL * Scene::NUM_CHANNELS)
348a94683196406b83b14218d1beef66067f126a16keunyoung#define W (Scene::WALL * Scene::NUM_CHANNELS)
358a94683196406b83b14218d1beef66067f126a16keunyoung#define R (Scene::ROOF * Scene::NUM_CHANNELS)
368a94683196406b83b14218d1beef66067f126a16keunyoung#define D (Scene::DOOR * Scene::NUM_CHANNELS)
378a94683196406b83b14218d1beef66067f126a16keunyoung#define C (Scene::CHIMNEY * Scene::NUM_CHANNELS)
388a94683196406b83b14218d1beef66067f126a16keunyoung#define I (Scene::WINDOW * Scene::NUM_CHANNELS)
398a94683196406b83b14218d1beef66067f126a16keunyoung#define U (Scene::SUN * Scene::NUM_CHANNELS)
408a94683196406b83b14218d1beef66067f126a16keunyoung#define K (Scene::SKY * Scene::NUM_CHANNELS)
418a94683196406b83b14218d1beef66067f126a16keunyoung#define M (Scene::MOON * Scene::NUM_CHANNELS)
428a94683196406b83b14218d1beef66067f126a16keunyoung
438a94683196406b83b14218d1beef66067f126a16keunyoungconst int Scene::kSceneWidth = 20;
448a94683196406b83b14218d1beef66067f126a16keunyoungconst int Scene::kSceneHeight = 20;
458a94683196406b83b14218d1beef66067f126a16keunyoung
468a94683196406b83b14218d1beef66067f126a16keunyoungconst uint8_t Scene::kScene[Scene::kSceneWidth * Scene::kSceneHeight] = {
478a94683196406b83b14218d1beef66067f126a16keunyoung    //      5         10        15        20
488a94683196406b83b14218d1beef66067f126a16keunyoung    K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,
498a94683196406b83b14218d1beef66067f126a16keunyoung    K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,
508a94683196406b83b14218d1beef66067f126a16keunyoung    K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,
518a94683196406b83b14218d1beef66067f126a16keunyoung    K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,
528a94683196406b83b14218d1beef66067f126a16keunyoung    K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K, // 5
538a94683196406b83b14218d1beef66067f126a16keunyoung    K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,
548a94683196406b83b14218d1beef66067f126a16keunyoung    K,K,K,K,K,K,K,K,H,H,H,H,H,H,H,H,H,H,H,H,
558a94683196406b83b14218d1beef66067f126a16keunyoung    K,K,K,K,K,K,K,K,H,H,H,H,H,H,H,C,C,H,H,H,
568a94683196406b83b14218d1beef66067f126a16keunyoung    K,K,K,K,K,K,H,H,H,H,H,H,H,H,H,C,C,H,H,H,
578a94683196406b83b14218d1beef66067f126a16keunyoung    H,K,K,K,K,K,H,R,R,R,R,R,R,R,R,R,R,R,R,H, // 10
588a94683196406b83b14218d1beef66067f126a16keunyoung    H,K,K,K,K,H,H,R,R,R,R,R,R,R,R,R,R,R,R,H,
598a94683196406b83b14218d1beef66067f126a16keunyoung    H,H,H,K,K,H,H,R,R,R,R,R,R,R,R,R,R,R,R,H,
608a94683196406b83b14218d1beef66067f126a16keunyoung    H,H,H,K,K,H,H,H,W,W,W,W,W,W,W,W,W,W,H,H,
618a94683196406b83b14218d1beef66067f126a16keunyoung    S,S,S,G,G,S,S,S,W,W,W,W,W,W,W,W,W,W,S,S,
628a94683196406b83b14218d1beef66067f126a16keunyoung    S,G,G,G,G,S,S,S,W,I,I,W,D,D,W,I,I,W,S,S, // 15
638a94683196406b83b14218d1beef66067f126a16keunyoung    G,G,G,G,G,G,S,S,W,I,I,W,D,D,W,I,I,W,S,S,
648a94683196406b83b14218d1beef66067f126a16keunyoung    G,G,G,G,G,G,G,G,W,W,W,W,D,D,W,W,W,W,G,G,
658a94683196406b83b14218d1beef66067f126a16keunyoung    G,G,G,G,G,G,G,G,W,W,W,W,D,D,W,W,W,W,G,G,
668a94683196406b83b14218d1beef66067f126a16keunyoung    G,G,G,G,G,G,G,G,S,S,S,S,S,S,S,S,S,S,G,G,
678a94683196406b83b14218d1beef66067f126a16keunyoung    G,G,G,G,G,G,G,G,S,S,S,S,S,S,S,S,S,S,G,G, // 20
688a94683196406b83b14218d1beef66067f126a16keunyoung    //      5         10        15        20
698a94683196406b83b14218d1beef66067f126a16keunyoung};
708a94683196406b83b14218d1beef66067f126a16keunyoung
718a94683196406b83b14218d1beef66067f126a16keunyoung#undef G
728a94683196406b83b14218d1beef66067f126a16keunyoung#undef S
738a94683196406b83b14218d1beef66067f126a16keunyoung#undef H
748a94683196406b83b14218d1beef66067f126a16keunyoung#undef W
758a94683196406b83b14218d1beef66067f126a16keunyoung#undef R
768a94683196406b83b14218d1beef66067f126a16keunyoung#undef D
778a94683196406b83b14218d1beef66067f126a16keunyoung#undef C
788a94683196406b83b14218d1beef66067f126a16keunyoung#undef I
798a94683196406b83b14218d1beef66067f126a16keunyoung#undef U
808a94683196406b83b14218d1beef66067f126a16keunyoung#undef K
818a94683196406b83b14218d1beef66067f126a16keunyoung#undef M
828a94683196406b83b14218d1beef66067f126a16keunyoung
838a94683196406b83b14218d1beef66067f126a16keunyoungScene::Scene(
848a94683196406b83b14218d1beef66067f126a16keunyoung    int sensorWidthPx,
858a94683196406b83b14218d1beef66067f126a16keunyoung    int sensorHeightPx,
868a94683196406b83b14218d1beef66067f126a16keunyoung    float sensorSensitivity):
878a94683196406b83b14218d1beef66067f126a16keunyoung        mSensorWidth(sensorWidthPx),
888a94683196406b83b14218d1beef66067f126a16keunyoung        mSensorHeight(sensorHeightPx),
898a94683196406b83b14218d1beef66067f126a16keunyoung        mHour(12),
908a94683196406b83b14218d1beef66067f126a16keunyoung        mExposureDuration(0.033f),
918a94683196406b83b14218d1beef66067f126a16keunyoung        mSensorSensitivity(sensorSensitivity)
928a94683196406b83b14218d1beef66067f126a16keunyoung{
938a94683196406b83b14218d1beef66067f126a16keunyoung    // Map scene to sensor pixels
948a94683196406b83b14218d1beef66067f126a16keunyoung    if (mSensorWidth > mSensorHeight) {
958a94683196406b83b14218d1beef66067f126a16keunyoung        mMapDiv = (mSensorWidth / (kSceneWidth + 1) ) + 1;
968a94683196406b83b14218d1beef66067f126a16keunyoung    } else {
978a94683196406b83b14218d1beef66067f126a16keunyoung        mMapDiv = (mSensorHeight / (kSceneHeight + 1) ) + 1;
988a94683196406b83b14218d1beef66067f126a16keunyoung    }
998a94683196406b83b14218d1beef66067f126a16keunyoung    mOffsetX = (kSceneWidth * mMapDiv - mSensorWidth) / 2;
1008a94683196406b83b14218d1beef66067f126a16keunyoung    mOffsetY = (kSceneHeight * mMapDiv - mSensorHeight) / 2;
1018a94683196406b83b14218d1beef66067f126a16keunyoung
1028a94683196406b83b14218d1beef66067f126a16keunyoung    // Assume that sensor filters are sRGB primaries to start
1038a94683196406b83b14218d1beef66067f126a16keunyoung    mFilterR[0]  =  3.2406f; mFilterR[1]  = -1.5372f; mFilterR[2]  = -0.4986f;
1048a94683196406b83b14218d1beef66067f126a16keunyoung    mFilterGr[0] = -0.9689f; mFilterGr[1] =  1.8758f; mFilterGr[2] =  0.0415f;
1058a94683196406b83b14218d1beef66067f126a16keunyoung    mFilterGb[0] = -0.9689f; mFilterGb[1] =  1.8758f; mFilterGb[2] =  0.0415f;
1068a94683196406b83b14218d1beef66067f126a16keunyoung    mFilterB[0]  =  0.0557f; mFilterB[1]  = -0.2040f; mFilterB[2]  =  1.0570f;
1078a94683196406b83b14218d1beef66067f126a16keunyoung
1088a94683196406b83b14218d1beef66067f126a16keunyoung
1098a94683196406b83b14218d1beef66067f126a16keunyoung}
1108a94683196406b83b14218d1beef66067f126a16keunyoung
1118a94683196406b83b14218d1beef66067f126a16keunyoungScene::~Scene() {
1128a94683196406b83b14218d1beef66067f126a16keunyoung}
1138a94683196406b83b14218d1beef66067f126a16keunyoung
1148a94683196406b83b14218d1beef66067f126a16keunyoungvoid Scene::setColorFilterXYZ(
1158a94683196406b83b14218d1beef66067f126a16keunyoung        float rX, float rY, float rZ,
1168a94683196406b83b14218d1beef66067f126a16keunyoung        float grX, float grY, float grZ,
1178a94683196406b83b14218d1beef66067f126a16keunyoung        float gbX, float gbY, float gbZ,
1188a94683196406b83b14218d1beef66067f126a16keunyoung        float bX, float bY, float bZ) {
1198a94683196406b83b14218d1beef66067f126a16keunyoung    mFilterR[0]  = rX;  mFilterR[1]  = rY;  mFilterR[2]  = rZ;
1208a94683196406b83b14218d1beef66067f126a16keunyoung    mFilterGr[0] = grX; mFilterGr[1] = grY; mFilterGr[2] = grZ;
1218a94683196406b83b14218d1beef66067f126a16keunyoung    mFilterGb[0] = gbX; mFilterGb[1] = gbY; mFilterGb[2] = gbZ;
1228a94683196406b83b14218d1beef66067f126a16keunyoung    mFilterB[0]  = bX;  mFilterB[1]  = bY;  mFilterB[2]  = bZ;
1238a94683196406b83b14218d1beef66067f126a16keunyoung}
1248a94683196406b83b14218d1beef66067f126a16keunyoung
1258a94683196406b83b14218d1beef66067f126a16keunyoungvoid Scene::setHour(int hour) {
1268a94683196406b83b14218d1beef66067f126a16keunyoung    ALOGV("Hour set to: %d", hour);
1278a94683196406b83b14218d1beef66067f126a16keunyoung    mHour = hour % 24;
1288a94683196406b83b14218d1beef66067f126a16keunyoung}
1298a94683196406b83b14218d1beef66067f126a16keunyoung
1308a94683196406b83b14218d1beef66067f126a16keunyoungint Scene::getHour() {
1318a94683196406b83b14218d1beef66067f126a16keunyoung    return mHour;
1328a94683196406b83b14218d1beef66067f126a16keunyoung}
1338a94683196406b83b14218d1beef66067f126a16keunyoung
1348a94683196406b83b14218d1beef66067f126a16keunyoungvoid Scene::setExposureDuration(float seconds) {
1358a94683196406b83b14218d1beef66067f126a16keunyoung    mExposureDuration = seconds;
1368a94683196406b83b14218d1beef66067f126a16keunyoung}
1378a94683196406b83b14218d1beef66067f126a16keunyoung
1388a94683196406b83b14218d1beef66067f126a16keunyoungvoid Scene::calculateScene(nsecs_t time) {
1398a94683196406b83b14218d1beef66067f126a16keunyoung    // Calculate time fractions for interpolation
1408a94683196406b83b14218d1beef66067f126a16keunyoung    int timeIdx = mHour / kTimeStep;
1418a94683196406b83b14218d1beef66067f126a16keunyoung    int nextTimeIdx = (timeIdx + 1) % (24 / kTimeStep);
1428a94683196406b83b14218d1beef66067f126a16keunyoung    const nsecs_t kOneHourInNsec = 1e9 * 60 * 60;
1438a94683196406b83b14218d1beef66067f126a16keunyoung    nsecs_t timeSinceIdx = (mHour - timeIdx * kTimeStep) * kOneHourInNsec + time;
1448a94683196406b83b14218d1beef66067f126a16keunyoung    float timeFrac = timeSinceIdx / (float)(kOneHourInNsec * kTimeStep);
1458a94683196406b83b14218d1beef66067f126a16keunyoung
1468a94683196406b83b14218d1beef66067f126a16keunyoung    // Determine overall sunlight levels
1478a94683196406b83b14218d1beef66067f126a16keunyoung    float sunLux =
1488a94683196406b83b14218d1beef66067f126a16keunyoung            kSunlight[timeIdx] * (1 - timeFrac) +
1498a94683196406b83b14218d1beef66067f126a16keunyoung            kSunlight[nextTimeIdx] * timeFrac;
1508a94683196406b83b14218d1beef66067f126a16keunyoung    ALOGV("Sun lux: %f", sunLux);
1518a94683196406b83b14218d1beef66067f126a16keunyoung
1528a94683196406b83b14218d1beef66067f126a16keunyoung    float sunShadeLux = sunLux * (kDaylightShadeIllum / kDirectSunIllum);
1538a94683196406b83b14218d1beef66067f126a16keunyoung
1548a94683196406b83b14218d1beef66067f126a16keunyoung    // Determine sun/shade illumination chromaticity
1558a94683196406b83b14218d1beef66067f126a16keunyoung    float currentSunXY[2];
1568a94683196406b83b14218d1beef66067f126a16keunyoung    float currentShadeXY[2];
1578a94683196406b83b14218d1beef66067f126a16keunyoung
1588a94683196406b83b14218d1beef66067f126a16keunyoung    const float *prevSunXY, *nextSunXY;
1598a94683196406b83b14218d1beef66067f126a16keunyoung    const float *prevShadeXY, *nextShadeXY;
1608a94683196406b83b14218d1beef66067f126a16keunyoung    if (kSunlight[timeIdx] == kSunsetIllum ||
1618a94683196406b83b14218d1beef66067f126a16keunyoung            kSunlight[timeIdx] == kTwilightIllum) {
1628a94683196406b83b14218d1beef66067f126a16keunyoung        prevSunXY = kSunsetXY;
1638a94683196406b83b14218d1beef66067f126a16keunyoung        prevShadeXY = kSunsetXY;
1648a94683196406b83b14218d1beef66067f126a16keunyoung    } else {
1658a94683196406b83b14218d1beef66067f126a16keunyoung        prevSunXY = kDirectSunlightXY;
1668a94683196406b83b14218d1beef66067f126a16keunyoung        prevShadeXY = kDaylightXY;
1678a94683196406b83b14218d1beef66067f126a16keunyoung    }
1688a94683196406b83b14218d1beef66067f126a16keunyoung    if (kSunlight[nextTimeIdx] == kSunsetIllum ||
1698a94683196406b83b14218d1beef66067f126a16keunyoung            kSunlight[nextTimeIdx] == kTwilightIllum) {
1708a94683196406b83b14218d1beef66067f126a16keunyoung        nextSunXY = kSunsetXY;
1718a94683196406b83b14218d1beef66067f126a16keunyoung        nextShadeXY = kSunsetXY;
1728a94683196406b83b14218d1beef66067f126a16keunyoung    } else {
1738a94683196406b83b14218d1beef66067f126a16keunyoung        nextSunXY = kDirectSunlightXY;
1748a94683196406b83b14218d1beef66067f126a16keunyoung        nextShadeXY = kDaylightXY;
1758a94683196406b83b14218d1beef66067f126a16keunyoung    }
1768a94683196406b83b14218d1beef66067f126a16keunyoung    currentSunXY[0] = prevSunXY[0] * (1 - timeFrac) +
1778a94683196406b83b14218d1beef66067f126a16keunyoung            nextSunXY[0] * timeFrac;
1788a94683196406b83b14218d1beef66067f126a16keunyoung    currentSunXY[1] = prevSunXY[1] * (1 - timeFrac) +
1798a94683196406b83b14218d1beef66067f126a16keunyoung            nextSunXY[1] * timeFrac;
1808a94683196406b83b14218d1beef66067f126a16keunyoung
1818a94683196406b83b14218d1beef66067f126a16keunyoung    currentShadeXY[0] = prevShadeXY[0] * (1 - timeFrac) +
1828a94683196406b83b14218d1beef66067f126a16keunyoung            nextShadeXY[0] * timeFrac;
1838a94683196406b83b14218d1beef66067f126a16keunyoung    currentShadeXY[1] = prevShadeXY[1] * (1 - timeFrac) +
1848a94683196406b83b14218d1beef66067f126a16keunyoung            nextShadeXY[1] * timeFrac;
1858a94683196406b83b14218d1beef66067f126a16keunyoung
1868a94683196406b83b14218d1beef66067f126a16keunyoung    ALOGV("Sun XY: %f, %f, Shade XY: %f, %f",
1878a94683196406b83b14218d1beef66067f126a16keunyoung            currentSunXY[0], currentSunXY[1],
1888a94683196406b83b14218d1beef66067f126a16keunyoung            currentShadeXY[0], currentShadeXY[1]);
1898a94683196406b83b14218d1beef66067f126a16keunyoung
1908a94683196406b83b14218d1beef66067f126a16keunyoung    // Converting for xyY to XYZ:
1918a94683196406b83b14218d1beef66067f126a16keunyoung    // X = Y / y * x
1928a94683196406b83b14218d1beef66067f126a16keunyoung    // Y = Y
1938a94683196406b83b14218d1beef66067f126a16keunyoung    // Z = Y / y * (1 - x - y);
1948a94683196406b83b14218d1beef66067f126a16keunyoung    float sunXYZ[3] = {
1958a94683196406b83b14218d1beef66067f126a16keunyoung        sunLux / currentSunXY[1] * currentSunXY[0],
1968a94683196406b83b14218d1beef66067f126a16keunyoung        sunLux,
1978a94683196406b83b14218d1beef66067f126a16keunyoung        sunLux / currentSunXY[1] *
1988a94683196406b83b14218d1beef66067f126a16keunyoung        (1 - currentSunXY[0] - currentSunXY[1])
1998a94683196406b83b14218d1beef66067f126a16keunyoung    };
2008a94683196406b83b14218d1beef66067f126a16keunyoung    float sunShadeXYZ[3] = {
2018a94683196406b83b14218d1beef66067f126a16keunyoung        sunShadeLux / currentShadeXY[1] * currentShadeXY[0],
2028a94683196406b83b14218d1beef66067f126a16keunyoung        sunShadeLux,
2038a94683196406b83b14218d1beef66067f126a16keunyoung        sunShadeLux / currentShadeXY[1] *
2048a94683196406b83b14218d1beef66067f126a16keunyoung        (1 - currentShadeXY[0] - currentShadeXY[1])
2058a94683196406b83b14218d1beef66067f126a16keunyoung    };
2068a94683196406b83b14218d1beef66067f126a16keunyoung    ALOGV("Sun XYZ: %f, %f, %f",
2078a94683196406b83b14218d1beef66067f126a16keunyoung            sunXYZ[0], sunXYZ[1], sunXYZ[2]);
2088a94683196406b83b14218d1beef66067f126a16keunyoung    ALOGV("Sun shade XYZ: %f, %f, %f",
2098a94683196406b83b14218d1beef66067f126a16keunyoung            sunShadeXYZ[0], sunShadeXYZ[1], sunShadeXYZ[2]);
2108a94683196406b83b14218d1beef66067f126a16keunyoung
2118a94683196406b83b14218d1beef66067f126a16keunyoung    // Determine moonlight levels
2128a94683196406b83b14218d1beef66067f126a16keunyoung    float moonLux =
2138a94683196406b83b14218d1beef66067f126a16keunyoung            kMoonlight[timeIdx] * (1 - timeFrac) +
2148a94683196406b83b14218d1beef66067f126a16keunyoung            kMoonlight[nextTimeIdx] * timeFrac;
2158a94683196406b83b14218d1beef66067f126a16keunyoung    float moonShadeLux = moonLux * (kDaylightShadeIllum / kDirectSunIllum);
2168a94683196406b83b14218d1beef66067f126a16keunyoung
2178a94683196406b83b14218d1beef66067f126a16keunyoung    float moonXYZ[3] = {
2188a94683196406b83b14218d1beef66067f126a16keunyoung        moonLux / kMoonlightXY[1] * kMoonlightXY[0],
2198a94683196406b83b14218d1beef66067f126a16keunyoung        moonLux,
2208a94683196406b83b14218d1beef66067f126a16keunyoung        moonLux / kMoonlightXY[1] *
2218a94683196406b83b14218d1beef66067f126a16keunyoung        (1 - kMoonlightXY[0] - kMoonlightXY[1])
2228a94683196406b83b14218d1beef66067f126a16keunyoung    };
2238a94683196406b83b14218d1beef66067f126a16keunyoung    float moonShadeXYZ[3] = {
2248a94683196406b83b14218d1beef66067f126a16keunyoung        moonShadeLux / kMoonlightXY[1] * kMoonlightXY[0],
2258a94683196406b83b14218d1beef66067f126a16keunyoung        moonShadeLux,
2268a94683196406b83b14218d1beef66067f126a16keunyoung        moonShadeLux / kMoonlightXY[1] *
2278a94683196406b83b14218d1beef66067f126a16keunyoung        (1 - kMoonlightXY[0] - kMoonlightXY[1])
2288a94683196406b83b14218d1beef66067f126a16keunyoung    };
2298a94683196406b83b14218d1beef66067f126a16keunyoung
2308a94683196406b83b14218d1beef66067f126a16keunyoung    // Determine starlight level
2318a94683196406b83b14218d1beef66067f126a16keunyoung    const float kClearNightXYZ[3] = {
2328a94683196406b83b14218d1beef66067f126a16keunyoung        kClearNightIllum / kMoonlightXY[1] * kMoonlightXY[0],
2338a94683196406b83b14218d1beef66067f126a16keunyoung        kClearNightIllum,
2348a94683196406b83b14218d1beef66067f126a16keunyoung        kClearNightIllum / kMoonlightXY[1] *
2358a94683196406b83b14218d1beef66067f126a16keunyoung            (1 - kMoonlightXY[0] - kMoonlightXY[1])
2368a94683196406b83b14218d1beef66067f126a16keunyoung    };
2378a94683196406b83b14218d1beef66067f126a16keunyoung
2388a94683196406b83b14218d1beef66067f126a16keunyoung    // Calculate direct and shaded light
2398a94683196406b83b14218d1beef66067f126a16keunyoung    float directIllumXYZ[3] = {
2408a94683196406b83b14218d1beef66067f126a16keunyoung        sunXYZ[0] + moonXYZ[0] + kClearNightXYZ[0],
2418a94683196406b83b14218d1beef66067f126a16keunyoung        sunXYZ[1] + moonXYZ[1] + kClearNightXYZ[1],
2428a94683196406b83b14218d1beef66067f126a16keunyoung        sunXYZ[2] + moonXYZ[2] + kClearNightXYZ[2],
2438a94683196406b83b14218d1beef66067f126a16keunyoung    };
2448a94683196406b83b14218d1beef66067f126a16keunyoung
2458a94683196406b83b14218d1beef66067f126a16keunyoung    float shadeIllumXYZ[3] = {
2468a94683196406b83b14218d1beef66067f126a16keunyoung        kClearNightXYZ[0],
2478a94683196406b83b14218d1beef66067f126a16keunyoung        kClearNightXYZ[1],
2488a94683196406b83b14218d1beef66067f126a16keunyoung        kClearNightXYZ[2]
2498a94683196406b83b14218d1beef66067f126a16keunyoung    };
2508a94683196406b83b14218d1beef66067f126a16keunyoung
2518a94683196406b83b14218d1beef66067f126a16keunyoung    shadeIllumXYZ[0] += (mHour < kSunOverhead) ? sunXYZ[0] : sunShadeXYZ[0];
2528a94683196406b83b14218d1beef66067f126a16keunyoung    shadeIllumXYZ[1] += (mHour < kSunOverhead) ? sunXYZ[1] : sunShadeXYZ[1];
2538a94683196406b83b14218d1beef66067f126a16keunyoung    shadeIllumXYZ[2] += (mHour < kSunOverhead) ? sunXYZ[2] : sunShadeXYZ[2];
2548a94683196406b83b14218d1beef66067f126a16keunyoung
2558a94683196406b83b14218d1beef66067f126a16keunyoung    // Moon up period covers 23->0 transition, shift for simplicity
2568a94683196406b83b14218d1beef66067f126a16keunyoung    int adjHour = (mHour + 12) % 24;
2578a94683196406b83b14218d1beef66067f126a16keunyoung    int adjMoonOverhead = (kMoonOverhead + 12 ) % 24;
2588a94683196406b83b14218d1beef66067f126a16keunyoung    shadeIllumXYZ[0] += (adjHour < adjMoonOverhead) ?
2598a94683196406b83b14218d1beef66067f126a16keunyoung            moonXYZ[0] : moonShadeXYZ[0];
2608a94683196406b83b14218d1beef66067f126a16keunyoung    shadeIllumXYZ[1] += (adjHour < adjMoonOverhead) ?
2618a94683196406b83b14218d1beef66067f126a16keunyoung            moonXYZ[1] : moonShadeXYZ[1];
2628a94683196406b83b14218d1beef66067f126a16keunyoung    shadeIllumXYZ[2] += (adjHour < adjMoonOverhead) ?
2638a94683196406b83b14218d1beef66067f126a16keunyoung            moonXYZ[2] : moonShadeXYZ[2];
2648a94683196406b83b14218d1beef66067f126a16keunyoung
2658a94683196406b83b14218d1beef66067f126a16keunyoung    ALOGV("Direct XYZ: %f, %f, %f",
2668a94683196406b83b14218d1beef66067f126a16keunyoung            directIllumXYZ[0],directIllumXYZ[1],directIllumXYZ[2]);
2678a94683196406b83b14218d1beef66067f126a16keunyoung    ALOGV("Shade XYZ: %f, %f, %f",
2688a94683196406b83b14218d1beef66067f126a16keunyoung            shadeIllumXYZ[0], shadeIllumXYZ[1], shadeIllumXYZ[2]);
2698a94683196406b83b14218d1beef66067f126a16keunyoung
2708a94683196406b83b14218d1beef66067f126a16keunyoung    for (int i = 0; i < NUM_MATERIALS; i++) {
2718a94683196406b83b14218d1beef66067f126a16keunyoung        // Converting for xyY to XYZ:
2728a94683196406b83b14218d1beef66067f126a16keunyoung        // X = Y / y * x
2738a94683196406b83b14218d1beef66067f126a16keunyoung        // Y = Y
2748a94683196406b83b14218d1beef66067f126a16keunyoung        // Z = Y / y * (1 - x - y);
2758a94683196406b83b14218d1beef66067f126a16keunyoung        float matXYZ[3] = {
2768a94683196406b83b14218d1beef66067f126a16keunyoung            kMaterials_xyY[i][2] / kMaterials_xyY[i][1] *
2778a94683196406b83b14218d1beef66067f126a16keunyoung              kMaterials_xyY[i][0],
2788a94683196406b83b14218d1beef66067f126a16keunyoung            kMaterials_xyY[i][2],
2798a94683196406b83b14218d1beef66067f126a16keunyoung            kMaterials_xyY[i][2] / kMaterials_xyY[i][1] *
2808a94683196406b83b14218d1beef66067f126a16keunyoung              (1 - kMaterials_xyY[i][0] - kMaterials_xyY[i][1])
2818a94683196406b83b14218d1beef66067f126a16keunyoung        };
2828a94683196406b83b14218d1beef66067f126a16keunyoung
2838a94683196406b83b14218d1beef66067f126a16keunyoung        if (kMaterialsFlags[i] == 0 || kMaterialsFlags[i] & kSky) {
2848a94683196406b83b14218d1beef66067f126a16keunyoung            matXYZ[0] *= directIllumXYZ[0];
2858a94683196406b83b14218d1beef66067f126a16keunyoung            matXYZ[1] *= directIllumXYZ[1];
2868a94683196406b83b14218d1beef66067f126a16keunyoung            matXYZ[2] *= directIllumXYZ[2];
2878a94683196406b83b14218d1beef66067f126a16keunyoung        } else if (kMaterialsFlags[i] & kShadowed) {
2888a94683196406b83b14218d1beef66067f126a16keunyoung            matXYZ[0] *= shadeIllumXYZ[0];
2898a94683196406b83b14218d1beef66067f126a16keunyoung            matXYZ[1] *= shadeIllumXYZ[1];
2908a94683196406b83b14218d1beef66067f126a16keunyoung            matXYZ[2] *= shadeIllumXYZ[2];
2918a94683196406b83b14218d1beef66067f126a16keunyoung        } // else if (kMaterialsFlags[i] * kSelfLit), do nothing
2928a94683196406b83b14218d1beef66067f126a16keunyoung
2938a94683196406b83b14218d1beef66067f126a16keunyoung        ALOGV("Mat %d XYZ: %f, %f, %f", i, matXYZ[0], matXYZ[1], matXYZ[2]);
2948a94683196406b83b14218d1beef66067f126a16keunyoung        float luxToElectrons = mSensorSensitivity * mExposureDuration /
2958a94683196406b83b14218d1beef66067f126a16keunyoung                (kAperture * kAperture);
2968a94683196406b83b14218d1beef66067f126a16keunyoung        mCurrentColors[i*NUM_CHANNELS + 0] =
2978a94683196406b83b14218d1beef66067f126a16keunyoung                (mFilterR[0] * matXYZ[0] +
2988a94683196406b83b14218d1beef66067f126a16keunyoung                 mFilterR[1] * matXYZ[1] +
2998a94683196406b83b14218d1beef66067f126a16keunyoung                 mFilterR[2] * matXYZ[2])
3008a94683196406b83b14218d1beef66067f126a16keunyoung                * luxToElectrons;
3018a94683196406b83b14218d1beef66067f126a16keunyoung        mCurrentColors[i*NUM_CHANNELS + 1] =
3028a94683196406b83b14218d1beef66067f126a16keunyoung                (mFilterGr[0] * matXYZ[0] +
3038a94683196406b83b14218d1beef66067f126a16keunyoung                 mFilterGr[1] * matXYZ[1] +
3048a94683196406b83b14218d1beef66067f126a16keunyoung                 mFilterGr[2] * matXYZ[2])
3058a94683196406b83b14218d1beef66067f126a16keunyoung                * luxToElectrons;
3068a94683196406b83b14218d1beef66067f126a16keunyoung        mCurrentColors[i*NUM_CHANNELS + 2] =
3078a94683196406b83b14218d1beef66067f126a16keunyoung                (mFilterGb[0] * matXYZ[0] +
3088a94683196406b83b14218d1beef66067f126a16keunyoung                 mFilterGb[1] * matXYZ[1] +
3098a94683196406b83b14218d1beef66067f126a16keunyoung                 mFilterGb[2] * matXYZ[2])
3108a94683196406b83b14218d1beef66067f126a16keunyoung                * luxToElectrons;
3118a94683196406b83b14218d1beef66067f126a16keunyoung        mCurrentColors[i*NUM_CHANNELS + 3] =
3128a94683196406b83b14218d1beef66067f126a16keunyoung                (mFilterB[0] * matXYZ[0] +
3138a94683196406b83b14218d1beef66067f126a16keunyoung                 mFilterB[1] * matXYZ[1] +
3148a94683196406b83b14218d1beef66067f126a16keunyoung                 mFilterB[2] * matXYZ[2])
3158a94683196406b83b14218d1beef66067f126a16keunyoung                * luxToElectrons;
3168a94683196406b83b14218d1beef66067f126a16keunyoung
3178a94683196406b83b14218d1beef66067f126a16keunyoung        ALOGV("Color %d RGGB: %d, %d, %d, %d", i,
3188a94683196406b83b14218d1beef66067f126a16keunyoung                mCurrentColors[i*NUM_CHANNELS + 0],
3198a94683196406b83b14218d1beef66067f126a16keunyoung                mCurrentColors[i*NUM_CHANNELS + 1],
3208a94683196406b83b14218d1beef66067f126a16keunyoung                mCurrentColors[i*NUM_CHANNELS + 2],
3218a94683196406b83b14218d1beef66067f126a16keunyoung                mCurrentColors[i*NUM_CHANNELS + 3]);
3228a94683196406b83b14218d1beef66067f126a16keunyoung    }
3235e936df9ce247b8bd0964dabb4369ea45875c825Eino-Ville Talvala    // Shake viewpoint; horizontal and vertical sinusoids at roughly
3245e936df9ce247b8bd0964dabb4369ea45875c825Eino-Ville Talvala    // human handshake frequencies
3255e936df9ce247b8bd0964dabb4369ea45875c825Eino-Ville Talvala    mHandshakeX =
3265e936df9ce247b8bd0964dabb4369ea45875c825Eino-Ville Talvala            ( kFreq1Magnitude * std::sin(kHorizShakeFreq1 * timeSinceIdx) +
3275e936df9ce247b8bd0964dabb4369ea45875c825Eino-Ville Talvala              kFreq2Magnitude * std::sin(kHorizShakeFreq2 * timeSinceIdx) ) *
3285e936df9ce247b8bd0964dabb4369ea45875c825Eino-Ville Talvala            mMapDiv * kShakeFraction;
3295e936df9ce247b8bd0964dabb4369ea45875c825Eino-Ville Talvala
3305e936df9ce247b8bd0964dabb4369ea45875c825Eino-Ville Talvala    mHandshakeY =
3315e936df9ce247b8bd0964dabb4369ea45875c825Eino-Ville Talvala            ( kFreq1Magnitude * std::sin(kVertShakeFreq1 * timeSinceIdx) +
3325e936df9ce247b8bd0964dabb4369ea45875c825Eino-Ville Talvala              kFreq2Magnitude * std::sin(kVertShakeFreq2 * timeSinceIdx) ) *
3335e936df9ce247b8bd0964dabb4369ea45875c825Eino-Ville Talvala            mMapDiv * kShakeFraction;
3345e936df9ce247b8bd0964dabb4369ea45875c825Eino-Ville Talvala
3358a94683196406b83b14218d1beef66067f126a16keunyoung    // Set starting pixel
3368a94683196406b83b14218d1beef66067f126a16keunyoung    setReadoutPixel(0,0);
3378a94683196406b83b14218d1beef66067f126a16keunyoung}
3388a94683196406b83b14218d1beef66067f126a16keunyoung
3398a94683196406b83b14218d1beef66067f126a16keunyoungvoid Scene::setReadoutPixel(int x, int y) {
3408a94683196406b83b14218d1beef66067f126a16keunyoung    mCurrentX = x;
3418a94683196406b83b14218d1beef66067f126a16keunyoung    mCurrentY = y;
3428a94683196406b83b14218d1beef66067f126a16keunyoung    mSubX = (x + mOffsetX + mHandshakeX) % mMapDiv;
3438a94683196406b83b14218d1beef66067f126a16keunyoung    mSubY = (y + mOffsetY + mHandshakeY) % mMapDiv;
3448a94683196406b83b14218d1beef66067f126a16keunyoung    mSceneX = (x + mOffsetX + mHandshakeX) / mMapDiv;
3458a94683196406b83b14218d1beef66067f126a16keunyoung    mSceneY = (y + mOffsetY + mHandshakeY) / mMapDiv;
3468a94683196406b83b14218d1beef66067f126a16keunyoung    mSceneIdx = mSceneY * kSceneWidth + mSceneX;
3478a94683196406b83b14218d1beef66067f126a16keunyoung    mCurrentSceneMaterial = &(mCurrentColors[kScene[mSceneIdx]]);
3488a94683196406b83b14218d1beef66067f126a16keunyoung}
3498a94683196406b83b14218d1beef66067f126a16keunyoung
3508a94683196406b83b14218d1beef66067f126a16keunyoungconst uint32_t* Scene::getPixelElectrons() {
3518a94683196406b83b14218d1beef66067f126a16keunyoung    const uint32_t *pixel = mCurrentSceneMaterial;
3528a94683196406b83b14218d1beef66067f126a16keunyoung    mCurrentX++;
3538a94683196406b83b14218d1beef66067f126a16keunyoung    mSubX++;
3548a94683196406b83b14218d1beef66067f126a16keunyoung    if (mCurrentX >= mSensorWidth) {
3558a94683196406b83b14218d1beef66067f126a16keunyoung        mCurrentX = 0;
3568a94683196406b83b14218d1beef66067f126a16keunyoung        mCurrentY++;
3578a94683196406b83b14218d1beef66067f126a16keunyoung        if (mCurrentY >= mSensorHeight) mCurrentY = 0;
3588a94683196406b83b14218d1beef66067f126a16keunyoung        setReadoutPixel(mCurrentX, mCurrentY);
3598a94683196406b83b14218d1beef66067f126a16keunyoung    } else if (mSubX > mMapDiv) {
3608a94683196406b83b14218d1beef66067f126a16keunyoung        mSceneIdx++;
3618a94683196406b83b14218d1beef66067f126a16keunyoung        mSceneX++;
3628a94683196406b83b14218d1beef66067f126a16keunyoung        mCurrentSceneMaterial = &(mCurrentColors[kScene[mSceneIdx]]);
3638a94683196406b83b14218d1beef66067f126a16keunyoung        mSubX = 0;
3648a94683196406b83b14218d1beef66067f126a16keunyoung    }
3658a94683196406b83b14218d1beef66067f126a16keunyoung    return pixel;
3668a94683196406b83b14218d1beef66067f126a16keunyoung}
3678a94683196406b83b14218d1beef66067f126a16keunyoung
3685e936df9ce247b8bd0964dabb4369ea45875c825Eino-Ville Talvala// Handshake model constants.
3695e936df9ce247b8bd0964dabb4369ea45875c825Eino-Ville Talvala// Frequencies measured in a nanosecond timebase
3705e936df9ce247b8bd0964dabb4369ea45875c825Eino-Ville Talvalaconst float Scene::kHorizShakeFreq1 = 2 * M_PI * 2  / 1e9; // 2 Hz
3715e936df9ce247b8bd0964dabb4369ea45875c825Eino-Ville Talvalaconst float Scene::kHorizShakeFreq2 = 2 * M_PI * 13 / 1e9; // 13 Hz
3725e936df9ce247b8bd0964dabb4369ea45875c825Eino-Ville Talvalaconst float Scene::kVertShakeFreq1  = 2 * M_PI * 3  / 1e9; // 3 Hz
3735e936df9ce247b8bd0964dabb4369ea45875c825Eino-Ville Talvalaconst float Scene::kVertShakeFreq2  = 2 * M_PI * 11 / 1e9; // 1 Hz
3745e936df9ce247b8bd0964dabb4369ea45875c825Eino-Ville Talvalaconst float Scene::kFreq1Magnitude  = 5;
3755e936df9ce247b8bd0964dabb4369ea45875c825Eino-Ville Talvalaconst float Scene::kFreq2Magnitude  = 1;
3765e936df9ce247b8bd0964dabb4369ea45875c825Eino-Ville Talvalaconst float Scene::kShakeFraction   = 0.03; // As a fraction of a scene tile
3775e936df9ce247b8bd0964dabb4369ea45875c825Eino-Ville Talvala
3788a94683196406b83b14218d1beef66067f126a16keunyoung// RGB->YUV, Jpeg standard
3798a94683196406b83b14218d1beef66067f126a16keunyoungconst float Scene::kRgb2Yuv[12] = {
3808a94683196406b83b14218d1beef66067f126a16keunyoung       0.299f,    0.587f,    0.114f,    0.f,
3818a94683196406b83b14218d1beef66067f126a16keunyoung    -0.16874f, -0.33126f,      0.5f, -128.f,
3828a94683196406b83b14218d1beef66067f126a16keunyoung         0.5f, -0.41869f, -0.08131f, -128.f,
3838a94683196406b83b14218d1beef66067f126a16keunyoung};
3848a94683196406b83b14218d1beef66067f126a16keunyoung
3858a94683196406b83b14218d1beef66067f126a16keunyoung// Aperture of imaging lens
3868a94683196406b83b14218d1beef66067f126a16keunyoungconst float Scene::kAperture = 2.8;
3878a94683196406b83b14218d1beef66067f126a16keunyoung
3888a94683196406b83b14218d1beef66067f126a16keunyoung// Sun illumination levels through the day
3898a94683196406b83b14218d1beef66067f126a16keunyoungconst float Scene::kSunlight[24/kTimeStep] =
3908a94683196406b83b14218d1beef66067f126a16keunyoung{
3918a94683196406b83b14218d1beef66067f126a16keunyoung    0, // 00:00
3928a94683196406b83b14218d1beef66067f126a16keunyoung    0,
3938a94683196406b83b14218d1beef66067f126a16keunyoung    0,
3948a94683196406b83b14218d1beef66067f126a16keunyoung    kTwilightIllum, // 06:00
3958a94683196406b83b14218d1beef66067f126a16keunyoung    kDirectSunIllum,
3968a94683196406b83b14218d1beef66067f126a16keunyoung    kDirectSunIllum,
3978a94683196406b83b14218d1beef66067f126a16keunyoung    kDirectSunIllum, // 12:00
3988a94683196406b83b14218d1beef66067f126a16keunyoung    kDirectSunIllum,
3998a94683196406b83b14218d1beef66067f126a16keunyoung    kDirectSunIllum,
4008a94683196406b83b14218d1beef66067f126a16keunyoung    kSunsetIllum, // 18:00
4018a94683196406b83b14218d1beef66067f126a16keunyoung    kTwilightIllum,
4028a94683196406b83b14218d1beef66067f126a16keunyoung    0
4038a94683196406b83b14218d1beef66067f126a16keunyoung};
4048a94683196406b83b14218d1beef66067f126a16keunyoung
4058a94683196406b83b14218d1beef66067f126a16keunyoung// Moon illumination levels through the day
4068a94683196406b83b14218d1beef66067f126a16keunyoungconst float Scene::kMoonlight[24/kTimeStep] =
4078a94683196406b83b14218d1beef66067f126a16keunyoung{
4088a94683196406b83b14218d1beef66067f126a16keunyoung    kFullMoonIllum, // 00:00
4098a94683196406b83b14218d1beef66067f126a16keunyoung    kFullMoonIllum,
4108a94683196406b83b14218d1beef66067f126a16keunyoung    0,
4118a94683196406b83b14218d1beef66067f126a16keunyoung    0, // 06:00
4128a94683196406b83b14218d1beef66067f126a16keunyoung    0,
4138a94683196406b83b14218d1beef66067f126a16keunyoung    0,
4148a94683196406b83b14218d1beef66067f126a16keunyoung    0, // 12:00
4158a94683196406b83b14218d1beef66067f126a16keunyoung    0,
4168a94683196406b83b14218d1beef66067f126a16keunyoung    0,
4178a94683196406b83b14218d1beef66067f126a16keunyoung    0, // 18:00
4188a94683196406b83b14218d1beef66067f126a16keunyoung    0,
4198a94683196406b83b14218d1beef66067f126a16keunyoung    kFullMoonIllum
4208a94683196406b83b14218d1beef66067f126a16keunyoung};
4218a94683196406b83b14218d1beef66067f126a16keunyoung
4228a94683196406b83b14218d1beef66067f126a16keunyoungconst int Scene::kSunOverhead = 12;
4238a94683196406b83b14218d1beef66067f126a16keunyoungconst int Scene::kMoonOverhead = 0;
4248a94683196406b83b14218d1beef66067f126a16keunyoung
4258a94683196406b83b14218d1beef66067f126a16keunyoung// Used for sun illumination levels
4268a94683196406b83b14218d1beef66067f126a16keunyoungconst float Scene::kDirectSunIllum     = 100000;
4278a94683196406b83b14218d1beef66067f126a16keunyoungconst float Scene::kSunsetIllum        = 400;
4288a94683196406b83b14218d1beef66067f126a16keunyoungconst float Scene::kTwilightIllum      = 4;
4298a94683196406b83b14218d1beef66067f126a16keunyoung// Used for moon illumination levels
4308a94683196406b83b14218d1beef66067f126a16keunyoungconst float Scene::kFullMoonIllum      = 1;
4318a94683196406b83b14218d1beef66067f126a16keunyoung// Other illumination levels
4328a94683196406b83b14218d1beef66067f126a16keunyoungconst float Scene::kDaylightShadeIllum = 20000;
4338a94683196406b83b14218d1beef66067f126a16keunyoungconst float Scene::kClearNightIllum    = 2e-3;
4348a94683196406b83b14218d1beef66067f126a16keunyoungconst float Scene::kStarIllum          = 2e-6;
4358a94683196406b83b14218d1beef66067f126a16keunyoungconst float Scene::kLivingRoomIllum    = 50;
4368a94683196406b83b14218d1beef66067f126a16keunyoung
4378a94683196406b83b14218d1beef66067f126a16keunyoungconst float Scene::kIncandescentXY[2]   = { 0.44757f, 0.40745f};
4388a94683196406b83b14218d1beef66067f126a16keunyoungconst float Scene::kDirectSunlightXY[2] = { 0.34842f, 0.35161f};
4398a94683196406b83b14218d1beef66067f126a16keunyoungconst float Scene::kDaylightXY[2]       = { 0.31271f, 0.32902f};
4408a94683196406b83b14218d1beef66067f126a16keunyoungconst float Scene::kNoonSkyXY[2]        = { 0.346f,   0.359f};
4418a94683196406b83b14218d1beef66067f126a16keunyoungconst float Scene::kMoonlightXY[2]      = { 0.34842f, 0.35161f};
4428a94683196406b83b14218d1beef66067f126a16keunyoungconst float Scene::kSunsetXY[2]         = { 0.527f,   0.413f};
4438a94683196406b83b14218d1beef66067f126a16keunyoung
4448a94683196406b83b14218d1beef66067f126a16keunyoungconst uint8_t Scene::kSelfLit  = 0x01;
4458a94683196406b83b14218d1beef66067f126a16keunyoungconst uint8_t Scene::kShadowed = 0x02;
4468a94683196406b83b14218d1beef66067f126a16keunyoungconst uint8_t Scene::kSky      = 0x04;
4478a94683196406b83b14218d1beef66067f126a16keunyoung
4488a94683196406b83b14218d1beef66067f126a16keunyoung// For non-self-lit materials, the Y component is normalized with 1=full
4498a94683196406b83b14218d1beef66067f126a16keunyoung// reflectance; for self-lit materials, it's the constant illuminance in lux.
4508a94683196406b83b14218d1beef66067f126a16keunyoungconst float Scene::kMaterials_xyY[Scene::NUM_MATERIALS][3] = {
4518a94683196406b83b14218d1beef66067f126a16keunyoung    { 0.3688f, 0.4501f, .1329f }, // GRASS
4528a94683196406b83b14218d1beef66067f126a16keunyoung    { 0.3688f, 0.4501f, .1329f }, // GRASS_SHADOW
4538a94683196406b83b14218d1beef66067f126a16keunyoung    { 0.3986f, 0.5002f, .4440f }, // HILL
4548a94683196406b83b14218d1beef66067f126a16keunyoung    { 0.3262f, 0.5040f, .2297f }, // WALL
4558a94683196406b83b14218d1beef66067f126a16keunyoung    { 0.4336f, 0.3787f, .1029f }, // ROOF
4568a94683196406b83b14218d1beef66067f126a16keunyoung    { 0.3316f, 0.2544f, .0639f }, // DOOR
4578a94683196406b83b14218d1beef66067f126a16keunyoung    { 0.3425f, 0.3577f, .0887f }, // CHIMNEY
4588a94683196406b83b14218d1beef66067f126a16keunyoung    { kIncandescentXY[0], kIncandescentXY[1], kLivingRoomIllum }, // WINDOW
4598a94683196406b83b14218d1beef66067f126a16keunyoung    { kDirectSunlightXY[0], kDirectSunlightXY[1], kDirectSunIllum }, // SUN
4608a94683196406b83b14218d1beef66067f126a16keunyoung    { kNoonSkyXY[0], kNoonSkyXY[1], kDaylightShadeIllum / kDirectSunIllum }, // SKY
4618a94683196406b83b14218d1beef66067f126a16keunyoung    { kMoonlightXY[0], kMoonlightXY[1], kFullMoonIllum } // MOON
4628a94683196406b83b14218d1beef66067f126a16keunyoung};
4638a94683196406b83b14218d1beef66067f126a16keunyoung
4648a94683196406b83b14218d1beef66067f126a16keunyoungconst uint8_t Scene::kMaterialsFlags[Scene::NUM_MATERIALS] = {
4658a94683196406b83b14218d1beef66067f126a16keunyoung    0,
4668a94683196406b83b14218d1beef66067f126a16keunyoung    kShadowed,
4678a94683196406b83b14218d1beef66067f126a16keunyoung    kShadowed,
4688a94683196406b83b14218d1beef66067f126a16keunyoung    kShadowed,
4698a94683196406b83b14218d1beef66067f126a16keunyoung    kShadowed,
4708a94683196406b83b14218d1beef66067f126a16keunyoung    kShadowed,
4718a94683196406b83b14218d1beef66067f126a16keunyoung    kShadowed,
4728a94683196406b83b14218d1beef66067f126a16keunyoung    kSelfLit,
4738a94683196406b83b14218d1beef66067f126a16keunyoung    kSelfLit,
4748a94683196406b83b14218d1beef66067f126a16keunyoung    kSky,
4758a94683196406b83b14218d1beef66067f126a16keunyoung    kSelfLit,
4768a94683196406b83b14218d1beef66067f126a16keunyoung};
4778a94683196406b83b14218d1beef66067f126a16keunyoung
4788a94683196406b83b14218d1beef66067f126a16keunyoung} // namespace android
479