//uniform highp mat4 projection;
//uniform highp mat4 faceFrame;
//uniform highp mat4 stableToImage;
uniform highp vec2 lipsPlainSize;
uniform highp vec2 lipsLeftEdge;
uniform highp vec2 lipsRightEdge;
uniform highp float faceSmile;
attribute highp vec4 position;
//attribute highp vec3 displacementVector;
//attribute highp float faceIndex;
//attribute highp float depthValue;
varying highp vec2 textureCoordinate;
uniform vec3 angles; // angles.x: pitch, angles.y: yaw, angles.z: roll
uniform vec2 size;

uniform sampler2D inputImageTexture;

highp float getElipseMask2(in highp vec2 sigmaScaling, in highp vec2 point,
in highp vec2 center, in highp vec2 boundingSize) {
    highp vec2 sigmas = boundingSize / sigmaScaling;
    highp vec2 lengths = (point - center) / sigmas;
    highp float mask = exp(-dot(lengths, lengths));
    return smoothstep(0.2, 0.8, mask);
}

float getElipseMask(in vec2 sigmaScaling, in vec2 point,in vec2 center, in vec2 boundingSize) {
    // un-normalization
    boundingSize = boundingSize * size;
    point = point * size;
    center = center * size;

    float cos_t = cos(angles.z);
    float sin_t = sin(angles.z);
    vec2 translate = (point - center);
    // rotate and scale
    vec2 v = vec2(dot(translate, vec2(cos_t, sin_t)), dot(translate, vec2(-sin_t, cos_t))) * sigmaScaling;

    float d2 = sqrt(dot(v / boundingSize, v / boundingSize));
    float a1 = 0.5;
    float a2 = 1.2;

    return 1.0 - smoothstep(a1, a2, d2);
}

highp vec2 rotate2DPoint(in highp vec2 point, in highp float angle) {
    return vec2(cos(angle) * point.x - sin(angle) * point.y,
    sin(angle) * point.x + cos(angle) * point.y);
}
highp vec2 rotate2DPointAroundCenter(in highp vec2 point, in highp vec2 center, in highp float angle) {
    return center + rotate2DPoint(point - center, angle);
}
const highp float kLipsEdgeWrinkleSizeToLipsSizeRatio = 0.23;
const highp float kPi = 3.14159265358979;
const highp float kLipsEdgeWrinklesRotationAngle = 0.025 * kPi;
highp vec3 getRotatedLipsEdgeWrinkle(in highp vec3 originalPoint, in bool isLeftSide) {
    highp vec2 wrinkleSize = vec2(kLipsEdgeWrinkleSizeToLipsSizeRatio * lipsPlainSize.x, 0.6*lipsPlainSize.y);
    highp vec2 lipsEdge = isLeftSide ? lipsLeftEdge : lipsRightEdge;
    highp float directionSign = isLeftSide ? 1.0 : -1.0;
    highp vec2 wrinkleCenter = lipsEdge + directionSign * 0.05 * (lipsRightEdge - lipsLeftEdge);

    highp float wrinkleMask = getElipseMask(vec2(0.8, 0.5), position.xy, wrinkleCenter,wrinkleSize);
    highp vec2 wrinkleRotationCenter = lipsEdge + directionSign * 0.2 * (lipsRightEdge - lipsLeftEdge);
    highp vec2 rotated2DPoint = rotate2DPointAroundCenter(originalPoint.xy, wrinkleRotationCenter, - directionSign * wrinkleMask * kLipsEdgeWrinklesRotationAngle);
    return vec3(rotated2DPoint, originalPoint.z);
}
highp vec3 getRotatedLipsLeftEdgeWrinkle(in highp vec3 originalPoint) {
    return getRotatedLipsEdgeWrinkle(originalPoint, true);
}
highp vec3 getRotatedLipsRightEdgeWrinkle(in highp vec3 originalPoint) {
    return getRotatedLipsEdgeWrinkle(originalPoint, false);
}
void main() {
    highp vec3 displacedPoint = position.xyz;
    displacedPoint = getRotatedLipsLeftEdgeWrinkle(displacedPoint);
    displacedPoint = getRotatedLipsRightEdgeWrinkle(displacedPoint);
    highp vec2 originalPosition = position.xy;
    highp vec2 displacedPosition = originalPosition + faceSmile * (displacedPoint.xy - originalPosition);
    textureCoordinate = displacedPosition.xy;
    gl_Position = vec4(originalPosition.x*2.0-1.0, originalPosition.y*2.0-1.0, 0.0, 1.0);
}