<commit_before>package luxe;

import luxe.Log.*;
import luxe.Visual;
import luxe.Vector;
import luxe.Rectangle;

import luxe.Resources;
import phoenix.geometry.Geometry;
import phoenix.geometry.QuadGeometry;

import luxe.options.SpriteOptions;

class Sprite extends Visual {


    @:isVar public var centered     (default, set) : Bool = true;
    @:isVar public var flipx        (default, set) : Bool = false;
    @:isVar public var flipy        (default, set) : Bool = false;
    @:isVar public var uv           (default, set) : Rectangle;

    public var geometry_quad : QuadGeometry;


    public function new( options:SpriteOptions ) {

        uv = new Rectangle();

        assertnull(options, 'Sprite requires non-null options');

            //centered
        if(options.centered != null) {
            centered = options.centered;
        }

            //flipx
        if(options.flipx != null) {
            flipx = options.flipx;
        }

            //flipy
        if(options.flipy != null) {
            flipy = options.flipy;
        }

            //create visual
        super( options );

    }

    override function on_geometry_created() {

        super.on_geometry_created();

        if(texture != null) {

                //because the default is 0,0,1,1 uv for the quad, we don't want that when
                //textures are padded (like on web)
            uv = def(options.uv, new Rectangle(0,0,texture.width,texture.height));

                //if texture is render target, flipy
            if(texture.resource_type == ResourceType.render_texture) {
                flipy = true;
            }

        } //texture !null

            //set the origin and centered once created
        centered = !!centered;
            //and re assign the flip values
        flipx = !!flipx;
        flipy = !!flipy;

    } //on_geometry_created

    override function set_geometry( _g:Geometry ) {

        geometry_quad = cast _g;
        return super.set_geometry(_g);

    } //set_geometry

//Helper functions

        /** Returns true if a point is inside the sprite, takes into account the sprite transform,
            which includes more cost than simple AABB like `point_inside_AABB` */
    public function point_inside( _p:Vector ) : Bool {

        if(geometry == null) return false;

        return Luxe.utils.geometry.point_in_geometry(_p, geometry);

    } //point_inside

        /** Returns true if a point is inside the AABB unrotated */
    public function point_inside_AABB(_p:Vector) : Bool {

        if(pos == null) return false;
        if(size == null) return false;

            //scaled size
        var _s_x = size.x * scale.x;
        var _s_y = size.y * scale.y;

        if(centered) {
            var _hx = _s_x / 2;
            var _hy = _s_y / 2;
            if(_p.x < pos.x - _hx) return false;
            if(_p.y < pos.y - _hy) return false;
            if(_p.x > pos.x+_s_x - _hx) return false;
            if(_p.y > pos.y+_s_y - _hy) return false;
        } else {
            if(_p.x < pos.x) return false;
            if(_p.y < pos.y) return false;
            if(_p.x > pos.x+_s_x) return false;
            if(_p.y > pos.y+_s_y) return false;
        }

        return true;

    } //point_inside_AABB

//Properties


//UV / source rect

    function set_uv(_uv:Rectangle) : Rectangle {

        if(geometry_quad != null) {
            geometry_quad.uv(_uv);
        }

        uv = _uv;

        Rectangle.listen( uv, _uv_change );

        return uv;
    }

//Flipping<commit_msg>Sprite; ensure clean up<commit_after>package luxe;

import luxe.Log.*;
import luxe.Visual;
import luxe.Vector;
import luxe.Rectangle;

import luxe.Resources;
import phoenix.geometry.Geometry;
import phoenix.geometry.QuadGeometry;

import luxe.options.SpriteOptions;

class Sprite extends Visual {


    @:isVar public var centered     (default, set) : Bool = true;
    @:isVar public var flipx        (default, set) : Bool = false;
    @:isVar public var flipy        (default, set) : Bool = false;
    @:isVar public var uv           (default, set) : Rectangle;

    public var geometry_quad : QuadGeometry;


    public function new( options:SpriteOptions ) {

        uv = new Rectangle();

        assertnull(options, 'Sprite requires non-null options');

            //centered
        if(options.centered != null) {
            centered = options.centered;
        }

            //flipx
        if(options.flipx != null) {
            flipx = options.flipx;
        }

            //flipy
        if(options.flipy != null) {
            flipy = options.flipy;
        }

            //create visual
        super( options );

    }

    override function on_geometry_created() {

        super.on_geometry_created();

        if(texture != null) {

                //because the default is 0,0,1,1 uv for the quad, we don't want that when
                //textures are padded (like on web)
            uv = def(options.uv, new Rectangle(0,0,texture.width,texture.height));

                //if texture is render target, flipy
            if(texture.resource_type == ResourceType.render_texture) {
                flipy = true;
            }

        } //texture !null

            //set the origin and centered once created
        centered = !!centered;
            //and re assign the flip values
        flipx = !!flipx;
        flipy = !!flipy;

    } //on_geometry_created

    override function set_geometry( _g:Geometry ) {

        geometry_quad = cast _g;
        return super.set_geometry(_g);

    } //set_geometry

    override function ondestroy() {

        uv = null;
        geometry_quad = null;
        
        super.ondestroy();

    }

//Helper functions

        /** Returns true if a point is inside the sprite, takes into account the sprite transform,
            which includes more cost than simple AABB like `point_inside_AABB` */
    public function point_inside( _p:Vector ) : Bool {

        if(geometry == null) return false;

        return Luxe.utils.geometry.point_in_geometry(_p, geometry);

    } //point_inside

        /** Returns true if a point is inside the AABB unrotated */
    public function point_inside_AABB(_p:Vector) : Bool {

        if(pos == null) return false;
        if(size == null) return false;

            //scaled size
        var _s_x = size.x * scale.x;
        var _s_y = size.y * scale.y;

        if(centered) {
            var _hx = _s_x / 2;
            var _hy = _s_y / 2;
            if(_p.x < pos.x - _hx) return false;
            if(_p.y < pos.y - _hy) return false;
            if(_p.x > pos.x+_s_x - _hx) return false;
            if(_p.y > pos.y+_s_y - _hy) return false;
        } else {
            if(_p.x < pos.x) return false;
            if(_p.y < pos.y) return false;
            if(_p.x > pos.x+_s_x) return false;
            if(_p.y > pos.y+_s_y) return false;
        }

        return true;

    } //point_inside_AABB

//Properties


//UV / source rect

    function set_uv(_uv:Rectangle) : Rectangle {

        if(_uv == null) return uv = _uv;

        if(geometry_quad != null) {
            geometry_quad.uv(_uv);
        }

        uv = _uv;

        Rectangle.listen( uv, _uv_change );

        return uv;
    }

//Flipping
{'fraction_non_alphanumeric': 0.10360484314804623, 'fraction_numerical': 0.002201430930104568, 'mean_word_length': 1.7861249520889229, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, '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': '2828275', 'n_tokens_mistral': 2312, 'n_tokens_neox': 2152, 'n_words': 611}