/*
 * 3D Engine 
 * camera.c: 
 * Based on pikuma.com 3D software renderer in C
 * Copyright (c) 2021 986-Studio. All rights reserved.
 *
 * Created by Manoël Trapier on 11/03/2021.
 */

#include <camera.h>
#include <vector.h>
#include <matrix.h>

void createCamera(camera_t *camera)
{
    camera->position = vec3(0, 0, 0);
    camera->direction = vec3(0, 0, 1 );
    camera->target = vec4FromVec3(vec3(0, 0, 1));
    camera->up = vec3(0, 1, 0);
    camera->yawAngle = 0;
    camera->pitchAngle = 0;
}

void cameraSetDirection(camera_t *camera, vec3_t direction)
{
    camera->direction = direction;
}

void cameraMoveForward(camera_t *camera, double distance)
{
    vec3_t velocity = vec3ScalarMult(camera->direction, distance);
    camera->position = vec3AddVectors(camera->position, velocity);
}

void cameraMoveBackward(camera_t *camera, double distance)
{
    vec3_t velocity = vec3ScalarMult(camera->direction, distance);
    camera->position = vec3SubVectors(camera->position, velocity);
}

void cameraMoveRelative (camera_t *camera, double x, double y, double z)
{
    camera->position.x += x;
    camera->position.y += y;
    camera->position.z += z;
}

void cameraRotateBy(camera_t *camera, double yaw, double pitch)
{
    camera->yawAngle += yaw;
    camera->pitchAngle += pitch;

    matrix4_t rotationMatrix = mat4ProdMat4(mat4RotationY(camera->yawAngle),
                                            mat4RotationX(camera->pitchAngle));
    camera->direction = vec3FromVec4(mat4ProdVec4(rotationMatrix, camera->target));
}

void cameraSetTarget(camera_t *camera, vec3_t target)
{
    camera->target = vec4FromVec3(target);
}

void cameraSetUp(camera_t *camera, vec3_t up)
{
    camera->up = up;
}

matrix4_t cameraGetViewMatrix(camera_t *camera)
{
    return mat4LookAt(camera->position,
                      vec3AddVectors(camera->position, camera->direction),
                      camera->up);
}