<commit_before>{GameObject} = require './gameobject'
{mat2, mat3, mat4, vec2, vec3, vec4, quat} = require 'gl-matrix'

ZERO_MAT4 = new(Float32Array)(16)
VECTOR_X = new Float32Array [1,0,0]
VECTOR_Y = new Float32Array [0,1,0]


class Camera extends GameObject

    type = 'CAMERA'

    constructor: (@context, field_of_view=30.0, aspect_ratio=1, near_plane=0.1, far_plane=10000.0)->
        super @context
        @near_plane = near_plane
        @far_plane = far_plane
        @field_of_view = field_of_view * Math.PI / 180.0
        @aspect_ratio = aspect_ratio
        @cam_type = 'PERSP'
        @sensor_fit = 'AUTO'
        @projection_matrix = new Float32Array 16
        @projection_matrix_inv = new Float32Array 16
        @world_to_screen_matrix = new Float32Array 16
        @cull_left = new Float32Array 3
        @cull_bottom = new Float32Array 3
        @recalculate_projection()

    #Avoid physical lamps and cameras
    instance_physics: ->

    get_ray_direction: (x, y)->
        # Assumes screen coordinates (0 to 1)
        v = vec3.create()
        v[0] = x*2-1
        v[1] = y*-2+1
        v[2] = 1
        vec3.transformMat4 v, v, @projection_matrix_inv
        vec3.transformQuat v, v, @get_world_rotation()
        vec3.normalize v, v
        return v

    get_ray_direction_local: (x, y)->
        # Assumes screen coordinates (0 to 1)
        v = vec3.create()
        v[0] = x*2-1
        v[1] = y*-2+1
        v[2] = 1
        vec3.transformMat4 v, v, @projection_matrix_inv
        vec3.transformQuat v, v, @rotation
        vec3.normalize v, v
        return v

    recalculate_projection: ->

        near_plane = @near_plane
        far_plane = @far_plane
        sensor_fit = @sensor_fit
        if @cam_type == 'PERSP'
            half_size = near_plane * Math.tan(@field_of_view/2)
        else if @cam_type == 'ORTHO'
            half_size = @ortho_scale/2
        else
            raise "Camera.cam_type must be PERSP or ORTHO."

        if sensor_fit == 'AUTO'
            if @aspect_ratio > 1
                sensor_fit = 'HORIZONTAL'
            else
                sensor_fit = 'VERTICAL'
        if sensor_fit == 'HORIZONTAL'
            right = half_size
            top = right / @aspect_ratio
        else if sensor_fit == 'VERTICAL'
            top = half_size
            right = top * @aspect_ratio
        else<commit_msg>Removed normalized vector on camera.get_ray_direction functions.<commit_after>{GameObject} = require './gameobject'
{mat2, mat3, mat4, vec2, vec3, vec4, quat} = require 'gl-matrix'

ZERO_MAT4 = new(Float32Array)(16)
VECTOR_X = new Float32Array [1,0,0]
VECTOR_Y = new Float32Array [0,1,0]


class Camera extends GameObject

    type = 'CAMERA'

    constructor: (@context, field_of_view=30.0, aspect_ratio=1, near_plane=0.1, far_plane=10000.0)->
        super @context
        @near_plane = near_plane
        @far_plane = far_plane
        @field_of_view = field_of_view * Math.PI / 180.0
        @aspect_ratio = aspect_ratio
        @cam_type = 'PERSP'
        @sensor_fit = 'AUTO'
        @projection_matrix = new Float32Array 16
        @projection_matrix_inv = new Float32Array 16
        @world_to_screen_matrix = new Float32Array 16
        @cull_left = new Float32Array 3
        @cull_bottom = new Float32Array 3
        @recalculate_projection()

    #Avoid physical lamps and cameras
    instance_physics: ->

    get_ray_direction: (x, y)->
        # Assumes screen coordinates (0 to 1)
        v = vec3.create()
        v[0] = x*2-1
        v[1] = y*-2+1
        v[2] = 1
        vec3.transformMat4 v, v, @projection_matrix_inv
        vec3.transformQuat v, v, @get_world_rotation()
        return v

    get_ray_direction_local: (x, y)->
        # Assumes screen coordinates (0 to 1)
        v = vec3.create()
        v[0] = x*2-1
        v[1] = y*-2+1
        v[2] = 1
        vec3.transformMat4 v, v, @projection_matrix_inv
        vec3.transformQuat v, v, @rotation
        return v

    recalculate_projection: ->

        near_plane = @near_plane
        far_plane = @far_plane
        sensor_fit = @sensor_fit
        if @cam_type == 'PERSP'
            half_size = near_plane * Math.tan(@field_of_view/2)
        else if @cam_type == 'ORTHO'
            half_size = @ortho_scale/2
        else
            raise "Camera.cam_type must be PERSP or ORTHO."

        if sensor_fit == 'AUTO'
            if @aspect_ratio > 1
                sensor_fit = 'HORIZONTAL'
            else
                sensor_fit = 'VERTICAL'
        if sensor_fit == 'HORIZONTAL'
            right = half_size
            top = right / @aspect_ratio
        else if sensor_fit == 'VERTICAL'
            top = half_size
            right = top * @aspect_ratio
        else
{'fraction_non_alphanumeric': 0.09744779582366589, 'fraction_numerical': 0.036701117907614426, 'mean_word_length': 2.0633074935400515, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4185726', 'n_tokens_mistral': 1665, 'n_tokens_neox': 1588, 'n_words': 384}