a
    V$ca!                     @   s2   d dl Z G dd deZG dd de jjjZdS )    Nc                   @   s   e Zd Zdd Zdd ZdS )Texturec                 C   s@   t j|}|jr$|d }|  || _|| _|| _|| _d S N)	renpyeasydisplayable_duplicatable
_duplicate_uniquefocusmainfitselfr   r
   r   r    r   renpy/display\model.py__init__   s    
zTexture.__init__c                 C   s,   | j  }|| j u r| S t|| j| j| jS r   )r   _in_current_storer   r
   r   r   )r   dr   r   r   r   (   s    

zTexture._in_current_storeN)__name__
__module____qualname__r   r   r   r   r   r   r      s   r   c                       s   e Zd ZdZd fdd	Zdd Zddd	Zdd
dZdd Zdd Z	dd Z
dd Z fddZdd Zdd Zdd Z  ZS )Modelar  
    :doc: model_displayable class

    This is a displayable that causes Ren'Py to create a 2D or 3D model
    for use with the model-based renderer, that will be drawn in a single
    operation with the shaders given here, or selected by an enclosing
    Transform or Displayable.

    `size`
        If not None, this should be a width, height tuple, that's used to
        give the size of the Model. If not given, the model is the size
        of the area provided to it. The fit parameter to a texture takes
        precedence.

    If no mesh method is called, a mesh that sets a_position and a_tex_coord
    to match the way Ren'Py loads textures is created if at least one texture
    is supplied. Otherwise, a mesh that only sets a_position is used.

    All methods on this calls return the displayable the method is called
    on, making it possible to chain calls.
    Nc                    s>   t t| jf i | || _g | _d| _g | _i | _i | _d S )NT)	superr   r   sizetextures_meshshadersuniforms
properties)r   r   r   	__class__r   r   r   I   s    zModel.__init__c                 C   s(   |dk s|dk rt dd||f| _| S )a  
        :doc: model_displayable method

        Creates a mesh that consists of a width x height grid of evenly
        spaced points, connecting each point to the closest points
        vertically and horizontally, and dividing each rectangle in
        the grid so created into triangles.

        `width`, `height`
            The number of points in the horizontal vertical directions,
            a integer that is at least 2.

           z1The width and height of a grid_mesh must be >= 2.grid)	Exceptionr   )r   widthheightr   r   r   	grid_meshU   s    zModel.grid_meshFc                 C   s   | j t|||| | S )a  
        :doc: model_displayable method

        Add a texture to this model, by rendering the given displayable.
        The first texture added will be ``tex0``, the second ``tex1``, a
        and so on.

        `focus`
            If true, focus events are passed to the displayable. It's
            assumed that coordinate relative to the model map 1:1 with
            coordinates relative to the displayable.

        `main`
            If true, this is marked as a main child of this displayable,
            which allows it to be inspected using the displayable
            inspector.

        `fit`
            If true, the Model is given the size of the displayable.
            This may only be true for one texture.
        )r   appendr   r   r   r   r   texturej   s    zModel.texturec                 C   s   | j |dd|d | S )z
        :doc: model_displayable method

        This is the same as the texture method, except that the `focus`
        and `main` parameters are set to true.
        T)r
   r   r   )r(   )r   r   r   r   r   r   child   s    zModel.childc                 C   s   | j | | S )z
        :doc: model_displayable method

        Adds a shader to this model.

        `shader`
            A string given the name of a shader to use with this model.
        )r   r'   )r   shaderr   r   r   r*      s    
zModel.shaderc                 C   s   || j |< | S )an  
        :doc: model_displayable method

        Sets the value of a uniform that is passed to the shaders.

        `name`
            A string giving the name of the uniform to set, including the
            "u\_" prefix.

        `value`
            The value of the uniform. Either a float, a 2, 3, or 4 element
            tuple of floats, or a Matrix.
        )r   r   namevaluer   r   r   uniform   s    
zModel.uniformc                 C   s   || j |< | S )a  
        :doc: model_displayable method

        Sets the value of a gl property.

        `name`
            A string giving the name of the GL property, including the "gl\_"
            prefix.

        `value`
            The value of the gl property.

        )r   r+   r   r   r   property   s    
zModel.propertyc                 C   s"   | j D ]}|j|r dS qdS )NTF)r   r   _handles_event)r   eventir   r   r   r0      s    
zModel._handles_eventc                    s0   t t| || | jD ]}|j|d qd S NF)r   r   set_style_prefixr   r   )r   prefixrootr2   r   r   r   r4      s    
zModel.set_style_prefixc                 C   sL   g }d}| j D ]"}| }|||uO }|| q|s:| S |  }||_ |S r3   )r   r   r'   _copy)r   r   changedoldnewrvr   r   r   r      s    
zModel._in_current_storec                 C   s   dd | j D S )Nc                 S   s   g | ]
}|j qS r   )r   .0r2   r   r   r   
<listcomp>       zModel.visit.<locals>.<listcomp>)r   )r   r   r   r   visit   s    zModel.visitc                    s  t jjjstd| jd ur&| j\ fdd| jD }t|| jD ]\}}|jrL|	 \qLt jj
}t|| jD ]\}}|j|d|j|jd q| jd u r| jrt jjjdddddd|_nt jjjdd|_nXt| jtr@| jd d	krH| j\}	}
}t jjj|
|dddddd
|_n| j|_| jD ]}|| qN| j D ]\}}||| qj| j D ]\}}||| q|S )
NzLThe Model displayable may only be used when model-based rendering is active.c              	      s$   g | ]}t jj|j qS r   )r   displayrenderr   r<   atr%   str$   r   r   r>      r?   z Model.render.<locals>.<listcomp>)r   r   )r
   r   g        g      ?r   r"   )r   rA   rB   modelsr#   r   r   zipr   get_sizeRenderblitr
   r   r   gl2gl2mesh2Mesh2texture_rectanglemesh	rectangle
isinstancetupletexture_grid_meshr   
add_shaderr   itemsadd_uniformr   add_property)r   r$   r%   rE   rD   renderscrtr;   _
mesh_widthmesh_heightr2   kvr   rC   r   rB      sH    







zModel.render)N)FFF)F)r   r   r   __doc__r   r&   r(   r)   r*   r.   r/   r0   r4   r   r@   rB   __classcell__r   r   r   r   r   2   s   

r   )r   objectr   rA   coreDisplayabler   r   r   r   r   <module>   s   