/**
 * Copyright (C) 2013 Stellar Jockeys.
 * All Rights Reserved.
 *
 * NOTICE: All information contained herein is, and remains the property of
 * Stellar Jockeys and its suppliers, if any.  The intellectual and technical
 * concepts contained herein are proprietary to Stellar Jockeys and its suppliers.
 * Dissemination of this information or reproduction of this material is
 * strictly forbidden unless prior written permission is obtained from
 * Stellar Jockeys.
 *
 * @file conversions.glsl
 * @author Harry Hsiao
 * @date 08/14/2013
 */
#ifndef CONVERSIONS_GLSL
#define CONVERSIONS_GLSL

/**
 * Depth Conversion factor:
 *
 * The derivation (not include) of f (see below) is just dimensional analysis.
 * At a high level f is a renomalization factor due to different depth ranges,
 * and a scale factor to convert between src world units and game world units.
 *
 *         depthRangeSrc * tileSizeGame * viewScale
 * let f = ----------------------------------------
 *              depthRangeGame * tileSizeSrc
 *
 * let a = uDepthConversion = tileSizeGame * viewScale / depthRangeGame
 * let b = DEPTH_CONVERSION_SRC = depthRangeSrc / tileSizeSrc
 * f = a * b
 *
 * adjustedDepth = (srcDepth - originBias) * f + baseDepth
 *
 * Reformat into MAD:
 * adjustedDepth = (srcDepth - originBias) * a * b + baseDepth
 * adjustedDepth = [(srcDepth * b) + (originBias * b)] * a + baseDepth
 */
/* Mathematical Constants */
const float SQRT_2 = 1.41421356237;

/* Configuration Constants */
const float NEAR_CLIP_SRC     = 2520.0;
const float FAR_CLIP_SRC      = 4820.0;
const float ORIGIN_OFFSET_SRC = 3540.0;
const float TILE_SIZE_SRC = 252.5;
const float TILE_WIDTH_SRC = 96.0;

/* Calculated Constants */
/*
 * Source depth uses white is near, so 0.0 is at the far plane.
 */
const float DEPTH_RANGE_SRC = FAR_CLIP_SRC - NEAR_CLIP_SRC;
const float ORIGIN_BIAS = (FAR_CLIP_SRC - ORIGIN_OFFSET_SRC) / DEPTH_RANGE_SRC;
const float DEPTH_CONVERSION_SRC = DEPTH_RANGE_SRC / TILE_SIZE_SRC;
const float CONVERSION_BIAS = (-ORIGIN_BIAS) * DEPTH_CONVERSION_SRC;
const float PPD_SRC = TILE_WIDTH_SRC * -DEPTH_RANGE_SRC / (SQRT_2 * TILE_SIZE_SRC);

/**
 * @brief Calculates the adjusted depth position.
 *
 * @param baseDepth The original fragment depth.
 * @param fragDepth The pixel's depth map value.
 * @param conversion The engine-side conversion factor.
 */
float AdjustedDepth(in float baseDepth, in float fragDepth, in float conversion)
{
    float depth = (fragDepth * DEPTH_CONVERSION_SRC) + CONVERSION_BIAS;
    return (depth * conversion) + baseDepth;
}

#endif // CONVERSIONS_GLSL
