// #include "version.sh"

#ifndef __CAMERA_SH__
#define __CAMERA_SH__

layout(std140) uniform CameraParams
{
    mat4 Projection;
    mat4 RteMatrixV;
    mat4 RteMatrixVP;
    
    vec4 eye_hl[2];     // only xyz valid
    vec4 zParams;       // near, far, 1/far, 1/(far-near)
};

//uniform vec3 _EyeHL[2]; // Split to high and low bits.

// eyeZ: abs(z) within eye space.
float Depth_EyeToLinear01(float eyeZ)
{
    // return eyeZ * zParams.z;
    return eyeZ * zParams.w - zParams.x * zParams.w;
}

// z01 is non-linear depth from 0 to 1.
float Depth_NonLinearToLinear01(float z01)
{
    return (z01 * zParams.x) / (zParams.y - z01 * (zParams.y - zParams.x));
}

// z01 is linear depth from 0 to 1.
float Depth_LinearToNonLinear01(float z01)
{
    return (z01 * zParams.y) / (zParams.x + z01 * (zParams.y - zParams.x));
}

vec3 DifferenceHL(vec3 p0_h, vec3 p0_l, vec3 p1_h, vec3 p1_l)
{
    vec3 difh = p0_h - p1_h;
    vec3 difl = p0_l - p1_l;
#if defined(DISL_DISABLE_OPTIMIZATION)
    return (difh + difl * 1.000001) * 1.000001;
#else
    return difh + difl;
#endif
}

vec3 CoordinateRTE(vec3 pos_h, vec3 pos_l)
{
    return DifferenceHL(pos_h, pos_l, eye_hl[0].xyz, eye_hl[1].xyz);
}

mat4 ViewMatrixRTO(vec3 ori_h, vec3 ori_l)
{
    vec4 translate = RteMatrixV * vec4(CoordinateRTE(ori_h, ori_l), 1.0f);
    mat4 rto = RteMatrixV;
    rto[3].xyz = translate.xyz;
    return rto;
}

#endif  // __CAMERA_SH__
